blob: 9c0dd6b8d6c9a9e6dfae193c36d469d8573853d4 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*******************************************************************************
2 *
3 * Linux ThunderLAN Driver
4 *
5 * tlan.c
6 * by James Banks
7 *
8 * (C) 1997-1998 Caldera, Inc.
9 * (C) 1998 James Banks
10 * (C) 1999-2001 Torben Mathiasen
11 * (C) 2002 Samuel Chessman
12 *
13 * This software may be used and distributed according to the terms
14 * of the GNU General Public License, incorporated herein by reference.
15 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 ** Useful (if not required) reading:
17 *
18 * Texas Instruments, ThunderLAN Programmer's Guide,
19 * TI Literature Number SPWU013A
20 * available in PDF format from www.ti.com
21 * Level One, LXT901 and LXT970 Data Sheets
22 * available in PDF format from www.level1.com
23 * National Semiconductor, DP83840A Data Sheet
24 * available in PDF format from www.national.com
25 * Microchip Technology, 24C01A/02A/04A Data Sheet
26 * available in PDF format from www.microchip.com
27 *
Sakari Ailusc659c382011-01-21 10:59:30 +000028 ******************************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -070029
Joe Perches50624aa2011-03-01 06:56:33 +000030#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31
Alexey Dobriyana6b7a402011-06-06 10:43:46 +000032#include <linux/hardirq.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include <linux/module.h>
34#include <linux/init.h>
Alexey Dobriyana6b7a402011-06-06 10:43:46 +000035#include <linux/interrupt.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include <linux/ioport.h>
37#include <linux/eisa.h>
38#include <linux/pci.h>
Domen Puncer1e7f0bd2005-06-26 18:22:14 -040039#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <linux/netdevice.h>
41#include <linux/etherdevice.h>
42#include <linux/delay.h>
43#include <linux/spinlock.h>
44#include <linux/workqueue.h>
45#include <linux/mii.h>
46
47#include "tlan.h"
48
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
50/* For removing EISA devices */
Sakari Ailusc659c382011-01-21 10:59:30 +000051static struct net_device *tlan_eisa_devices;
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
Sakari Ailusc659c382011-01-21 10:59:30 +000053static int tlan_devices_installed;
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55/* Set speed, duplex and aui settings */
56static int aui[MAX_TLAN_BOARDS];
57static int duplex[MAX_TLAN_BOARDS];
58static int speed[MAX_TLAN_BOARDS];
59static int boards_found;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -070060module_param_array(aui, int, NULL, 0);
61module_param_array(duplex, int, NULL, 0);
62module_param_array(speed, int, NULL, 0);
63MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
Sakari Ailusc659c382011-01-21 10:59:30 +000064MODULE_PARM_DESC(duplex,
65 "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
Joe Perches50624aa2011-03-01 06:56:33 +000066MODULE_PARM_DESC(speed, "ThunderLAN port speed setting(s) (0,10,100)");
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
68MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
69MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
70MODULE_LICENSE("GPL");
71
72
73/* Define this to enable Link beat monitoring */
74#undef MONITOR
75
76/* Turn on debugging. See Documentation/networking/tlan.txt for details */
77static int debug;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -070078module_param(debug, int, 0);
79MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
Linus Torvalds1da177e2005-04-16 15:20:36 -070080
Sakari Ailusc659c382011-01-21 10:59:30 +000081static const char tlan_signature[] = "TLAN";
Sakari Ailusfa6d5d42011-01-21 10:59:31 +000082static const char tlan_banner[] = "ThunderLAN driver v1.17\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -070083static int tlan_have_pci;
84static int tlan_have_eisa;
85
Sakari Ailusc659c382011-01-21 10:59:30 +000086static const char * const media[] = {
87 "10BaseT-HD", "10BaseT-FD", "100baseTx-HD",
88 "100BaseTx-FD", "100BaseT4", NULL
Linus Torvalds1da177e2005-04-16 15:20:36 -070089};
90
91static struct board {
Sakari Ailusc659c382011-01-21 10:59:30 +000092 const char *device_label;
93 u32 flags;
94 u16 addr_ofs;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095} board_info[] = {
96 { "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
Sakari Ailusc659c382011-01-21 10:59:30 +000097 { "Compaq Netelligent 10/100 TX PCI UTP",
98 TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 { "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700100 { "Compaq NetFlex-3/P",
101 TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 { "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700103 { "Compaq Netelligent Integrated 10/100 TX UTP",
104 TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
Sakari Ailusc659c382011-01-21 10:59:30 +0000105 { "Compaq Netelligent Dual 10/100 TX PCI UTP",
106 TLAN_ADAPTER_NONE, 0x83 },
107 { "Compaq Netelligent 10/100 TX Embedded UTP",
108 TLAN_ADAPTER_NONE, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
Sakari Ailusc659c382011-01-21 10:59:30 +0000110 { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 },
111 { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xf8 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
Sakari Ailusc659c382011-01-21 10:59:30 +0000113 { "Compaq Netelligent 10 T/2 PCI UTP/coax", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700114 { "Compaq NetFlex-3/E",
Sakari Ailusc659c382011-01-21 10:59:30 +0000115 TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700116 TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
Sakari Ailusc659c382011-01-21 10:59:30 +0000117 { "Compaq NetFlex-3/E",
118 TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119};
120
Alexey Dobriyana3aa1882010-01-07 11:58:11 +0000121static DEFINE_PCI_DEVICE_TABLE(tlan_pci_tbl) = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
Sakari Ailusc659c382011-01-21 10:59:30 +0000123 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
Sakari Ailusc659c382011-01-21 10:59:30 +0000125 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3I,
Sakari Ailusc659c382011-01-21 10:59:30 +0000127 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_THUNDER,
Sakari Ailusc659c382011-01-21 10:59:30 +0000129 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3B,
Sakari Ailusc659c382011-01-21 10:59:30 +0000131 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100PI,
Sakari Ailusc659c382011-01-21 10:59:30 +0000133 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100D,
Sakari Ailusc659c382011-01-21 10:59:30 +0000135 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100I,
Sakari Ailusc659c382011-01-21 10:59:30 +0000137 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183,
Sakari Ailusc659c382011-01-21 10:59:30 +0000139 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325,
Sakari Ailusc659c382011-01-21 10:59:30 +0000141 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
Sakari Ailusc659c382011-01-21 10:59:30 +0000143 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,
Sakari Ailusc659c382011-01-21 10:59:30 +0000145 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2,
Sakari Ailusc659c382011-01-21 10:59:30 +0000147 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 { 0,}
149};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400150MODULE_DEVICE_TABLE(pci, tlan_pci_tbl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
Sakari Ailusc659c382011-01-21 10:59:30 +0000152static void tlan_eisa_probe(void);
153static void tlan_eisa_cleanup(void);
154static int tlan_init(struct net_device *);
155static int tlan_open(struct net_device *dev);
156static netdev_tx_t tlan_start_tx(struct sk_buff *, struct net_device *);
157static irqreturn_t tlan_handle_interrupt(int, void *);
158static int tlan_close(struct net_device *);
159static struct net_device_stats *tlan_get_stats(struct net_device *);
160static void tlan_set_multicast_list(struct net_device *);
161static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
162static int tlan_probe1(struct pci_dev *pdev, long ioaddr,
163 int irq, int rev, const struct pci_device_id *ent);
164static void tlan_tx_timeout(struct net_device *dev);
165static void tlan_tx_timeout_work(struct work_struct *work);
166static int tlan_init_one(struct pci_dev *pdev,
167 const struct pci_device_id *ent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168
Sakari Ailusc659c382011-01-21 10:59:30 +0000169static u32 tlan_handle_tx_eof(struct net_device *, u16);
170static u32 tlan_handle_stat_overflow(struct net_device *, u16);
171static u32 tlan_handle_rx_eof(struct net_device *, u16);
172static u32 tlan_handle_dummy(struct net_device *, u16);
173static u32 tlan_handle_tx_eoc(struct net_device *, u16);
174static u32 tlan_handle_status_check(struct net_device *, u16);
175static u32 tlan_handle_rx_eoc(struct net_device *, u16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176
Sakari Ailusc659c382011-01-21 10:59:30 +0000177static void tlan_timer(unsigned long);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178
Sakari Ailusc659c382011-01-21 10:59:30 +0000179static void tlan_reset_lists(struct net_device *);
180static void tlan_free_lists(struct net_device *);
181static void tlan_print_dio(u16);
182static void tlan_print_list(struct tlan_list *, char *, int);
183static void tlan_read_and_clear_stats(struct net_device *, int);
184static void tlan_reset_adapter(struct net_device *);
185static void tlan_finish_reset(struct net_device *);
186static void tlan_set_mac(struct net_device *, int areg, char *mac);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187
Sakari Ailusc659c382011-01-21 10:59:30 +0000188static void tlan_phy_print(struct net_device *);
189static void tlan_phy_detect(struct net_device *);
190static void tlan_phy_power_down(struct net_device *);
191static void tlan_phy_power_up(struct net_device *);
192static void tlan_phy_reset(struct net_device *);
193static void tlan_phy_start_link(struct net_device *);
194static void tlan_phy_finish_auto_neg(struct net_device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195#ifdef MONITOR
Sakari Ailusc659c382011-01-21 10:59:30 +0000196static void tlan_phy_monitor(struct net_device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197#endif
198
199/*
Sakari Ailusc659c382011-01-21 10:59:30 +0000200 static int tlan_phy_nop(struct net_device *);
201 static int tlan_phy_internal_check(struct net_device *);
202 static int tlan_phy_internal_service(struct net_device *);
203 static int tlan_phy_dp83840a_check(struct net_device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204*/
205
Sakari Ailusc659c382011-01-21 10:59:30 +0000206static bool tlan_mii_read_reg(struct net_device *, u16, u16, u16 *);
207static void tlan_mii_send_data(u16, u32, unsigned);
208static void tlan_mii_sync(u16);
209static void tlan_mii_write_reg(struct net_device *, u16, u16, u16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210
Sakari Ailusc659c382011-01-21 10:59:30 +0000211static void tlan_ee_send_start(u16);
212static int tlan_ee_send_byte(u16, u8, int);
213static void tlan_ee_receive_byte(u16, u8 *, int);
214static int tlan_ee_read_byte(struct net_device *, u8, u8 *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
216
Stephen Hemminger93e16842008-05-30 09:49:55 -0700217static inline void
Sakari Ailusc659c382011-01-21 10:59:30 +0000218tlan_store_skb(struct tlan_list *tag, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219{
220 unsigned long addr = (unsigned long)skb;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700221 tag->buffer[9].address = addr;
222 tag->buffer[8].address = upper_32_bits(addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223}
224
Stephen Hemminger93e16842008-05-30 09:49:55 -0700225static inline struct sk_buff *
Sakari Ailusc659c382011-01-21 10:59:30 +0000226tlan_get_skb(const struct tlan_list *tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227{
Stephen Hemminger93e16842008-05-30 09:49:55 -0700228 unsigned long addr;
229
Robert Fitzsimons0d63bea2008-08-09 17:54:02 +0100230 addr = tag->buffer[9].address;
231 addr |= (tag->buffer[8].address << 16) << 16;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 return (struct sk_buff *) addr;
233}
234
Sakari Ailusc659c382011-01-21 10:59:30 +0000235static u32
236(*tlan_int_vector[TLAN_INT_NUMBER_OF_INTS])(struct net_device *, u16) = {
Stephen Hemmingera3ccc782008-05-30 09:49:57 -0700237 NULL,
Sakari Ailusc659c382011-01-21 10:59:30 +0000238 tlan_handle_tx_eof,
239 tlan_handle_stat_overflow,
240 tlan_handle_rx_eof,
241 tlan_handle_dummy,
242 tlan_handle_tx_eoc,
243 tlan_handle_status_check,
244 tlan_handle_rx_eoc
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245};
246
247static inline void
Sakari Ailusc659c382011-01-21 10:59:30 +0000248tlan_set_timer(struct net_device *dev, u32 ticks, u32 type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249{
Sakari Ailusc659c382011-01-21 10:59:30 +0000250 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 unsigned long flags = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400252
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 if (!in_irq())
254 spin_lock_irqsave(&priv->lock, flags);
Sakari Ailusc659c382011-01-21 10:59:30 +0000255 if (priv->timer.function != NULL &&
256 priv->timer_type != TLAN_TIMER_ACTIVITY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 if (!in_irq())
258 spin_unlock_irqrestore(&priv->lock, flags);
259 return;
260 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000261 priv->timer.function = tlan_timer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 if (!in_irq())
263 spin_unlock_irqrestore(&priv->lock, flags);
264
265 priv->timer.data = (unsigned long) dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000266 priv->timer_set_at = jiffies;
267 priv->timer_type = type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 mod_timer(&priv->timer, jiffies + ticks);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400269
Sakari Ailusc659c382011-01-21 10:59:30 +0000270}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271
272
273/*****************************************************************************
274******************************************************************************
275
Sakari Ailusc659c382011-01-21 10:59:30 +0000276ThunderLAN driver primary functions
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
Sakari Ailusc659c382011-01-21 10:59:30 +0000278these functions are more or less common to all linux network drivers.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279
280******************************************************************************
281*****************************************************************************/
282
283
284
285
286
Sakari Ailusc659c382011-01-21 10:59:30 +0000287/***************************************************************
288 * tlan_remove_one
289 *
290 * Returns:
291 * Nothing
292 * Parms:
293 * None
294 *
295 * Goes through the TLanDevices list and frees the device
296 * structs and memory associated with each device (lists
297 * and buffers). It also ureserves the IO port regions
298 * associated with this device.
299 *
300 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301
302
Sakari Ailusc659c382011-01-21 10:59:30 +0000303static void __devexit tlan_remove_one(struct pci_dev *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304{
Sakari Ailusc659c382011-01-21 10:59:30 +0000305 struct net_device *dev = pci_get_drvdata(pdev);
306 struct tlan_priv *priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400307
Sakari Ailusc659c382011-01-21 10:59:30 +0000308 unregister_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309
Sakari Ailusc659c382011-01-21 10:59:30 +0000310 if (priv->dma_storage) {
311 pci_free_consistent(priv->pci_dev,
312 priv->dma_size, priv->dma_storage,
313 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 }
315
316#ifdef CONFIG_PCI
317 pci_release_regions(pdev);
318#endif
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400319
Sakari Ailusc659c382011-01-21 10:59:30 +0000320 free_netdev(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400321
Sakari Ailusc659c382011-01-21 10:59:30 +0000322 pci_set_drvdata(pdev, NULL);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400323}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000325static void tlan_start(struct net_device *dev)
326{
327 tlan_reset_lists(dev);
328 /* NOTE: It might not be necessary to read the stats before a
329 reset if you don't care what the values are.
330 */
331 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
332 tlan_reset_adapter(dev);
333 netif_wake_queue(dev);
334}
335
336static void tlan_stop(struct net_device *dev)
337{
338 struct tlan_priv *priv = netdev_priv(dev);
339
340 tlan_read_and_clear_stats(dev, TLAN_RECORD);
341 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
342 /* Reset and power down phy */
343 tlan_reset_adapter(dev);
344 if (priv->timer.function != NULL) {
345 del_timer_sync(&priv->timer);
346 priv->timer.function = NULL;
347 }
348}
349
350#ifdef CONFIG_PM
351
352static int tlan_suspend(struct pci_dev *pdev, pm_message_t state)
353{
354 struct net_device *dev = pci_get_drvdata(pdev);
355
356 if (netif_running(dev))
357 tlan_stop(dev);
358
359 netif_device_detach(dev);
360 pci_save_state(pdev);
361 pci_disable_device(pdev);
362 pci_wake_from_d3(pdev, false);
363 pci_set_power_state(pdev, PCI_D3hot);
364
365 return 0;
366}
367
368static int tlan_resume(struct pci_dev *pdev)
369{
370 struct net_device *dev = pci_get_drvdata(pdev);
371
372 pci_set_power_state(pdev, PCI_D0);
373 pci_restore_state(pdev);
374 pci_enable_wake(pdev, 0, 0);
375 netif_device_attach(dev);
376
377 if (netif_running(dev))
378 tlan_start(dev);
379
380 return 0;
381}
382
383#else /* CONFIG_PM */
384
385#define tlan_suspend NULL
386#define tlan_resume NULL
387
388#endif /* CONFIG_PM */
389
390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391static struct pci_driver tlan_driver = {
392 .name = "tlan",
393 .id_table = tlan_pci_tbl,
394 .probe = tlan_init_one,
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400395 .remove = __devexit_p(tlan_remove_one),
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000396 .suspend = tlan_suspend,
397 .resume = tlan_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398};
399
400static int __init tlan_probe(void)
401{
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800402 int rc = -ENODEV;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400403
Joe Perches50624aa2011-03-01 06:56:33 +0000404 pr_info("%s", tlan_banner);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400405
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 /* Use new style PCI probing. Now the kernel will
409 do most of this for us */
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800410 rc = pci_register_driver(&tlan_driver);
411
412 if (rc != 0) {
Joe Perches50624aa2011-03-01 06:56:33 +0000413 pr_err("Could not register pci driver\n");
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800414 goto err_out_pci_free;
415 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
417 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000418 tlan_eisa_probe();
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400419
Joe Perches50624aa2011-03-01 06:56:33 +0000420 pr_info("%d device%s installed, PCI: %d EISA: %d\n",
421 tlan_devices_installed, tlan_devices_installed == 1 ? "" : "s",
422 tlan_have_pci, tlan_have_eisa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
Sakari Ailusc659c382011-01-21 10:59:30 +0000424 if (tlan_devices_installed == 0) {
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800425 rc = -ENODEV;
426 goto err_out_pci_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 }
428 return 0;
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800429
430err_out_pci_unreg:
431 pci_unregister_driver(&tlan_driver);
432err_out_pci_free:
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800433 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400435
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436
Sakari Ailusc659c382011-01-21 10:59:30 +0000437static int __devinit tlan_init_one(struct pci_dev *pdev,
438 const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439{
Sakari Ailusc659c382011-01-21 10:59:30 +0000440 return tlan_probe1(pdev, -1, -1, 0, ent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441}
442
443
444/*
Sakari Ailusc659c382011-01-21 10:59:30 +0000445***************************************************************
446* tlan_probe1
447*
448* Returns:
449* 0 on success, error code on error
450* Parms:
451* none
452*
453* The name is lower case to fit in with all the rest of
454* the netcard_probe names. This function looks for
455* another TLan based adapter, setting it up with the
456* allocated device struct if one is found.
457* tlan_probe has been ported to the new net API and
458* now allocates its own device structure. This function
459* is also used by modules.
460*
461**************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462
Sakari Ailusc659c382011-01-21 10:59:30 +0000463static int __devinit tlan_probe1(struct pci_dev *pdev,
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700464 long ioaddr, int irq, int rev,
Sakari Ailusc659c382011-01-21 10:59:30 +0000465 const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466{
467
468 struct net_device *dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000469 struct tlan_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 u16 device_id;
471 int reg, rc = -ENODEV;
472
Adrian Bunkad9f6712006-02-05 00:37:47 +0100473#ifdef CONFIG_PCI
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 if (pdev) {
475 rc = pci_enable_device(pdev);
476 if (rc)
477 return rc;
478
Sakari Ailusc659c382011-01-21 10:59:30 +0000479 rc = pci_request_regions(pdev, tlan_signature);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000481 pr_err("Could not reserve IO regions\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 goto err_out;
483 }
484 }
Adrian Bunkad9f6712006-02-05 00:37:47 +0100485#endif /* CONFIG_PCI */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
Sakari Ailusc659c382011-01-21 10:59:30 +0000487 dev = alloc_etherdev(sizeof(struct tlan_priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 if (dev == NULL) {
Joe Perches50624aa2011-03-01 06:56:33 +0000489 pr_err("Could not allocate memory for device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 rc = -ENOMEM;
491 goto err_out_regions;
492 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 SET_NETDEV_DEV(dev, &pdev->dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400494
Linus Torvalds1da177e2005-04-16 15:20:36 -0700495 priv = netdev_priv(dev);
496
Sakari Ailusc659c382011-01-21 10:59:30 +0000497 priv->pci_dev = pdev;
David Howellsc4028952006-11-22 14:57:56 +0000498 priv->dev = dev;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400499
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 /* Is this a PCI device? */
501 if (pdev) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000502 u32 pci_io_base = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503
504 priv->adapter = &board_info[ent->driver_data];
505
Yang Hongyang284901a2009-04-06 19:01:15 -0700506 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000508 pr_err("No suitable PCI mapping available\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 goto err_out_free_dev;
510 }
511
Sakari Ailusc659c382011-01-21 10:59:30 +0000512 for (reg = 0; reg <= 5; reg++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513 if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
514 pci_io_base = pci_resource_start(pdev, reg);
Sakari Ailusc659c382011-01-21 10:59:30 +0000515 TLAN_DBG(TLAN_DEBUG_GNRL,
516 "IO mapping is available at %x.\n",
517 pci_io_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 break;
519 }
520 }
521 if (!pci_io_base) {
Joe Perches50624aa2011-03-01 06:56:33 +0000522 pr_err("No IO mappings available\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 rc = -EIO;
524 goto err_out_free_dev;
525 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400526
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 dev->base_addr = pci_io_base;
528 dev->irq = pdev->irq;
Sakari Ailusc659c382011-01-21 10:59:30 +0000529 priv->adapter_rev = pdev->revision;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 pci_set_master(pdev);
531 pci_set_drvdata(pdev, dev);
532
533 } else { /* EISA card */
534 /* This is a hack. We need to know which board structure
535 * is suited for this adapter */
536 device_id = inw(ioaddr + EISA_ID2);
537 priv->is_eisa = 1;
538 if (device_id == 0x20F1) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000539 priv->adapter = &board_info[13]; /* NetFlex-3/E */
540 priv->adapter_rev = 23; /* TLAN 2.3 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 } else {
542 priv->adapter = &board_info[14];
Sakari Ailusc659c382011-01-21 10:59:30 +0000543 priv->adapter_rev = 10; /* TLAN 1.0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 }
545 dev->base_addr = ioaddr;
546 dev->irq = irq;
547 }
548
549 /* Kernel parameters */
550 if (dev->mem_start) {
551 priv->aui = dev->mem_start & 0x01;
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700552 priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0
553 : (dev->mem_start & 0x06) >> 1;
554 priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0
555 : (dev->mem_start & 0x18) >> 3;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400556
Sakari Ailusc659c382011-01-21 10:59:30 +0000557 if (priv->speed == 0x1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 priv->speed = TLAN_SPEED_10;
Sakari Ailusc659c382011-01-21 10:59:30 +0000559 else if (priv->speed == 0x2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 priv->speed = TLAN_SPEED_100;
Sakari Ailusc659c382011-01-21 10:59:30 +0000561
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 debug = priv->debug = dev->mem_end;
563 } else {
564 priv->aui = aui[boards_found];
565 priv->speed = speed[boards_found];
566 priv->duplex = duplex[boards_found];
567 priv->debug = debug;
568 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400569
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 /* This will be used when we get an adapter error from
571 * within our irq handler */
Sakari Ailusc659c382011-01-21 10:59:30 +0000572 INIT_WORK(&priv->tlan_tqueue, tlan_tx_timeout_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573
574 spin_lock_init(&priv->lock);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400575
Sakari Ailusc659c382011-01-21 10:59:30 +0000576 rc = tlan_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000578 pr_err("Could not set up device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 goto err_out_free_dev;
580 }
581
582 rc = register_netdev(dev);
583 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000584 pr_err("Could not register device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 goto err_out_uninit;
586 }
587
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400588
Sakari Ailusc659c382011-01-21 10:59:30 +0000589 tlan_devices_installed++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 boards_found++;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400591
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 /* pdev is NULL if this is an EISA device */
593 if (pdev)
594 tlan_have_pci++;
595 else {
Sakari Ailusc659c382011-01-21 10:59:30 +0000596 priv->next_device = tlan_eisa_devices;
597 tlan_eisa_devices = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 tlan_have_eisa++;
599 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400600
Joe Perches50624aa2011-03-01 06:56:33 +0000601 netdev_info(dev, "irq=%2d, io=%04x, %s, Rev. %d\n",
602 (int)dev->irq,
603 (int)dev->base_addr,
604 priv->adapter->device_label,
605 priv->adapter_rev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 return 0;
607
608err_out_uninit:
Sakari Ailusc659c382011-01-21 10:59:30 +0000609 pci_free_consistent(priv->pci_dev, priv->dma_size, priv->dma_storage,
610 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611err_out_free_dev:
612 free_netdev(dev);
613err_out_regions:
614#ifdef CONFIG_PCI
615 if (pdev)
616 pci_release_regions(pdev);
617#endif
618err_out:
619 if (pdev)
620 pci_disable_device(pdev);
621 return rc;
622}
623
624
Sakari Ailusc659c382011-01-21 10:59:30 +0000625static void tlan_eisa_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626{
627 struct net_device *dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000628 struct tlan_priv *priv;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400629
Sakari Ailusc659c382011-01-21 10:59:30 +0000630 while (tlan_have_eisa) {
631 dev = tlan_eisa_devices;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 priv = netdev_priv(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +0000633 if (priv->dma_storage) {
634 pci_free_consistent(priv->pci_dev, priv->dma_size,
635 priv->dma_storage,
636 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000638 release_region(dev->base_addr, 0x10);
639 unregister_netdev(dev);
640 tlan_eisa_devices = priv->next_device;
641 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 tlan_have_eisa--;
643 }
644}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400645
646
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647static void __exit tlan_exit(void)
648{
649 pci_unregister_driver(&tlan_driver);
650
651 if (tlan_have_eisa)
Sakari Ailusc659c382011-01-21 10:59:30 +0000652 tlan_eisa_cleanup();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654}
655
656
657/* Module loading/unloading */
658module_init(tlan_probe);
659module_exit(tlan_exit);
660
661
662
Sakari Ailusc659c382011-01-21 10:59:30 +0000663/**************************************************************
664 * tlan_eisa_probe
665 *
666 * Returns: 0 on success, 1 otherwise
667 *
668 * Parms: None
669 *
670 *
671 * This functions probes for EISA devices and calls
672 * TLan_probe1 when one is found.
673 *
674 *************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675
Sakari Ailusc659c382011-01-21 10:59:30 +0000676static void __init tlan_eisa_probe(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677{
Sakari Ailusc659c382011-01-21 10:59:30 +0000678 long ioaddr;
679 int rc = -ENODEV;
680 int irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 u16 device_id;
682
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400683 if (!EISA_bus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
685 return;
686 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400687
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 /* Loop through all slots of the EISA bus */
689 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400690
Sakari Ailusc659c382011-01-21 10:59:30 +0000691 TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
692 (int) ioaddr + 0xc80, inw(ioaddr + EISA_ID));
693 TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
694 (int) ioaddr + 0xc82, inw(ioaddr + EISA_ID2));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695
696
Sakari Ailusc659c382011-01-21 10:59:30 +0000697 TLAN_DBG(TLAN_DEBUG_PROBE,
698 "Probing for EISA adapter at IO: 0x%4x : ",
699 (int) ioaddr);
700 if (request_region(ioaddr, 0x10, tlan_signature) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 goto out;
702
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400703 if (inw(ioaddr + EISA_ID) != 0x110E) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704 release_region(ioaddr, 0x10);
705 goto out;
706 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400707
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 device_id = inw(ioaddr + EISA_ID2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400709 if (device_id != 0x20F1 && device_id != 0x40F1) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000710 release_region(ioaddr, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 goto out;
712 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400713
Sakari Ailusc659c382011-01-21 10:59:30 +0000714 /* check if adapter is enabled */
715 if (inb(ioaddr + EISA_CR) != 0x1) {
716 release_region(ioaddr, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 goto out2;
718 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400719
720 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000721 pr_info("Found one\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
723
724 /* Get irq from board */
Sakari Ailusc659c382011-01-21 10:59:30 +0000725 switch (inb(ioaddr + 0xcc0)) {
726 case(0x10):
727 irq = 5;
728 break;
729 case(0x20):
730 irq = 9;
731 break;
732 case(0x40):
733 irq = 10;
734 break;
735 case(0x80):
736 irq = 11;
737 break;
738 default:
739 goto out;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400740 }
741
742
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 /* Setup the newly found eisa adapter */
Sakari Ailusc659c382011-01-21 10:59:30 +0000744 rc = tlan_probe1(NULL, ioaddr, irq,
745 12, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400747
Sakari Ailusc659c382011-01-21 10:59:30 +0000748out:
749 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000750 pr_info("None found\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000751 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752
Sakari Ailusc659c382011-01-21 10:59:30 +0000753out2:
754 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000755 pr_info("Card found but it is not enabled, skipping\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000756 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400757
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 }
759
Sakari Ailusc659c382011-01-21 10:59:30 +0000760}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761
762#ifdef CONFIG_NET_POLL_CONTROLLER
Sakari Ailusc659c382011-01-21 10:59:30 +0000763static void tlan_poll(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764{
765 disable_irq(dev->irq);
Sakari Ailusc659c382011-01-21 10:59:30 +0000766 tlan_handle_interrupt(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 enable_irq(dev->irq);
768}
769#endif
770
Sakari Ailusc659c382011-01-21 10:59:30 +0000771static const struct net_device_ops tlan_netdev_ops = {
772 .ndo_open = tlan_open,
773 .ndo_stop = tlan_close,
774 .ndo_start_xmit = tlan_start_tx,
775 .ndo_tx_timeout = tlan_tx_timeout,
776 .ndo_get_stats = tlan_get_stats,
Jiri Pirkoafc4b132011-08-16 06:29:01 +0000777 .ndo_set_rx_mode = tlan_set_multicast_list,
Sakari Ailusc659c382011-01-21 10:59:30 +0000778 .ndo_do_ioctl = tlan_ioctl,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800779 .ndo_change_mtu = eth_change_mtu,
Sakari Ailusc659c382011-01-21 10:59:30 +0000780 .ndo_set_mac_address = eth_mac_addr,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800781 .ndo_validate_addr = eth_validate_addr,
782#ifdef CONFIG_NET_POLL_CONTROLLER
Sakari Ailusc659c382011-01-21 10:59:30 +0000783 .ndo_poll_controller = tlan_poll,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800784#endif
785};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400786
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787
788
Sakari Ailusc659c382011-01-21 10:59:30 +0000789/***************************************************************
790 * tlan_init
791 *
792 * Returns:
793 * 0 on success, error code otherwise.
794 * Parms:
795 * dev The structure of the device to be
796 * init'ed.
797 *
798 * This function completes the initialization of the
799 * device structure and driver. It reserves the IO
800 * addresses, allocates memory for the lists and bounce
801 * buffers, retrieves the MAC address from the eeprom
802 * and assignes the device's methods.
803 *
804 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805
Sakari Ailusc659c382011-01-21 10:59:30 +0000806static int tlan_init(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807{
808 int dma_size;
Sakari Ailusc659c382011-01-21 10:59:30 +0000809 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +0000811 struct tlan_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
813 priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400814
Sakari Ailusc659c382011-01-21 10:59:30 +0000815 dma_size = (TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS)
816 * (sizeof(struct tlan_list));
817 priv->dma_storage = pci_alloc_consistent(priv->pci_dev,
818 dma_size,
819 &priv->dma_storage_dma);
820 priv->dma_size = dma_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400821
Sakari Ailusc659c382011-01-21 10:59:30 +0000822 if (priv->dma_storage == NULL) {
Joe Perches50624aa2011-03-01 06:56:33 +0000823 pr_err("Could not allocate lists and buffers for %s\n",
Sakari Ailusc659c382011-01-21 10:59:30 +0000824 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 return -ENOMEM;
826 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000827 memset(priv->dma_storage, 0, dma_size);
828 priv->rx_list = (struct tlan_list *)
829 ALIGN((unsigned long)priv->dma_storage, 8);
830 priv->rx_list_dma = ALIGN(priv->dma_storage_dma, 8);
831 priv->tx_list = priv->rx_list + TLAN_NUM_RX_LISTS;
832 priv->tx_list_dma =
833 priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700834
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835 err = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +0000836 for (i = 0; i < 6 ; i++)
837 err |= tlan_ee_read_byte(dev,
838 (u8) priv->adapter->addr_ofs + i,
839 (u8 *) &dev->dev_addr[i]);
840 if (err) {
Joe Perches50624aa2011-03-01 06:56:33 +0000841 pr_err("%s: Error reading MAC from eeprom: %d\n",
842 dev->name, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 }
844 dev->addr_len = 6;
845
846 netif_carrier_off(dev);
847
848 /* Device methods */
Sakari Ailusc659c382011-01-21 10:59:30 +0000849 dev->netdev_ops = &tlan_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850 dev->watchdog_timeo = TX_TIMEOUT;
851
852 return 0;
853
Sakari Ailusc659c382011-01-21 10:59:30 +0000854}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855
856
857
858
Sakari Ailusc659c382011-01-21 10:59:30 +0000859/***************************************************************
860 * tlan_open
861 *
862 * Returns:
863 * 0 on success, error code otherwise.
864 * Parms:
865 * dev Structure of device to be opened.
866 *
867 * This routine puts the driver and TLAN adapter in a
868 * state where it is ready to send and receive packets.
869 * It allocates the IRQ, resets and brings the adapter
870 * out of reset, and allows interrupts. It also delays
871 * the startup for autonegotiation or sends a Rx GO
872 * command to the adapter, as appropriate.
873 *
874 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
Sakari Ailusc659c382011-01-21 10:59:30 +0000876static int tlan_open(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877{
Sakari Ailusc659c382011-01-21 10:59:30 +0000878 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 int err;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400880
Sakari Ailusc659c382011-01-21 10:59:30 +0000881 priv->tlan_rev = tlan_dio_read8(dev->base_addr, TLAN_DEF_REVISION);
882 err = request_irq(dev->irq, tlan_handle_interrupt, IRQF_SHARED,
883 dev->name, dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400884
Sakari Ailusc659c382011-01-21 10:59:30 +0000885 if (err) {
Joe Perches50624aa2011-03-01 06:56:33 +0000886 netdev_err(dev, "Cannot open because IRQ %d is already in use\n",
887 dev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 return err;
889 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400890
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 init_timer(&priv->timer);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400892
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000893 tlan_start(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894
Sakari Ailusc659c382011-01-21 10:59:30 +0000895 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n",
896 dev->name, priv->tlan_rev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897
898 return 0;
899
Sakari Ailusc659c382011-01-21 10:59:30 +0000900}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901
902
903
Sakari Ailusc659c382011-01-21 10:59:30 +0000904/**************************************************************
905 * tlan_ioctl
906 *
907 * Returns:
908 * 0 on success, error code otherwise
909 * Params:
910 * dev structure of device to receive ioctl.
911 *
912 * rq ifreq structure to hold userspace data.
913 *
914 * cmd ioctl command.
915 *
916 *
917 *************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918
Sakari Ailusc659c382011-01-21 10:59:30 +0000919static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920{
Sakari Ailusc659c382011-01-21 10:59:30 +0000921 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 struct mii_ioctl_data *data = if_mii(rq);
Sakari Ailusc659c382011-01-21 10:59:30 +0000923 u32 phy = priv->phy[priv->phy_num];
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400924
Sakari Ailusc659c382011-01-21 10:59:30 +0000925 if (!priv->phy_online)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 return -EAGAIN;
927
Sakari Ailusc659c382011-01-21 10:59:30 +0000928 switch (cmd) {
929 case SIOCGMIIPHY: /* get address of MII PHY in use. */
930 data->phy_id = phy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
932
Sakari Ailusc659c382011-01-21 10:59:30 +0000933 case SIOCGMIIREG: /* read MII PHY register. */
934 tlan_mii_read_reg(dev, data->phy_id & 0x1f,
935 data->reg_num & 0x1f, &data->val_out);
936 return 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400937
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938
Sakari Ailusc659c382011-01-21 10:59:30 +0000939 case SIOCSMIIREG: /* write MII PHY register. */
940 tlan_mii_write_reg(dev, data->phy_id & 0x1f,
941 data->reg_num & 0x1f, data->val_in);
942 return 0;
943 default:
944 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000946}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
948
Sakari Ailusc659c382011-01-21 10:59:30 +0000949/***************************************************************
950 * tlan_tx_timeout
951 *
952 * Returns: nothing
953 *
954 * Params:
955 * dev structure of device which timed out
956 * during transmit.
957 *
958 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
Sakari Ailusc659c382011-01-21 10:59:30 +0000960static void tlan_tx_timeout(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961{
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400962
Sakari Ailusc659c382011-01-21 10:59:30 +0000963 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400964
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 /* Ok so we timed out, lets see what we can do about it...*/
Sakari Ailusc659c382011-01-21 10:59:30 +0000966 tlan_free_lists(dev);
967 tlan_reset_lists(dev);
968 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
969 tlan_reset_adapter(dev);
Eric Dumazet1ae5dc32010-05-10 05:01:31 -0700970 dev->trans_start = jiffies; /* prevent tx timeout */
Sakari Ailusc659c382011-01-21 10:59:30 +0000971 netif_wake_queue(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
973}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400974
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975
Sakari Ailusc659c382011-01-21 10:59:30 +0000976/***************************************************************
977 * tlan_tx_timeout_work
978 *
979 * Returns: nothing
980 *
981 * Params:
982 * work work item of device which timed out
983 *
984 **************************************************************/
David Howellsc4028952006-11-22 14:57:56 +0000985
Sakari Ailusc659c382011-01-21 10:59:30 +0000986static void tlan_tx_timeout_work(struct work_struct *work)
David Howellsc4028952006-11-22 14:57:56 +0000987{
Sakari Ailusc659c382011-01-21 10:59:30 +0000988 struct tlan_priv *priv =
989 container_of(work, struct tlan_priv, tlan_tqueue);
David Howellsc4028952006-11-22 14:57:56 +0000990
Sakari Ailusc659c382011-01-21 10:59:30 +0000991 tlan_tx_timeout(priv->dev);
David Howellsc4028952006-11-22 14:57:56 +0000992}
993
994
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995
Sakari Ailusc659c382011-01-21 10:59:30 +0000996/***************************************************************
997 * tlan_start_tx
998 *
999 * Returns:
1000 * 0 on success, non-zero on failure.
1001 * Parms:
1002 * skb A pointer to the sk_buff containing the
1003 * frame to be sent.
1004 * dev The device to send the data on.
1005 *
1006 * This function adds a frame to the Tx list to be sent
1007 * ASAP. First it verifies that the adapter is ready and
1008 * there is room in the queue. Then it sets up the next
1009 * available list, copies the frame to the corresponding
1010 * buffer. If the adapter Tx channel is idle, it gives
1011 * the adapter a Tx Go command on the list, otherwise it
1012 * sets the forward address of the previous list to point
1013 * to this one. Then it frees the sk_buff.
1014 *
1015 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016
Sakari Ailusc659c382011-01-21 10:59:30 +00001017static netdev_tx_t tlan_start_tx(struct sk_buff *skb, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018{
Sakari Ailusc659c382011-01-21 10:59:30 +00001019 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 dma_addr_t tail_list_phys;
Sakari Ailusc659c382011-01-21 10:59:30 +00001021 struct tlan_list *tail_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 unsigned long flags;
Sakari Ailus8953f122008-12-16 01:44:05 -08001023 unsigned int txlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024
Sakari Ailusc659c382011-01-21 10:59:30 +00001025 if (!priv->phy_online) {
1026 TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n",
1027 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 dev_kfree_skb_any(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001029 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 }
1031
Stephen Hemminger41873e92008-05-30 09:49:52 -07001032 if (skb_padto(skb, TLAN_MIN_FRAME_SIZE))
Patrick McHardy6ed10652009-06-23 06:03:08 +00001033 return NETDEV_TX_OK;
Sakari Ailus8953f122008-12-16 01:44:05 -08001034 txlen = max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE);
Stephen Hemminger41873e92008-05-30 09:49:52 -07001035
Sakari Ailusc659c382011-01-21 10:59:30 +00001036 tail_list = priv->tx_list + priv->tx_tail;
1037 tail_list_phys =
1038 priv->tx_list_dma + sizeof(struct tlan_list)*priv->tx_tail;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001039
Sakari Ailusc659c382011-01-21 10:59:30 +00001040 if (tail_list->c_stat != TLAN_CSTAT_UNUSED) {
1041 TLAN_DBG(TLAN_DEBUG_TX,
1042 "TRANSMIT: %s is busy (Head=%d Tail=%d)\n",
1043 dev->name, priv->tx_head, priv->tx_tail);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 netif_stop_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001045 priv->tx_busy_count++;
Patrick McHardy5b548142009-06-12 06:22:29 +00001046 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 }
1048
1049 tail_list->forward = 0;
1050
Sakari Ailusc659c382011-01-21 10:59:30 +00001051 tail_list->buffer[0].address = pci_map_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001052 skb->data, txlen,
1053 PCI_DMA_TODEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001054 tlan_store_skb(tail_list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055
Sakari Ailusc659c382011-01-21 10:59:30 +00001056 tail_list->frame_size = (u16) txlen;
Sakari Ailus8953f122008-12-16 01:44:05 -08001057 tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) txlen;
Stephen Hemminger41873e92008-05-30 09:49:52 -07001058 tail_list->buffer[1].count = 0;
1059 tail_list->buffer[1].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
1061 spin_lock_irqsave(&priv->lock, flags);
Sakari Ailusc659c382011-01-21 10:59:30 +00001062 tail_list->c_stat = TLAN_CSTAT_READY;
1063 if (!priv->tx_in_progress) {
1064 priv->tx_in_progress = 1;
1065 TLAN_DBG(TLAN_DEBUG_TX,
1066 "TRANSMIT: Starting TX on buffer %d\n",
1067 priv->tx_tail);
1068 outl(tail_list_phys, dev->base_addr + TLAN_CH_PARM);
1069 outl(TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001071 TLAN_DBG(TLAN_DEBUG_TX,
1072 "TRANSMIT: Adding buffer %d to TX channel\n",
1073 priv->tx_tail);
1074 if (priv->tx_tail == 0) {
1075 (priv->tx_list + (TLAN_NUM_TX_LISTS - 1))->forward
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001076 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001078 (priv->tx_list + (priv->tx_tail - 1))->forward
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001079 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 }
1081 }
1082 spin_unlock_irqrestore(&priv->lock, flags);
1083
Sakari Ailusc659c382011-01-21 10:59:30 +00001084 CIRC_INC(priv->tx_tail, TLAN_NUM_TX_LISTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
Patrick McHardy6ed10652009-06-23 06:03:08 +00001086 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
Sakari Ailusc659c382011-01-21 10:59:30 +00001088}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
1090
1091
1092
Sakari Ailusc659c382011-01-21 10:59:30 +00001093/***************************************************************
1094 * tlan_handle_interrupt
1095 *
1096 * Returns:
1097 * Nothing
1098 * Parms:
1099 * irq The line on which the interrupt
1100 * occurred.
1101 * dev_id A pointer to the device assigned to
1102 * this irq line.
1103 *
1104 * This function handles an interrupt generated by its
1105 * assigned TLAN adapter. The function deactivates
1106 * interrupts on its adapter, records the type of
1107 * interrupt, executes the appropriate subhandler, and
1108 * acknowdges the interrupt to the adapter (thus
1109 * re-enabling adapter interrupts.
1110 *
1111 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Sakari Ailusc659c382011-01-21 10:59:30 +00001113static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114{
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001115 struct net_device *dev = dev_id;
Sakari Ailusc659c382011-01-21 10:59:30 +00001116 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 u16 host_int;
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001118 u16 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
1120 spin_lock(&priv->lock);
1121
Sakari Ailusc659c382011-01-21 10:59:30 +00001122 host_int = inw(dev->base_addr + TLAN_HOST_INT);
1123 type = (host_int & TLAN_HI_IT_MASK) >> 2;
1124 if (type) {
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001125 u32 ack;
1126 u32 host_cmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127
Sakari Ailusc659c382011-01-21 10:59:30 +00001128 outw(host_int, dev->base_addr + TLAN_HOST_INT);
1129 ack = tlan_int_vector[type](dev, host_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130
Sakari Ailusc659c382011-01-21 10:59:30 +00001131 if (ack) {
1132 host_cmd = TLAN_HC_ACK | ack | (type << 18);
1133 outl(host_cmd, dev->base_addr + TLAN_HOST_CMD);
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001134 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 }
1136
1137 spin_unlock(&priv->lock);
1138
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001139 return IRQ_RETVAL(type);
Sakari Ailusc659c382011-01-21 10:59:30 +00001140}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141
1142
1143
1144
Sakari Ailusc659c382011-01-21 10:59:30 +00001145/***************************************************************
1146 * tlan_close
1147 *
1148 * Returns:
1149 * An error code.
1150 * Parms:
1151 * dev The device structure of the device to
1152 * close.
1153 *
1154 * This function shuts down the adapter. It records any
1155 * stats, puts the adapter into reset state, deactivates
1156 * its time as needed, and frees the irq it is using.
1157 *
1158 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159
Sakari Ailusc659c382011-01-21 10:59:30 +00001160static int tlan_close(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161{
Sakari Ailusc659c382011-01-21 10:59:30 +00001162 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 priv->neg_be_verbose = 0;
Sakari Ailusfa6d5d42011-01-21 10:59:31 +00001165 tlan_stop(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001166
Sakari Ailusc659c382011-01-21 10:59:30 +00001167 free_irq(dev->irq, dev);
1168 tlan_free_lists(dev);
1169 TLAN_DBG(TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170
1171 return 0;
1172
Sakari Ailusc659c382011-01-21 10:59:30 +00001173}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174
1175
1176
1177
Sakari Ailusc659c382011-01-21 10:59:30 +00001178/***************************************************************
1179 * tlan_get_stats
1180 *
1181 * Returns:
1182 * A pointer to the device's statistics structure.
1183 * Parms:
1184 * dev The device structure to return the
1185 * stats for.
1186 *
1187 * This function updates the devices statistics by reading
1188 * the TLAN chip's onboard registers. Then it returns the
1189 * address of the statistics structure.
1190 *
1191 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192
Sakari Ailusc659c382011-01-21 10:59:30 +00001193static struct net_device_stats *tlan_get_stats(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194{
Sakari Ailusc659c382011-01-21 10:59:30 +00001195 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 int i;
1197
1198 /* Should only read stats if open ? */
Sakari Ailusc659c382011-01-21 10:59:30 +00001199 tlan_read_and_clear_stats(dev, TLAN_RECORD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
Sakari Ailusc659c382011-01-21 10:59:30 +00001201 TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name,
1202 priv->rx_eoc_count);
1203 TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name,
1204 priv->tx_busy_count);
1205 if (debug & TLAN_DEBUG_GNRL) {
1206 tlan_print_dio(dev->base_addr);
1207 tlan_phy_print(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001209 if (debug & TLAN_DEBUG_LIST) {
1210 for (i = 0; i < TLAN_NUM_RX_LISTS; i++)
1211 tlan_print_list(priv->rx_list + i, "RX", i);
1212 for (i = 0; i < TLAN_NUM_TX_LISTS; i++)
1213 tlan_print_list(priv->tx_list + i, "TX", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001215
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001216 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217
Sakari Ailusc659c382011-01-21 10:59:30 +00001218}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
1220
1221
1222
Sakari Ailusc659c382011-01-21 10:59:30 +00001223/***************************************************************
1224 * tlan_set_multicast_list
1225 *
1226 * Returns:
1227 * Nothing
1228 * Parms:
1229 * dev The device structure to set the
1230 * multicast list for.
1231 *
1232 * This function sets the TLAN adaptor to various receive
1233 * modes. If the IFF_PROMISC flag is set, promiscuous
1234 * mode is acitviated. Otherwise, promiscuous mode is
1235 * turned off. If the IFF_ALLMULTI flag is set, then
1236 * the hash table is set to receive all group addresses.
1237 * Otherwise, the first three multicast addresses are
1238 * stored in AREG_1-3, and the rest are selected via the
1239 * hash table, as necessary.
1240 *
1241 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
Sakari Ailusc659c382011-01-21 10:59:30 +00001243static void tlan_set_multicast_list(struct net_device *dev)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001244{
Jiri Pirko22bedad32010-04-01 21:22:57 +00001245 struct netdev_hw_addr *ha;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246 u32 hash1 = 0;
1247 u32 hash2 = 0;
1248 int i;
1249 u32 offset;
1250 u8 tmp;
1251
Sakari Ailusc659c382011-01-21 10:59:30 +00001252 if (dev->flags & IFF_PROMISC) {
1253 tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
1254 tlan_dio_write8(dev->base_addr,
1255 TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001257 tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
1258 tlan_dio_write8(dev->base_addr,
1259 TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF);
1260 if (dev->flags & IFF_ALLMULTI) {
1261 for (i = 0; i < 3; i++)
1262 tlan_set_mac(dev, i + 1, NULL);
1263 tlan_dio_write32(dev->base_addr, TLAN_HASH_1,
1264 0xffffffff);
1265 tlan_dio_write32(dev->base_addr, TLAN_HASH_2,
1266 0xffffffff);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 } else {
Jiri Pirko567ec872010-02-23 23:17:07 +00001268 i = 0;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001269 netdev_for_each_mc_addr(ha, dev) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001270 if (i < 3) {
1271 tlan_set_mac(dev, i + 1,
Jiri Pirko22bedad32010-04-01 21:22:57 +00001272 (char *) &ha->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001274 offset =
1275 tlan_hash_func((u8 *)&ha->addr);
1276 if (offset < 32)
1277 hash1 |= (1 << offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278 else
Sakari Ailusc659c382011-01-21 10:59:30 +00001279 hash2 |= (1 << (offset - 32));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 }
Jiri Pirko567ec872010-02-23 23:17:07 +00001281 i++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001283 for ( ; i < 3; i++)
1284 tlan_set_mac(dev, i + 1, NULL);
1285 tlan_dio_write32(dev->base_addr, TLAN_HASH_1, hash1);
1286 tlan_dio_write32(dev->base_addr, TLAN_HASH_2, hash2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287 }
1288 }
1289
Sakari Ailusc659c382011-01-21 10:59:30 +00001290}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291
1292
1293
1294/*****************************************************************************
1295******************************************************************************
1296
Sakari Ailusc659c382011-01-21 10:59:30 +00001297ThunderLAN driver interrupt vectors and table
Linus Torvalds1da177e2005-04-16 15:20:36 -07001298
Sakari Ailusc659c382011-01-21 10:59:30 +00001299please see chap. 4, "Interrupt Handling" of the "ThunderLAN
1300Programmer's Guide" for more informations on handling interrupts
1301generated by TLAN based adapters.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302
1303******************************************************************************
1304*****************************************************************************/
1305
1306
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
1308
Sakari Ailusc659c382011-01-21 10:59:30 +00001309/***************************************************************
1310 * tlan_handle_tx_eof
1311 *
1312 * Returns:
1313 * 1
1314 * Parms:
1315 * dev Device assigned the IRQ that was
1316 * raised.
1317 * host_int The contents of the HOST_INT
1318 * port.
1319 *
1320 * This function handles Tx EOF interrupts which are raised
1321 * by the adapter when it has completed sending the
1322 * contents of a buffer. If detemines which list/buffer
1323 * was completed and resets it. If the buffer was the last
1324 * in the channel (EOC), then the function checks to see if
1325 * another buffer is ready to send, and if so, sends a Tx
1326 * Go command. Finally, the driver activates/continues the
1327 * activity LED.
1328 *
1329 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330
Sakari Ailusc659c382011-01-21 10:59:30 +00001331static u32 tlan_handle_tx_eof(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332{
Sakari Ailusc659c382011-01-21 10:59:30 +00001333 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 int eoc = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001335 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 dma_addr_t head_list_phys;
1337 u32 ack = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001338 u16 tmp_c_stat;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001339
Sakari Ailusc659c382011-01-21 10:59:30 +00001340 TLAN_DBG(TLAN_DEBUG_TX,
1341 "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n",
1342 priv->tx_head, priv->tx_tail);
1343 head_list = priv->tx_list + priv->tx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344
Sakari Ailusc659c382011-01-21 10:59:30 +00001345 while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
1346 && (ack < 255)) {
1347 struct sk_buff *skb = tlan_get_skb(head_list);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001348
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 ack++;
Sakari Ailusc659c382011-01-21 10:59:30 +00001350 pci_unmap_single(priv->pci_dev, head_list->buffer[0].address,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001351 max(skb->len,
1352 (unsigned int)TLAN_MIN_FRAME_SIZE),
1353 PCI_DMA_TODEVICE);
1354 dev_kfree_skb_any(skb);
1355 head_list->buffer[8].address = 0;
1356 head_list->buffer[9].address = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001357
Sakari Ailusc659c382011-01-21 10:59:30 +00001358 if (tmp_c_stat & TLAN_CSTAT_EOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001360
Sakari Ailusc659c382011-01-21 10:59:30 +00001361 dev->stats.tx_bytes += head_list->frame_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362
Sakari Ailusc659c382011-01-21 10:59:30 +00001363 head_list->c_stat = TLAN_CSTAT_UNUSED;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001364 netif_start_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001365 CIRC_INC(priv->tx_head, TLAN_NUM_TX_LISTS);
1366 head_list = priv->tx_list + priv->tx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367 }
1368
1369 if (!ack)
Joe Perches50624aa2011-03-01 06:56:33 +00001370 netdev_info(dev,
1371 "Received interrupt for uncompleted TX frame\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001372
Sakari Ailusc659c382011-01-21 10:59:30 +00001373 if (eoc) {
1374 TLAN_DBG(TLAN_DEBUG_TX,
1375 "TRANSMIT: handling TX EOC (Head=%d Tail=%d)\n",
1376 priv->tx_head, priv->tx_tail);
1377 head_list = priv->tx_list + priv->tx_head;
1378 head_list_phys = priv->tx_list_dma
1379 + sizeof(struct tlan_list)*priv->tx_head;
Sakari Ailusf45437e2011-02-09 10:25:06 +00001380 if ((head_list->c_stat & TLAN_CSTAT_READY)
1381 == TLAN_CSTAT_READY) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001382 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 ack |= TLAN_HC_GO;
1384 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001385 priv->tx_in_progress = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 }
1387 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001388
Sakari Ailusc659c382011-01-21 10:59:30 +00001389 if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
1390 tlan_dio_write8(dev->base_addr,
1391 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
1392 if (priv->timer.function == NULL) {
1393 priv->timer.function = tlan_timer;
1394 priv->timer.data = (unsigned long) dev;
1395 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1396 priv->timer_set_at = jiffies;
1397 priv->timer_type = TLAN_TIMER_ACTIVITY;
1398 add_timer(&priv->timer);
1399 } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
1400 priv->timer_set_at = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 }
1402 }
1403
1404 return ack;
1405
Sakari Ailusc659c382011-01-21 10:59:30 +00001406}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
1408
1409
1410
Sakari Ailusc659c382011-01-21 10:59:30 +00001411/***************************************************************
1412 * TLan_HandleStatOverflow
1413 *
1414 * Returns:
1415 * 1
1416 * Parms:
1417 * dev Device assigned the IRQ that was
1418 * raised.
1419 * host_int The contents of the HOST_INT
1420 * port.
1421 *
1422 * This function handles the Statistics Overflow interrupt
1423 * which means that one or more of the TLAN statistics
1424 * registers has reached 1/2 capacity and needs to be read.
1425 *
1426 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427
Sakari Ailusc659c382011-01-21 10:59:30 +00001428static u32 tlan_handle_stat_overflow(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429{
Sakari Ailusc659c382011-01-21 10:59:30 +00001430 tlan_read_and_clear_stats(dev, TLAN_RECORD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431
1432 return 1;
1433
Sakari Ailusc659c382011-01-21 10:59:30 +00001434}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435
1436
1437
1438
Sakari Ailusc659c382011-01-21 10:59:30 +00001439/***************************************************************
1440 * TLan_HandleRxEOF
1441 *
1442 * Returns:
1443 * 1
1444 * Parms:
1445 * dev Device assigned the IRQ that was
1446 * raised.
1447 * host_int The contents of the HOST_INT
1448 * port.
1449 *
1450 * This function handles the Rx EOF interrupt which
1451 * indicates a frame has been received by the adapter from
1452 * the net and the frame has been transferred to memory.
1453 * The function determines the bounce buffer the frame has
1454 * been loaded into, creates a new sk_buff big enough to
1455 * hold the frame, and sends it to protocol stack. It
1456 * then resets the used buffer and appends it to the end
1457 * of the list. If the frame was the last in the Rx
1458 * channel (EOC), the function restarts the receive channel
1459 * by sending an Rx Go command to the adapter. Then it
1460 * activates/continues the activity LED.
1461 *
1462 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463
Sakari Ailusc659c382011-01-21 10:59:30 +00001464static u32 tlan_handle_rx_eof(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465{
Sakari Ailusc659c382011-01-21 10:59:30 +00001466 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 u32 ack = 0;
1468 int eoc = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001469 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 struct sk_buff *skb;
Sakari Ailusc659c382011-01-21 10:59:30 +00001471 struct tlan_list *tail_list;
1472 u16 tmp_c_stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 dma_addr_t head_list_phys;
1474
Sakari Ailusc659c382011-01-21 10:59:30 +00001475 TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: handling RX EOF (Head=%d Tail=%d)\n",
1476 priv->rx_head, priv->rx_tail);
1477 head_list = priv->rx_list + priv->rx_head;
1478 head_list_phys =
1479 priv->rx_list_dma + sizeof(struct tlan_list)*priv->rx_head;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001480
Sakari Ailusc659c382011-01-21 10:59:30 +00001481 while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
1482 && (ack < 255)) {
1483 dma_addr_t frame_dma = head_list->buffer[0].address;
1484 u32 frame_size = head_list->frame_size;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001485 struct sk_buff *new_skb;
1486
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 ack++;
Sakari Ailusc659c382011-01-21 10:59:30 +00001488 if (tmp_c_stat & TLAN_CSTAT_EOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001490
Eric Dumazet89d71a62009-10-13 05:34:20 +00001491 new_skb = netdev_alloc_skb_ip_align(dev,
1492 TLAN_MAX_FRAME_SIZE + 5);
Sakari Ailusc659c382011-01-21 10:59:30 +00001493 if (!new_skb)
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001494 goto drop_and_reuse;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001495
Sakari Ailusc659c382011-01-21 10:59:30 +00001496 skb = tlan_get_skb(head_list);
1497 pci_unmap_single(priv->pci_dev, frame_dma,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001498 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001499 skb_put(skb, frame_size);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001500
Sakari Ailusc659c382011-01-21 10:59:30 +00001501 dev->stats.rx_bytes += frame_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001502
Sakari Ailusc659c382011-01-21 10:59:30 +00001503 skb->protocol = eth_type_trans(skb, dev);
1504 netif_rx(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505
Sakari Ailusc659c382011-01-21 10:59:30 +00001506 head_list->buffer[0].address =
1507 pci_map_single(priv->pci_dev, new_skb->data,
1508 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509
Sakari Ailusc659c382011-01-21 10:59:30 +00001510 tlan_store_skb(head_list, new_skb);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001511drop_and_reuse:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 head_list->forward = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001513 head_list->c_stat = 0;
1514 tail_list = priv->rx_list + priv->rx_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 tail_list->forward = head_list_phys;
1516
Sakari Ailusc659c382011-01-21 10:59:30 +00001517 CIRC_INC(priv->rx_head, TLAN_NUM_RX_LISTS);
1518 CIRC_INC(priv->rx_tail, TLAN_NUM_RX_LISTS);
1519 head_list = priv->rx_list + priv->rx_head;
1520 head_list_phys = priv->rx_list_dma
1521 + sizeof(struct tlan_list)*priv->rx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 }
1523
1524 if (!ack)
Joe Perches50624aa2011-03-01 06:56:33 +00001525 netdev_info(dev,
1526 "Received interrupt for uncompleted RX frame\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527
1528
Sakari Ailusc659c382011-01-21 10:59:30 +00001529 if (eoc) {
1530 TLAN_DBG(TLAN_DEBUG_RX,
1531 "RECEIVE: handling RX EOC (Head=%d Tail=%d)\n",
1532 priv->rx_head, priv->rx_tail);
1533 head_list = priv->rx_list + priv->rx_head;
1534 head_list_phys = priv->rx_list_dma
1535 + sizeof(struct tlan_list)*priv->rx_head;
1536 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 ack |= TLAN_HC_GO | TLAN_HC_RT;
Sakari Ailusc659c382011-01-21 10:59:30 +00001538 priv->rx_eoc_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 }
1540
Sakari Ailusc659c382011-01-21 10:59:30 +00001541 if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
1542 tlan_dio_write8(dev->base_addr,
1543 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
1544 if (priv->timer.function == NULL) {
1545 priv->timer.function = tlan_timer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 priv->timer.data = (unsigned long) dev;
1547 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
Sakari Ailusc659c382011-01-21 10:59:30 +00001548 priv->timer_set_at = jiffies;
1549 priv->timer_type = TLAN_TIMER_ACTIVITY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 add_timer(&priv->timer);
Sakari Ailusc659c382011-01-21 10:59:30 +00001551 } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
1552 priv->timer_set_at = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 }
1554 }
1555
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 return ack;
1557
Sakari Ailusc659c382011-01-21 10:59:30 +00001558}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
1560
1561
1562
Sakari Ailusc659c382011-01-21 10:59:30 +00001563/***************************************************************
1564 * tlan_handle_dummy
1565 *
1566 * Returns:
1567 * 1
1568 * Parms:
1569 * dev Device assigned the IRQ that was
1570 * raised.
1571 * host_int The contents of the HOST_INT
1572 * port.
1573 *
1574 * This function handles the Dummy interrupt, which is
1575 * raised whenever a test interrupt is generated by setting
1576 * the Req_Int bit of HOST_CMD to 1.
1577 *
1578 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579
Sakari Ailusc659c382011-01-21 10:59:30 +00001580static u32 tlan_handle_dummy(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581{
Joe Perches50624aa2011-03-01 06:56:33 +00001582 netdev_info(dev, "Test interrupt\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 return 1;
1584
Sakari Ailusc659c382011-01-21 10:59:30 +00001585}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586
1587
1588
1589
Sakari Ailusc659c382011-01-21 10:59:30 +00001590/***************************************************************
1591 * tlan_handle_tx_eoc
1592 *
1593 * Returns:
1594 * 1
1595 * Parms:
1596 * dev Device assigned the IRQ that was
1597 * raised.
1598 * host_int The contents of the HOST_INT
1599 * port.
1600 *
1601 * This driver is structured to determine EOC occurrences by
1602 * reading the CSTAT member of the list structure. Tx EOC
1603 * interrupts are disabled via the DIO INTDIS register.
1604 * However, TLAN chips before revision 3.0 didn't have this
1605 * functionality, so process EOC events if this is the
1606 * case.
1607 *
1608 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609
Sakari Ailusc659c382011-01-21 10:59:30 +00001610static u32 tlan_handle_tx_eoc(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611{
Sakari Ailusc659c382011-01-21 10:59:30 +00001612 struct tlan_priv *priv = netdev_priv(dev);
1613 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 dma_addr_t head_list_phys;
1615 u32 ack = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001616
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 host_int = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001618 if (priv->tlan_rev < 0x30) {
1619 TLAN_DBG(TLAN_DEBUG_TX,
1620 "TRANSMIT: handling TX EOC (Head=%d Tail=%d) -- IRQ\n",
1621 priv->tx_head, priv->tx_tail);
1622 head_list = priv->tx_list + priv->tx_head;
1623 head_list_phys = priv->tx_list_dma
1624 + sizeof(struct tlan_list)*priv->tx_head;
Sakari Ailusf45437e2011-02-09 10:25:06 +00001625 if ((head_list->c_stat & TLAN_CSTAT_READY)
1626 == TLAN_CSTAT_READY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 netif_stop_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001628 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 ack |= TLAN_HC_GO;
1630 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001631 priv->tx_in_progress = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 }
1633 }
1634
1635 return ack;
1636
Sakari Ailusc659c382011-01-21 10:59:30 +00001637}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638
1639
1640
1641
Sakari Ailusc659c382011-01-21 10:59:30 +00001642/***************************************************************
1643 * tlan_handle_status_check
1644 *
1645 * Returns:
1646 * 0 if Adapter check, 1 if Network Status check.
1647 * Parms:
1648 * dev Device assigned the IRQ that was
1649 * raised.
1650 * host_int The contents of the HOST_INT
1651 * port.
1652 *
1653 * This function handles Adapter Check/Network Status
1654 * interrupts generated by the adapter. It checks the
1655 * vector in the HOST_INT register to determine if it is
1656 * an Adapter Check interrupt. If so, it resets the
1657 * adapter. Otherwise it clears the status registers
1658 * and services the PHY.
1659 *
1660 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661
Sakari Ailusc659c382011-01-21 10:59:30 +00001662static u32 tlan_handle_status_check(struct net_device *dev, u16 host_int)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001663{
Sakari Ailusc659c382011-01-21 10:59:30 +00001664 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 u32 ack;
1666 u32 error;
1667 u8 net_sts;
1668 u32 phy;
1669 u16 tlphy_ctl;
1670 u16 tlphy_sts;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001671
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 ack = 1;
Sakari Ailusc659c382011-01-21 10:59:30 +00001673 if (host_int & TLAN_HI_IV_MASK) {
1674 netif_stop_queue(dev);
1675 error = inl(dev->base_addr + TLAN_CH_PARM);
Joe Perches50624aa2011-03-01 06:56:33 +00001676 netdev_info(dev, "Adaptor Error = 0x%x\n", error);
Sakari Ailusc659c382011-01-21 10:59:30 +00001677 tlan_read_and_clear_stats(dev, TLAN_RECORD);
1678 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679
1680 schedule_work(&priv->tlan_tqueue);
1681
1682 netif_wake_queue(dev);
1683 ack = 0;
1684 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001685 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name);
1686 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
Sakari Ailusc659c382011-01-21 10:59:30 +00001688 net_sts = tlan_dio_read8(dev->base_addr, TLAN_NET_STS);
1689 if (net_sts) {
1690 tlan_dio_write8(dev->base_addr, TLAN_NET_STS, net_sts);
1691 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n",
1692 dev->name, (unsigned) net_sts);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001694 if ((net_sts & TLAN_NET_STS_MIRQ) && (priv->phy_num == 0)) {
1695 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_STS, &tlphy_sts);
1696 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
1697 if (!(tlphy_sts & TLAN_TS_POLOK) &&
1698 !(tlphy_ctl & TLAN_TC_SWAPOL)) {
1699 tlphy_ctl |= TLAN_TC_SWAPOL;
1700 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
1701 tlphy_ctl);
1702 } else if ((tlphy_sts & TLAN_TS_POLOK) &&
1703 (tlphy_ctl & TLAN_TC_SWAPOL)) {
1704 tlphy_ctl &= ~TLAN_TC_SWAPOL;
1705 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
1706 tlphy_ctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001708
1709 if (debug)
1710 tlan_phy_print(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 }
1712 }
1713
1714 return ack;
1715
Sakari Ailusc659c382011-01-21 10:59:30 +00001716}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717
1718
1719
1720
Sakari Ailusc659c382011-01-21 10:59:30 +00001721/***************************************************************
1722 * tlan_handle_rx_eoc
1723 *
1724 * Returns:
1725 * 1
1726 * Parms:
1727 * dev Device assigned the IRQ that was
1728 * raised.
1729 * host_int The contents of the HOST_INT
1730 * port.
1731 *
1732 * This driver is structured to determine EOC occurrences by
1733 * reading the CSTAT member of the list structure. Rx EOC
1734 * interrupts are disabled via the DIO INTDIS register.
1735 * However, TLAN chips before revision 3.0 didn't have this
1736 * CSTAT member or a INTDIS register, so if this chip is
1737 * pre-3.0, process EOC interrupts normally.
1738 *
1739 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
Sakari Ailusc659c382011-01-21 10:59:30 +00001741static u32 tlan_handle_rx_eoc(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742{
Sakari Ailusc659c382011-01-21 10:59:30 +00001743 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 dma_addr_t head_list_phys;
1745 u32 ack = 1;
1746
Sakari Ailusc659c382011-01-21 10:59:30 +00001747 if (priv->tlan_rev < 0x30) {
1748 TLAN_DBG(TLAN_DEBUG_RX,
1749 "RECEIVE: Handling RX EOC (head=%d tail=%d) -- IRQ\n",
1750 priv->rx_head, priv->rx_tail);
1751 head_list_phys = priv->rx_list_dma
1752 + sizeof(struct tlan_list)*priv->rx_head;
1753 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 ack |= TLAN_HC_GO | TLAN_HC_RT;
Sakari Ailusc659c382011-01-21 10:59:30 +00001755 priv->rx_eoc_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 }
1757
1758 return ack;
1759
Sakari Ailusc659c382011-01-21 10:59:30 +00001760}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761
1762
1763
1764
1765/*****************************************************************************
1766******************************************************************************
1767
Sakari Ailusc659c382011-01-21 10:59:30 +00001768ThunderLAN driver timer function
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
1770******************************************************************************
1771*****************************************************************************/
1772
1773
Sakari Ailusc659c382011-01-21 10:59:30 +00001774/***************************************************************
1775 * tlan_timer
1776 *
1777 * Returns:
1778 * Nothing
1779 * Parms:
1780 * data A value given to add timer when
1781 * add_timer was called.
1782 *
1783 * This function handles timed functionality for the
1784 * TLAN driver. The two current timer uses are for
1785 * delaying for autonegotionation and driving the ACT LED.
1786 * - Autonegotiation requires being allowed about
1787 * 2 1/2 seconds before attempting to transmit a
1788 * packet. It would be a very bad thing to hang
1789 * the kernel this long, so the driver doesn't
1790 * allow transmission 'til after this time, for
1791 * certain PHYs. It would be much nicer if all
1792 * PHYs were interrupt-capable like the internal
1793 * PHY.
1794 * - The ACT LED, which shows adapter activity, is
1795 * driven by the driver, and so must be left on
1796 * for a short period to power up the LED so it
1797 * can be seen. This delay can be changed by
1798 * changing the TLAN_TIMER_ACT_DELAY in tlan.h,
1799 * if desired. 100 ms produces a slightly
1800 * sluggish response.
1801 *
1802 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803
Sakari Ailusc659c382011-01-21 10:59:30 +00001804static void tlan_timer(unsigned long data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805{
1806 struct net_device *dev = (struct net_device *) data;
Sakari Ailusc659c382011-01-21 10:59:30 +00001807 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 u32 elapsed;
1809 unsigned long flags = 0;
1810
1811 priv->timer.function = NULL;
1812
Sakari Ailusc659c382011-01-21 10:59:30 +00001813 switch (priv->timer_type) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001814#ifdef MONITOR
Sakari Ailusc659c382011-01-21 10:59:30 +00001815 case TLAN_TIMER_LINK_BEAT:
1816 tlan_phy_monitor(dev);
1817 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818#endif
Sakari Ailusc659c382011-01-21 10:59:30 +00001819 case TLAN_TIMER_PHY_PDOWN:
1820 tlan_phy_power_down(dev);
1821 break;
1822 case TLAN_TIMER_PHY_PUP:
1823 tlan_phy_power_up(dev);
1824 break;
1825 case TLAN_TIMER_PHY_RESET:
1826 tlan_phy_reset(dev);
1827 break;
1828 case TLAN_TIMER_PHY_START_LINK:
1829 tlan_phy_start_link(dev);
1830 break;
1831 case TLAN_TIMER_PHY_FINISH_AN:
1832 tlan_phy_finish_auto_neg(dev);
1833 break;
1834 case TLAN_TIMER_FINISH_RESET:
1835 tlan_finish_reset(dev);
1836 break;
1837 case TLAN_TIMER_ACTIVITY:
1838 spin_lock_irqsave(&priv->lock, flags);
1839 if (priv->timer.function == NULL) {
1840 elapsed = jiffies - priv->timer_set_at;
1841 if (elapsed >= TLAN_TIMER_ACT_DELAY) {
1842 tlan_dio_write8(dev->base_addr,
1843 TLAN_LED_REG, TLAN_LED_LINK);
1844 } else {
1845 priv->timer.function = tlan_timer;
1846 priv->timer.expires = priv->timer_set_at
1847 + TLAN_TIMER_ACT_DELAY;
1848 spin_unlock_irqrestore(&priv->lock, flags);
1849 add_timer(&priv->timer);
1850 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001852 }
1853 spin_unlock_irqrestore(&priv->lock, flags);
1854 break;
1855 default:
1856 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 }
1858
Sakari Ailusc659c382011-01-21 10:59:30 +00001859}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
1861
1862
1863
1864/*****************************************************************************
1865******************************************************************************
1866
Sakari Ailusc659c382011-01-21 10:59:30 +00001867ThunderLAN driver adapter related routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868
1869******************************************************************************
1870*****************************************************************************/
1871
1872
Sakari Ailusc659c382011-01-21 10:59:30 +00001873/***************************************************************
1874 * tlan_reset_lists
1875 *
1876 * Returns:
1877 * Nothing
1878 * Parms:
1879 * dev The device structure with the list
1880 * stuctures to be reset.
1881 *
1882 * This routine sets the variables associated with managing
1883 * the TLAN lists to their initial values.
1884 *
1885 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886
Sakari Ailusc659c382011-01-21 10:59:30 +00001887static void tlan_reset_lists(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888{
Sakari Ailusc659c382011-01-21 10:59:30 +00001889 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +00001891 struct tlan_list *list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 dma_addr_t list_phys;
1893 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894
Sakari Ailusc659c382011-01-21 10:59:30 +00001895 priv->tx_head = 0;
1896 priv->tx_tail = 0;
1897 for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
1898 list = priv->tx_list + i;
1899 list->c_stat = TLAN_CSTAT_UNUSED;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001900 list->buffer[0].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 list->buffer[2].count = 0;
1902 list->buffer[2].address = 0;
1903 list->buffer[8].address = 0;
1904 list->buffer[9].address = 0;
1905 }
1906
Sakari Ailusc659c382011-01-21 10:59:30 +00001907 priv->rx_head = 0;
1908 priv->rx_tail = TLAN_NUM_RX_LISTS - 1;
1909 for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
1910 list = priv->rx_list + i;
1911 list_phys = priv->rx_list_dma + sizeof(struct tlan_list)*i;
1912 list->c_stat = TLAN_CSTAT_READY;
1913 list->frame_size = TLAN_MAX_FRAME_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
Eric Dumazet89d71a62009-10-13 05:34:20 +00001915 skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5);
Sakari Ailusc659c382011-01-21 10:59:30 +00001916 if (!skb) {
Joe Perches50624aa2011-03-01 06:56:33 +00001917 netdev_err(dev, "Out of memory for received data\n");
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001918 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 }
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001920
Sakari Ailusc659c382011-01-21 10:59:30 +00001921 list->buffer[0].address = pci_map_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001922 skb->data,
1923 TLAN_MAX_FRAME_SIZE,
1924 PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001925 tlan_store_skb(list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 list->buffer[1].count = 0;
1927 list->buffer[1].address = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001928 list->forward = list_phys + sizeof(struct tlan_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 }
1930
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001931 /* in case ran out of memory early, clear bits */
1932 while (i < TLAN_NUM_RX_LISTS) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001933 tlan_store_skb(priv->rx_list + i, NULL);
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001934 ++i;
1935 }
1936 list->forward = 0;
1937
Sakari Ailusc659c382011-01-21 10:59:30 +00001938}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939
1940
Sakari Ailusc659c382011-01-21 10:59:30 +00001941static void tlan_free_lists(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942{
Sakari Ailusc659c382011-01-21 10:59:30 +00001943 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +00001945 struct tlan_list *list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 struct sk_buff *skb;
1947
Sakari Ailusc659c382011-01-21 10:59:30 +00001948 for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
1949 list = priv->tx_list + i;
1950 skb = tlan_get_skb(list);
1951 if (skb) {
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001952 pci_unmap_single(
Sakari Ailusc659c382011-01-21 10:59:30 +00001953 priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001954 list->buffer[0].address,
1955 max(skb->len,
1956 (unsigned int)TLAN_MIN_FRAME_SIZE),
1957 PCI_DMA_TODEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001958 dev_kfree_skb_any(skb);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001959 list->buffer[8].address = 0;
1960 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 }
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001962 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963
Sakari Ailusc659c382011-01-21 10:59:30 +00001964 for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
1965 list = priv->rx_list + i;
1966 skb = tlan_get_skb(list);
1967 if (skb) {
1968 pci_unmap_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001969 list->buffer[0].address,
1970 TLAN_MAX_FRAME_SIZE,
1971 PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001972 dev_kfree_skb_any(skb);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001973 list->buffer[8].address = 0;
1974 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975 }
1976 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001977}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978
1979
1980
1981
Sakari Ailusc659c382011-01-21 10:59:30 +00001982/***************************************************************
1983 * tlan_print_dio
1984 *
1985 * Returns:
1986 * Nothing
1987 * Parms:
1988 * io_base Base IO port of the device of
1989 * which to print DIO registers.
1990 *
1991 * This function prints out all the internal (DIO)
1992 * registers of a TLAN chip.
1993 *
1994 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995
Sakari Ailusc659c382011-01-21 10:59:30 +00001996static void tlan_print_dio(u16 io_base)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997{
1998 u32 data0, data1;
1999 int i;
2000
Joe Perches50624aa2011-03-01 06:56:33 +00002001 pr_info("Contents of internal registers for io base 0x%04hx\n",
2002 io_base);
2003 pr_info("Off. +0 +4\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002004 for (i = 0; i < 0x4C; i += 8) {
2005 data0 = tlan_dio_read32(io_base, i);
2006 data1 = tlan_dio_read32(io_base, i + 0x4);
Joe Perches50624aa2011-03-01 06:56:33 +00002007 pr_info("0x%02x 0x%08x 0x%08x\n", i, data0, data1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008 }
2009
Sakari Ailusc659c382011-01-21 10:59:30 +00002010}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011
2012
2013
2014
Sakari Ailusc659c382011-01-21 10:59:30 +00002015/***************************************************************
2016 * TLan_PrintList
2017 *
2018 * Returns:
2019 * Nothing
2020 * Parms:
2021 * list A pointer to the struct tlan_list structure to
2022 * be printed.
2023 * type A string to designate type of list,
2024 * "Rx" or "Tx".
2025 * num The index of the list.
2026 *
2027 * This function prints out the contents of the list
2028 * pointed to by the list parameter.
2029 *
2030 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031
Sakari Ailusc659c382011-01-21 10:59:30 +00002032static void tlan_print_list(struct tlan_list *list, char *type, int num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033{
2034 int i;
2035
Joe Perches50624aa2011-03-01 06:56:33 +00002036 pr_info("%s List %d at %p\n", type, num, list);
2037 pr_info(" Forward = 0x%08x\n", list->forward);
2038 pr_info(" CSTAT = 0x%04hx\n", list->c_stat);
2039 pr_info(" Frame Size = 0x%04hx\n", list->frame_size);
Sakari Ailusc659c382011-01-21 10:59:30 +00002040 /* for (i = 0; i < 10; i++) { */
2041 for (i = 0; i < 2; i++) {
Joe Perches50624aa2011-03-01 06:56:33 +00002042 pr_info(" Buffer[%d].count, addr = 0x%08x, 0x%08x\n",
2043 i, list->buffer[i].count, list->buffer[i].address);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044 }
2045
Sakari Ailusc659c382011-01-21 10:59:30 +00002046}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047
2048
2049
2050
Sakari Ailusc659c382011-01-21 10:59:30 +00002051/***************************************************************
2052 * tlan_read_and_clear_stats
2053 *
2054 * Returns:
2055 * Nothing
2056 * Parms:
2057 * dev Pointer to device structure of adapter
2058 * to which to read stats.
2059 * record Flag indicating whether to add
2060 *
2061 * This functions reads all the internal status registers
2062 * of the TLAN chip, which clears them as a side effect.
2063 * It then either adds the values to the device's status
2064 * struct, or discards them, depending on whether record
2065 * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0).
2066 *
2067 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068
Sakari Ailusc659c382011-01-21 10:59:30 +00002069static void tlan_read_and_clear_stats(struct net_device *dev, int record)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 u32 tx_good, tx_under;
2072 u32 rx_good, rx_over;
2073 u32 def_tx, crc, code;
2074 u32 multi_col, single_col;
2075 u32 excess_col, late_col, loss;
2076
Sakari Ailusc659c382011-01-21 10:59:30 +00002077 outw(TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR);
2078 tx_good = inb(dev->base_addr + TLAN_DIO_DATA);
2079 tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2080 tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
2081 tx_under = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082
Sakari Ailusc659c382011-01-21 10:59:30 +00002083 outw(TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR);
2084 rx_good = inb(dev->base_addr + TLAN_DIO_DATA);
2085 rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2086 rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
2087 rx_over = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002088
Sakari Ailusc659c382011-01-21 10:59:30 +00002089 outw(TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR);
2090 def_tx = inb(dev->base_addr + TLAN_DIO_DATA);
2091 def_tx += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2092 crc = inb(dev->base_addr + TLAN_DIO_DATA + 2);
2093 code = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002094
Sakari Ailusc659c382011-01-21 10:59:30 +00002095 outw(TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
2096 multi_col = inb(dev->base_addr + TLAN_DIO_DATA);
2097 multi_col += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2098 single_col = inb(dev->base_addr + TLAN_DIO_DATA + 2);
2099 single_col += inb(dev->base_addr + TLAN_DIO_DATA + 3) << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100
Sakari Ailusc659c382011-01-21 10:59:30 +00002101 outw(TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
2102 excess_col = inb(dev->base_addr + TLAN_DIO_DATA);
2103 late_col = inb(dev->base_addr + TLAN_DIO_DATA + 1);
2104 loss = inb(dev->base_addr + TLAN_DIO_DATA + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105
Sakari Ailusc659c382011-01-21 10:59:30 +00002106 if (record) {
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002107 dev->stats.rx_packets += rx_good;
2108 dev->stats.rx_errors += rx_over + crc + code;
2109 dev->stats.tx_packets += tx_good;
2110 dev->stats.tx_errors += tx_under + loss;
Sakari Ailusc659c382011-01-21 10:59:30 +00002111 dev->stats.collisions += multi_col
2112 + single_col + excess_col + late_col;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002114 dev->stats.rx_over_errors += rx_over;
2115 dev->stats.rx_crc_errors += crc;
2116 dev->stats.rx_frame_errors += code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002118 dev->stats.tx_aborted_errors += tx_under;
2119 dev->stats.tx_carrier_errors += loss;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002121
Sakari Ailusc659c382011-01-21 10:59:30 +00002122}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123
2124
2125
2126
Sakari Ailusc659c382011-01-21 10:59:30 +00002127/***************************************************************
2128 * TLan_Reset
2129 *
2130 * Returns:
2131 * 0
2132 * Parms:
2133 * dev Pointer to device structure of adapter
2134 * to be reset.
2135 *
2136 * This function resets the adapter and it's physical
2137 * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
2138 * Programmer's Guide" for details. The routine tries to
2139 * implement what is detailed there, though adjustments
2140 * have been made.
2141 *
2142 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143
Harvey Harrison98e0f522008-02-18 10:04:38 -08002144static void
Sakari Ailusc659c382011-01-21 10:59:30 +00002145tlan_reset_adapter(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146{
Sakari Ailusc659c382011-01-21 10:59:30 +00002147 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 int i;
2149 u32 addr;
2150 u32 data;
2151 u8 data8;
2152
Sakari Ailusc659c382011-01-21 10:59:30 +00002153 priv->tlan_full_duplex = false;
2154 priv->phy_online = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 netif_carrier_off(dev);
2156
2157/* 1. Assert reset bit. */
2158
2159 data = inl(dev->base_addr + TLAN_HOST_CMD);
2160 data |= TLAN_HC_AD_RST;
2161 outl(data, dev->base_addr + TLAN_HOST_CMD);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002162
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163 udelay(1000);
2164
Sakari Ailusc659c382011-01-21 10:59:30 +00002165/* 2. Turn off interrupts. (Probably isn't necessary) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166
2167 data = inl(dev->base_addr + TLAN_HOST_CMD);
2168 data |= TLAN_HC_INT_OFF;
2169 outl(data, dev->base_addr + TLAN_HOST_CMD);
2170
2171/* 3. Clear AREGs and HASHs. */
2172
Sakari Ailusc659c382011-01-21 10:59:30 +00002173 for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4)
2174 tlan_dio_write32(dev->base_addr, (u16) i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175
2176/* 4. Setup NetConfig register. */
2177
2178 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
Sakari Ailusc659c382011-01-21 10:59:30 +00002179 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180
2181/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
2182
Sakari Ailusc659c382011-01-21 10:59:30 +00002183 outl(TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD);
2184 outl(TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002185
2186/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
2187
Sakari Ailusc659c382011-01-21 10:59:30 +00002188 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189 addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Sakari Ailusc659c382011-01-21 10:59:30 +00002190 tlan_set_bit(TLAN_NET_SIO_NMRST, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191
2192/* 7. Setup the remaining registers. */
2193
Sakari Ailusc659c382011-01-21 10:59:30 +00002194 if (priv->tlan_rev >= 0x30) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195 data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
Sakari Ailusc659c382011-01-21 10:59:30 +00002196 tlan_dio_write8(dev->base_addr, TLAN_INT_DIS, data8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002198 tlan_phy_detect(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002200
Sakari Ailusc659c382011-01-21 10:59:30 +00002201 if (priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202 data |= TLAN_NET_CFG_BIT;
Sakari Ailusc659c382011-01-21 10:59:30 +00002203 if (priv->aui == 1) {
2204 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x0a);
2205 } else if (priv->duplex == TLAN_DUPLEX_FULL) {
2206 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x00);
2207 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002209 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x08);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210 }
2211 }
2212
Sakari Ailusc659c382011-01-21 10:59:30 +00002213 if (priv->phy_num == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214 data |= TLAN_NET_CFG_PHY_EN;
Sakari Ailusc659c382011-01-21 10:59:30 +00002215 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216
Sakari Ailusc659c382011-01-21 10:59:30 +00002217 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY)
2218 tlan_finish_reset(dev);
2219 else
2220 tlan_phy_power_down(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221
Sakari Ailusc659c382011-01-21 10:59:30 +00002222}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002223
2224
2225
2226
Harvey Harrison98e0f522008-02-18 10:04:38 -08002227static void
Sakari Ailusc659c382011-01-21 10:59:30 +00002228tlan_finish_reset(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229{
Sakari Ailusc659c382011-01-21 10:59:30 +00002230 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 u8 data;
2232 u32 phy;
2233 u8 sio;
2234 u16 status;
2235 u16 partner;
2236 u16 tlphy_ctl;
Sakari Ailusc659c382011-01-21 10:59:30 +00002237 u16 tlphy_par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238 u16 tlphy_id1, tlphy_id2;
Sakari Ailusc659c382011-01-21 10:59:30 +00002239 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240
Sakari Ailusc659c382011-01-21 10:59:30 +00002241 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242
2243 data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
Sakari Ailusc659c382011-01-21 10:59:30 +00002244 if (priv->tlan_full_duplex)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 data |= TLAN_NET_CMD_DUPLEX;
Sakari Ailusc659c382011-01-21 10:59:30 +00002246 tlan_dio_write8(dev->base_addr, TLAN_NET_CMD, data);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002247 data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
Sakari Ailusc659c382011-01-21 10:59:30 +00002248 if (priv->phy_num == 0)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002249 data |= TLAN_NET_MASK_MASK7;
Sakari Ailusc659c382011-01-21 10:59:30 +00002250 tlan_dio_write8(dev->base_addr, TLAN_NET_MASK, data);
2251 tlan_dio_write16(dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7);
2252 tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &tlphy_id1);
2253 tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &tlphy_id2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002254
Sakari Ailusc659c382011-01-21 10:59:30 +00002255 if ((priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) ||
2256 (priv->aui)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 status = MII_GS_LINK;
Joe Perches50624aa2011-03-01 06:56:33 +00002258 netdev_info(dev, "Link forced\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002260 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2261 udelay(1000);
2262 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2263 if ((status & MII_GS_LINK) &&
2264 /* We only support link info on Nat.Sem. PHY's */
2265 (tlphy_id1 == NAT_SEM_ID1) &&
2266 (tlphy_id2 == NAT_SEM_ID2)) {
2267 tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner);
2268 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002269
Joe Perches50624aa2011-03-01 06:56:33 +00002270 netdev_info(dev,
2271 "Link active with %s %uMbps %s-Duplex\n",
2272 !(tlphy_par & TLAN_PHY_AN_EN_STAT)
2273 ? "forced" : "Autonegotiation enabled,",
2274 tlphy_par & TLAN_PHY_SPEED_100
2275 ? 100 : 10,
2276 tlphy_par & TLAN_PHY_DUPLEX_FULL
2277 ? "Full" : "Half");
2278
2279 if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
2280 netdev_info(dev, "Partner capability:");
2281 for (i = 5; i < 10; i++)
2282 if (partner & (1 << i))
2283 pr_cont(" %s", media[i-5]);
2284 pr_cont("\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285 }
2286
Sakari Ailusc659c382011-01-21 10:59:30 +00002287 tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
2288 TLAN_LED_LINK);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002289#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290 /* We have link beat..for now anyway */
Sakari Ailusc659c382011-01-21 10:59:30 +00002291 priv->link = 1;
2292 /*Enabling link beat monitoring */
2293 tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002294#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295 } else if (status & MII_GS_LINK) {
Joe Perches50624aa2011-03-01 06:56:33 +00002296 netdev_info(dev, "Link active\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002297 tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
2298 TLAN_LED_LINK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299 }
2300 }
2301
Sakari Ailusc659c382011-01-21 10:59:30 +00002302 if (priv->phy_num == 0) {
2303 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
2304 tlphy_ctl |= TLAN_TC_INTEN;
2305 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
2306 sio = tlan_dio_read8(dev->base_addr, TLAN_NET_SIO);
2307 sio |= TLAN_NET_SIO_MINTEN;
2308 tlan_dio_write8(dev->base_addr, TLAN_NET_SIO, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309 }
2310
Sakari Ailusc659c382011-01-21 10:59:30 +00002311 if (status & MII_GS_LINK) {
2312 tlan_set_mac(dev, 0, dev->dev_addr);
2313 priv->phy_online = 1;
2314 outb((TLAN_HC_INT_ON >> 8), dev->base_addr + TLAN_HOST_CMD + 1);
2315 if (debug >= 1 && debug != TLAN_DEBUG_PROBE)
2316 outb((TLAN_HC_REQ_INT >> 8),
2317 dev->base_addr + TLAN_HOST_CMD + 1);
2318 outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM);
2319 outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320 netif_carrier_on(dev);
2321 } else {
Joe Perches50624aa2011-03-01 06:56:33 +00002322 netdev_info(dev, "Link inactive, will retry in 10 secs...\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002323 tlan_set_timer(dev, (10*HZ), TLAN_TIMER_FINISH_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 return;
2325 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002326 tlan_set_multicast_list(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327
Sakari Ailusc659c382011-01-21 10:59:30 +00002328}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329
2330
2331
2332
Sakari Ailusc659c382011-01-21 10:59:30 +00002333/***************************************************************
2334 * tlan_set_mac
2335 *
2336 * Returns:
2337 * Nothing
2338 * Parms:
2339 * dev Pointer to device structure of adapter
2340 * on which to change the AREG.
2341 * areg The AREG to set the address in (0 - 3).
2342 * mac A pointer to an array of chars. Each
2343 * element stores one byte of the address.
2344 * IE, it isn't in ascii.
2345 *
2346 * This function transfers a MAC address to one of the
2347 * TLAN AREGs (address registers). The TLAN chip locks
2348 * the register on writing to offset 0 and unlocks the
2349 * register after writing to offset 5. If NULL is passed
2350 * in mac, then the AREG is filled with 0's.
2351 *
2352 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353
Sakari Ailusc659c382011-01-21 10:59:30 +00002354static void tlan_set_mac(struct net_device *dev, int areg, char *mac)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355{
2356 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002357
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358 areg *= 6;
2359
Sakari Ailusc659c382011-01-21 10:59:30 +00002360 if (mac != NULL) {
2361 for (i = 0; i < 6; i++)
2362 tlan_dio_write8(dev->base_addr,
2363 TLAN_AREG_0 + areg + i, mac[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002365 for (i = 0; i < 6; i++)
2366 tlan_dio_write8(dev->base_addr,
2367 TLAN_AREG_0 + areg + i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002368 }
2369
Sakari Ailusc659c382011-01-21 10:59:30 +00002370}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002371
2372
2373
2374
2375/*****************************************************************************
2376******************************************************************************
2377
Sakari Ailusc659c382011-01-21 10:59:30 +00002378ThunderLAN driver PHY layer routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379
2380******************************************************************************
2381*****************************************************************************/
2382
2383
2384
Sakari Ailusc659c382011-01-21 10:59:30 +00002385/*********************************************************************
2386 * tlan_phy_print
2387 *
2388 * Returns:
2389 * Nothing
2390 * Parms:
2391 * dev A pointer to the device structure of the
2392 * TLAN device having the PHYs to be detailed.
2393 *
2394 * This function prints the registers a PHY (aka transceiver).
2395 *
2396 ********************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397
Sakari Ailusc659c382011-01-21 10:59:30 +00002398static void tlan_phy_print(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399{
Sakari Ailusc659c382011-01-21 10:59:30 +00002400 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 u16 i, data0, data1, data2, data3, phy;
2402
Sakari Ailusc659c382011-01-21 10:59:30 +00002403 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002404
Sakari Ailusc659c382011-01-21 10:59:30 +00002405 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
Joe Perches50624aa2011-03-01 06:56:33 +00002406 netdev_info(dev, "Unmanaged PHY\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002407 } else if (phy <= TLAN_PHY_MAX_ADDR) {
Joe Perches50624aa2011-03-01 06:56:33 +00002408 netdev_info(dev, "PHY 0x%02x\n", phy);
2409 pr_info(" Off. +0 +1 +2 +3\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002410 for (i = 0; i < 0x20; i += 4) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002411 tlan_mii_read_reg(dev, phy, i, &data0);
Sakari Ailusc659c382011-01-21 10:59:30 +00002412 tlan_mii_read_reg(dev, phy, i + 1, &data1);
Sakari Ailusc659c382011-01-21 10:59:30 +00002413 tlan_mii_read_reg(dev, phy, i + 2, &data2);
Sakari Ailusc659c382011-01-21 10:59:30 +00002414 tlan_mii_read_reg(dev, phy, i + 3, &data3);
Joe Perches50624aa2011-03-01 06:56:33 +00002415 pr_info(" 0x%02x 0x%04hx 0x%04hx 0x%04hx 0x%04hx\n",
2416 i, data0, data1, data2, data3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417 }
2418 } else {
Joe Perches50624aa2011-03-01 06:56:33 +00002419 netdev_info(dev, "Invalid PHY\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420 }
2421
Sakari Ailusc659c382011-01-21 10:59:30 +00002422}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002423
2424
2425
2426
Sakari Ailusc659c382011-01-21 10:59:30 +00002427/*********************************************************************
2428 * tlan_phy_detect
2429 *
2430 * Returns:
2431 * Nothing
2432 * Parms:
2433 * dev A pointer to the device structure of the adapter
2434 * for which the PHY needs determined.
2435 *
2436 * So far I've found that adapters which have external PHYs
2437 * may also use the internal PHY for part of the functionality.
2438 * (eg, AUI/Thinnet). This function finds out if this TLAN
2439 * chip has an internal PHY, and then finds the first external
2440 * PHY (starting from address 0) if it exists).
2441 *
2442 ********************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443
Sakari Ailusc659c382011-01-21 10:59:30 +00002444static void tlan_phy_detect(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445{
Sakari Ailusc659c382011-01-21 10:59:30 +00002446 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447 u16 control;
2448 u16 hi;
2449 u16 lo;
2450 u32 phy;
2451
Sakari Ailusc659c382011-01-21 10:59:30 +00002452 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
2453 priv->phy_num = 0xffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454 return;
2455 }
2456
Sakari Ailusc659c382011-01-21 10:59:30 +00002457 tlan_mii_read_reg(dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002458
Sakari Ailusc659c382011-01-21 10:59:30 +00002459 if (hi != 0xffff)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460 priv->phy[0] = TLAN_PHY_MAX_ADDR;
Sakari Ailusc659c382011-01-21 10:59:30 +00002461 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002462 priv->phy[0] = TLAN_PHY_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002463
2464 priv->phy[1] = TLAN_PHY_NONE;
Sakari Ailusc659c382011-01-21 10:59:30 +00002465 for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) {
2466 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &control);
2467 tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &hi);
2468 tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &lo);
2469 if ((control != 0xffff) ||
2470 (hi != 0xffff) || (lo != 0xffff)) {
2471 TLAN_DBG(TLAN_DEBUG_GNRL,
2472 "PHY found at %02x %04x %04x %04x\n",
2473 phy, control, hi, lo);
2474 if ((priv->phy[1] == TLAN_PHY_NONE) &&
2475 (phy != TLAN_PHY_MAX_ADDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002476 priv->phy[1] = phy;
2477 }
2478 }
2479 }
2480
Sakari Ailusc659c382011-01-21 10:59:30 +00002481 if (priv->phy[1] != TLAN_PHY_NONE)
2482 priv->phy_num = 1;
2483 else if (priv->phy[0] != TLAN_PHY_NONE)
2484 priv->phy_num = 0;
2485 else
Joe Perches50624aa2011-03-01 06:56:33 +00002486 netdev_info(dev, "Cannot initialize device, no PHY was found!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487
Sakari Ailusc659c382011-01-21 10:59:30 +00002488}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489
2490
2491
2492
Sakari Ailusc659c382011-01-21 10:59:30 +00002493static void tlan_phy_power_down(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494{
Sakari Ailusc659c382011-01-21 10:59:30 +00002495 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496 u16 value;
2497
Sakari Ailusc659c382011-01-21 10:59:30 +00002498 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
Sakari Ailusc659c382011-01-21 10:59:30 +00002500 tlan_mii_sync(dev->base_addr);
2501 tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
2502 if ((priv->phy_num == 0) &&
2503 (priv->phy[1] != TLAN_PHY_NONE) &&
2504 (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) {
2505 tlan_mii_sync(dev->base_addr);
2506 tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507 }
2508
2509 /* Wait for 50 ms and powerup
2510 * This is abitrary. It is intended to make sure the
2511 * transceiver settles.
2512 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002513 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_PUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514
Sakari Ailusc659c382011-01-21 10:59:30 +00002515}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516
2517
2518
2519
Sakari Ailusc659c382011-01-21 10:59:30 +00002520static void tlan_phy_power_up(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521{
Sakari Ailusc659c382011-01-21 10:59:30 +00002522 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523 u16 value;
2524
Sakari Ailusc659c382011-01-21 10:59:30 +00002525 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name);
2526 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527 value = MII_GC_LOOPBK;
Sakari Ailusc659c382011-01-21 10:59:30 +00002528 tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
2529 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 /* Wait for 500 ms and reset the
2531 * transceiver. The TLAN docs say both 50 ms and
2532 * 500 ms, so do the longer, just in case.
2533 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002534 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535
Sakari Ailusc659c382011-01-21 10:59:30 +00002536}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537
2538
2539
2540
Sakari Ailusc659c382011-01-21 10:59:30 +00002541static void tlan_phy_reset(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002542{
Sakari Ailusc659c382011-01-21 10:59:30 +00002543 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 u16 phy;
2545 u16 value;
2546
Sakari Ailusc659c382011-01-21 10:59:30 +00002547 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548
Sakari Ailusc659c382011-01-21 10:59:30 +00002549 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name);
2550 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 value = MII_GC_LOOPBK | MII_GC_RESET;
Sakari Ailusc659c382011-01-21 10:59:30 +00002552 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value);
2553 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
2554 while (value & MII_GC_RESET)
2555 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002556
2557 /* Wait for 500 ms and initialize.
2558 * I don't remember why I wait this long.
2559 * I've changed this to 50ms, as it seems long enough.
2560 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002561 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_START_LINK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562
Sakari Ailusc659c382011-01-21 10:59:30 +00002563}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564
2565
2566
2567
Sakari Ailusc659c382011-01-21 10:59:30 +00002568static void tlan_phy_start_link(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569{
Sakari Ailusc659c382011-01-21 10:59:30 +00002570 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571 u16 ability;
2572 u16 control;
2573 u16 data;
2574 u16 phy;
2575 u16 status;
2576 u16 tctl;
2577
Sakari Ailusc659c382011-01-21 10:59:30 +00002578 phy = priv->phy[priv->phy_num];
2579 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name);
2580 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2581 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &ability);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582
Sakari Ailusc659c382011-01-21 10:59:30 +00002583 if ((status & MII_GS_AUTONEG) &&
2584 (!priv->aui)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585 ability = status >> 11;
Sakari Ailusc659c382011-01-21 10:59:30 +00002586 if (priv->speed == TLAN_SPEED_10 &&
2587 priv->duplex == TLAN_DUPLEX_HALF) {
2588 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0000);
2589 } else if (priv->speed == TLAN_SPEED_10 &&
2590 priv->duplex == TLAN_DUPLEX_FULL) {
2591 priv->tlan_full_duplex = true;
2592 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0100);
2593 } else if (priv->speed == TLAN_SPEED_100 &&
2594 priv->duplex == TLAN_DUPLEX_HALF) {
2595 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2000);
2596 } else if (priv->speed == TLAN_SPEED_100 &&
2597 priv->duplex == TLAN_DUPLEX_FULL) {
2598 priv->tlan_full_duplex = true;
2599 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2100);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 } else {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002601
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602 /* Set Auto-Neg advertisement */
Sakari Ailusc659c382011-01-21 10:59:30 +00002603 tlan_mii_write_reg(dev, phy, MII_AN_ADV,
2604 (ability << 5) | 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605 /* Enablee Auto-Neg */
Sakari Ailusc659c382011-01-21 10:59:30 +00002606 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1000);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607 /* Restart Auto-Neg */
Sakari Ailusc659c382011-01-21 10:59:30 +00002608 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1200);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609 /* Wait for 4 sec for autonegotiation
Sakari Ailusc659c382011-01-21 10:59:30 +00002610 * to complete. The max spec time is less than this
2611 * but the card need additional time to start AN.
2612 * .5 sec should be plenty extra.
2613 */
Joe Perches50624aa2011-03-01 06:56:33 +00002614 netdev_info(dev, "Starting autonegotiation\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002615 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002616 return;
2617 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002618
2619 }
2620
Sakari Ailusc659c382011-01-21 10:59:30 +00002621 if ((priv->aui) && (priv->phy_num != 0)) {
2622 priv->phy_num = 0;
2623 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
2624 | TLAN_NET_CFG_PHY_EN;
2625 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
2626 tlan_set_timer(dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627 return;
Sakari Ailusc659c382011-01-21 10:59:30 +00002628 } else if (priv->phy_num == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629 control = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002630 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tctl);
2631 if (priv->aui) {
2632 tctl |= TLAN_TC_AUISEL;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002633 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002634 tctl &= ~TLAN_TC_AUISEL;
2635 if (priv->duplex == TLAN_DUPLEX_FULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 control |= MII_GC_DUPLEX;
Sakari Ailusc659c382011-01-21 10:59:30 +00002637 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002639 if (priv->speed == TLAN_SPEED_100)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640 control |= MII_GC_SPEEDSEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002642 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, control);
2643 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644 }
2645
2646 /* Wait for 2 sec to give the transceiver time
2647 * to establish link.
2648 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002649 tlan_set_timer(dev, (4*HZ), TLAN_TIMER_FINISH_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002650
Sakari Ailusc659c382011-01-21 10:59:30 +00002651}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652
2653
2654
2655
Sakari Ailusc659c382011-01-21 10:59:30 +00002656static void tlan_phy_finish_auto_neg(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657{
Sakari Ailusc659c382011-01-21 10:59:30 +00002658 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002659 u16 an_adv;
2660 u16 an_lpa;
2661 u16 data;
2662 u16 mode;
2663 u16 phy;
2664 u16 status;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002665
Sakari Ailusc659c382011-01-21 10:59:30 +00002666 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667
Sakari Ailusc659c382011-01-21 10:59:30 +00002668 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2669 udelay(1000);
2670 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671
Sakari Ailusc659c382011-01-21 10:59:30 +00002672 if (!(status & MII_GS_AUTOCMPLT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 /* Wait for 8 sec to give the process
2674 * more time. Perhaps we should fail after a while.
2675 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002676 if (!priv->neg_be_verbose++) {
Joe Perches50624aa2011-03-01 06:56:33 +00002677 pr_info("Giving autonegotiation more time.\n");
2678 pr_info("Please check that your adapter has\n");
2679 pr_info("been properly connected to a HUB or Switch.\n");
2680 pr_info("Trying to establish link in the background...\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002681 }
2682 tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683 return;
2684 }
2685
Joe Perches50624aa2011-03-01 06:56:33 +00002686 netdev_info(dev, "Autonegotiation complete\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002687 tlan_mii_read_reg(dev, phy, MII_AN_ADV, &an_adv);
2688 tlan_mii_read_reg(dev, phy, MII_AN_LPA, &an_lpa);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002689 mode = an_adv & an_lpa & 0x03E0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002690 if (mode & 0x0100)
2691 priv->tlan_full_duplex = true;
2692 else if (!(mode & 0x0080) && (mode & 0x0040))
2693 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694
Sakari Ailusc659c382011-01-21 10:59:30 +00002695 if ((!(mode & 0x0180)) &&
2696 (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) &&
2697 (priv->phy_num != 0)) {
2698 priv->phy_num = 0;
2699 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
2700 | TLAN_NET_CFG_PHY_EN;
2701 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
2702 tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703 return;
2704 }
2705
Sakari Ailusc659c382011-01-21 10:59:30 +00002706 if (priv->phy_num == 0) {
2707 if ((priv->duplex == TLAN_DUPLEX_FULL) ||
2708 (an_adv & an_lpa & 0x0040)) {
2709 tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
2710 MII_GC_AUTOENB | MII_GC_DUPLEX);
Joe Perches50624aa2011-03-01 06:56:33 +00002711 netdev_info(dev, "Starting internal PHY with FULL-DUPLEX\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002713 tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
2714 MII_GC_AUTOENB);
Joe Perches50624aa2011-03-01 06:56:33 +00002715 netdev_info(dev, "Starting internal PHY with HALF-DUPLEX\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716 }
2717 }
2718
2719 /* Wait for 100 ms. No reason in partiticular.
2720 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002721 tlan_set_timer(dev, (HZ/10), TLAN_TIMER_FINISH_RESET);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002722
Sakari Ailusc659c382011-01-21 10:59:30 +00002723}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002724
2725#ifdef MONITOR
2726
Sakari Ailusc659c382011-01-21 10:59:30 +00002727/*********************************************************************
2728 *
2729 * tlan_phy_monitor
2730 *
2731 * Returns:
2732 * None
2733 *
2734 * Params:
2735 * dev The device structure of this device.
2736 *
2737 *
2738 * This function monitors PHY condition by reading the status
2739 * register via the MII bus. This can be used to give info
2740 * about link changes (up/down), and possible switch to alternate
2741 * media.
2742 *
2743 *******************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744
Sakari Ailusc659c382011-01-21 10:59:30 +00002745void tlan_phy_monitor(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746{
Sakari Ailusc659c382011-01-21 10:59:30 +00002747 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748 u16 phy;
2749 u16 phy_status;
2750
Sakari Ailusc659c382011-01-21 10:59:30 +00002751 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752
Sakari Ailusc659c382011-01-21 10:59:30 +00002753 /* Get PHY status register */
2754 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &phy_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002755
Sakari Ailusc659c382011-01-21 10:59:30 +00002756 /* Check if link has been lost */
2757 if (!(phy_status & MII_GS_LINK)) {
2758 if (priv->link) {
2759 priv->link = 0;
2760 printk(KERN_DEBUG "TLAN: %s has lost link\n",
2761 dev->name);
2762 netif_carrier_off(dev);
2763 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
2764 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765 }
2766 }
2767
Sakari Ailusc659c382011-01-21 10:59:30 +00002768 /* Link restablished? */
2769 if ((phy_status & MII_GS_LINK) && !priv->link) {
2770 priv->link = 1;
2771 printk(KERN_DEBUG "TLAN: %s has reestablished link\n",
2772 dev->name);
7d17c1d2005-05-12 19:45:25 -04002773 netif_carrier_on(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00002774 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002775
2776 /* Setup a new monitor */
Sakari Ailusc659c382011-01-21 10:59:30 +00002777 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002778}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779
2780#endif /* MONITOR */
2781
2782
2783/*****************************************************************************
2784******************************************************************************
2785
Sakari Ailusc659c382011-01-21 10:59:30 +00002786ThunderLAN driver MII routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787
Sakari Ailusc659c382011-01-21 10:59:30 +00002788these routines are based on the information in chap. 2 of the
2789"ThunderLAN Programmer's Guide", pp. 15-24.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002790
2791******************************************************************************
2792*****************************************************************************/
2793
2794
Sakari Ailusc659c382011-01-21 10:59:30 +00002795/***************************************************************
2796 * tlan_mii_read_reg
2797 *
2798 * Returns:
2799 * false if ack received ok
2800 * true if no ack received or other error
2801 *
2802 * Parms:
2803 * dev The device structure containing
2804 * The io address and interrupt count
2805 * for this device.
2806 * phy The address of the PHY to be queried.
2807 * reg The register whose contents are to be
2808 * retrieved.
2809 * val A pointer to a variable to store the
2810 * retrieved value.
2811 *
2812 * This function uses the TLAN's MII bus to retrieve the contents
2813 * of a given register on a PHY. It sends the appropriate info
2814 * and then reads the 16-bit register value from the MII bus via
2815 * the TLAN SIO register.
2816 *
2817 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818
Sakari Ailusc659c382011-01-21 10:59:30 +00002819static bool
2820tlan_mii_read_reg(struct net_device *dev, u16 phy, u16 reg, u16 *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821{
2822 u8 nack;
2823 u16 sio, tmp;
Sakari Ailusc659c382011-01-21 10:59:30 +00002824 u32 i;
Joe Perches37fce432010-01-12 20:59:13 +00002825 bool err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 int minten;
Sakari Ailusc659c382011-01-21 10:59:30 +00002827 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002828 unsigned long flags = 0;
2829
Joe Perches37fce432010-01-12 20:59:13 +00002830 err = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2832 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002833
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 if (!in_irq())
2835 spin_lock_irqsave(&priv->lock, flags);
2836
Sakari Ailusc659c382011-01-21 10:59:30 +00002837 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838
Sakari Ailusc659c382011-01-21 10:59:30 +00002839 minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
2840 if (minten)
2841 tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842
Sakari Ailusc659c382011-01-21 10:59:30 +00002843 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */
2844 tlan_mii_send_data(dev->base_addr, 0x2, 2); /* read (10b) */
2845 tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */
2846 tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847
2848
Sakari Ailusc659c382011-01-21 10:59:30 +00002849 tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio); /* change direction */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850
Sakari Ailusc659c382011-01-21 10:59:30 +00002851 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* clock idle bit */
2852 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
2853 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* wait 300ns */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854
Sakari Ailusc659c382011-01-21 10:59:30 +00002855 nack = tlan_get_bit(TLAN_NET_SIO_MDATA, sio); /* check for ACK */
2856 tlan_set_bit(TLAN_NET_SIO_MCLK, sio); /* finish ACK */
2857 if (nack) { /* no ACK, so fake it */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 for (i = 0; i < 16; i++) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002859 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2860 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861 }
2862 tmp = 0xffff;
Joe Perches37fce432010-01-12 20:59:13 +00002863 err = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002864 } else { /* ACK, so read data */
2865 for (tmp = 0, i = 0x8000; i; i >>= 1) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002866 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2867 if (tlan_get_bit(TLAN_NET_SIO_MDATA, sio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002868 tmp |= i;
Sakari Ailusc659c382011-01-21 10:59:30 +00002869 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870 }
2871 }
2872
2873
Sakari Ailusc659c382011-01-21 10:59:30 +00002874 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
2875 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876
Sakari Ailusc659c382011-01-21 10:59:30 +00002877 if (minten)
2878 tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879
2880 *val = tmp;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002881
Linus Torvalds1da177e2005-04-16 15:20:36 -07002882 if (!in_irq())
2883 spin_unlock_irqrestore(&priv->lock, flags);
2884
2885 return err;
2886
Sakari Ailusc659c382011-01-21 10:59:30 +00002887}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002888
2889
2890
2891
Sakari Ailusc659c382011-01-21 10:59:30 +00002892/***************************************************************
2893 * tlan_mii_send_data
2894 *
2895 * Returns:
2896 * Nothing
2897 * Parms:
2898 * base_port The base IO port of the adapter in
2899 * question.
2900 * dev The address of the PHY to be queried.
2901 * data The value to be placed on the MII bus.
2902 * num_bits The number of bits in data that are to
2903 * be placed on the MII bus.
2904 *
2905 * This function sends on sequence of bits on the MII
2906 * configuration bus.
2907 *
2908 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909
Sakari Ailusc659c382011-01-21 10:59:30 +00002910static void tlan_mii_send_data(u16 base_port, u32 data, unsigned num_bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911{
2912 u16 sio;
2913 u32 i;
2914
Sakari Ailusc659c382011-01-21 10:59:30 +00002915 if (num_bits == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916 return;
2917
Sakari Ailusc659c382011-01-21 10:59:30 +00002918 outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
Sakari Ailusc659c382011-01-21 10:59:30 +00002920 tlan_set_bit(TLAN_NET_SIO_MTXEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921
Sakari Ailusc659c382011-01-21 10:59:30 +00002922 for (i = (0x1 << (num_bits - 1)); i; i >>= 1) {
2923 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2924 (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
2925 if (data & i)
2926 tlan_set_bit(TLAN_NET_SIO_MDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 else
Sakari Ailusc659c382011-01-21 10:59:30 +00002928 tlan_clear_bit(TLAN_NET_SIO_MDATA, sio);
2929 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
2930 (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931 }
2932
Sakari Ailusc659c382011-01-21 10:59:30 +00002933}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934
2935
2936
2937
Sakari Ailusc659c382011-01-21 10:59:30 +00002938/***************************************************************
2939 * TLan_MiiSync
2940 *
2941 * Returns:
2942 * Nothing
2943 * Parms:
2944 * base_port The base IO port of the adapter in
2945 * question.
2946 *
2947 * This functions syncs all PHYs in terms of the MII configuration
2948 * bus.
2949 *
2950 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002951
Sakari Ailusc659c382011-01-21 10:59:30 +00002952static void tlan_mii_sync(u16 base_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953{
2954 int i;
2955 u16 sio;
2956
Sakari Ailusc659c382011-01-21 10:59:30 +00002957 outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002958 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
2959
Sakari Ailusc659c382011-01-21 10:59:30 +00002960 tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio);
2961 for (i = 0; i < 32; i++) {
2962 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2963 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 }
2965
Sakari Ailusc659c382011-01-21 10:59:30 +00002966}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002967
2968
2969
2970
Sakari Ailusc659c382011-01-21 10:59:30 +00002971/***************************************************************
2972 * tlan_mii_write_reg
2973 *
2974 * Returns:
2975 * Nothing
2976 * Parms:
2977 * dev The device structure for the device
2978 * to write to.
2979 * phy The address of the PHY to be written to.
2980 * reg The register whose contents are to be
2981 * written.
2982 * val The value to be written to the register.
2983 *
2984 * This function uses the TLAN's MII bus to write the contents of a
2985 * given register on a PHY. It sends the appropriate info and then
2986 * writes the 16-bit register value from the MII configuration bus
2987 * via the TLAN SIO register.
2988 *
2989 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990
Sakari Ailusc659c382011-01-21 10:59:30 +00002991static void
2992tlan_mii_write_reg(struct net_device *dev, u16 phy, u16 reg, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993{
2994 u16 sio;
2995 int minten;
2996 unsigned long flags = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002997 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998
2999 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
3000 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003001
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002 if (!in_irq())
3003 spin_lock_irqsave(&priv->lock, flags);
3004
Sakari Ailusc659c382011-01-21 10:59:30 +00003005 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006
Sakari Ailusc659c382011-01-21 10:59:30 +00003007 minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
3008 if (minten)
3009 tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010
Sakari Ailusc659c382011-01-21 10:59:30 +00003011 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */
3012 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* write (01b) */
3013 tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */
3014 tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015
Sakari Ailusc659c382011-01-21 10:59:30 +00003016 tlan_mii_send_data(dev->base_addr, 0x2, 2); /* send ACK */
3017 tlan_mii_send_data(dev->base_addr, val, 16); /* send data */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018
Sakari Ailusc659c382011-01-21 10:59:30 +00003019 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
3020 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003021
Sakari Ailusc659c382011-01-21 10:59:30 +00003022 if (minten)
3023 tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003024
Linus Torvalds1da177e2005-04-16 15:20:36 -07003025 if (!in_irq())
3026 spin_unlock_irqrestore(&priv->lock, flags);
3027
Sakari Ailusc659c382011-01-21 10:59:30 +00003028}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029
3030
3031
3032
3033/*****************************************************************************
3034******************************************************************************
3035
Sakari Ailusc659c382011-01-21 10:59:30 +00003036ThunderLAN driver eeprom routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037
Sakari Ailusc659c382011-01-21 10:59:30 +00003038the Compaq netelligent 10 and 10/100 cards use a microchip 24C02A
3039EEPROM. these functions are based on information in microchip's
3040data sheet. I don't know how well this functions will work with
3041other Eeproms.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042
3043******************************************************************************
3044*****************************************************************************/
3045
3046
Sakari Ailusc659c382011-01-21 10:59:30 +00003047/***************************************************************
3048 * tlan_ee_send_start
3049 *
3050 * Returns:
3051 * Nothing
3052 * Parms:
3053 * io_base The IO port base address for the
3054 * TLAN device with the EEPROM to
3055 * use.
3056 *
3057 * This function sends a start cycle to an EEPROM attached
3058 * to a TLAN chip.
3059 *
3060 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061
Sakari Ailusc659c382011-01-21 10:59:30 +00003062static void tlan_ee_send_start(u16 io_base)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003063{
3064 u16 sio;
3065
Sakari Ailusc659c382011-01-21 10:59:30 +00003066 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3068
Sakari Ailusc659c382011-01-21 10:59:30 +00003069 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3070 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
3071 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
3072 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3073 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074
Sakari Ailusc659c382011-01-21 10:59:30 +00003075}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076
3077
3078
3079
Sakari Ailusc659c382011-01-21 10:59:30 +00003080/***************************************************************
3081 * tlan_ee_send_byte
3082 *
3083 * Returns:
3084 * If the correct ack was received, 0, otherwise 1
3085 * Parms: io_base The IO port base address for the
3086 * TLAN device with the EEPROM to
3087 * use.
3088 * data The 8 bits of information to
3089 * send to the EEPROM.
3090 * stop If TLAN_EEPROM_STOP is passed, a
3091 * stop cycle is sent after the
3092 * byte is sent after the ack is
3093 * read.
3094 *
3095 * This function sends a byte on the serial EEPROM line,
3096 * driving the clock to send each bit. The function then
3097 * reverses transmission direction and reads an acknowledge
3098 * bit.
3099 *
3100 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003101
Sakari Ailusc659c382011-01-21 10:59:30 +00003102static int tlan_ee_send_byte(u16 io_base, u8 data, int stop)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003103{
3104 int err;
3105 u8 place;
3106 u16 sio;
3107
Sakari Ailusc659c382011-01-21 10:59:30 +00003108 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003109 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3110
3111 /* Assume clock is low, tx is enabled; */
Sakari Ailusc659c382011-01-21 10:59:30 +00003112 for (place = 0x80; place != 0; place >>= 1) {
3113 if (place & data)
3114 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115 else
Sakari Ailusc659c382011-01-21 10:59:30 +00003116 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3117 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3118 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003119 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003120 tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
3121 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3122 err = tlan_get_bit(TLAN_NET_SIO_EDATA, sio);
3123 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
3124 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003125
Sakari Ailusc659c382011-01-21 10:59:30 +00003126 if ((!err) && stop) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003127 /* STOP, raise data while clock is high */
Sakari Ailusc659c382011-01-21 10:59:30 +00003128 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3129 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3130 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131 }
3132
Eric Dumazet807540b2010-09-23 05:40:09 +00003133 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134
Sakari Ailusc659c382011-01-21 10:59:30 +00003135}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136
3137
3138
3139
Sakari Ailusc659c382011-01-21 10:59:30 +00003140/***************************************************************
3141 * tlan_ee_receive_byte
3142 *
3143 * Returns:
3144 * Nothing
3145 * Parms:
3146 * io_base The IO port base address for the
3147 * TLAN device with the EEPROM to
3148 * use.
3149 * data An address to a char to hold the
3150 * data sent from the EEPROM.
3151 * stop If TLAN_EEPROM_STOP is passed, a
3152 * stop cycle is sent after the
3153 * byte is received, and no ack is
3154 * sent.
3155 *
3156 * This function receives 8 bits of data from the EEPROM
3157 * over the serial link. It then sends and ack bit, or no
3158 * ack and a stop bit. This function is used to retrieve
3159 * data after the address of a byte in the EEPROM has been
3160 * sent.
3161 *
3162 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003163
Sakari Ailusc659c382011-01-21 10:59:30 +00003164static void tlan_ee_receive_byte(u16 io_base, u8 *data, int stop)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165{
3166 u8 place;
3167 u16 sio;
3168
Sakari Ailusc659c382011-01-21 10:59:30 +00003169 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003170 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3171 *data = 0;
3172
3173 /* Assume clock is low, tx is enabled; */
Sakari Ailusc659c382011-01-21 10:59:30 +00003174 tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
3175 for (place = 0x80; place; place >>= 1) {
3176 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3177 if (tlan_get_bit(TLAN_NET_SIO_EDATA, sio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178 *data |= place;
Sakari Ailusc659c382011-01-21 10:59:30 +00003179 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003180 }
3181
Sakari Ailusc659c382011-01-21 10:59:30 +00003182 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
3183 if (!stop) {
3184 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); /* ack = 0 */
3185 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3186 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003187 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00003188 tlan_set_bit(TLAN_NET_SIO_EDATA, sio); /* no ack = 1 (?) */
3189 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3190 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003191 /* STOP, raise data while clock is high */
Sakari Ailusc659c382011-01-21 10:59:30 +00003192 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3193 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3194 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195 }
3196
Sakari Ailusc659c382011-01-21 10:59:30 +00003197}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003198
3199
3200
3201
Sakari Ailusc659c382011-01-21 10:59:30 +00003202/***************************************************************
3203 * tlan_ee_read_byte
3204 *
3205 * Returns:
3206 * No error = 0, else, the stage at which the error
3207 * occurred.
3208 * Parms:
3209 * io_base The IO port base address for the
3210 * TLAN device with the EEPROM to
3211 * use.
3212 * ee_addr The address of the byte in the
3213 * EEPROM whose contents are to be
3214 * retrieved.
3215 * data An address to a char to hold the
3216 * data obtained from the EEPROM.
3217 *
3218 * This function reads a byte of information from an byte
3219 * cell in the EEPROM.
3220 *
3221 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003222
Sakari Ailusc659c382011-01-21 10:59:30 +00003223static int tlan_ee_read_byte(struct net_device *dev, u8 ee_addr, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003224{
3225 int err;
Sakari Ailusc659c382011-01-21 10:59:30 +00003226 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003227 unsigned long flags = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00003228 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003229
3230 spin_lock_irqsave(&priv->lock, flags);
3231
Sakari Ailusc659c382011-01-21 10:59:30 +00003232 tlan_ee_send_start(dev->base_addr);
3233 err = tlan_ee_send_byte(dev->base_addr, 0xa0, TLAN_EEPROM_ACK);
3234 if (err) {
3235 ret = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003236 goto fail;
3237 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003238 err = tlan_ee_send_byte(dev->base_addr, ee_addr, TLAN_EEPROM_ACK);
3239 if (err) {
3240 ret = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003241 goto fail;
3242 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003243 tlan_ee_send_start(dev->base_addr);
3244 err = tlan_ee_send_byte(dev->base_addr, 0xa1, TLAN_EEPROM_ACK);
3245 if (err) {
3246 ret = 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003247 goto fail;
3248 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003249 tlan_ee_receive_byte(dev->base_addr, data, TLAN_EEPROM_STOP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003250fail:
3251 spin_unlock_irqrestore(&priv->lock, flags);
3252
3253 return ret;
3254
Sakari Ailusc659c382011-01-21 10:59:30 +00003255}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003256
3257
3258