blob: ccee3eddc5f4c24b4afcdf6cb4dcaf8759165b7a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*******************************************************************************
2 *
3 * Linux ThunderLAN Driver
4 *
5 * tlan.c
6 * by James Banks
7 *
8 * (C) 1997-1998 Caldera, Inc.
9 * (C) 1998 James Banks
10 * (C) 1999-2001 Torben Mathiasen
11 * (C) 2002 Samuel Chessman
12 *
13 * This software may be used and distributed according to the terms
14 * of the GNU General Public License, incorporated herein by reference.
15 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 ** Useful (if not required) reading:
17 *
18 * Texas Instruments, ThunderLAN Programmer's Guide,
19 * TI Literature Number SPWU013A
20 * available in PDF format from www.ti.com
21 * Level One, LXT901 and LXT970 Data Sheets
22 * available in PDF format from www.level1.com
23 * National Semiconductor, DP83840A Data Sheet
24 * available in PDF format from www.national.com
25 * Microchip Technology, 24C01A/02A/04A Data Sheet
26 * available in PDF format from www.microchip.com
27 *
28 * Change History
29 *
30 * Tigran Aivazian <tigran@sco.com>: TLan_PciProbe() now uses
31 * new PCI BIOS interface.
Alan Cox113aa832008-10-13 19:01:08 -070032 * Alan Cox <alan@lxorguk.ukuu.org.uk>:
33 * Fixed the out of memory
Linus Torvalds1da177e2005-04-16 15:20:36 -070034 * handling.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040035 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070036 * Torben Mathiasen <torben.mathiasen@compaq.com> New Maintainer!
37 *
38 * v1.1 Dec 20, 1999 - Removed linux version checking
Jeff Garzik6aa20a22006-09-13 13:24:59 -040039 * Patch from Tigran Aivazian.
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 * - v1.1 includes Alan's SMP updates.
41 * - We still have problems on SMP though,
Jeff Garzik6aa20a22006-09-13 13:24:59 -040042 * but I'm looking into that.
43 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 * v1.2 Jan 02, 2000 - Hopefully fixed the SMP deadlock.
45 * - Removed dependency of HZ being 100.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040046 * - We now allow higher priority timers to
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 * overwrite timers like TLAN_TIMER_ACTIVITY
48 * Patch from John Cagle <john.cagle@compaq.com>.
49 * - Fixed a few compiler warnings.
50 *
51 * v1.3 Feb 04, 2000 - Fixed the remaining HZ issues.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040052 * - Removed call to pci_present().
Linus Torvalds1da177e2005-04-16 15:20:36 -070053 * - Removed SA_INTERRUPT flag from irq handler.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040054 * - Added __init and __initdata to reduce resisdent
Linus Torvalds1da177e2005-04-16 15:20:36 -070055 * code size.
56 * - Driver now uses module_init/module_exit.
57 * - Rewrote init_module and tlan_probe to
58 * share a lot more code. We now use tlan_probe
59 * with builtin and module driver.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040060 * - Driver ported to new net API.
61 * - tlan.txt has been reworked to reflect current
Linus Torvalds1da177e2005-04-16 15:20:36 -070062 * driver (almost)
63 * - Other minor stuff
64 *
65 * v1.4 Feb 10, 2000 - Updated with more changes required after Dave's
66 * network cleanup in 2.3.43pre7 (Tigran & myself)
67 * - Minor stuff.
68 *
69 * v1.5 March 22, 2000 - Fixed another timer bug that would hang the driver
70 * if no cable/link were present.
71 * - Cosmetic changes.
72 * - TODO: Port completely to new PCI/DMA API
73 * Auto-Neg fallback.
74 *
75 * v1.6 April 04, 2000 - Fixed driver support for kernel-parameters. Haven't
Jeff Garzik6aa20a22006-09-13 13:24:59 -040076 * tested it though, as the kernel support is currently
Linus Torvalds1da177e2005-04-16 15:20:36 -070077 * broken (2.3.99p4p3).
78 * - Updated tlan.txt accordingly.
79 * - Adjusted minimum/maximum frame length.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040080 * - There is now a TLAN website up at
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 * http://tlan.kernel.dk
82 *
83 * v1.7 April 07, 2000 - Started to implement custom ioctls. Driver now
84 * reports PHY information when used with Donald
85 * Beckers userspace MII diagnostics utility.
86 *
87 * v1.8 April 23, 2000 - Fixed support for forced speed/duplex settings.
88 * - Added link information to Auto-Neg and forced
89 * modes. When NIC operates with auto-neg the driver
90 * will report Link speed & duplex modes as well as
91 * link partner abilities. When forced link is used,
92 * the driver will report status of the established
93 * link.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040094 * Please read tlan.txt for additional information.
95 * - Removed call to check_region(), and used
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 * return value of request_region() instead.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040097 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 * v1.8a May 28, 2000 - Minor updates.
99 *
100 * v1.9 July 25, 2000 - Fixed a few remaining Full-Duplex issues.
101 * - Updated with timer fixes from Andrew Morton.
102 * - Fixed module race in TLan_Open.
103 * - Added routine to monitor PHY status.
104 * - Added activity led support for Proliant devices.
105 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400106 * v1.10 Aug 30, 2000 - Added support for EISA based tlan controllers
107 * like the Compaq NetFlex3/E.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 * - Rewrote tlan_probe to better handle multiple
109 * bus probes. Probing and device setup is now
110 * done through TLan_Probe and TLan_init_one. Actual
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400111 * hardware probe is done with kernel API and
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 * TLan_EisaProbe.
113 * - Adjusted debug information for probing.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400114 * - Fixed bug that would cause general debug information
115 * to be printed after driver removal.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 * - Added transmit timeout handling.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400117 * - Fixed OOM return values in tlan_probe.
118 * - Fixed possible mem leak in tlan_exit
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 * (now tlan_remove_one).
120 * - Fixed timer bug in TLan_phyMonitor.
121 * - This driver version is alpha quality, please
122 * send me any bug issues you may encounter.
123 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400124 * v1.11 Aug 31, 2000 - Do not try to register irq 0 if no irq line was
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 * set for EISA cards.
126 * - Added support for NetFlex3/E with nibble-rate
127 * 10Base-T PHY. This is untestet as I haven't got
128 * one of these cards.
129 * - Fixed timer being added twice.
130 * - Disabled PhyMonitoring by default as this is
131 * work in progress. Define MONITOR to enable it.
132 * - Now we don't display link info with PHYs that
133 * doesn't support it (level1).
134 * - Incresed tx_timeout beacuse of auto-neg.
135 * - Adjusted timers for forced speeds.
136 *
137 * v1.12 Oct 12, 2000 - Minor fixes (memleak, init, etc.)
138 *
139 * v1.13 Nov 28, 2000 - Stop flooding console with auto-neg issues
140 * when link can't be established.
141 * - Added the bbuf option as a kernel parameter.
142 * - Fixed ioaddr probe bug.
143 * - Fixed stupid deadlock with MII interrupts.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400144 * - Added support for speed/duplex selection with
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145 * multiple nics.
146 * - Added partly fix for TX Channel lockup with
147 * TLAN v1.0 silicon. This needs to be investigated
148 * further.
149 *
150 * v1.14 Dec 16, 2000 - Added support for servicing multiple frames per.
151 * interrupt. Thanks goes to
152 * Adam Keys <adam@ti.com>
153 * Denis Beaudoin <dbeaudoin@ti.com>
154 * for providing the patch.
155 * - Fixed auto-neg output when using multiple
156 * adapters.
157 * - Converted to use new taskq interface.
158 *
159 * v1.14a Jan 6, 2001 - Minor adjustments (spinlocks, etc.)
160 *
161 * Samuel Chessman <chessman@tux.org> New Maintainer!
162 *
163 * v1.15 Apr 4, 2002 - Correct operation when aui=1 to be
164 * 10T half duplex no loopback
165 * Thanks to Gunnar Eikman
Sakari Ailus5eeabf52008-12-16 15:24:05 -0800166 *
167 * Sakari Ailus <sakari.ailus@iki.fi>:
168 *
169 * v1.15a Dec 15 2008 - Remove bbuf support, it doesn't work anyway.
170 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 *******************************************************************************/
172
173#include <linux/module.h>
174#include <linux/init.h>
175#include <linux/ioport.h>
176#include <linux/eisa.h>
177#include <linux/pci.h>
Domen Puncer1e7f0bd2005-06-26 18:22:14 -0400178#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179#include <linux/netdevice.h>
180#include <linux/etherdevice.h>
181#include <linux/delay.h>
182#include <linux/spinlock.h>
183#include <linux/workqueue.h>
184#include <linux/mii.h>
185
186#include "tlan.h"
187
188typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 );
189
190
191/* For removing EISA devices */
192static struct net_device *TLan_Eisa_Devices;
193
194static int TLanDevicesInstalled;
195
196/* Set speed, duplex and aui settings */
197static int aui[MAX_TLAN_BOARDS];
198static int duplex[MAX_TLAN_BOARDS];
199static int speed[MAX_TLAN_BOARDS];
200static int boards_found;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -0700201module_param_array(aui, int, NULL, 0);
202module_param_array(duplex, int, NULL, 0);
203module_param_array(speed, int, NULL, 0);
204MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
205MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
206MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207
208MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
209MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
210MODULE_LICENSE("GPL");
211
212
213/* Define this to enable Link beat monitoring */
214#undef MONITOR
215
216/* Turn on debugging. See Documentation/networking/tlan.txt for details */
217static int debug;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -0700218module_param(debug, int, 0);
219MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
Stephen Hemmingera3ccc782008-05-30 09:49:57 -0700221static const char TLanSignature[] = "TLAN";
Sakari Ailus5eeabf52008-12-16 15:24:05 -0800222static const char tlan_banner[] = "ThunderLAN driver v1.15a\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223static int tlan_have_pci;
224static int tlan_have_eisa;
225
226static const char *media[] = {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400227 "10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 "100baseTx-FD", "100baseT4", NULL
229};
230
231static struct board {
232 const char *deviceLabel;
233 u32 flags;
234 u16 addrOfs;
235} board_info[] = {
236 { "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
237 { "Compaq Netelligent 10/100 TX PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
238 { "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700239 { "Compaq NetFlex-3/P",
240 TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 { "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700242 { "Compaq Netelligent Integrated 10/100 TX UTP",
243 TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244 { "Compaq Netelligent Dual 10/100 TX PCI UTP", TLAN_ADAPTER_NONE, 0x83 },
245 { "Compaq Netelligent 10/100 TX Embedded UTP", TLAN_ADAPTER_NONE, 0x83 },
246 { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
247 { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xF8 },
248 { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xF8 },
249 { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
250 { "Compaq Netelligent 10 T/2 PCI UTP/Coax", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700251 { "Compaq NetFlex-3/E",
252 TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */
253 TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
255};
256
Alexey Dobriyana3aa1882010-01-07 11:58:11 +0000257static DEFINE_PCI_DEVICE_TABLE(tlan_pci_tbl) = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
259 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
260 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
261 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
262 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3I,
263 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
264 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_THUNDER,
265 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
266 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3B,
267 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
268 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100PI,
269 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
270 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100D,
271 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
272 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100I,
273 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
274 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183,
275 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
276 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325,
277 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
278 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
279 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
280 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,
281 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
282 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2,
283 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
284 { 0,}
285};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400286MODULE_DEVICE_TABLE(pci, tlan_pci_tbl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287
288static void TLan_EisaProbe( void );
289static void TLan_Eisa_Cleanup( void );
290static int TLan_Init( struct net_device * );
291static int TLan_Open( struct net_device *dev );
Stephen Hemminger613573252009-08-31 19:50:58 +0000292static netdev_tx_t TLan_StartTx( struct sk_buff *, struct net_device *);
David Howells7d12e782006-10-05 14:55:46 +0100293static irqreturn_t TLan_HandleInterrupt( int, void *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294static int TLan_Close( struct net_device *);
295static struct net_device_stats *TLan_GetStats( struct net_device *);
296static void TLan_SetMulticastList( struct net_device *);
297static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700298static int TLan_probe1( struct pci_dev *pdev, long ioaddr,
299 int irq, int rev, const struct pci_device_id *ent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300static void TLan_tx_timeout( struct net_device *dev);
David Howellsc4028952006-11-22 14:57:56 +0000301static void TLan_tx_timeout_work(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
303
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304static u32 TLan_HandleTxEOF( struct net_device *, u16 );
305static u32 TLan_HandleStatOverflow( struct net_device *, u16 );
306static u32 TLan_HandleRxEOF( struct net_device *, u16 );
307static u32 TLan_HandleDummy( struct net_device *, u16 );
308static u32 TLan_HandleTxEOC( struct net_device *, u16 );
309static u32 TLan_HandleStatusCheck( struct net_device *, u16 );
310static u32 TLan_HandleRxEOC( struct net_device *, u16 );
311
312static void TLan_Timer( unsigned long );
313
314static void TLan_ResetLists( struct net_device * );
315static void TLan_FreeLists( struct net_device * );
316static void TLan_PrintDio( u16 );
317static void TLan_PrintList( TLanList *, char *, int );
318static void TLan_ReadAndClearStats( struct net_device *, int );
319static void TLan_ResetAdapter( struct net_device * );
320static void TLan_FinishReset( struct net_device * );
321static void TLan_SetMac( struct net_device *, int areg, char *mac );
322
323static void TLan_PhyPrint( struct net_device * );
324static void TLan_PhyDetect( struct net_device * );
325static void TLan_PhyPowerDown( struct net_device * );
326static void TLan_PhyPowerUp( struct net_device * );
327static void TLan_PhyReset( struct net_device * );
328static void TLan_PhyStartLink( struct net_device * );
329static void TLan_PhyFinishAutoNeg( struct net_device * );
330#ifdef MONITOR
331static void TLan_PhyMonitor( struct net_device * );
332#endif
333
334/*
335static int TLan_PhyNop( struct net_device * );
336static int TLan_PhyInternalCheck( struct net_device * );
337static int TLan_PhyInternalService( struct net_device * );
338static int TLan_PhyDp83840aCheck( struct net_device * );
339*/
340
Joe Perches37fce432010-01-12 20:59:13 +0000341static bool TLan_MiiReadReg( struct net_device *, u16, u16, u16 * );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342static void TLan_MiiSendData( u16, u32, unsigned );
343static void TLan_MiiSync( u16 );
344static void TLan_MiiWriteReg( struct net_device *, u16, u16, u16 );
345
346static void TLan_EeSendStart( u16 );
347static int TLan_EeSendByte( u16, u8, int );
348static void TLan_EeReceiveByte( u16, u8 *, int );
349static int TLan_EeReadByte( struct net_device *, u8, u8 * );
350
351
Stephen Hemminger93e16842008-05-30 09:49:55 -0700352static inline void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353TLan_StoreSKB( struct tlan_list_tag *tag, struct sk_buff *skb)
354{
355 unsigned long addr = (unsigned long)skb;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700356 tag->buffer[9].address = addr;
357 tag->buffer[8].address = upper_32_bits(addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358}
359
Stephen Hemminger93e16842008-05-30 09:49:55 -0700360static inline struct sk_buff *
361TLan_GetSKB( const struct tlan_list_tag *tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362{
Stephen Hemminger93e16842008-05-30 09:49:55 -0700363 unsigned long addr;
364
Robert Fitzsimons0d63bea2008-08-09 17:54:02 +0100365 addr = tag->buffer[9].address;
366 addr |= (tag->buffer[8].address << 16) << 16;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 return (struct sk_buff *) addr;
368}
369
370
371static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = {
Stephen Hemmingera3ccc782008-05-30 09:49:57 -0700372 NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 TLan_HandleTxEOF,
374 TLan_HandleStatOverflow,
375 TLan_HandleRxEOF,
376 TLan_HandleDummy,
377 TLan_HandleTxEOC,
378 TLan_HandleStatusCheck,
379 TLan_HandleRxEOC
380};
381
382static inline void
383TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type )
384{
385 TLanPrivateInfo *priv = netdev_priv(dev);
386 unsigned long flags = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400387
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 if (!in_irq())
389 spin_lock_irqsave(&priv->lock, flags);
390 if ( priv->timer.function != NULL &&
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400391 priv->timerType != TLAN_TIMER_ACTIVITY ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 if (!in_irq())
393 spin_unlock_irqrestore(&priv->lock, flags);
394 return;
395 }
396 priv->timer.function = &TLan_Timer;
397 if (!in_irq())
398 spin_unlock_irqrestore(&priv->lock, flags);
399
400 priv->timer.data = (unsigned long) dev;
401 priv->timerSetAt = jiffies;
402 priv->timerType = type;
403 mod_timer(&priv->timer, jiffies + ticks);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400404
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405} /* TLan_SetTimer */
406
407
408/*****************************************************************************
409******************************************************************************
410
411 ThunderLAN Driver Primary Functions
412
413 These functions are more or less common to all Linux network drivers.
414
415******************************************************************************
416*****************************************************************************/
417
418
419
420
421
422 /***************************************************************
423 * tlan_remove_one
424 *
425 * Returns:
426 * Nothing
427 * Parms:
428 * None
429 *
430 * Goes through the TLanDevices list and frees the device
431 * structs and memory associated with each device (lists
432 * and buffers). It also ureserves the IO port regions
433 * associated with this device.
434 *
435 **************************************************************/
436
437
438static void __devexit tlan_remove_one( struct pci_dev *pdev)
439{
440 struct net_device *dev = pci_get_drvdata( pdev );
441 TLanPrivateInfo *priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400442
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 unregister_netdev( dev );
444
445 if ( priv->dmaStorage ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700446 pci_free_consistent(priv->pciDev,
447 priv->dmaSize, priv->dmaStorage,
448 priv->dmaStorageDMA );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 }
450
451#ifdef CONFIG_PCI
452 pci_release_regions(pdev);
453#endif
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400454
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 free_netdev( dev );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400456
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 pci_set_drvdata( pdev, NULL );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400458}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459
460static struct pci_driver tlan_driver = {
461 .name = "tlan",
462 .id_table = tlan_pci_tbl,
463 .probe = tlan_init_one,
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400464 .remove = __devexit_p(tlan_remove_one),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465};
466
467static int __init tlan_probe(void)
468{
Leonardo Potenza6c04a5152008-02-04 23:47:16 -0800469 int rc = -ENODEV;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400470
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 printk(KERN_INFO "%s", tlan_banner);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400472
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400474
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 /* Use new style PCI probing. Now the kernel will
476 do most of this for us */
Leonardo Potenza6c04a5152008-02-04 23:47:16 -0800477 rc = pci_register_driver(&tlan_driver);
478
479 if (rc != 0) {
480 printk(KERN_ERR "TLAN: Could not register pci driver.\n");
481 goto err_out_pci_free;
482 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483
484 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
485 TLan_EisaProbe();
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400486
487 printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d EISA: %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 TLanDevicesInstalled, TLanDevicesInstalled == 1 ? "" : "s",
489 tlan_have_pci, tlan_have_eisa);
490
491 if (TLanDevicesInstalled == 0) {
Leonardo Potenza6c04a5152008-02-04 23:47:16 -0800492 rc = -ENODEV;
493 goto err_out_pci_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 }
495 return 0;
Leonardo Potenza6c04a5152008-02-04 23:47:16 -0800496
497err_out_pci_unreg:
498 pci_unregister_driver(&tlan_driver);
499err_out_pci_free:
Leonardo Potenza6c04a5152008-02-04 23:47:16 -0800500 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400502
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503
504static int __devinit tlan_init_one( struct pci_dev *pdev,
505 const struct pci_device_id *ent)
506{
507 return TLan_probe1( pdev, -1, -1, 0, ent);
508}
509
510
511/*
512 ***************************************************************
513 * tlan_probe1
514 *
515 * Returns:
516 * 0 on success, error code on error
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400517 * Parms:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 * none
519 *
520 * The name is lower case to fit in with all the rest of
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400521 * the netcard_probe names. This function looks for
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 * another TLan based adapter, setting it up with the
523 * allocated device struct if one is found.
524 * tlan_probe has been ported to the new net API and
525 * now allocates its own device structure. This function
526 * is also used by modules.
527 *
528 **************************************************************/
529
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400530static int __devinit TLan_probe1(struct pci_dev *pdev,
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700531 long ioaddr, int irq, int rev,
532 const struct pci_device_id *ent )
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533{
534
535 struct net_device *dev;
536 TLanPrivateInfo *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 u16 device_id;
538 int reg, rc = -ENODEV;
539
Adrian Bunkad9f6712006-02-05 00:37:47 +0100540#ifdef CONFIG_PCI
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 if (pdev) {
542 rc = pci_enable_device(pdev);
543 if (rc)
544 return rc;
545
546 rc = pci_request_regions(pdev, TLanSignature);
547 if (rc) {
548 printk(KERN_ERR "TLAN: Could not reserve IO regions\n");
549 goto err_out;
550 }
551 }
Adrian Bunkad9f6712006-02-05 00:37:47 +0100552#endif /* CONFIG_PCI */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553
554 dev = alloc_etherdev(sizeof(TLanPrivateInfo));
555 if (dev == NULL) {
556 printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");
557 rc = -ENOMEM;
558 goto err_out_regions;
559 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 SET_NETDEV_DEV(dev, &pdev->dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400561
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 priv = netdev_priv(dev);
563
564 priv->pciDev = pdev;
David Howellsc4028952006-11-22 14:57:56 +0000565 priv->dev = dev;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 /* Is this a PCI device? */
568 if (pdev) {
569 u32 pci_io_base = 0;
570
571 priv->adapter = &board_info[ent->driver_data];
572
Yang Hongyang284901a2009-04-06 19:01:15 -0700573 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 if (rc) {
575 printk(KERN_ERR "TLAN: No suitable PCI mapping available.\n");
576 goto err_out_free_dev;
577 }
578
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 for ( reg= 0; reg <= 5; reg ++ ) {
580 if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
581 pci_io_base = pci_resource_start(pdev, reg);
582 TLAN_DBG( TLAN_DEBUG_GNRL, "IO mapping is available at %x.\n",
583 pci_io_base);
584 break;
585 }
586 }
587 if (!pci_io_base) {
588 printk(KERN_ERR "TLAN: No IO mappings available\n");
589 rc = -EIO;
590 goto err_out_free_dev;
591 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400592
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 dev->base_addr = pci_io_base;
594 dev->irq = pdev->irq;
Auke Kok44c10132007-06-08 15:46:36 -0700595 priv->adapterRev = pdev->revision;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 pci_set_master(pdev);
597 pci_set_drvdata(pdev, dev);
598
599 } else { /* EISA card */
600 /* This is a hack. We need to know which board structure
601 * is suited for this adapter */
602 device_id = inw(ioaddr + EISA_ID2);
603 priv->is_eisa = 1;
604 if (device_id == 0x20F1) {
605 priv->adapter = &board_info[13]; /* NetFlex-3/E */
606 priv->adapterRev = 23; /* TLAN 2.3 */
607 } else {
608 priv->adapter = &board_info[14];
609 priv->adapterRev = 10; /* TLAN 1.0 */
610 }
611 dev->base_addr = ioaddr;
612 dev->irq = irq;
613 }
614
615 /* Kernel parameters */
616 if (dev->mem_start) {
617 priv->aui = dev->mem_start & 0x01;
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700618 priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0
619 : (dev->mem_start & 0x06) >> 1;
620 priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0
621 : (dev->mem_start & 0x18) >> 3;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400622
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 if (priv->speed == 0x1) {
624 priv->speed = TLAN_SPEED_10;
625 } else if (priv->speed == 0x2) {
626 priv->speed = TLAN_SPEED_100;
627 }
628 debug = priv->debug = dev->mem_end;
629 } else {
630 priv->aui = aui[boards_found];
631 priv->speed = speed[boards_found];
632 priv->duplex = duplex[boards_found];
633 priv->debug = debug;
634 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400635
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 /* This will be used when we get an adapter error from
637 * within our irq handler */
David Howellsc4028952006-11-22 14:57:56 +0000638 INIT_WORK(&priv->tlan_tqueue, TLan_tx_timeout_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639
640 spin_lock_init(&priv->lock);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 rc = TLan_Init(dev);
643 if (rc) {
644 printk(KERN_ERR "TLAN: Could not set up device.\n");
645 goto err_out_free_dev;
646 }
647
648 rc = register_netdev(dev);
649 if (rc) {
650 printk(KERN_ERR "TLAN: Could not register device.\n");
651 goto err_out_uninit;
652 }
653
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400654
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 TLanDevicesInstalled++;
656 boards_found++;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400657
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 /* pdev is NULL if this is an EISA device */
659 if (pdev)
660 tlan_have_pci++;
661 else {
662 priv->nextDevice = TLan_Eisa_Devices;
663 TLan_Eisa_Devices = dev;
664 tlan_have_eisa++;
665 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400666
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n",
668 dev->name,
669 (int) dev->irq,
670 (int) dev->base_addr,
671 priv->adapter->deviceLabel,
672 priv->adapterRev);
673 return 0;
674
675err_out_uninit:
676 pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage,
677 priv->dmaStorageDMA );
678err_out_free_dev:
679 free_netdev(dev);
680err_out_regions:
681#ifdef CONFIG_PCI
682 if (pdev)
683 pci_release_regions(pdev);
684#endif
685err_out:
686 if (pdev)
687 pci_disable_device(pdev);
688 return rc;
689}
690
691
692static void TLan_Eisa_Cleanup(void)
693{
694 struct net_device *dev;
695 TLanPrivateInfo *priv;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400696
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 while( tlan_have_eisa ) {
698 dev = TLan_Eisa_Devices;
699 priv = netdev_priv(dev);
700 if (priv->dmaStorage) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700701 pci_free_consistent(priv->pciDev, priv->dmaSize,
702 priv->dmaStorage, priv->dmaStorageDMA );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 }
704 release_region( dev->base_addr, 0x10);
705 unregister_netdev( dev );
706 TLan_Eisa_Devices = priv->nextDevice;
707 free_netdev( dev );
708 tlan_have_eisa--;
709 }
710}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400711
712
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713static void __exit tlan_exit(void)
714{
715 pci_unregister_driver(&tlan_driver);
716
717 if (tlan_have_eisa)
718 TLan_Eisa_Cleanup();
719
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720}
721
722
723/* Module loading/unloading */
724module_init(tlan_probe);
725module_exit(tlan_exit);
726
727
728
729 /**************************************************************
730 * TLan_EisaProbe
731 *
732 * Returns: 0 on success, 1 otherwise
733 *
734 * Parms: None
735 *
736 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400737 * This functions probes for EISA devices and calls
738 * TLan_probe1 when one is found.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 *
740 *************************************************************/
741
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400742static void __init TLan_EisaProbe (void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743{
744 long ioaddr;
745 int rc = -ENODEV;
746 int irq;
747 u16 device_id;
748
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400749 if (!EISA_bus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
751 return;
752 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400753
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 /* Loop through all slots of the EISA bus */
755 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400756
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700757 TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n",
758 (int) ioaddr + 0xC80, inw(ioaddr + EISA_ID));
759 TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n",
760 (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761
762
763 TLAN_DBG(TLAN_DEBUG_PROBE, "Probing for EISA adapter at IO: 0x%4x : ",
764 (int) ioaddr);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400765 if (request_region(ioaddr, 0x10, TLanSignature) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 goto out;
767
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400768 if (inw(ioaddr + EISA_ID) != 0x110E) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 release_region(ioaddr, 0x10);
770 goto out;
771 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400772
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 device_id = inw(ioaddr + EISA_ID2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400774 if (device_id != 0x20F1 && device_id != 0x40F1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 release_region (ioaddr, 0x10);
776 goto out;
777 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400778
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 if (inb(ioaddr + EISA_CR) != 0x1) { /* Check if adapter is enabled */
780 release_region (ioaddr, 0x10);
781 goto out2;
782 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400783
784 if (debug == 0x10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 printk("Found one\n");
786
787
788 /* Get irq from board */
789 switch (inb(ioaddr + 0xCC0)) {
790 case(0x10):
791 irq=5;
792 break;
793 case(0x20):
794 irq=9;
795 break;
796 case(0x40):
797 irq=10;
798 break;
799 case(0x80):
800 irq=11;
801 break;
802 default:
803 goto out;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400804 }
805
806
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 /* Setup the newly found eisa adapter */
808 rc = TLan_probe1( NULL, ioaddr, irq,
809 12, NULL);
810 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400811
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 out:
813 if (debug == 0x10)
814 printk("None found\n");
815 continue;
816
817 out2: if (debug == 0x10)
818 printk("Card found but it is not enabled, skipping\n");
819 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400820
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821 }
822
823} /* TLan_EisaProbe */
824
825#ifdef CONFIG_NET_POLL_CONTROLLER
826static void TLan_Poll(struct net_device *dev)
827{
828 disable_irq(dev->irq);
David Howells7d12e782006-10-05 14:55:46 +0100829 TLan_HandleInterrupt(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830 enable_irq(dev->irq);
831}
832#endif
833
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800834static const struct net_device_ops TLan_netdev_ops = {
835 .ndo_open = TLan_Open,
836 .ndo_stop = TLan_Close,
837 .ndo_start_xmit = TLan_StartTx,
838 .ndo_tx_timeout = TLan_tx_timeout,
839 .ndo_get_stats = TLan_GetStats,
840 .ndo_set_multicast_list = TLan_SetMulticastList,
841 .ndo_do_ioctl = TLan_ioctl,
842 .ndo_change_mtu = eth_change_mtu,
843 .ndo_set_mac_address = eth_mac_addr,
844 .ndo_validate_addr = eth_validate_addr,
845#ifdef CONFIG_NET_POLL_CONTROLLER
846 .ndo_poll_controller = TLan_Poll,
847#endif
848};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400849
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850
851
852 /***************************************************************
853 * TLan_Init
854 *
855 * Returns:
856 * 0 on success, error code otherwise.
857 * Parms:
858 * dev The structure of the device to be
859 * init'ed.
860 *
861 * This function completes the initialization of the
862 * device structure and driver. It reserves the IO
863 * addresses, allocates memory for the lists and bounce
864 * buffers, retrieves the MAC address from the eeprom
865 * and assignes the device's methods.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400866 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 **************************************************************/
868
869static int TLan_Init( struct net_device *dev )
870{
871 int dma_size;
872 int err;
873 int i;
874 TLanPrivateInfo *priv;
875
876 priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400877
Sakari Ailus5eeabf52008-12-16 15:24:05 -0800878 dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
879 * ( sizeof(TLanList) );
Stephen Hemminger93e16842008-05-30 09:49:55 -0700880 priv->dmaStorage = pci_alloc_consistent(priv->pciDev,
881 dma_size, &priv->dmaStorageDMA);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 priv->dmaSize = dma_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400883
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 if ( priv->dmaStorage == NULL ) {
885 printk(KERN_ERR "TLAN: Could not allocate lists and buffers for %s.\n",
886 dev->name );
887 return -ENOMEM;
888 }
889 memset( priv->dmaStorage, 0, dma_size );
Stephen Hemminger93e16842008-05-30 09:49:55 -0700890 priv->rxList = (TLanList *) ALIGN((unsigned long)priv->dmaStorage, 8);
891 priv->rxListDMA = ALIGN(priv->dmaStorageDMA, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 priv->txList = priv->rxList + TLAN_NUM_RX_LISTS;
893 priv->txListDMA = priv->rxListDMA + sizeof(TLanList) * TLAN_NUM_RX_LISTS;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700894
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895 err = 0;
896 for ( i = 0; i < 6 ; i++ )
897 err |= TLan_EeReadByte( dev,
898 (u8) priv->adapter->addrOfs + i,
899 (u8 *) &dev->dev_addr[i] );
900 if ( err ) {
901 printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n",
902 dev->name,
903 err );
904 }
905 dev->addr_len = 6;
906
907 netif_carrier_off(dev);
908
909 /* Device methods */
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800910 dev->netdev_ops = &TLan_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 dev->watchdog_timeo = TX_TIMEOUT;
912
913 return 0;
914
915} /* TLan_Init */
916
917
918
919
920 /***************************************************************
921 * TLan_Open
922 *
923 * Returns:
924 * 0 on success, error code otherwise.
925 * Parms:
926 * dev Structure of device to be opened.
927 *
928 * This routine puts the driver and TLAN adapter in a
929 * state where it is ready to send and receive packets.
930 * It allocates the IRQ, resets and brings the adapter
931 * out of reset, and allows interrupts. It also delays
932 * the startup for autonegotiation or sends a Rx GO
933 * command to the adapter, as appropriate.
934 *
935 **************************************************************/
936
937static int TLan_Open( struct net_device *dev )
938{
939 TLanPrivateInfo *priv = netdev_priv(dev);
940 int err;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400941
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION );
Stephen Hemmingera3ccc782008-05-30 09:49:57 -0700943 err = request_irq( dev->irq, TLan_HandleInterrupt, IRQF_SHARED,
944 dev->name, dev );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400945
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 if ( err ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700947 pr_err("TLAN: Cannot open %s because IRQ %d is already in use.\n",
948 dev->name, dev->irq );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 return err;
950 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400951
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 init_timer(&priv->timer);
953 netif_start_queue(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400954
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 /* NOTE: It might not be necessary to read the stats before a
956 reset if you don't care what the values are.
957 */
958 TLan_ResetLists( dev );
959 TLan_ReadAndClearStats( dev, TLAN_IGNORE );
960 TLan_ResetAdapter( dev );
961
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700962 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n",
963 dev->name, priv->tlanRev );
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964
965 return 0;
966
967} /* TLan_Open */
968
969
970
971 /**************************************************************
972 * TLan_ioctl
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400973 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 * Returns:
975 * 0 on success, error code otherwise
976 * Params:
977 * dev structure of device to receive ioctl.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400978 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 * rq ifreq structure to hold userspace data.
980 *
981 * cmd ioctl command.
982 *
983 *
984 *************************************************************/
985
986static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
987{
988 TLanPrivateInfo *priv = netdev_priv(dev);
989 struct mii_ioctl_data *data = if_mii(rq);
990 u32 phy = priv->phy[priv->phyNum];
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400991
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992 if (!priv->phyOnline)
993 return -EAGAIN;
994
995 switch(cmd) {
996 case SIOCGMIIPHY: /* Get address of MII PHY in use. */
997 data->phy_id = phy;
998
999
1000 case SIOCGMIIREG: /* Read MII PHY register. */
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001001 TLan_MiiReadReg(dev, data->phy_id & 0x1f,
1002 data->reg_num & 0x1f, &data->val_out);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 return 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001004
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005
1006 case SIOCSMIIREG: /* Write MII PHY register. */
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001007 TLan_MiiWriteReg(dev, data->phy_id & 0x1f,
1008 data->reg_num & 0x1f, data->val_in);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 return 0;
1010 default:
1011 return -EOPNOTSUPP;
1012 }
1013} /* tlan_ioctl */
1014
1015
1016 /***************************************************************
1017 * TLan_tx_timeout
1018 *
1019 * Returns: nothing
1020 *
1021 * Params:
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001022 * dev structure of device which timed out
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 * during transmit.
1024 *
1025 **************************************************************/
1026
1027static void TLan_tx_timeout(struct net_device *dev)
1028{
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001029
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001031
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 /* Ok so we timed out, lets see what we can do about it...*/
1033 TLan_FreeLists( dev );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001034 TLan_ResetLists( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 TLan_ReadAndClearStats( dev, TLAN_IGNORE );
1036 TLan_ResetAdapter( dev );
Eric Dumazet1ae5dc32010-05-10 05:01:31 -07001037 dev->trans_start = jiffies; /* prevent tx timeout */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001038 netif_wake_queue( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039
1040}
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001041
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
David Howellsc4028952006-11-22 14:57:56 +00001043 /***************************************************************
1044 * TLan_tx_timeout_work
1045 *
1046 * Returns: nothing
1047 *
1048 * Params:
1049 * work work item of device which timed out
1050 *
1051 **************************************************************/
1052
1053static void TLan_tx_timeout_work(struct work_struct *work)
1054{
1055 TLanPrivateInfo *priv =
1056 container_of(work, TLanPrivateInfo, tlan_tqueue);
1057
1058 TLan_tx_timeout(priv->dev);
1059}
1060
1061
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062
1063 /***************************************************************
1064 * TLan_StartTx
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001065 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 * Returns:
1067 * 0 on success, non-zero on failure.
1068 * Parms:
1069 * skb A pointer to the sk_buff containing the
1070 * frame to be sent.
1071 * dev The device to send the data on.
1072 *
1073 * This function adds a frame to the Tx list to be sent
1074 * ASAP. First it verifies that the adapter is ready and
1075 * there is room in the queue. Then it sets up the next
1076 * available list, copies the frame to the corresponding
1077 * buffer. If the adapter Tx channel is idle, it gives
1078 * the adapter a Tx Go command on the list, otherwise it
1079 * sets the forward address of the previous list to point
1080 * to this one. Then it frees the sk_buff.
1081 *
1082 **************************************************************/
1083
Stephen Hemminger613573252009-08-31 19:50:58 +00001084static netdev_tx_t TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085{
1086 TLanPrivateInfo *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087 dma_addr_t tail_list_phys;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001088 TLanList *tail_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 unsigned long flags;
Sakari Ailus8953f122008-12-16 01:44:05 -08001090 unsigned int txlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091
1092 if ( ! priv->phyOnline ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001093 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n",
1094 dev->name );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095 dev_kfree_skb_any(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001096 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 }
1098
Stephen Hemminger41873e92008-05-30 09:49:52 -07001099 if (skb_padto(skb, TLAN_MIN_FRAME_SIZE))
Patrick McHardy6ed10652009-06-23 06:03:08 +00001100 return NETDEV_TX_OK;
Sakari Ailus8953f122008-12-16 01:44:05 -08001101 txlen = max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE);
Stephen Hemminger41873e92008-05-30 09:49:52 -07001102
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 tail_list = priv->txList + priv->txTail;
1104 tail_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txTail;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001105
Linus Torvalds1da177e2005-04-16 15:20:36 -07001106 if ( tail_list->cStat != TLAN_CSTAT_UNUSED ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001107 TLAN_DBG( TLAN_DEBUG_TX,
1108 "TRANSMIT: %s is busy (Head=%d Tail=%d)\n",
1109 dev->name, priv->txHead, priv->txTail );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110 netif_stop_queue(dev);
1111 priv->txBusyCount++;
Patrick McHardy5b548142009-06-12 06:22:29 +00001112 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 }
1114
1115 tail_list->forward = 0;
1116
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001117 tail_list->buffer[0].address = pci_map_single(priv->pciDev,
1118 skb->data, txlen,
1119 PCI_DMA_TODEVICE);
1120 TLan_StoreSKB(tail_list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121
Sakari Ailus8953f122008-12-16 01:44:05 -08001122 tail_list->frameSize = (u16) txlen;
1123 tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) txlen;
Stephen Hemminger41873e92008-05-30 09:49:52 -07001124 tail_list->buffer[1].count = 0;
1125 tail_list->buffer[1].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126
1127 spin_lock_irqsave(&priv->lock, flags);
1128 tail_list->cStat = TLAN_CSTAT_READY;
1129 if ( ! priv->txInProgress ) {
1130 priv->txInProgress = 1;
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001131 TLAN_DBG( TLAN_DEBUG_TX,
1132 "TRANSMIT: Starting TX on buffer %d\n", priv->txTail );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 outl( tail_list_phys, dev->base_addr + TLAN_CH_PARM );
1134 outl( TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD );
1135 } else {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001136 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Adding buffer %d to TX channel\n",
1137 priv->txTail );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 if ( priv->txTail == 0 ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001139 ( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward
1140 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 } else {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001142 ( priv->txList + ( priv->txTail - 1 ) )->forward
1143 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 }
1145 }
1146 spin_unlock_irqrestore(&priv->lock, flags);
1147
1148 CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS );
1149
Patrick McHardy6ed10652009-06-23 06:03:08 +00001150 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151
1152} /* TLan_StartTx */
1153
1154
1155
1156
1157 /***************************************************************
1158 * TLan_HandleInterrupt
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001159 *
1160 * Returns:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 * Nothing
1162 * Parms:
1163 * irq The line on which the interrupt
1164 * occurred.
1165 * dev_id A pointer to the device assigned to
1166 * this irq line.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167 *
1168 * This function handles an interrupt generated by its
1169 * assigned TLAN adapter. The function deactivates
1170 * interrupts on its adapter, records the type of
1171 * interrupt, executes the appropriate subhandler, and
1172 * acknowdges the interrupt to the adapter (thus
1173 * re-enabling adapter interrupts.
1174 *
1175 **************************************************************/
1176
David Howells7d12e782006-10-05 14:55:46 +01001177static irqreturn_t TLan_HandleInterrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178{
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001179 struct net_device *dev = dev_id;
1180 TLanPrivateInfo *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 u16 host_int;
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001182 u16 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183
1184 spin_lock(&priv->lock);
1185
1186 host_int = inw( dev->base_addr + TLAN_HOST_INT );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 type = ( host_int & TLAN_HI_IT_MASK ) >> 2;
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001188 if ( type ) {
1189 u32 ack;
1190 u32 host_cmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001192 outw( host_int, dev->base_addr + TLAN_HOST_INT );
1193 ack = TLanIntVector[type]( dev, host_int );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001195 if ( ack ) {
1196 host_cmd = TLAN_HC_ACK | ack | ( type << 18 );
1197 outl( host_cmd, dev->base_addr + TLAN_HOST_CMD );
1198 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199 }
1200
1201 spin_unlock(&priv->lock);
1202
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001203 return IRQ_RETVAL(type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204} /* TLan_HandleInterrupts */
1205
1206
1207
1208
1209 /***************************************************************
1210 * TLan_Close
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001211 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 * Returns:
1213 * An error code.
1214 * Parms:
1215 * dev The device structure of the device to
1216 * close.
1217 *
1218 * This function shuts down the adapter. It records any
1219 * stats, puts the adapter into reset state, deactivates
1220 * its time as needed, and frees the irq it is using.
1221 *
1222 **************************************************************/
1223
1224static int TLan_Close(struct net_device *dev)
1225{
1226 TLanPrivateInfo *priv = netdev_priv(dev);
1227
1228 netif_stop_queue(dev);
1229 priv->neg_be_verbose = 0;
1230
1231 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1232 outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
1233 if ( priv->timer.function != NULL ) {
1234 del_timer_sync( &priv->timer );
1235 priv->timer.function = NULL;
1236 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001237
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 free_irq( dev->irq, dev );
1239 TLan_FreeLists( dev );
1240 TLAN_DBG( TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name );
1241
1242 return 0;
1243
1244} /* TLan_Close */
1245
1246
1247
1248
1249 /***************************************************************
1250 * TLan_GetStats
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001251 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 * Returns:
1253 * A pointer to the device's statistics structure.
1254 * Parms:
1255 * dev The device structure to return the
1256 * stats for.
1257 *
1258 * This function updates the devices statistics by reading
1259 * the TLAN chip's onboard registers. Then it returns the
1260 * address of the statistics structure.
1261 *
1262 **************************************************************/
1263
1264static struct net_device_stats *TLan_GetStats( struct net_device *dev )
1265{
1266 TLanPrivateInfo *priv = netdev_priv(dev);
1267 int i;
1268
1269 /* Should only read stats if open ? */
1270 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1271
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001272 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name,
1273 priv->rxEocCount );
1274 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name,
1275 priv->txBusyCount );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 if ( debug & TLAN_DEBUG_GNRL ) {
1277 TLan_PrintDio( dev->base_addr );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001278 TLan_PhyPrint( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 }
1280 if ( debug & TLAN_DEBUG_LIST ) {
1281 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ )
1282 TLan_PrintList( priv->rxList + i, "RX", i );
1283 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ )
1284 TLan_PrintList( priv->txList + i, "TX", i );
1285 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001286
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001287 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288
1289} /* TLan_GetStats */
1290
1291
1292
1293
1294 /***************************************************************
1295 * TLan_SetMulticastList
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001296 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 * Returns:
1298 * Nothing
1299 * Parms:
1300 * dev The device structure to set the
1301 * multicast list for.
1302 *
1303 * This function sets the TLAN adaptor to various receive
1304 * modes. If the IFF_PROMISC flag is set, promiscuous
1305 * mode is acitviated. Otherwise, promiscuous mode is
1306 * turned off. If the IFF_ALLMULTI flag is set, then
1307 * the hash table is set to receive all group addresses.
1308 * Otherwise, the first three multicast addresses are
1309 * stored in AREG_1-3, and the rest are selected via the
1310 * hash table, as necessary.
1311 *
1312 **************************************************************/
1313
1314static void TLan_SetMulticastList( struct net_device *dev )
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001315{
Jiri Pirko22bedad32010-04-01 21:22:57 +00001316 struct netdev_hw_addr *ha;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 u32 hash1 = 0;
1318 u32 hash2 = 0;
1319 int i;
1320 u32 offset;
1321 u8 tmp;
1322
1323 if ( dev->flags & IFF_PROMISC ) {
1324 tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001325 TLan_DioWrite8( dev->base_addr,
1326 TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 } else {
1328 tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001329 TLan_DioWrite8( dev->base_addr,
1330 TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 if ( dev->flags & IFF_ALLMULTI ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001332 for ( i = 0; i < 3; i++ )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 TLan_SetMac( dev, i + 1, NULL );
1334 TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, 0xFFFFFFFF );
1335 TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, 0xFFFFFFFF );
1336 } else {
Jiri Pirko567ec872010-02-23 23:17:07 +00001337 i = 0;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001338 netdev_for_each_mc_addr(ha, dev) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 if ( i < 3 ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001340 TLan_SetMac( dev, i + 1,
Jiri Pirko22bedad32010-04-01 21:22:57 +00001341 (char *) &ha->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 } else {
Jiri Pirko22bedad32010-04-01 21:22:57 +00001343 offset = TLan_HashFunc((u8 *)&ha->addr);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001344 if ( offset < 32 )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 hash1 |= ( 1 << offset );
1346 else
1347 hash2 |= ( 1 << ( offset - 32 ) );
1348 }
Jiri Pirko567ec872010-02-23 23:17:07 +00001349 i++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001351 for ( ; i < 3; i++ )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 TLan_SetMac( dev, i + 1, NULL );
1353 TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, hash1 );
1354 TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, hash2 );
1355 }
1356 }
1357
1358} /* TLan_SetMulticastList */
1359
1360
1361
1362/*****************************************************************************
1363******************************************************************************
1364
1365 ThunderLAN Driver Interrupt Vectors and Table
1366
1367 Please see Chap. 4, "Interrupt Handling" of the "ThunderLAN
1368 Programmer's Guide" for more informations on handling interrupts
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001369 generated by TLAN based adapters.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370
1371******************************************************************************
1372*****************************************************************************/
1373
1374
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375
1376
1377 /***************************************************************
1378 * TLan_HandleTxEOF
1379 *
1380 * Returns:
1381 * 1
1382 * Parms:
1383 * dev Device assigned the IRQ that was
1384 * raised.
1385 * host_int The contents of the HOST_INT
1386 * port.
1387 *
1388 * This function handles Tx EOF interrupts which are raised
1389 * by the adapter when it has completed sending the
1390 * contents of a buffer. If detemines which list/buffer
1391 * was completed and resets it. If the buffer was the last
1392 * in the channel (EOC), then the function checks to see if
1393 * another buffer is ready to send, and if so, sends a Tx
1394 * Go command. Finally, the driver activates/continues the
1395 * activity LED.
1396 *
1397 **************************************************************/
1398
Harvey Harrison98e0f522008-02-18 10:04:38 -08001399static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400{
1401 TLanPrivateInfo *priv = netdev_priv(dev);
1402 int eoc = 0;
1403 TLanList *head_list;
1404 dma_addr_t head_list_phys;
1405 u32 ack = 0;
1406 u16 tmpCStat;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001407
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001408 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n",
1409 priv->txHead, priv->txTail );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 head_list = priv->txList + priv->txHead;
1411
1412 while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001413 struct sk_buff *skb = TLan_GetSKB(head_list);
1414
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 ack++;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001416 pci_unmap_single(priv->pciDev, head_list->buffer[0].address,
1417 max(skb->len,
1418 (unsigned int)TLAN_MIN_FRAME_SIZE),
1419 PCI_DMA_TODEVICE);
1420 dev_kfree_skb_any(skb);
1421 head_list->buffer[8].address = 0;
1422 head_list->buffer[9].address = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001423
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 if ( tmpCStat & TLAN_CSTAT_EOC )
1425 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001426
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001427 dev->stats.tx_bytes += head_list->frameSize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
1429 head_list->cStat = TLAN_CSTAT_UNUSED;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001430 netif_start_queue(dev);
1431 CIRC_INC( priv->txHead, TLAN_NUM_TX_LISTS );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 head_list = priv->txList + priv->txHead;
1433 }
1434
1435 if (!ack)
1436 printk(KERN_INFO "TLAN: Received interrupt for uncompleted TX frame.\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001437
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438 if ( eoc ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001439 TLAN_DBG( TLAN_DEBUG_TX,
1440 "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n",
1441 priv->txHead, priv->txTail );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 head_list = priv->txList + priv->txHead;
1443 head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead;
1444 if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
1445 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM );
1446 ack |= TLAN_HC_GO;
1447 } else {
1448 priv->txInProgress = 0;
1449 }
1450 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001451
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001453 TLan_DioWrite8( dev->base_addr,
1454 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455 if ( priv->timer.function == NULL ) {
1456 priv->timer.function = &TLan_Timer;
1457 priv->timer.data = (unsigned long) dev;
1458 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1459 priv->timerSetAt = jiffies;
1460 priv->timerType = TLAN_TIMER_ACTIVITY;
1461 add_timer(&priv->timer);
1462 } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
1463 priv->timerSetAt = jiffies;
1464 }
1465 }
1466
1467 return ack;
1468
1469} /* TLan_HandleTxEOF */
1470
1471
1472
1473
1474 /***************************************************************
1475 * TLan_HandleStatOverflow
1476 *
1477 * Returns:
1478 * 1
1479 * Parms:
1480 * dev Device assigned the IRQ that was
1481 * raised.
1482 * host_int The contents of the HOST_INT
1483 * port.
1484 *
1485 * This function handles the Statistics Overflow interrupt
1486 * which means that one or more of the TLAN statistics
1487 * registers has reached 1/2 capacity and needs to be read.
1488 *
1489 **************************************************************/
1490
Harvey Harrison98e0f522008-02-18 10:04:38 -08001491static u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492{
1493 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1494
1495 return 1;
1496
1497} /* TLan_HandleStatOverflow */
1498
1499
1500
1501
1502 /***************************************************************
1503 * TLan_HandleRxEOF
1504 *
1505 * Returns:
1506 * 1
1507 * Parms:
1508 * dev Device assigned the IRQ that was
1509 * raised.
1510 * host_int The contents of the HOST_INT
1511 * port.
1512 *
1513 * This function handles the Rx EOF interrupt which
1514 * indicates a frame has been received by the adapter from
1515 * the net and the frame has been transferred to memory.
1516 * The function determines the bounce buffer the frame has
1517 * been loaded into, creates a new sk_buff big enough to
1518 * hold the frame, and sends it to protocol stack. It
1519 * then resets the used buffer and appends it to the end
1520 * of the list. If the frame was the last in the Rx
1521 * channel (EOC), the function restarts the receive channel
1522 * by sending an Rx Go command to the adapter. Then it
1523 * activates/continues the activity LED.
1524 *
1525 **************************************************************/
1526
Harvey Harrison98e0f522008-02-18 10:04:38 -08001527static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528{
1529 TLanPrivateInfo *priv = netdev_priv(dev);
1530 u32 ack = 0;
1531 int eoc = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 TLanList *head_list;
1533 struct sk_buff *skb;
1534 TLanList *tail_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 u16 tmpCStat;
1536 dma_addr_t head_list_phys;
1537
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001538 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOF (Head=%d Tail=%d)\n",
1539 priv->rxHead, priv->rxTail );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 head_list = priv->rxList + priv->rxHead;
1541 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001542
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001544 dma_addr_t frameDma = head_list->buffer[0].address;
1545 u32 frameSize = head_list->frameSize;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001546 struct sk_buff *new_skb;
1547
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 ack++;
1549 if (tmpCStat & TLAN_CSTAT_EOC)
1550 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001551
Eric Dumazet89d71a62009-10-13 05:34:20 +00001552 new_skb = netdev_alloc_skb_ip_align(dev,
1553 TLAN_MAX_FRAME_SIZE + 5);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001554 if ( !new_skb )
1555 goto drop_and_reuse;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001556
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001557 skb = TLan_GetSKB(head_list);
1558 pci_unmap_single(priv->pciDev, frameDma,
1559 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
1560 skb_put( skb, frameSize );
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001561
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001562 dev->stats.rx_bytes += frameSize;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001563
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001564 skb->protocol = eth_type_trans( skb, dev );
1565 netif_rx( skb );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001567 head_list->buffer[0].address = pci_map_single(priv->pciDev,
1568 new_skb->data,
1569 TLAN_MAX_FRAME_SIZE,
1570 PCI_DMA_FROMDEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001572 TLan_StoreSKB(head_list, new_skb);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001573drop_and_reuse:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 head_list->forward = 0;
1575 head_list->cStat = 0;
1576 tail_list = priv->rxList + priv->rxTail;
1577 tail_list->forward = head_list_phys;
1578
1579 CIRC_INC( priv->rxHead, TLAN_NUM_RX_LISTS );
1580 CIRC_INC( priv->rxTail, TLAN_NUM_RX_LISTS );
1581 head_list = priv->rxList + priv->rxHead;
1582 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1583 }
1584
1585 if (!ack)
1586 printk(KERN_INFO "TLAN: Received interrupt for uncompleted RX frame.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587
1588
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001589 if ( eoc ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001590 TLAN_DBG( TLAN_DEBUG_RX,
1591 "RECEIVE: Handling RX EOC (Head=%d Tail=%d)\n",
1592 priv->rxHead, priv->rxTail );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 head_list = priv->rxList + priv->rxHead;
1594 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1595 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM );
1596 ack |= TLAN_HC_GO | TLAN_HC_RT;
1597 priv->rxEocCount++;
1598 }
1599
1600 if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001601 TLan_DioWrite8( dev->base_addr,
1602 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 if ( priv->timer.function == NULL ) {
1604 priv->timer.function = &TLan_Timer;
1605 priv->timer.data = (unsigned long) dev;
1606 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1607 priv->timerSetAt = jiffies;
1608 priv->timerType = TLAN_TIMER_ACTIVITY;
1609 add_timer(&priv->timer);
1610 } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
1611 priv->timerSetAt = jiffies;
1612 }
1613 }
1614
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615 return ack;
1616
1617} /* TLan_HandleRxEOF */
1618
1619
1620
1621
1622 /***************************************************************
1623 * TLan_HandleDummy
1624 *
1625 * Returns:
1626 * 1
1627 * Parms:
1628 * dev Device assigned the IRQ that was
1629 * raised.
1630 * host_int The contents of the HOST_INT
1631 * port.
1632 *
1633 * This function handles the Dummy interrupt, which is
1634 * raised whenever a test interrupt is generated by setting
1635 * the Req_Int bit of HOST_CMD to 1.
1636 *
1637 **************************************************************/
1638
Harvey Harrison98e0f522008-02-18 10:04:38 -08001639static u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640{
1641 printk( "TLAN: Test interrupt on %s.\n", dev->name );
1642 return 1;
1643
1644} /* TLan_HandleDummy */
1645
1646
1647
1648
1649 /***************************************************************
1650 * TLan_HandleTxEOC
1651 *
1652 * Returns:
1653 * 1
1654 * Parms:
1655 * dev Device assigned the IRQ that was
1656 * raised.
1657 * host_int The contents of the HOST_INT
1658 * port.
1659 *
1660 * This driver is structured to determine EOC occurrences by
1661 * reading the CSTAT member of the list structure. Tx EOC
1662 * interrupts are disabled via the DIO INTDIS register.
1663 * However, TLAN chips before revision 3.0 didn't have this
1664 * functionality, so process EOC events if this is the
1665 * case.
1666 *
1667 **************************************************************/
1668
Harvey Harrison98e0f522008-02-18 10:04:38 -08001669static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670{
1671 TLanPrivateInfo *priv = netdev_priv(dev);
1672 TLanList *head_list;
1673 dma_addr_t head_list_phys;
1674 u32 ack = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001675
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 host_int = 0;
1677 if ( priv->tlanRev < 0x30 ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001678 TLAN_DBG( TLAN_DEBUG_TX,
1679 "TRANSMIT: Handling TX EOC (Head=%d Tail=%d) -- IRQ\n",
1680 priv->txHead, priv->txTail );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681 head_list = priv->txList + priv->txHead;
1682 head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead;
1683 if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
1684 netif_stop_queue(dev);
1685 outl( head_list_phys, dev->base_addr + TLAN_CH_PARM );
1686 ack |= TLAN_HC_GO;
1687 } else {
1688 priv->txInProgress = 0;
1689 }
1690 }
1691
1692 return ack;
1693
1694} /* TLan_HandleTxEOC */
1695
1696
1697
1698
1699 /***************************************************************
1700 * TLan_HandleStatusCheck
1701 *
1702 * Returns:
1703 * 0 if Adapter check, 1 if Network Status check.
1704 * Parms:
1705 * dev Device assigned the IRQ that was
1706 * raised.
1707 * host_int The contents of the HOST_INT
1708 * port.
1709 *
1710 * This function handles Adapter Check/Network Status
1711 * interrupts generated by the adapter. It checks the
1712 * vector in the HOST_INT register to determine if it is
1713 * an Adapter Check interrupt. If so, it resets the
1714 * adapter. Otherwise it clears the status registers
1715 * and services the PHY.
1716 *
1717 **************************************************************/
1718
Harvey Harrison98e0f522008-02-18 10:04:38 -08001719static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001720{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 TLanPrivateInfo *priv = netdev_priv(dev);
1722 u32 ack;
1723 u32 error;
1724 u8 net_sts;
1725 u32 phy;
1726 u16 tlphy_ctl;
1727 u16 tlphy_sts;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001728
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 ack = 1;
1730 if ( host_int & TLAN_HI_IV_MASK ) {
1731 netif_stop_queue( dev );
1732 error = inl( dev->base_addr + TLAN_CH_PARM );
1733 printk( "TLAN: %s: Adaptor Error = 0x%x\n", dev->name, error );
1734 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1735 outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
1736
1737 schedule_work(&priv->tlan_tqueue);
1738
1739 netif_wake_queue(dev);
1740 ack = 0;
1741 } else {
1742 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name );
1743 phy = priv->phy[priv->phyNum];
1744
1745 net_sts = TLan_DioRead8( dev->base_addr, TLAN_NET_STS );
1746 if ( net_sts ) {
1747 TLan_DioWrite8( dev->base_addr, TLAN_NET_STS, net_sts );
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001748 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n",
1749 dev->name, (unsigned) net_sts );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 }
1751 if ( ( net_sts & TLAN_NET_STS_MIRQ ) && ( priv->phyNum == 0 ) ) {
1752 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_STS, &tlphy_sts );
1753 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001754 if ( ! ( tlphy_sts & TLAN_TS_POLOK ) &&
1755 ! ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 tlphy_ctl |= TLAN_TC_SWAPOL;
1757 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
Joe Perches8e95a202009-12-03 07:58:21 +00001758 } else if ( ( tlphy_sts & TLAN_TS_POLOK ) &&
1759 ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 tlphy_ctl &= ~TLAN_TC_SWAPOL;
1761 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
1762 }
1763
1764 if (debug) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001765 TLan_PhyPrint( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 }
1767 }
1768 }
1769
1770 return ack;
1771
1772} /* TLan_HandleStatusCheck */
1773
1774
1775
1776
1777 /***************************************************************
1778 * TLan_HandleRxEOC
1779 *
1780 * Returns:
1781 * 1
1782 * Parms:
1783 * dev Device assigned the IRQ that was
1784 * raised.
1785 * host_int The contents of the HOST_INT
1786 * port.
1787 *
1788 * This driver is structured to determine EOC occurrences by
1789 * reading the CSTAT member of the list structure. Rx EOC
1790 * interrupts are disabled via the DIO INTDIS register.
1791 * However, TLAN chips before revision 3.0 didn't have this
1792 * CSTAT member or a INTDIS register, so if this chip is
1793 * pre-3.0, process EOC interrupts normally.
1794 *
1795 **************************************************************/
1796
Harvey Harrison98e0f522008-02-18 10:04:38 -08001797static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798{
1799 TLanPrivateInfo *priv = netdev_priv(dev);
1800 dma_addr_t head_list_phys;
1801 u32 ack = 1;
1802
1803 if ( priv->tlanRev < 0x30 ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001804 TLAN_DBG( TLAN_DEBUG_RX,
1805 "RECEIVE: Handling RX EOC (Head=%d Tail=%d) -- IRQ\n",
1806 priv->rxHead, priv->rxTail );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1808 outl( head_list_phys, dev->base_addr + TLAN_CH_PARM );
1809 ack |= TLAN_HC_GO | TLAN_HC_RT;
1810 priv->rxEocCount++;
1811 }
1812
1813 return ack;
1814
1815} /* TLan_HandleRxEOC */
1816
1817
1818
1819
1820/*****************************************************************************
1821******************************************************************************
1822
1823 ThunderLAN Driver Timer Function
1824
1825******************************************************************************
1826*****************************************************************************/
1827
1828
1829 /***************************************************************
1830 * TLan_Timer
1831 *
1832 * Returns:
1833 * Nothing
1834 * Parms:
1835 * data A value given to add timer when
1836 * add_timer was called.
1837 *
1838 * This function handles timed functionality for the
1839 * TLAN driver. The two current timer uses are for
1840 * delaying for autonegotionation and driving the ACT LED.
1841 * - Autonegotiation requires being allowed about
1842 * 2 1/2 seconds before attempting to transmit a
1843 * packet. It would be a very bad thing to hang
1844 * the kernel this long, so the driver doesn't
1845 * allow transmission 'til after this time, for
1846 * certain PHYs. It would be much nicer if all
1847 * PHYs were interrupt-capable like the internal
1848 * PHY.
1849 * - The ACT LED, which shows adapter activity, is
1850 * driven by the driver, and so must be left on
1851 * for a short period to power up the LED so it
1852 * can be seen. This delay can be changed by
1853 * changing the TLAN_TIMER_ACT_DELAY in tlan.h,
1854 * if desired. 100 ms produces a slightly
1855 * sluggish response.
1856 *
1857 **************************************************************/
1858
Harvey Harrison98e0f522008-02-18 10:04:38 -08001859static void TLan_Timer( unsigned long data )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860{
1861 struct net_device *dev = (struct net_device *) data;
1862 TLanPrivateInfo *priv = netdev_priv(dev);
1863 u32 elapsed;
1864 unsigned long flags = 0;
1865
1866 priv->timer.function = NULL;
1867
1868 switch ( priv->timerType ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001869#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 case TLAN_TIMER_LINK_BEAT:
1871 TLan_PhyMonitor( dev );
1872 break;
1873#endif
1874 case TLAN_TIMER_PHY_PDOWN:
1875 TLan_PhyPowerDown( dev );
1876 break;
1877 case TLAN_TIMER_PHY_PUP:
1878 TLan_PhyPowerUp( dev );
1879 break;
1880 case TLAN_TIMER_PHY_RESET:
1881 TLan_PhyReset( dev );
1882 break;
1883 case TLAN_TIMER_PHY_START_LINK:
1884 TLan_PhyStartLink( dev );
1885 break;
1886 case TLAN_TIMER_PHY_FINISH_AN:
1887 TLan_PhyFinishAutoNeg( dev );
1888 break;
1889 case TLAN_TIMER_FINISH_RESET:
1890 TLan_FinishReset( dev );
1891 break;
1892 case TLAN_TIMER_ACTIVITY:
1893 spin_lock_irqsave(&priv->lock, flags);
1894 if ( priv->timer.function == NULL ) {
1895 elapsed = jiffies - priv->timerSetAt;
1896 if ( elapsed >= TLAN_TIMER_ACT_DELAY ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001897 TLan_DioWrite8( dev->base_addr,
1898 TLAN_LED_REG, TLAN_LED_LINK );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 } else {
1900 priv->timer.function = &TLan_Timer;
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001901 priv->timer.expires = priv->timerSetAt
1902 + TLAN_TIMER_ACT_DELAY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903 spin_unlock_irqrestore(&priv->lock, flags);
1904 add_timer( &priv->timer );
1905 break;
1906 }
1907 }
1908 spin_unlock_irqrestore(&priv->lock, flags);
1909 break;
1910 default:
1911 break;
1912 }
1913
1914} /* TLan_Timer */
1915
1916
1917
1918
1919/*****************************************************************************
1920******************************************************************************
1921
1922 ThunderLAN Driver Adapter Related Routines
1923
1924******************************************************************************
1925*****************************************************************************/
1926
1927
1928 /***************************************************************
1929 * TLan_ResetLists
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001930 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 * Returns:
1932 * Nothing
1933 * Parms:
1934 * dev The device structure with the list
1935 * stuctures to be reset.
1936 *
1937 * This routine sets the variables associated with managing
1938 * the TLAN lists to their initial values.
1939 *
1940 **************************************************************/
1941
Harvey Harrison98e0f522008-02-18 10:04:38 -08001942static void TLan_ResetLists( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943{
1944 TLanPrivateInfo *priv = netdev_priv(dev);
1945 int i;
1946 TLanList *list;
1947 dma_addr_t list_phys;
1948 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949
1950 priv->txHead = 0;
1951 priv->txTail = 0;
1952 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
1953 list = priv->txList + i;
1954 list->cStat = TLAN_CSTAT_UNUSED;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001955 list->buffer[0].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 list->buffer[2].count = 0;
1957 list->buffer[2].address = 0;
1958 list->buffer[8].address = 0;
1959 list->buffer[9].address = 0;
1960 }
1961
1962 priv->rxHead = 0;
1963 priv->rxTail = TLAN_NUM_RX_LISTS - 1;
1964 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
1965 list = priv->rxList + i;
1966 list_phys = priv->rxListDMA + sizeof(TLanList) * i;
1967 list->cStat = TLAN_CSTAT_READY;
1968 list->frameSize = TLAN_MAX_FRAME_SIZE;
1969 list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
Eric Dumazet89d71a62009-10-13 05:34:20 +00001970 skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001971 if ( !skb ) {
1972 pr_err("TLAN: out of memory for received data.\n" );
1973 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 }
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001975
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001976 list->buffer[0].address = pci_map_single(priv->pciDev,
1977 skb->data,
1978 TLAN_MAX_FRAME_SIZE,
1979 PCI_DMA_FROMDEVICE);
1980 TLan_StoreSKB(list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 list->buffer[1].count = 0;
1982 list->buffer[1].address = 0;
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001983 list->forward = list_phys + sizeof(TLanList);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 }
1985
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001986 /* in case ran out of memory early, clear bits */
1987 while (i < TLAN_NUM_RX_LISTS) {
1988 TLan_StoreSKB(priv->rxList + i, NULL);
1989 ++i;
1990 }
1991 list->forward = 0;
1992
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993} /* TLan_ResetLists */
1994
1995
Harvey Harrison98e0f522008-02-18 10:04:38 -08001996static void TLan_FreeLists( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997{
1998 TLanPrivateInfo *priv = netdev_priv(dev);
1999 int i;
2000 TLanList *list;
2001 struct sk_buff *skb;
2002
Sakari Ailus5eeabf52008-12-16 15:24:05 -08002003 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
2004 list = priv->txList + i;
2005 skb = TLan_GetSKB(list);
2006 if ( skb ) {
2007 pci_unmap_single(
2008 priv->pciDev,
2009 list->buffer[0].address,
2010 max(skb->len,
2011 (unsigned int)TLAN_MIN_FRAME_SIZE),
2012 PCI_DMA_TODEVICE);
2013 dev_kfree_skb_any( skb );
2014 list->buffer[8].address = 0;
2015 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016 }
Sakari Ailus5eeabf52008-12-16 15:24:05 -08002017 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018
Sakari Ailus5eeabf52008-12-16 15:24:05 -08002019 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
2020 list = priv->rxList + i;
2021 skb = TLan_GetSKB(list);
2022 if ( skb ) {
2023 pci_unmap_single(priv->pciDev,
2024 list->buffer[0].address,
2025 TLAN_MAX_FRAME_SIZE,
2026 PCI_DMA_FROMDEVICE);
2027 dev_kfree_skb_any( skb );
2028 list->buffer[8].address = 0;
2029 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030 }
2031 }
2032} /* TLan_FreeLists */
2033
2034
2035
2036
2037 /***************************************************************
2038 * TLan_PrintDio
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002039 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002040 * Returns:
2041 * Nothing
2042 * Parms:
2043 * io_base Base IO port of the device of
2044 * which to print DIO registers.
2045 *
2046 * This function prints out all the internal (DIO)
2047 * registers of a TLAN chip.
2048 *
2049 **************************************************************/
2050
Harvey Harrison98e0f522008-02-18 10:04:38 -08002051static void TLan_PrintDio( u16 io_base )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002052{
2053 u32 data0, data1;
2054 int i;
2055
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002056 printk( "TLAN: Contents of internal registers for io base 0x%04hx.\n",
2057 io_base );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058 printk( "TLAN: Off. +0 +4\n" );
2059 for ( i = 0; i < 0x4C; i+= 8 ) {
2060 data0 = TLan_DioRead32( io_base, i );
2061 data1 = TLan_DioRead32( io_base, i + 0x4 );
2062 printk( "TLAN: 0x%02x 0x%08x 0x%08x\n", i, data0, data1 );
2063 }
2064
2065} /* TLan_PrintDio */
2066
2067
2068
2069
2070 /***************************************************************
2071 * TLan_PrintList
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002072 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 * Returns:
2074 * Nothing
2075 * Parms:
2076 * list A pointer to the TLanList structure to
2077 * be printed.
2078 * type A string to designate type of list,
2079 * "Rx" or "Tx".
2080 * num The index of the list.
2081 *
2082 * This function prints out the contents of the list
2083 * pointed to by the list parameter.
2084 *
2085 **************************************************************/
2086
Harvey Harrison98e0f522008-02-18 10:04:38 -08002087static void TLan_PrintList( TLanList *list, char *type, int num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088{
2089 int i;
2090
Stephen Hemminger93e16842008-05-30 09:49:55 -07002091 printk( "TLAN: %s List %d at %p\n", type, num, list );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092 printk( "TLAN: Forward = 0x%08x\n", list->forward );
2093 printk( "TLAN: CSTAT = 0x%04hx\n", list->cStat );
2094 printk( "TLAN: Frame Size = 0x%04hx\n", list->frameSize );
2095 /* for ( i = 0; i < 10; i++ ) { */
2096 for ( i = 0; i < 2; i++ ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002097 printk( "TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n",
2098 i, list->buffer[i].count, list->buffer[i].address );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099 }
2100
2101} /* TLan_PrintList */
2102
2103
2104
2105
2106 /***************************************************************
2107 * TLan_ReadAndClearStats
2108 *
2109 * Returns:
2110 * Nothing
2111 * Parms:
2112 * dev Pointer to device structure of adapter
2113 * to which to read stats.
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002114 * record Flag indicating whether to add
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115 *
2116 * This functions reads all the internal status registers
2117 * of the TLAN chip, which clears them as a side effect.
2118 * It then either adds the values to the device's status
2119 * struct, or discards them, depending on whether record
2120 * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0).
2121 *
2122 **************************************************************/
2123
Harvey Harrison98e0f522008-02-18 10:04:38 -08002124static void TLan_ReadAndClearStats( struct net_device *dev, int record )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002126 u32 tx_good, tx_under;
2127 u32 rx_good, rx_over;
2128 u32 def_tx, crc, code;
2129 u32 multi_col, single_col;
2130 u32 excess_col, late_col, loss;
2131
2132 outw( TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR );
2133 tx_good = inb( dev->base_addr + TLAN_DIO_DATA );
2134 tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2135 tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
2136 tx_under = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
2137
2138 outw( TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR );
2139 rx_good = inb( dev->base_addr + TLAN_DIO_DATA );
2140 rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2141 rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
2142 rx_over = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002143
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 outw( TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR );
2145 def_tx = inb( dev->base_addr + TLAN_DIO_DATA );
2146 def_tx += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2147 crc = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2148 code = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002149
Linus Torvalds1da177e2005-04-16 15:20:36 -07002150 outw( TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
2151 multi_col = inb( dev->base_addr + TLAN_DIO_DATA );
2152 multi_col += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2153 single_col = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2154 single_col += inb( dev->base_addr + TLAN_DIO_DATA + 3 ) << 8;
2155
2156 outw( TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
2157 excess_col = inb( dev->base_addr + TLAN_DIO_DATA );
2158 late_col = inb( dev->base_addr + TLAN_DIO_DATA + 1 );
2159 loss = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2160
2161 if ( record ) {
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002162 dev->stats.rx_packets += rx_good;
2163 dev->stats.rx_errors += rx_over + crc + code;
2164 dev->stats.tx_packets += tx_good;
2165 dev->stats.tx_errors += tx_under + loss;
2166 dev->stats.collisions += multi_col + single_col + excess_col + late_col;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002168 dev->stats.rx_over_errors += rx_over;
2169 dev->stats.rx_crc_errors += crc;
2170 dev->stats.rx_frame_errors += code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002172 dev->stats.tx_aborted_errors += tx_under;
2173 dev->stats.tx_carrier_errors += loss;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002175
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176} /* TLan_ReadAndClearStats */
2177
2178
2179
2180
2181 /***************************************************************
2182 * TLan_Reset
2183 *
2184 * Returns:
2185 * 0
2186 * Parms:
2187 * dev Pointer to device structure of adapter
2188 * to be reset.
2189 *
2190 * This function resets the adapter and it's physical
2191 * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
2192 * Programmer's Guide" for details. The routine tries to
2193 * implement what is detailed there, though adjustments
2194 * have been made.
2195 *
2196 **************************************************************/
2197
Harvey Harrison98e0f522008-02-18 10:04:38 -08002198static void
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199TLan_ResetAdapter( struct net_device *dev )
2200{
2201 TLanPrivateInfo *priv = netdev_priv(dev);
2202 int i;
2203 u32 addr;
2204 u32 data;
2205 u8 data8;
2206
Joe Perches37fce432010-01-12 20:59:13 +00002207 priv->tlanFullDuplex = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 priv->phyOnline=0;
2209 netif_carrier_off(dev);
2210
2211/* 1. Assert reset bit. */
2212
2213 data = inl(dev->base_addr + TLAN_HOST_CMD);
2214 data |= TLAN_HC_AD_RST;
2215 outl(data, dev->base_addr + TLAN_HOST_CMD);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002216
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217 udelay(1000);
2218
2219/* 2. Turn off interrupts. ( Probably isn't necessary ) */
2220
2221 data = inl(dev->base_addr + TLAN_HOST_CMD);
2222 data |= TLAN_HC_INT_OFF;
2223 outl(data, dev->base_addr + TLAN_HOST_CMD);
2224
2225/* 3. Clear AREGs and HASHs. */
2226
2227 for ( i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4 ) {
2228 TLan_DioWrite32( dev->base_addr, (u16) i, 0 );
2229 }
2230
2231/* 4. Setup NetConfig register. */
2232
2233 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2234 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
2235
2236/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
2237
2238 outl( TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD );
2239 outl( TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD );
2240
2241/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
2242
2243 outw( TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR );
2244 addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
2245 TLan_SetBit( TLAN_NET_SIO_NMRST, addr );
2246
2247/* 7. Setup the remaining registers. */
2248
2249 if ( priv->tlanRev >= 0x30 ) {
2250 data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
2251 TLan_DioWrite8( dev->base_addr, TLAN_INT_DIS, data8 );
2252 }
2253 TLan_PhyDetect( dev );
2254 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002255
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256 if ( priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY ) {
2257 data |= TLAN_NET_CFG_BIT;
2258 if ( priv->aui == 1 ) {
2259 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x0a );
2260 } else if ( priv->duplex == TLAN_DUPLEX_FULL ) {
2261 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x00 );
Joe Perches37fce432010-01-12 20:59:13 +00002262 priv->tlanFullDuplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263 } else {
2264 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x08 );
2265 }
2266 }
2267
2268 if ( priv->phyNum == 0 ) {
2269 data |= TLAN_NET_CFG_PHY_EN;
2270 }
2271 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
2272
2273 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2274 TLan_FinishReset( dev );
2275 } else {
2276 TLan_PhyPowerDown( dev );
2277 }
2278
2279} /* TLan_ResetAdapter */
2280
2281
2282
2283
Harvey Harrison98e0f522008-02-18 10:04:38 -08002284static void
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285TLan_FinishReset( struct net_device *dev )
2286{
2287 TLanPrivateInfo *priv = netdev_priv(dev);
2288 u8 data;
2289 u32 phy;
2290 u8 sio;
2291 u16 status;
2292 u16 partner;
2293 u16 tlphy_ctl;
2294 u16 tlphy_par;
2295 u16 tlphy_id1, tlphy_id2;
2296 int i;
2297
2298 phy = priv->phy[priv->phyNum];
2299
2300 data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
2301 if ( priv->tlanFullDuplex ) {
2302 data |= TLAN_NET_CMD_DUPLEX;
2303 }
2304 TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, data );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002305 data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002306 if ( priv->phyNum == 0 ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002307 data |= TLAN_NET_MASK_MASK7;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 }
2309 TLan_DioWrite8( dev->base_addr, TLAN_NET_MASK, data );
2310 TLan_DioWrite16( dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7 );
2311 TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &tlphy_id1 );
2312 TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &tlphy_id2 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002313
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002314 if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) ||
2315 ( priv->aui ) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316 status = MII_GS_LINK;
2317 printk( "TLAN: %s: Link forced.\n", dev->name );
2318 } else {
2319 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2320 udelay( 1000 );
2321 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002322 if ( (status & MII_GS_LINK) &&
2323 /* We only support link info on Nat.Sem. PHY's */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 (tlphy_id1 == NAT_SEM_ID1) &&
2325 (tlphy_id2 == NAT_SEM_ID2) ) {
2326 TLan_MiiReadReg( dev, phy, MII_AN_LPA, &partner );
2327 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_PAR, &tlphy_par );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002328
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 printk( "TLAN: %s: Link active with ", dev->name );
2330 if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002331 printk( "forced 10%sMbps %s-Duplex\n",
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002332 tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
2333 tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002334 } else {
2335 printk( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n",
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002336 tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
2337 tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338 printk("TLAN: Partner capability: ");
2339 for (i = 5; i <= 10; i++)
2340 if (partner & (1<<i))
2341 printk("%s",media[i-5]);
2342 printk("\n");
2343 }
2344
2345 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002346#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07002347 /* We have link beat..for now anyway */
2348 priv->link = 1;
2349 /*Enabling link beat monitoring */
2350 TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_LINK_BEAT );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002351#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352 } else if (status & MII_GS_LINK) {
2353 printk( "TLAN: %s: Link active\n", dev->name );
2354 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
2355 }
2356 }
2357
2358 if ( priv->phyNum == 0 ) {
2359 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
2360 tlphy_ctl |= TLAN_TC_INTEN;
2361 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl );
2362 sio = TLan_DioRead8( dev->base_addr, TLAN_NET_SIO );
2363 sio |= TLAN_NET_SIO_MINTEN;
2364 TLan_DioWrite8( dev->base_addr, TLAN_NET_SIO, sio );
2365 }
2366
2367 if ( status & MII_GS_LINK ) {
2368 TLan_SetMac( dev, 0, dev->dev_addr );
2369 priv->phyOnline = 1;
2370 outb( ( TLAN_HC_INT_ON >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
2371 if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) {
2372 outb( ( TLAN_HC_REQ_INT >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
2373 }
2374 outl( priv->rxListDMA, dev->base_addr + TLAN_CH_PARM );
2375 outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD );
2376 netif_carrier_on(dev);
2377 } else {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002378 printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n",
2379 dev->name );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002380 TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
2381 return;
2382 }
James Harper562faf42005-05-05 15:14:18 -07002383 TLan_SetMulticastList(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384
2385} /* TLan_FinishReset */
2386
2387
2388
2389
2390 /***************************************************************
2391 * TLan_SetMac
2392 *
2393 * Returns:
2394 * Nothing
2395 * Parms:
2396 * dev Pointer to device structure of adapter
2397 * on which to change the AREG.
2398 * areg The AREG to set the address in (0 - 3).
2399 * mac A pointer to an array of chars. Each
2400 * element stores one byte of the address.
2401 * IE, it isn't in ascii.
2402 *
2403 * This function transfers a MAC address to one of the
2404 * TLAN AREGs (address registers). The TLAN chip locks
2405 * the register on writing to offset 0 and unlocks the
2406 * register after writing to offset 5. If NULL is passed
2407 * in mac, then the AREG is filled with 0's.
2408 *
2409 **************************************************************/
2410
Harvey Harrison98e0f522008-02-18 10:04:38 -08002411static void TLan_SetMac( struct net_device *dev, int areg, char *mac )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412{
2413 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002414
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415 areg *= 6;
2416
2417 if ( mac != NULL ) {
2418 for ( i = 0; i < 6; i++ )
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002419 TLan_DioWrite8( dev->base_addr,
2420 TLAN_AREG_0 + areg + i, mac[i] );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421 } else {
2422 for ( i = 0; i < 6; i++ )
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002423 TLan_DioWrite8( dev->base_addr,
2424 TLAN_AREG_0 + areg + i, 0 );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425 }
2426
2427} /* TLan_SetMac */
2428
2429
2430
2431
2432/*****************************************************************************
2433******************************************************************************
2434
2435 ThunderLAN Driver PHY Layer Routines
2436
2437******************************************************************************
2438*****************************************************************************/
2439
2440
2441
2442 /*********************************************************************
2443 * TLan_PhyPrint
2444 *
2445 * Returns:
2446 * Nothing
2447 * Parms:
2448 * dev A pointer to the device structure of the
2449 * TLAN device having the PHYs to be detailed.
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002450 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451 * This function prints the registers a PHY (aka transceiver).
2452 *
2453 ********************************************************************/
2454
Harvey Harrison98e0f522008-02-18 10:04:38 -08002455static void TLan_PhyPrint( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456{
2457 TLanPrivateInfo *priv = netdev_priv(dev);
2458 u16 i, data0, data1, data2, data3, phy;
2459
2460 phy = priv->phy[priv->phyNum];
2461
2462 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2463 printk( "TLAN: Device %s, Unmanaged PHY.\n", dev->name );
2464 } else if ( phy <= TLAN_PHY_MAX_ADDR ) {
2465 printk( "TLAN: Device %s, PHY 0x%02x.\n", dev->name, phy );
Frans Pop2381a552010-03-24 07:57:36 +00002466 printk( "TLAN: Off. +0 +1 +2 +3\n" );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467 for ( i = 0; i < 0x20; i+= 4 ) {
2468 printk( "TLAN: 0x%02x", i );
2469 TLan_MiiReadReg( dev, phy, i, &data0 );
2470 printk( " 0x%04hx", data0 );
2471 TLan_MiiReadReg( dev, phy, i + 1, &data1 );
2472 printk( " 0x%04hx", data1 );
2473 TLan_MiiReadReg( dev, phy, i + 2, &data2 );
2474 printk( " 0x%04hx", data2 );
2475 TLan_MiiReadReg( dev, phy, i + 3, &data3 );
2476 printk( " 0x%04hx\n", data3 );
2477 }
2478 } else {
2479 printk( "TLAN: Device %s, Invalid PHY.\n", dev->name );
2480 }
2481
2482} /* TLan_PhyPrint */
2483
2484
2485
2486
2487 /*********************************************************************
2488 * TLan_PhyDetect
2489 *
2490 * Returns:
2491 * Nothing
2492 * Parms:
2493 * dev A pointer to the device structure of the adapter
2494 * for which the PHY needs determined.
2495 *
2496 * So far I've found that adapters which have external PHYs
2497 * may also use the internal PHY for part of the functionality.
2498 * (eg, AUI/Thinnet). This function finds out if this TLAN
2499 * chip has an internal PHY, and then finds the first external
2500 * PHY (starting from address 0) if it exists).
2501 *
2502 ********************************************************************/
2503
Harvey Harrison98e0f522008-02-18 10:04:38 -08002504static void TLan_PhyDetect( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505{
2506 TLanPrivateInfo *priv = netdev_priv(dev);
2507 u16 control;
2508 u16 hi;
2509 u16 lo;
2510 u32 phy;
2511
2512 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2513 priv->phyNum = 0xFFFF;
2514 return;
2515 }
2516
2517 TLan_MiiReadReg( dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002518
Linus Torvalds1da177e2005-04-16 15:20:36 -07002519 if ( hi != 0xFFFF ) {
2520 priv->phy[0] = TLAN_PHY_MAX_ADDR;
2521 } else {
2522 priv->phy[0] = TLAN_PHY_NONE;
2523 }
2524
2525 priv->phy[1] = TLAN_PHY_NONE;
2526 for ( phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++ ) {
2527 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &control );
2528 TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &hi );
2529 TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &lo );
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002530 if ( ( control != 0xFFFF ) ||
2531 ( hi != 0xFFFF ) || ( lo != 0xFFFF ) ) {
2532 TLAN_DBG( TLAN_DEBUG_GNRL,
2533 "PHY found at %02x %04x %04x %04x\n",
2534 phy, control, hi, lo );
2535 if ( ( priv->phy[1] == TLAN_PHY_NONE ) &&
2536 ( phy != TLAN_PHY_MAX_ADDR ) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537 priv->phy[1] = phy;
2538 }
2539 }
2540 }
2541
2542 if ( priv->phy[1] != TLAN_PHY_NONE ) {
2543 priv->phyNum = 1;
2544 } else if ( priv->phy[0] != TLAN_PHY_NONE ) {
2545 priv->phyNum = 0;
2546 } else {
2547 printk( "TLAN: Cannot initialize device, no PHY was found!\n" );
2548 }
2549
2550} /* TLan_PhyDetect */
2551
2552
2553
2554
Harvey Harrison98e0f522008-02-18 10:04:38 -08002555static void TLan_PhyPowerDown( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556{
2557 TLanPrivateInfo *priv = netdev_priv(dev);
2558 u16 value;
2559
2560 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name );
2561 value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
2562 TLan_MiiSync( dev->base_addr );
2563 TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002564 if ( ( priv->phyNum == 0 ) &&
2565 ( priv->phy[1] != TLAN_PHY_NONE ) &&
2566 ( ! ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) ) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567 TLan_MiiSync( dev->base_addr );
2568 TLan_MiiWriteReg( dev, priv->phy[1], MII_GEN_CTL, value );
2569 }
2570
2571 /* Wait for 50 ms and powerup
2572 * This is abitrary. It is intended to make sure the
2573 * transceiver settles.
2574 */
2575 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP );
2576
2577} /* TLan_PhyPowerDown */
2578
2579
2580
2581
Harvey Harrison98e0f522008-02-18 10:04:38 -08002582static void TLan_PhyPowerUp( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583{
2584 TLanPrivateInfo *priv = netdev_priv(dev);
2585 u16 value;
2586
2587 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name );
2588 TLan_MiiSync( dev->base_addr );
2589 value = MII_GC_LOOPBK;
2590 TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
2591 TLan_MiiSync(dev->base_addr);
2592 /* Wait for 500 ms and reset the
2593 * transceiver. The TLAN docs say both 50 ms and
2594 * 500 ms, so do the longer, just in case.
2595 */
2596 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET );
2597
2598} /* TLan_PhyPowerUp */
2599
2600
2601
2602
Harvey Harrison98e0f522008-02-18 10:04:38 -08002603static void TLan_PhyReset( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604{
2605 TLanPrivateInfo *priv = netdev_priv(dev);
2606 u16 phy;
2607 u16 value;
2608
2609 phy = priv->phy[priv->phyNum];
2610
2611 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name );
2612 TLan_MiiSync( dev->base_addr );
2613 value = MII_GC_LOOPBK | MII_GC_RESET;
2614 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, value );
2615 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
2616 while ( value & MII_GC_RESET ) {
2617 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
2618 }
2619
2620 /* Wait for 500 ms and initialize.
2621 * I don't remember why I wait this long.
2622 * I've changed this to 50ms, as it seems long enough.
2623 */
2624 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK );
2625
2626} /* TLan_PhyReset */
2627
2628
2629
2630
Harvey Harrison98e0f522008-02-18 10:04:38 -08002631static void TLan_PhyStartLink( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632{
2633 TLanPrivateInfo *priv = netdev_priv(dev);
2634 u16 ability;
2635 u16 control;
2636 u16 data;
2637 u16 phy;
2638 u16 status;
2639 u16 tctl;
2640
2641 phy = priv->phy[priv->phyNum];
2642 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name );
2643 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2644 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &ability );
2645
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002646 if ( ( status & MII_GS_AUTONEG ) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002647 ( ! priv->aui ) ) {
2648 ability = status >> 11;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002649 if ( priv->speed == TLAN_SPEED_10 &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650 priv->duplex == TLAN_DUPLEX_HALF) {
2651 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000);
2652 } else if ( priv->speed == TLAN_SPEED_10 &&
2653 priv->duplex == TLAN_DUPLEX_FULL) {
Joe Perches37fce432010-01-12 20:59:13 +00002654 priv->tlanFullDuplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100);
2656 } else if ( priv->speed == TLAN_SPEED_100 &&
2657 priv->duplex == TLAN_DUPLEX_HALF) {
2658 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000);
2659 } else if ( priv->speed == TLAN_SPEED_100 &&
2660 priv->duplex == TLAN_DUPLEX_FULL) {
Joe Perches37fce432010-01-12 20:59:13 +00002661 priv->tlanFullDuplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100);
2663 } else {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002664
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665 /* Set Auto-Neg advertisement */
2666 TLan_MiiWriteReg( dev, phy, MII_AN_ADV, (ability << 5) | 1);
2667 /* Enablee Auto-Neg */
2668 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 );
2669 /* Restart Auto-Neg */
2670 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 );
2671 /* Wait for 4 sec for autonegotiation
2672 * to complete. The max spec time is less than this
2673 * but the card need additional time to start AN.
2674 * .5 sec should be plenty extra.
2675 */
2676 printk( "TLAN: %s: Starting autonegotiation.\n", dev->name );
2677 TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN );
2678 return;
2679 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002680
2681 }
2682
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683 if ( ( priv->aui ) && ( priv->phyNum != 0 ) ) {
2684 priv->phyNum = 0;
2685 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2686 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
2687 TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN );
2688 return;
2689 } else if ( priv->phyNum == 0 ) {
2690 control = 0;
2691 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tctl );
2692 if ( priv->aui ) {
2693 tctl |= TLAN_TC_AUISEL;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002694 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002695 tctl &= ~TLAN_TC_AUISEL;
2696 if ( priv->duplex == TLAN_DUPLEX_FULL ) {
2697 control |= MII_GC_DUPLEX;
Joe Perches37fce432010-01-12 20:59:13 +00002698 priv->tlanFullDuplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699 }
2700 if ( priv->speed == TLAN_SPEED_100 ) {
2701 control |= MII_GC_SPEEDSEL;
2702 }
2703 }
2704 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, control );
2705 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl );
2706 }
2707
2708 /* Wait for 2 sec to give the transceiver time
2709 * to establish link.
2710 */
2711 TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET );
2712
2713} /* TLan_PhyStartLink */
2714
2715
2716
2717
Harvey Harrison98e0f522008-02-18 10:04:38 -08002718static void TLan_PhyFinishAutoNeg( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719{
2720 TLanPrivateInfo *priv = netdev_priv(dev);
2721 u16 an_adv;
2722 u16 an_lpa;
2723 u16 data;
2724 u16 mode;
2725 u16 phy;
2726 u16 status;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002727
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 phy = priv->phy[priv->phyNum];
2729
2730 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2731 udelay( 1000 );
2732 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2733
2734 if ( ! ( status & MII_GS_AUTOCMPLT ) ) {
2735 /* Wait for 8 sec to give the process
2736 * more time. Perhaps we should fail after a while.
2737 */
2738 if (!priv->neg_be_verbose++) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002739 pr_info("TLAN: Giving autonegotiation more time.\n");
2740 pr_info("TLAN: Please check that your adapter has\n");
2741 pr_info("TLAN: been properly connected to a HUB or Switch.\n");
2742 pr_info("TLAN: Trying to establish link in the background...\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002743 }
2744 TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN );
2745 return;
2746 }
2747
2748 printk( "TLAN: %s: Autonegotiation complete.\n", dev->name );
2749 TLan_MiiReadReg( dev, phy, MII_AN_ADV, &an_adv );
2750 TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa );
2751 mode = an_adv & an_lpa & 0x03E0;
2752 if ( mode & 0x0100 ) {
Joe Perches37fce432010-01-12 20:59:13 +00002753 priv->tlanFullDuplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754 } else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) {
Joe Perches37fce432010-01-12 20:59:13 +00002755 priv->tlanFullDuplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756 }
2757
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002758 if ( ( ! ( mode & 0x0180 ) ) &&
2759 ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) &&
2760 ( priv->phyNum != 0 ) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002761 priv->phyNum = 0;
2762 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2763 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
2764 TLan_SetTimer( dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN );
2765 return;
2766 }
2767
2768 if ( priv->phyNum == 0 ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002769 if ( ( priv->duplex == TLAN_DUPLEX_FULL ) ||
2770 ( an_adv & an_lpa & 0x0040 ) ) {
2771 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL,
2772 MII_GC_AUTOENB | MII_GC_DUPLEX );
2773 pr_info("TLAN: Starting internal PHY with FULL-DUPLEX\n" );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002774 } else {
2775 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB );
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07002776 pr_info( "TLAN: Starting internal PHY with HALF-DUPLEX\n" );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777 }
2778 }
2779
2780 /* Wait for 100 ms. No reason in partiticular.
2781 */
2782 TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002783
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784} /* TLan_PhyFinishAutoNeg */
2785
2786#ifdef MONITOR
2787
2788 /*********************************************************************
2789 *
2790 * TLan_phyMonitor
2791 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002792 * Returns:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002793 * None
2794 *
2795 * Params:
2796 * dev The device structure of this device.
2797 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002798 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799 * This function monitors PHY condition by reading the status
2800 * register via the MII bus. This can be used to give info
2801 * about link changes (up/down), and possible switch to alternate
2802 * media.
2803 *
2804 * ******************************************************************/
2805
2806void TLan_PhyMonitor( struct net_device *dev )
2807{
2808 TLanPrivateInfo *priv = netdev_priv(dev);
2809 u16 phy;
2810 u16 phy_status;
2811
2812 phy = priv->phy[priv->phyNum];
2813
2814 /* Get PHY status register */
2815 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &phy_status );
2816
2817 /* Check if link has been lost */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002818 if (!(phy_status & MII_GS_LINK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819 if (priv->link) {
2820 priv->link = 0;
2821 printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name);
7d17c1d2005-05-12 19:45:25 -04002822 netif_carrier_off(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823 TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
2824 return;
2825 }
2826 }
2827
2828 /* Link restablished? */
2829 if ((phy_status & MII_GS_LINK) && !priv->link) {
2830 priv->link = 1;
2831 printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);
7d17c1d2005-05-12 19:45:25 -04002832 netif_carrier_on(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 }
2834
2835 /* Setup a new monitor */
2836 TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002837}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838
2839#endif /* MONITOR */
2840
2841
2842/*****************************************************************************
2843******************************************************************************
2844
2845 ThunderLAN Driver MII Routines
2846
2847 These routines are based on the information in Chap. 2 of the
2848 "ThunderLAN Programmer's Guide", pp. 15-24.
2849
2850******************************************************************************
2851*****************************************************************************/
2852
2853
2854 /***************************************************************
2855 * TLan_MiiReadReg
2856 *
2857 * Returns:
Joe Perches37fce432010-01-12 20:59:13 +00002858 * false if ack received ok
2859 * true if no ack received or other error
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 *
2861 * Parms:
2862 * dev The device structure containing
2863 * The io address and interrupt count
2864 * for this device.
2865 * phy The address of the PHY to be queried.
2866 * reg The register whose contents are to be
Matt Mackall4a4efbd2006-01-03 13:27:11 +01002867 * retrieved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 * val A pointer to a variable to store the
2869 * retrieved value.
2870 *
Matt Mackall4a4efbd2006-01-03 13:27:11 +01002871 * This function uses the TLAN's MII bus to retrieve the contents
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872 * of a given register on a PHY. It sends the appropriate info
2873 * and then reads the 16-bit register value from the MII bus via
2874 * the TLAN SIO register.
2875 *
2876 **************************************************************/
2877
Joe Perches37fce432010-01-12 20:59:13 +00002878static bool TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879{
2880 u8 nack;
2881 u16 sio, tmp;
2882 u32 i;
Joe Perches37fce432010-01-12 20:59:13 +00002883 bool err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884 int minten;
2885 TLanPrivateInfo *priv = netdev_priv(dev);
2886 unsigned long flags = 0;
2887
Joe Perches37fce432010-01-12 20:59:13 +00002888 err = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2890 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002891
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892 if (!in_irq())
2893 spin_lock_irqsave(&priv->lock, flags);
2894
2895 TLan_MiiSync(dev->base_addr);
2896
2897 minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );
2898 if ( minten )
2899 TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);
2900
2901 TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Start ( 01b ) */
2902 TLan_MiiSendData( dev->base_addr, 0x2, 2 ); /* Read ( 10b ) */
2903 TLan_MiiSendData( dev->base_addr, phy, 5 ); /* Device # */
2904 TLan_MiiSendData( dev->base_addr, reg, 5 ); /* Register # */
2905
2906
2907 TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); /* Change direction */
2908
2909 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Clock Idle bit */
2910 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2911 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Wait 300ns */
2912
2913 nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio); /* Check for ACK */
2914 TLan_SetBit(TLAN_NET_SIO_MCLK, sio); /* Finish ACK */
2915 if (nack) { /* No ACK, so fake it */
2916 for (i = 0; i < 16; i++) {
2917 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
2918 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2919 }
2920 tmp = 0xffff;
Joe Perches37fce432010-01-12 20:59:13 +00002921 err = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 } else { /* ACK, so read data */
2923 for (tmp = 0, i = 0x8000; i; i >>= 1) {
2924 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
2925 if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio))
2926 tmp |= i;
2927 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2928 }
2929 }
2930
2931
2932 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */
2933 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2934
2935 if ( minten )
2936 TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);
2937
2938 *val = tmp;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002939
Linus Torvalds1da177e2005-04-16 15:20:36 -07002940 if (!in_irq())
2941 spin_unlock_irqrestore(&priv->lock, flags);
2942
2943 return err;
2944
2945} /* TLan_MiiReadReg */
2946
2947
2948
2949
2950 /***************************************************************
2951 * TLan_MiiSendData
2952 *
2953 * Returns:
2954 * Nothing
2955 * Parms:
2956 * base_port The base IO port of the adapter in
2957 * question.
2958 * dev The address of the PHY to be queried.
2959 * data The value to be placed on the MII bus.
2960 * num_bits The number of bits in data that are to
2961 * be placed on the MII bus.
2962 *
2963 * This function sends on sequence of bits on the MII
2964 * configuration bus.
2965 *
2966 **************************************************************/
2967
Harvey Harrison98e0f522008-02-18 10:04:38 -08002968static void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002969{
2970 u16 sio;
2971 u32 i;
2972
2973 if ( num_bits == 0 )
2974 return;
2975
2976 outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );
2977 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
2978 TLan_SetBit( TLAN_NET_SIO_MTXEN, sio );
2979
2980 for ( i = ( 0x1 << ( num_bits - 1 ) ); i; i >>= 1 ) {
2981 TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
2982 (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
2983 if ( data & i )
2984 TLan_SetBit( TLAN_NET_SIO_MDATA, sio );
2985 else
2986 TLan_ClearBit( TLAN_NET_SIO_MDATA, sio );
2987 TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
2988 (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
2989 }
2990
2991} /* TLan_MiiSendData */
2992
2993
2994
2995
2996 /***************************************************************
2997 * TLan_MiiSync
2998 *
2999 * Returns:
3000 * Nothing
3001 * Parms:
3002 * base_port The base IO port of the adapter in
3003 * question.
3004 *
3005 * This functions syncs all PHYs in terms of the MII configuration
3006 * bus.
3007 *
3008 **************************************************************/
3009
Harvey Harrison98e0f522008-02-18 10:04:38 -08003010static void TLan_MiiSync( u16 base_port )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011{
3012 int i;
3013 u16 sio;
3014
3015 outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );
3016 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
3017
3018 TLan_ClearBit( TLAN_NET_SIO_MTXEN, sio );
3019 for ( i = 0; i < 32; i++ ) {
3020 TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
3021 TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
3022 }
3023
3024} /* TLan_MiiSync */
3025
3026
3027
3028
3029 /***************************************************************
3030 * TLan_MiiWriteReg
3031 *
3032 * Returns:
3033 * Nothing
3034 * Parms:
3035 * dev The device structure for the device
3036 * to write to.
3037 * phy The address of the PHY to be written to.
3038 * reg The register whose contents are to be
3039 * written.
3040 * val The value to be written to the register.
3041 *
3042 * This function uses the TLAN's MII bus to write the contents of a
3043 * given register on a PHY. It sends the appropriate info and then
3044 * writes the 16-bit register value from the MII configuration bus
3045 * via the TLAN SIO register.
3046 *
3047 **************************************************************/
3048
Harvey Harrison98e0f522008-02-18 10:04:38 -08003049static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003050{
3051 u16 sio;
3052 int minten;
3053 unsigned long flags = 0;
3054 TLanPrivateInfo *priv = netdev_priv(dev);
3055
3056 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
3057 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003058
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059 if (!in_irq())
3060 spin_lock_irqsave(&priv->lock, flags);
3061
3062 TLan_MiiSync( dev->base_addr );
3063
3064 minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );
3065 if ( minten )
3066 TLan_ClearBit( TLAN_NET_SIO_MINTEN, sio );
3067
3068 TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Start ( 01b ) */
3069 TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Write ( 01b ) */
3070 TLan_MiiSendData( dev->base_addr, phy, 5 ); /* Device # */
3071 TLan_MiiSendData( dev->base_addr, reg, 5 ); /* Register # */
3072
3073 TLan_MiiSendData( dev->base_addr, 0x2, 2 ); /* Send ACK */
3074 TLan_MiiSendData( dev->base_addr, val, 16 ); /* Send Data */
3075
3076 TLan_ClearBit( TLAN_NET_SIO_MCLK, sio ); /* Idle cycle */
3077 TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
3078
3079 if ( minten )
3080 TLan_SetBit( TLAN_NET_SIO_MINTEN, sio );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003081
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082 if (!in_irq())
3083 spin_unlock_irqrestore(&priv->lock, flags);
3084
3085} /* TLan_MiiWriteReg */
3086
3087
3088
3089
3090/*****************************************************************************
3091******************************************************************************
3092
3093 ThunderLAN Driver Eeprom routines
3094
3095 The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A
3096 EEPROM. These functions are based on information in Microchip's
3097 data sheet. I don't know how well this functions will work with
3098 other EEPROMs.
3099
3100******************************************************************************
3101*****************************************************************************/
3102
3103
3104 /***************************************************************
3105 * TLan_EeSendStart
3106 *
3107 * Returns:
3108 * Nothing
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003109 * Parms:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110 * io_base The IO port base address for the
3111 * TLAN device with the EEPROM to
3112 * use.
3113 *
3114 * This function sends a start cycle to an EEPROM attached
3115 * to a TLAN chip.
3116 *
3117 **************************************************************/
3118
Harvey Harrison98e0f522008-02-18 10:04:38 -08003119static void TLan_EeSendStart( u16 io_base )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120{
3121 u16 sio;
3122
3123 outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
3124 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3125
3126 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3127 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3128 TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
3129 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
3130 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3131
3132} /* TLan_EeSendStart */
3133
3134
3135
3136
3137 /***************************************************************
3138 * TLan_EeSendByte
3139 *
3140 * Returns:
3141 * If the correct ack was received, 0, otherwise 1
3142 * Parms: io_base The IO port base address for the
3143 * TLAN device with the EEPROM to
3144 * use.
3145 * data The 8 bits of information to
3146 * send to the EEPROM.
3147 * stop If TLAN_EEPROM_STOP is passed, a
3148 * stop cycle is sent after the
3149 * byte is sent after the ack is
3150 * read.
3151 *
3152 * This function sends a byte on the serial EEPROM line,
3153 * driving the clock to send each bit. The function then
3154 * reverses transmission direction and reads an acknowledge
3155 * bit.
3156 *
3157 **************************************************************/
3158
Harvey Harrison98e0f522008-02-18 10:04:38 -08003159static int TLan_EeSendByte( u16 io_base, u8 data, int stop )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160{
3161 int err;
3162 u8 place;
3163 u16 sio;
3164
3165 outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
3166 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3167
3168 /* Assume clock is low, tx is enabled; */
3169 for ( place = 0x80; place != 0; place >>= 1 ) {
3170 if ( place & data )
3171 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3172 else
3173 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
3174 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3175 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3176 }
3177 TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
3178 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3179 err = TLan_GetBit( TLAN_NET_SIO_EDATA, sio );
3180 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3181 TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
3182
3183 if ( ( ! err ) && stop ) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003184 /* STOP, raise data while clock is high */
3185 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3187 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3188 }
3189
3190 return ( err );
3191
3192} /* TLan_EeSendByte */
3193
3194
3195
3196
3197 /***************************************************************
3198 * TLan_EeReceiveByte
3199 *
3200 * Returns:
3201 * Nothing
3202 * Parms:
3203 * io_base The IO port base address for the
3204 * TLAN device with the EEPROM to
3205 * use.
3206 * data An address to a char to hold the
3207 * data sent from the EEPROM.
3208 * stop If TLAN_EEPROM_STOP is passed, a
3209 * stop cycle is sent after the
3210 * byte is received, and no ack is
3211 * sent.
3212 *
3213 * This function receives 8 bits of data from the EEPROM
3214 * over the serial link. It then sends and ack bit, or no
3215 * ack and a stop bit. This function is used to retrieve
3216 * data after the address of a byte in the EEPROM has been
3217 * sent.
3218 *
3219 **************************************************************/
3220
Harvey Harrison98e0f522008-02-18 10:04:38 -08003221static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003222{
3223 u8 place;
3224 u16 sio;
3225
3226 outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
3227 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3228 *data = 0;
3229
3230 /* Assume clock is low, tx is enabled; */
3231 TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
3232 for ( place = 0x80; place; place >>= 1 ) {
3233 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3234 if ( TLan_GetBit( TLAN_NET_SIO_EDATA, sio ) )
3235 *data |= place;
3236 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3237 }
3238
3239 TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
3240 if ( ! stop ) {
3241 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* Ack = 0 */
3242 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3243 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3244 } else {
3245 TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); /* No ack = 1 (?) */
3246 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3247 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003248 /* STOP, raise data while clock is high */
3249 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
Linus Torvalds1da177e2005-04-16 15:20:36 -07003250 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3251 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3252 }
3253
3254} /* TLan_EeReceiveByte */
3255
3256
3257
3258
3259 /***************************************************************
3260 * TLan_EeReadByte
3261 *
3262 * Returns:
3263 * No error = 0, else, the stage at which the error
3264 * occurred.
3265 * Parms:
3266 * io_base The IO port base address for the
3267 * TLAN device with the EEPROM to
3268 * use.
3269 * ee_addr The address of the byte in the
3270 * EEPROM whose contents are to be
3271 * retrieved.
3272 * data An address to a char to hold the
3273 * data obtained from the EEPROM.
3274 *
3275 * This function reads a byte of information from an byte
3276 * cell in the EEPROM.
3277 *
3278 **************************************************************/
3279
Harvey Harrison98e0f522008-02-18 10:04:38 -08003280static int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281{
3282 int err;
3283 TLanPrivateInfo *priv = netdev_priv(dev);
3284 unsigned long flags = 0;
3285 int ret=0;
3286
3287 spin_lock_irqsave(&priv->lock, flags);
3288
3289 TLan_EeSendStart( dev->base_addr );
3290 err = TLan_EeSendByte( dev->base_addr, 0xA0, TLAN_EEPROM_ACK );
3291 if (err)
3292 {
3293 ret=1;
3294 goto fail;
3295 }
3296 err = TLan_EeSendByte( dev->base_addr, ee_addr, TLAN_EEPROM_ACK );
3297 if (err)
3298 {
3299 ret=2;
3300 goto fail;
3301 }
3302 TLan_EeSendStart( dev->base_addr );
3303 err = TLan_EeSendByte( dev->base_addr, 0xA1, TLAN_EEPROM_ACK );
3304 if (err)
3305 {
3306 ret=3;
3307 goto fail;
3308 }
3309 TLan_EeReceiveByte( dev->base_addr, data, TLAN_EEPROM_STOP );
3310fail:
3311 spin_unlock_irqrestore(&priv->lock, flags);
3312
3313 return ret;
3314
3315} /* TLan_EeReadByte */
3316
3317
3318