blob: 01aa331e18384bf79d1fe474f8994f03466aa6ae [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
Stephen Hemmingera3ccc782008-05-30 09:49:57 -0700221static const char TLanSignature[] = "TLAN";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222static 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300static u32 TLan_HandleTxEOF( struct net_device *, u16 );
301static u32 TLan_HandleStatOverflow( struct net_device *, u16 );
302static u32 TLan_HandleRxEOF( struct net_device *, u16 );
303static u32 TLan_HandleDummy( struct net_device *, u16 );
304static u32 TLan_HandleTxEOC( struct net_device *, u16 );
305static u32 TLan_HandleStatusCheck( struct net_device *, u16 );
306static u32 TLan_HandleRxEOC( struct net_device *, u16 );
307
308static void TLan_Timer( unsigned long );
309
310static void TLan_ResetLists( struct net_device * );
311static void TLan_FreeLists( struct net_device * );
312static void TLan_PrintDio( u16 );
313static void TLan_PrintList( TLanList *, char *, int );
314static void TLan_ReadAndClearStats( struct net_device *, int );
315static void TLan_ResetAdapter( struct net_device * );
316static void TLan_FinishReset( struct net_device * );
317static void TLan_SetMac( struct net_device *, int areg, char *mac );
318
319static void TLan_PhyPrint( struct net_device * );
320static void TLan_PhyDetect( struct net_device * );
321static void TLan_PhyPowerDown( struct net_device * );
322static void TLan_PhyPowerUp( struct net_device * );
323static void TLan_PhyReset( struct net_device * );
324static void TLan_PhyStartLink( struct net_device * );
325static void TLan_PhyFinishAutoNeg( struct net_device * );
326#ifdef MONITOR
327static void TLan_PhyMonitor( struct net_device * );
328#endif
329
330/*
331static int TLan_PhyNop( struct net_device * );
332static int TLan_PhyInternalCheck( struct net_device * );
333static int TLan_PhyInternalService( struct net_device * );
334static int TLan_PhyDp83840aCheck( struct net_device * );
335*/
336
337static int TLan_MiiReadReg( struct net_device *, u16, u16, u16 * );
338static void TLan_MiiSendData( u16, u32, unsigned );
339static void TLan_MiiSync( u16 );
340static void TLan_MiiWriteReg( struct net_device *, u16, u16, u16 );
341
342static void TLan_EeSendStart( u16 );
343static int TLan_EeSendByte( u16, u8, int );
344static void TLan_EeReceiveByte( u16, u8 *, int );
345static int TLan_EeReadByte( struct net_device *, u8, u8 * );
346
347
Stephen Hemminger93e16842008-05-30 09:49:55 -0700348static inline void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349TLan_StoreSKB( struct tlan_list_tag *tag, struct sk_buff *skb)
350{
351 unsigned long addr = (unsigned long)skb;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700352 tag->buffer[9].address = addr;
353 tag->buffer[8].address = upper_32_bits(addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354}
355
Stephen Hemminger93e16842008-05-30 09:49:55 -0700356static inline struct sk_buff *
357TLan_GetSKB( const struct tlan_list_tag *tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358{
Stephen Hemminger93e16842008-05-30 09:49:55 -0700359 unsigned long addr;
360
361 addr = tag->buffer[8].address;
362 addr |= (tag->buffer[9].address << 16) << 16;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 return (struct sk_buff *) addr;
364}
365
366
367static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = {
Stephen Hemmingera3ccc782008-05-30 09:49:57 -0700368 NULL,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 TLan_HandleTxEOF,
370 TLan_HandleStatOverflow,
371 TLan_HandleRxEOF,
372 TLan_HandleDummy,
373 TLan_HandleTxEOC,
374 TLan_HandleStatusCheck,
375 TLan_HandleRxEOC
376};
377
378static inline void
379TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type )
380{
381 TLanPrivateInfo *priv = netdev_priv(dev);
382 unsigned long flags = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 if (!in_irq())
385 spin_lock_irqsave(&priv->lock, flags);
386 if ( priv->timer.function != NULL &&
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400387 priv->timerType != TLAN_TIMER_ACTIVITY ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 if (!in_irq())
389 spin_unlock_irqrestore(&priv->lock, flags);
390 return;
391 }
392 priv->timer.function = &TLan_Timer;
393 if (!in_irq())
394 spin_unlock_irqrestore(&priv->lock, flags);
395
396 priv->timer.data = (unsigned long) dev;
397 priv->timerSetAt = jiffies;
398 priv->timerType = type;
399 mod_timer(&priv->timer, jiffies + ticks);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400400
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401} /* TLan_SetTimer */
402
403
404/*****************************************************************************
405******************************************************************************
406
407 ThunderLAN Driver Primary Functions
408
409 These functions are more or less common to all Linux network drivers.
410
411******************************************************************************
412*****************************************************************************/
413
414
415
416
417
418 /***************************************************************
419 * tlan_remove_one
420 *
421 * Returns:
422 * Nothing
423 * Parms:
424 * None
425 *
426 * Goes through the TLanDevices list and frees the device
427 * structs and memory associated with each device (lists
428 * and buffers). It also ureserves the IO port regions
429 * associated with this device.
430 *
431 **************************************************************/
432
433
434static void __devexit tlan_remove_one( struct pci_dev *pdev)
435{
436 struct net_device *dev = pci_get_drvdata( pdev );
437 TLanPrivateInfo *priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400438
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439 unregister_netdev( dev );
440
441 if ( priv->dmaStorage ) {
442 pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA );
443 }
444
445#ifdef CONFIG_PCI
446 pci_release_regions(pdev);
447#endif
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400448
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 free_netdev( dev );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400450
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 pci_set_drvdata( pdev, NULL );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400452}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453
454static struct pci_driver tlan_driver = {
455 .name = "tlan",
456 .id_table = tlan_pci_tbl,
457 .probe = tlan_init_one,
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400458 .remove = __devexit_p(tlan_remove_one),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459};
460
461static int __init tlan_probe(void)
462{
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800463 int rc = -ENODEV;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400464
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 printk(KERN_INFO "%s", tlan_banner);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400466
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400468
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 /* Use new style PCI probing. Now the kernel will
470 do most of this for us */
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800471 rc = pci_register_driver(&tlan_driver);
472
473 if (rc != 0) {
474 printk(KERN_ERR "TLAN: Could not register pci driver.\n");
475 goto err_out_pci_free;
476 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477
478 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
479 TLan_EisaProbe();
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400480
481 printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d EISA: %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 TLanDevicesInstalled, TLanDevicesInstalled == 1 ? "" : "s",
483 tlan_have_pci, tlan_have_eisa);
484
485 if (TLanDevicesInstalled == 0) {
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800486 rc = -ENODEV;
487 goto err_out_pci_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 }
489 return 0;
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800490
491err_out_pci_unreg:
492 pci_unregister_driver(&tlan_driver);
493err_out_pci_free:
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800494 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400496
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497
498static int __devinit tlan_init_one( struct pci_dev *pdev,
499 const struct pci_device_id *ent)
500{
501 return TLan_probe1( pdev, -1, -1, 0, ent);
502}
503
504
505/*
506 ***************************************************************
507 * tlan_probe1
508 *
509 * Returns:
510 * 0 on success, error code on error
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400511 * Parms:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 * none
513 *
514 * The name is lower case to fit in with all the rest of
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400515 * the netcard_probe names. This function looks for
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 * another TLan based adapter, setting it up with the
517 * allocated device struct if one is found.
518 * tlan_probe has been ported to the new net API and
519 * now allocates its own device structure. This function
520 * is also used by modules.
521 *
522 **************************************************************/
523
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400524static int __devinit TLan_probe1(struct pci_dev *pdev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 long ioaddr, int irq, int rev, const struct pci_device_id *ent )
526{
527
528 struct net_device *dev;
529 TLanPrivateInfo *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 u16 device_id;
531 int reg, rc = -ENODEV;
532
Adrian Bunkad9f6712006-02-05 00:37:47 +0100533#ifdef CONFIG_PCI
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 if (pdev) {
535 rc = pci_enable_device(pdev);
536 if (rc)
537 return rc;
538
539 rc = pci_request_regions(pdev, TLanSignature);
540 if (rc) {
541 printk(KERN_ERR "TLAN: Could not reserve IO regions\n");
542 goto err_out;
543 }
544 }
Adrian Bunkad9f6712006-02-05 00:37:47 +0100545#endif /* CONFIG_PCI */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
547 dev = alloc_etherdev(sizeof(TLanPrivateInfo));
548 if (dev == NULL) {
549 printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");
550 rc = -ENOMEM;
551 goto err_out_regions;
552 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 SET_NETDEV_DEV(dev, &pdev->dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400554
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 priv = netdev_priv(dev);
556
557 priv->pciDev = pdev;
David Howellsc4028952006-11-22 14:57:56 +0000558 priv->dev = dev;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400559
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 /* Is this a PCI device? */
561 if (pdev) {
562 u32 pci_io_base = 0;
563
564 priv->adapter = &board_info[ent->driver_data];
565
Domen Puncer1e7f0bd2005-06-26 18:22:14 -0400566 rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 if (rc) {
568 printk(KERN_ERR "TLAN: No suitable PCI mapping available.\n");
569 goto err_out_free_dev;
570 }
571
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 for ( reg= 0; reg <= 5; reg ++ ) {
573 if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
574 pci_io_base = pci_resource_start(pdev, reg);
575 TLAN_DBG( TLAN_DEBUG_GNRL, "IO mapping is available at %x.\n",
576 pci_io_base);
577 break;
578 }
579 }
580 if (!pci_io_base) {
581 printk(KERN_ERR "TLAN: No IO mappings available\n");
582 rc = -EIO;
583 goto err_out_free_dev;
584 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400585
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 dev->base_addr = pci_io_base;
587 dev->irq = pdev->irq;
Auke Kok44c10132007-06-08 15:46:36 -0700588 priv->adapterRev = pdev->revision;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 pci_set_master(pdev);
590 pci_set_drvdata(pdev, dev);
591
592 } else { /* EISA card */
593 /* This is a hack. We need to know which board structure
594 * is suited for this adapter */
595 device_id = inw(ioaddr + EISA_ID2);
596 priv->is_eisa = 1;
597 if (device_id == 0x20F1) {
598 priv->adapter = &board_info[13]; /* NetFlex-3/E */
599 priv->adapterRev = 23; /* TLAN 2.3 */
600 } else {
601 priv->adapter = &board_info[14];
602 priv->adapterRev = 10; /* TLAN 1.0 */
603 }
604 dev->base_addr = ioaddr;
605 dev->irq = irq;
606 }
607
608 /* Kernel parameters */
609 if (dev->mem_start) {
610 priv->aui = dev->mem_start & 0x01;
611 priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0 : (dev->mem_start & 0x06) >> 1;
612 priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400613
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 if (priv->speed == 0x1) {
615 priv->speed = TLAN_SPEED_10;
616 } else if (priv->speed == 0x2) {
617 priv->speed = TLAN_SPEED_100;
618 }
619 debug = priv->debug = dev->mem_end;
620 } else {
621 priv->aui = aui[boards_found];
622 priv->speed = speed[boards_found];
623 priv->duplex = duplex[boards_found];
624 priv->debug = debug;
625 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400626
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 /* This will be used when we get an adapter error from
628 * within our irq handler */
David Howellsc4028952006-11-22 14:57:56 +0000629 INIT_WORK(&priv->tlan_tqueue, TLan_tx_timeout_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630
631 spin_lock_init(&priv->lock);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400632
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 rc = TLan_Init(dev);
634 if (rc) {
635 printk(KERN_ERR "TLAN: Could not set up device.\n");
636 goto err_out_free_dev;
637 }
638
639 rc = register_netdev(dev);
640 if (rc) {
641 printk(KERN_ERR "TLAN: Could not register device.\n");
642 goto err_out_uninit;
643 }
644
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400645
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 TLanDevicesInstalled++;
647 boards_found++;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400648
Linus Torvalds1da177e2005-04-16 15:20:36 -0700649 /* pdev is NULL if this is an EISA device */
650 if (pdev)
651 tlan_have_pci++;
652 else {
653 priv->nextDevice = TLan_Eisa_Devices;
654 TLan_Eisa_Devices = dev;
655 tlan_have_eisa++;
656 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400657
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n",
659 dev->name,
660 (int) dev->irq,
661 (int) dev->base_addr,
662 priv->adapter->deviceLabel,
663 priv->adapterRev);
664 return 0;
665
666err_out_uninit:
667 pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage,
668 priv->dmaStorageDMA );
669err_out_free_dev:
670 free_netdev(dev);
671err_out_regions:
672#ifdef CONFIG_PCI
673 if (pdev)
674 pci_release_regions(pdev);
675#endif
676err_out:
677 if (pdev)
678 pci_disable_device(pdev);
679 return rc;
680}
681
682
683static void TLan_Eisa_Cleanup(void)
684{
685 struct net_device *dev;
686 TLanPrivateInfo *priv;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400687
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 while( tlan_have_eisa ) {
689 dev = TLan_Eisa_Devices;
690 priv = netdev_priv(dev);
691 if (priv->dmaStorage) {
692 pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA );
693 }
694 release_region( dev->base_addr, 0x10);
695 unregister_netdev( dev );
696 TLan_Eisa_Devices = priv->nextDevice;
697 free_netdev( dev );
698 tlan_have_eisa--;
699 }
700}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400701
702
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703static void __exit tlan_exit(void)
704{
705 pci_unregister_driver(&tlan_driver);
706
707 if (tlan_have_eisa)
708 TLan_Eisa_Cleanup();
709
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710}
711
712
713/* Module loading/unloading */
714module_init(tlan_probe);
715module_exit(tlan_exit);
716
717
718
719 /**************************************************************
720 * TLan_EisaProbe
721 *
722 * Returns: 0 on success, 1 otherwise
723 *
724 * Parms: None
725 *
726 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400727 * This functions probes for EISA devices and calls
728 * TLan_probe1 when one is found.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 *
730 *************************************************************/
731
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400732static void __init TLan_EisaProbe (void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733{
734 long ioaddr;
735 int rc = -ENODEV;
736 int irq;
737 u16 device_id;
738
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400739 if (!EISA_bus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
741 return;
742 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400743
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 /* Loop through all slots of the EISA bus */
745 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400746
747 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 -0700748 TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2));
749
750
751 TLAN_DBG(TLAN_DEBUG_PROBE, "Probing for EISA adapter at IO: 0x%4x : ",
752 (int) ioaddr);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400753 if (request_region(ioaddr, 0x10, TLanSignature) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 goto out;
755
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400756 if (inw(ioaddr + EISA_ID) != 0x110E) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 release_region(ioaddr, 0x10);
758 goto out;
759 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400760
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 device_id = inw(ioaddr + EISA_ID2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400762 if (device_id != 0x20F1 && device_id != 0x40F1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 release_region (ioaddr, 0x10);
764 goto out;
765 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400766
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 if (inb(ioaddr + EISA_CR) != 0x1) { /* Check if adapter is enabled */
768 release_region (ioaddr, 0x10);
769 goto out2;
770 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400771
772 if (debug == 0x10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 printk("Found one\n");
774
775
776 /* Get irq from board */
777 switch (inb(ioaddr + 0xCC0)) {
778 case(0x10):
779 irq=5;
780 break;
781 case(0x20):
782 irq=9;
783 break;
784 case(0x40):
785 irq=10;
786 break;
787 case(0x80):
788 irq=11;
789 break;
790 default:
791 goto out;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400792 }
793
794
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 /* Setup the newly found eisa adapter */
796 rc = TLan_probe1( NULL, ioaddr, irq,
797 12, NULL);
798 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400799
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 out:
801 if (debug == 0x10)
802 printk("None found\n");
803 continue;
804
805 out2: if (debug == 0x10)
806 printk("Card found but it is not enabled, skipping\n");
807 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400808
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 }
810
811} /* TLan_EisaProbe */
812
813#ifdef CONFIG_NET_POLL_CONTROLLER
814static void TLan_Poll(struct net_device *dev)
815{
816 disable_irq(dev->irq);
David Howells7d12e782006-10-05 14:55:46 +0100817 TLan_HandleInterrupt(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 enable_irq(dev->irq);
819}
820#endif
821
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400822
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
824
825 /***************************************************************
826 * TLan_Init
827 *
828 * Returns:
829 * 0 on success, error code otherwise.
830 * Parms:
831 * dev The structure of the device to be
832 * init'ed.
833 *
834 * This function completes the initialization of the
835 * device structure and driver. It reserves the IO
836 * addresses, allocates memory for the lists and bounce
837 * buffers, retrieves the MAC address from the eeprom
838 * and assignes the device's methods.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400839 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 **************************************************************/
841
842static int TLan_Init( struct net_device *dev )
843{
844 int dma_size;
845 int err;
846 int i;
847 TLanPrivateInfo *priv;
848
849 priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400850
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 if ( bbuf ) {
852 dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
853 * ( sizeof(TLanList) + TLAN_MAX_FRAME_SIZE );
854 } else {
855 dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
856 * ( sizeof(TLanList) );
857 }
Stephen Hemminger93e16842008-05-30 09:49:55 -0700858 priv->dmaStorage = pci_alloc_consistent(priv->pciDev,
859 dma_size, &priv->dmaStorageDMA);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 priv->dmaSize = dma_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400861
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 if ( priv->dmaStorage == NULL ) {
863 printk(KERN_ERR "TLAN: Could not allocate lists and buffers for %s.\n",
864 dev->name );
865 return -ENOMEM;
866 }
867 memset( priv->dmaStorage, 0, dma_size );
Stephen Hemminger93e16842008-05-30 09:49:55 -0700868 priv->rxList = (TLanList *) ALIGN((unsigned long)priv->dmaStorage, 8);
869 priv->rxListDMA = ALIGN(priv->dmaStorageDMA, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 priv->txList = priv->rxList + TLAN_NUM_RX_LISTS;
871 priv->txListDMA = priv->rxListDMA + sizeof(TLanList) * TLAN_NUM_RX_LISTS;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700872
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 if ( bbuf ) {
874 priv->rxBuffer = (u8 *) ( priv->txList + TLAN_NUM_TX_LISTS );
875 priv->rxBufferDMA =priv->txListDMA + sizeof(TLanList) * TLAN_NUM_TX_LISTS;
876 priv->txBuffer = priv->rxBuffer + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
877 priv->txBufferDMA = priv->rxBufferDMA + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
878 }
879
880 err = 0;
881 for ( i = 0; i < 6 ; i++ )
882 err |= TLan_EeReadByte( dev,
883 (u8) priv->adapter->addrOfs + i,
884 (u8 *) &dev->dev_addr[i] );
885 if ( err ) {
886 printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n",
887 dev->name,
888 err );
889 }
890 dev->addr_len = 6;
891
892 netif_carrier_off(dev);
893
894 /* Device methods */
895 dev->open = &TLan_Open;
896 dev->hard_start_xmit = &TLan_StartTx;
897 dev->stop = &TLan_Close;
898 dev->get_stats = &TLan_GetStats;
899 dev->set_multicast_list = &TLan_SetMulticastList;
900 dev->do_ioctl = &TLan_ioctl;
901#ifdef CONFIG_NET_POLL_CONTROLLER
902 dev->poll_controller = &TLan_Poll;
903#endif
904 dev->tx_timeout = &TLan_tx_timeout;
905 dev->watchdog_timeo = TX_TIMEOUT;
906
907 return 0;
908
909} /* TLan_Init */
910
911
912
913
914 /***************************************************************
915 * TLan_Open
916 *
917 * Returns:
918 * 0 on success, error code otherwise.
919 * Parms:
920 * dev Structure of device to be opened.
921 *
922 * This routine puts the driver and TLAN adapter in a
923 * state where it is ready to send and receive packets.
924 * It allocates the IRQ, resets and brings the adapter
925 * out of reset, and allows interrupts. It also delays
926 * the startup for autonegotiation or sends a Rx GO
927 * command to the adapter, as appropriate.
928 *
929 **************************************************************/
930
931static int TLan_Open( struct net_device *dev )
932{
933 TLanPrivateInfo *priv = netdev_priv(dev);
934 int err;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400935
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION );
Stephen Hemmingera3ccc782008-05-30 09:49:57 -0700937 err = request_irq( dev->irq, TLan_HandleInterrupt, IRQF_SHARED,
938 dev->name, 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{
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001170 struct net_device *dev = dev_id;
1171 TLanPrivateInfo *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172 u16 host_int;
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001173 u16 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174
1175 spin_lock(&priv->lock);
1176
1177 host_int = inw( dev->base_addr + TLAN_HOST_INT );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 type = ( host_int & TLAN_HI_IT_MASK ) >> 2;
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001179 if ( type ) {
1180 u32 ack;
1181 u32 host_cmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001183 outw( host_int, dev->base_addr + TLAN_HOST_INT );
1184 ack = TLanIntVector[type]( dev, host_int );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001186 if ( ack ) {
1187 host_cmd = TLAN_HC_ACK | ack | ( type << 18 );
1188 outl( host_cmd, dev->base_addr + TLAN_HOST_CMD );
1189 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 }
1191
1192 spin_unlock(&priv->lock);
1193
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001194 return IRQ_RETVAL(type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195} /* TLan_HandleInterrupts */
1196
1197
1198
1199
1200 /***************************************************************
1201 * TLan_Close
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001202 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 * Returns:
1204 * An error code.
1205 * Parms:
1206 * dev The device structure of the device to
1207 * close.
1208 *
1209 * This function shuts down the adapter. It records any
1210 * stats, puts the adapter into reset state, deactivates
1211 * its time as needed, and frees the irq it is using.
1212 *
1213 **************************************************************/
1214
1215static int TLan_Close(struct net_device *dev)
1216{
1217 TLanPrivateInfo *priv = netdev_priv(dev);
1218
1219 netif_stop_queue(dev);
1220 priv->neg_be_verbose = 0;
1221
1222 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1223 outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
1224 if ( priv->timer.function != NULL ) {
1225 del_timer_sync( &priv->timer );
1226 priv->timer.function = NULL;
1227 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001228
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 free_irq( dev->irq, dev );
1230 TLan_FreeLists( dev );
1231 TLAN_DBG( TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name );
1232
1233 return 0;
1234
1235} /* TLan_Close */
1236
1237
1238
1239
1240 /***************************************************************
1241 * TLan_GetStats
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001242 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 * Returns:
1244 * A pointer to the device's statistics structure.
1245 * Parms:
1246 * dev The device structure to return the
1247 * stats for.
1248 *
1249 * This function updates the devices statistics by reading
1250 * the TLAN chip's onboard registers. Then it returns the
1251 * address of the statistics structure.
1252 *
1253 **************************************************************/
1254
1255static struct net_device_stats *TLan_GetStats( struct net_device *dev )
1256{
1257 TLanPrivateInfo *priv = netdev_priv(dev);
1258 int i;
1259
1260 /* Should only read stats if open ? */
1261 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1262
1263 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name, priv->rxEocCount );
1264 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name, priv->txBusyCount );
1265 if ( debug & TLAN_DEBUG_GNRL ) {
1266 TLan_PrintDio( dev->base_addr );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001267 TLan_PhyPrint( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268 }
1269 if ( debug & TLAN_DEBUG_LIST ) {
1270 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ )
1271 TLan_PrintList( priv->rxList + i, "RX", i );
1272 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ )
1273 TLan_PrintList( priv->txList + i, "TX", i );
1274 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001275
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001276 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277
1278} /* TLan_GetStats */
1279
1280
1281
1282
1283 /***************************************************************
1284 * TLan_SetMulticastList
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001285 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286 * Returns:
1287 * Nothing
1288 * Parms:
1289 * dev The device structure to set the
1290 * multicast list for.
1291 *
1292 * This function sets the TLAN adaptor to various receive
1293 * modes. If the IFF_PROMISC flag is set, promiscuous
1294 * mode is acitviated. Otherwise, promiscuous mode is
1295 * turned off. If the IFF_ALLMULTI flag is set, then
1296 * the hash table is set to receive all group addresses.
1297 * Otherwise, the first three multicast addresses are
1298 * stored in AREG_1-3, and the rest are selected via the
1299 * hash table, as necessary.
1300 *
1301 **************************************************************/
1302
1303static void TLan_SetMulticastList( struct net_device *dev )
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001304{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305 struct dev_mc_list *dmi = dev->mc_list;
1306 u32 hash1 = 0;
1307 u32 hash2 = 0;
1308 int i;
1309 u32 offset;
1310 u8 tmp;
1311
1312 if ( dev->flags & IFF_PROMISC ) {
1313 tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
1314 TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF );
1315 } else {
1316 tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
1317 TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF );
1318 if ( dev->flags & IFF_ALLMULTI ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001319 for ( i = 0; i < 3; i++ )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 TLan_SetMac( dev, i + 1, NULL );
1321 TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, 0xFFFFFFFF );
1322 TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, 0xFFFFFFFF );
1323 } else {
1324 for ( i = 0; i < dev->mc_count; i++ ) {
1325 if ( i < 3 ) {
1326 TLan_SetMac( dev, i + 1, (char *) &dmi->dmi_addr );
1327 } else {
1328 offset = TLan_HashFunc( (u8 *) &dmi->dmi_addr );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001329 if ( offset < 32 )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 hash1 |= ( 1 << offset );
1331 else
1332 hash2 |= ( 1 << ( offset - 32 ) );
1333 }
1334 dmi = dmi->next;
1335 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001336 for ( ; i < 3; i++ )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 TLan_SetMac( dev, i + 1, NULL );
1338 TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, hash1 );
1339 TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, hash2 );
1340 }
1341 }
1342
1343} /* TLan_SetMulticastList */
1344
1345
1346
1347/*****************************************************************************
1348******************************************************************************
1349
1350 ThunderLAN Driver Interrupt Vectors and Table
1351
1352 Please see Chap. 4, "Interrupt Handling" of the "ThunderLAN
1353 Programmer's Guide" for more informations on handling interrupts
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001354 generated by TLAN based adapters.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355
1356******************************************************************************
1357*****************************************************************************/
1358
1359
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360
1361
1362 /***************************************************************
1363 * TLan_HandleTxEOF
1364 *
1365 * Returns:
1366 * 1
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 Tx EOF interrupts which are raised
1374 * by the adapter when it has completed sending the
1375 * contents of a buffer. If detemines which list/buffer
1376 * was completed and resets it. If the buffer was the last
1377 * in the channel (EOC), then the function checks to see if
1378 * another buffer is ready to send, and if so, sends a Tx
1379 * Go command. Finally, the driver activates/continues the
1380 * activity LED.
1381 *
1382 **************************************************************/
1383
Harvey Harrison98e0f522008-02-18 10:04:38 -08001384static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385{
1386 TLanPrivateInfo *priv = netdev_priv(dev);
1387 int eoc = 0;
1388 TLanList *head_list;
1389 dma_addr_t head_list_phys;
1390 u32 ack = 0;
1391 u16 tmpCStat;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001392
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
1394 head_list = priv->txList + priv->txHead;
1395
1396 while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
1397 ack++;
1398 if ( ! bbuf ) {
1399 struct sk_buff *skb = TLan_GetSKB(head_list);
1400 pci_unmap_single(priv->pciDev, head_list->buffer[0].address, skb->len, PCI_DMA_TODEVICE);
1401 dev_kfree_skb_any(skb);
1402 head_list->buffer[8].address = 0;
1403 head_list->buffer[9].address = 0;
1404 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001405
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 if ( tmpCStat & TLAN_CSTAT_EOC )
1407 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001408
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001409 dev->stats.tx_bytes += head_list->frameSize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410
1411 head_list->cStat = TLAN_CSTAT_UNUSED;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001412 netif_start_queue(dev);
1413 CIRC_INC( priv->txHead, TLAN_NUM_TX_LISTS );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 head_list = priv->txList + priv->txHead;
1415 }
1416
1417 if (!ack)
1418 printk(KERN_INFO "TLAN: Received interrupt for uncompleted TX frame.\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001419
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 if ( eoc ) {
1421 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
1422 head_list = priv->txList + priv->txHead;
1423 head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead;
1424 if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
1425 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM );
1426 ack |= TLAN_HC_GO;
1427 } else {
1428 priv->txInProgress = 0;
1429 }
1430 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001431
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
1433 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
1434 if ( priv->timer.function == NULL ) {
1435 priv->timer.function = &TLan_Timer;
1436 priv->timer.data = (unsigned long) dev;
1437 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1438 priv->timerSetAt = jiffies;
1439 priv->timerType = TLAN_TIMER_ACTIVITY;
1440 add_timer(&priv->timer);
1441 } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
1442 priv->timerSetAt = jiffies;
1443 }
1444 }
1445
1446 return ack;
1447
1448} /* TLan_HandleTxEOF */
1449
1450
1451
1452
1453 /***************************************************************
1454 * TLan_HandleStatOverflow
1455 *
1456 * Returns:
1457 * 1
1458 * Parms:
1459 * dev Device assigned the IRQ that was
1460 * raised.
1461 * host_int The contents of the HOST_INT
1462 * port.
1463 *
1464 * This function handles the Statistics Overflow interrupt
1465 * which means that one or more of the TLAN statistics
1466 * registers has reached 1/2 capacity and needs to be read.
1467 *
1468 **************************************************************/
1469
Harvey Harrison98e0f522008-02-18 10:04:38 -08001470static u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471{
1472 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1473
1474 return 1;
1475
1476} /* TLan_HandleStatOverflow */
1477
1478
1479
1480
1481 /***************************************************************
1482 * TLan_HandleRxEOF
1483 *
1484 * Returns:
1485 * 1
1486 * Parms:
1487 * dev Device assigned the IRQ that was
1488 * raised.
1489 * host_int The contents of the HOST_INT
1490 * port.
1491 *
1492 * This function handles the Rx EOF interrupt which
1493 * indicates a frame has been received by the adapter from
1494 * the net and the frame has been transferred to memory.
1495 * The function determines the bounce buffer the frame has
1496 * been loaded into, creates a new sk_buff big enough to
1497 * hold the frame, and sends it to protocol stack. It
1498 * then resets the used buffer and appends it to the end
1499 * of the list. If the frame was the last in the Rx
1500 * channel (EOC), the function restarts the receive channel
1501 * by sending an Rx Go command to the adapter. Then it
1502 * activates/continues the activity LED.
1503 *
1504 **************************************************************/
1505
Harvey Harrison98e0f522008-02-18 10:04:38 -08001506static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507{
1508 TLanPrivateInfo *priv = netdev_priv(dev);
1509 u32 ack = 0;
1510 int eoc = 0;
1511 u8 *head_buffer;
1512 TLanList *head_list;
1513 struct sk_buff *skb;
1514 TLanList *tail_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 u16 tmpCStat;
1516 dma_addr_t head_list_phys;
1517
1518 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOF (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
1519 head_list = priv->rxList + priv->rxHead;
1520 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001521
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001523 dma_addr_t frameDma = head_list->buffer[0].address;
1524 u32 frameSize = head_list->frameSize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 ack++;
1526 if (tmpCStat & TLAN_CSTAT_EOC)
1527 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001528
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 if (bbuf) {
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001530 skb = netdev_alloc_skb(dev, frameSize + 7);
1531 if ( skb ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 head_buffer = priv->rxBuffer + (priv->rxHead * TLAN_MAX_FRAME_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533 skb_reserve(skb, 2);
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001534 pci_dma_sync_single_for_cpu(priv->pciDev,
1535 frameDma, frameSize,
1536 PCI_DMA_FROMDEVICE);
1537 skb_copy_from_linear_data(skb, head_buffer, frameSize);
1538 skb_put(skb, frameSize);
1539 dev->stats.rx_bytes += frameSize;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001540
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 skb->protocol = eth_type_trans( skb, dev );
1542 netif_rx( skb );
1543 }
1544 } else {
1545 struct sk_buff *new_skb;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001546
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001547 new_skb = netdev_alloc_skb(dev, TLAN_MAX_FRAME_SIZE + 7 );
1548 if ( new_skb ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 skb = TLan_GetSKB(head_list);
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001550 pci_unmap_single(priv->pciDev, frameDma, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Stephen Hemminger93e16842008-05-30 09:49:55 -07001551 skb_put( skb, frameSize );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001553 dev->stats.rx_bytes += frameSize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554
1555 skb->protocol = eth_type_trans( skb, dev );
1556 netif_rx( skb );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001557
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001558 skb_reserve( new_skb, NET_IP_ALIGN );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 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 -07001560
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 TLan_StoreSKB(head_list, new_skb);
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001562 }
1563
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 }
1565
1566 head_list->forward = 0;
1567 head_list->cStat = 0;
1568 tail_list = priv->rxList + priv->rxTail;
1569 tail_list->forward = head_list_phys;
1570
1571 CIRC_INC( priv->rxHead, TLAN_NUM_RX_LISTS );
1572 CIRC_INC( priv->rxTail, TLAN_NUM_RX_LISTS );
1573 head_list = priv->rxList + priv->rxHead;
1574 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1575 }
1576
1577 if (!ack)
1578 printk(KERN_INFO "TLAN: Received interrupt for uncompleted RX frame.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579
1580
1581
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001582
1583 if ( eoc ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
1585 head_list = priv->rxList + priv->rxHead;
1586 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1587 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM );
1588 ack |= TLAN_HC_GO | TLAN_HC_RT;
1589 priv->rxEocCount++;
1590 }
1591
1592 if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
1593 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
1594 if ( priv->timer.function == NULL ) {
1595 priv->timer.function = &TLan_Timer;
1596 priv->timer.data = (unsigned long) dev;
1597 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1598 priv->timerSetAt = jiffies;
1599 priv->timerType = TLAN_TIMER_ACTIVITY;
1600 add_timer(&priv->timer);
1601 } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
1602 priv->timerSetAt = jiffies;
1603 }
1604 }
1605
1606 dev->last_rx = jiffies;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001607
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 return ack;
1609
1610} /* TLan_HandleRxEOF */
1611
1612
1613
1614
1615 /***************************************************************
1616 * TLan_HandleDummy
1617 *
1618 * Returns:
1619 * 1
1620 * Parms:
1621 * dev Device assigned the IRQ that was
1622 * raised.
1623 * host_int The contents of the HOST_INT
1624 * port.
1625 *
1626 * This function handles the Dummy interrupt, which is
1627 * raised whenever a test interrupt is generated by setting
1628 * the Req_Int bit of HOST_CMD to 1.
1629 *
1630 **************************************************************/
1631
Harvey Harrison98e0f522008-02-18 10:04:38 -08001632static u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633{
1634 printk( "TLAN: Test interrupt on %s.\n", dev->name );
1635 return 1;
1636
1637} /* TLan_HandleDummy */
1638
1639
1640
1641
1642 /***************************************************************
1643 * TLan_HandleTxEOC
1644 *
1645 * Returns:
1646 * 1
1647 * Parms:
1648 * dev Device assigned the IRQ that was
1649 * raised.
1650 * host_int The contents of the HOST_INT
1651 * port.
1652 *
1653 * This driver is structured to determine EOC occurrences by
1654 * reading the CSTAT member of the list structure. Tx EOC
1655 * interrupts are disabled via the DIO INTDIS register.
1656 * However, TLAN chips before revision 3.0 didn't have this
1657 * functionality, so process EOC events if this is the
1658 * case.
1659 *
1660 **************************************************************/
1661
Harvey Harrison98e0f522008-02-18 10:04:38 -08001662static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663{
1664 TLanPrivateInfo *priv = netdev_priv(dev);
1665 TLanList *head_list;
1666 dma_addr_t head_list_phys;
1667 u32 ack = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001668
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 host_int = 0;
1670 if ( priv->tlanRev < 0x30 ) {
1671 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d) -- IRQ\n", priv->txHead, priv->txTail );
1672 head_list = priv->txList + priv->txHead;
1673 head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead;
1674 if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
1675 netif_stop_queue(dev);
1676 outl( head_list_phys, dev->base_addr + TLAN_CH_PARM );
1677 ack |= TLAN_HC_GO;
1678 } else {
1679 priv->txInProgress = 0;
1680 }
1681 }
1682
1683 return ack;
1684
1685} /* TLan_HandleTxEOC */
1686
1687
1688
1689
1690 /***************************************************************
1691 * TLan_HandleStatusCheck
1692 *
1693 * Returns:
1694 * 0 if Adapter check, 1 if Network Status check.
1695 * Parms:
1696 * dev Device assigned the IRQ that was
1697 * raised.
1698 * host_int The contents of the HOST_INT
1699 * port.
1700 *
1701 * This function handles Adapter Check/Network Status
1702 * interrupts generated by the adapter. It checks the
1703 * vector in the HOST_INT register to determine if it is
1704 * an Adapter Check interrupt. If so, it resets the
1705 * adapter. Otherwise it clears the status registers
1706 * and services the PHY.
1707 *
1708 **************************************************************/
1709
Harvey Harrison98e0f522008-02-18 10:04:38 -08001710static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001711{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 TLanPrivateInfo *priv = netdev_priv(dev);
1713 u32 ack;
1714 u32 error;
1715 u8 net_sts;
1716 u32 phy;
1717 u16 tlphy_ctl;
1718 u16 tlphy_sts;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001719
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 ack = 1;
1721 if ( host_int & TLAN_HI_IV_MASK ) {
1722 netif_stop_queue( dev );
1723 error = inl( dev->base_addr + TLAN_CH_PARM );
1724 printk( "TLAN: %s: Adaptor Error = 0x%x\n", dev->name, error );
1725 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1726 outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
1727
1728 schedule_work(&priv->tlan_tqueue);
1729
1730 netif_wake_queue(dev);
1731 ack = 0;
1732 } else {
1733 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name );
1734 phy = priv->phy[priv->phyNum];
1735
1736 net_sts = TLan_DioRead8( dev->base_addr, TLAN_NET_STS );
1737 if ( net_sts ) {
1738 TLan_DioWrite8( dev->base_addr, TLAN_NET_STS, net_sts );
1739 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n", dev->name, (unsigned) net_sts );
1740 }
1741 if ( ( net_sts & TLAN_NET_STS_MIRQ ) && ( priv->phyNum == 0 ) ) {
1742 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_STS, &tlphy_sts );
1743 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
1744 if ( ! ( tlphy_sts & TLAN_TS_POLOK ) && ! ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
1745 tlphy_ctl |= TLAN_TC_SWAPOL;
1746 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
1747 } else if ( ( tlphy_sts & TLAN_TS_POLOK ) && ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
1748 tlphy_ctl &= ~TLAN_TC_SWAPOL;
1749 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
1750 }
1751
1752 if (debug) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001753 TLan_PhyPrint( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 }
1755 }
1756 }
1757
1758 return ack;
1759
1760} /* TLan_HandleStatusCheck */
1761
1762
1763
1764
1765 /***************************************************************
1766 * TLan_HandleRxEOC
1767 *
1768 * Returns:
1769 * 1
1770 * Parms:
1771 * dev Device assigned the IRQ that was
1772 * raised.
1773 * host_int The contents of the HOST_INT
1774 * port.
1775 *
1776 * This driver is structured to determine EOC occurrences by
1777 * reading the CSTAT member of the list structure. Rx EOC
1778 * interrupts are disabled via the DIO INTDIS register.
1779 * However, TLAN chips before revision 3.0 didn't have this
1780 * CSTAT member or a INTDIS register, so if this chip is
1781 * pre-3.0, process EOC interrupts normally.
1782 *
1783 **************************************************************/
1784
Harvey Harrison98e0f522008-02-18 10:04:38 -08001785static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786{
1787 TLanPrivateInfo *priv = netdev_priv(dev);
1788 dma_addr_t head_list_phys;
1789 u32 ack = 1;
1790
1791 if ( priv->tlanRev < 0x30 ) {
1792 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d) -- IRQ\n", priv->rxHead, priv->rxTail );
1793 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1794 outl( head_list_phys, dev->base_addr + TLAN_CH_PARM );
1795 ack |= TLAN_HC_GO | TLAN_HC_RT;
1796 priv->rxEocCount++;
1797 }
1798
1799 return ack;
1800
1801} /* TLan_HandleRxEOC */
1802
1803
1804
1805
1806/*****************************************************************************
1807******************************************************************************
1808
1809 ThunderLAN Driver Timer Function
1810
1811******************************************************************************
1812*****************************************************************************/
1813
1814
1815 /***************************************************************
1816 * TLan_Timer
1817 *
1818 * Returns:
1819 * Nothing
1820 * Parms:
1821 * data A value given to add timer when
1822 * add_timer was called.
1823 *
1824 * This function handles timed functionality for the
1825 * TLAN driver. The two current timer uses are for
1826 * delaying for autonegotionation and driving the ACT LED.
1827 * - Autonegotiation requires being allowed about
1828 * 2 1/2 seconds before attempting to transmit a
1829 * packet. It would be a very bad thing to hang
1830 * the kernel this long, so the driver doesn't
1831 * allow transmission 'til after this time, for
1832 * certain PHYs. It would be much nicer if all
1833 * PHYs were interrupt-capable like the internal
1834 * PHY.
1835 * - The ACT LED, which shows adapter activity, is
1836 * driven by the driver, and so must be left on
1837 * for a short period to power up the LED so it
1838 * can be seen. This delay can be changed by
1839 * changing the TLAN_TIMER_ACT_DELAY in tlan.h,
1840 * if desired. 100 ms produces a slightly
1841 * sluggish response.
1842 *
1843 **************************************************************/
1844
Harvey Harrison98e0f522008-02-18 10:04:38 -08001845static void TLan_Timer( unsigned long data )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846{
1847 struct net_device *dev = (struct net_device *) data;
1848 TLanPrivateInfo *priv = netdev_priv(dev);
1849 u32 elapsed;
1850 unsigned long flags = 0;
1851
1852 priv->timer.function = NULL;
1853
1854 switch ( priv->timerType ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001855#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 case TLAN_TIMER_LINK_BEAT:
1857 TLan_PhyMonitor( dev );
1858 break;
1859#endif
1860 case TLAN_TIMER_PHY_PDOWN:
1861 TLan_PhyPowerDown( dev );
1862 break;
1863 case TLAN_TIMER_PHY_PUP:
1864 TLan_PhyPowerUp( dev );
1865 break;
1866 case TLAN_TIMER_PHY_RESET:
1867 TLan_PhyReset( dev );
1868 break;
1869 case TLAN_TIMER_PHY_START_LINK:
1870 TLan_PhyStartLink( dev );
1871 break;
1872 case TLAN_TIMER_PHY_FINISH_AN:
1873 TLan_PhyFinishAutoNeg( dev );
1874 break;
1875 case TLAN_TIMER_FINISH_RESET:
1876 TLan_FinishReset( dev );
1877 break;
1878 case TLAN_TIMER_ACTIVITY:
1879 spin_lock_irqsave(&priv->lock, flags);
1880 if ( priv->timer.function == NULL ) {
1881 elapsed = jiffies - priv->timerSetAt;
1882 if ( elapsed >= TLAN_TIMER_ACT_DELAY ) {
1883 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
1884 } else {
1885 priv->timer.function = &TLan_Timer;
1886 priv->timer.expires = priv->timerSetAt + TLAN_TIMER_ACT_DELAY;
1887 spin_unlock_irqrestore(&priv->lock, flags);
1888 add_timer( &priv->timer );
1889 break;
1890 }
1891 }
1892 spin_unlock_irqrestore(&priv->lock, flags);
1893 break;
1894 default:
1895 break;
1896 }
1897
1898} /* TLan_Timer */
1899
1900
1901
1902
1903/*****************************************************************************
1904******************************************************************************
1905
1906 ThunderLAN Driver Adapter Related Routines
1907
1908******************************************************************************
1909*****************************************************************************/
1910
1911
1912 /***************************************************************
1913 * TLan_ResetLists
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001914 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 * Returns:
1916 * Nothing
1917 * Parms:
1918 * dev The device structure with the list
1919 * stuctures to be reset.
1920 *
1921 * This routine sets the variables associated with managing
1922 * the TLAN lists to their initial values.
1923 *
1924 **************************************************************/
1925
Harvey Harrison98e0f522008-02-18 10:04:38 -08001926static void TLan_ResetLists( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927{
1928 TLanPrivateInfo *priv = netdev_priv(dev);
1929 int i;
1930 TLanList *list;
1931 dma_addr_t list_phys;
1932 struct sk_buff *skb;
1933 void *t = NULL;
1934
1935 priv->txHead = 0;
1936 priv->txTail = 0;
1937 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
1938 list = priv->txList + i;
1939 list->cStat = TLAN_CSTAT_UNUSED;
1940 if ( bbuf ) {
1941 list->buffer[0].address = priv->txBufferDMA + ( i * TLAN_MAX_FRAME_SIZE );
1942 } else {
1943 list->buffer[0].address = 0;
1944 }
1945 list->buffer[2].count = 0;
1946 list->buffer[2].address = 0;
1947 list->buffer[8].address = 0;
1948 list->buffer[9].address = 0;
1949 }
1950
1951 priv->rxHead = 0;
1952 priv->rxTail = TLAN_NUM_RX_LISTS - 1;
1953 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
1954 list = priv->rxList + i;
1955 list_phys = priv->rxListDMA + sizeof(TLanList) * i;
1956 list->cStat = TLAN_CSTAT_READY;
1957 list->frameSize = TLAN_MAX_FRAME_SIZE;
1958 list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
1959 if ( bbuf ) {
1960 list->buffer[0].address = priv->rxBufferDMA + ( i * TLAN_MAX_FRAME_SIZE );
1961 } else {
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001962 skb = netdev_alloc_skb(dev, TLAN_MAX_FRAME_SIZE + 7 );
1963 if ( !skb ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964 printk( "TLAN: Couldn't allocate memory for received data.\n" );
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001965 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966 }
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001967
1968 skb_reserve( skb, NET_IP_ALIGN );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969 list->buffer[0].address = pci_map_single(priv->pciDev, t, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970 TLan_StoreSKB(list, skb);
1971 }
1972 list->buffer[1].count = 0;
1973 list->buffer[1].address = 0;
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001974 list->forward = list_phys + sizeof(TLanList);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975 }
1976
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001977 /* in case ran out of memory early, clear bits */
1978 while (i < TLAN_NUM_RX_LISTS) {
1979 TLan_StoreSKB(priv->rxList + i, NULL);
1980 ++i;
1981 }
1982 list->forward = 0;
1983
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984} /* TLan_ResetLists */
1985
1986
Harvey Harrison98e0f522008-02-18 10:04:38 -08001987static void TLan_FreeLists( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988{
1989 TLanPrivateInfo *priv = netdev_priv(dev);
1990 int i;
1991 TLanList *list;
1992 struct sk_buff *skb;
1993
1994 if ( ! bbuf ) {
1995 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
1996 list = priv->txList + i;
1997 skb = TLan_GetSKB(list);
1998 if ( skb ) {
1999 pci_unmap_single(priv->pciDev, list->buffer[0].address, skb->len, PCI_DMA_TODEVICE);
2000 dev_kfree_skb_any( skb );
2001 list->buffer[8].address = 0;
2002 list->buffer[9].address = 0;
2003 }
2004 }
2005
2006 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
2007 list = priv->rxList + i;
2008 skb = TLan_GetSKB(list);
2009 if ( skb ) {
2010 pci_unmap_single(priv->pciDev, list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
2011 dev_kfree_skb_any( skb );
2012 list->buffer[8].address = 0;
2013 list->buffer[9].address = 0;
2014 }
2015 }
2016 }
2017} /* TLan_FreeLists */
2018
2019
2020
2021
2022 /***************************************************************
2023 * TLan_PrintDio
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002024 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025 * Returns:
2026 * Nothing
2027 * Parms:
2028 * io_base Base IO port of the device of
2029 * which to print DIO registers.
2030 *
2031 * This function prints out all the internal (DIO)
2032 * registers of a TLAN chip.
2033 *
2034 **************************************************************/
2035
Harvey Harrison98e0f522008-02-18 10:04:38 -08002036static void TLan_PrintDio( u16 io_base )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037{
2038 u32 data0, data1;
2039 int i;
2040
2041 printk( "TLAN: Contents of internal registers for io base 0x%04hx.\n", io_base );
2042 printk( "TLAN: Off. +0 +4\n" );
2043 for ( i = 0; i < 0x4C; i+= 8 ) {
2044 data0 = TLan_DioRead32( io_base, i );
2045 data1 = TLan_DioRead32( io_base, i + 0x4 );
2046 printk( "TLAN: 0x%02x 0x%08x 0x%08x\n", i, data0, data1 );
2047 }
2048
2049} /* TLan_PrintDio */
2050
2051
2052
2053
2054 /***************************************************************
2055 * TLan_PrintList
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002056 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057 * Returns:
2058 * Nothing
2059 * Parms:
2060 * list A pointer to the TLanList structure to
2061 * be printed.
2062 * type A string to designate type of list,
2063 * "Rx" or "Tx".
2064 * num The index of the list.
2065 *
2066 * This function prints out the contents of the list
2067 * pointed to by the list parameter.
2068 *
2069 **************************************************************/
2070
Harvey Harrison98e0f522008-02-18 10:04:38 -08002071static void TLan_PrintList( TLanList *list, char *type, int num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002072{
2073 int i;
2074
Stephen Hemminger93e16842008-05-30 09:49:55 -07002075 printk( "TLAN: %s List %d at %p\n", type, num, list );
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076 printk( "TLAN: Forward = 0x%08x\n", list->forward );
2077 printk( "TLAN: CSTAT = 0x%04hx\n", list->cStat );
2078 printk( "TLAN: Frame Size = 0x%04hx\n", list->frameSize );
2079 /* for ( i = 0; i < 10; i++ ) { */
2080 for ( i = 0; i < 2; i++ ) {
2081 printk( "TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n", i, list->buffer[i].count, list->buffer[i].address );
2082 }
2083
2084} /* TLan_PrintList */
2085
2086
2087
2088
2089 /***************************************************************
2090 * TLan_ReadAndClearStats
2091 *
2092 * Returns:
2093 * Nothing
2094 * Parms:
2095 * dev Pointer to device structure of adapter
2096 * to which to read stats.
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002097 * record Flag indicating whether to add
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098 *
2099 * This functions reads all the internal status registers
2100 * of the TLAN chip, which clears them as a side effect.
2101 * It then either adds the values to the device's status
2102 * struct, or discards them, depending on whether record
2103 * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0).
2104 *
2105 **************************************************************/
2106
Harvey Harrison98e0f522008-02-18 10:04:38 -08002107static void TLan_ReadAndClearStats( struct net_device *dev, int record )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109 u32 tx_good, tx_under;
2110 u32 rx_good, rx_over;
2111 u32 def_tx, crc, code;
2112 u32 multi_col, single_col;
2113 u32 excess_col, late_col, loss;
2114
2115 outw( TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR );
2116 tx_good = inb( dev->base_addr + TLAN_DIO_DATA );
2117 tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2118 tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
2119 tx_under = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
2120
2121 outw( TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR );
2122 rx_good = inb( dev->base_addr + TLAN_DIO_DATA );
2123 rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2124 rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
2125 rx_over = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002126
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127 outw( TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR );
2128 def_tx = inb( dev->base_addr + TLAN_DIO_DATA );
2129 def_tx += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2130 crc = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2131 code = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002132
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133 outw( TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
2134 multi_col = inb( dev->base_addr + TLAN_DIO_DATA );
2135 multi_col += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2136 single_col = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2137 single_col += inb( dev->base_addr + TLAN_DIO_DATA + 3 ) << 8;
2138
2139 outw( TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
2140 excess_col = inb( dev->base_addr + TLAN_DIO_DATA );
2141 late_col = inb( dev->base_addr + TLAN_DIO_DATA + 1 );
2142 loss = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2143
2144 if ( record ) {
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002145 dev->stats.rx_packets += rx_good;
2146 dev->stats.rx_errors += rx_over + crc + code;
2147 dev->stats.tx_packets += tx_good;
2148 dev->stats.tx_errors += tx_under + loss;
2149 dev->stats.collisions += multi_col + single_col + excess_col + late_col;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002150
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002151 dev->stats.rx_over_errors += rx_over;
2152 dev->stats.rx_crc_errors += crc;
2153 dev->stats.rx_frame_errors += code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002155 dev->stats.tx_aborted_errors += tx_under;
2156 dev->stats.tx_carrier_errors += loss;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002158
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159} /* TLan_ReadAndClearStats */
2160
2161
2162
2163
2164 /***************************************************************
2165 * TLan_Reset
2166 *
2167 * Returns:
2168 * 0
2169 * Parms:
2170 * dev Pointer to device structure of adapter
2171 * to be reset.
2172 *
2173 * This function resets the adapter and it's physical
2174 * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
2175 * Programmer's Guide" for details. The routine tries to
2176 * implement what is detailed there, though adjustments
2177 * have been made.
2178 *
2179 **************************************************************/
2180
Harvey Harrison98e0f522008-02-18 10:04:38 -08002181static void
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182TLan_ResetAdapter( struct net_device *dev )
2183{
2184 TLanPrivateInfo *priv = netdev_priv(dev);
2185 int i;
2186 u32 addr;
2187 u32 data;
2188 u8 data8;
2189
2190 priv->tlanFullDuplex = FALSE;
2191 priv->phyOnline=0;
2192 netif_carrier_off(dev);
2193
2194/* 1. Assert reset bit. */
2195
2196 data = inl(dev->base_addr + TLAN_HOST_CMD);
2197 data |= TLAN_HC_AD_RST;
2198 outl(data, dev->base_addr + TLAN_HOST_CMD);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002199
Linus Torvalds1da177e2005-04-16 15:20:36 -07002200 udelay(1000);
2201
2202/* 2. Turn off interrupts. ( Probably isn't necessary ) */
2203
2204 data = inl(dev->base_addr + TLAN_HOST_CMD);
2205 data |= TLAN_HC_INT_OFF;
2206 outl(data, dev->base_addr + TLAN_HOST_CMD);
2207
2208/* 3. Clear AREGs and HASHs. */
2209
2210 for ( i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4 ) {
2211 TLan_DioWrite32( dev->base_addr, (u16) i, 0 );
2212 }
2213
2214/* 4. Setup NetConfig register. */
2215
2216 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2217 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
2218
2219/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
2220
2221 outl( TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD );
2222 outl( TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD );
2223
2224/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
2225
2226 outw( TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR );
2227 addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
2228 TLan_SetBit( TLAN_NET_SIO_NMRST, addr );
2229
2230/* 7. Setup the remaining registers. */
2231
2232 if ( priv->tlanRev >= 0x30 ) {
2233 data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
2234 TLan_DioWrite8( dev->base_addr, TLAN_INT_DIS, data8 );
2235 }
2236 TLan_PhyDetect( dev );
2237 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002238
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 if ( priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY ) {
2240 data |= TLAN_NET_CFG_BIT;
2241 if ( priv->aui == 1 ) {
2242 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x0a );
2243 } else if ( priv->duplex == TLAN_DUPLEX_FULL ) {
2244 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x00 );
2245 priv->tlanFullDuplex = TRUE;
2246 } else {
2247 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x08 );
2248 }
2249 }
2250
2251 if ( priv->phyNum == 0 ) {
2252 data |= TLAN_NET_CFG_PHY_EN;
2253 }
2254 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
2255
2256 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2257 TLan_FinishReset( dev );
2258 } else {
2259 TLan_PhyPowerDown( dev );
2260 }
2261
2262} /* TLan_ResetAdapter */
2263
2264
2265
2266
Harvey Harrison98e0f522008-02-18 10:04:38 -08002267static void
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268TLan_FinishReset( struct net_device *dev )
2269{
2270 TLanPrivateInfo *priv = netdev_priv(dev);
2271 u8 data;
2272 u32 phy;
2273 u8 sio;
2274 u16 status;
2275 u16 partner;
2276 u16 tlphy_ctl;
2277 u16 tlphy_par;
2278 u16 tlphy_id1, tlphy_id2;
2279 int i;
2280
2281 phy = priv->phy[priv->phyNum];
2282
2283 data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
2284 if ( priv->tlanFullDuplex ) {
2285 data |= TLAN_NET_CMD_DUPLEX;
2286 }
2287 TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, data );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002288 data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289 if ( priv->phyNum == 0 ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002290 data |= TLAN_NET_MASK_MASK7;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291 }
2292 TLan_DioWrite8( dev->base_addr, TLAN_NET_MASK, data );
2293 TLan_DioWrite16( dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7 );
2294 TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &tlphy_id1 );
2295 TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &tlphy_id2 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002296
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297 if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) || ( priv->aui ) ) {
2298 status = MII_GS_LINK;
2299 printk( "TLAN: %s: Link forced.\n", dev->name );
2300 } else {
2301 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2302 udelay( 1000 );
2303 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002304 if ( (status & MII_GS_LINK) && /* We only support link info on Nat.Sem. PHY's */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305 (tlphy_id1 == NAT_SEM_ID1) &&
2306 (tlphy_id2 == NAT_SEM_ID2) ) {
2307 TLan_MiiReadReg( dev, phy, MII_AN_LPA, &partner );
2308 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_PAR, &tlphy_par );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002309
Linus Torvalds1da177e2005-04-16 15:20:36 -07002310 printk( "TLAN: %s: Link active with ", dev->name );
2311 if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002312 printk( "forced 10%sMbps %s-Duplex\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313 tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
2314 tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
2315 } else {
2316 printk( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n",
2317 tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
2318 tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
2319 printk("TLAN: Partner capability: ");
2320 for (i = 5; i <= 10; i++)
2321 if (partner & (1<<i))
2322 printk("%s",media[i-5]);
2323 printk("\n");
2324 }
2325
2326 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002327#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328 /* We have link beat..for now anyway */
2329 priv->link = 1;
2330 /*Enabling link beat monitoring */
2331 TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_LINK_BEAT );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002332#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333 } else if (status & MII_GS_LINK) {
2334 printk( "TLAN: %s: Link active\n", dev->name );
2335 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
2336 }
2337 }
2338
2339 if ( priv->phyNum == 0 ) {
2340 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
2341 tlphy_ctl |= TLAN_TC_INTEN;
2342 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl );
2343 sio = TLan_DioRead8( dev->base_addr, TLAN_NET_SIO );
2344 sio |= TLAN_NET_SIO_MINTEN;
2345 TLan_DioWrite8( dev->base_addr, TLAN_NET_SIO, sio );
2346 }
2347
2348 if ( status & MII_GS_LINK ) {
2349 TLan_SetMac( dev, 0, dev->dev_addr );
2350 priv->phyOnline = 1;
2351 outb( ( TLAN_HC_INT_ON >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
2352 if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) {
2353 outb( ( TLAN_HC_REQ_INT >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
2354 }
2355 outl( priv->rxListDMA, dev->base_addr + TLAN_CH_PARM );
2356 outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD );
2357 netif_carrier_on(dev);
2358 } else {
2359 printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name );
2360 TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
2361 return;
2362 }
James Harper562faf42005-05-05 15:14:18 -07002363 TLan_SetMulticastList(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364
2365} /* TLan_FinishReset */
2366
2367
2368
2369
2370 /***************************************************************
2371 * TLan_SetMac
2372 *
2373 * Returns:
2374 * Nothing
2375 * Parms:
2376 * dev Pointer to device structure of adapter
2377 * on which to change the AREG.
2378 * areg The AREG to set the address in (0 - 3).
2379 * mac A pointer to an array of chars. Each
2380 * element stores one byte of the address.
2381 * IE, it isn't in ascii.
2382 *
2383 * This function transfers a MAC address to one of the
2384 * TLAN AREGs (address registers). The TLAN chip locks
2385 * the register on writing to offset 0 and unlocks the
2386 * register after writing to offset 5. If NULL is passed
2387 * in mac, then the AREG is filled with 0's.
2388 *
2389 **************************************************************/
2390
Harvey Harrison98e0f522008-02-18 10:04:38 -08002391static void TLan_SetMac( struct net_device *dev, int areg, char *mac )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392{
2393 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002394
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395 areg *= 6;
2396
2397 if ( mac != NULL ) {
2398 for ( i = 0; i < 6; i++ )
2399 TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, mac[i] );
2400 } else {
2401 for ( i = 0; i < 6; i++ )
2402 TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, 0 );
2403 }
2404
2405} /* TLan_SetMac */
2406
2407
2408
2409
2410/*****************************************************************************
2411******************************************************************************
2412
2413 ThunderLAN Driver PHY Layer Routines
2414
2415******************************************************************************
2416*****************************************************************************/
2417
2418
2419
2420 /*********************************************************************
2421 * TLan_PhyPrint
2422 *
2423 * Returns:
2424 * Nothing
2425 * Parms:
2426 * dev A pointer to the device structure of the
2427 * TLAN device having the PHYs to be detailed.
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002428 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429 * This function prints the registers a PHY (aka transceiver).
2430 *
2431 ********************************************************************/
2432
Harvey Harrison98e0f522008-02-18 10:04:38 -08002433static void TLan_PhyPrint( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434{
2435 TLanPrivateInfo *priv = netdev_priv(dev);
2436 u16 i, data0, data1, data2, data3, phy;
2437
2438 phy = priv->phy[priv->phyNum];
2439
2440 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2441 printk( "TLAN: Device %s, Unmanaged PHY.\n", dev->name );
2442 } else if ( phy <= TLAN_PHY_MAX_ADDR ) {
2443 printk( "TLAN: Device %s, PHY 0x%02x.\n", dev->name, phy );
2444 printk( "TLAN: Off. +0 +1 +2 +3 \n" );
2445 for ( i = 0; i < 0x20; i+= 4 ) {
2446 printk( "TLAN: 0x%02x", i );
2447 TLan_MiiReadReg( dev, phy, i, &data0 );
2448 printk( " 0x%04hx", data0 );
2449 TLan_MiiReadReg( dev, phy, i + 1, &data1 );
2450 printk( " 0x%04hx", data1 );
2451 TLan_MiiReadReg( dev, phy, i + 2, &data2 );
2452 printk( " 0x%04hx", data2 );
2453 TLan_MiiReadReg( dev, phy, i + 3, &data3 );
2454 printk( " 0x%04hx\n", data3 );
2455 }
2456 } else {
2457 printk( "TLAN: Device %s, Invalid PHY.\n", dev->name );
2458 }
2459
2460} /* TLan_PhyPrint */
2461
2462
2463
2464
2465 /*********************************************************************
2466 * TLan_PhyDetect
2467 *
2468 * Returns:
2469 * Nothing
2470 * Parms:
2471 * dev A pointer to the device structure of the adapter
2472 * for which the PHY needs determined.
2473 *
2474 * So far I've found that adapters which have external PHYs
2475 * may also use the internal PHY for part of the functionality.
2476 * (eg, AUI/Thinnet). This function finds out if this TLAN
2477 * chip has an internal PHY, and then finds the first external
2478 * PHY (starting from address 0) if it exists).
2479 *
2480 ********************************************************************/
2481
Harvey Harrison98e0f522008-02-18 10:04:38 -08002482static void TLan_PhyDetect( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483{
2484 TLanPrivateInfo *priv = netdev_priv(dev);
2485 u16 control;
2486 u16 hi;
2487 u16 lo;
2488 u32 phy;
2489
2490 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2491 priv->phyNum = 0xFFFF;
2492 return;
2493 }
2494
2495 TLan_MiiReadReg( dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002496
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497 if ( hi != 0xFFFF ) {
2498 priv->phy[0] = TLAN_PHY_MAX_ADDR;
2499 } else {
2500 priv->phy[0] = TLAN_PHY_NONE;
2501 }
2502
2503 priv->phy[1] = TLAN_PHY_NONE;
2504 for ( phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++ ) {
2505 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &control );
2506 TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &hi );
2507 TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &lo );
2508 if ( ( control != 0xFFFF ) || ( hi != 0xFFFF ) || ( lo != 0xFFFF ) ) {
2509 TLAN_DBG( TLAN_DEBUG_GNRL, "PHY found at %02x %04x %04x %04x\n", phy, control, hi, lo );
2510 if ( ( priv->phy[1] == TLAN_PHY_NONE ) && ( phy != TLAN_PHY_MAX_ADDR ) ) {
2511 priv->phy[1] = phy;
2512 }
2513 }
2514 }
2515
2516 if ( priv->phy[1] != TLAN_PHY_NONE ) {
2517 priv->phyNum = 1;
2518 } else if ( priv->phy[0] != TLAN_PHY_NONE ) {
2519 priv->phyNum = 0;
2520 } else {
2521 printk( "TLAN: Cannot initialize device, no PHY was found!\n" );
2522 }
2523
2524} /* TLan_PhyDetect */
2525
2526
2527
2528
Harvey Harrison98e0f522008-02-18 10:04:38 -08002529static void TLan_PhyPowerDown( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530{
2531 TLanPrivateInfo *priv = netdev_priv(dev);
2532 u16 value;
2533
2534 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name );
2535 value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
2536 TLan_MiiSync( dev->base_addr );
2537 TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
2538 if ( ( priv->phyNum == 0 ) && ( priv->phy[1] != TLAN_PHY_NONE ) && ( ! ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) ) ) {
2539 TLan_MiiSync( dev->base_addr );
2540 TLan_MiiWriteReg( dev, priv->phy[1], MII_GEN_CTL, value );
2541 }
2542
2543 /* Wait for 50 ms and powerup
2544 * This is abitrary. It is intended to make sure the
2545 * transceiver settles.
2546 */
2547 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP );
2548
2549} /* TLan_PhyPowerDown */
2550
2551
2552
2553
Harvey Harrison98e0f522008-02-18 10:04:38 -08002554static void TLan_PhyPowerUp( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555{
2556 TLanPrivateInfo *priv = netdev_priv(dev);
2557 u16 value;
2558
2559 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name );
2560 TLan_MiiSync( dev->base_addr );
2561 value = MII_GC_LOOPBK;
2562 TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
2563 TLan_MiiSync(dev->base_addr);
2564 /* Wait for 500 ms and reset the
2565 * transceiver. The TLAN docs say both 50 ms and
2566 * 500 ms, so do the longer, just in case.
2567 */
2568 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET );
2569
2570} /* TLan_PhyPowerUp */
2571
2572
2573
2574
Harvey Harrison98e0f522008-02-18 10:04:38 -08002575static void TLan_PhyReset( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576{
2577 TLanPrivateInfo *priv = netdev_priv(dev);
2578 u16 phy;
2579 u16 value;
2580
2581 phy = priv->phy[priv->phyNum];
2582
2583 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name );
2584 TLan_MiiSync( dev->base_addr );
2585 value = MII_GC_LOOPBK | MII_GC_RESET;
2586 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, value );
2587 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
2588 while ( value & MII_GC_RESET ) {
2589 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
2590 }
2591
2592 /* Wait for 500 ms and initialize.
2593 * I don't remember why I wait this long.
2594 * I've changed this to 50ms, as it seems long enough.
2595 */
2596 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK );
2597
2598} /* TLan_PhyReset */
2599
2600
2601
2602
Harvey Harrison98e0f522008-02-18 10:04:38 -08002603static void TLan_PhyStartLink( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604{
2605 TLanPrivateInfo *priv = netdev_priv(dev);
2606 u16 ability;
2607 u16 control;
2608 u16 data;
2609 u16 phy;
2610 u16 status;
2611 u16 tctl;
2612
2613 phy = priv->phy[priv->phyNum];
2614 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name );
2615 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2616 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &ability );
2617
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002618 if ( ( status & MII_GS_AUTONEG ) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619 ( ! priv->aui ) ) {
2620 ability = status >> 11;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002621 if ( priv->speed == TLAN_SPEED_10 &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622 priv->duplex == TLAN_DUPLEX_HALF) {
2623 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000);
2624 } else if ( priv->speed == TLAN_SPEED_10 &&
2625 priv->duplex == TLAN_DUPLEX_FULL) {
2626 priv->tlanFullDuplex = TRUE;
2627 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100);
2628 } else if ( priv->speed == TLAN_SPEED_100 &&
2629 priv->duplex == TLAN_DUPLEX_HALF) {
2630 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000);
2631 } else if ( priv->speed == TLAN_SPEED_100 &&
2632 priv->duplex == TLAN_DUPLEX_FULL) {
2633 priv->tlanFullDuplex = TRUE;
2634 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100);
2635 } else {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002636
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637 /* Set Auto-Neg advertisement */
2638 TLan_MiiWriteReg( dev, phy, MII_AN_ADV, (ability << 5) | 1);
2639 /* Enablee Auto-Neg */
2640 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 );
2641 /* Restart Auto-Neg */
2642 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 );
2643 /* Wait for 4 sec for autonegotiation
2644 * to complete. The max spec time is less than this
2645 * but the card need additional time to start AN.
2646 * .5 sec should be plenty extra.
2647 */
2648 printk( "TLAN: %s: Starting autonegotiation.\n", dev->name );
2649 TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN );
2650 return;
2651 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002652
2653 }
2654
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655 if ( ( priv->aui ) && ( priv->phyNum != 0 ) ) {
2656 priv->phyNum = 0;
2657 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2658 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
2659 TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN );
2660 return;
2661 } else if ( priv->phyNum == 0 ) {
2662 control = 0;
2663 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tctl );
2664 if ( priv->aui ) {
2665 tctl |= TLAN_TC_AUISEL;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002666 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667 tctl &= ~TLAN_TC_AUISEL;
2668 if ( priv->duplex == TLAN_DUPLEX_FULL ) {
2669 control |= MII_GC_DUPLEX;
2670 priv->tlanFullDuplex = TRUE;
2671 }
2672 if ( priv->speed == TLAN_SPEED_100 ) {
2673 control |= MII_GC_SPEEDSEL;
2674 }
2675 }
2676 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, control );
2677 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl );
2678 }
2679
2680 /* Wait for 2 sec to give the transceiver time
2681 * to establish link.
2682 */
2683 TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET );
2684
2685} /* TLan_PhyStartLink */
2686
2687
2688
2689
Harvey Harrison98e0f522008-02-18 10:04:38 -08002690static void TLan_PhyFinishAutoNeg( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691{
2692 TLanPrivateInfo *priv = netdev_priv(dev);
2693 u16 an_adv;
2694 u16 an_lpa;
2695 u16 data;
2696 u16 mode;
2697 u16 phy;
2698 u16 status;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002699
Linus Torvalds1da177e2005-04-16 15:20:36 -07002700 phy = priv->phy[priv->phyNum];
2701
2702 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2703 udelay( 1000 );
2704 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2705
2706 if ( ! ( status & MII_GS_AUTOCMPLT ) ) {
2707 /* Wait for 8 sec to give the process
2708 * more time. Perhaps we should fail after a while.
2709 */
2710 if (!priv->neg_be_verbose++) {
2711 printk(KERN_INFO "TLAN: Giving autonegotiation more time.\n");
2712 printk(KERN_INFO "TLAN: Please check that your adapter has\n");
2713 printk(KERN_INFO "TLAN: been properly connected to a HUB or Switch.\n");
2714 printk(KERN_INFO "TLAN: Trying to establish link in the background...\n");
2715 }
2716 TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN );
2717 return;
2718 }
2719
2720 printk( "TLAN: %s: Autonegotiation complete.\n", dev->name );
2721 TLan_MiiReadReg( dev, phy, MII_AN_ADV, &an_adv );
2722 TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa );
2723 mode = an_adv & an_lpa & 0x03E0;
2724 if ( mode & 0x0100 ) {
2725 priv->tlanFullDuplex = TRUE;
2726 } else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) {
2727 priv->tlanFullDuplex = TRUE;
2728 }
2729
2730 if ( ( ! ( mode & 0x0180 ) ) && ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) && ( priv->phyNum != 0 ) ) {
2731 priv->phyNum = 0;
2732 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2733 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
2734 TLan_SetTimer( dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN );
2735 return;
2736 }
2737
2738 if ( priv->phyNum == 0 ) {
2739 if ( ( priv->duplex == TLAN_DUPLEX_FULL ) || ( an_adv & an_lpa & 0x0040 ) ) {
2740 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB | MII_GC_DUPLEX );
2741 printk( "TLAN: Starting internal PHY with FULL-DUPLEX\n" );
2742 } else {
2743 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB );
2744 printk( "TLAN: Starting internal PHY with HALF-DUPLEX\n" );
2745 }
2746 }
2747
2748 /* Wait for 100 ms. No reason in partiticular.
2749 */
2750 TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002751
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752} /* TLan_PhyFinishAutoNeg */
2753
2754#ifdef MONITOR
2755
2756 /*********************************************************************
2757 *
2758 * TLan_phyMonitor
2759 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002760 * Returns:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002761 * None
2762 *
2763 * Params:
2764 * dev The device structure of this device.
2765 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002766 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767 * This function monitors PHY condition by reading the status
2768 * register via the MII bus. This can be used to give info
2769 * about link changes (up/down), and possible switch to alternate
2770 * media.
2771 *
2772 * ******************************************************************/
2773
2774void TLan_PhyMonitor( struct net_device *dev )
2775{
2776 TLanPrivateInfo *priv = netdev_priv(dev);
2777 u16 phy;
2778 u16 phy_status;
2779
2780 phy = priv->phy[priv->phyNum];
2781
2782 /* Get PHY status register */
2783 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &phy_status );
2784
2785 /* Check if link has been lost */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002786 if (!(phy_status & MII_GS_LINK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787 if (priv->link) {
2788 priv->link = 0;
2789 printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name);
7d17c1d2005-05-12 19:45:25 -04002790 netif_carrier_off(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002791 TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
2792 return;
2793 }
2794 }
2795
2796 /* Link restablished? */
2797 if ((phy_status & MII_GS_LINK) && !priv->link) {
2798 priv->link = 1;
2799 printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);
7d17c1d2005-05-12 19:45:25 -04002800 netif_carrier_on(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801 }
2802
2803 /* Setup a new monitor */
2804 TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002805}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002806
2807#endif /* MONITOR */
2808
2809
2810/*****************************************************************************
2811******************************************************************************
2812
2813 ThunderLAN Driver MII Routines
2814
2815 These routines are based on the information in Chap. 2 of the
2816 "ThunderLAN Programmer's Guide", pp. 15-24.
2817
2818******************************************************************************
2819*****************************************************************************/
2820
2821
2822 /***************************************************************
2823 * TLan_MiiReadReg
2824 *
2825 * Returns:
2826 * 0 if ack received ok
2827 * 1 otherwise.
2828 *
2829 * Parms:
2830 * dev The device structure containing
2831 * The io address and interrupt count
2832 * for this device.
2833 * phy The address of the PHY to be queried.
2834 * reg The register whose contents are to be
Matt Mackall4a4efbd2006-01-03 13:27:11 +01002835 * retrieved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836 * val A pointer to a variable to store the
2837 * retrieved value.
2838 *
Matt Mackall4a4efbd2006-01-03 13:27:11 +01002839 * This function uses the TLAN's MII bus to retrieve the contents
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840 * of a given register on a PHY. It sends the appropriate info
2841 * and then reads the 16-bit register value from the MII bus via
2842 * the TLAN SIO register.
2843 *
2844 **************************************************************/
2845
Harvey Harrison98e0f522008-02-18 10:04:38 -08002846static int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847{
2848 u8 nack;
2849 u16 sio, tmp;
2850 u32 i;
2851 int err;
2852 int minten;
2853 TLanPrivateInfo *priv = netdev_priv(dev);
2854 unsigned long flags = 0;
2855
2856 err = FALSE;
2857 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2858 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002859
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 if (!in_irq())
2861 spin_lock_irqsave(&priv->lock, flags);
2862
2863 TLan_MiiSync(dev->base_addr);
2864
2865 minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );
2866 if ( minten )
2867 TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);
2868
2869 TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Start ( 01b ) */
2870 TLan_MiiSendData( dev->base_addr, 0x2, 2 ); /* Read ( 10b ) */
2871 TLan_MiiSendData( dev->base_addr, phy, 5 ); /* Device # */
2872 TLan_MiiSendData( dev->base_addr, reg, 5 ); /* Register # */
2873
2874
2875 TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); /* Change direction */
2876
2877 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Clock Idle bit */
2878 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2879 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Wait 300ns */
2880
2881 nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio); /* Check for ACK */
2882 TLan_SetBit(TLAN_NET_SIO_MCLK, sio); /* Finish ACK */
2883 if (nack) { /* No ACK, so fake it */
2884 for (i = 0; i < 16; i++) {
2885 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
2886 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2887 }
2888 tmp = 0xffff;
2889 err = TRUE;
2890 } else { /* ACK, so read data */
2891 for (tmp = 0, i = 0x8000; i; i >>= 1) {
2892 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
2893 if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio))
2894 tmp |= i;
2895 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2896 }
2897 }
2898
2899
2900 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */
2901 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2902
2903 if ( minten )
2904 TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);
2905
2906 *val = tmp;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002907
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908 if (!in_irq())
2909 spin_unlock_irqrestore(&priv->lock, flags);
2910
2911 return err;
2912
2913} /* TLan_MiiReadReg */
2914
2915
2916
2917
2918 /***************************************************************
2919 * TLan_MiiSendData
2920 *
2921 * Returns:
2922 * Nothing
2923 * Parms:
2924 * base_port The base IO port of the adapter in
2925 * question.
2926 * dev The address of the PHY to be queried.
2927 * data The value to be placed on the MII bus.
2928 * num_bits The number of bits in data that are to
2929 * be placed on the MII bus.
2930 *
2931 * This function sends on sequence of bits on the MII
2932 * configuration bus.
2933 *
2934 **************************************************************/
2935
Harvey Harrison98e0f522008-02-18 10:04:38 -08002936static void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937{
2938 u16 sio;
2939 u32 i;
2940
2941 if ( num_bits == 0 )
2942 return;
2943
2944 outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );
2945 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
2946 TLan_SetBit( TLAN_NET_SIO_MTXEN, sio );
2947
2948 for ( i = ( 0x1 << ( num_bits - 1 ) ); i; i >>= 1 ) {
2949 TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
2950 (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
2951 if ( data & i )
2952 TLan_SetBit( TLAN_NET_SIO_MDATA, sio );
2953 else
2954 TLan_ClearBit( TLAN_NET_SIO_MDATA, sio );
2955 TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
2956 (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
2957 }
2958
2959} /* TLan_MiiSendData */
2960
2961
2962
2963
2964 /***************************************************************
2965 * TLan_MiiSync
2966 *
2967 * Returns:
2968 * Nothing
2969 * Parms:
2970 * base_port The base IO port of the adapter in
2971 * question.
2972 *
2973 * This functions syncs all PHYs in terms of the MII configuration
2974 * bus.
2975 *
2976 **************************************************************/
2977
Harvey Harrison98e0f522008-02-18 10:04:38 -08002978static void TLan_MiiSync( u16 base_port )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979{
2980 int i;
2981 u16 sio;
2982
2983 outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );
2984 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
2985
2986 TLan_ClearBit( TLAN_NET_SIO_MTXEN, sio );
2987 for ( i = 0; i < 32; i++ ) {
2988 TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
2989 TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
2990 }
2991
2992} /* TLan_MiiSync */
2993
2994
2995
2996
2997 /***************************************************************
2998 * TLan_MiiWriteReg
2999 *
3000 * Returns:
3001 * Nothing
3002 * Parms:
3003 * dev The device structure for the device
3004 * to write to.
3005 * phy The address of the PHY to be written to.
3006 * reg The register whose contents are to be
3007 * written.
3008 * val The value to be written to the register.
3009 *
3010 * This function uses the TLAN's MII bus to write the contents of a
3011 * given register on a PHY. It sends the appropriate info and then
3012 * writes the 16-bit register value from the MII configuration bus
3013 * via the TLAN SIO register.
3014 *
3015 **************************************************************/
3016
Harvey Harrison98e0f522008-02-18 10:04:38 -08003017static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018{
3019 u16 sio;
3020 int minten;
3021 unsigned long flags = 0;
3022 TLanPrivateInfo *priv = netdev_priv(dev);
3023
3024 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
3025 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003026
Linus Torvalds1da177e2005-04-16 15:20:36 -07003027 if (!in_irq())
3028 spin_lock_irqsave(&priv->lock, flags);
3029
3030 TLan_MiiSync( dev->base_addr );
3031
3032 minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );
3033 if ( minten )
3034 TLan_ClearBit( TLAN_NET_SIO_MINTEN, sio );
3035
3036 TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Start ( 01b ) */
3037 TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Write ( 01b ) */
3038 TLan_MiiSendData( dev->base_addr, phy, 5 ); /* Device # */
3039 TLan_MiiSendData( dev->base_addr, reg, 5 ); /* Register # */
3040
3041 TLan_MiiSendData( dev->base_addr, 0x2, 2 ); /* Send ACK */
3042 TLan_MiiSendData( dev->base_addr, val, 16 ); /* Send Data */
3043
3044 TLan_ClearBit( TLAN_NET_SIO_MCLK, sio ); /* Idle cycle */
3045 TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
3046
3047 if ( minten )
3048 TLan_SetBit( TLAN_NET_SIO_MINTEN, sio );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003049
Linus Torvalds1da177e2005-04-16 15:20:36 -07003050 if (!in_irq())
3051 spin_unlock_irqrestore(&priv->lock, flags);
3052
3053} /* TLan_MiiWriteReg */
3054
3055
3056
3057
3058/*****************************************************************************
3059******************************************************************************
3060
3061 ThunderLAN Driver Eeprom routines
3062
3063 The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A
3064 EEPROM. These functions are based on information in Microchip's
3065 data sheet. I don't know how well this functions will work with
3066 other EEPROMs.
3067
3068******************************************************************************
3069*****************************************************************************/
3070
3071
3072 /***************************************************************
3073 * TLan_EeSendStart
3074 *
3075 * Returns:
3076 * Nothing
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003077 * Parms:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003078 * io_base The IO port base address for the
3079 * TLAN device with the EEPROM to
3080 * use.
3081 *
3082 * This function sends a start cycle to an EEPROM attached
3083 * to a TLAN chip.
3084 *
3085 **************************************************************/
3086
Harvey Harrison98e0f522008-02-18 10:04:38 -08003087static void TLan_EeSendStart( u16 io_base )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003088{
3089 u16 sio;
3090
3091 outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
3092 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3093
3094 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3095 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3096 TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
3097 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
3098 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3099
3100} /* TLan_EeSendStart */
3101
3102
3103
3104
3105 /***************************************************************
3106 * TLan_EeSendByte
3107 *
3108 * Returns:
3109 * If the correct ack was received, 0, otherwise 1
3110 * Parms: io_base The IO port base address for the
3111 * TLAN device with the EEPROM to
3112 * use.
3113 * data The 8 bits of information to
3114 * send to the EEPROM.
3115 * stop If TLAN_EEPROM_STOP is passed, a
3116 * stop cycle is sent after the
3117 * byte is sent after the ack is
3118 * read.
3119 *
3120 * This function sends a byte on the serial EEPROM line,
3121 * driving the clock to send each bit. The function then
3122 * reverses transmission direction and reads an acknowledge
3123 * bit.
3124 *
3125 **************************************************************/
3126
Harvey Harrison98e0f522008-02-18 10:04:38 -08003127static int TLan_EeSendByte( u16 io_base, u8 data, int stop )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003128{
3129 int err;
3130 u8 place;
3131 u16 sio;
3132
3133 outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
3134 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3135
3136 /* Assume clock is low, tx is enabled; */
3137 for ( place = 0x80; place != 0; place >>= 1 ) {
3138 if ( place & data )
3139 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3140 else
3141 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
3142 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3143 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3144 }
3145 TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
3146 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3147 err = TLan_GetBit( TLAN_NET_SIO_EDATA, sio );
3148 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3149 TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
3150
3151 if ( ( ! err ) && stop ) {
3152 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* STOP, raise data while clock is high */
3153 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3154 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3155 }
3156
3157 return ( err );
3158
3159} /* TLan_EeSendByte */
3160
3161
3162
3163
3164 /***************************************************************
3165 * TLan_EeReceiveByte
3166 *
3167 * Returns:
3168 * Nothing
3169 * Parms:
3170 * io_base The IO port base address for the
3171 * TLAN device with the EEPROM to
3172 * use.
3173 * data An address to a char to hold the
3174 * data sent from the EEPROM.
3175 * stop If TLAN_EEPROM_STOP is passed, a
3176 * stop cycle is sent after the
3177 * byte is received, and no ack is
3178 * sent.
3179 *
3180 * This function receives 8 bits of data from the EEPROM
3181 * over the serial link. It then sends and ack bit, or no
3182 * ack and a stop bit. This function is used to retrieve
3183 * data after the address of a byte in the EEPROM has been
3184 * sent.
3185 *
3186 **************************************************************/
3187
Harvey Harrison98e0f522008-02-18 10:04:38 -08003188static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189{
3190 u8 place;
3191 u16 sio;
3192
3193 outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
3194 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3195 *data = 0;
3196
3197 /* Assume clock is low, tx is enabled; */
3198 TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
3199 for ( place = 0x80; place; place >>= 1 ) {
3200 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3201 if ( TLan_GetBit( TLAN_NET_SIO_EDATA, sio ) )
3202 *data |= place;
3203 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3204 }
3205
3206 TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
3207 if ( ! stop ) {
3208 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* Ack = 0 */
3209 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3210 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3211 } else {
3212 TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); /* No ack = 1 (?) */
3213 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3214 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3215 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* STOP, raise data while clock is high */
3216 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3217 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3218 }
3219
3220} /* TLan_EeReceiveByte */
3221
3222
3223
3224
3225 /***************************************************************
3226 * TLan_EeReadByte
3227 *
3228 * Returns:
3229 * No error = 0, else, the stage at which the error
3230 * occurred.
3231 * Parms:
3232 * io_base The IO port base address for the
3233 * TLAN device with the EEPROM to
3234 * use.
3235 * ee_addr The address of the byte in the
3236 * EEPROM whose contents are to be
3237 * retrieved.
3238 * data An address to a char to hold the
3239 * data obtained from the EEPROM.
3240 *
3241 * This function reads a byte of information from an byte
3242 * cell in the EEPROM.
3243 *
3244 **************************************************************/
3245
Harvey Harrison98e0f522008-02-18 10:04:38 -08003246static int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003247{
3248 int err;
3249 TLanPrivateInfo *priv = netdev_priv(dev);
3250 unsigned long flags = 0;
3251 int ret=0;
3252
3253 spin_lock_irqsave(&priv->lock, flags);
3254
3255 TLan_EeSendStart( dev->base_addr );
3256 err = TLan_EeSendByte( dev->base_addr, 0xA0, TLAN_EEPROM_ACK );
3257 if (err)
3258 {
3259 ret=1;
3260 goto fail;
3261 }
3262 err = TLan_EeSendByte( dev->base_addr, ee_addr, TLAN_EEPROM_ACK );
3263 if (err)
3264 {
3265 ret=2;
3266 goto fail;
3267 }
3268 TLan_EeSendStart( dev->base_addr );
3269 err = TLan_EeSendByte( dev->base_addr, 0xA1, TLAN_EEPROM_ACK );
3270 if (err)
3271 {
3272 ret=3;
3273 goto fail;
3274 }
3275 TLan_EeReceiveByte( dev->base_addr, data, TLAN_EEPROM_STOP );
3276fail:
3277 spin_unlock_irqrestore(&priv->lock, flags);
3278
3279 return ret;
3280
3281} /* TLan_EeReadByte */
3282
3283
3284