blob: aee2a458adc3749066f4aed5877e86e3ac42535b [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 *
16 ** This file is best viewed/edited with columns>=132.
17 *
18 ** Useful (if not required) reading:
19 *
20 * Texas Instruments, ThunderLAN Programmer's Guide,
21 * TI Literature Number SPWU013A
22 * available in PDF format from www.ti.com
23 * Level One, LXT901 and LXT970 Data Sheets
24 * available in PDF format from www.level1.com
25 * National Semiconductor, DP83840A Data Sheet
26 * available in PDF format from www.national.com
27 * Microchip Technology, 24C01A/02A/04A Data Sheet
28 * available in PDF format from www.microchip.com
29 *
30 * Change History
31 *
32 * Tigran Aivazian <tigran@sco.com>: TLan_PciProbe() now uses
33 * new PCI BIOS interface.
34 * Alan Cox <alan@redhat.com>: Fixed the out of memory
35 * handling.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040036 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 * Torben Mathiasen <torben.mathiasen@compaq.com> New Maintainer!
38 *
39 * v1.1 Dec 20, 1999 - Removed linux version checking
Jeff Garzik6aa20a22006-09-13 13:24:59 -040040 * Patch from Tigran Aivazian.
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 * - v1.1 includes Alan's SMP updates.
42 * - We still have problems on SMP though,
Jeff Garzik6aa20a22006-09-13 13:24:59 -040043 * but I'm looking into that.
44 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 * v1.2 Jan 02, 2000 - Hopefully fixed the SMP deadlock.
46 * - Removed dependency of HZ being 100.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040047 * - We now allow higher priority timers to
Linus Torvalds1da177e2005-04-16 15:20:36 -070048 * overwrite timers like TLAN_TIMER_ACTIVITY
49 * Patch from John Cagle <john.cagle@compaq.com>.
50 * - Fixed a few compiler warnings.
51 *
52 * v1.3 Feb 04, 2000 - Fixed the remaining HZ issues.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040053 * - Removed call to pci_present().
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 * - Removed SA_INTERRUPT flag from irq handler.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040055 * - Added __init and __initdata to reduce resisdent
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 * code size.
57 * - Driver now uses module_init/module_exit.
58 * - Rewrote init_module and tlan_probe to
59 * share a lot more code. We now use tlan_probe
60 * with builtin and module driver.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040061 * - Driver ported to new net API.
62 * - tlan.txt has been reworked to reflect current
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 * driver (almost)
64 * - Other minor stuff
65 *
66 * v1.4 Feb 10, 2000 - Updated with more changes required after Dave's
67 * network cleanup in 2.3.43pre7 (Tigran & myself)
68 * - Minor stuff.
69 *
70 * v1.5 March 22, 2000 - Fixed another timer bug that would hang the driver
71 * if no cable/link were present.
72 * - Cosmetic changes.
73 * - TODO: Port completely to new PCI/DMA API
74 * Auto-Neg fallback.
75 *
76 * v1.6 April 04, 2000 - Fixed driver support for kernel-parameters. Haven't
Jeff Garzik6aa20a22006-09-13 13:24:59 -040077 * tested it though, as the kernel support is currently
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 * broken (2.3.99p4p3).
79 * - Updated tlan.txt accordingly.
80 * - Adjusted minimum/maximum frame length.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040081 * - There is now a TLAN website up at
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 * http://tlan.kernel.dk
83 *
84 * v1.7 April 07, 2000 - Started to implement custom ioctls. Driver now
85 * reports PHY information when used with Donald
86 * Beckers userspace MII diagnostics utility.
87 *
88 * v1.8 April 23, 2000 - Fixed support for forced speed/duplex settings.
89 * - Added link information to Auto-Neg and forced
90 * modes. When NIC operates with auto-neg the driver
91 * will report Link speed & duplex modes as well as
92 * link partner abilities. When forced link is used,
93 * the driver will report status of the established
94 * link.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040095 * Please read tlan.txt for additional information.
96 * - Removed call to check_region(), and used
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 * return value of request_region() instead.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040098 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 * v1.8a May 28, 2000 - Minor updates.
100 *
101 * v1.9 July 25, 2000 - Fixed a few remaining Full-Duplex issues.
102 * - Updated with timer fixes from Andrew Morton.
103 * - Fixed module race in TLan_Open.
104 * - Added routine to monitor PHY status.
105 * - Added activity led support for Proliant devices.
106 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400107 * v1.10 Aug 30, 2000 - Added support for EISA based tlan controllers
108 * like the Compaq NetFlex3/E.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 * - Rewrote tlan_probe to better handle multiple
110 * bus probes. Probing and device setup is now
111 * done through TLan_Probe and TLan_init_one. Actual
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400112 * hardware probe is done with kernel API and
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113 * TLan_EisaProbe.
114 * - Adjusted debug information for probing.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400115 * - Fixed bug that would cause general debug information
116 * to be printed after driver removal.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 * - Added transmit timeout handling.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400118 * - Fixed OOM return values in tlan_probe.
119 * - Fixed possible mem leak in tlan_exit
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 * (now tlan_remove_one).
121 * - Fixed timer bug in TLan_phyMonitor.
122 * - This driver version is alpha quality, please
123 * send me any bug issues you may encounter.
124 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400125 * v1.11 Aug 31, 2000 - Do not try to register irq 0 if no irq line was
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 * set for EISA cards.
127 * - Added support for NetFlex3/E with nibble-rate
128 * 10Base-T PHY. This is untestet as I haven't got
129 * one of these cards.
130 * - Fixed timer being added twice.
131 * - Disabled PhyMonitoring by default as this is
132 * work in progress. Define MONITOR to enable it.
133 * - Now we don't display link info with PHYs that
134 * doesn't support it (level1).
135 * - Incresed tx_timeout beacuse of auto-neg.
136 * - Adjusted timers for forced speeds.
137 *
138 * v1.12 Oct 12, 2000 - Minor fixes (memleak, init, etc.)
139 *
140 * v1.13 Nov 28, 2000 - Stop flooding console with auto-neg issues
141 * when link can't be established.
142 * - Added the bbuf option as a kernel parameter.
143 * - Fixed ioaddr probe bug.
144 * - Fixed stupid deadlock with MII interrupts.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400145 * - Added support for speed/duplex selection with
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 * multiple nics.
147 * - Added partly fix for TX Channel lockup with
148 * TLAN v1.0 silicon. This needs to be investigated
149 * further.
150 *
151 * v1.14 Dec 16, 2000 - Added support for servicing multiple frames per.
152 * interrupt. Thanks goes to
153 * Adam Keys <adam@ti.com>
154 * Denis Beaudoin <dbeaudoin@ti.com>
155 * for providing the patch.
156 * - Fixed auto-neg output when using multiple
157 * adapters.
158 * - Converted to use new taskq interface.
159 *
160 * v1.14a Jan 6, 2001 - Minor adjustments (spinlocks, etc.)
161 *
162 * Samuel Chessman <chessman@tux.org> New Maintainer!
163 *
164 * v1.15 Apr 4, 2002 - Correct operation when aui=1 to be
165 * 10T half duplex no loopback
166 * Thanks to Gunnar Eikman
167 *******************************************************************************/
168
169#include <linux/module.h>
170#include <linux/init.h>
171#include <linux/ioport.h>
172#include <linux/eisa.h>
173#include <linux/pci.h>
Domen Puncer1e7f0bd2005-06-26 18:22:14 -0400174#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175#include <linux/netdevice.h>
176#include <linux/etherdevice.h>
177#include <linux/delay.h>
178#include <linux/spinlock.h>
179#include <linux/workqueue.h>
180#include <linux/mii.h>
181
182#include "tlan.h"
183
184typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 );
185
186
187/* For removing EISA devices */
188static struct net_device *TLan_Eisa_Devices;
189
190static int TLanDevicesInstalled;
191
192/* Set speed, duplex and aui settings */
193static int aui[MAX_TLAN_BOARDS];
194static int duplex[MAX_TLAN_BOARDS];
195static int speed[MAX_TLAN_BOARDS];
196static int boards_found;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -0700197module_param_array(aui, int, NULL, 0);
198module_param_array(duplex, int, NULL, 0);
199module_param_array(speed, int, NULL, 0);
200MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
201MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
202MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
205MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
206MODULE_LICENSE("GPL");
207
208
209/* Define this to enable Link beat monitoring */
210#undef MONITOR
211
212/* Turn on debugging. See Documentation/networking/tlan.txt for details */
213static int debug;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -0700214module_param(debug, int, 0);
215MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216
217static int bbuf;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -0700218module_param(bbuf, int, 0);
219MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)");
220
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221static char TLanSignature[] = "TLAN";
222static const char tlan_banner[] = "ThunderLAN driver v1.15\n";
223static 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 },
239 { "Compaq NetFlex-3/P", TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
240 { "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
241 { "Compaq Netelligent Integrated 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
242 { "Compaq Netelligent Dual 10/100 TX PCI UTP", TLAN_ADAPTER_NONE, 0x83 },
243 { "Compaq Netelligent 10/100 TX Embedded UTP", TLAN_ADAPTER_NONE, 0x83 },
244 { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
245 { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xF8 },
246 { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xF8 },
247 { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
248 { "Compaq Netelligent 10 T/2 PCI UTP/Coax", TLAN_ADAPTER_NONE, 0x83 },
249 { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400250 TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
252};
253
254static struct pci_device_id tlan_pci_tbl[] = {
255 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
256 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
257 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
258 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
259 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3I,
260 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
261 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_THUNDER,
262 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
263 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3B,
264 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
265 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100PI,
266 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
267 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100D,
268 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
269 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100I,
270 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
271 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183,
272 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
273 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325,
274 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
275 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
276 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
277 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,
278 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
279 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2,
280 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
281 { 0,}
282};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400283MODULE_DEVICE_TABLE(pci, tlan_pci_tbl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284
285static void TLan_EisaProbe( void );
286static void TLan_Eisa_Cleanup( void );
287static int TLan_Init( struct net_device * );
288static int TLan_Open( struct net_device *dev );
289static int TLan_StartTx( struct sk_buff *, struct net_device *);
David Howells7d12e782006-10-05 14:55:46 +0100290static irqreturn_t TLan_HandleInterrupt( int, void *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291static int TLan_Close( struct net_device *);
292static struct net_device_stats *TLan_GetStats( struct net_device *);
293static void TLan_SetMulticastList( struct net_device *);
294static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd);
295static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
296static void TLan_tx_timeout( struct net_device *dev);
David Howellsc4028952006-11-22 14:57:56 +0000297static void TLan_tx_timeout_work(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
299
300static u32 TLan_HandleInvalid( struct net_device *, u16 );
301static u32 TLan_HandleTxEOF( struct net_device *, u16 );
302static u32 TLan_HandleStatOverflow( struct net_device *, u16 );
303static u32 TLan_HandleRxEOF( struct net_device *, u16 );
304static u32 TLan_HandleDummy( struct net_device *, u16 );
305static u32 TLan_HandleTxEOC( struct net_device *, u16 );
306static u32 TLan_HandleStatusCheck( struct net_device *, u16 );
307static u32 TLan_HandleRxEOC( struct net_device *, u16 );
308
309static void TLan_Timer( unsigned long );
310
311static void TLan_ResetLists( struct net_device * );
312static void TLan_FreeLists( struct net_device * );
313static void TLan_PrintDio( u16 );
314static void TLan_PrintList( TLanList *, char *, int );
315static void TLan_ReadAndClearStats( struct net_device *, int );
316static void TLan_ResetAdapter( struct net_device * );
317static void TLan_FinishReset( struct net_device * );
318static void TLan_SetMac( struct net_device *, int areg, char *mac );
319
320static void TLan_PhyPrint( struct net_device * );
321static void TLan_PhyDetect( struct net_device * );
322static void TLan_PhyPowerDown( struct net_device * );
323static void TLan_PhyPowerUp( struct net_device * );
324static void TLan_PhyReset( struct net_device * );
325static void TLan_PhyStartLink( struct net_device * );
326static void TLan_PhyFinishAutoNeg( struct net_device * );
327#ifdef MONITOR
328static void TLan_PhyMonitor( struct net_device * );
329#endif
330
331/*
332static int TLan_PhyNop( struct net_device * );
333static int TLan_PhyInternalCheck( struct net_device * );
334static int TLan_PhyInternalService( struct net_device * );
335static int TLan_PhyDp83840aCheck( struct net_device * );
336*/
337
338static int TLan_MiiReadReg( struct net_device *, u16, u16, u16 * );
339static void TLan_MiiSendData( u16, u32, unsigned );
340static void TLan_MiiSync( u16 );
341static void TLan_MiiWriteReg( struct net_device *, u16, u16, u16 );
342
343static void TLan_EeSendStart( u16 );
344static int TLan_EeSendByte( u16, u8, int );
345static void TLan_EeReceiveByte( u16, u8 *, int );
346static int TLan_EeReadByte( struct net_device *, u8, u8 * );
347
348
Stephen Hemminger93e16842008-05-30 09:49:55 -0700349static inline void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350TLan_StoreSKB( struct tlan_list_tag *tag, struct sk_buff *skb)
351{
352 unsigned long addr = (unsigned long)skb;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700353 tag->buffer[9].address = addr;
354 tag->buffer[8].address = upper_32_bits(addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355}
356
Stephen Hemminger93e16842008-05-30 09:49:55 -0700357static inline struct sk_buff *
358TLan_GetSKB( const struct tlan_list_tag *tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359{
Stephen Hemminger93e16842008-05-30 09:49:55 -0700360 unsigned long addr;
361
362 addr = tag->buffer[8].address;
363 addr |= (tag->buffer[9].address << 16) << 16;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 return (struct sk_buff *) addr;
365}
366
367
368static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = {
369 TLan_HandleInvalid,
370 TLan_HandleTxEOF,
371 TLan_HandleStatOverflow,
372 TLan_HandleRxEOF,
373 TLan_HandleDummy,
374 TLan_HandleTxEOC,
375 TLan_HandleStatusCheck,
376 TLan_HandleRxEOC
377};
378
379static inline void
380TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type )
381{
382 TLanPrivateInfo *priv = netdev_priv(dev);
383 unsigned long flags = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400384
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 if (!in_irq())
386 spin_lock_irqsave(&priv->lock, flags);
387 if ( priv->timer.function != NULL &&
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400388 priv->timerType != TLAN_TIMER_ACTIVITY ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 if (!in_irq())
390 spin_unlock_irqrestore(&priv->lock, flags);
391 return;
392 }
393 priv->timer.function = &TLan_Timer;
394 if (!in_irq())
395 spin_unlock_irqrestore(&priv->lock, flags);
396
397 priv->timer.data = (unsigned long) dev;
398 priv->timerSetAt = jiffies;
399 priv->timerType = type;
400 mod_timer(&priv->timer, jiffies + ticks);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400401
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402} /* TLan_SetTimer */
403
404
405/*****************************************************************************
406******************************************************************************
407
408 ThunderLAN Driver Primary Functions
409
410 These functions are more or less common to all Linux network drivers.
411
412******************************************************************************
413*****************************************************************************/
414
415
416
417
418
419 /***************************************************************
420 * tlan_remove_one
421 *
422 * Returns:
423 * Nothing
424 * Parms:
425 * None
426 *
427 * Goes through the TLanDevices list and frees the device
428 * structs and memory associated with each device (lists
429 * and buffers). It also ureserves the IO port regions
430 * associated with this device.
431 *
432 **************************************************************/
433
434
435static void __devexit tlan_remove_one( struct pci_dev *pdev)
436{
437 struct net_device *dev = pci_get_drvdata( pdev );
438 TLanPrivateInfo *priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400439
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 unregister_netdev( dev );
441
442 if ( priv->dmaStorage ) {
443 pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA );
444 }
445
446#ifdef CONFIG_PCI
447 pci_release_regions(pdev);
448#endif
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400449
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 free_netdev( dev );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400451
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 pci_set_drvdata( pdev, NULL );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400453}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454
455static struct pci_driver tlan_driver = {
456 .name = "tlan",
457 .id_table = tlan_pci_tbl,
458 .probe = tlan_init_one,
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400459 .remove = __devexit_p(tlan_remove_one),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460};
461
462static int __init tlan_probe(void)
463{
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800464 int rc = -ENODEV;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400465
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 printk(KERN_INFO "%s", tlan_banner);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400467
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400469
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 /* Use new style PCI probing. Now the kernel will
471 do most of this for us */
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800472 rc = pci_register_driver(&tlan_driver);
473
474 if (rc != 0) {
475 printk(KERN_ERR "TLAN: Could not register pci driver.\n");
476 goto err_out_pci_free;
477 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478
479 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
480 TLan_EisaProbe();
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400481
482 printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d EISA: %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 TLanDevicesInstalled, TLanDevicesInstalled == 1 ? "" : "s",
484 tlan_have_pci, tlan_have_eisa);
485
486 if (TLanDevicesInstalled == 0) {
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800487 rc = -ENODEV;
488 goto err_out_pci_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 }
490 return 0;
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800491
492err_out_pci_unreg:
493 pci_unregister_driver(&tlan_driver);
494err_out_pci_free:
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800495 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400497
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498
499static int __devinit tlan_init_one( struct pci_dev *pdev,
500 const struct pci_device_id *ent)
501{
502 return TLan_probe1( pdev, -1, -1, 0, ent);
503}
504
505
506/*
507 ***************************************************************
508 * tlan_probe1
509 *
510 * Returns:
511 * 0 on success, error code on error
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400512 * Parms:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 * none
514 *
515 * The name is lower case to fit in with all the rest of
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400516 * the netcard_probe names. This function looks for
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 * another TLan based adapter, setting it up with the
518 * allocated device struct if one is found.
519 * tlan_probe has been ported to the new net API and
520 * now allocates its own device structure. This function
521 * is also used by modules.
522 *
523 **************************************************************/
524
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400525static int __devinit TLan_probe1(struct pci_dev *pdev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 long ioaddr, int irq, int rev, const struct pci_device_id *ent )
527{
528
529 struct net_device *dev;
530 TLanPrivateInfo *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 u16 device_id;
532 int reg, rc = -ENODEV;
533
Adrian Bunkad9f6712006-02-05 00:37:47 +0100534#ifdef CONFIG_PCI
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 if (pdev) {
536 rc = pci_enable_device(pdev);
537 if (rc)
538 return rc;
539
540 rc = pci_request_regions(pdev, TLanSignature);
541 if (rc) {
542 printk(KERN_ERR "TLAN: Could not reserve IO regions\n");
543 goto err_out;
544 }
545 }
Adrian Bunkad9f6712006-02-05 00:37:47 +0100546#endif /* CONFIG_PCI */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
548 dev = alloc_etherdev(sizeof(TLanPrivateInfo));
549 if (dev == NULL) {
550 printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");
551 rc = -ENOMEM;
552 goto err_out_regions;
553 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 SET_NETDEV_DEV(dev, &pdev->dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400555
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 priv = netdev_priv(dev);
557
558 priv->pciDev = pdev;
David Howellsc4028952006-11-22 14:57:56 +0000559 priv->dev = dev;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400560
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 /* Is this a PCI device? */
562 if (pdev) {
563 u32 pci_io_base = 0;
564
565 priv->adapter = &board_info[ent->driver_data];
566
Domen Puncer1e7f0bd2005-06-26 18:22:14 -0400567 rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 if (rc) {
569 printk(KERN_ERR "TLAN: No suitable PCI mapping available.\n");
570 goto err_out_free_dev;
571 }
572
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 for ( reg= 0; reg <= 5; reg ++ ) {
574 if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
575 pci_io_base = pci_resource_start(pdev, reg);
576 TLAN_DBG( TLAN_DEBUG_GNRL, "IO mapping is available at %x.\n",
577 pci_io_base);
578 break;
579 }
580 }
581 if (!pci_io_base) {
582 printk(KERN_ERR "TLAN: No IO mappings available\n");
583 rc = -EIO;
584 goto err_out_free_dev;
585 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400586
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 dev->base_addr = pci_io_base;
588 dev->irq = pdev->irq;
Auke Kok44c10132007-06-08 15:46:36 -0700589 priv->adapterRev = pdev->revision;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 pci_set_master(pdev);
591 pci_set_drvdata(pdev, dev);
592
593 } else { /* EISA card */
594 /* This is a hack. We need to know which board structure
595 * is suited for this adapter */
596 device_id = inw(ioaddr + EISA_ID2);
597 priv->is_eisa = 1;
598 if (device_id == 0x20F1) {
599 priv->adapter = &board_info[13]; /* NetFlex-3/E */
600 priv->adapterRev = 23; /* TLAN 2.3 */
601 } else {
602 priv->adapter = &board_info[14];
603 priv->adapterRev = 10; /* TLAN 1.0 */
604 }
605 dev->base_addr = ioaddr;
606 dev->irq = irq;
607 }
608
609 /* Kernel parameters */
610 if (dev->mem_start) {
611 priv->aui = dev->mem_start & 0x01;
612 priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0 : (dev->mem_start & 0x06) >> 1;
613 priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400614
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 if (priv->speed == 0x1) {
616 priv->speed = TLAN_SPEED_10;
617 } else if (priv->speed == 0x2) {
618 priv->speed = TLAN_SPEED_100;
619 }
620 debug = priv->debug = dev->mem_end;
621 } else {
622 priv->aui = aui[boards_found];
623 priv->speed = speed[boards_found];
624 priv->duplex = duplex[boards_found];
625 priv->debug = debug;
626 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400627
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 /* This will be used when we get an adapter error from
629 * within our irq handler */
David Howellsc4028952006-11-22 14:57:56 +0000630 INIT_WORK(&priv->tlan_tqueue, TLan_tx_timeout_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631
632 spin_lock_init(&priv->lock);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400633
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 rc = TLan_Init(dev);
635 if (rc) {
636 printk(KERN_ERR "TLAN: Could not set up device.\n");
637 goto err_out_free_dev;
638 }
639
640 rc = register_netdev(dev);
641 if (rc) {
642 printk(KERN_ERR "TLAN: Could not register device.\n");
643 goto err_out_uninit;
644 }
645
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400646
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647 TLanDevicesInstalled++;
648 boards_found++;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400649
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 /* pdev is NULL if this is an EISA device */
651 if (pdev)
652 tlan_have_pci++;
653 else {
654 priv->nextDevice = TLan_Eisa_Devices;
655 TLan_Eisa_Devices = dev;
656 tlan_have_eisa++;
657 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400658
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659 printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n",
660 dev->name,
661 (int) dev->irq,
662 (int) dev->base_addr,
663 priv->adapter->deviceLabel,
664 priv->adapterRev);
665 return 0;
666
667err_out_uninit:
668 pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage,
669 priv->dmaStorageDMA );
670err_out_free_dev:
671 free_netdev(dev);
672err_out_regions:
673#ifdef CONFIG_PCI
674 if (pdev)
675 pci_release_regions(pdev);
676#endif
677err_out:
678 if (pdev)
679 pci_disable_device(pdev);
680 return rc;
681}
682
683
684static void TLan_Eisa_Cleanup(void)
685{
686 struct net_device *dev;
687 TLanPrivateInfo *priv;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400688
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 while( tlan_have_eisa ) {
690 dev = TLan_Eisa_Devices;
691 priv = netdev_priv(dev);
692 if (priv->dmaStorage) {
693 pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA );
694 }
695 release_region( dev->base_addr, 0x10);
696 unregister_netdev( dev );
697 TLan_Eisa_Devices = priv->nextDevice;
698 free_netdev( dev );
699 tlan_have_eisa--;
700 }
701}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400702
703
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704static void __exit tlan_exit(void)
705{
706 pci_unregister_driver(&tlan_driver);
707
708 if (tlan_have_eisa)
709 TLan_Eisa_Cleanup();
710
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711}
712
713
714/* Module loading/unloading */
715module_init(tlan_probe);
716module_exit(tlan_exit);
717
718
719
720 /**************************************************************
721 * TLan_EisaProbe
722 *
723 * Returns: 0 on success, 1 otherwise
724 *
725 * Parms: None
726 *
727 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400728 * This functions probes for EISA devices and calls
729 * TLan_probe1 when one is found.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 *
731 *************************************************************/
732
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400733static void __init TLan_EisaProbe (void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734{
735 long ioaddr;
736 int rc = -ENODEV;
737 int irq;
738 u16 device_id;
739
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400740 if (!EISA_bus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
742 return;
743 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400744
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 /* Loop through all slots of the EISA bus */
746 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400747
748 TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC80, inw(ioaddr + EISA_ID));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2));
750
751
752 TLAN_DBG(TLAN_DEBUG_PROBE, "Probing for EISA adapter at IO: 0x%4x : ",
753 (int) ioaddr);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400754 if (request_region(ioaddr, 0x10, TLanSignature) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 goto out;
756
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400757 if (inw(ioaddr + EISA_ID) != 0x110E) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 release_region(ioaddr, 0x10);
759 goto out;
760 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400761
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 device_id = inw(ioaddr + EISA_ID2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400763 if (device_id != 0x20F1 && device_id != 0x40F1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 release_region (ioaddr, 0x10);
765 goto out;
766 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400767
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 if (inb(ioaddr + EISA_CR) != 0x1) { /* Check if adapter is enabled */
769 release_region (ioaddr, 0x10);
770 goto out2;
771 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400772
773 if (debug == 0x10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 printk("Found one\n");
775
776
777 /* Get irq from board */
778 switch (inb(ioaddr + 0xCC0)) {
779 case(0x10):
780 irq=5;
781 break;
782 case(0x20):
783 irq=9;
784 break;
785 case(0x40):
786 irq=10;
787 break;
788 case(0x80):
789 irq=11;
790 break;
791 default:
792 goto out;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400793 }
794
795
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 /* Setup the newly found eisa adapter */
797 rc = TLan_probe1( NULL, ioaddr, irq,
798 12, NULL);
799 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400800
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 out:
802 if (debug == 0x10)
803 printk("None found\n");
804 continue;
805
806 out2: if (debug == 0x10)
807 printk("Card found but it is not enabled, skipping\n");
808 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400809
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 }
811
812} /* TLan_EisaProbe */
813
814#ifdef CONFIG_NET_POLL_CONTROLLER
815static void TLan_Poll(struct net_device *dev)
816{
817 disable_irq(dev->irq);
David Howells7d12e782006-10-05 14:55:46 +0100818 TLan_HandleInterrupt(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 enable_irq(dev->irq);
820}
821#endif
822
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400823
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
825
826 /***************************************************************
827 * TLan_Init
828 *
829 * Returns:
830 * 0 on success, error code otherwise.
831 * Parms:
832 * dev The structure of the device to be
833 * init'ed.
834 *
835 * This function completes the initialization of the
836 * device structure and driver. It reserves the IO
837 * addresses, allocates memory for the lists and bounce
838 * buffers, retrieves the MAC address from the eeprom
839 * and assignes the device's methods.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400840 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 **************************************************************/
842
843static int TLan_Init( struct net_device *dev )
844{
845 int dma_size;
846 int err;
847 int i;
848 TLanPrivateInfo *priv;
849
850 priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400851
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 if ( bbuf ) {
853 dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
854 * ( sizeof(TLanList) + TLAN_MAX_FRAME_SIZE );
855 } else {
856 dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
857 * ( sizeof(TLanList) );
858 }
Stephen Hemminger93e16842008-05-30 09:49:55 -0700859 priv->dmaStorage = pci_alloc_consistent(priv->pciDev,
860 dma_size, &priv->dmaStorageDMA);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 priv->dmaSize = dma_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400862
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863 if ( priv->dmaStorage == NULL ) {
864 printk(KERN_ERR "TLAN: Could not allocate lists and buffers for %s.\n",
865 dev->name );
866 return -ENOMEM;
867 }
868 memset( priv->dmaStorage, 0, dma_size );
Stephen Hemminger93e16842008-05-30 09:49:55 -0700869 priv->rxList = (TLanList *) ALIGN((unsigned long)priv->dmaStorage, 8);
870 priv->rxListDMA = ALIGN(priv->dmaStorageDMA, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 priv->txList = priv->rxList + TLAN_NUM_RX_LISTS;
872 priv->txListDMA = priv->rxListDMA + sizeof(TLanList) * TLAN_NUM_RX_LISTS;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 if ( bbuf ) {
875 priv->rxBuffer = (u8 *) ( priv->txList + TLAN_NUM_TX_LISTS );
876 priv->rxBufferDMA =priv->txListDMA + sizeof(TLanList) * TLAN_NUM_TX_LISTS;
877 priv->txBuffer = priv->rxBuffer + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
878 priv->txBufferDMA = priv->rxBufferDMA + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
879 }
880
881 err = 0;
882 for ( i = 0; i < 6 ; i++ )
883 err |= TLan_EeReadByte( dev,
884 (u8) priv->adapter->addrOfs + i,
885 (u8 *) &dev->dev_addr[i] );
886 if ( err ) {
887 printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n",
888 dev->name,
889 err );
890 }
891 dev->addr_len = 6;
892
893 netif_carrier_off(dev);
894
895 /* Device methods */
896 dev->open = &TLan_Open;
897 dev->hard_start_xmit = &TLan_StartTx;
898 dev->stop = &TLan_Close;
899 dev->get_stats = &TLan_GetStats;
900 dev->set_multicast_list = &TLan_SetMulticastList;
901 dev->do_ioctl = &TLan_ioctl;
902#ifdef CONFIG_NET_POLL_CONTROLLER
903 dev->poll_controller = &TLan_Poll;
904#endif
905 dev->tx_timeout = &TLan_tx_timeout;
906 dev->watchdog_timeo = TX_TIMEOUT;
907
908 return 0;
909
910} /* TLan_Init */
911
912
913
914
915 /***************************************************************
916 * TLan_Open
917 *
918 * Returns:
919 * 0 on success, error code otherwise.
920 * Parms:
921 * dev Structure of device to be opened.
922 *
923 * This routine puts the driver and TLAN adapter in a
924 * state where it is ready to send and receive packets.
925 * It allocates the IRQ, resets and brings the adapter
926 * out of reset, and allows interrupts. It also delays
927 * the startup for autonegotiation or sends a Rx GO
928 * command to the adapter, as appropriate.
929 *
930 **************************************************************/
931
932static int TLan_Open( struct net_device *dev )
933{
934 TLanPrivateInfo *priv = netdev_priv(dev);
935 int err;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400936
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION );
Thomas Gleixner1fb9df52006-07-01 19:29:39 -0700938 err = request_irq( dev->irq, TLan_HandleInterrupt, IRQF_SHARED, TLanSignature, dev );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400939
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 if ( err ) {
941 printk(KERN_ERR "TLAN: Cannot open %s because IRQ %d is already in use.\n", dev->name, dev->irq );
942 return err;
943 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400944
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 init_timer(&priv->timer);
946 netif_start_queue(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400947
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948 /* NOTE: It might not be necessary to read the stats before a
949 reset if you don't care what the values are.
950 */
951 TLan_ResetLists( dev );
952 TLan_ReadAndClearStats( dev, TLAN_IGNORE );
953 TLan_ResetAdapter( dev );
954
955 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n", dev->name, priv->tlanRev );
956
957 return 0;
958
959} /* TLan_Open */
960
961
962
963 /**************************************************************
964 * TLan_ioctl
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400965 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 * Returns:
967 * 0 on success, error code otherwise
968 * Params:
969 * dev structure of device to receive ioctl.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400970 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971 * rq ifreq structure to hold userspace data.
972 *
973 * cmd ioctl command.
974 *
975 *
976 *************************************************************/
977
978static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
979{
980 TLanPrivateInfo *priv = netdev_priv(dev);
981 struct mii_ioctl_data *data = if_mii(rq);
982 u32 phy = priv->phy[priv->phyNum];
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400983
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 if (!priv->phyOnline)
985 return -EAGAIN;
986
987 switch(cmd) {
988 case SIOCGMIIPHY: /* Get address of MII PHY in use. */
989 data->phy_id = phy;
990
991
992 case SIOCGMIIREG: /* Read MII PHY register. */
993 TLan_MiiReadReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, &data->val_out);
994 return 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400995
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996
997 case SIOCSMIIREG: /* Write MII PHY register. */
998 if (!capable(CAP_NET_ADMIN))
999 return -EPERM;
1000 TLan_MiiWriteReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
1001 return 0;
1002 default:
1003 return -EOPNOTSUPP;
1004 }
1005} /* tlan_ioctl */
1006
1007
1008 /***************************************************************
1009 * TLan_tx_timeout
1010 *
1011 * Returns: nothing
1012 *
1013 * Params:
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001014 * dev structure of device which timed out
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 * during transmit.
1016 *
1017 **************************************************************/
1018
1019static void TLan_tx_timeout(struct net_device *dev)
1020{
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001021
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001023
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 /* Ok so we timed out, lets see what we can do about it...*/
1025 TLan_FreeLists( dev );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001026 TLan_ResetLists( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 TLan_ReadAndClearStats( dev, TLAN_IGNORE );
1028 TLan_ResetAdapter( dev );
1029 dev->trans_start = jiffies;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001030 netif_wake_queue( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031
1032}
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001033
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034
David Howellsc4028952006-11-22 14:57:56 +00001035 /***************************************************************
1036 * TLan_tx_timeout_work
1037 *
1038 * Returns: nothing
1039 *
1040 * Params:
1041 * work work item of device which timed out
1042 *
1043 **************************************************************/
1044
1045static void TLan_tx_timeout_work(struct work_struct *work)
1046{
1047 TLanPrivateInfo *priv =
1048 container_of(work, TLanPrivateInfo, tlan_tqueue);
1049
1050 TLan_tx_timeout(priv->dev);
1051}
1052
1053
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
1055 /***************************************************************
1056 * TLan_StartTx
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001057 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 * Returns:
1059 * 0 on success, non-zero on failure.
1060 * Parms:
1061 * skb A pointer to the sk_buff containing the
1062 * frame to be sent.
1063 * dev The device to send the data on.
1064 *
1065 * This function adds a frame to the Tx list to be sent
1066 * ASAP. First it verifies that the adapter is ready and
1067 * there is room in the queue. Then it sets up the next
1068 * available list, copies the frame to the corresponding
1069 * buffer. If the adapter Tx channel is idle, it gives
1070 * the adapter a Tx Go command on the list, otherwise it
1071 * sets the forward address of the previous list to point
1072 * to this one. Then it frees the sk_buff.
1073 *
1074 **************************************************************/
1075
1076static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
1077{
1078 TLanPrivateInfo *priv = netdev_priv(dev);
1079 TLanList *tail_list;
1080 dma_addr_t tail_list_phys;
1081 u8 *tail_buffer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 unsigned long flags;
1083
1084 if ( ! priv->phyOnline ) {
1085 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n", dev->name );
1086 dev_kfree_skb_any(skb);
1087 return 0;
1088 }
1089
Stephen Hemminger41873e92008-05-30 09:49:52 -07001090 if (skb_padto(skb, TLAN_MIN_FRAME_SIZE))
1091 return 0;
1092
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 tail_list = priv->txList + priv->txTail;
1094 tail_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txTail;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001095
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 if ( tail_list->cStat != TLAN_CSTAT_UNUSED ) {
1097 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s is busy (Head=%d Tail=%d)\n", dev->name, priv->txHead, priv->txTail );
1098 netif_stop_queue(dev);
1099 priv->txBusyCount++;
1100 return 1;
1101 }
1102
1103 tail_list->forward = 0;
1104
1105 if ( bbuf ) {
1106 tail_buffer = priv->txBuffer + ( priv->txTail * TLAN_MAX_FRAME_SIZE );
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03001107 skb_copy_from_linear_data(skb, tail_buffer, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108 } else {
1109 tail_list->buffer[0].address = pci_map_single(priv->pciDev, skb->data, skb->len, PCI_DMA_TODEVICE);
1110 TLan_StoreSKB(tail_list, skb);
1111 }
1112
Stephen Hemminger41873e92008-05-30 09:49:52 -07001113 tail_list->frameSize = (u16) skb->len;
1114 tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) skb->len;
1115 tail_list->buffer[1].count = 0;
1116 tail_list->buffer[1].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
1118 spin_lock_irqsave(&priv->lock, flags);
1119 tail_list->cStat = TLAN_CSTAT_READY;
1120 if ( ! priv->txInProgress ) {
1121 priv->txInProgress = 1;
1122 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Starting TX on buffer %d\n", priv->txTail );
1123 outl( tail_list_phys, dev->base_addr + TLAN_CH_PARM );
1124 outl( TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD );
1125 } else {
1126 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Adding buffer %d to TX channel\n", priv->txTail );
1127 if ( priv->txTail == 0 ) {
1128 ( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward = tail_list_phys;
1129 } else {
1130 ( priv->txList + ( priv->txTail - 1 ) )->forward = tail_list_phys;
1131 }
1132 }
1133 spin_unlock_irqrestore(&priv->lock, flags);
1134
1135 CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS );
1136
1137 if ( bbuf )
1138 dev_kfree_skb_any(skb);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001139
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 dev->trans_start = jiffies;
1141 return 0;
1142
1143} /* TLan_StartTx */
1144
1145
1146
1147
1148 /***************************************************************
1149 * TLan_HandleInterrupt
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001150 *
1151 * Returns:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 * Nothing
1153 * Parms:
1154 * irq The line on which the interrupt
1155 * occurred.
1156 * dev_id A pointer to the device assigned to
1157 * this irq line.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 *
1159 * This function handles an interrupt generated by its
1160 * assigned TLAN adapter. The function deactivates
1161 * interrupts on its adapter, records the type of
1162 * interrupt, executes the appropriate subhandler, and
1163 * acknowdges the interrupt to the adapter (thus
1164 * re-enabling adapter interrupts.
1165 *
1166 **************************************************************/
1167
David Howells7d12e782006-10-05 14:55:46 +01001168static irqreturn_t TLan_HandleInterrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169{
1170 u32 ack;
1171 struct net_device *dev;
1172 u32 host_cmd;
1173 u16 host_int;
1174 int type;
1175 TLanPrivateInfo *priv;
1176
1177 dev = dev_id;
1178 priv = netdev_priv(dev);
1179
1180 spin_lock(&priv->lock);
1181
1182 host_int = inw( dev->base_addr + TLAN_HOST_INT );
1183 outw( host_int, dev->base_addr + TLAN_HOST_INT );
1184
1185 type = ( host_int & TLAN_HI_IT_MASK ) >> 2;
1186
1187 ack = TLanIntVector[type]( dev, host_int );
1188
1189 if ( ack ) {
1190 host_cmd = TLAN_HC_ACK | ack | ( type << 18 );
1191 outl( host_cmd, dev->base_addr + TLAN_HOST_CMD );
1192 }
1193
1194 spin_unlock(&priv->lock);
1195
1196 return IRQ_HANDLED;
1197} /* TLan_HandleInterrupts */
1198
1199
1200
1201
1202 /***************************************************************
1203 * TLan_Close
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001204 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 * Returns:
1206 * An error code.
1207 * Parms:
1208 * dev The device structure of the device to
1209 * close.
1210 *
1211 * This function shuts down the adapter. It records any
1212 * stats, puts the adapter into reset state, deactivates
1213 * its time as needed, and frees the irq it is using.
1214 *
1215 **************************************************************/
1216
1217static int TLan_Close(struct net_device *dev)
1218{
1219 TLanPrivateInfo *priv = netdev_priv(dev);
1220
1221 netif_stop_queue(dev);
1222 priv->neg_be_verbose = 0;
1223
1224 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1225 outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
1226 if ( priv->timer.function != NULL ) {
1227 del_timer_sync( &priv->timer );
1228 priv->timer.function = NULL;
1229 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001230
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 free_irq( dev->irq, dev );
1232 TLan_FreeLists( dev );
1233 TLAN_DBG( TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name );
1234
1235 return 0;
1236
1237} /* TLan_Close */
1238
1239
1240
1241
1242 /***************************************************************
1243 * TLan_GetStats
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001244 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 * Returns:
1246 * A pointer to the device's statistics structure.
1247 * Parms:
1248 * dev The device structure to return the
1249 * stats for.
1250 *
1251 * This function updates the devices statistics by reading
1252 * the TLAN chip's onboard registers. Then it returns the
1253 * address of the statistics structure.
1254 *
1255 **************************************************************/
1256
1257static struct net_device_stats *TLan_GetStats( struct net_device *dev )
1258{
1259 TLanPrivateInfo *priv = netdev_priv(dev);
1260 int i;
1261
1262 /* Should only read stats if open ? */
1263 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1264
1265 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name, priv->rxEocCount );
1266 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name, priv->txBusyCount );
1267 if ( debug & TLAN_DEBUG_GNRL ) {
1268 TLan_PrintDio( dev->base_addr );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001269 TLan_PhyPrint( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 }
1271 if ( debug & TLAN_DEBUG_LIST ) {
1272 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ )
1273 TLan_PrintList( priv->rxList + i, "RX", i );
1274 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ )
1275 TLan_PrintList( priv->txList + i, "TX", i );
1276 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001277
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001278 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279
1280} /* TLan_GetStats */
1281
1282
1283
1284
1285 /***************************************************************
1286 * TLan_SetMulticastList
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001287 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 * Returns:
1289 * Nothing
1290 * Parms:
1291 * dev The device structure to set the
1292 * multicast list for.
1293 *
1294 * This function sets the TLAN adaptor to various receive
1295 * modes. If the IFF_PROMISC flag is set, promiscuous
1296 * mode is acitviated. Otherwise, promiscuous mode is
1297 * turned off. If the IFF_ALLMULTI flag is set, then
1298 * the hash table is set to receive all group addresses.
1299 * Otherwise, the first three multicast addresses are
1300 * stored in AREG_1-3, and the rest are selected via the
1301 * hash table, as necessary.
1302 *
1303 **************************************************************/
1304
1305static void TLan_SetMulticastList( struct net_device *dev )
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001306{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 struct dev_mc_list *dmi = dev->mc_list;
1308 u32 hash1 = 0;
1309 u32 hash2 = 0;
1310 int i;
1311 u32 offset;
1312 u8 tmp;
1313
1314 if ( dev->flags & IFF_PROMISC ) {
1315 tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
1316 TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF );
1317 } else {
1318 tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
1319 TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF );
1320 if ( dev->flags & IFF_ALLMULTI ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001321 for ( i = 0; i < 3; i++ )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 TLan_SetMac( dev, i + 1, NULL );
1323 TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, 0xFFFFFFFF );
1324 TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, 0xFFFFFFFF );
1325 } else {
1326 for ( i = 0; i < dev->mc_count; i++ ) {
1327 if ( i < 3 ) {
1328 TLan_SetMac( dev, i + 1, (char *) &dmi->dmi_addr );
1329 } else {
1330 offset = TLan_HashFunc( (u8 *) &dmi->dmi_addr );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001331 if ( offset < 32 )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 hash1 |= ( 1 << offset );
1333 else
1334 hash2 |= ( 1 << ( offset - 32 ) );
1335 }
1336 dmi = dmi->next;
1337 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001338 for ( ; i < 3; i++ )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 TLan_SetMac( dev, i + 1, NULL );
1340 TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, hash1 );
1341 TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, hash2 );
1342 }
1343 }
1344
1345} /* TLan_SetMulticastList */
1346
1347
1348
1349/*****************************************************************************
1350******************************************************************************
1351
1352 ThunderLAN Driver Interrupt Vectors and Table
1353
1354 Please see Chap. 4, "Interrupt Handling" of the "ThunderLAN
1355 Programmer's Guide" for more informations on handling interrupts
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001356 generated by TLAN based adapters.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357
1358******************************************************************************
1359*****************************************************************************/
1360
1361
1362 /***************************************************************
1363 * TLan_HandleInvalid
1364 *
1365 * Returns:
1366 * 0
1367 * Parms:
1368 * dev Device assigned the IRQ that was
1369 * raised.
1370 * host_int The contents of the HOST_INT
1371 * port.
1372 *
1373 * This function handles invalid interrupts. This should
1374 * never happen unless some other adapter is trying to use
1375 * the IRQ line assigned to the device.
1376 *
1377 **************************************************************/
1378
Harvey Harrison98e0f522008-02-18 10:04:38 -08001379static u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380{
1381 /* printk( "TLAN: Invalid interrupt on %s.\n", dev->name ); */
1382 return 0;
1383
1384} /* TLan_HandleInvalid */
1385
1386
1387
1388
1389 /***************************************************************
1390 * TLan_HandleTxEOF
1391 *
1392 * Returns:
1393 * 1
1394 * Parms:
1395 * dev Device assigned the IRQ that was
1396 * raised.
1397 * host_int The contents of the HOST_INT
1398 * port.
1399 *
1400 * This function handles Tx EOF interrupts which are raised
1401 * by the adapter when it has completed sending the
1402 * contents of a buffer. If detemines which list/buffer
1403 * was completed and resets it. If the buffer was the last
1404 * in the channel (EOC), then the function checks to see if
1405 * another buffer is ready to send, and if so, sends a Tx
1406 * Go command. Finally, the driver activates/continues the
1407 * activity LED.
1408 *
1409 **************************************************************/
1410
Harvey Harrison98e0f522008-02-18 10:04:38 -08001411static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412{
1413 TLanPrivateInfo *priv = netdev_priv(dev);
1414 int eoc = 0;
1415 TLanList *head_list;
1416 dma_addr_t head_list_phys;
1417 u32 ack = 0;
1418 u16 tmpCStat;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001419
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
1421 head_list = priv->txList + priv->txHead;
1422
1423 while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
1424 ack++;
1425 if ( ! bbuf ) {
1426 struct sk_buff *skb = TLan_GetSKB(head_list);
1427 pci_unmap_single(priv->pciDev, head_list->buffer[0].address, skb->len, PCI_DMA_TODEVICE);
1428 dev_kfree_skb_any(skb);
1429 head_list->buffer[8].address = 0;
1430 head_list->buffer[9].address = 0;
1431 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001432
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433 if ( tmpCStat & TLAN_CSTAT_EOC )
1434 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001435
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001436 dev->stats.tx_bytes += head_list->frameSize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437
1438 head_list->cStat = TLAN_CSTAT_UNUSED;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001439 netif_start_queue(dev);
1440 CIRC_INC( priv->txHead, TLAN_NUM_TX_LISTS );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 head_list = priv->txList + priv->txHead;
1442 }
1443
1444 if (!ack)
1445 printk(KERN_INFO "TLAN: Received interrupt for uncompleted TX frame.\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001446
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447 if ( eoc ) {
1448 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
1449 head_list = priv->txList + priv->txHead;
1450 head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead;
1451 if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
1452 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM );
1453 ack |= TLAN_HC_GO;
1454 } else {
1455 priv->txInProgress = 0;
1456 }
1457 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001458
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
1460 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
1461 if ( priv->timer.function == NULL ) {
1462 priv->timer.function = &TLan_Timer;
1463 priv->timer.data = (unsigned long) dev;
1464 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1465 priv->timerSetAt = jiffies;
1466 priv->timerType = TLAN_TIMER_ACTIVITY;
1467 add_timer(&priv->timer);
1468 } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
1469 priv->timerSetAt = jiffies;
1470 }
1471 }
1472
1473 return ack;
1474
1475} /* TLan_HandleTxEOF */
1476
1477
1478
1479
1480 /***************************************************************
1481 * TLan_HandleStatOverflow
1482 *
1483 * Returns:
1484 * 1
1485 * Parms:
1486 * dev Device assigned the IRQ that was
1487 * raised.
1488 * host_int The contents of the HOST_INT
1489 * port.
1490 *
1491 * This function handles the Statistics Overflow interrupt
1492 * which means that one or more of the TLAN statistics
1493 * registers has reached 1/2 capacity and needs to be read.
1494 *
1495 **************************************************************/
1496
Harvey Harrison98e0f522008-02-18 10:04:38 -08001497static u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498{
1499 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1500
1501 return 1;
1502
1503} /* TLan_HandleStatOverflow */
1504
1505
1506
1507
1508 /***************************************************************
1509 * TLan_HandleRxEOF
1510 *
1511 * Returns:
1512 * 1
1513 * Parms:
1514 * dev Device assigned the IRQ that was
1515 * raised.
1516 * host_int The contents of the HOST_INT
1517 * port.
1518 *
1519 * This function handles the Rx EOF interrupt which
1520 * indicates a frame has been received by the adapter from
1521 * the net and the frame has been transferred to memory.
1522 * The function determines the bounce buffer the frame has
1523 * been loaded into, creates a new sk_buff big enough to
1524 * hold the frame, and sends it to protocol stack. It
1525 * then resets the used buffer and appends it to the end
1526 * of the list. If the frame was the last in the Rx
1527 * channel (EOC), the function restarts the receive channel
1528 * by sending an Rx Go command to the adapter. Then it
1529 * activates/continues the activity LED.
1530 *
1531 **************************************************************/
1532
Harvey Harrison98e0f522008-02-18 10:04:38 -08001533static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534{
1535 TLanPrivateInfo *priv = netdev_priv(dev);
1536 u32 ack = 0;
1537 int eoc = 0;
1538 u8 *head_buffer;
1539 TLanList *head_list;
1540 struct sk_buff *skb;
1541 TLanList *tail_list;
1542 void *t;
1543 u32 frameSize;
1544 u16 tmpCStat;
1545 dma_addr_t head_list_phys;
1546
1547 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOF (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
1548 head_list = priv->rxList + priv->rxHead;
1549 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001550
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
1552 frameSize = head_list->frameSize;
1553 ack++;
1554 if (tmpCStat & TLAN_CSTAT_EOC)
1555 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001556
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 if (bbuf) {
1558 skb = dev_alloc_skb(frameSize + 7);
1559 if (skb == NULL)
1560 printk(KERN_INFO "TLAN: Couldn't allocate memory for received data.\n");
1561 else {
1562 head_buffer = priv->rxBuffer + (priv->rxHead * TLAN_MAX_FRAME_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563 skb_reserve(skb, 2);
1564 t = (void *) skb_put(skb, frameSize);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001565
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001566 dev->stats.rx_bytes += head_list->frameSize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
1568 memcpy( t, head_buffer, frameSize );
1569 skb->protocol = eth_type_trans( skb, dev );
1570 netif_rx( skb );
1571 }
1572 } else {
1573 struct sk_buff *new_skb;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001574
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 /*
1576 * I changed the algorithm here. What we now do
1577 * is allocate the new frame. If this fails we
1578 * simply recycle the frame.
1579 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001580
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 new_skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001582
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 if ( new_skb != NULL ) {
1584 skb = TLan_GetSKB(head_list);
1585 pci_unmap_single(priv->pciDev, head_list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Stephen Hemminger93e16842008-05-30 09:49:55 -07001586 skb_put( skb, frameSize );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001588 dev->stats.rx_bytes += frameSize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589
1590 skb->protocol = eth_type_trans( skb, dev );
1591 netif_rx( skb );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001592
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 skb_reserve( new_skb, 2 );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594 head_list->buffer[0].address = pci_map_single(priv->pciDev, new_skb->data, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Stephen Hemminger93e16842008-05-30 09:49:55 -07001595
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 TLan_StoreSKB(head_list, new_skb);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001597 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 printk(KERN_WARNING "TLAN: Couldn't allocate memory for received data.\n" );
1599 }
1600
1601 head_list->forward = 0;
1602 head_list->cStat = 0;
1603 tail_list = priv->rxList + priv->rxTail;
1604 tail_list->forward = head_list_phys;
1605
1606 CIRC_INC( priv->rxHead, TLAN_NUM_RX_LISTS );
1607 CIRC_INC( priv->rxTail, TLAN_NUM_RX_LISTS );
1608 head_list = priv->rxList + priv->rxHead;
1609 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1610 }
1611
1612 if (!ack)
1613 printk(KERN_INFO "TLAN: Received interrupt for uncompleted RX frame.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614
1615
1616
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001617
1618 if ( eoc ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
1620 head_list = priv->rxList + priv->rxHead;
1621 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1622 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM );
1623 ack |= TLAN_HC_GO | TLAN_HC_RT;
1624 priv->rxEocCount++;
1625 }
1626
1627 if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
1628 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
1629 if ( priv->timer.function == NULL ) {
1630 priv->timer.function = &TLan_Timer;
1631 priv->timer.data = (unsigned long) dev;
1632 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1633 priv->timerSetAt = jiffies;
1634 priv->timerType = TLAN_TIMER_ACTIVITY;
1635 add_timer(&priv->timer);
1636 } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
1637 priv->timerSetAt = jiffies;
1638 }
1639 }
1640
1641 dev->last_rx = jiffies;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001642
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 return ack;
1644
1645} /* TLan_HandleRxEOF */
1646
1647
1648
1649
1650 /***************************************************************
1651 * TLan_HandleDummy
1652 *
1653 * Returns:
1654 * 1
1655 * Parms:
1656 * dev Device assigned the IRQ that was
1657 * raised.
1658 * host_int The contents of the HOST_INT
1659 * port.
1660 *
1661 * This function handles the Dummy interrupt, which is
1662 * raised whenever a test interrupt is generated by setting
1663 * the Req_Int bit of HOST_CMD to 1.
1664 *
1665 **************************************************************/
1666
Harvey Harrison98e0f522008-02-18 10:04:38 -08001667static u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668{
1669 printk( "TLAN: Test interrupt on %s.\n", dev->name );
1670 return 1;
1671
1672} /* TLan_HandleDummy */
1673
1674
1675
1676
1677 /***************************************************************
1678 * TLan_HandleTxEOC
1679 *
1680 * Returns:
1681 * 1
1682 * Parms:
1683 * dev Device assigned the IRQ that was
1684 * raised.
1685 * host_int The contents of the HOST_INT
1686 * port.
1687 *
1688 * This driver is structured to determine EOC occurrences by
1689 * reading the CSTAT member of the list structure. Tx EOC
1690 * interrupts are disabled via the DIO INTDIS register.
1691 * However, TLAN chips before revision 3.0 didn't have this
1692 * functionality, so process EOC events if this is the
1693 * case.
1694 *
1695 **************************************************************/
1696
Harvey Harrison98e0f522008-02-18 10:04:38 -08001697static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698{
1699 TLanPrivateInfo *priv = netdev_priv(dev);
1700 TLanList *head_list;
1701 dma_addr_t head_list_phys;
1702 u32 ack = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001703
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 host_int = 0;
1705 if ( priv->tlanRev < 0x30 ) {
1706 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d) -- IRQ\n", priv->txHead, priv->txTail );
1707 head_list = priv->txList + priv->txHead;
1708 head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead;
1709 if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
1710 netif_stop_queue(dev);
1711 outl( head_list_phys, dev->base_addr + TLAN_CH_PARM );
1712 ack |= TLAN_HC_GO;
1713 } else {
1714 priv->txInProgress = 0;
1715 }
1716 }
1717
1718 return ack;
1719
1720} /* TLan_HandleTxEOC */
1721
1722
1723
1724
1725 /***************************************************************
1726 * TLan_HandleStatusCheck
1727 *
1728 * Returns:
1729 * 0 if Adapter check, 1 if Network Status check.
1730 * Parms:
1731 * dev Device assigned the IRQ that was
1732 * raised.
1733 * host_int The contents of the HOST_INT
1734 * port.
1735 *
1736 * This function handles Adapter Check/Network Status
1737 * interrupts generated by the adapter. It checks the
1738 * vector in the HOST_INT register to determine if it is
1739 * an Adapter Check interrupt. If so, it resets the
1740 * adapter. Otherwise it clears the status registers
1741 * and services the PHY.
1742 *
1743 **************************************************************/
1744
Harvey Harrison98e0f522008-02-18 10:04:38 -08001745static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001746{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 TLanPrivateInfo *priv = netdev_priv(dev);
1748 u32 ack;
1749 u32 error;
1750 u8 net_sts;
1751 u32 phy;
1752 u16 tlphy_ctl;
1753 u16 tlphy_sts;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001754
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 ack = 1;
1756 if ( host_int & TLAN_HI_IV_MASK ) {
1757 netif_stop_queue( dev );
1758 error = inl( dev->base_addr + TLAN_CH_PARM );
1759 printk( "TLAN: %s: Adaptor Error = 0x%x\n", dev->name, error );
1760 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1761 outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
1762
1763 schedule_work(&priv->tlan_tqueue);
1764
1765 netif_wake_queue(dev);
1766 ack = 0;
1767 } else {
1768 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name );
1769 phy = priv->phy[priv->phyNum];
1770
1771 net_sts = TLan_DioRead8( dev->base_addr, TLAN_NET_STS );
1772 if ( net_sts ) {
1773 TLan_DioWrite8( dev->base_addr, TLAN_NET_STS, net_sts );
1774 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n", dev->name, (unsigned) net_sts );
1775 }
1776 if ( ( net_sts & TLAN_NET_STS_MIRQ ) && ( priv->phyNum == 0 ) ) {
1777 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_STS, &tlphy_sts );
1778 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
1779 if ( ! ( tlphy_sts & TLAN_TS_POLOK ) && ! ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
1780 tlphy_ctl |= TLAN_TC_SWAPOL;
1781 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
1782 } else if ( ( tlphy_sts & TLAN_TS_POLOK ) && ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
1783 tlphy_ctl &= ~TLAN_TC_SWAPOL;
1784 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
1785 }
1786
1787 if (debug) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001788 TLan_PhyPrint( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789 }
1790 }
1791 }
1792
1793 return ack;
1794
1795} /* TLan_HandleStatusCheck */
1796
1797
1798
1799
1800 /***************************************************************
1801 * TLan_HandleRxEOC
1802 *
1803 * Returns:
1804 * 1
1805 * Parms:
1806 * dev Device assigned the IRQ that was
1807 * raised.
1808 * host_int The contents of the HOST_INT
1809 * port.
1810 *
1811 * This driver is structured to determine EOC occurrences by
1812 * reading the CSTAT member of the list structure. Rx EOC
1813 * interrupts are disabled via the DIO INTDIS register.
1814 * However, TLAN chips before revision 3.0 didn't have this
1815 * CSTAT member or a INTDIS register, so if this chip is
1816 * pre-3.0, process EOC interrupts normally.
1817 *
1818 **************************************************************/
1819
Harvey Harrison98e0f522008-02-18 10:04:38 -08001820static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821{
1822 TLanPrivateInfo *priv = netdev_priv(dev);
1823 dma_addr_t head_list_phys;
1824 u32 ack = 1;
1825
1826 if ( priv->tlanRev < 0x30 ) {
1827 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d) -- IRQ\n", priv->rxHead, priv->rxTail );
1828 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1829 outl( head_list_phys, dev->base_addr + TLAN_CH_PARM );
1830 ack |= TLAN_HC_GO | TLAN_HC_RT;
1831 priv->rxEocCount++;
1832 }
1833
1834 return ack;
1835
1836} /* TLan_HandleRxEOC */
1837
1838
1839
1840
1841/*****************************************************************************
1842******************************************************************************
1843
1844 ThunderLAN Driver Timer Function
1845
1846******************************************************************************
1847*****************************************************************************/
1848
1849
1850 /***************************************************************
1851 * TLan_Timer
1852 *
1853 * Returns:
1854 * Nothing
1855 * Parms:
1856 * data A value given to add timer when
1857 * add_timer was called.
1858 *
1859 * This function handles timed functionality for the
1860 * TLAN driver. The two current timer uses are for
1861 * delaying for autonegotionation and driving the ACT LED.
1862 * - Autonegotiation requires being allowed about
1863 * 2 1/2 seconds before attempting to transmit a
1864 * packet. It would be a very bad thing to hang
1865 * the kernel this long, so the driver doesn't
1866 * allow transmission 'til after this time, for
1867 * certain PHYs. It would be much nicer if all
1868 * PHYs were interrupt-capable like the internal
1869 * PHY.
1870 * - The ACT LED, which shows adapter activity, is
1871 * driven by the driver, and so must be left on
1872 * for a short period to power up the LED so it
1873 * can be seen. This delay can be changed by
1874 * changing the TLAN_TIMER_ACT_DELAY in tlan.h,
1875 * if desired. 100 ms produces a slightly
1876 * sluggish response.
1877 *
1878 **************************************************************/
1879
Harvey Harrison98e0f522008-02-18 10:04:38 -08001880static void TLan_Timer( unsigned long data )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881{
1882 struct net_device *dev = (struct net_device *) data;
1883 TLanPrivateInfo *priv = netdev_priv(dev);
1884 u32 elapsed;
1885 unsigned long flags = 0;
1886
1887 priv->timer.function = NULL;
1888
1889 switch ( priv->timerType ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001890#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 case TLAN_TIMER_LINK_BEAT:
1892 TLan_PhyMonitor( dev );
1893 break;
1894#endif
1895 case TLAN_TIMER_PHY_PDOWN:
1896 TLan_PhyPowerDown( dev );
1897 break;
1898 case TLAN_TIMER_PHY_PUP:
1899 TLan_PhyPowerUp( dev );
1900 break;
1901 case TLAN_TIMER_PHY_RESET:
1902 TLan_PhyReset( dev );
1903 break;
1904 case TLAN_TIMER_PHY_START_LINK:
1905 TLan_PhyStartLink( dev );
1906 break;
1907 case TLAN_TIMER_PHY_FINISH_AN:
1908 TLan_PhyFinishAutoNeg( dev );
1909 break;
1910 case TLAN_TIMER_FINISH_RESET:
1911 TLan_FinishReset( dev );
1912 break;
1913 case TLAN_TIMER_ACTIVITY:
1914 spin_lock_irqsave(&priv->lock, flags);
1915 if ( priv->timer.function == NULL ) {
1916 elapsed = jiffies - priv->timerSetAt;
1917 if ( elapsed >= TLAN_TIMER_ACT_DELAY ) {
1918 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
1919 } else {
1920 priv->timer.function = &TLan_Timer;
1921 priv->timer.expires = priv->timerSetAt + TLAN_TIMER_ACT_DELAY;
1922 spin_unlock_irqrestore(&priv->lock, flags);
1923 add_timer( &priv->timer );
1924 break;
1925 }
1926 }
1927 spin_unlock_irqrestore(&priv->lock, flags);
1928 break;
1929 default:
1930 break;
1931 }
1932
1933} /* TLan_Timer */
1934
1935
1936
1937
1938/*****************************************************************************
1939******************************************************************************
1940
1941 ThunderLAN Driver Adapter Related Routines
1942
1943******************************************************************************
1944*****************************************************************************/
1945
1946
1947 /***************************************************************
1948 * TLan_ResetLists
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001949 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 * Returns:
1951 * Nothing
1952 * Parms:
1953 * dev The device structure with the list
1954 * stuctures to be reset.
1955 *
1956 * This routine sets the variables associated with managing
1957 * the TLAN lists to their initial values.
1958 *
1959 **************************************************************/
1960
Harvey Harrison98e0f522008-02-18 10:04:38 -08001961static void TLan_ResetLists( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962{
1963 TLanPrivateInfo *priv = netdev_priv(dev);
1964 int i;
1965 TLanList *list;
1966 dma_addr_t list_phys;
1967 struct sk_buff *skb;
1968 void *t = NULL;
1969
1970 priv->txHead = 0;
1971 priv->txTail = 0;
1972 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
1973 list = priv->txList + i;
1974 list->cStat = TLAN_CSTAT_UNUSED;
1975 if ( bbuf ) {
1976 list->buffer[0].address = priv->txBufferDMA + ( i * TLAN_MAX_FRAME_SIZE );
1977 } else {
1978 list->buffer[0].address = 0;
1979 }
1980 list->buffer[2].count = 0;
1981 list->buffer[2].address = 0;
1982 list->buffer[8].address = 0;
1983 list->buffer[9].address = 0;
1984 }
1985
1986 priv->rxHead = 0;
1987 priv->rxTail = TLAN_NUM_RX_LISTS - 1;
1988 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
1989 list = priv->rxList + i;
1990 list_phys = priv->rxListDMA + sizeof(TLanList) * i;
1991 list->cStat = TLAN_CSTAT_READY;
1992 list->frameSize = TLAN_MAX_FRAME_SIZE;
1993 list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
1994 if ( bbuf ) {
1995 list->buffer[0].address = priv->rxBufferDMA + ( i * TLAN_MAX_FRAME_SIZE );
1996 } else {
1997 skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
1998 if ( skb == NULL ) {
1999 printk( "TLAN: Couldn't allocate memory for received data.\n" );
2000 /* If this ever happened it would be a problem */
2001 } else {
2002 skb->dev = dev;
2003 skb_reserve( skb, 2 );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 }
2005 list->buffer[0].address = pci_map_single(priv->pciDev, t, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006 TLan_StoreSKB(list, skb);
2007 }
2008 list->buffer[1].count = 0;
2009 list->buffer[1].address = 0;
2010 if ( i < TLAN_NUM_RX_LISTS - 1 )
2011 list->forward = list_phys + sizeof(TLanList);
2012 else
2013 list->forward = 0;
2014 }
2015
2016} /* TLan_ResetLists */
2017
2018
Harvey Harrison98e0f522008-02-18 10:04:38 -08002019static void TLan_FreeLists( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020{
2021 TLanPrivateInfo *priv = netdev_priv(dev);
2022 int i;
2023 TLanList *list;
2024 struct sk_buff *skb;
2025
2026 if ( ! bbuf ) {
2027 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
2028 list = priv->txList + i;
2029 skb = TLan_GetSKB(list);
2030 if ( skb ) {
2031 pci_unmap_single(priv->pciDev, list->buffer[0].address, skb->len, PCI_DMA_TODEVICE);
2032 dev_kfree_skb_any( skb );
2033 list->buffer[8].address = 0;
2034 list->buffer[9].address = 0;
2035 }
2036 }
2037
2038 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
2039 list = priv->rxList + i;
2040 skb = TLan_GetSKB(list);
2041 if ( skb ) {
2042 pci_unmap_single(priv->pciDev, list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
2043 dev_kfree_skb_any( skb );
2044 list->buffer[8].address = 0;
2045 list->buffer[9].address = 0;
2046 }
2047 }
2048 }
2049} /* TLan_FreeLists */
2050
2051
2052
2053
2054 /***************************************************************
2055 * TLan_PrintDio
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002056 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057 * Returns:
2058 * Nothing
2059 * Parms:
2060 * io_base Base IO port of the device of
2061 * which to print DIO registers.
2062 *
2063 * This function prints out all the internal (DIO)
2064 * registers of a TLAN chip.
2065 *
2066 **************************************************************/
2067
Harvey Harrison98e0f522008-02-18 10:04:38 -08002068static void TLan_PrintDio( u16 io_base )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069{
2070 u32 data0, data1;
2071 int i;
2072
2073 printk( "TLAN: Contents of internal registers for io base 0x%04hx.\n", io_base );
2074 printk( "TLAN: Off. +0 +4\n" );
2075 for ( i = 0; i < 0x4C; i+= 8 ) {
2076 data0 = TLan_DioRead32( io_base, i );
2077 data1 = TLan_DioRead32( io_base, i + 0x4 );
2078 printk( "TLAN: 0x%02x 0x%08x 0x%08x\n", i, data0, data1 );
2079 }
2080
2081} /* TLan_PrintDio */
2082
2083
2084
2085
2086 /***************************************************************
2087 * TLan_PrintList
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002088 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002089 * Returns:
2090 * Nothing
2091 * Parms:
2092 * list A pointer to the TLanList structure to
2093 * be printed.
2094 * type A string to designate type of list,
2095 * "Rx" or "Tx".
2096 * num The index of the list.
2097 *
2098 * This function prints out the contents of the list
2099 * pointed to by the list parameter.
2100 *
2101 **************************************************************/
2102
Harvey Harrison98e0f522008-02-18 10:04:38 -08002103static void TLan_PrintList( TLanList *list, char *type, int num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104{
2105 int i;
2106
Stephen Hemminger93e16842008-05-30 09:49:55 -07002107 printk( "TLAN: %s List %d at %p\n", type, num, list );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108 printk( "TLAN: Forward = 0x%08x\n", list->forward );
2109 printk( "TLAN: CSTAT = 0x%04hx\n", list->cStat );
2110 printk( "TLAN: Frame Size = 0x%04hx\n", list->frameSize );
2111 /* for ( i = 0; i < 10; i++ ) { */
2112 for ( i = 0; i < 2; i++ ) {
2113 printk( "TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n", i, list->buffer[i].count, list->buffer[i].address );
2114 }
2115
2116} /* TLan_PrintList */
2117
2118
2119
2120
2121 /***************************************************************
2122 * TLan_ReadAndClearStats
2123 *
2124 * Returns:
2125 * Nothing
2126 * Parms:
2127 * dev Pointer to device structure of adapter
2128 * to which to read stats.
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002129 * record Flag indicating whether to add
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130 *
2131 * This functions reads all the internal status registers
2132 * of the TLAN chip, which clears them as a side effect.
2133 * It then either adds the values to the device's status
2134 * struct, or discards them, depending on whether record
2135 * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0).
2136 *
2137 **************************************************************/
2138
Harvey Harrison98e0f522008-02-18 10:04:38 -08002139static void TLan_ReadAndClearStats( struct net_device *dev, int record )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002140{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 u32 tx_good, tx_under;
2142 u32 rx_good, rx_over;
2143 u32 def_tx, crc, code;
2144 u32 multi_col, single_col;
2145 u32 excess_col, late_col, loss;
2146
2147 outw( TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR );
2148 tx_good = inb( dev->base_addr + TLAN_DIO_DATA );
2149 tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2150 tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
2151 tx_under = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
2152
2153 outw( TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR );
2154 rx_good = inb( dev->base_addr + TLAN_DIO_DATA );
2155 rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2156 rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
2157 rx_over = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002158
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159 outw( TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR );
2160 def_tx = inb( dev->base_addr + TLAN_DIO_DATA );
2161 def_tx += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2162 crc = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2163 code = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002164
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165 outw( TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
2166 multi_col = inb( dev->base_addr + TLAN_DIO_DATA );
2167 multi_col += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2168 single_col = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2169 single_col += inb( dev->base_addr + TLAN_DIO_DATA + 3 ) << 8;
2170
2171 outw( TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
2172 excess_col = inb( dev->base_addr + TLAN_DIO_DATA );
2173 late_col = inb( dev->base_addr + TLAN_DIO_DATA + 1 );
2174 loss = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2175
2176 if ( record ) {
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002177 dev->stats.rx_packets += rx_good;
2178 dev->stats.rx_errors += rx_over + crc + code;
2179 dev->stats.tx_packets += tx_good;
2180 dev->stats.tx_errors += tx_under + loss;
2181 dev->stats.collisions += multi_col + single_col + excess_col + late_col;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002183 dev->stats.rx_over_errors += rx_over;
2184 dev->stats.rx_crc_errors += crc;
2185 dev->stats.rx_frame_errors += code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002187 dev->stats.tx_aborted_errors += tx_under;
2188 dev->stats.tx_carrier_errors += loss;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002190
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191} /* TLan_ReadAndClearStats */
2192
2193
2194
2195
2196 /***************************************************************
2197 * TLan_Reset
2198 *
2199 * Returns:
2200 * 0
2201 * Parms:
2202 * dev Pointer to device structure of adapter
2203 * to be reset.
2204 *
2205 * This function resets the adapter and it's physical
2206 * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
2207 * Programmer's Guide" for details. The routine tries to
2208 * implement what is detailed there, though adjustments
2209 * have been made.
2210 *
2211 **************************************************************/
2212
Harvey Harrison98e0f522008-02-18 10:04:38 -08002213static void
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214TLan_ResetAdapter( struct net_device *dev )
2215{
2216 TLanPrivateInfo *priv = netdev_priv(dev);
2217 int i;
2218 u32 addr;
2219 u32 data;
2220 u8 data8;
2221
2222 priv->tlanFullDuplex = FALSE;
2223 priv->phyOnline=0;
2224 netif_carrier_off(dev);
2225
2226/* 1. Assert reset bit. */
2227
2228 data = inl(dev->base_addr + TLAN_HOST_CMD);
2229 data |= TLAN_HC_AD_RST;
2230 outl(data, dev->base_addr + TLAN_HOST_CMD);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002231
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232 udelay(1000);
2233
2234/* 2. Turn off interrupts. ( Probably isn't necessary ) */
2235
2236 data = inl(dev->base_addr + TLAN_HOST_CMD);
2237 data |= TLAN_HC_INT_OFF;
2238 outl(data, dev->base_addr + TLAN_HOST_CMD);
2239
2240/* 3. Clear AREGs and HASHs. */
2241
2242 for ( i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4 ) {
2243 TLan_DioWrite32( dev->base_addr, (u16) i, 0 );
2244 }
2245
2246/* 4. Setup NetConfig register. */
2247
2248 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2249 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
2250
2251/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
2252
2253 outl( TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD );
2254 outl( TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD );
2255
2256/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
2257
2258 outw( TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR );
2259 addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
2260 TLan_SetBit( TLAN_NET_SIO_NMRST, addr );
2261
2262/* 7. Setup the remaining registers. */
2263
2264 if ( priv->tlanRev >= 0x30 ) {
2265 data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
2266 TLan_DioWrite8( dev->base_addr, TLAN_INT_DIS, data8 );
2267 }
2268 TLan_PhyDetect( dev );
2269 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002270
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271 if ( priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY ) {
2272 data |= TLAN_NET_CFG_BIT;
2273 if ( priv->aui == 1 ) {
2274 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x0a );
2275 } else if ( priv->duplex == TLAN_DUPLEX_FULL ) {
2276 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x00 );
2277 priv->tlanFullDuplex = TRUE;
2278 } else {
2279 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x08 );
2280 }
2281 }
2282
2283 if ( priv->phyNum == 0 ) {
2284 data |= TLAN_NET_CFG_PHY_EN;
2285 }
2286 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
2287
2288 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2289 TLan_FinishReset( dev );
2290 } else {
2291 TLan_PhyPowerDown( dev );
2292 }
2293
2294} /* TLan_ResetAdapter */
2295
2296
2297
2298
Harvey Harrison98e0f522008-02-18 10:04:38 -08002299static void
Linus Torvalds1da177e2005-04-16 15:20:36 -07002300TLan_FinishReset( struct net_device *dev )
2301{
2302 TLanPrivateInfo *priv = netdev_priv(dev);
2303 u8 data;
2304 u32 phy;
2305 u8 sio;
2306 u16 status;
2307 u16 partner;
2308 u16 tlphy_ctl;
2309 u16 tlphy_par;
2310 u16 tlphy_id1, tlphy_id2;
2311 int i;
2312
2313 phy = priv->phy[priv->phyNum];
2314
2315 data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
2316 if ( priv->tlanFullDuplex ) {
2317 data |= TLAN_NET_CMD_DUPLEX;
2318 }
2319 TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, data );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002320 data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321 if ( priv->phyNum == 0 ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002322 data |= TLAN_NET_MASK_MASK7;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 }
2324 TLan_DioWrite8( dev->base_addr, TLAN_NET_MASK, data );
2325 TLan_DioWrite16( dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7 );
2326 TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &tlphy_id1 );
2327 TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &tlphy_id2 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002328
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) || ( priv->aui ) ) {
2330 status = MII_GS_LINK;
2331 printk( "TLAN: %s: Link forced.\n", dev->name );
2332 } else {
2333 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2334 udelay( 1000 );
2335 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002336 if ( (status & MII_GS_LINK) && /* We only support link info on Nat.Sem. PHY's */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337 (tlphy_id1 == NAT_SEM_ID1) &&
2338 (tlphy_id2 == NAT_SEM_ID2) ) {
2339 TLan_MiiReadReg( dev, phy, MII_AN_LPA, &partner );
2340 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_PAR, &tlphy_par );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002341
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342 printk( "TLAN: %s: Link active with ", dev->name );
2343 if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002344 printk( "forced 10%sMbps %s-Duplex\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002345 tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
2346 tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
2347 } else {
2348 printk( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n",
2349 tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
2350 tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
2351 printk("TLAN: Partner capability: ");
2352 for (i = 5; i <= 10; i++)
2353 if (partner & (1<<i))
2354 printk("%s",media[i-5]);
2355 printk("\n");
2356 }
2357
2358 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002359#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360 /* We have link beat..for now anyway */
2361 priv->link = 1;
2362 /*Enabling link beat monitoring */
2363 TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_LINK_BEAT );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002364#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365 } else if (status & MII_GS_LINK) {
2366 printk( "TLAN: %s: Link active\n", dev->name );
2367 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
2368 }
2369 }
2370
2371 if ( priv->phyNum == 0 ) {
2372 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
2373 tlphy_ctl |= TLAN_TC_INTEN;
2374 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl );
2375 sio = TLan_DioRead8( dev->base_addr, TLAN_NET_SIO );
2376 sio |= TLAN_NET_SIO_MINTEN;
2377 TLan_DioWrite8( dev->base_addr, TLAN_NET_SIO, sio );
2378 }
2379
2380 if ( status & MII_GS_LINK ) {
2381 TLan_SetMac( dev, 0, dev->dev_addr );
2382 priv->phyOnline = 1;
2383 outb( ( TLAN_HC_INT_ON >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
2384 if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) {
2385 outb( ( TLAN_HC_REQ_INT >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
2386 }
2387 outl( priv->rxListDMA, dev->base_addr + TLAN_CH_PARM );
2388 outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD );
2389 netif_carrier_on(dev);
2390 } else {
2391 printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name );
2392 TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
2393 return;
2394 }
James Harper562faf42005-05-05 15:14:18 -07002395 TLan_SetMulticastList(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396
2397} /* TLan_FinishReset */
2398
2399
2400
2401
2402 /***************************************************************
2403 * TLan_SetMac
2404 *
2405 * Returns:
2406 * Nothing
2407 * Parms:
2408 * dev Pointer to device structure of adapter
2409 * on which to change the AREG.
2410 * areg The AREG to set the address in (0 - 3).
2411 * mac A pointer to an array of chars. Each
2412 * element stores one byte of the address.
2413 * IE, it isn't in ascii.
2414 *
2415 * This function transfers a MAC address to one of the
2416 * TLAN AREGs (address registers). The TLAN chip locks
2417 * the register on writing to offset 0 and unlocks the
2418 * register after writing to offset 5. If NULL is passed
2419 * in mac, then the AREG is filled with 0's.
2420 *
2421 **************************************************************/
2422
Harvey Harrison98e0f522008-02-18 10:04:38 -08002423static void TLan_SetMac( struct net_device *dev, int areg, char *mac )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424{
2425 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002426
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 areg *= 6;
2428
2429 if ( mac != NULL ) {
2430 for ( i = 0; i < 6; i++ )
2431 TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, mac[i] );
2432 } else {
2433 for ( i = 0; i < 6; i++ )
2434 TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, 0 );
2435 }
2436
2437} /* TLan_SetMac */
2438
2439
2440
2441
2442/*****************************************************************************
2443******************************************************************************
2444
2445 ThunderLAN Driver PHY Layer Routines
2446
2447******************************************************************************
2448*****************************************************************************/
2449
2450
2451
2452 /*********************************************************************
2453 * TLan_PhyPrint
2454 *
2455 * Returns:
2456 * Nothing
2457 * Parms:
2458 * dev A pointer to the device structure of the
2459 * TLAN device having the PHYs to be detailed.
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002460 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002461 * This function prints the registers a PHY (aka transceiver).
2462 *
2463 ********************************************************************/
2464
Harvey Harrison98e0f522008-02-18 10:04:38 -08002465static void TLan_PhyPrint( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002466{
2467 TLanPrivateInfo *priv = netdev_priv(dev);
2468 u16 i, data0, data1, data2, data3, phy;
2469
2470 phy = priv->phy[priv->phyNum];
2471
2472 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2473 printk( "TLAN: Device %s, Unmanaged PHY.\n", dev->name );
2474 } else if ( phy <= TLAN_PHY_MAX_ADDR ) {
2475 printk( "TLAN: Device %s, PHY 0x%02x.\n", dev->name, phy );
2476 printk( "TLAN: Off. +0 +1 +2 +3 \n" );
2477 for ( i = 0; i < 0x20; i+= 4 ) {
2478 printk( "TLAN: 0x%02x", i );
2479 TLan_MiiReadReg( dev, phy, i, &data0 );
2480 printk( " 0x%04hx", data0 );
2481 TLan_MiiReadReg( dev, phy, i + 1, &data1 );
2482 printk( " 0x%04hx", data1 );
2483 TLan_MiiReadReg( dev, phy, i + 2, &data2 );
2484 printk( " 0x%04hx", data2 );
2485 TLan_MiiReadReg( dev, phy, i + 3, &data3 );
2486 printk( " 0x%04hx\n", data3 );
2487 }
2488 } else {
2489 printk( "TLAN: Device %s, Invalid PHY.\n", dev->name );
2490 }
2491
2492} /* TLan_PhyPrint */
2493
2494
2495
2496
2497 /*********************************************************************
2498 * TLan_PhyDetect
2499 *
2500 * Returns:
2501 * Nothing
2502 * Parms:
2503 * dev A pointer to the device structure of the adapter
2504 * for which the PHY needs determined.
2505 *
2506 * So far I've found that adapters which have external PHYs
2507 * may also use the internal PHY for part of the functionality.
2508 * (eg, AUI/Thinnet). This function finds out if this TLAN
2509 * chip has an internal PHY, and then finds the first external
2510 * PHY (starting from address 0) if it exists).
2511 *
2512 ********************************************************************/
2513
Harvey Harrison98e0f522008-02-18 10:04:38 -08002514static void TLan_PhyDetect( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515{
2516 TLanPrivateInfo *priv = netdev_priv(dev);
2517 u16 control;
2518 u16 hi;
2519 u16 lo;
2520 u32 phy;
2521
2522 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2523 priv->phyNum = 0xFFFF;
2524 return;
2525 }
2526
2527 TLan_MiiReadReg( dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002528
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 if ( hi != 0xFFFF ) {
2530 priv->phy[0] = TLAN_PHY_MAX_ADDR;
2531 } else {
2532 priv->phy[0] = TLAN_PHY_NONE;
2533 }
2534
2535 priv->phy[1] = TLAN_PHY_NONE;
2536 for ( phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++ ) {
2537 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &control );
2538 TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &hi );
2539 TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &lo );
2540 if ( ( control != 0xFFFF ) || ( hi != 0xFFFF ) || ( lo != 0xFFFF ) ) {
2541 TLAN_DBG( TLAN_DEBUG_GNRL, "PHY found at %02x %04x %04x %04x\n", phy, control, hi, lo );
2542 if ( ( priv->phy[1] == TLAN_PHY_NONE ) && ( phy != TLAN_PHY_MAX_ADDR ) ) {
2543 priv->phy[1] = phy;
2544 }
2545 }
2546 }
2547
2548 if ( priv->phy[1] != TLAN_PHY_NONE ) {
2549 priv->phyNum = 1;
2550 } else if ( priv->phy[0] != TLAN_PHY_NONE ) {
2551 priv->phyNum = 0;
2552 } else {
2553 printk( "TLAN: Cannot initialize device, no PHY was found!\n" );
2554 }
2555
2556} /* TLan_PhyDetect */
2557
2558
2559
2560
Harvey Harrison98e0f522008-02-18 10:04:38 -08002561static void TLan_PhyPowerDown( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562{
2563 TLanPrivateInfo *priv = netdev_priv(dev);
2564 u16 value;
2565
2566 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name );
2567 value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
2568 TLan_MiiSync( dev->base_addr );
2569 TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
2570 if ( ( priv->phyNum == 0 ) && ( priv->phy[1] != TLAN_PHY_NONE ) && ( ! ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) ) ) {
2571 TLan_MiiSync( dev->base_addr );
2572 TLan_MiiWriteReg( dev, priv->phy[1], MII_GEN_CTL, value );
2573 }
2574
2575 /* Wait for 50 ms and powerup
2576 * This is abitrary. It is intended to make sure the
2577 * transceiver settles.
2578 */
2579 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP );
2580
2581} /* TLan_PhyPowerDown */
2582
2583
2584
2585
Harvey Harrison98e0f522008-02-18 10:04:38 -08002586static void TLan_PhyPowerUp( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587{
2588 TLanPrivateInfo *priv = netdev_priv(dev);
2589 u16 value;
2590
2591 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name );
2592 TLan_MiiSync( dev->base_addr );
2593 value = MII_GC_LOOPBK;
2594 TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
2595 TLan_MiiSync(dev->base_addr);
2596 /* Wait for 500 ms and reset the
2597 * transceiver. The TLAN docs say both 50 ms and
2598 * 500 ms, so do the longer, just in case.
2599 */
2600 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET );
2601
2602} /* TLan_PhyPowerUp */
2603
2604
2605
2606
Harvey Harrison98e0f522008-02-18 10:04:38 -08002607static void TLan_PhyReset( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608{
2609 TLanPrivateInfo *priv = netdev_priv(dev);
2610 u16 phy;
2611 u16 value;
2612
2613 phy = priv->phy[priv->phyNum];
2614
2615 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name );
2616 TLan_MiiSync( dev->base_addr );
2617 value = MII_GC_LOOPBK | MII_GC_RESET;
2618 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, value );
2619 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
2620 while ( value & MII_GC_RESET ) {
2621 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
2622 }
2623
2624 /* Wait for 500 ms and initialize.
2625 * I don't remember why I wait this long.
2626 * I've changed this to 50ms, as it seems long enough.
2627 */
2628 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK );
2629
2630} /* TLan_PhyReset */
2631
2632
2633
2634
Harvey Harrison98e0f522008-02-18 10:04:38 -08002635static void TLan_PhyStartLink( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636{
2637 TLanPrivateInfo *priv = netdev_priv(dev);
2638 u16 ability;
2639 u16 control;
2640 u16 data;
2641 u16 phy;
2642 u16 status;
2643 u16 tctl;
2644
2645 phy = priv->phy[priv->phyNum];
2646 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name );
2647 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2648 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &ability );
2649
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002650 if ( ( status & MII_GS_AUTONEG ) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651 ( ! priv->aui ) ) {
2652 ability = status >> 11;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002653 if ( priv->speed == TLAN_SPEED_10 &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654 priv->duplex == TLAN_DUPLEX_HALF) {
2655 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000);
2656 } else if ( priv->speed == TLAN_SPEED_10 &&
2657 priv->duplex == TLAN_DUPLEX_FULL) {
2658 priv->tlanFullDuplex = TRUE;
2659 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100);
2660 } else if ( priv->speed == TLAN_SPEED_100 &&
2661 priv->duplex == TLAN_DUPLEX_HALF) {
2662 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000);
2663 } else if ( priv->speed == TLAN_SPEED_100 &&
2664 priv->duplex == TLAN_DUPLEX_FULL) {
2665 priv->tlanFullDuplex = TRUE;
2666 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100);
2667 } else {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002668
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 /* Set Auto-Neg advertisement */
2670 TLan_MiiWriteReg( dev, phy, MII_AN_ADV, (ability << 5) | 1);
2671 /* Enablee Auto-Neg */
2672 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 );
2673 /* Restart Auto-Neg */
2674 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 );
2675 /* Wait for 4 sec for autonegotiation
2676 * to complete. The max spec time is less than this
2677 * but the card need additional time to start AN.
2678 * .5 sec should be plenty extra.
2679 */
2680 printk( "TLAN: %s: Starting autonegotiation.\n", dev->name );
2681 TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN );
2682 return;
2683 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002684
2685 }
2686
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687 if ( ( priv->aui ) && ( priv->phyNum != 0 ) ) {
2688 priv->phyNum = 0;
2689 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2690 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
2691 TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN );
2692 return;
2693 } else if ( priv->phyNum == 0 ) {
2694 control = 0;
2695 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tctl );
2696 if ( priv->aui ) {
2697 tctl |= TLAN_TC_AUISEL;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002698 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699 tctl &= ~TLAN_TC_AUISEL;
2700 if ( priv->duplex == TLAN_DUPLEX_FULL ) {
2701 control |= MII_GC_DUPLEX;
2702 priv->tlanFullDuplex = TRUE;
2703 }
2704 if ( priv->speed == TLAN_SPEED_100 ) {
2705 control |= MII_GC_SPEEDSEL;
2706 }
2707 }
2708 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, control );
2709 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl );
2710 }
2711
2712 /* Wait for 2 sec to give the transceiver time
2713 * to establish link.
2714 */
2715 TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET );
2716
2717} /* TLan_PhyStartLink */
2718
2719
2720
2721
Harvey Harrison98e0f522008-02-18 10:04:38 -08002722static void TLan_PhyFinishAutoNeg( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723{
2724 TLanPrivateInfo *priv = netdev_priv(dev);
2725 u16 an_adv;
2726 u16 an_lpa;
2727 u16 data;
2728 u16 mode;
2729 u16 phy;
2730 u16 status;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002731
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732 phy = priv->phy[priv->phyNum];
2733
2734 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2735 udelay( 1000 );
2736 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2737
2738 if ( ! ( status & MII_GS_AUTOCMPLT ) ) {
2739 /* Wait for 8 sec to give the process
2740 * more time. Perhaps we should fail after a while.
2741 */
2742 if (!priv->neg_be_verbose++) {
2743 printk(KERN_INFO "TLAN: Giving autonegotiation more time.\n");
2744 printk(KERN_INFO "TLAN: Please check that your adapter has\n");
2745 printk(KERN_INFO "TLAN: been properly connected to a HUB or Switch.\n");
2746 printk(KERN_INFO "TLAN: Trying to establish link in the background...\n");
2747 }
2748 TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN );
2749 return;
2750 }
2751
2752 printk( "TLAN: %s: Autonegotiation complete.\n", dev->name );
2753 TLan_MiiReadReg( dev, phy, MII_AN_ADV, &an_adv );
2754 TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa );
2755 mode = an_adv & an_lpa & 0x03E0;
2756 if ( mode & 0x0100 ) {
2757 priv->tlanFullDuplex = TRUE;
2758 } else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) {
2759 priv->tlanFullDuplex = TRUE;
2760 }
2761
2762 if ( ( ! ( mode & 0x0180 ) ) && ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) && ( priv->phyNum != 0 ) ) {
2763 priv->phyNum = 0;
2764 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2765 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
2766 TLan_SetTimer( dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN );
2767 return;
2768 }
2769
2770 if ( priv->phyNum == 0 ) {
2771 if ( ( priv->duplex == TLAN_DUPLEX_FULL ) || ( an_adv & an_lpa & 0x0040 ) ) {
2772 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB | MII_GC_DUPLEX );
2773 printk( "TLAN: Starting internal PHY with FULL-DUPLEX\n" );
2774 } else {
2775 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB );
2776 printk( "TLAN: Starting internal PHY with HALF-DUPLEX\n" );
2777 }
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:
2858 * 0 if ack received ok
2859 * 1 otherwise.
2860 *
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
Harvey Harrison98e0f522008-02-18 10:04:38 -08002878static int 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;
2883 int err;
2884 int minten;
2885 TLanPrivateInfo *priv = netdev_priv(dev);
2886 unsigned long flags = 0;
2887
2888 err = FALSE;
2889 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;
2921 err = TRUE;
2922 } 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 ) {
3184 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* STOP, raise data while clock is high */
3185 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3186 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3187 }
3188
3189 return ( err );
3190
3191} /* TLan_EeSendByte */
3192
3193
3194
3195
3196 /***************************************************************
3197 * TLan_EeReceiveByte
3198 *
3199 * Returns:
3200 * Nothing
3201 * Parms:
3202 * io_base The IO port base address for the
3203 * TLAN device with the EEPROM to
3204 * use.
3205 * data An address to a char to hold the
3206 * data sent from the EEPROM.
3207 * stop If TLAN_EEPROM_STOP is passed, a
3208 * stop cycle is sent after the
3209 * byte is received, and no ack is
3210 * sent.
3211 *
3212 * This function receives 8 bits of data from the EEPROM
3213 * over the serial link. It then sends and ack bit, or no
3214 * ack and a stop bit. This function is used to retrieve
3215 * data after the address of a byte in the EEPROM has been
3216 * sent.
3217 *
3218 **************************************************************/
3219
Harvey Harrison98e0f522008-02-18 10:04:38 -08003220static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003221{
3222 u8 place;
3223 u16 sio;
3224
3225 outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
3226 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3227 *data = 0;
3228
3229 /* Assume clock is low, tx is enabled; */
3230 TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
3231 for ( place = 0x80; place; place >>= 1 ) {
3232 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3233 if ( TLan_GetBit( TLAN_NET_SIO_EDATA, sio ) )
3234 *data |= place;
3235 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3236 }
3237
3238 TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
3239 if ( ! stop ) {
3240 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* Ack = 0 */
3241 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3242 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3243 } else {
3244 TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); /* No ack = 1 (?) */
3245 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3246 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3247 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* STOP, raise data while clock is high */
3248 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3249 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3250 }
3251
3252} /* TLan_EeReceiveByte */
3253
3254
3255
3256
3257 /***************************************************************
3258 * TLan_EeReadByte
3259 *
3260 * Returns:
3261 * No error = 0, else, the stage at which the error
3262 * occurred.
3263 * Parms:
3264 * io_base The IO port base address for the
3265 * TLAN device with the EEPROM to
3266 * use.
3267 * ee_addr The address of the byte in the
3268 * EEPROM whose contents are to be
3269 * retrieved.
3270 * data An address to a char to hold the
3271 * data obtained from the EEPROM.
3272 *
3273 * This function reads a byte of information from an byte
3274 * cell in the EEPROM.
3275 *
3276 **************************************************************/
3277
Harvey Harrison98e0f522008-02-18 10:04:38 -08003278static int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003279{
3280 int err;
3281 TLanPrivateInfo *priv = netdev_priv(dev);
3282 unsigned long flags = 0;
3283 int ret=0;
3284
3285 spin_lock_irqsave(&priv->lock, flags);
3286
3287 TLan_EeSendStart( dev->base_addr );
3288 err = TLan_EeSendByte( dev->base_addr, 0xA0, TLAN_EEPROM_ACK );
3289 if (err)
3290 {
3291 ret=1;
3292 goto fail;
3293 }
3294 err = TLan_EeSendByte( dev->base_addr, ee_addr, TLAN_EEPROM_ACK );
3295 if (err)
3296 {
3297 ret=2;
3298 goto fail;
3299 }
3300 TLan_EeSendStart( dev->base_addr );
3301 err = TLan_EeSendByte( dev->base_addr, 0xA1, TLAN_EEPROM_ACK );
3302 if (err)
3303 {
3304 ret=3;
3305 goto fail;
3306 }
3307 TLan_EeReceiveByte( dev->base_addr, data, TLAN_EEPROM_STOP );
3308fail:
3309 spin_unlock_irqrestore(&priv->lock, flags);
3310
3311 return ret;
3312
3313} /* TLan_EeReadByte */
3314
3315
3316