blob: 0166407d7061b417f9d4276dfea49b15043ee39a [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*******************************************************************************
2 *
3 * Linux ThunderLAN Driver
4 *
5 * tlan.c
6 * by James Banks
7 *
8 * (C) 1997-1998 Caldera, Inc.
9 * (C) 1998 James Banks
10 * (C) 1999-2001 Torben Mathiasen
11 * (C) 2002 Samuel Chessman
12 *
13 * This software may be used and distributed according to the terms
14 * of the GNU General Public License, incorporated herein by reference.
15 *
16 ** This file is best viewed/edited with columns>=132.
17 *
18 ** Useful (if not required) reading:
19 *
20 * Texas Instruments, ThunderLAN Programmer's Guide,
21 * TI Literature Number SPWU013A
22 * available in PDF format from www.ti.com
23 * Level One, LXT901 and LXT970 Data Sheets
24 * available in PDF format from www.level1.com
25 * National Semiconductor, DP83840A Data Sheet
26 * available in PDF format from www.national.com
27 * Microchip Technology, 24C01A/02A/04A Data Sheet
28 * available in PDF format from www.microchip.com
29 *
30 * Change History
31 *
32 * Tigran Aivazian <tigran@sco.com>: TLan_PciProbe() now uses
33 * new PCI BIOS interface.
34 * Alan Cox <alan@redhat.com>: Fixed the out of memory
35 * handling.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040036 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 * Torben Mathiasen <torben.mathiasen@compaq.com> New Maintainer!
38 *
39 * v1.1 Dec 20, 1999 - Removed linux version checking
Jeff Garzik6aa20a22006-09-13 13:24:59 -040040 * Patch from Tigran Aivazian.
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 * - v1.1 includes Alan's SMP updates.
42 * - We still have problems on SMP though,
Jeff Garzik6aa20a22006-09-13 13:24:59 -040043 * but I'm looking into that.
44 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 * v1.2 Jan 02, 2000 - Hopefully fixed the SMP deadlock.
46 * - Removed dependency of HZ being 100.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040047 * - We now allow higher priority timers to
Linus Torvalds1da177e2005-04-16 15:20:36 -070048 * overwrite timers like TLAN_TIMER_ACTIVITY
49 * Patch from John Cagle <john.cagle@compaq.com>.
50 * - Fixed a few compiler warnings.
51 *
52 * v1.3 Feb 04, 2000 - Fixed the remaining HZ issues.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040053 * - Removed call to pci_present().
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 * - Removed SA_INTERRUPT flag from irq handler.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040055 * - Added __init and __initdata to reduce resisdent
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 * code size.
57 * - Driver now uses module_init/module_exit.
58 * - Rewrote init_module and tlan_probe to
59 * share a lot more code. We now use tlan_probe
60 * with builtin and module driver.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040061 * - Driver ported to new net API.
62 * - tlan.txt has been reworked to reflect current
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 * driver (almost)
64 * - Other minor stuff
65 *
66 * v1.4 Feb 10, 2000 - Updated with more changes required after Dave's
67 * network cleanup in 2.3.43pre7 (Tigran & myself)
68 * - Minor stuff.
69 *
70 * v1.5 March 22, 2000 - Fixed another timer bug that would hang the driver
71 * if no cable/link were present.
72 * - Cosmetic changes.
73 * - TODO: Port completely to new PCI/DMA API
74 * Auto-Neg fallback.
75 *
76 * v1.6 April 04, 2000 - Fixed driver support for kernel-parameters. Haven't
Jeff Garzik6aa20a22006-09-13 13:24:59 -040077 * tested it though, as the kernel support is currently
Linus Torvalds1da177e2005-04-16 15:20:36 -070078 * broken (2.3.99p4p3).
79 * - Updated tlan.txt accordingly.
80 * - Adjusted minimum/maximum frame length.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040081 * - There is now a TLAN website up at
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 * http://tlan.kernel.dk
83 *
84 * v1.7 April 07, 2000 - Started to implement custom ioctls. Driver now
85 * reports PHY information when used with Donald
86 * Beckers userspace MII diagnostics utility.
87 *
88 * v1.8 April 23, 2000 - Fixed support for forced speed/duplex settings.
89 * - Added link information to Auto-Neg and forced
90 * modes. When NIC operates with auto-neg the driver
91 * will report Link speed & duplex modes as well as
92 * link partner abilities. When forced link is used,
93 * the driver will report status of the established
94 * link.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040095 * Please read tlan.txt for additional information.
96 * - Removed call to check_region(), and used
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 * return value of request_region() instead.
Jeff Garzik6aa20a22006-09-13 13:24:59 -040098 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 * v1.8a May 28, 2000 - Minor updates.
100 *
101 * v1.9 July 25, 2000 - Fixed a few remaining Full-Duplex issues.
102 * - Updated with timer fixes from Andrew Morton.
103 * - Fixed module race in TLan_Open.
104 * - Added routine to monitor PHY status.
105 * - Added activity led support for Proliant devices.
106 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400107 * v1.10 Aug 30, 2000 - Added support for EISA based tlan controllers
108 * like the Compaq NetFlex3/E.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 * - Rewrote tlan_probe to better handle multiple
110 * bus probes. Probing and device setup is now
111 * done through TLan_Probe and TLan_init_one. Actual
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400112 * hardware probe is done with kernel API and
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113 * TLan_EisaProbe.
114 * - Adjusted debug information for probing.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400115 * - Fixed bug that would cause general debug information
116 * to be printed after driver removal.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 * - Added transmit timeout handling.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400118 * - Fixed OOM return values in tlan_probe.
119 * - Fixed possible mem leak in tlan_exit
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 * (now tlan_remove_one).
121 * - Fixed timer bug in TLan_phyMonitor.
122 * - This driver version is alpha quality, please
123 * send me any bug issues you may encounter.
124 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400125 * v1.11 Aug 31, 2000 - Do not try to register irq 0 if no irq line was
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 * set for EISA cards.
127 * - Added support for NetFlex3/E with nibble-rate
128 * 10Base-T PHY. This is untestet as I haven't got
129 * one of these cards.
130 * - Fixed timer being added twice.
131 * - Disabled PhyMonitoring by default as this is
132 * work in progress. Define MONITOR to enable it.
133 * - Now we don't display link info with PHYs that
134 * doesn't support it (level1).
135 * - Incresed tx_timeout beacuse of auto-neg.
136 * - Adjusted timers for forced speeds.
137 *
138 * v1.12 Oct 12, 2000 - Minor fixes (memleak, init, etc.)
139 *
140 * v1.13 Nov 28, 2000 - Stop flooding console with auto-neg issues
141 * when link can't be established.
142 * - Added the bbuf option as a kernel parameter.
143 * - Fixed ioaddr probe bug.
144 * - Fixed stupid deadlock with MII interrupts.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400145 * - Added support for speed/duplex selection with
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 * multiple nics.
147 * - Added partly fix for TX Channel lockup with
148 * TLAN v1.0 silicon. This needs to be investigated
149 * further.
150 *
151 * v1.14 Dec 16, 2000 - Added support for servicing multiple frames per.
152 * interrupt. Thanks goes to
153 * Adam Keys <adam@ti.com>
154 * Denis Beaudoin <dbeaudoin@ti.com>
155 * for providing the patch.
156 * - Fixed auto-neg output when using multiple
157 * adapters.
158 * - Converted to use new taskq interface.
159 *
160 * v1.14a Jan 6, 2001 - Minor adjustments (spinlocks, etc.)
161 *
162 * Samuel Chessman <chessman@tux.org> New Maintainer!
163 *
164 * v1.15 Apr 4, 2002 - Correct operation when aui=1 to be
165 * 10T half duplex no loopback
166 * Thanks to Gunnar Eikman
167 *******************************************************************************/
168
169#include <linux/module.h>
170#include <linux/init.h>
171#include <linux/ioport.h>
172#include <linux/eisa.h>
173#include <linux/pci.h>
Domen Puncer1e7f0bd2005-06-26 18:22:14 -0400174#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175#include <linux/netdevice.h>
176#include <linux/etherdevice.h>
177#include <linux/delay.h>
178#include <linux/spinlock.h>
179#include <linux/workqueue.h>
180#include <linux/mii.h>
181
182#include "tlan.h"
183
184typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 );
185
186
187/* For removing EISA devices */
188static struct net_device *TLan_Eisa_Devices;
189
190static int TLanDevicesInstalled;
191
192/* Set speed, duplex and aui settings */
193static int aui[MAX_TLAN_BOARDS];
194static int duplex[MAX_TLAN_BOARDS];
195static int speed[MAX_TLAN_BOARDS];
196static int boards_found;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -0700197module_param_array(aui, int, NULL, 0);
198module_param_array(duplex, int, NULL, 0);
199module_param_array(speed, int, NULL, 0);
200MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
201MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
202MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
205MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
206MODULE_LICENSE("GPL");
207
208
209/* Define this to enable Link beat monitoring */
210#undef MONITOR
211
212/* Turn on debugging. See Documentation/networking/tlan.txt for details */
213static int debug;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -0700214module_param(debug, int, 0);
215MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216
217static int bbuf;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -0700218module_param(bbuf, int, 0);
219MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)");
220
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221static u8 *TLanPadBuffer;
222static dma_addr_t TLanPadBufferDMA;
223static char TLanSignature[] = "TLAN";
224static const char tlan_banner[] = "ThunderLAN driver v1.15\n";
225static int tlan_have_pci;
226static int tlan_have_eisa;
227
228static const char *media[] = {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400229 "10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 "100baseTx-FD", "100baseT4", NULL
231};
232
233static struct board {
234 const char *deviceLabel;
235 u32 flags;
236 u16 addrOfs;
237} board_info[] = {
238 { "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
239 { "Compaq Netelligent 10/100 TX PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
240 { "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
241 { "Compaq NetFlex-3/P", TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
242 { "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
243 { "Compaq Netelligent Integrated 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
244 { "Compaq Netelligent Dual 10/100 TX PCI UTP", TLAN_ADAPTER_NONE, 0x83 },
245 { "Compaq Netelligent 10/100 TX Embedded UTP", TLAN_ADAPTER_NONE, 0x83 },
246 { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
247 { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xF8 },
248 { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xF8 },
249 { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
250 { "Compaq Netelligent 10 T/2 PCI UTP/Coax", TLAN_ADAPTER_NONE, 0x83 },
251 { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400252 TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
254};
255
256static struct pci_device_id tlan_pci_tbl[] = {
257 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
258 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
259 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
260 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
261 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3I,
262 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
263 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_THUNDER,
264 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
265 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3B,
266 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
267 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100PI,
268 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
269 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100D,
270 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
271 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100I,
272 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
273 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183,
274 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
275 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325,
276 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
277 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
278 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
279 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,
280 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
281 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2,
282 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
283 { 0,}
284};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400285MODULE_DEVICE_TABLE(pci, tlan_pci_tbl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286
287static void TLan_EisaProbe( void );
288static void TLan_Eisa_Cleanup( void );
289static int TLan_Init( struct net_device * );
290static int TLan_Open( struct net_device *dev );
291static int TLan_StartTx( struct sk_buff *, struct net_device *);
David Howells7d12e782006-10-05 14:55:46 +0100292static irqreturn_t TLan_HandleInterrupt( int, void *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293static int TLan_Close( struct net_device *);
294static struct net_device_stats *TLan_GetStats( struct net_device *);
295static void TLan_SetMulticastList( struct net_device *);
296static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd);
297static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
298static void TLan_tx_timeout( struct net_device *dev);
David Howellsc4028952006-11-22 14:57:56 +0000299static void TLan_tx_timeout_work(struct work_struct *work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
301
302static u32 TLan_HandleInvalid( struct net_device *, u16 );
303static u32 TLan_HandleTxEOF( struct net_device *, u16 );
304static u32 TLan_HandleStatOverflow( struct net_device *, u16 );
305static u32 TLan_HandleRxEOF( struct net_device *, u16 );
306static u32 TLan_HandleDummy( struct net_device *, u16 );
307static u32 TLan_HandleTxEOC( struct net_device *, u16 );
308static u32 TLan_HandleStatusCheck( struct net_device *, u16 );
309static u32 TLan_HandleRxEOC( struct net_device *, u16 );
310
311static void TLan_Timer( unsigned long );
312
313static void TLan_ResetLists( struct net_device * );
314static void TLan_FreeLists( struct net_device * );
315static void TLan_PrintDio( u16 );
316static void TLan_PrintList( TLanList *, char *, int );
317static void TLan_ReadAndClearStats( struct net_device *, int );
318static void TLan_ResetAdapter( struct net_device * );
319static void TLan_FinishReset( struct net_device * );
320static void TLan_SetMac( struct net_device *, int areg, char *mac );
321
322static void TLan_PhyPrint( struct net_device * );
323static void TLan_PhyDetect( struct net_device * );
324static void TLan_PhyPowerDown( struct net_device * );
325static void TLan_PhyPowerUp( struct net_device * );
326static void TLan_PhyReset( struct net_device * );
327static void TLan_PhyStartLink( struct net_device * );
328static void TLan_PhyFinishAutoNeg( struct net_device * );
329#ifdef MONITOR
330static void TLan_PhyMonitor( struct net_device * );
331#endif
332
333/*
334static int TLan_PhyNop( struct net_device * );
335static int TLan_PhyInternalCheck( struct net_device * );
336static int TLan_PhyInternalService( struct net_device * );
337static int TLan_PhyDp83840aCheck( struct net_device * );
338*/
339
340static int TLan_MiiReadReg( struct net_device *, u16, u16, u16 * );
341static void TLan_MiiSendData( u16, u32, unsigned );
342static void TLan_MiiSync( u16 );
343static void TLan_MiiWriteReg( struct net_device *, u16, u16, u16 );
344
345static void TLan_EeSendStart( u16 );
346static int TLan_EeSendByte( u16, u8, int );
347static void TLan_EeReceiveByte( u16, u8 *, int );
348static int TLan_EeReadByte( struct net_device *, u8, u8 * );
349
350
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400351static void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352TLan_StoreSKB( struct tlan_list_tag *tag, struct sk_buff *skb)
353{
354 unsigned long addr = (unsigned long)skb;
355 tag->buffer[9].address = (u32)addr;
356 addr >>= 31; /* >>= 32 is undefined for 32bit arch, stupid C */
357 addr >>= 1;
358 tag->buffer[8].address = (u32)addr;
359}
360
361static struct sk_buff *
362TLan_GetSKB( struct tlan_list_tag *tag)
363{
364 unsigned long addr = tag->buffer[8].address;
365 addr <<= 31;
366 addr <<= 1;
367 addr |= tag->buffer[9].address;
368 return (struct sk_buff *) addr;
369}
370
371
372static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = {
373 TLan_HandleInvalid,
374 TLan_HandleTxEOF,
375 TLan_HandleStatOverflow,
376 TLan_HandleRxEOF,
377 TLan_HandleDummy,
378 TLan_HandleTxEOC,
379 TLan_HandleStatusCheck,
380 TLan_HandleRxEOC
381};
382
383static inline void
384TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type )
385{
386 TLanPrivateInfo *priv = netdev_priv(dev);
387 unsigned long flags = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400388
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 if (!in_irq())
390 spin_lock_irqsave(&priv->lock, flags);
391 if ( priv->timer.function != NULL &&
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400392 priv->timerType != TLAN_TIMER_ACTIVITY ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 if (!in_irq())
394 spin_unlock_irqrestore(&priv->lock, flags);
395 return;
396 }
397 priv->timer.function = &TLan_Timer;
398 if (!in_irq())
399 spin_unlock_irqrestore(&priv->lock, flags);
400
401 priv->timer.data = (unsigned long) dev;
402 priv->timerSetAt = jiffies;
403 priv->timerType = type;
404 mod_timer(&priv->timer, jiffies + ticks);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400405
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406} /* TLan_SetTimer */
407
408
409/*****************************************************************************
410******************************************************************************
411
412 ThunderLAN Driver Primary Functions
413
414 These functions are more or less common to all Linux network drivers.
415
416******************************************************************************
417*****************************************************************************/
418
419
420
421
422
423 /***************************************************************
424 * tlan_remove_one
425 *
426 * Returns:
427 * Nothing
428 * Parms:
429 * None
430 *
431 * Goes through the TLanDevices list and frees the device
432 * structs and memory associated with each device (lists
433 * and buffers). It also ureserves the IO port regions
434 * associated with this device.
435 *
436 **************************************************************/
437
438
439static void __devexit tlan_remove_one( struct pci_dev *pdev)
440{
441 struct net_device *dev = pci_get_drvdata( pdev );
442 TLanPrivateInfo *priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400443
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 unregister_netdev( dev );
445
446 if ( priv->dmaStorage ) {
447 pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA );
448 }
449
450#ifdef CONFIG_PCI
451 pci_release_regions(pdev);
452#endif
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400453
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 free_netdev( dev );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400455
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456 pci_set_drvdata( pdev, NULL );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400457}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
459static struct pci_driver tlan_driver = {
460 .name = "tlan",
461 .id_table = tlan_pci_tbl,
462 .probe = tlan_init_one,
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400463 .remove = __devexit_p(tlan_remove_one),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700464};
465
466static int __init tlan_probe(void)
467{
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800468 int rc = -ENODEV;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400469
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 printk(KERN_INFO "%s", tlan_banner);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400471
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 TLanPadBuffer = (u8 *) pci_alloc_consistent(NULL, TLAN_MIN_FRAME_SIZE, &TLanPadBufferDMA);
473
474 if (TLanPadBuffer == NULL) {
475 printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n");
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800476 rc = -ENOMEM;
477 goto err_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 }
479
480 memset(TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
482 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400483
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 /* Use new style PCI probing. Now the kernel will
485 do most of this for us */
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800486 rc = pci_register_driver(&tlan_driver);
487
488 if (rc != 0) {
489 printk(KERN_ERR "TLAN: Could not register pci driver.\n");
490 goto err_out_pci_free;
491 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492
493 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
494 TLan_EisaProbe();
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400495
496 printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d EISA: %d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 TLanDevicesInstalled, TLanDevicesInstalled == 1 ? "" : "s",
498 tlan_have_pci, tlan_have_eisa);
499
500 if (TLanDevicesInstalled == 0) {
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800501 rc = -ENODEV;
502 goto err_out_pci_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 }
504 return 0;
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800505
506err_out_pci_unreg:
507 pci_unregister_driver(&tlan_driver);
508err_out_pci_free:
509 pci_free_consistent(NULL, TLAN_MIN_FRAME_SIZE, TLanPadBuffer, TLanPadBufferDMA);
510err_out:
511 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400513
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514
515static int __devinit tlan_init_one( struct pci_dev *pdev,
516 const struct pci_device_id *ent)
517{
518 return TLan_probe1( pdev, -1, -1, 0, ent);
519}
520
521
522/*
523 ***************************************************************
524 * tlan_probe1
525 *
526 * Returns:
527 * 0 on success, error code on error
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400528 * Parms:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 * none
530 *
531 * The name is lower case to fit in with all the rest of
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400532 * the netcard_probe names. This function looks for
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 * another TLan based adapter, setting it up with the
534 * allocated device struct if one is found.
535 * tlan_probe has been ported to the new net API and
536 * now allocates its own device structure. This function
537 * is also used by modules.
538 *
539 **************************************************************/
540
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400541static int __devinit TLan_probe1(struct pci_dev *pdev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 long ioaddr, int irq, int rev, const struct pci_device_id *ent )
543{
544
545 struct net_device *dev;
546 TLanPrivateInfo *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 u16 device_id;
548 int reg, rc = -ENODEV;
549
Adrian Bunkad9f6712006-02-05 00:37:47 +0100550#ifdef CONFIG_PCI
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 if (pdev) {
552 rc = pci_enable_device(pdev);
553 if (rc)
554 return rc;
555
556 rc = pci_request_regions(pdev, TLanSignature);
557 if (rc) {
558 printk(KERN_ERR "TLAN: Could not reserve IO regions\n");
559 goto err_out;
560 }
561 }
Adrian Bunkad9f6712006-02-05 00:37:47 +0100562#endif /* CONFIG_PCI */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563
564 dev = alloc_etherdev(sizeof(TLanPrivateInfo));
565 if (dev == NULL) {
566 printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");
567 rc = -ENOMEM;
568 goto err_out_regions;
569 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 SET_NETDEV_DEV(dev, &pdev->dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400571
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 priv = netdev_priv(dev);
573
574 priv->pciDev = pdev;
David Howellsc4028952006-11-22 14:57:56 +0000575 priv->dev = dev;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400576
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 /* Is this a PCI device? */
578 if (pdev) {
579 u32 pci_io_base = 0;
580
581 priv->adapter = &board_info[ent->driver_data];
582
Domen Puncer1e7f0bd2005-06-26 18:22:14 -0400583 rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 if (rc) {
585 printk(KERN_ERR "TLAN: No suitable PCI mapping available.\n");
586 goto err_out_free_dev;
587 }
588
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 for ( reg= 0; reg <= 5; reg ++ ) {
590 if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
591 pci_io_base = pci_resource_start(pdev, reg);
592 TLAN_DBG( TLAN_DEBUG_GNRL, "IO mapping is available at %x.\n",
593 pci_io_base);
594 break;
595 }
596 }
597 if (!pci_io_base) {
598 printk(KERN_ERR "TLAN: No IO mappings available\n");
599 rc = -EIO;
600 goto err_out_free_dev;
601 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400602
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 dev->base_addr = pci_io_base;
604 dev->irq = pdev->irq;
Auke Kok44c10132007-06-08 15:46:36 -0700605 priv->adapterRev = pdev->revision;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 pci_set_master(pdev);
607 pci_set_drvdata(pdev, dev);
608
609 } else { /* EISA card */
610 /* This is a hack. We need to know which board structure
611 * is suited for this adapter */
612 device_id = inw(ioaddr + EISA_ID2);
613 priv->is_eisa = 1;
614 if (device_id == 0x20F1) {
615 priv->adapter = &board_info[13]; /* NetFlex-3/E */
616 priv->adapterRev = 23; /* TLAN 2.3 */
617 } else {
618 priv->adapter = &board_info[14];
619 priv->adapterRev = 10; /* TLAN 1.0 */
620 }
621 dev->base_addr = ioaddr;
622 dev->irq = irq;
623 }
624
625 /* Kernel parameters */
626 if (dev->mem_start) {
627 priv->aui = dev->mem_start & 0x01;
628 priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0 : (dev->mem_start & 0x06) >> 1;
629 priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400630
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 if (priv->speed == 0x1) {
632 priv->speed = TLAN_SPEED_10;
633 } else if (priv->speed == 0x2) {
634 priv->speed = TLAN_SPEED_100;
635 }
636 debug = priv->debug = dev->mem_end;
637 } else {
638 priv->aui = aui[boards_found];
639 priv->speed = speed[boards_found];
640 priv->duplex = duplex[boards_found];
641 priv->debug = debug;
642 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400643
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 /* This will be used when we get an adapter error from
645 * within our irq handler */
David Howellsc4028952006-11-22 14:57:56 +0000646 INIT_WORK(&priv->tlan_tqueue, TLan_tx_timeout_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647
648 spin_lock_init(&priv->lock);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400649
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 rc = TLan_Init(dev);
651 if (rc) {
652 printk(KERN_ERR "TLAN: Could not set up device.\n");
653 goto err_out_free_dev;
654 }
655
656 rc = register_netdev(dev);
657 if (rc) {
658 printk(KERN_ERR "TLAN: Could not register device.\n");
659 goto err_out_uninit;
660 }
661
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400662
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663 TLanDevicesInstalled++;
664 boards_found++;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400665
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 /* pdev is NULL if this is an EISA device */
667 if (pdev)
668 tlan_have_pci++;
669 else {
670 priv->nextDevice = TLan_Eisa_Devices;
671 TLan_Eisa_Devices = dev;
672 tlan_have_eisa++;
673 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400674
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n",
676 dev->name,
677 (int) dev->irq,
678 (int) dev->base_addr,
679 priv->adapter->deviceLabel,
680 priv->adapterRev);
681 return 0;
682
683err_out_uninit:
684 pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage,
685 priv->dmaStorageDMA );
686err_out_free_dev:
687 free_netdev(dev);
688err_out_regions:
689#ifdef CONFIG_PCI
690 if (pdev)
691 pci_release_regions(pdev);
692#endif
693err_out:
694 if (pdev)
695 pci_disable_device(pdev);
696 return rc;
697}
698
699
700static void TLan_Eisa_Cleanup(void)
701{
702 struct net_device *dev;
703 TLanPrivateInfo *priv;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400704
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 while( tlan_have_eisa ) {
706 dev = TLan_Eisa_Devices;
707 priv = netdev_priv(dev);
708 if (priv->dmaStorage) {
709 pci_free_consistent(priv->pciDev, priv->dmaSize, priv->dmaStorage, priv->dmaStorageDMA );
710 }
711 release_region( dev->base_addr, 0x10);
712 unregister_netdev( dev );
713 TLan_Eisa_Devices = priv->nextDevice;
714 free_netdev( dev );
715 tlan_have_eisa--;
716 }
717}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400718
719
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720static void __exit tlan_exit(void)
721{
722 pci_unregister_driver(&tlan_driver);
723
724 if (tlan_have_eisa)
725 TLan_Eisa_Cleanup();
726
727 pci_free_consistent(NULL, TLAN_MIN_FRAME_SIZE, TLanPadBuffer, TLanPadBufferDMA);
728
729}
730
731
732/* Module loading/unloading */
733module_init(tlan_probe);
734module_exit(tlan_exit);
735
736
737
738 /**************************************************************
739 * TLan_EisaProbe
740 *
741 * Returns: 0 on success, 1 otherwise
742 *
743 * Parms: None
744 *
745 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400746 * This functions probes for EISA devices and calls
747 * TLan_probe1 when one is found.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 *
749 *************************************************************/
750
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400751static void __init TLan_EisaProbe (void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752{
753 long ioaddr;
754 int rc = -ENODEV;
755 int irq;
756 u16 device_id;
757
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400758 if (!EISA_bus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759 TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
760 return;
761 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400762
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 /* Loop through all slots of the EISA bus */
764 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400765
766 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 -0700767 TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2));
768
769
770 TLAN_DBG(TLAN_DEBUG_PROBE, "Probing for EISA adapter at IO: 0x%4x : ",
771 (int) ioaddr);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400772 if (request_region(ioaddr, 0x10, TLanSignature) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 goto out;
774
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400775 if (inw(ioaddr + EISA_ID) != 0x110E) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 release_region(ioaddr, 0x10);
777 goto out;
778 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400779
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 device_id = inw(ioaddr + EISA_ID2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400781 if (device_id != 0x20F1 && device_id != 0x40F1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 release_region (ioaddr, 0x10);
783 goto out;
784 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400785
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786 if (inb(ioaddr + EISA_CR) != 0x1) { /* Check if adapter is enabled */
787 release_region (ioaddr, 0x10);
788 goto out2;
789 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400790
791 if (debug == 0x10)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792 printk("Found one\n");
793
794
795 /* Get irq from board */
796 switch (inb(ioaddr + 0xCC0)) {
797 case(0x10):
798 irq=5;
799 break;
800 case(0x20):
801 irq=9;
802 break;
803 case(0x40):
804 irq=10;
805 break;
806 case(0x80):
807 irq=11;
808 break;
809 default:
810 goto out;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400811 }
812
813
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 /* Setup the newly found eisa adapter */
815 rc = TLan_probe1( NULL, ioaddr, irq,
816 12, NULL);
817 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400818
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 out:
820 if (debug == 0x10)
821 printk("None found\n");
822 continue;
823
824 out2: if (debug == 0x10)
825 printk("Card found but it is not enabled, skipping\n");
826 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400827
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 }
829
830} /* TLan_EisaProbe */
831
832#ifdef CONFIG_NET_POLL_CONTROLLER
833static void TLan_Poll(struct net_device *dev)
834{
835 disable_irq(dev->irq);
David Howells7d12e782006-10-05 14:55:46 +0100836 TLan_HandleInterrupt(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 enable_irq(dev->irq);
838}
839#endif
840
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400841
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842
843
844 /***************************************************************
845 * TLan_Init
846 *
847 * Returns:
848 * 0 on success, error code otherwise.
849 * Parms:
850 * dev The structure of the device to be
851 * init'ed.
852 *
853 * This function completes the initialization of the
854 * device structure and driver. It reserves the IO
855 * addresses, allocates memory for the lists and bounce
856 * buffers, retrieves the MAC address from the eeprom
857 * and assignes the device's methods.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400858 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 **************************************************************/
860
861static int TLan_Init( struct net_device *dev )
862{
863 int dma_size;
864 int err;
865 int i;
866 TLanPrivateInfo *priv;
867
868 priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400869
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870 if ( bbuf ) {
871 dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
872 * ( sizeof(TLanList) + TLAN_MAX_FRAME_SIZE );
873 } else {
874 dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
875 * ( sizeof(TLanList) );
876 }
877 priv->dmaStorage = pci_alloc_consistent(priv->pciDev, dma_size, &priv->dmaStorageDMA);
878 priv->dmaSize = dma_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400879
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 if ( priv->dmaStorage == NULL ) {
881 printk(KERN_ERR "TLAN: Could not allocate lists and buffers for %s.\n",
882 dev->name );
883 return -ENOMEM;
884 }
885 memset( priv->dmaStorage, 0, dma_size );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400886 priv->rxList = (TLanList *)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 ( ( ( (u32) priv->dmaStorage ) + 7 ) & 0xFFFFFFF8 );
888 priv->rxListDMA = ( ( ( (u32) priv->dmaStorageDMA ) + 7 ) & 0xFFFFFFF8 );
889 priv->txList = priv->rxList + TLAN_NUM_RX_LISTS;
890 priv->txListDMA = priv->rxListDMA + sizeof(TLanList) * TLAN_NUM_RX_LISTS;
891 if ( bbuf ) {
892 priv->rxBuffer = (u8 *) ( priv->txList + TLAN_NUM_TX_LISTS );
893 priv->rxBufferDMA =priv->txListDMA + sizeof(TLanList) * TLAN_NUM_TX_LISTS;
894 priv->txBuffer = priv->rxBuffer + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
895 priv->txBufferDMA = priv->rxBufferDMA + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
896 }
897
898 err = 0;
899 for ( i = 0; i < 6 ; i++ )
900 err |= TLan_EeReadByte( dev,
901 (u8) priv->adapter->addrOfs + i,
902 (u8 *) &dev->dev_addr[i] );
903 if ( err ) {
904 printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n",
905 dev->name,
906 err );
907 }
908 dev->addr_len = 6;
909
910 netif_carrier_off(dev);
911
912 /* Device methods */
913 dev->open = &TLan_Open;
914 dev->hard_start_xmit = &TLan_StartTx;
915 dev->stop = &TLan_Close;
916 dev->get_stats = &TLan_GetStats;
917 dev->set_multicast_list = &TLan_SetMulticastList;
918 dev->do_ioctl = &TLan_ioctl;
919#ifdef CONFIG_NET_POLL_CONTROLLER
920 dev->poll_controller = &TLan_Poll;
921#endif
922 dev->tx_timeout = &TLan_tx_timeout;
923 dev->watchdog_timeo = TX_TIMEOUT;
924
925 return 0;
926
927} /* TLan_Init */
928
929
930
931
932 /***************************************************************
933 * TLan_Open
934 *
935 * Returns:
936 * 0 on success, error code otherwise.
937 * Parms:
938 * dev Structure of device to be opened.
939 *
940 * This routine puts the driver and TLAN adapter in a
941 * state where it is ready to send and receive packets.
942 * It allocates the IRQ, resets and brings the adapter
943 * out of reset, and allows interrupts. It also delays
944 * the startup for autonegotiation or sends a Rx GO
945 * command to the adapter, as appropriate.
946 *
947 **************************************************************/
948
949static int TLan_Open( struct net_device *dev )
950{
951 TLanPrivateInfo *priv = netdev_priv(dev);
952 int err;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400953
Linus Torvalds1da177e2005-04-16 15:20:36 -0700954 priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION );
Thomas Gleixner1fb9df52006-07-01 19:29:39 -0700955 err = request_irq( dev->irq, TLan_HandleInterrupt, IRQF_SHARED, TLanSignature, dev );
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400956
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957 if ( err ) {
958 printk(KERN_ERR "TLAN: Cannot open %s because IRQ %d is already in use.\n", dev->name, dev->irq );
959 return err;
960 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400961
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 init_timer(&priv->timer);
963 netif_start_queue(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400964
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 /* NOTE: It might not be necessary to read the stats before a
966 reset if you don't care what the values are.
967 */
968 TLan_ResetLists( dev );
969 TLan_ReadAndClearStats( dev, TLAN_IGNORE );
970 TLan_ResetAdapter( dev );
971
972 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n", dev->name, priv->tlanRev );
973
974 return 0;
975
976} /* TLan_Open */
977
978
979
980 /**************************************************************
981 * TLan_ioctl
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400982 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 * Returns:
984 * 0 on success, error code otherwise
985 * Params:
986 * dev structure of device to receive ioctl.
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400987 *
Linus Torvalds1da177e2005-04-16 15:20:36 -0700988 * rq ifreq structure to hold userspace data.
989 *
990 * cmd ioctl command.
991 *
992 *
993 *************************************************************/
994
995static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
996{
997 TLanPrivateInfo *priv = netdev_priv(dev);
998 struct mii_ioctl_data *data = if_mii(rq);
999 u32 phy = priv->phy[priv->phyNum];
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001000
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001 if (!priv->phyOnline)
1002 return -EAGAIN;
1003
1004 switch(cmd) {
1005 case SIOCGMIIPHY: /* Get address of MII PHY in use. */
1006 data->phy_id = phy;
1007
1008
1009 case SIOCGMIIREG: /* Read MII PHY register. */
1010 TLan_MiiReadReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, &data->val_out);
1011 return 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001012
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013
1014 case SIOCSMIIREG: /* Write MII PHY register. */
1015 if (!capable(CAP_NET_ADMIN))
1016 return -EPERM;
1017 TLan_MiiWriteReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
1018 return 0;
1019 default:
1020 return -EOPNOTSUPP;
1021 }
1022} /* tlan_ioctl */
1023
1024
1025 /***************************************************************
1026 * TLan_tx_timeout
1027 *
1028 * Returns: nothing
1029 *
1030 * Params:
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001031 * dev structure of device which timed out
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 * during transmit.
1033 *
1034 **************************************************************/
1035
1036static void TLan_tx_timeout(struct net_device *dev)
1037{
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001038
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001040
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 /* Ok so we timed out, lets see what we can do about it...*/
1042 TLan_FreeLists( dev );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001043 TLan_ResetLists( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 TLan_ReadAndClearStats( dev, TLAN_IGNORE );
1045 TLan_ResetAdapter( dev );
1046 dev->trans_start = jiffies;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001047 netif_wake_queue( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
1049}
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001050
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051
David Howellsc4028952006-11-22 14:57:56 +00001052 /***************************************************************
1053 * TLan_tx_timeout_work
1054 *
1055 * Returns: nothing
1056 *
1057 * Params:
1058 * work work item of device which timed out
1059 *
1060 **************************************************************/
1061
1062static void TLan_tx_timeout_work(struct work_struct *work)
1063{
1064 TLanPrivateInfo *priv =
1065 container_of(work, TLanPrivateInfo, tlan_tqueue);
1066
1067 TLan_tx_timeout(priv->dev);
1068}
1069
1070
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071
1072 /***************************************************************
1073 * TLan_StartTx
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001074 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 * Returns:
1076 * 0 on success, non-zero on failure.
1077 * Parms:
1078 * skb A pointer to the sk_buff containing the
1079 * frame to be sent.
1080 * dev The device to send the data on.
1081 *
1082 * This function adds a frame to the Tx list to be sent
1083 * ASAP. First it verifies that the adapter is ready and
1084 * there is room in the queue. Then it sets up the next
1085 * available list, copies the frame to the corresponding
1086 * buffer. If the adapter Tx channel is idle, it gives
1087 * the adapter a Tx Go command on the list, otherwise it
1088 * sets the forward address of the previous list to point
1089 * to this one. Then it frees the sk_buff.
1090 *
1091 **************************************************************/
1092
1093static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
1094{
1095 TLanPrivateInfo *priv = netdev_priv(dev);
1096 TLanList *tail_list;
1097 dma_addr_t tail_list_phys;
1098 u8 *tail_buffer;
1099 int pad;
1100 unsigned long flags;
1101
1102 if ( ! priv->phyOnline ) {
1103 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n", dev->name );
1104 dev_kfree_skb_any(skb);
1105 return 0;
1106 }
1107
1108 tail_list = priv->txList + priv->txTail;
1109 tail_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txTail;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001110
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 if ( tail_list->cStat != TLAN_CSTAT_UNUSED ) {
1112 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s is busy (Head=%d Tail=%d)\n", dev->name, priv->txHead, priv->txTail );
1113 netif_stop_queue(dev);
1114 priv->txBusyCount++;
1115 return 1;
1116 }
1117
1118 tail_list->forward = 0;
1119
1120 if ( bbuf ) {
1121 tail_buffer = priv->txBuffer + ( priv->txTail * TLAN_MAX_FRAME_SIZE );
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -03001122 skb_copy_from_linear_data(skb, tail_buffer, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 } else {
1124 tail_list->buffer[0].address = pci_map_single(priv->pciDev, skb->data, skb->len, PCI_DMA_TODEVICE);
1125 TLan_StoreSKB(tail_list, skb);
1126 }
1127
1128 pad = TLAN_MIN_FRAME_SIZE - skb->len;
1129
1130 if ( pad > 0 ) {
1131 tail_list->frameSize = (u16) skb->len + pad;
1132 tail_list->buffer[0].count = (u32) skb->len;
1133 tail_list->buffer[1].count = TLAN_LAST_BUFFER | (u32) pad;
1134 tail_list->buffer[1].address = TLanPadBufferDMA;
1135 } else {
1136 tail_list->frameSize = (u16) skb->len;
1137 tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) skb->len;
1138 tail_list->buffer[1].count = 0;
1139 tail_list->buffer[1].address = 0;
1140 }
1141
1142 spin_lock_irqsave(&priv->lock, flags);
1143 tail_list->cStat = TLAN_CSTAT_READY;
1144 if ( ! priv->txInProgress ) {
1145 priv->txInProgress = 1;
1146 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Starting TX on buffer %d\n", priv->txTail );
1147 outl( tail_list_phys, dev->base_addr + TLAN_CH_PARM );
1148 outl( TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD );
1149 } else {
1150 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Adding buffer %d to TX channel\n", priv->txTail );
1151 if ( priv->txTail == 0 ) {
1152 ( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward = tail_list_phys;
1153 } else {
1154 ( priv->txList + ( priv->txTail - 1 ) )->forward = tail_list_phys;
1155 }
1156 }
1157 spin_unlock_irqrestore(&priv->lock, flags);
1158
1159 CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS );
1160
1161 if ( bbuf )
1162 dev_kfree_skb_any(skb);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001163
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 dev->trans_start = jiffies;
1165 return 0;
1166
1167} /* TLan_StartTx */
1168
1169
1170
1171
1172 /***************************************************************
1173 * TLan_HandleInterrupt
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001174 *
1175 * Returns:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 * Nothing
1177 * Parms:
1178 * irq The line on which the interrupt
1179 * occurred.
1180 * dev_id A pointer to the device assigned to
1181 * this irq line.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 *
1183 * This function handles an interrupt generated by its
1184 * assigned TLAN adapter. The function deactivates
1185 * interrupts on its adapter, records the type of
1186 * interrupt, executes the appropriate subhandler, and
1187 * acknowdges the interrupt to the adapter (thus
1188 * re-enabling adapter interrupts.
1189 *
1190 **************************************************************/
1191
David Howells7d12e782006-10-05 14:55:46 +01001192static irqreturn_t TLan_HandleInterrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193{
1194 u32 ack;
1195 struct net_device *dev;
1196 u32 host_cmd;
1197 u16 host_int;
1198 int type;
1199 TLanPrivateInfo *priv;
1200
1201 dev = dev_id;
1202 priv = netdev_priv(dev);
1203
1204 spin_lock(&priv->lock);
1205
1206 host_int = inw( dev->base_addr + TLAN_HOST_INT );
1207 outw( host_int, dev->base_addr + TLAN_HOST_INT );
1208
1209 type = ( host_int & TLAN_HI_IT_MASK ) >> 2;
1210
1211 ack = TLanIntVector[type]( dev, host_int );
1212
1213 if ( ack ) {
1214 host_cmd = TLAN_HC_ACK | ack | ( type << 18 );
1215 outl( host_cmd, dev->base_addr + TLAN_HOST_CMD );
1216 }
1217
1218 spin_unlock(&priv->lock);
1219
1220 return IRQ_HANDLED;
1221} /* TLan_HandleInterrupts */
1222
1223
1224
1225
1226 /***************************************************************
1227 * TLan_Close
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001228 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 * Returns:
1230 * An error code.
1231 * Parms:
1232 * dev The device structure of the device to
1233 * close.
1234 *
1235 * This function shuts down the adapter. It records any
1236 * stats, puts the adapter into reset state, deactivates
1237 * its time as needed, and frees the irq it is using.
1238 *
1239 **************************************************************/
1240
1241static int TLan_Close(struct net_device *dev)
1242{
1243 TLanPrivateInfo *priv = netdev_priv(dev);
1244
1245 netif_stop_queue(dev);
1246 priv->neg_be_verbose = 0;
1247
1248 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1249 outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
1250 if ( priv->timer.function != NULL ) {
1251 del_timer_sync( &priv->timer );
1252 priv->timer.function = NULL;
1253 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001254
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 free_irq( dev->irq, dev );
1256 TLan_FreeLists( dev );
1257 TLAN_DBG( TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name );
1258
1259 return 0;
1260
1261} /* TLan_Close */
1262
1263
1264
1265
1266 /***************************************************************
1267 * TLan_GetStats
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001268 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269 * Returns:
1270 * A pointer to the device's statistics structure.
1271 * Parms:
1272 * dev The device structure to return the
1273 * stats for.
1274 *
1275 * This function updates the devices statistics by reading
1276 * the TLAN chip's onboard registers. Then it returns the
1277 * address of the statistics structure.
1278 *
1279 **************************************************************/
1280
1281static struct net_device_stats *TLan_GetStats( struct net_device *dev )
1282{
1283 TLanPrivateInfo *priv = netdev_priv(dev);
1284 int i;
1285
1286 /* Should only read stats if open ? */
1287 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1288
1289 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name, priv->rxEocCount );
1290 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name, priv->txBusyCount );
1291 if ( debug & TLAN_DEBUG_GNRL ) {
1292 TLan_PrintDio( dev->base_addr );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001293 TLan_PhyPrint( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 }
1295 if ( debug & TLAN_DEBUG_LIST ) {
1296 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ )
1297 TLan_PrintList( priv->rxList + i, "RX", i );
1298 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ )
1299 TLan_PrintList( priv->txList + i, "TX", i );
1300 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001301
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302 return ( &( (TLanPrivateInfo *) netdev_priv(dev) )->stats );
1303
1304} /* TLan_GetStats */
1305
1306
1307
1308
1309 /***************************************************************
1310 * TLan_SetMulticastList
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001311 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 * Returns:
1313 * Nothing
1314 * Parms:
1315 * dev The device structure to set the
1316 * multicast list for.
1317 *
1318 * This function sets the TLAN adaptor to various receive
1319 * modes. If the IFF_PROMISC flag is set, promiscuous
1320 * mode is acitviated. Otherwise, promiscuous mode is
1321 * turned off. If the IFF_ALLMULTI flag is set, then
1322 * the hash table is set to receive all group addresses.
1323 * Otherwise, the first three multicast addresses are
1324 * stored in AREG_1-3, and the rest are selected via the
1325 * hash table, as necessary.
1326 *
1327 **************************************************************/
1328
1329static void TLan_SetMulticastList( struct net_device *dev )
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001330{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 struct dev_mc_list *dmi = dev->mc_list;
1332 u32 hash1 = 0;
1333 u32 hash2 = 0;
1334 int i;
1335 u32 offset;
1336 u8 tmp;
1337
1338 if ( dev->flags & IFF_PROMISC ) {
1339 tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
1340 TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF );
1341 } else {
1342 tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
1343 TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF );
1344 if ( dev->flags & IFF_ALLMULTI ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001345 for ( i = 0; i < 3; i++ )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 TLan_SetMac( dev, i + 1, NULL );
1347 TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, 0xFFFFFFFF );
1348 TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, 0xFFFFFFFF );
1349 } else {
1350 for ( i = 0; i < dev->mc_count; i++ ) {
1351 if ( i < 3 ) {
1352 TLan_SetMac( dev, i + 1, (char *) &dmi->dmi_addr );
1353 } else {
1354 offset = TLan_HashFunc( (u8 *) &dmi->dmi_addr );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001355 if ( offset < 32 )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 hash1 |= ( 1 << offset );
1357 else
1358 hash2 |= ( 1 << ( offset - 32 ) );
1359 }
1360 dmi = dmi->next;
1361 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001362 for ( ; i < 3; i++ )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 TLan_SetMac( dev, i + 1, NULL );
1364 TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, hash1 );
1365 TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, hash2 );
1366 }
1367 }
1368
1369} /* TLan_SetMulticastList */
1370
1371
1372
1373/*****************************************************************************
1374******************************************************************************
1375
1376 ThunderLAN Driver Interrupt Vectors and Table
1377
1378 Please see Chap. 4, "Interrupt Handling" of the "ThunderLAN
1379 Programmer's Guide" for more informations on handling interrupts
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001380 generated by TLAN based adapters.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381
1382******************************************************************************
1383*****************************************************************************/
1384
1385
1386 /***************************************************************
1387 * TLan_HandleInvalid
1388 *
1389 * Returns:
1390 * 0
1391 * Parms:
1392 * dev Device assigned the IRQ that was
1393 * raised.
1394 * host_int The contents of the HOST_INT
1395 * port.
1396 *
1397 * This function handles invalid interrupts. This should
1398 * never happen unless some other adapter is trying to use
1399 * the IRQ line assigned to the device.
1400 *
1401 **************************************************************/
1402
Harvey Harrison98e0f522008-02-18 10:04:38 -08001403static u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404{
1405 /* printk( "TLAN: Invalid interrupt on %s.\n", dev->name ); */
1406 return 0;
1407
1408} /* TLan_HandleInvalid */
1409
1410
1411
1412
1413 /***************************************************************
1414 * TLan_HandleTxEOF
1415 *
1416 * Returns:
1417 * 1
1418 * Parms:
1419 * dev Device assigned the IRQ that was
1420 * raised.
1421 * host_int The contents of the HOST_INT
1422 * port.
1423 *
1424 * This function handles Tx EOF interrupts which are raised
1425 * by the adapter when it has completed sending the
1426 * contents of a buffer. If detemines which list/buffer
1427 * was completed and resets it. If the buffer was the last
1428 * in the channel (EOC), then the function checks to see if
1429 * another buffer is ready to send, and if so, sends a Tx
1430 * Go command. Finally, the driver activates/continues the
1431 * activity LED.
1432 *
1433 **************************************************************/
1434
Harvey Harrison98e0f522008-02-18 10:04:38 -08001435static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436{
1437 TLanPrivateInfo *priv = netdev_priv(dev);
1438 int eoc = 0;
1439 TLanList *head_list;
1440 dma_addr_t head_list_phys;
1441 u32 ack = 0;
1442 u16 tmpCStat;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001443
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
1445 head_list = priv->txList + priv->txHead;
1446
1447 while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
1448 ack++;
1449 if ( ! bbuf ) {
1450 struct sk_buff *skb = TLan_GetSKB(head_list);
1451 pci_unmap_single(priv->pciDev, head_list->buffer[0].address, skb->len, PCI_DMA_TODEVICE);
1452 dev_kfree_skb_any(skb);
1453 head_list->buffer[8].address = 0;
1454 head_list->buffer[9].address = 0;
1455 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001456
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457 if ( tmpCStat & TLAN_CSTAT_EOC )
1458 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001459
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 priv->stats.tx_bytes += head_list->frameSize;
1461
1462 head_list->cStat = TLAN_CSTAT_UNUSED;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001463 netif_start_queue(dev);
1464 CIRC_INC( priv->txHead, TLAN_NUM_TX_LISTS );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 head_list = priv->txList + priv->txHead;
1466 }
1467
1468 if (!ack)
1469 printk(KERN_INFO "TLAN: Received interrupt for uncompleted TX frame.\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001470
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471 if ( eoc ) {
1472 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
1473 head_list = priv->txList + priv->txHead;
1474 head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead;
1475 if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
1476 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM );
1477 ack |= TLAN_HC_GO;
1478 } else {
1479 priv->txInProgress = 0;
1480 }
1481 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001482
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
1484 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
1485 if ( priv->timer.function == NULL ) {
1486 priv->timer.function = &TLan_Timer;
1487 priv->timer.data = (unsigned long) dev;
1488 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1489 priv->timerSetAt = jiffies;
1490 priv->timerType = TLAN_TIMER_ACTIVITY;
1491 add_timer(&priv->timer);
1492 } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
1493 priv->timerSetAt = jiffies;
1494 }
1495 }
1496
1497 return ack;
1498
1499} /* TLan_HandleTxEOF */
1500
1501
1502
1503
1504 /***************************************************************
1505 * TLan_HandleStatOverflow
1506 *
1507 * Returns:
1508 * 1
1509 * Parms:
1510 * dev Device assigned the IRQ that was
1511 * raised.
1512 * host_int The contents of the HOST_INT
1513 * port.
1514 *
1515 * This function handles the Statistics Overflow interrupt
1516 * which means that one or more of the TLAN statistics
1517 * registers has reached 1/2 capacity and needs to be read.
1518 *
1519 **************************************************************/
1520
Harvey Harrison98e0f522008-02-18 10:04:38 -08001521static u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522{
1523 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1524
1525 return 1;
1526
1527} /* TLan_HandleStatOverflow */
1528
1529
1530
1531
1532 /***************************************************************
1533 * TLan_HandleRxEOF
1534 *
1535 * Returns:
1536 * 1
1537 * Parms:
1538 * dev Device assigned the IRQ that was
1539 * raised.
1540 * host_int The contents of the HOST_INT
1541 * port.
1542 *
1543 * This function handles the Rx EOF interrupt which
1544 * indicates a frame has been received by the adapter from
1545 * the net and the frame has been transferred to memory.
1546 * The function determines the bounce buffer the frame has
1547 * been loaded into, creates a new sk_buff big enough to
1548 * hold the frame, and sends it to protocol stack. It
1549 * then resets the used buffer and appends it to the end
1550 * of the list. If the frame was the last in the Rx
1551 * channel (EOC), the function restarts the receive channel
1552 * by sending an Rx Go command to the adapter. Then it
1553 * activates/continues the activity LED.
1554 *
1555 **************************************************************/
1556
Harvey Harrison98e0f522008-02-18 10:04:38 -08001557static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558{
1559 TLanPrivateInfo *priv = netdev_priv(dev);
1560 u32 ack = 0;
1561 int eoc = 0;
1562 u8 *head_buffer;
1563 TLanList *head_list;
1564 struct sk_buff *skb;
1565 TLanList *tail_list;
1566 void *t;
1567 u32 frameSize;
1568 u16 tmpCStat;
1569 dma_addr_t head_list_phys;
1570
1571 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOF (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
1572 head_list = priv->rxList + priv->rxHead;
1573 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001574
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
1576 frameSize = head_list->frameSize;
1577 ack++;
1578 if (tmpCStat & TLAN_CSTAT_EOC)
1579 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001580
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 if (bbuf) {
1582 skb = dev_alloc_skb(frameSize + 7);
1583 if (skb == NULL)
1584 printk(KERN_INFO "TLAN: Couldn't allocate memory for received data.\n");
1585 else {
1586 head_buffer = priv->rxBuffer + (priv->rxHead * TLAN_MAX_FRAME_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587 skb_reserve(skb, 2);
1588 t = (void *) skb_put(skb, frameSize);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001589
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 priv->stats.rx_bytes += head_list->frameSize;
1591
1592 memcpy( t, head_buffer, frameSize );
1593 skb->protocol = eth_type_trans( skb, dev );
1594 netif_rx( skb );
1595 }
1596 } else {
1597 struct sk_buff *new_skb;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001598
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 /*
1600 * I changed the algorithm here. What we now do
1601 * is allocate the new frame. If this fails we
1602 * simply recycle the frame.
1603 */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001604
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 new_skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001606
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 if ( new_skb != NULL ) {
1608 skb = TLan_GetSKB(head_list);
1609 pci_unmap_single(priv->pciDev, head_list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
1610 skb_trim( skb, frameSize );
1611
1612 priv->stats.rx_bytes += frameSize;
1613
1614 skb->protocol = eth_type_trans( skb, dev );
1615 netif_rx( skb );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001616
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 skb_reserve( new_skb, 2 );
1618 t = (void *) skb_put( new_skb, TLAN_MAX_FRAME_SIZE );
1619 head_list->buffer[0].address = pci_map_single(priv->pciDev, new_skb->data, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
1620 head_list->buffer[8].address = (u32) t;
1621 TLan_StoreSKB(head_list, new_skb);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001622 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 printk(KERN_WARNING "TLAN: Couldn't allocate memory for received data.\n" );
1624 }
1625
1626 head_list->forward = 0;
1627 head_list->cStat = 0;
1628 tail_list = priv->rxList + priv->rxTail;
1629 tail_list->forward = head_list_phys;
1630
1631 CIRC_INC( priv->rxHead, TLAN_NUM_RX_LISTS );
1632 CIRC_INC( priv->rxTail, TLAN_NUM_RX_LISTS );
1633 head_list = priv->rxList + priv->rxHead;
1634 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1635 }
1636
1637 if (!ack)
1638 printk(KERN_INFO "TLAN: Received interrupt for uncompleted RX frame.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
1640
1641
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001642
1643 if ( eoc ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
1645 head_list = priv->rxList + priv->rxHead;
1646 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1647 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM );
1648 ack |= TLAN_HC_GO | TLAN_HC_RT;
1649 priv->rxEocCount++;
1650 }
1651
1652 if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
1653 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
1654 if ( priv->timer.function == NULL ) {
1655 priv->timer.function = &TLan_Timer;
1656 priv->timer.data = (unsigned long) dev;
1657 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1658 priv->timerSetAt = jiffies;
1659 priv->timerType = TLAN_TIMER_ACTIVITY;
1660 add_timer(&priv->timer);
1661 } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
1662 priv->timerSetAt = jiffies;
1663 }
1664 }
1665
1666 dev->last_rx = jiffies;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001667
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 return ack;
1669
1670} /* TLan_HandleRxEOF */
1671
1672
1673
1674
1675 /***************************************************************
1676 * TLan_HandleDummy
1677 *
1678 * Returns:
1679 * 1
1680 * Parms:
1681 * dev Device assigned the IRQ that was
1682 * raised.
1683 * host_int The contents of the HOST_INT
1684 * port.
1685 *
1686 * This function handles the Dummy interrupt, which is
1687 * raised whenever a test interrupt is generated by setting
1688 * the Req_Int bit of HOST_CMD to 1.
1689 *
1690 **************************************************************/
1691
Harvey Harrison98e0f522008-02-18 10:04:38 -08001692static u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693{
1694 printk( "TLAN: Test interrupt on %s.\n", dev->name );
1695 return 1;
1696
1697} /* TLan_HandleDummy */
1698
1699
1700
1701
1702 /***************************************************************
1703 * TLan_HandleTxEOC
1704 *
1705 * Returns:
1706 * 1
1707 * Parms:
1708 * dev Device assigned the IRQ that was
1709 * raised.
1710 * host_int The contents of the HOST_INT
1711 * port.
1712 *
1713 * This driver is structured to determine EOC occurrences by
1714 * reading the CSTAT member of the list structure. Tx EOC
1715 * interrupts are disabled via the DIO INTDIS register.
1716 * However, TLAN chips before revision 3.0 didn't have this
1717 * functionality, so process EOC events if this is the
1718 * case.
1719 *
1720 **************************************************************/
1721
Harvey Harrison98e0f522008-02-18 10:04:38 -08001722static u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723{
1724 TLanPrivateInfo *priv = netdev_priv(dev);
1725 TLanList *head_list;
1726 dma_addr_t head_list_phys;
1727 u32 ack = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001728
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 host_int = 0;
1730 if ( priv->tlanRev < 0x30 ) {
1731 TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d) -- IRQ\n", priv->txHead, priv->txTail );
1732 head_list = priv->txList + priv->txHead;
1733 head_list_phys = priv->txListDMA + sizeof(TLanList) * priv->txHead;
1734 if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
1735 netif_stop_queue(dev);
1736 outl( head_list_phys, dev->base_addr + TLAN_CH_PARM );
1737 ack |= TLAN_HC_GO;
1738 } else {
1739 priv->txInProgress = 0;
1740 }
1741 }
1742
1743 return ack;
1744
1745} /* TLan_HandleTxEOC */
1746
1747
1748
1749
1750 /***************************************************************
1751 * TLan_HandleStatusCheck
1752 *
1753 * Returns:
1754 * 0 if Adapter check, 1 if Network Status check.
1755 * Parms:
1756 * dev Device assigned the IRQ that was
1757 * raised.
1758 * host_int The contents of the HOST_INT
1759 * port.
1760 *
1761 * This function handles Adapter Check/Network Status
1762 * interrupts generated by the adapter. It checks the
1763 * vector in the HOST_INT register to determine if it is
1764 * an Adapter Check interrupt. If so, it resets the
1765 * adapter. Otherwise it clears the status registers
1766 * and services the PHY.
1767 *
1768 **************************************************************/
1769
Harvey Harrison98e0f522008-02-18 10:04:38 -08001770static u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001771{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 TLanPrivateInfo *priv = netdev_priv(dev);
1773 u32 ack;
1774 u32 error;
1775 u8 net_sts;
1776 u32 phy;
1777 u16 tlphy_ctl;
1778 u16 tlphy_sts;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001779
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 ack = 1;
1781 if ( host_int & TLAN_HI_IV_MASK ) {
1782 netif_stop_queue( dev );
1783 error = inl( dev->base_addr + TLAN_CH_PARM );
1784 printk( "TLAN: %s: Adaptor Error = 0x%x\n", dev->name, error );
1785 TLan_ReadAndClearStats( dev, TLAN_RECORD );
1786 outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
1787
1788 schedule_work(&priv->tlan_tqueue);
1789
1790 netif_wake_queue(dev);
1791 ack = 0;
1792 } else {
1793 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name );
1794 phy = priv->phy[priv->phyNum];
1795
1796 net_sts = TLan_DioRead8( dev->base_addr, TLAN_NET_STS );
1797 if ( net_sts ) {
1798 TLan_DioWrite8( dev->base_addr, TLAN_NET_STS, net_sts );
1799 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n", dev->name, (unsigned) net_sts );
1800 }
1801 if ( ( net_sts & TLAN_NET_STS_MIRQ ) && ( priv->phyNum == 0 ) ) {
1802 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_STS, &tlphy_sts );
1803 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
1804 if ( ! ( tlphy_sts & TLAN_TS_POLOK ) && ! ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
1805 tlphy_ctl |= TLAN_TC_SWAPOL;
1806 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
1807 } else if ( ( tlphy_sts & TLAN_TS_POLOK ) && ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
1808 tlphy_ctl &= ~TLAN_TC_SWAPOL;
1809 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
1810 }
1811
1812 if (debug) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001813 TLan_PhyPrint( dev );
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 }
1815 }
1816 }
1817
1818 return ack;
1819
1820} /* TLan_HandleStatusCheck */
1821
1822
1823
1824
1825 /***************************************************************
1826 * TLan_HandleRxEOC
1827 *
1828 * Returns:
1829 * 1
1830 * Parms:
1831 * dev Device assigned the IRQ that was
1832 * raised.
1833 * host_int The contents of the HOST_INT
1834 * port.
1835 *
1836 * This driver is structured to determine EOC occurrences by
1837 * reading the CSTAT member of the list structure. Rx EOC
1838 * interrupts are disabled via the DIO INTDIS register.
1839 * However, TLAN chips before revision 3.0 didn't have this
1840 * CSTAT member or a INTDIS register, so if this chip is
1841 * pre-3.0, process EOC interrupts normally.
1842 *
1843 **************************************************************/
1844
Harvey Harrison98e0f522008-02-18 10:04:38 -08001845static u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846{
1847 TLanPrivateInfo *priv = netdev_priv(dev);
1848 dma_addr_t head_list_phys;
1849 u32 ack = 1;
1850
1851 if ( priv->tlanRev < 0x30 ) {
1852 TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d) -- IRQ\n", priv->rxHead, priv->rxTail );
1853 head_list_phys = priv->rxListDMA + sizeof(TLanList) * priv->rxHead;
1854 outl( head_list_phys, dev->base_addr + TLAN_CH_PARM );
1855 ack |= TLAN_HC_GO | TLAN_HC_RT;
1856 priv->rxEocCount++;
1857 }
1858
1859 return ack;
1860
1861} /* TLan_HandleRxEOC */
1862
1863
1864
1865
1866/*****************************************************************************
1867******************************************************************************
1868
1869 ThunderLAN Driver Timer Function
1870
1871******************************************************************************
1872*****************************************************************************/
1873
1874
1875 /***************************************************************
1876 * TLan_Timer
1877 *
1878 * Returns:
1879 * Nothing
1880 * Parms:
1881 * data A value given to add timer when
1882 * add_timer was called.
1883 *
1884 * This function handles timed functionality for the
1885 * TLAN driver. The two current timer uses are for
1886 * delaying for autonegotionation and driving the ACT LED.
1887 * - Autonegotiation requires being allowed about
1888 * 2 1/2 seconds before attempting to transmit a
1889 * packet. It would be a very bad thing to hang
1890 * the kernel this long, so the driver doesn't
1891 * allow transmission 'til after this time, for
1892 * certain PHYs. It would be much nicer if all
1893 * PHYs were interrupt-capable like the internal
1894 * PHY.
1895 * - The ACT LED, which shows adapter activity, is
1896 * driven by the driver, and so must be left on
1897 * for a short period to power up the LED so it
1898 * can be seen. This delay can be changed by
1899 * changing the TLAN_TIMER_ACT_DELAY in tlan.h,
1900 * if desired. 100 ms produces a slightly
1901 * sluggish response.
1902 *
1903 **************************************************************/
1904
Harvey Harrison98e0f522008-02-18 10:04:38 -08001905static void TLan_Timer( unsigned long data )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906{
1907 struct net_device *dev = (struct net_device *) data;
1908 TLanPrivateInfo *priv = netdev_priv(dev);
1909 u32 elapsed;
1910 unsigned long flags = 0;
1911
1912 priv->timer.function = NULL;
1913
1914 switch ( priv->timerType ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001915#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916 case TLAN_TIMER_LINK_BEAT:
1917 TLan_PhyMonitor( dev );
1918 break;
1919#endif
1920 case TLAN_TIMER_PHY_PDOWN:
1921 TLan_PhyPowerDown( dev );
1922 break;
1923 case TLAN_TIMER_PHY_PUP:
1924 TLan_PhyPowerUp( dev );
1925 break;
1926 case TLAN_TIMER_PHY_RESET:
1927 TLan_PhyReset( dev );
1928 break;
1929 case TLAN_TIMER_PHY_START_LINK:
1930 TLan_PhyStartLink( dev );
1931 break;
1932 case TLAN_TIMER_PHY_FINISH_AN:
1933 TLan_PhyFinishAutoNeg( dev );
1934 break;
1935 case TLAN_TIMER_FINISH_RESET:
1936 TLan_FinishReset( dev );
1937 break;
1938 case TLAN_TIMER_ACTIVITY:
1939 spin_lock_irqsave(&priv->lock, flags);
1940 if ( priv->timer.function == NULL ) {
1941 elapsed = jiffies - priv->timerSetAt;
1942 if ( elapsed >= TLAN_TIMER_ACT_DELAY ) {
1943 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
1944 } else {
1945 priv->timer.function = &TLan_Timer;
1946 priv->timer.expires = priv->timerSetAt + TLAN_TIMER_ACT_DELAY;
1947 spin_unlock_irqrestore(&priv->lock, flags);
1948 add_timer( &priv->timer );
1949 break;
1950 }
1951 }
1952 spin_unlock_irqrestore(&priv->lock, flags);
1953 break;
1954 default:
1955 break;
1956 }
1957
1958} /* TLan_Timer */
1959
1960
1961
1962
1963/*****************************************************************************
1964******************************************************************************
1965
1966 ThunderLAN Driver Adapter Related Routines
1967
1968******************************************************************************
1969*****************************************************************************/
1970
1971
1972 /***************************************************************
1973 * TLan_ResetLists
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001974 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975 * Returns:
1976 * Nothing
1977 * Parms:
1978 * dev The device structure with the list
1979 * stuctures to be reset.
1980 *
1981 * This routine sets the variables associated with managing
1982 * the TLAN lists to their initial values.
1983 *
1984 **************************************************************/
1985
Harvey Harrison98e0f522008-02-18 10:04:38 -08001986static void TLan_ResetLists( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987{
1988 TLanPrivateInfo *priv = netdev_priv(dev);
1989 int i;
1990 TLanList *list;
1991 dma_addr_t list_phys;
1992 struct sk_buff *skb;
1993 void *t = NULL;
1994
1995 priv->txHead = 0;
1996 priv->txTail = 0;
1997 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
1998 list = priv->txList + i;
1999 list->cStat = TLAN_CSTAT_UNUSED;
2000 if ( bbuf ) {
2001 list->buffer[0].address = priv->txBufferDMA + ( i * TLAN_MAX_FRAME_SIZE );
2002 } else {
2003 list->buffer[0].address = 0;
2004 }
2005 list->buffer[2].count = 0;
2006 list->buffer[2].address = 0;
2007 list->buffer[8].address = 0;
2008 list->buffer[9].address = 0;
2009 }
2010
2011 priv->rxHead = 0;
2012 priv->rxTail = TLAN_NUM_RX_LISTS - 1;
2013 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
2014 list = priv->rxList + i;
2015 list_phys = priv->rxListDMA + sizeof(TLanList) * i;
2016 list->cStat = TLAN_CSTAT_READY;
2017 list->frameSize = TLAN_MAX_FRAME_SIZE;
2018 list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
2019 if ( bbuf ) {
2020 list->buffer[0].address = priv->rxBufferDMA + ( i * TLAN_MAX_FRAME_SIZE );
2021 } else {
2022 skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
2023 if ( skb == NULL ) {
2024 printk( "TLAN: Couldn't allocate memory for received data.\n" );
2025 /* If this ever happened it would be a problem */
2026 } else {
2027 skb->dev = dev;
2028 skb_reserve( skb, 2 );
2029 t = (void *) skb_put( skb, TLAN_MAX_FRAME_SIZE );
2030 }
2031 list->buffer[0].address = pci_map_single(priv->pciDev, t, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
2032 list->buffer[8].address = (u32) t;
2033 TLan_StoreSKB(list, skb);
2034 }
2035 list->buffer[1].count = 0;
2036 list->buffer[1].address = 0;
2037 if ( i < TLAN_NUM_RX_LISTS - 1 )
2038 list->forward = list_phys + sizeof(TLanList);
2039 else
2040 list->forward = 0;
2041 }
2042
2043} /* TLan_ResetLists */
2044
2045
Harvey Harrison98e0f522008-02-18 10:04:38 -08002046static void TLan_FreeLists( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047{
2048 TLanPrivateInfo *priv = netdev_priv(dev);
2049 int i;
2050 TLanList *list;
2051 struct sk_buff *skb;
2052
2053 if ( ! bbuf ) {
2054 for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
2055 list = priv->txList + i;
2056 skb = TLan_GetSKB(list);
2057 if ( skb ) {
2058 pci_unmap_single(priv->pciDev, list->buffer[0].address, skb->len, PCI_DMA_TODEVICE);
2059 dev_kfree_skb_any( skb );
2060 list->buffer[8].address = 0;
2061 list->buffer[9].address = 0;
2062 }
2063 }
2064
2065 for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
2066 list = priv->rxList + i;
2067 skb = TLan_GetSKB(list);
2068 if ( skb ) {
2069 pci_unmap_single(priv->pciDev, list->buffer[0].address, TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
2070 dev_kfree_skb_any( skb );
2071 list->buffer[8].address = 0;
2072 list->buffer[9].address = 0;
2073 }
2074 }
2075 }
2076} /* TLan_FreeLists */
2077
2078
2079
2080
2081 /***************************************************************
2082 * TLan_PrintDio
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002083 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084 * Returns:
2085 * Nothing
2086 * Parms:
2087 * io_base Base IO port of the device of
2088 * which to print DIO registers.
2089 *
2090 * This function prints out all the internal (DIO)
2091 * registers of a TLAN chip.
2092 *
2093 **************************************************************/
2094
Harvey Harrison98e0f522008-02-18 10:04:38 -08002095static void TLan_PrintDio( u16 io_base )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096{
2097 u32 data0, data1;
2098 int i;
2099
2100 printk( "TLAN: Contents of internal registers for io base 0x%04hx.\n", io_base );
2101 printk( "TLAN: Off. +0 +4\n" );
2102 for ( i = 0; i < 0x4C; i+= 8 ) {
2103 data0 = TLan_DioRead32( io_base, i );
2104 data1 = TLan_DioRead32( io_base, i + 0x4 );
2105 printk( "TLAN: 0x%02x 0x%08x 0x%08x\n", i, data0, data1 );
2106 }
2107
2108} /* TLan_PrintDio */
2109
2110
2111
2112
2113 /***************************************************************
2114 * TLan_PrintList
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002115 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002116 * Returns:
2117 * Nothing
2118 * Parms:
2119 * list A pointer to the TLanList structure to
2120 * be printed.
2121 * type A string to designate type of list,
2122 * "Rx" or "Tx".
2123 * num The index of the list.
2124 *
2125 * This function prints out the contents of the list
2126 * pointed to by the list parameter.
2127 *
2128 **************************************************************/
2129
Harvey Harrison98e0f522008-02-18 10:04:38 -08002130static void TLan_PrintList( TLanList *list, char *type, int num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002131{
2132 int i;
2133
2134 printk( "TLAN: %s List %d at 0x%08x\n", type, num, (u32) list );
2135 printk( "TLAN: Forward = 0x%08x\n", list->forward );
2136 printk( "TLAN: CSTAT = 0x%04hx\n", list->cStat );
2137 printk( "TLAN: Frame Size = 0x%04hx\n", list->frameSize );
2138 /* for ( i = 0; i < 10; i++ ) { */
2139 for ( i = 0; i < 2; i++ ) {
2140 printk( "TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n", i, list->buffer[i].count, list->buffer[i].address );
2141 }
2142
2143} /* TLan_PrintList */
2144
2145
2146
2147
2148 /***************************************************************
2149 * TLan_ReadAndClearStats
2150 *
2151 * Returns:
2152 * Nothing
2153 * Parms:
2154 * dev Pointer to device structure of adapter
2155 * to which to read stats.
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002156 * record Flag indicating whether to add
Linus Torvalds1da177e2005-04-16 15:20:36 -07002157 *
2158 * This functions reads all the internal status registers
2159 * of the TLAN chip, which clears them as a side effect.
2160 * It then either adds the values to the device's status
2161 * struct, or discards them, depending on whether record
2162 * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0).
2163 *
2164 **************************************************************/
2165
Harvey Harrison98e0f522008-02-18 10:04:38 -08002166static void TLan_ReadAndClearStats( struct net_device *dev, int record )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002167{
2168 TLanPrivateInfo *priv = netdev_priv(dev);
2169 u32 tx_good, tx_under;
2170 u32 rx_good, rx_over;
2171 u32 def_tx, crc, code;
2172 u32 multi_col, single_col;
2173 u32 excess_col, late_col, loss;
2174
2175 outw( TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR );
2176 tx_good = inb( dev->base_addr + TLAN_DIO_DATA );
2177 tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2178 tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
2179 tx_under = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
2180
2181 outw( TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR );
2182 rx_good = inb( dev->base_addr + TLAN_DIO_DATA );
2183 rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2184 rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
2185 rx_over = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002186
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187 outw( TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR );
2188 def_tx = inb( dev->base_addr + TLAN_DIO_DATA );
2189 def_tx += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2190 crc = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2191 code = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002192
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193 outw( TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
2194 multi_col = inb( dev->base_addr + TLAN_DIO_DATA );
2195 multi_col += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
2196 single_col = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2197 single_col += inb( dev->base_addr + TLAN_DIO_DATA + 3 ) << 8;
2198
2199 outw( TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
2200 excess_col = inb( dev->base_addr + TLAN_DIO_DATA );
2201 late_col = inb( dev->base_addr + TLAN_DIO_DATA + 1 );
2202 loss = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
2203
2204 if ( record ) {
2205 priv->stats.rx_packets += rx_good;
2206 priv->stats.rx_errors += rx_over + crc + code;
2207 priv->stats.tx_packets += tx_good;
2208 priv->stats.tx_errors += tx_under + loss;
2209 priv->stats.collisions += multi_col + single_col + excess_col + late_col;
2210
2211 priv->stats.rx_over_errors += rx_over;
2212 priv->stats.rx_crc_errors += crc;
2213 priv->stats.rx_frame_errors += code;
2214
2215 priv->stats.tx_aborted_errors += tx_under;
2216 priv->stats.tx_carrier_errors += loss;
2217 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002218
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219} /* TLan_ReadAndClearStats */
2220
2221
2222
2223
2224 /***************************************************************
2225 * TLan_Reset
2226 *
2227 * Returns:
2228 * 0
2229 * Parms:
2230 * dev Pointer to device structure of adapter
2231 * to be reset.
2232 *
2233 * This function resets the adapter and it's physical
2234 * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
2235 * Programmer's Guide" for details. The routine tries to
2236 * implement what is detailed there, though adjustments
2237 * have been made.
2238 *
2239 **************************************************************/
2240
Harvey Harrison98e0f522008-02-18 10:04:38 -08002241static void
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242TLan_ResetAdapter( struct net_device *dev )
2243{
2244 TLanPrivateInfo *priv = netdev_priv(dev);
2245 int i;
2246 u32 addr;
2247 u32 data;
2248 u8 data8;
2249
2250 priv->tlanFullDuplex = FALSE;
2251 priv->phyOnline=0;
2252 netif_carrier_off(dev);
2253
2254/* 1. Assert reset bit. */
2255
2256 data = inl(dev->base_addr + TLAN_HOST_CMD);
2257 data |= TLAN_HC_AD_RST;
2258 outl(data, dev->base_addr + TLAN_HOST_CMD);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002259
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 udelay(1000);
2261
2262/* 2. Turn off interrupts. ( Probably isn't necessary ) */
2263
2264 data = inl(dev->base_addr + TLAN_HOST_CMD);
2265 data |= TLAN_HC_INT_OFF;
2266 outl(data, dev->base_addr + TLAN_HOST_CMD);
2267
2268/* 3. Clear AREGs and HASHs. */
2269
2270 for ( i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4 ) {
2271 TLan_DioWrite32( dev->base_addr, (u16) i, 0 );
2272 }
2273
2274/* 4. Setup NetConfig register. */
2275
2276 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2277 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
2278
2279/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
2280
2281 outl( TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD );
2282 outl( TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD );
2283
2284/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
2285
2286 outw( TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR );
2287 addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
2288 TLan_SetBit( TLAN_NET_SIO_NMRST, addr );
2289
2290/* 7. Setup the remaining registers. */
2291
2292 if ( priv->tlanRev >= 0x30 ) {
2293 data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
2294 TLan_DioWrite8( dev->base_addr, TLAN_INT_DIS, data8 );
2295 }
2296 TLan_PhyDetect( dev );
2297 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002298
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299 if ( priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY ) {
2300 data |= TLAN_NET_CFG_BIT;
2301 if ( priv->aui == 1 ) {
2302 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x0a );
2303 } else if ( priv->duplex == TLAN_DUPLEX_FULL ) {
2304 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x00 );
2305 priv->tlanFullDuplex = TRUE;
2306 } else {
2307 TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x08 );
2308 }
2309 }
2310
2311 if ( priv->phyNum == 0 ) {
2312 data |= TLAN_NET_CFG_PHY_EN;
2313 }
2314 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
2315
2316 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2317 TLan_FinishReset( dev );
2318 } else {
2319 TLan_PhyPowerDown( dev );
2320 }
2321
2322} /* TLan_ResetAdapter */
2323
2324
2325
2326
Harvey Harrison98e0f522008-02-18 10:04:38 -08002327static void
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328TLan_FinishReset( struct net_device *dev )
2329{
2330 TLanPrivateInfo *priv = netdev_priv(dev);
2331 u8 data;
2332 u32 phy;
2333 u8 sio;
2334 u16 status;
2335 u16 partner;
2336 u16 tlphy_ctl;
2337 u16 tlphy_par;
2338 u16 tlphy_id1, tlphy_id2;
2339 int i;
2340
2341 phy = priv->phy[priv->phyNum];
2342
2343 data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
2344 if ( priv->tlanFullDuplex ) {
2345 data |= TLAN_NET_CMD_DUPLEX;
2346 }
2347 TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, data );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002348 data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349 if ( priv->phyNum == 0 ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002350 data |= TLAN_NET_MASK_MASK7;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351 }
2352 TLan_DioWrite8( dev->base_addr, TLAN_NET_MASK, data );
2353 TLan_DioWrite16( dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7 );
2354 TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &tlphy_id1 );
2355 TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &tlphy_id2 );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002356
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357 if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) || ( priv->aui ) ) {
2358 status = MII_GS_LINK;
2359 printk( "TLAN: %s: Link forced.\n", dev->name );
2360 } else {
2361 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2362 udelay( 1000 );
2363 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002364 if ( (status & MII_GS_LINK) && /* We only support link info on Nat.Sem. PHY's */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365 (tlphy_id1 == NAT_SEM_ID1) &&
2366 (tlphy_id2 == NAT_SEM_ID2) ) {
2367 TLan_MiiReadReg( dev, phy, MII_AN_LPA, &partner );
2368 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_PAR, &tlphy_par );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002369
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370 printk( "TLAN: %s: Link active with ", dev->name );
2371 if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002372 printk( "forced 10%sMbps %s-Duplex\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002373 tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
2374 tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
2375 } else {
2376 printk( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n",
2377 tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
2378 tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
2379 printk("TLAN: Partner capability: ");
2380 for (i = 5; i <= 10; i++)
2381 if (partner & (1<<i))
2382 printk("%s",media[i-5]);
2383 printk("\n");
2384 }
2385
2386 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002387#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388 /* We have link beat..for now anyway */
2389 priv->link = 1;
2390 /*Enabling link beat monitoring */
2391 TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_LINK_BEAT );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002392#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002393 } else if (status & MII_GS_LINK) {
2394 printk( "TLAN: %s: Link active\n", dev->name );
2395 TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
2396 }
2397 }
2398
2399 if ( priv->phyNum == 0 ) {
2400 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
2401 tlphy_ctl |= TLAN_TC_INTEN;
2402 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl );
2403 sio = TLan_DioRead8( dev->base_addr, TLAN_NET_SIO );
2404 sio |= TLAN_NET_SIO_MINTEN;
2405 TLan_DioWrite8( dev->base_addr, TLAN_NET_SIO, sio );
2406 }
2407
2408 if ( status & MII_GS_LINK ) {
2409 TLan_SetMac( dev, 0, dev->dev_addr );
2410 priv->phyOnline = 1;
2411 outb( ( TLAN_HC_INT_ON >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
2412 if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) {
2413 outb( ( TLAN_HC_REQ_INT >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
2414 }
2415 outl( priv->rxListDMA, dev->base_addr + TLAN_CH_PARM );
2416 outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD );
2417 netif_carrier_on(dev);
2418 } else {
2419 printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name );
2420 TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
2421 return;
2422 }
James Harper562faf42005-05-05 15:14:18 -07002423 TLan_SetMulticastList(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424
2425} /* TLan_FinishReset */
2426
2427
2428
2429
2430 /***************************************************************
2431 * TLan_SetMac
2432 *
2433 * Returns:
2434 * Nothing
2435 * Parms:
2436 * dev Pointer to device structure of adapter
2437 * on which to change the AREG.
2438 * areg The AREG to set the address in (0 - 3).
2439 * mac A pointer to an array of chars. Each
2440 * element stores one byte of the address.
2441 * IE, it isn't in ascii.
2442 *
2443 * This function transfers a MAC address to one of the
2444 * TLAN AREGs (address registers). The TLAN chip locks
2445 * the register on writing to offset 0 and unlocks the
2446 * register after writing to offset 5. If NULL is passed
2447 * in mac, then the AREG is filled with 0's.
2448 *
2449 **************************************************************/
2450
Harvey Harrison98e0f522008-02-18 10:04:38 -08002451static void TLan_SetMac( struct net_device *dev, int areg, char *mac )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452{
2453 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002454
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455 areg *= 6;
2456
2457 if ( mac != NULL ) {
2458 for ( i = 0; i < 6; i++ )
2459 TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, mac[i] );
2460 } else {
2461 for ( i = 0; i < 6; i++ )
2462 TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, 0 );
2463 }
2464
2465} /* TLan_SetMac */
2466
2467
2468
2469
2470/*****************************************************************************
2471******************************************************************************
2472
2473 ThunderLAN Driver PHY Layer Routines
2474
2475******************************************************************************
2476*****************************************************************************/
2477
2478
2479
2480 /*********************************************************************
2481 * TLan_PhyPrint
2482 *
2483 * Returns:
2484 * Nothing
2485 * Parms:
2486 * dev A pointer to the device structure of the
2487 * TLAN device having the PHYs to be detailed.
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002488 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489 * This function prints the registers a PHY (aka transceiver).
2490 *
2491 ********************************************************************/
2492
Harvey Harrison98e0f522008-02-18 10:04:38 -08002493static void TLan_PhyPrint( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494{
2495 TLanPrivateInfo *priv = netdev_priv(dev);
2496 u16 i, data0, data1, data2, data3, phy;
2497
2498 phy = priv->phy[priv->phyNum];
2499
2500 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2501 printk( "TLAN: Device %s, Unmanaged PHY.\n", dev->name );
2502 } else if ( phy <= TLAN_PHY_MAX_ADDR ) {
2503 printk( "TLAN: Device %s, PHY 0x%02x.\n", dev->name, phy );
2504 printk( "TLAN: Off. +0 +1 +2 +3 \n" );
2505 for ( i = 0; i < 0x20; i+= 4 ) {
2506 printk( "TLAN: 0x%02x", i );
2507 TLan_MiiReadReg( dev, phy, i, &data0 );
2508 printk( " 0x%04hx", data0 );
2509 TLan_MiiReadReg( dev, phy, i + 1, &data1 );
2510 printk( " 0x%04hx", data1 );
2511 TLan_MiiReadReg( dev, phy, i + 2, &data2 );
2512 printk( " 0x%04hx", data2 );
2513 TLan_MiiReadReg( dev, phy, i + 3, &data3 );
2514 printk( " 0x%04hx\n", data3 );
2515 }
2516 } else {
2517 printk( "TLAN: Device %s, Invalid PHY.\n", dev->name );
2518 }
2519
2520} /* TLan_PhyPrint */
2521
2522
2523
2524
2525 /*********************************************************************
2526 * TLan_PhyDetect
2527 *
2528 * Returns:
2529 * Nothing
2530 * Parms:
2531 * dev A pointer to the device structure of the adapter
2532 * for which the PHY needs determined.
2533 *
2534 * So far I've found that adapters which have external PHYs
2535 * may also use the internal PHY for part of the functionality.
2536 * (eg, AUI/Thinnet). This function finds out if this TLAN
2537 * chip has an internal PHY, and then finds the first external
2538 * PHY (starting from address 0) if it exists).
2539 *
2540 ********************************************************************/
2541
Harvey Harrison98e0f522008-02-18 10:04:38 -08002542static void TLan_PhyDetect( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543{
2544 TLanPrivateInfo *priv = netdev_priv(dev);
2545 u16 control;
2546 u16 hi;
2547 u16 lo;
2548 u32 phy;
2549
2550 if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
2551 priv->phyNum = 0xFFFF;
2552 return;
2553 }
2554
2555 TLan_MiiReadReg( dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002556
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557 if ( hi != 0xFFFF ) {
2558 priv->phy[0] = TLAN_PHY_MAX_ADDR;
2559 } else {
2560 priv->phy[0] = TLAN_PHY_NONE;
2561 }
2562
2563 priv->phy[1] = TLAN_PHY_NONE;
2564 for ( phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++ ) {
2565 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &control );
2566 TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &hi );
2567 TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &lo );
2568 if ( ( control != 0xFFFF ) || ( hi != 0xFFFF ) || ( lo != 0xFFFF ) ) {
2569 TLAN_DBG( TLAN_DEBUG_GNRL, "PHY found at %02x %04x %04x %04x\n", phy, control, hi, lo );
2570 if ( ( priv->phy[1] == TLAN_PHY_NONE ) && ( phy != TLAN_PHY_MAX_ADDR ) ) {
2571 priv->phy[1] = phy;
2572 }
2573 }
2574 }
2575
2576 if ( priv->phy[1] != TLAN_PHY_NONE ) {
2577 priv->phyNum = 1;
2578 } else if ( priv->phy[0] != TLAN_PHY_NONE ) {
2579 priv->phyNum = 0;
2580 } else {
2581 printk( "TLAN: Cannot initialize device, no PHY was found!\n" );
2582 }
2583
2584} /* TLan_PhyDetect */
2585
2586
2587
2588
Harvey Harrison98e0f522008-02-18 10:04:38 -08002589static void TLan_PhyPowerDown( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002590{
2591 TLanPrivateInfo *priv = netdev_priv(dev);
2592 u16 value;
2593
2594 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name );
2595 value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
2596 TLan_MiiSync( dev->base_addr );
2597 TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
2598 if ( ( priv->phyNum == 0 ) && ( priv->phy[1] != TLAN_PHY_NONE ) && ( ! ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) ) ) {
2599 TLan_MiiSync( dev->base_addr );
2600 TLan_MiiWriteReg( dev, priv->phy[1], MII_GEN_CTL, value );
2601 }
2602
2603 /* Wait for 50 ms and powerup
2604 * This is abitrary. It is intended to make sure the
2605 * transceiver settles.
2606 */
2607 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP );
2608
2609} /* TLan_PhyPowerDown */
2610
2611
2612
2613
Harvey Harrison98e0f522008-02-18 10:04:38 -08002614static void TLan_PhyPowerUp( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615{
2616 TLanPrivateInfo *priv = netdev_priv(dev);
2617 u16 value;
2618
2619 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name );
2620 TLan_MiiSync( dev->base_addr );
2621 value = MII_GC_LOOPBK;
2622 TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
2623 TLan_MiiSync(dev->base_addr);
2624 /* Wait for 500 ms and reset the
2625 * transceiver. The TLAN docs say both 50 ms and
2626 * 500 ms, so do the longer, just in case.
2627 */
2628 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET );
2629
2630} /* TLan_PhyPowerUp */
2631
2632
2633
2634
Harvey Harrison98e0f522008-02-18 10:04:38 -08002635static void TLan_PhyReset( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636{
2637 TLanPrivateInfo *priv = netdev_priv(dev);
2638 u16 phy;
2639 u16 value;
2640
2641 phy = priv->phy[priv->phyNum];
2642
2643 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name );
2644 TLan_MiiSync( dev->base_addr );
2645 value = MII_GC_LOOPBK | MII_GC_RESET;
2646 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, value );
2647 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
2648 while ( value & MII_GC_RESET ) {
2649 TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
2650 }
2651
2652 /* Wait for 500 ms and initialize.
2653 * I don't remember why I wait this long.
2654 * I've changed this to 50ms, as it seems long enough.
2655 */
2656 TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK );
2657
2658} /* TLan_PhyReset */
2659
2660
2661
2662
Harvey Harrison98e0f522008-02-18 10:04:38 -08002663static void TLan_PhyStartLink( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002664{
2665 TLanPrivateInfo *priv = netdev_priv(dev);
2666 u16 ability;
2667 u16 control;
2668 u16 data;
2669 u16 phy;
2670 u16 status;
2671 u16 tctl;
2672
2673 phy = priv->phy[priv->phyNum];
2674 TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name );
2675 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2676 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &ability );
2677
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002678 if ( ( status & MII_GS_AUTONEG ) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679 ( ! priv->aui ) ) {
2680 ability = status >> 11;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002681 if ( priv->speed == TLAN_SPEED_10 &&
Linus Torvalds1da177e2005-04-16 15:20:36 -07002682 priv->duplex == TLAN_DUPLEX_HALF) {
2683 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000);
2684 } else if ( priv->speed == TLAN_SPEED_10 &&
2685 priv->duplex == TLAN_DUPLEX_FULL) {
2686 priv->tlanFullDuplex = TRUE;
2687 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100);
2688 } else if ( priv->speed == TLAN_SPEED_100 &&
2689 priv->duplex == TLAN_DUPLEX_HALF) {
2690 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000);
2691 } else if ( priv->speed == TLAN_SPEED_100 &&
2692 priv->duplex == TLAN_DUPLEX_FULL) {
2693 priv->tlanFullDuplex = TRUE;
2694 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100);
2695 } else {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002696
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697 /* Set Auto-Neg advertisement */
2698 TLan_MiiWriteReg( dev, phy, MII_AN_ADV, (ability << 5) | 1);
2699 /* Enablee Auto-Neg */
2700 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 );
2701 /* Restart Auto-Neg */
2702 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 );
2703 /* Wait for 4 sec for autonegotiation
2704 * to complete. The max spec time is less than this
2705 * but the card need additional time to start AN.
2706 * .5 sec should be plenty extra.
2707 */
2708 printk( "TLAN: %s: Starting autonegotiation.\n", dev->name );
2709 TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN );
2710 return;
2711 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002712
2713 }
2714
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715 if ( ( priv->aui ) && ( priv->phyNum != 0 ) ) {
2716 priv->phyNum = 0;
2717 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2718 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
2719 TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN );
2720 return;
2721 } else if ( priv->phyNum == 0 ) {
2722 control = 0;
2723 TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tctl );
2724 if ( priv->aui ) {
2725 tctl |= TLAN_TC_AUISEL;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002726 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727 tctl &= ~TLAN_TC_AUISEL;
2728 if ( priv->duplex == TLAN_DUPLEX_FULL ) {
2729 control |= MII_GC_DUPLEX;
2730 priv->tlanFullDuplex = TRUE;
2731 }
2732 if ( priv->speed == TLAN_SPEED_100 ) {
2733 control |= MII_GC_SPEEDSEL;
2734 }
2735 }
2736 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, control );
2737 TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl );
2738 }
2739
2740 /* Wait for 2 sec to give the transceiver time
2741 * to establish link.
2742 */
2743 TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET );
2744
2745} /* TLan_PhyStartLink */
2746
2747
2748
2749
Harvey Harrison98e0f522008-02-18 10:04:38 -08002750static void TLan_PhyFinishAutoNeg( struct net_device *dev )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751{
2752 TLanPrivateInfo *priv = netdev_priv(dev);
2753 u16 an_adv;
2754 u16 an_lpa;
2755 u16 data;
2756 u16 mode;
2757 u16 phy;
2758 u16 status;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002759
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760 phy = priv->phy[priv->phyNum];
2761
2762 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2763 udelay( 1000 );
2764 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
2765
2766 if ( ! ( status & MII_GS_AUTOCMPLT ) ) {
2767 /* Wait for 8 sec to give the process
2768 * more time. Perhaps we should fail after a while.
2769 */
2770 if (!priv->neg_be_verbose++) {
2771 printk(KERN_INFO "TLAN: Giving autonegotiation more time.\n");
2772 printk(KERN_INFO "TLAN: Please check that your adapter has\n");
2773 printk(KERN_INFO "TLAN: been properly connected to a HUB or Switch.\n");
2774 printk(KERN_INFO "TLAN: Trying to establish link in the background...\n");
2775 }
2776 TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN );
2777 return;
2778 }
2779
2780 printk( "TLAN: %s: Autonegotiation complete.\n", dev->name );
2781 TLan_MiiReadReg( dev, phy, MII_AN_ADV, &an_adv );
2782 TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa );
2783 mode = an_adv & an_lpa & 0x03E0;
2784 if ( mode & 0x0100 ) {
2785 priv->tlanFullDuplex = TRUE;
2786 } else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) {
2787 priv->tlanFullDuplex = TRUE;
2788 }
2789
2790 if ( ( ! ( mode & 0x0180 ) ) && ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) && ( priv->phyNum != 0 ) ) {
2791 priv->phyNum = 0;
2792 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
2793 TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
2794 TLan_SetTimer( dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN );
2795 return;
2796 }
2797
2798 if ( priv->phyNum == 0 ) {
2799 if ( ( priv->duplex == TLAN_DUPLEX_FULL ) || ( an_adv & an_lpa & 0x0040 ) ) {
2800 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB | MII_GC_DUPLEX );
2801 printk( "TLAN: Starting internal PHY with FULL-DUPLEX\n" );
2802 } else {
2803 TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB );
2804 printk( "TLAN: Starting internal PHY with HALF-DUPLEX\n" );
2805 }
2806 }
2807
2808 /* Wait for 100 ms. No reason in partiticular.
2809 */
2810 TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002811
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812} /* TLan_PhyFinishAutoNeg */
2813
2814#ifdef MONITOR
2815
2816 /*********************************************************************
2817 *
2818 * TLan_phyMonitor
2819 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002820 * Returns:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 * None
2822 *
2823 * Params:
2824 * dev The device structure of this device.
2825 *
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002826 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 * This function monitors PHY condition by reading the status
2828 * register via the MII bus. This can be used to give info
2829 * about link changes (up/down), and possible switch to alternate
2830 * media.
2831 *
2832 * ******************************************************************/
2833
2834void TLan_PhyMonitor( struct net_device *dev )
2835{
2836 TLanPrivateInfo *priv = netdev_priv(dev);
2837 u16 phy;
2838 u16 phy_status;
2839
2840 phy = priv->phy[priv->phyNum];
2841
2842 /* Get PHY status register */
2843 TLan_MiiReadReg( dev, phy, MII_GEN_STS, &phy_status );
2844
2845 /* Check if link has been lost */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002846 if (!(phy_status & MII_GS_LINK)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 if (priv->link) {
2848 priv->link = 0;
2849 printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name);
7d17c1d2005-05-12 19:45:25 -04002850 netif_carrier_off(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851 TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
2852 return;
2853 }
2854 }
2855
2856 /* Link restablished? */
2857 if ((phy_status & MII_GS_LINK) && !priv->link) {
2858 priv->link = 1;
2859 printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);
7d17c1d2005-05-12 19:45:25 -04002860 netif_carrier_on(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861 }
2862
2863 /* Setup a new monitor */
2864 TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002865}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866
2867#endif /* MONITOR */
2868
2869
2870/*****************************************************************************
2871******************************************************************************
2872
2873 ThunderLAN Driver MII Routines
2874
2875 These routines are based on the information in Chap. 2 of the
2876 "ThunderLAN Programmer's Guide", pp. 15-24.
2877
2878******************************************************************************
2879*****************************************************************************/
2880
2881
2882 /***************************************************************
2883 * TLan_MiiReadReg
2884 *
2885 * Returns:
2886 * 0 if ack received ok
2887 * 1 otherwise.
2888 *
2889 * Parms:
2890 * dev The device structure containing
2891 * The io address and interrupt count
2892 * for this device.
2893 * phy The address of the PHY to be queried.
2894 * reg The register whose contents are to be
Matt Mackall4a4efbd2006-01-03 13:27:11 +01002895 * retrieved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 * val A pointer to a variable to store the
2897 * retrieved value.
2898 *
Matt Mackall4a4efbd2006-01-03 13:27:11 +01002899 * This function uses the TLAN's MII bus to retrieve the contents
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900 * of a given register on a PHY. It sends the appropriate info
2901 * and then reads the 16-bit register value from the MII bus via
2902 * the TLAN SIO register.
2903 *
2904 **************************************************************/
2905
Harvey Harrison98e0f522008-02-18 10:04:38 -08002906static int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907{
2908 u8 nack;
2909 u16 sio, tmp;
2910 u32 i;
2911 int err;
2912 int minten;
2913 TLanPrivateInfo *priv = netdev_priv(dev);
2914 unsigned long flags = 0;
2915
2916 err = FALSE;
2917 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2918 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002919
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920 if (!in_irq())
2921 spin_lock_irqsave(&priv->lock, flags);
2922
2923 TLan_MiiSync(dev->base_addr);
2924
2925 minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );
2926 if ( minten )
2927 TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);
2928
2929 TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Start ( 01b ) */
2930 TLan_MiiSendData( dev->base_addr, 0x2, 2 ); /* Read ( 10b ) */
2931 TLan_MiiSendData( dev->base_addr, phy, 5 ); /* Device # */
2932 TLan_MiiSendData( dev->base_addr, reg, 5 ); /* Register # */
2933
2934
2935 TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); /* Change direction */
2936
2937 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Clock Idle bit */
2938 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2939 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Wait 300ns */
2940
2941 nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio); /* Check for ACK */
2942 TLan_SetBit(TLAN_NET_SIO_MCLK, sio); /* Finish ACK */
2943 if (nack) { /* No ACK, so fake it */
2944 for (i = 0; i < 16; i++) {
2945 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
2946 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2947 }
2948 tmp = 0xffff;
2949 err = TRUE;
2950 } else { /* ACK, so read data */
2951 for (tmp = 0, i = 0x8000; i; i >>= 1) {
2952 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
2953 if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio))
2954 tmp |= i;
2955 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2956 }
2957 }
2958
2959
2960 TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */
2961 TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
2962
2963 if ( minten )
2964 TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);
2965
2966 *val = tmp;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002967
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968 if (!in_irq())
2969 spin_unlock_irqrestore(&priv->lock, flags);
2970
2971 return err;
2972
2973} /* TLan_MiiReadReg */
2974
2975
2976
2977
2978 /***************************************************************
2979 * TLan_MiiSendData
2980 *
2981 * Returns:
2982 * Nothing
2983 * Parms:
2984 * base_port The base IO port of the adapter in
2985 * question.
2986 * dev The address of the PHY to be queried.
2987 * data The value to be placed on the MII bus.
2988 * num_bits The number of bits in data that are to
2989 * be placed on the MII bus.
2990 *
2991 * This function sends on sequence of bits on the MII
2992 * configuration bus.
2993 *
2994 **************************************************************/
2995
Harvey Harrison98e0f522008-02-18 10:04:38 -08002996static void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997{
2998 u16 sio;
2999 u32 i;
3000
3001 if ( num_bits == 0 )
3002 return;
3003
3004 outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );
3005 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
3006 TLan_SetBit( TLAN_NET_SIO_MTXEN, sio );
3007
3008 for ( i = ( 0x1 << ( num_bits - 1 ) ); i; i >>= 1 ) {
3009 TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
3010 (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
3011 if ( data & i )
3012 TLan_SetBit( TLAN_NET_SIO_MDATA, sio );
3013 else
3014 TLan_ClearBit( TLAN_NET_SIO_MDATA, sio );
3015 TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
3016 (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
3017 }
3018
3019} /* TLan_MiiSendData */
3020
3021
3022
3023
3024 /***************************************************************
3025 * TLan_MiiSync
3026 *
3027 * Returns:
3028 * Nothing
3029 * Parms:
3030 * base_port The base IO port of the adapter in
3031 * question.
3032 *
3033 * This functions syncs all PHYs in terms of the MII configuration
3034 * bus.
3035 *
3036 **************************************************************/
3037
Harvey Harrison98e0f522008-02-18 10:04:38 -08003038static void TLan_MiiSync( u16 base_port )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039{
3040 int i;
3041 u16 sio;
3042
3043 outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );
3044 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
3045
3046 TLan_ClearBit( TLAN_NET_SIO_MTXEN, sio );
3047 for ( i = 0; i < 32; i++ ) {
3048 TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
3049 TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
3050 }
3051
3052} /* TLan_MiiSync */
3053
3054
3055
3056
3057 /***************************************************************
3058 * TLan_MiiWriteReg
3059 *
3060 * Returns:
3061 * Nothing
3062 * Parms:
3063 * dev The device structure for the device
3064 * to write to.
3065 * phy The address of the PHY to be written to.
3066 * reg The register whose contents are to be
3067 * written.
3068 * val The value to be written to the register.
3069 *
3070 * This function uses the TLAN's MII bus to write the contents of a
3071 * given register on a PHY. It sends the appropriate info and then
3072 * writes the 16-bit register value from the MII configuration bus
3073 * via the TLAN SIO register.
3074 *
3075 **************************************************************/
3076
Harvey Harrison98e0f522008-02-18 10:04:38 -08003077static void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003078{
3079 u16 sio;
3080 int minten;
3081 unsigned long flags = 0;
3082 TLanPrivateInfo *priv = netdev_priv(dev);
3083
3084 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
3085 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003086
Linus Torvalds1da177e2005-04-16 15:20:36 -07003087 if (!in_irq())
3088 spin_lock_irqsave(&priv->lock, flags);
3089
3090 TLan_MiiSync( dev->base_addr );
3091
3092 minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );
3093 if ( minten )
3094 TLan_ClearBit( TLAN_NET_SIO_MINTEN, sio );
3095
3096 TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Start ( 01b ) */
3097 TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Write ( 01b ) */
3098 TLan_MiiSendData( dev->base_addr, phy, 5 ); /* Device # */
3099 TLan_MiiSendData( dev->base_addr, reg, 5 ); /* Register # */
3100
3101 TLan_MiiSendData( dev->base_addr, 0x2, 2 ); /* Send ACK */
3102 TLan_MiiSendData( dev->base_addr, val, 16 ); /* Send Data */
3103
3104 TLan_ClearBit( TLAN_NET_SIO_MCLK, sio ); /* Idle cycle */
3105 TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
3106
3107 if ( minten )
3108 TLan_SetBit( TLAN_NET_SIO_MINTEN, sio );
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003109
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110 if (!in_irq())
3111 spin_unlock_irqrestore(&priv->lock, flags);
3112
3113} /* TLan_MiiWriteReg */
3114
3115
3116
3117
3118/*****************************************************************************
3119******************************************************************************
3120
3121 ThunderLAN Driver Eeprom routines
3122
3123 The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A
3124 EEPROM. These functions are based on information in Microchip's
3125 data sheet. I don't know how well this functions will work with
3126 other EEPROMs.
3127
3128******************************************************************************
3129*****************************************************************************/
3130
3131
3132 /***************************************************************
3133 * TLan_EeSendStart
3134 *
3135 * Returns:
3136 * Nothing
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003137 * Parms:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138 * io_base The IO port base address for the
3139 * TLAN device with the EEPROM to
3140 * use.
3141 *
3142 * This function sends a start cycle to an EEPROM attached
3143 * to a TLAN chip.
3144 *
3145 **************************************************************/
3146
Harvey Harrison98e0f522008-02-18 10:04:38 -08003147static void TLan_EeSendStart( u16 io_base )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003148{
3149 u16 sio;
3150
3151 outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
3152 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3153
3154 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3155 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3156 TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
3157 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
3158 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3159
3160} /* TLan_EeSendStart */
3161
3162
3163
3164
3165 /***************************************************************
3166 * TLan_EeSendByte
3167 *
3168 * Returns:
3169 * If the correct ack was received, 0, otherwise 1
3170 * Parms: io_base The IO port base address for the
3171 * TLAN device with the EEPROM to
3172 * use.
3173 * data The 8 bits of information to
3174 * send to the EEPROM.
3175 * stop If TLAN_EEPROM_STOP is passed, a
3176 * stop cycle is sent after the
3177 * byte is sent after the ack is
3178 * read.
3179 *
3180 * This function sends a byte on the serial EEPROM line,
3181 * driving the clock to send each bit. The function then
3182 * reverses transmission direction and reads an acknowledge
3183 * bit.
3184 *
3185 **************************************************************/
3186
Harvey Harrison98e0f522008-02-18 10:04:38 -08003187static int TLan_EeSendByte( u16 io_base, u8 data, int stop )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188{
3189 int err;
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
3196 /* Assume clock is low, tx is enabled; */
3197 for ( place = 0x80; place != 0; place >>= 1 ) {
3198 if ( place & data )
3199 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3200 else
3201 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
3202 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3203 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3204 }
3205 TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
3206 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3207 err = TLan_GetBit( TLAN_NET_SIO_EDATA, sio );
3208 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3209 TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
3210
3211 if ( ( ! err ) && stop ) {
3212 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* STOP, raise data while clock is high */
3213 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3214 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3215 }
3216
3217 return ( err );
3218
3219} /* TLan_EeSendByte */
3220
3221
3222
3223
3224 /***************************************************************
3225 * TLan_EeReceiveByte
3226 *
3227 * Returns:
3228 * Nothing
3229 * Parms:
3230 * io_base The IO port base address for the
3231 * TLAN device with the EEPROM to
3232 * use.
3233 * data An address to a char to hold the
3234 * data sent from the EEPROM.
3235 * stop If TLAN_EEPROM_STOP is passed, a
3236 * stop cycle is sent after the
3237 * byte is received, and no ack is
3238 * sent.
3239 *
3240 * This function receives 8 bits of data from the EEPROM
3241 * over the serial link. It then sends and ack bit, or no
3242 * ack and a stop bit. This function is used to retrieve
3243 * data after the address of a byte in the EEPROM has been
3244 * sent.
3245 *
3246 **************************************************************/
3247
Harvey Harrison98e0f522008-02-18 10:04:38 -08003248static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003249{
3250 u8 place;
3251 u16 sio;
3252
3253 outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
3254 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3255 *data = 0;
3256
3257 /* Assume clock is low, tx is enabled; */
3258 TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
3259 for ( place = 0x80; place; place >>= 1 ) {
3260 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3261 if ( TLan_GetBit( TLAN_NET_SIO_EDATA, sio ) )
3262 *data |= place;
3263 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3264 }
3265
3266 TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
3267 if ( ! stop ) {
3268 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* Ack = 0 */
3269 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3270 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3271 } else {
3272 TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); /* No ack = 1 (?) */
3273 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3274 TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
3275 TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* STOP, raise data while clock is high */
3276 TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
3277 TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
3278 }
3279
3280} /* TLan_EeReceiveByte */
3281
3282
3283
3284
3285 /***************************************************************
3286 * TLan_EeReadByte
3287 *
3288 * Returns:
3289 * No error = 0, else, the stage at which the error
3290 * occurred.
3291 * Parms:
3292 * io_base The IO port base address for the
3293 * TLAN device with the EEPROM to
3294 * use.
3295 * ee_addr The address of the byte in the
3296 * EEPROM whose contents are to be
3297 * retrieved.
3298 * data An address to a char to hold the
3299 * data obtained from the EEPROM.
3300 *
3301 * This function reads a byte of information from an byte
3302 * cell in the EEPROM.
3303 *
3304 **************************************************************/
3305
Harvey Harrison98e0f522008-02-18 10:04:38 -08003306static int TLan_EeReadByte( struct net_device *dev, u8 ee_addr, u8 *data )
Linus Torvalds1da177e2005-04-16 15:20:36 -07003307{
3308 int err;
3309 TLanPrivateInfo *priv = netdev_priv(dev);
3310 unsigned long flags = 0;
3311 int ret=0;
3312
3313 spin_lock_irqsave(&priv->lock, flags);
3314
3315 TLan_EeSendStart( dev->base_addr );
3316 err = TLan_EeSendByte( dev->base_addr, 0xA0, TLAN_EEPROM_ACK );
3317 if (err)
3318 {
3319 ret=1;
3320 goto fail;
3321 }
3322 err = TLan_EeSendByte( dev->base_addr, ee_addr, TLAN_EEPROM_ACK );
3323 if (err)
3324 {
3325 ret=2;
3326 goto fail;
3327 }
3328 TLan_EeSendStart( dev->base_addr );
3329 err = TLan_EeSendByte( dev->base_addr, 0xA1, TLAN_EEPROM_ACK );
3330 if (err)
3331 {
3332 ret=3;
3333 goto fail;
3334 }
3335 TLan_EeReceiveByte( dev->base_addr, data, TLAN_EEPROM_STOP );
3336fail:
3337 spin_unlock_irqrestore(&priv->lock, flags);
3338
3339 return ret;
3340
3341} /* TLan_EeReadByte */
3342
3343
3344