blob: 62b19be5183d3349433ee5855ad082b1560b5c69 [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;
Benjamin Poirierda3a9e92012-04-25 04:49:20 +0000231 addr |= ((unsigned long) 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
Bill Pemberton36915872012-12-03 09:23:44 -0500303static void 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
Devendra Naga1e0a8b12013-04-16 01:30:38 +0000322 cancel_work_sync(&priv->tlan_tqueue);
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);
Yijing Wang1ca01512013-06-27 20:53:42 +0800374 pci_enable_wake(pdev, PCI_D0, 0);
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000375 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,
Bill Pemberton36915872012-12-03 09:23:44 -0500395 .remove = 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
Bill Pemberton36915872012-12-03 09:23:44 -0500437static int tlan_init_one(struct pci_dev *pdev,
Sakari Ailusc659c382011-01-21 10:59:30 +0000438 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
Greg Kroah-Hartman1dd06ae2012-12-06 14:30:56 +0000463static int tlan_probe1(struct pci_dev *pdev, long ioaddr, int irq, int rev,
464 const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465{
466
467 struct net_device *dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000468 struct tlan_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 u16 device_id;
470 int reg, rc = -ENODEV;
471
Adrian Bunkad9f6712006-02-05 00:37:47 +0100472#ifdef CONFIG_PCI
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 if (pdev) {
474 rc = pci_enable_device(pdev);
475 if (rc)
476 return rc;
477
Sakari Ailusc659c382011-01-21 10:59:30 +0000478 rc = pci_request_regions(pdev, tlan_signature);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000480 pr_err("Could not reserve IO regions\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 goto err_out;
482 }
483 }
Adrian Bunkad9f6712006-02-05 00:37:47 +0100484#endif /* CONFIG_PCI */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485
Sakari Ailusc659c382011-01-21 10:59:30 +0000486 dev = alloc_etherdev(sizeof(struct tlan_priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 if (dev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 rc = -ENOMEM;
489 goto err_out_regions;
490 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 SET_NETDEV_DEV(dev, &pdev->dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400492
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 priv = netdev_priv(dev);
494
Sakari Ailusc659c382011-01-21 10:59:30 +0000495 priv->pci_dev = pdev;
David Howellsc4028952006-11-22 14:57:56 +0000496 priv->dev = dev;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400497
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498 /* Is this a PCI device? */
499 if (pdev) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000500 u32 pci_io_base = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501
502 priv->adapter = &board_info[ent->driver_data];
503
Yang Hongyang284901a2009-04-06 19:01:15 -0700504 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000506 pr_err("No suitable PCI mapping available\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 goto err_out_free_dev;
508 }
509
Sakari Ailusc659c382011-01-21 10:59:30 +0000510 for (reg = 0; reg <= 5; reg++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
512 pci_io_base = pci_resource_start(pdev, reg);
Sakari Ailusc659c382011-01-21 10:59:30 +0000513 TLAN_DBG(TLAN_DEBUG_GNRL,
514 "IO mapping is available at %x.\n",
515 pci_io_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 break;
517 }
518 }
519 if (!pci_io_base) {
Joe Perches50624aa2011-03-01 06:56:33 +0000520 pr_err("No IO mappings available\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 rc = -EIO;
522 goto err_out_free_dev;
523 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400524
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 dev->base_addr = pci_io_base;
526 dev->irq = pdev->irq;
Sakari Ailusc659c382011-01-21 10:59:30 +0000527 priv->adapter_rev = pdev->revision;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 pci_set_master(pdev);
529 pci_set_drvdata(pdev, dev);
530
531 } else { /* EISA card */
532 /* This is a hack. We need to know which board structure
533 * is suited for this adapter */
534 device_id = inw(ioaddr + EISA_ID2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 if (device_id == 0x20F1) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000536 priv->adapter = &board_info[13]; /* NetFlex-3/E */
537 priv->adapter_rev = 23; /* TLAN 2.3 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 } else {
539 priv->adapter = &board_info[14];
Sakari Ailusc659c382011-01-21 10:59:30 +0000540 priv->adapter_rev = 10; /* TLAN 1.0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 }
542 dev->base_addr = ioaddr;
543 dev->irq = irq;
544 }
545
546 /* Kernel parameters */
547 if (dev->mem_start) {
548 priv->aui = dev->mem_start & 0x01;
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700549 priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0
550 : (dev->mem_start & 0x06) >> 1;
551 priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0
552 : (dev->mem_start & 0x18) >> 3;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400553
Sakari Ailusc659c382011-01-21 10:59:30 +0000554 if (priv->speed == 0x1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 priv->speed = TLAN_SPEED_10;
Sakari Ailusc659c382011-01-21 10:59:30 +0000556 else if (priv->speed == 0x2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 priv->speed = TLAN_SPEED_100;
Sakari Ailusc659c382011-01-21 10:59:30 +0000558
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 debug = priv->debug = dev->mem_end;
560 } else {
561 priv->aui = aui[boards_found];
562 priv->speed = speed[boards_found];
563 priv->duplex = duplex[boards_found];
564 priv->debug = debug;
565 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 /* This will be used when we get an adapter error from
568 * within our irq handler */
Sakari Ailusc659c382011-01-21 10:59:30 +0000569 INIT_WORK(&priv->tlan_tqueue, tlan_tx_timeout_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
571 spin_lock_init(&priv->lock);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400572
Sakari Ailusc659c382011-01-21 10:59:30 +0000573 rc = tlan_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000575 pr_err("Could not set up device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 goto err_out_free_dev;
577 }
578
579 rc = register_netdev(dev);
580 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000581 pr_err("Could not register device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 goto err_out_uninit;
583 }
584
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400585
Sakari Ailusc659c382011-01-21 10:59:30 +0000586 tlan_devices_installed++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 boards_found++;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400588
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 /* pdev is NULL if this is an EISA device */
590 if (pdev)
591 tlan_have_pci++;
592 else {
Sakari Ailusc659c382011-01-21 10:59:30 +0000593 priv->next_device = tlan_eisa_devices;
594 tlan_eisa_devices = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 tlan_have_eisa++;
596 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400597
Joe Perches50624aa2011-03-01 06:56:33 +0000598 netdev_info(dev, "irq=%2d, io=%04x, %s, Rev. %d\n",
599 (int)dev->irq,
600 (int)dev->base_addr,
601 priv->adapter->device_label,
602 priv->adapter_rev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 return 0;
604
605err_out_uninit:
Sakari Ailusc659c382011-01-21 10:59:30 +0000606 pci_free_consistent(priv->pci_dev, priv->dma_size, priv->dma_storage,
607 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608err_out_free_dev:
609 free_netdev(dev);
610err_out_regions:
611#ifdef CONFIG_PCI
612 if (pdev)
613 pci_release_regions(pdev);
614#endif
615err_out:
616 if (pdev)
617 pci_disable_device(pdev);
618 return rc;
619}
620
621
Sakari Ailusc659c382011-01-21 10:59:30 +0000622static void tlan_eisa_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623{
624 struct net_device *dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000625 struct tlan_priv *priv;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400626
Sakari Ailusc659c382011-01-21 10:59:30 +0000627 while (tlan_have_eisa) {
628 dev = tlan_eisa_devices;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 priv = netdev_priv(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +0000630 if (priv->dma_storage) {
631 pci_free_consistent(priv->pci_dev, priv->dma_size,
632 priv->dma_storage,
633 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000635 release_region(dev->base_addr, 0x10);
636 unregister_netdev(dev);
637 tlan_eisa_devices = priv->next_device;
638 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 tlan_have_eisa--;
640 }
641}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400642
643
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644static void __exit tlan_exit(void)
645{
646 pci_unregister_driver(&tlan_driver);
647
648 if (tlan_have_eisa)
Sakari Ailusc659c382011-01-21 10:59:30 +0000649 tlan_eisa_cleanup();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651}
652
653
654/* Module loading/unloading */
655module_init(tlan_probe);
656module_exit(tlan_exit);
657
658
659
Sakari Ailusc659c382011-01-21 10:59:30 +0000660/**************************************************************
661 * tlan_eisa_probe
662 *
663 * Returns: 0 on success, 1 otherwise
664 *
665 * Parms: None
666 *
667 *
668 * This functions probes for EISA devices and calls
669 * TLan_probe1 when one is found.
670 *
671 *************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672
Sakari Ailusc659c382011-01-21 10:59:30 +0000673static void __init tlan_eisa_probe(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674{
Sakari Ailusc659c382011-01-21 10:59:30 +0000675 long ioaddr;
676 int rc = -ENODEV;
677 int irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 u16 device_id;
679
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400680 if (!EISA_bus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
682 return;
683 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400684
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 /* Loop through all slots of the EISA bus */
686 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400687
Sakari Ailusc659c382011-01-21 10:59:30 +0000688 TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
689 (int) ioaddr + 0xc80, inw(ioaddr + EISA_ID));
690 TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
691 (int) ioaddr + 0xc82, inw(ioaddr + EISA_ID2));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692
693
Sakari Ailusc659c382011-01-21 10:59:30 +0000694 TLAN_DBG(TLAN_DEBUG_PROBE,
695 "Probing for EISA adapter at IO: 0x%4x : ",
696 (int) ioaddr);
697 if (request_region(ioaddr, 0x10, tlan_signature) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 goto out;
699
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400700 if (inw(ioaddr + EISA_ID) != 0x110E) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 release_region(ioaddr, 0x10);
702 goto out;
703 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400704
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 device_id = inw(ioaddr + EISA_ID2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400706 if (device_id != 0x20F1 && device_id != 0x40F1) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000707 release_region(ioaddr, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 goto out;
709 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400710
Sakari Ailusc659c382011-01-21 10:59:30 +0000711 /* check if adapter is enabled */
712 if (inb(ioaddr + EISA_CR) != 0x1) {
713 release_region(ioaddr, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 goto out2;
715 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400716
717 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000718 pr_info("Found one\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719
720
721 /* Get irq from board */
Sakari Ailusc659c382011-01-21 10:59:30 +0000722 switch (inb(ioaddr + 0xcc0)) {
723 case(0x10):
724 irq = 5;
725 break;
726 case(0x20):
727 irq = 9;
728 break;
729 case(0x40):
730 irq = 10;
731 break;
732 case(0x80):
733 irq = 11;
734 break;
735 default:
736 goto out;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400737 }
738
739
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 /* Setup the newly found eisa adapter */
Sakari Ailusc659c382011-01-21 10:59:30 +0000741 rc = tlan_probe1(NULL, ioaddr, irq,
742 12, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400744
Sakari Ailusc659c382011-01-21 10:59:30 +0000745out:
746 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000747 pr_info("None found\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000748 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749
Sakari Ailusc659c382011-01-21 10:59:30 +0000750out2:
751 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000752 pr_info("Card found but it is not enabled, skipping\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000753 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400754
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755 }
756
Sakari Ailusc659c382011-01-21 10:59:30 +0000757}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758
759#ifdef CONFIG_NET_POLL_CONTROLLER
Sakari Ailusc659c382011-01-21 10:59:30 +0000760static void tlan_poll(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761{
762 disable_irq(dev->irq);
Sakari Ailusc659c382011-01-21 10:59:30 +0000763 tlan_handle_interrupt(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 enable_irq(dev->irq);
765}
766#endif
767
Sakari Ailusc659c382011-01-21 10:59:30 +0000768static const struct net_device_ops tlan_netdev_ops = {
769 .ndo_open = tlan_open,
770 .ndo_stop = tlan_close,
771 .ndo_start_xmit = tlan_start_tx,
772 .ndo_tx_timeout = tlan_tx_timeout,
773 .ndo_get_stats = tlan_get_stats,
Jiri Pirkoafc4b132011-08-16 06:29:01 +0000774 .ndo_set_rx_mode = tlan_set_multicast_list,
Sakari Ailusc659c382011-01-21 10:59:30 +0000775 .ndo_do_ioctl = tlan_ioctl,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800776 .ndo_change_mtu = eth_change_mtu,
Sakari Ailusc659c382011-01-21 10:59:30 +0000777 .ndo_set_mac_address = eth_mac_addr,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800778 .ndo_validate_addr = eth_validate_addr,
779#ifdef CONFIG_NET_POLL_CONTROLLER
Sakari Ailusc659c382011-01-21 10:59:30 +0000780 .ndo_poll_controller = tlan_poll,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800781#endif
782};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400783
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784
785
Sakari Ailusc659c382011-01-21 10:59:30 +0000786/***************************************************************
787 * tlan_init
788 *
789 * Returns:
790 * 0 on success, error code otherwise.
791 * Parms:
792 * dev The structure of the device to be
793 * init'ed.
794 *
795 * This function completes the initialization of the
796 * device structure and driver. It reserves the IO
797 * addresses, allocates memory for the lists and bounce
798 * buffers, retrieves the MAC address from the eeprom
799 * and assignes the device's methods.
800 *
801 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802
Sakari Ailusc659c382011-01-21 10:59:30 +0000803static int tlan_init(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804{
805 int dma_size;
Sakari Ailusc659c382011-01-21 10:59:30 +0000806 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +0000808 struct tlan_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809
810 priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400811
Sakari Ailusc659c382011-01-21 10:59:30 +0000812 dma_size = (TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS)
813 * (sizeof(struct tlan_list));
814 priv->dma_storage = pci_alloc_consistent(priv->pci_dev,
815 dma_size,
816 &priv->dma_storage_dma);
817 priv->dma_size = dma_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400818
Sakari Ailusc659c382011-01-21 10:59:30 +0000819 if (priv->dma_storage == NULL) {
Joe Perches50624aa2011-03-01 06:56:33 +0000820 pr_err("Could not allocate lists and buffers for %s\n",
Sakari Ailusc659c382011-01-21 10:59:30 +0000821 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700822 return -ENOMEM;
823 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000824 memset(priv->dma_storage, 0, dma_size);
825 priv->rx_list = (struct tlan_list *)
826 ALIGN((unsigned long)priv->dma_storage, 8);
827 priv->rx_list_dma = ALIGN(priv->dma_storage_dma, 8);
828 priv->tx_list = priv->rx_list + TLAN_NUM_RX_LISTS;
829 priv->tx_list_dma =
830 priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700831
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 err = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +0000833 for (i = 0; i < 6 ; i++)
834 err |= tlan_ee_read_byte(dev,
835 (u8) priv->adapter->addr_ofs + i,
836 (u8 *) &dev->dev_addr[i]);
837 if (err) {
Joe Perches50624aa2011-03-01 06:56:33 +0000838 pr_err("%s: Error reading MAC from eeprom: %d\n",
839 dev->name, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 }
841 dev->addr_len = 6;
842
843 netif_carrier_off(dev);
844
845 /* Device methods */
Sakari Ailusc659c382011-01-21 10:59:30 +0000846 dev->netdev_ops = &tlan_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 dev->watchdog_timeo = TX_TIMEOUT;
848
849 return 0;
850
Sakari Ailusc659c382011-01-21 10:59:30 +0000851}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852
853
854
855
Sakari Ailusc659c382011-01-21 10:59:30 +0000856/***************************************************************
857 * tlan_open
858 *
859 * Returns:
860 * 0 on success, error code otherwise.
861 * Parms:
862 * dev Structure of device to be opened.
863 *
864 * This routine puts the driver and TLAN adapter in a
865 * state where it is ready to send and receive packets.
866 * It allocates the IRQ, resets and brings the adapter
867 * out of reset, and allows interrupts. It also delays
868 * the startup for autonegotiation or sends a Rx GO
869 * command to the adapter, as appropriate.
870 *
871 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872
Sakari Ailusc659c382011-01-21 10:59:30 +0000873static int tlan_open(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874{
Sakari Ailusc659c382011-01-21 10:59:30 +0000875 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 int err;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400877
Sakari Ailusc659c382011-01-21 10:59:30 +0000878 priv->tlan_rev = tlan_dio_read8(dev->base_addr, TLAN_DEF_REVISION);
879 err = request_irq(dev->irq, tlan_handle_interrupt, IRQF_SHARED,
880 dev->name, dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400881
Sakari Ailusc659c382011-01-21 10:59:30 +0000882 if (err) {
Joe Perches50624aa2011-03-01 06:56:33 +0000883 netdev_err(dev, "Cannot open because IRQ %d is already in use\n",
884 dev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 return err;
886 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400887
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 init_timer(&priv->timer);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400889
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000890 tlan_start(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891
Sakari Ailusc659c382011-01-21 10:59:30 +0000892 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n",
893 dev->name, priv->tlan_rev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894
895 return 0;
896
Sakari Ailusc659c382011-01-21 10:59:30 +0000897}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898
899
900
Sakari Ailusc659c382011-01-21 10:59:30 +0000901/**************************************************************
902 * tlan_ioctl
903 *
904 * Returns:
905 * 0 on success, error code otherwise
906 * Params:
907 * dev structure of device to receive ioctl.
908 *
909 * rq ifreq structure to hold userspace data.
910 *
911 * cmd ioctl command.
912 *
913 *
914 *************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915
Sakari Ailusc659c382011-01-21 10:59:30 +0000916static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917{
Sakari Ailusc659c382011-01-21 10:59:30 +0000918 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 struct mii_ioctl_data *data = if_mii(rq);
Sakari Ailusc659c382011-01-21 10:59:30 +0000920 u32 phy = priv->phy[priv->phy_num];
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400921
Sakari Ailusc659c382011-01-21 10:59:30 +0000922 if (!priv->phy_online)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 return -EAGAIN;
924
Sakari Ailusc659c382011-01-21 10:59:30 +0000925 switch (cmd) {
926 case SIOCGMIIPHY: /* get address of MII PHY in use. */
927 data->phy_id = phy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928
929
Sakari Ailusc659c382011-01-21 10:59:30 +0000930 case SIOCGMIIREG: /* read MII PHY register. */
931 tlan_mii_read_reg(dev, data->phy_id & 0x1f,
932 data->reg_num & 0x1f, &data->val_out);
933 return 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400934
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935
Sakari Ailusc659c382011-01-21 10:59:30 +0000936 case SIOCSMIIREG: /* write MII PHY register. */
937 tlan_mii_write_reg(dev, data->phy_id & 0x1f,
938 data->reg_num & 0x1f, data->val_in);
939 return 0;
940 default:
941 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000943}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944
945
Sakari Ailusc659c382011-01-21 10:59:30 +0000946/***************************************************************
947 * tlan_tx_timeout
948 *
949 * Returns: nothing
950 *
951 * Params:
952 * dev structure of device which timed out
953 * during transmit.
954 *
955 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956
Sakari Ailusc659c382011-01-21 10:59:30 +0000957static void tlan_tx_timeout(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958{
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400959
Sakari Ailusc659c382011-01-21 10:59:30 +0000960 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400961
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 /* Ok so we timed out, lets see what we can do about it...*/
Sakari Ailusc659c382011-01-21 10:59:30 +0000963 tlan_free_lists(dev);
964 tlan_reset_lists(dev);
965 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
966 tlan_reset_adapter(dev);
Eric Dumazet1ae5dc32010-05-10 05:01:31 -0700967 dev->trans_start = jiffies; /* prevent tx timeout */
Sakari Ailusc659c382011-01-21 10:59:30 +0000968 netif_wake_queue(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969
970}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400971
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
Sakari Ailusc659c382011-01-21 10:59:30 +0000973/***************************************************************
974 * tlan_tx_timeout_work
975 *
976 * Returns: nothing
977 *
978 * Params:
979 * work work item of device which timed out
980 *
981 **************************************************************/
David Howellsc4028952006-11-22 14:57:56 +0000982
Sakari Ailusc659c382011-01-21 10:59:30 +0000983static void tlan_tx_timeout_work(struct work_struct *work)
David Howellsc4028952006-11-22 14:57:56 +0000984{
Sakari Ailusc659c382011-01-21 10:59:30 +0000985 struct tlan_priv *priv =
986 container_of(work, struct tlan_priv, tlan_tqueue);
David Howellsc4028952006-11-22 14:57:56 +0000987
Sakari Ailusc659c382011-01-21 10:59:30 +0000988 tlan_tx_timeout(priv->dev);
David Howellsc4028952006-11-22 14:57:56 +0000989}
990
991
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992
Sakari Ailusc659c382011-01-21 10:59:30 +0000993/***************************************************************
994 * tlan_start_tx
995 *
996 * Returns:
997 * 0 on success, non-zero on failure.
998 * Parms:
999 * skb A pointer to the sk_buff containing the
1000 * frame to be sent.
1001 * dev The device to send the data on.
1002 *
1003 * This function adds a frame to the Tx list to be sent
1004 * ASAP. First it verifies that the adapter is ready and
1005 * there is room in the queue. Then it sets up the next
1006 * available list, copies the frame to the corresponding
1007 * buffer. If the adapter Tx channel is idle, it gives
1008 * the adapter a Tx Go command on the list, otherwise it
1009 * sets the forward address of the previous list to point
1010 * to this one. Then it frees the sk_buff.
1011 *
1012 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013
Sakari Ailusc659c382011-01-21 10:59:30 +00001014static netdev_tx_t tlan_start_tx(struct sk_buff *skb, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015{
Sakari Ailusc659c382011-01-21 10:59:30 +00001016 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017 dma_addr_t tail_list_phys;
Sakari Ailusc659c382011-01-21 10:59:30 +00001018 struct tlan_list *tail_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019 unsigned long flags;
Sakari Ailus8953f122008-12-16 01:44:05 -08001020 unsigned int txlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021
Sakari Ailusc659c382011-01-21 10:59:30 +00001022 if (!priv->phy_online) {
1023 TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n",
1024 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 dev_kfree_skb_any(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001026 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 }
1028
Stephen Hemminger41873e92008-05-30 09:49:52 -07001029 if (skb_padto(skb, TLAN_MIN_FRAME_SIZE))
Patrick McHardy6ed10652009-06-23 06:03:08 +00001030 return NETDEV_TX_OK;
Sakari Ailus8953f122008-12-16 01:44:05 -08001031 txlen = max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE);
Stephen Hemminger41873e92008-05-30 09:49:52 -07001032
Sakari Ailusc659c382011-01-21 10:59:30 +00001033 tail_list = priv->tx_list + priv->tx_tail;
1034 tail_list_phys =
1035 priv->tx_list_dma + sizeof(struct tlan_list)*priv->tx_tail;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001036
Sakari Ailusc659c382011-01-21 10:59:30 +00001037 if (tail_list->c_stat != TLAN_CSTAT_UNUSED) {
1038 TLAN_DBG(TLAN_DEBUG_TX,
1039 "TRANSMIT: %s is busy (Head=%d Tail=%d)\n",
1040 dev->name, priv->tx_head, priv->tx_tail);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 netif_stop_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001042 priv->tx_busy_count++;
Patrick McHardy5b548142009-06-12 06:22:29 +00001043 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 }
1045
1046 tail_list->forward = 0;
1047
Sakari Ailusc659c382011-01-21 10:59:30 +00001048 tail_list->buffer[0].address = pci_map_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001049 skb->data, txlen,
1050 PCI_DMA_TODEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001051 tlan_store_skb(tail_list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052
Sakari Ailusc659c382011-01-21 10:59:30 +00001053 tail_list->frame_size = (u16) txlen;
Sakari Ailus8953f122008-12-16 01:44:05 -08001054 tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) txlen;
Stephen Hemminger41873e92008-05-30 09:49:52 -07001055 tail_list->buffer[1].count = 0;
1056 tail_list->buffer[1].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057
1058 spin_lock_irqsave(&priv->lock, flags);
Sakari Ailusc659c382011-01-21 10:59:30 +00001059 tail_list->c_stat = TLAN_CSTAT_READY;
1060 if (!priv->tx_in_progress) {
1061 priv->tx_in_progress = 1;
1062 TLAN_DBG(TLAN_DEBUG_TX,
1063 "TRANSMIT: Starting TX on buffer %d\n",
1064 priv->tx_tail);
1065 outl(tail_list_phys, dev->base_addr + TLAN_CH_PARM);
1066 outl(TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001068 TLAN_DBG(TLAN_DEBUG_TX,
1069 "TRANSMIT: Adding buffer %d to TX channel\n",
1070 priv->tx_tail);
1071 if (priv->tx_tail == 0) {
1072 (priv->tx_list + (TLAN_NUM_TX_LISTS - 1))->forward
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001073 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001075 (priv->tx_list + (priv->tx_tail - 1))->forward
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001076 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 }
1078 }
1079 spin_unlock_irqrestore(&priv->lock, flags);
1080
Sakari Ailusc659c382011-01-21 10:59:30 +00001081 CIRC_INC(priv->tx_tail, TLAN_NUM_TX_LISTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082
Patrick McHardy6ed10652009-06-23 06:03:08 +00001083 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084
Sakari Ailusc659c382011-01-21 10:59:30 +00001085}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086
1087
1088
1089
Sakari Ailusc659c382011-01-21 10:59:30 +00001090/***************************************************************
1091 * tlan_handle_interrupt
1092 *
1093 * Returns:
1094 * Nothing
1095 * Parms:
1096 * irq The line on which the interrupt
1097 * occurred.
1098 * dev_id A pointer to the device assigned to
1099 * this irq line.
1100 *
1101 * This function handles an interrupt generated by its
1102 * assigned TLAN adapter. The function deactivates
1103 * interrupts on its adapter, records the type of
1104 * interrupt, executes the appropriate subhandler, and
1105 * acknowdges the interrupt to the adapter (thus
1106 * re-enabling adapter interrupts.
1107 *
1108 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109
Sakari Ailusc659c382011-01-21 10:59:30 +00001110static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111{
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001112 struct net_device *dev = dev_id;
Sakari Ailusc659c382011-01-21 10:59:30 +00001113 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 u16 host_int;
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001115 u16 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116
1117 spin_lock(&priv->lock);
1118
Sakari Ailusc659c382011-01-21 10:59:30 +00001119 host_int = inw(dev->base_addr + TLAN_HOST_INT);
1120 type = (host_int & TLAN_HI_IT_MASK) >> 2;
1121 if (type) {
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001122 u32 ack;
1123 u32 host_cmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124
Sakari Ailusc659c382011-01-21 10:59:30 +00001125 outw(host_int, dev->base_addr + TLAN_HOST_INT);
1126 ack = tlan_int_vector[type](dev, host_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127
Sakari Ailusc659c382011-01-21 10:59:30 +00001128 if (ack) {
1129 host_cmd = TLAN_HC_ACK | ack | (type << 18);
1130 outl(host_cmd, dev->base_addr + TLAN_HOST_CMD);
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001131 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 }
1133
1134 spin_unlock(&priv->lock);
1135
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001136 return IRQ_RETVAL(type);
Sakari Ailusc659c382011-01-21 10:59:30 +00001137}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138
1139
1140
1141
Sakari Ailusc659c382011-01-21 10:59:30 +00001142/***************************************************************
1143 * tlan_close
1144 *
1145 * Returns:
1146 * An error code.
1147 * Parms:
1148 * dev The device structure of the device to
1149 * close.
1150 *
1151 * This function shuts down the adapter. It records any
1152 * stats, puts the adapter into reset state, deactivates
1153 * its time as needed, and frees the irq it is using.
1154 *
1155 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156
Sakari Ailusc659c382011-01-21 10:59:30 +00001157static int tlan_close(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158{
Sakari Ailusc659c382011-01-21 10:59:30 +00001159 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 priv->neg_be_verbose = 0;
Sakari Ailusfa6d5d42011-01-21 10:59:31 +00001162 tlan_stop(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001163
Sakari Ailusc659c382011-01-21 10:59:30 +00001164 free_irq(dev->irq, dev);
1165 tlan_free_lists(dev);
1166 TLAN_DBG(TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167
1168 return 0;
1169
Sakari Ailusc659c382011-01-21 10:59:30 +00001170}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171
1172
1173
1174
Sakari Ailusc659c382011-01-21 10:59:30 +00001175/***************************************************************
1176 * tlan_get_stats
1177 *
1178 * Returns:
1179 * A pointer to the device's statistics structure.
1180 * Parms:
1181 * dev The device structure to return the
1182 * stats for.
1183 *
1184 * This function updates the devices statistics by reading
1185 * the TLAN chip's onboard registers. Then it returns the
1186 * address of the statistics structure.
1187 *
1188 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189
Sakari Ailusc659c382011-01-21 10:59:30 +00001190static struct net_device_stats *tlan_get_stats(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191{
Sakari Ailusc659c382011-01-21 10:59:30 +00001192 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 int i;
1194
1195 /* Should only read stats if open ? */
Sakari Ailusc659c382011-01-21 10:59:30 +00001196 tlan_read_and_clear_stats(dev, TLAN_RECORD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197
Sakari Ailusc659c382011-01-21 10:59:30 +00001198 TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name,
1199 priv->rx_eoc_count);
1200 TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name,
1201 priv->tx_busy_count);
1202 if (debug & TLAN_DEBUG_GNRL) {
1203 tlan_print_dio(dev->base_addr);
1204 tlan_phy_print(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001206 if (debug & TLAN_DEBUG_LIST) {
1207 for (i = 0; i < TLAN_NUM_RX_LISTS; i++)
1208 tlan_print_list(priv->rx_list + i, "RX", i);
1209 for (i = 0; i < TLAN_NUM_TX_LISTS; i++)
1210 tlan_print_list(priv->tx_list + i, "TX", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001212
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001213 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214
Sakari Ailusc659c382011-01-21 10:59:30 +00001215}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216
1217
1218
1219
Sakari Ailusc659c382011-01-21 10:59:30 +00001220/***************************************************************
1221 * tlan_set_multicast_list
1222 *
1223 * Returns:
1224 * Nothing
1225 * Parms:
1226 * dev The device structure to set the
1227 * multicast list for.
1228 *
1229 * This function sets the TLAN adaptor to various receive
1230 * modes. If the IFF_PROMISC flag is set, promiscuous
1231 * mode is acitviated. Otherwise, promiscuous mode is
1232 * turned off. If the IFF_ALLMULTI flag is set, then
1233 * the hash table is set to receive all group addresses.
1234 * Otherwise, the first three multicast addresses are
1235 * stored in AREG_1-3, and the rest are selected via the
1236 * hash table, as necessary.
1237 *
1238 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239
Sakari Ailusc659c382011-01-21 10:59:30 +00001240static void tlan_set_multicast_list(struct net_device *dev)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001241{
Jiri Pirko22bedad32010-04-01 21:22:57 +00001242 struct netdev_hw_addr *ha;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 u32 hash1 = 0;
1244 u32 hash2 = 0;
1245 int i;
1246 u32 offset;
1247 u8 tmp;
1248
Sakari Ailusc659c382011-01-21 10:59:30 +00001249 if (dev->flags & IFF_PROMISC) {
1250 tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
1251 tlan_dio_write8(dev->base_addr,
1252 TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001254 tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
1255 tlan_dio_write8(dev->base_addr,
1256 TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF);
1257 if (dev->flags & IFF_ALLMULTI) {
1258 for (i = 0; i < 3; i++)
1259 tlan_set_mac(dev, i + 1, NULL);
1260 tlan_dio_write32(dev->base_addr, TLAN_HASH_1,
1261 0xffffffff);
1262 tlan_dio_write32(dev->base_addr, TLAN_HASH_2,
1263 0xffffffff);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264 } else {
Jiri Pirko567ec872010-02-23 23:17:07 +00001265 i = 0;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001266 netdev_for_each_mc_addr(ha, dev) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001267 if (i < 3) {
1268 tlan_set_mac(dev, i + 1,
Jiri Pirko22bedad32010-04-01 21:22:57 +00001269 (char *) &ha->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001271 offset =
1272 tlan_hash_func((u8 *)&ha->addr);
1273 if (offset < 32)
1274 hash1 |= (1 << offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275 else
Sakari Ailusc659c382011-01-21 10:59:30 +00001276 hash2 |= (1 << (offset - 32));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 }
Jiri Pirko567ec872010-02-23 23:17:07 +00001278 i++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001280 for ( ; i < 3; i++)
1281 tlan_set_mac(dev, i + 1, NULL);
1282 tlan_dio_write32(dev->base_addr, TLAN_HASH_1, hash1);
1283 tlan_dio_write32(dev->base_addr, TLAN_HASH_2, hash2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 }
1285 }
1286
Sakari Ailusc659c382011-01-21 10:59:30 +00001287}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288
1289
1290
1291/*****************************************************************************
1292******************************************************************************
1293
Sakari Ailusc659c382011-01-21 10:59:30 +00001294ThunderLAN driver interrupt vectors and table
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295
Sakari Ailusc659c382011-01-21 10:59:30 +00001296please see chap. 4, "Interrupt Handling" of the "ThunderLAN
1297Programmer's Guide" for more informations on handling interrupts
1298generated by TLAN based adapters.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299
1300******************************************************************************
1301*****************************************************************************/
1302
1303
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304
1305
Sakari Ailusc659c382011-01-21 10:59:30 +00001306/***************************************************************
1307 * tlan_handle_tx_eof
1308 *
1309 * Returns:
1310 * 1
1311 * Parms:
1312 * dev Device assigned the IRQ that was
1313 * raised.
1314 * host_int The contents of the HOST_INT
1315 * port.
1316 *
1317 * This function handles Tx EOF interrupts which are raised
1318 * by the adapter when it has completed sending the
1319 * contents of a buffer. If detemines which list/buffer
1320 * was completed and resets it. If the buffer was the last
1321 * in the channel (EOC), then the function checks to see if
1322 * another buffer is ready to send, and if so, sends a Tx
1323 * Go command. Finally, the driver activates/continues the
1324 * activity LED.
1325 *
1326 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327
Sakari Ailusc659c382011-01-21 10:59:30 +00001328static u32 tlan_handle_tx_eof(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329{
Sakari Ailusc659c382011-01-21 10:59:30 +00001330 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 int eoc = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001332 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 dma_addr_t head_list_phys;
1334 u32 ack = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001335 u16 tmp_c_stat;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001336
Sakari Ailusc659c382011-01-21 10:59:30 +00001337 TLAN_DBG(TLAN_DEBUG_TX,
1338 "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n",
1339 priv->tx_head, priv->tx_tail);
1340 head_list = priv->tx_list + priv->tx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341
Sakari Ailusc659c382011-01-21 10:59:30 +00001342 while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
1343 && (ack < 255)) {
1344 struct sk_buff *skb = tlan_get_skb(head_list);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001345
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 ack++;
Sakari Ailusc659c382011-01-21 10:59:30 +00001347 pci_unmap_single(priv->pci_dev, head_list->buffer[0].address,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001348 max(skb->len,
1349 (unsigned int)TLAN_MIN_FRAME_SIZE),
1350 PCI_DMA_TODEVICE);
1351 dev_kfree_skb_any(skb);
1352 head_list->buffer[8].address = 0;
1353 head_list->buffer[9].address = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001354
Sakari Ailusc659c382011-01-21 10:59:30 +00001355 if (tmp_c_stat & TLAN_CSTAT_EOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001357
Sakari Ailusc659c382011-01-21 10:59:30 +00001358 dev->stats.tx_bytes += head_list->frame_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359
Sakari Ailusc659c382011-01-21 10:59:30 +00001360 head_list->c_stat = TLAN_CSTAT_UNUSED;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001361 netif_start_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001362 CIRC_INC(priv->tx_head, TLAN_NUM_TX_LISTS);
1363 head_list = priv->tx_list + priv->tx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 }
1365
1366 if (!ack)
Joe Perches50624aa2011-03-01 06:56:33 +00001367 netdev_info(dev,
1368 "Received interrupt for uncompleted TX frame\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001369
Sakari Ailusc659c382011-01-21 10:59:30 +00001370 if (eoc) {
1371 TLAN_DBG(TLAN_DEBUG_TX,
1372 "TRANSMIT: handling TX EOC (Head=%d Tail=%d)\n",
1373 priv->tx_head, priv->tx_tail);
1374 head_list = priv->tx_list + priv->tx_head;
1375 head_list_phys = priv->tx_list_dma
1376 + sizeof(struct tlan_list)*priv->tx_head;
Sakari Ailusf45437e2011-02-09 10:25:06 +00001377 if ((head_list->c_stat & TLAN_CSTAT_READY)
1378 == TLAN_CSTAT_READY) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001379 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 ack |= TLAN_HC_GO;
1381 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001382 priv->tx_in_progress = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 }
1384 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001385
Sakari Ailusc659c382011-01-21 10:59:30 +00001386 if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
1387 tlan_dio_write8(dev->base_addr,
1388 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
1389 if (priv->timer.function == NULL) {
1390 priv->timer.function = tlan_timer;
1391 priv->timer.data = (unsigned long) dev;
1392 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1393 priv->timer_set_at = jiffies;
1394 priv->timer_type = TLAN_TIMER_ACTIVITY;
1395 add_timer(&priv->timer);
1396 } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
1397 priv->timer_set_at = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001398 }
1399 }
1400
1401 return ack;
1402
Sakari Ailusc659c382011-01-21 10:59:30 +00001403}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
1405
1406
1407
Sakari Ailusc659c382011-01-21 10:59:30 +00001408/***************************************************************
1409 * TLan_HandleStatOverflow
1410 *
1411 * Returns:
1412 * 1
1413 * Parms:
1414 * dev Device assigned the IRQ that was
1415 * raised.
1416 * host_int The contents of the HOST_INT
1417 * port.
1418 *
1419 * This function handles the Statistics Overflow interrupt
1420 * which means that one or more of the TLAN statistics
1421 * registers has reached 1/2 capacity and needs to be read.
1422 *
1423 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424
Sakari Ailusc659c382011-01-21 10:59:30 +00001425static u32 tlan_handle_stat_overflow(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426{
Sakari Ailusc659c382011-01-21 10:59:30 +00001427 tlan_read_and_clear_stats(dev, TLAN_RECORD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
1429 return 1;
1430
Sakari Ailusc659c382011-01-21 10:59:30 +00001431}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432
1433
1434
1435
Sakari Ailusc659c382011-01-21 10:59:30 +00001436/***************************************************************
1437 * TLan_HandleRxEOF
1438 *
1439 * Returns:
1440 * 1
1441 * Parms:
1442 * dev Device assigned the IRQ that was
1443 * raised.
1444 * host_int The contents of the HOST_INT
1445 * port.
1446 *
1447 * This function handles the Rx EOF interrupt which
1448 * indicates a frame has been received by the adapter from
1449 * the net and the frame has been transferred to memory.
1450 * The function determines the bounce buffer the frame has
1451 * been loaded into, creates a new sk_buff big enough to
1452 * hold the frame, and sends it to protocol stack. It
1453 * then resets the used buffer and appends it to the end
1454 * of the list. If the frame was the last in the Rx
1455 * channel (EOC), the function restarts the receive channel
1456 * by sending an Rx Go command to the adapter. Then it
1457 * activates/continues the activity LED.
1458 *
1459 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460
Sakari Ailusc659c382011-01-21 10:59:30 +00001461static u32 tlan_handle_rx_eof(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462{
Sakari Ailusc659c382011-01-21 10:59:30 +00001463 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 u32 ack = 0;
1465 int eoc = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001466 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 struct sk_buff *skb;
Sakari Ailusc659c382011-01-21 10:59:30 +00001468 struct tlan_list *tail_list;
1469 u16 tmp_c_stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 dma_addr_t head_list_phys;
1471
Sakari Ailusc659c382011-01-21 10:59:30 +00001472 TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: handling RX EOF (Head=%d Tail=%d)\n",
1473 priv->rx_head, priv->rx_tail);
1474 head_list = priv->rx_list + priv->rx_head;
1475 head_list_phys =
1476 priv->rx_list_dma + sizeof(struct tlan_list)*priv->rx_head;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001477
Sakari Ailusc659c382011-01-21 10:59:30 +00001478 while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
1479 && (ack < 255)) {
1480 dma_addr_t frame_dma = head_list->buffer[0].address;
1481 u32 frame_size = head_list->frame_size;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001482 struct sk_buff *new_skb;
1483
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 ack++;
Sakari Ailusc659c382011-01-21 10:59:30 +00001485 if (tmp_c_stat & TLAN_CSTAT_EOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001487
Eric Dumazet89d71a62009-10-13 05:34:20 +00001488 new_skb = netdev_alloc_skb_ip_align(dev,
1489 TLAN_MAX_FRAME_SIZE + 5);
Sakari Ailusc659c382011-01-21 10:59:30 +00001490 if (!new_skb)
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001491 goto drop_and_reuse;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001492
Sakari Ailusc659c382011-01-21 10:59:30 +00001493 skb = tlan_get_skb(head_list);
1494 pci_unmap_single(priv->pci_dev, frame_dma,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001495 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001496 skb_put(skb, frame_size);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001497
Sakari Ailusc659c382011-01-21 10:59:30 +00001498 dev->stats.rx_bytes += frame_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001499
Sakari Ailusc659c382011-01-21 10:59:30 +00001500 skb->protocol = eth_type_trans(skb, dev);
1501 netif_rx(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502
Sakari Ailusc659c382011-01-21 10:59:30 +00001503 head_list->buffer[0].address =
1504 pci_map_single(priv->pci_dev, new_skb->data,
1505 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506
Sakari Ailusc659c382011-01-21 10:59:30 +00001507 tlan_store_skb(head_list, new_skb);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001508drop_and_reuse:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 head_list->forward = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001510 head_list->c_stat = 0;
1511 tail_list = priv->rx_list + priv->rx_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 tail_list->forward = head_list_phys;
1513
Sakari Ailusc659c382011-01-21 10:59:30 +00001514 CIRC_INC(priv->rx_head, TLAN_NUM_RX_LISTS);
1515 CIRC_INC(priv->rx_tail, TLAN_NUM_RX_LISTS);
1516 head_list = priv->rx_list + priv->rx_head;
1517 head_list_phys = priv->rx_list_dma
1518 + sizeof(struct tlan_list)*priv->rx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519 }
1520
1521 if (!ack)
Joe Perches50624aa2011-03-01 06:56:33 +00001522 netdev_info(dev,
1523 "Received interrupt for uncompleted RX frame\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524
1525
Sakari Ailusc659c382011-01-21 10:59:30 +00001526 if (eoc) {
1527 TLAN_DBG(TLAN_DEBUG_RX,
1528 "RECEIVE: handling RX EOC (Head=%d Tail=%d)\n",
1529 priv->rx_head, priv->rx_tail);
1530 head_list = priv->rx_list + priv->rx_head;
1531 head_list_phys = priv->rx_list_dma
1532 + sizeof(struct tlan_list)*priv->rx_head;
1533 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 ack |= TLAN_HC_GO | TLAN_HC_RT;
Sakari Ailusc659c382011-01-21 10:59:30 +00001535 priv->rx_eoc_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 }
1537
Sakari Ailusc659c382011-01-21 10:59:30 +00001538 if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
1539 tlan_dio_write8(dev->base_addr,
1540 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
1541 if (priv->timer.function == NULL) {
1542 priv->timer.function = tlan_timer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 priv->timer.data = (unsigned long) dev;
1544 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
Sakari Ailusc659c382011-01-21 10:59:30 +00001545 priv->timer_set_at = jiffies;
1546 priv->timer_type = TLAN_TIMER_ACTIVITY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 add_timer(&priv->timer);
Sakari Ailusc659c382011-01-21 10:59:30 +00001548 } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
1549 priv->timer_set_at = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 }
1551 }
1552
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 return ack;
1554
Sakari Ailusc659c382011-01-21 10:59:30 +00001555}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556
1557
1558
1559
Sakari Ailusc659c382011-01-21 10:59:30 +00001560/***************************************************************
1561 * tlan_handle_dummy
1562 *
1563 * Returns:
1564 * 1
1565 * Parms:
1566 * dev Device assigned the IRQ that was
1567 * raised.
1568 * host_int The contents of the HOST_INT
1569 * port.
1570 *
1571 * This function handles the Dummy interrupt, which is
1572 * raised whenever a test interrupt is generated by setting
1573 * the Req_Int bit of HOST_CMD to 1.
1574 *
1575 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576
Sakari Ailusc659c382011-01-21 10:59:30 +00001577static u32 tlan_handle_dummy(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578{
Joe Perches50624aa2011-03-01 06:56:33 +00001579 netdev_info(dev, "Test interrupt\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580 return 1;
1581
Sakari Ailusc659c382011-01-21 10:59:30 +00001582}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583
1584
1585
1586
Sakari Ailusc659c382011-01-21 10:59:30 +00001587/***************************************************************
1588 * tlan_handle_tx_eoc
1589 *
1590 * Returns:
1591 * 1
1592 * Parms:
1593 * dev Device assigned the IRQ that was
1594 * raised.
1595 * host_int The contents of the HOST_INT
1596 * port.
1597 *
1598 * This driver is structured to determine EOC occurrences by
1599 * reading the CSTAT member of the list structure. Tx EOC
1600 * interrupts are disabled via the DIO INTDIS register.
1601 * However, TLAN chips before revision 3.0 didn't have this
1602 * functionality, so process EOC events if this is the
1603 * case.
1604 *
1605 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606
Sakari Ailusc659c382011-01-21 10:59:30 +00001607static u32 tlan_handle_tx_eoc(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608{
Sakari Ailusc659c382011-01-21 10:59:30 +00001609 struct tlan_priv *priv = netdev_priv(dev);
1610 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 dma_addr_t head_list_phys;
1612 u32 ack = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001613
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 host_int = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001615 if (priv->tlan_rev < 0x30) {
1616 TLAN_DBG(TLAN_DEBUG_TX,
1617 "TRANSMIT: handling TX EOC (Head=%d Tail=%d) -- IRQ\n",
1618 priv->tx_head, priv->tx_tail);
1619 head_list = priv->tx_list + priv->tx_head;
1620 head_list_phys = priv->tx_list_dma
1621 + sizeof(struct tlan_list)*priv->tx_head;
Sakari Ailusf45437e2011-02-09 10:25:06 +00001622 if ((head_list->c_stat & TLAN_CSTAT_READY)
1623 == TLAN_CSTAT_READY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001624 netif_stop_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001625 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 ack |= TLAN_HC_GO;
1627 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001628 priv->tx_in_progress = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 }
1630 }
1631
1632 return ack;
1633
Sakari Ailusc659c382011-01-21 10:59:30 +00001634}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001635
1636
1637
1638
Sakari Ailusc659c382011-01-21 10:59:30 +00001639/***************************************************************
1640 * tlan_handle_status_check
1641 *
1642 * Returns:
1643 * 0 if Adapter check, 1 if Network Status check.
1644 * Parms:
1645 * dev Device assigned the IRQ that was
1646 * raised.
1647 * host_int The contents of the HOST_INT
1648 * port.
1649 *
1650 * This function handles Adapter Check/Network Status
1651 * interrupts generated by the adapter. It checks the
1652 * vector in the HOST_INT register to determine if it is
1653 * an Adapter Check interrupt. If so, it resets the
1654 * adapter. Otherwise it clears the status registers
1655 * and services the PHY.
1656 *
1657 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658
Sakari Ailusc659c382011-01-21 10:59:30 +00001659static u32 tlan_handle_status_check(struct net_device *dev, u16 host_int)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001660{
Sakari Ailusc659c382011-01-21 10:59:30 +00001661 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 u32 ack;
1663 u32 error;
1664 u8 net_sts;
1665 u32 phy;
1666 u16 tlphy_ctl;
1667 u16 tlphy_sts;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001668
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 ack = 1;
Sakari Ailusc659c382011-01-21 10:59:30 +00001670 if (host_int & TLAN_HI_IV_MASK) {
1671 netif_stop_queue(dev);
1672 error = inl(dev->base_addr + TLAN_CH_PARM);
Joe Perches50624aa2011-03-01 06:56:33 +00001673 netdev_info(dev, "Adaptor Error = 0x%x\n", error);
Sakari Ailusc659c382011-01-21 10:59:30 +00001674 tlan_read_and_clear_stats(dev, TLAN_RECORD);
1675 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676
1677 schedule_work(&priv->tlan_tqueue);
1678
1679 netif_wake_queue(dev);
1680 ack = 0;
1681 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001682 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name);
1683 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001684
Sakari Ailusc659c382011-01-21 10:59:30 +00001685 net_sts = tlan_dio_read8(dev->base_addr, TLAN_NET_STS);
1686 if (net_sts) {
1687 tlan_dio_write8(dev->base_addr, TLAN_NET_STS, net_sts);
1688 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n",
1689 dev->name, (unsigned) net_sts);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001691 if ((net_sts & TLAN_NET_STS_MIRQ) && (priv->phy_num == 0)) {
1692 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_STS, &tlphy_sts);
1693 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
1694 if (!(tlphy_sts & TLAN_TS_POLOK) &&
1695 !(tlphy_ctl & TLAN_TC_SWAPOL)) {
1696 tlphy_ctl |= TLAN_TC_SWAPOL;
1697 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
1698 tlphy_ctl);
1699 } else if ((tlphy_sts & TLAN_TS_POLOK) &&
1700 (tlphy_ctl & TLAN_TC_SWAPOL)) {
1701 tlphy_ctl &= ~TLAN_TC_SWAPOL;
1702 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
1703 tlphy_ctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001705
1706 if (debug)
1707 tlan_phy_print(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 }
1709 }
1710
1711 return ack;
1712
Sakari Ailusc659c382011-01-21 10:59:30 +00001713}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714
1715
1716
1717
Sakari Ailusc659c382011-01-21 10:59:30 +00001718/***************************************************************
1719 * tlan_handle_rx_eoc
1720 *
1721 * Returns:
1722 * 1
1723 * Parms:
1724 * dev Device assigned the IRQ that was
1725 * raised.
1726 * host_int The contents of the HOST_INT
1727 * port.
1728 *
1729 * This driver is structured to determine EOC occurrences by
1730 * reading the CSTAT member of the list structure. Rx EOC
1731 * interrupts are disabled via the DIO INTDIS register.
1732 * However, TLAN chips before revision 3.0 didn't have this
1733 * CSTAT member or a INTDIS register, so if this chip is
1734 * pre-3.0, process EOC interrupts normally.
1735 *
1736 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737
Sakari Ailusc659c382011-01-21 10:59:30 +00001738static u32 tlan_handle_rx_eoc(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739{
Sakari Ailusc659c382011-01-21 10:59:30 +00001740 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 dma_addr_t head_list_phys;
1742 u32 ack = 1;
1743
Sakari Ailusc659c382011-01-21 10:59:30 +00001744 if (priv->tlan_rev < 0x30) {
1745 TLAN_DBG(TLAN_DEBUG_RX,
1746 "RECEIVE: Handling RX EOC (head=%d tail=%d) -- IRQ\n",
1747 priv->rx_head, priv->rx_tail);
1748 head_list_phys = priv->rx_list_dma
1749 + sizeof(struct tlan_list)*priv->rx_head;
1750 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 ack |= TLAN_HC_GO | TLAN_HC_RT;
Sakari Ailusc659c382011-01-21 10:59:30 +00001752 priv->rx_eoc_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 }
1754
1755 return ack;
1756
Sakari Ailusc659c382011-01-21 10:59:30 +00001757}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758
1759
1760
1761
1762/*****************************************************************************
1763******************************************************************************
1764
Sakari Ailusc659c382011-01-21 10:59:30 +00001765ThunderLAN driver timer function
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766
1767******************************************************************************
1768*****************************************************************************/
1769
1770
Sakari Ailusc659c382011-01-21 10:59:30 +00001771/***************************************************************
1772 * tlan_timer
1773 *
1774 * Returns:
1775 * Nothing
1776 * Parms:
1777 * data A value given to add timer when
1778 * add_timer was called.
1779 *
1780 * This function handles timed functionality for the
1781 * TLAN driver. The two current timer uses are for
1782 * delaying for autonegotionation and driving the ACT LED.
1783 * - Autonegotiation requires being allowed about
1784 * 2 1/2 seconds before attempting to transmit a
1785 * packet. It would be a very bad thing to hang
1786 * the kernel this long, so the driver doesn't
1787 * allow transmission 'til after this time, for
1788 * certain PHYs. It would be much nicer if all
1789 * PHYs were interrupt-capable like the internal
1790 * PHY.
1791 * - The ACT LED, which shows adapter activity, is
1792 * driven by the driver, and so must be left on
1793 * for a short period to power up the LED so it
1794 * can be seen. This delay can be changed by
1795 * changing the TLAN_TIMER_ACT_DELAY in tlan.h,
1796 * if desired. 100 ms produces a slightly
1797 * sluggish response.
1798 *
1799 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800
Sakari Ailusc659c382011-01-21 10:59:30 +00001801static void tlan_timer(unsigned long data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802{
1803 struct net_device *dev = (struct net_device *) data;
Sakari Ailusc659c382011-01-21 10:59:30 +00001804 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 u32 elapsed;
1806 unsigned long flags = 0;
1807
1808 priv->timer.function = NULL;
1809
Sakari Ailusc659c382011-01-21 10:59:30 +00001810 switch (priv->timer_type) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001811#ifdef MONITOR
Sakari Ailusc659c382011-01-21 10:59:30 +00001812 case TLAN_TIMER_LINK_BEAT:
1813 tlan_phy_monitor(dev);
1814 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815#endif
Sakari Ailusc659c382011-01-21 10:59:30 +00001816 case TLAN_TIMER_PHY_PDOWN:
1817 tlan_phy_power_down(dev);
1818 break;
1819 case TLAN_TIMER_PHY_PUP:
1820 tlan_phy_power_up(dev);
1821 break;
1822 case TLAN_TIMER_PHY_RESET:
1823 tlan_phy_reset(dev);
1824 break;
1825 case TLAN_TIMER_PHY_START_LINK:
1826 tlan_phy_start_link(dev);
1827 break;
1828 case TLAN_TIMER_PHY_FINISH_AN:
1829 tlan_phy_finish_auto_neg(dev);
1830 break;
1831 case TLAN_TIMER_FINISH_RESET:
1832 tlan_finish_reset(dev);
1833 break;
1834 case TLAN_TIMER_ACTIVITY:
1835 spin_lock_irqsave(&priv->lock, flags);
1836 if (priv->timer.function == NULL) {
1837 elapsed = jiffies - priv->timer_set_at;
1838 if (elapsed >= TLAN_TIMER_ACT_DELAY) {
1839 tlan_dio_write8(dev->base_addr,
1840 TLAN_LED_REG, TLAN_LED_LINK);
1841 } else {
1842 priv->timer.function = tlan_timer;
1843 priv->timer.expires = priv->timer_set_at
1844 + TLAN_TIMER_ACT_DELAY;
1845 spin_unlock_irqrestore(&priv->lock, flags);
1846 add_timer(&priv->timer);
1847 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001849 }
1850 spin_unlock_irqrestore(&priv->lock, flags);
1851 break;
1852 default:
1853 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 }
1855
Sakari Ailusc659c382011-01-21 10:59:30 +00001856}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857
1858
1859
1860
1861/*****************************************************************************
1862******************************************************************************
1863
Sakari Ailusc659c382011-01-21 10:59:30 +00001864ThunderLAN driver adapter related routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865
1866******************************************************************************
1867*****************************************************************************/
1868
1869
Sakari Ailusc659c382011-01-21 10:59:30 +00001870/***************************************************************
1871 * tlan_reset_lists
1872 *
1873 * Returns:
1874 * Nothing
1875 * Parms:
1876 * dev The device structure with the list
1877 * stuctures to be reset.
1878 *
1879 * This routine sets the variables associated with managing
1880 * the TLAN lists to their initial values.
1881 *
1882 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883
Sakari Ailusc659c382011-01-21 10:59:30 +00001884static void tlan_reset_lists(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885{
Sakari Ailusc659c382011-01-21 10:59:30 +00001886 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +00001888 struct tlan_list *list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 dma_addr_t list_phys;
1890 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891
Sakari Ailusc659c382011-01-21 10:59:30 +00001892 priv->tx_head = 0;
1893 priv->tx_tail = 0;
1894 for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
1895 list = priv->tx_list + i;
1896 list->c_stat = TLAN_CSTAT_UNUSED;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001897 list->buffer[0].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 list->buffer[2].count = 0;
1899 list->buffer[2].address = 0;
1900 list->buffer[8].address = 0;
1901 list->buffer[9].address = 0;
1902 }
1903
Sakari Ailusc659c382011-01-21 10:59:30 +00001904 priv->rx_head = 0;
1905 priv->rx_tail = TLAN_NUM_RX_LISTS - 1;
1906 for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
1907 list = priv->rx_list + i;
1908 list_phys = priv->rx_list_dma + sizeof(struct tlan_list)*i;
1909 list->c_stat = TLAN_CSTAT_READY;
1910 list->frame_size = TLAN_MAX_FRAME_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
Eric Dumazet89d71a62009-10-13 05:34:20 +00001912 skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5);
Joe Perches720a43e2013-03-08 15:03:25 +00001913 if (!skb)
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001914 break;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001915
Sakari Ailusc659c382011-01-21 10:59:30 +00001916 list->buffer[0].address = pci_map_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001917 skb->data,
1918 TLAN_MAX_FRAME_SIZE,
1919 PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001920 tlan_store_skb(list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 list->buffer[1].count = 0;
1922 list->buffer[1].address = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001923 list->forward = list_phys + sizeof(struct tlan_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 }
1925
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001926 /* in case ran out of memory early, clear bits */
1927 while (i < TLAN_NUM_RX_LISTS) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001928 tlan_store_skb(priv->rx_list + i, NULL);
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001929 ++i;
1930 }
1931 list->forward = 0;
1932
Sakari Ailusc659c382011-01-21 10:59:30 +00001933}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934
1935
Sakari Ailusc659c382011-01-21 10:59:30 +00001936static void tlan_free_lists(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001937{
Sakari Ailusc659c382011-01-21 10:59:30 +00001938 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +00001940 struct tlan_list *list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941 struct sk_buff *skb;
1942
Sakari Ailusc659c382011-01-21 10:59:30 +00001943 for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
1944 list = priv->tx_list + i;
1945 skb = tlan_get_skb(list);
1946 if (skb) {
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001947 pci_unmap_single(
Sakari Ailusc659c382011-01-21 10:59:30 +00001948 priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001949 list->buffer[0].address,
1950 max(skb->len,
1951 (unsigned int)TLAN_MIN_FRAME_SIZE),
1952 PCI_DMA_TODEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001953 dev_kfree_skb_any(skb);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001954 list->buffer[8].address = 0;
1955 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 }
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001957 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958
Sakari Ailusc659c382011-01-21 10:59:30 +00001959 for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
1960 list = priv->rx_list + i;
1961 skb = tlan_get_skb(list);
1962 if (skb) {
1963 pci_unmap_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001964 list->buffer[0].address,
1965 TLAN_MAX_FRAME_SIZE,
1966 PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001967 dev_kfree_skb_any(skb);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001968 list->buffer[8].address = 0;
1969 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001970 }
1971 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001972}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973
1974
1975
1976
Sakari Ailusc659c382011-01-21 10:59:30 +00001977/***************************************************************
1978 * tlan_print_dio
1979 *
1980 * Returns:
1981 * Nothing
1982 * Parms:
1983 * io_base Base IO port of the device of
1984 * which to print DIO registers.
1985 *
1986 * This function prints out all the internal (DIO)
1987 * registers of a TLAN chip.
1988 *
1989 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990
Sakari Ailusc659c382011-01-21 10:59:30 +00001991static void tlan_print_dio(u16 io_base)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992{
1993 u32 data0, data1;
1994 int i;
1995
Joe Perches50624aa2011-03-01 06:56:33 +00001996 pr_info("Contents of internal registers for io base 0x%04hx\n",
1997 io_base);
1998 pr_info("Off. +0 +4\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00001999 for (i = 0; i < 0x4C; i += 8) {
2000 data0 = tlan_dio_read32(io_base, i);
2001 data1 = tlan_dio_read32(io_base, i + 0x4);
Joe Perches50624aa2011-03-01 06:56:33 +00002002 pr_info("0x%02x 0x%08x 0x%08x\n", i, data0, data1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003 }
2004
Sakari Ailusc659c382011-01-21 10:59:30 +00002005}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006
2007
2008
2009
Sakari Ailusc659c382011-01-21 10:59:30 +00002010/***************************************************************
2011 * TLan_PrintList
2012 *
2013 * Returns:
2014 * Nothing
2015 * Parms:
2016 * list A pointer to the struct tlan_list structure to
2017 * be printed.
2018 * type A string to designate type of list,
2019 * "Rx" or "Tx".
2020 * num The index of the list.
2021 *
2022 * This function prints out the contents of the list
2023 * pointed to by the list parameter.
2024 *
2025 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026
Sakari Ailusc659c382011-01-21 10:59:30 +00002027static void tlan_print_list(struct tlan_list *list, char *type, int num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028{
2029 int i;
2030
Joe Perches50624aa2011-03-01 06:56:33 +00002031 pr_info("%s List %d at %p\n", type, num, list);
2032 pr_info(" Forward = 0x%08x\n", list->forward);
2033 pr_info(" CSTAT = 0x%04hx\n", list->c_stat);
2034 pr_info(" Frame Size = 0x%04hx\n", list->frame_size);
Sakari Ailusc659c382011-01-21 10:59:30 +00002035 /* for (i = 0; i < 10; i++) { */
2036 for (i = 0; i < 2; i++) {
Joe Perches50624aa2011-03-01 06:56:33 +00002037 pr_info(" Buffer[%d].count, addr = 0x%08x, 0x%08x\n",
2038 i, list->buffer[i].count, list->buffer[i].address);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039 }
2040
Sakari Ailusc659c382011-01-21 10:59:30 +00002041}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042
2043
2044
2045
Sakari Ailusc659c382011-01-21 10:59:30 +00002046/***************************************************************
2047 * tlan_read_and_clear_stats
2048 *
2049 * Returns:
2050 * Nothing
2051 * Parms:
2052 * dev Pointer to device structure of adapter
2053 * to which to read stats.
2054 * record Flag indicating whether to add
2055 *
2056 * This functions reads all the internal status registers
2057 * of the TLAN chip, which clears them as a side effect.
2058 * It then either adds the values to the device's status
2059 * struct, or discards them, depending on whether record
2060 * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0).
2061 *
2062 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063
Sakari Ailusc659c382011-01-21 10:59:30 +00002064static void tlan_read_and_clear_stats(struct net_device *dev, int record)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066 u32 tx_good, tx_under;
2067 u32 rx_good, rx_over;
2068 u32 def_tx, crc, code;
2069 u32 multi_col, single_col;
2070 u32 excess_col, late_col, loss;
2071
Sakari Ailusc659c382011-01-21 10:59:30 +00002072 outw(TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR);
2073 tx_good = inb(dev->base_addr + TLAN_DIO_DATA);
2074 tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2075 tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
2076 tx_under = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077
Sakari Ailusc659c382011-01-21 10:59:30 +00002078 outw(TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR);
2079 rx_good = inb(dev->base_addr + TLAN_DIO_DATA);
2080 rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2081 rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
2082 rx_over = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002083
Sakari Ailusc659c382011-01-21 10:59:30 +00002084 outw(TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR);
2085 def_tx = inb(dev->base_addr + TLAN_DIO_DATA);
2086 def_tx += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2087 crc = inb(dev->base_addr + TLAN_DIO_DATA + 2);
2088 code = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002089
Sakari Ailusc659c382011-01-21 10:59:30 +00002090 outw(TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
2091 multi_col = inb(dev->base_addr + TLAN_DIO_DATA);
2092 multi_col += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2093 single_col = inb(dev->base_addr + TLAN_DIO_DATA + 2);
2094 single_col += inb(dev->base_addr + TLAN_DIO_DATA + 3) << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095
Sakari Ailusc659c382011-01-21 10:59:30 +00002096 outw(TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
2097 excess_col = inb(dev->base_addr + TLAN_DIO_DATA);
2098 late_col = inb(dev->base_addr + TLAN_DIO_DATA + 1);
2099 loss = inb(dev->base_addr + TLAN_DIO_DATA + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100
Sakari Ailusc659c382011-01-21 10:59:30 +00002101 if (record) {
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002102 dev->stats.rx_packets += rx_good;
2103 dev->stats.rx_errors += rx_over + crc + code;
2104 dev->stats.tx_packets += tx_good;
2105 dev->stats.tx_errors += tx_under + loss;
Sakari Ailusc659c382011-01-21 10:59:30 +00002106 dev->stats.collisions += multi_col
2107 + single_col + excess_col + late_col;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002109 dev->stats.rx_over_errors += rx_over;
2110 dev->stats.rx_crc_errors += crc;
2111 dev->stats.rx_frame_errors += code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002113 dev->stats.tx_aborted_errors += tx_under;
2114 dev->stats.tx_carrier_errors += loss;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002116
Sakari Ailusc659c382011-01-21 10:59:30 +00002117}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118
2119
2120
2121
Sakari Ailusc659c382011-01-21 10:59:30 +00002122/***************************************************************
2123 * TLan_Reset
2124 *
2125 * Returns:
2126 * 0
2127 * Parms:
2128 * dev Pointer to device structure of adapter
2129 * to be reset.
2130 *
2131 * This function resets the adapter and it's physical
2132 * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
2133 * Programmer's Guide" for details. The routine tries to
2134 * implement what is detailed there, though adjustments
2135 * have been made.
2136 *
2137 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138
Harvey Harrison98e0f522008-02-18 10:04:38 -08002139static void
Sakari Ailusc659c382011-01-21 10:59:30 +00002140tlan_reset_adapter(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141{
Sakari Ailusc659c382011-01-21 10:59:30 +00002142 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 int i;
2144 u32 addr;
2145 u32 data;
2146 u8 data8;
2147
Sakari Ailusc659c382011-01-21 10:59:30 +00002148 priv->tlan_full_duplex = false;
2149 priv->phy_online = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002150 netif_carrier_off(dev);
2151
2152/* 1. Assert reset bit. */
2153
2154 data = inl(dev->base_addr + TLAN_HOST_CMD);
2155 data |= TLAN_HC_AD_RST;
2156 outl(data, dev->base_addr + TLAN_HOST_CMD);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002157
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 udelay(1000);
2159
Sakari Ailusc659c382011-01-21 10:59:30 +00002160/* 2. Turn off interrupts. (Probably isn't necessary) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161
2162 data = inl(dev->base_addr + TLAN_HOST_CMD);
2163 data |= TLAN_HC_INT_OFF;
2164 outl(data, dev->base_addr + TLAN_HOST_CMD);
2165
2166/* 3. Clear AREGs and HASHs. */
2167
Sakari Ailusc659c382011-01-21 10:59:30 +00002168 for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4)
2169 tlan_dio_write32(dev->base_addr, (u16) i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170
2171/* 4. Setup NetConfig register. */
2172
2173 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
Sakari Ailusc659c382011-01-21 10:59:30 +00002174 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175
2176/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
2177
Sakari Ailusc659c382011-01-21 10:59:30 +00002178 outl(TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD);
2179 outl(TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180
2181/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
2182
Sakari Ailusc659c382011-01-21 10:59:30 +00002183 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184 addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Sakari Ailusc659c382011-01-21 10:59:30 +00002185 tlan_set_bit(TLAN_NET_SIO_NMRST, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186
2187/* 7. Setup the remaining registers. */
2188
Sakari Ailusc659c382011-01-21 10:59:30 +00002189 if (priv->tlan_rev >= 0x30) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002190 data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
Sakari Ailusc659c382011-01-21 10:59:30 +00002191 tlan_dio_write8(dev->base_addr, TLAN_INT_DIS, data8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002193 tlan_phy_detect(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002195
Sakari Ailusc659c382011-01-21 10:59:30 +00002196 if (priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197 data |= TLAN_NET_CFG_BIT;
Sakari Ailusc659c382011-01-21 10:59:30 +00002198 if (priv->aui == 1) {
2199 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x0a);
2200 } else if (priv->duplex == TLAN_DUPLEX_FULL) {
2201 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x00);
2202 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002204 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x08);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205 }
2206 }
2207
Sakari Ailusc659c382011-01-21 10:59:30 +00002208 if (priv->phy_num == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 data |= TLAN_NET_CFG_PHY_EN;
Sakari Ailusc659c382011-01-21 10:59:30 +00002210 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211
Sakari Ailusc659c382011-01-21 10:59:30 +00002212 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY)
2213 tlan_finish_reset(dev);
2214 else
2215 tlan_phy_power_down(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216
Sakari Ailusc659c382011-01-21 10:59:30 +00002217}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218
2219
2220
2221
Harvey Harrison98e0f522008-02-18 10:04:38 -08002222static void
Sakari Ailusc659c382011-01-21 10:59:30 +00002223tlan_finish_reset(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224{
Sakari Ailusc659c382011-01-21 10:59:30 +00002225 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226 u8 data;
2227 u32 phy;
2228 u8 sio;
2229 u16 status;
2230 u16 partner;
2231 u16 tlphy_ctl;
Sakari Ailusc659c382011-01-21 10:59:30 +00002232 u16 tlphy_par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233 u16 tlphy_id1, tlphy_id2;
Sakari Ailusc659c382011-01-21 10:59:30 +00002234 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235
Sakari Ailusc659c382011-01-21 10:59:30 +00002236 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237
2238 data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
Sakari Ailusc659c382011-01-21 10:59:30 +00002239 if (priv->tlan_full_duplex)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240 data |= TLAN_NET_CMD_DUPLEX;
Sakari Ailusc659c382011-01-21 10:59:30 +00002241 tlan_dio_write8(dev->base_addr, TLAN_NET_CMD, data);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002242 data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
Sakari Ailusc659c382011-01-21 10:59:30 +00002243 if (priv->phy_num == 0)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002244 data |= TLAN_NET_MASK_MASK7;
Sakari Ailusc659c382011-01-21 10:59:30 +00002245 tlan_dio_write8(dev->base_addr, TLAN_NET_MASK, data);
2246 tlan_dio_write16(dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7);
2247 tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &tlphy_id1);
2248 tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &tlphy_id2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002249
Sakari Ailusc659c382011-01-21 10:59:30 +00002250 if ((priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) ||
2251 (priv->aui)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252 status = MII_GS_LINK;
Joe Perches50624aa2011-03-01 06:56:33 +00002253 netdev_info(dev, "Link forced\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002255 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2256 udelay(1000);
2257 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2258 if ((status & MII_GS_LINK) &&
2259 /* We only support link info on Nat.Sem. PHY's */
2260 (tlphy_id1 == NAT_SEM_ID1) &&
2261 (tlphy_id2 == NAT_SEM_ID2)) {
2262 tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner);
2263 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002264
Joe Perches50624aa2011-03-01 06:56:33 +00002265 netdev_info(dev,
2266 "Link active with %s %uMbps %s-Duplex\n",
2267 !(tlphy_par & TLAN_PHY_AN_EN_STAT)
2268 ? "forced" : "Autonegotiation enabled,",
2269 tlphy_par & TLAN_PHY_SPEED_100
2270 ? 100 : 10,
2271 tlphy_par & TLAN_PHY_DUPLEX_FULL
2272 ? "Full" : "Half");
2273
2274 if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
2275 netdev_info(dev, "Partner capability:");
2276 for (i = 5; i < 10; i++)
2277 if (partner & (1 << i))
2278 pr_cont(" %s", media[i-5]);
2279 pr_cont("\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280 }
2281
Sakari Ailusc659c382011-01-21 10:59:30 +00002282 tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
2283 TLAN_LED_LINK);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002284#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285 /* We have link beat..for now anyway */
Sakari Ailusc659c382011-01-21 10:59:30 +00002286 priv->link = 1;
2287 /*Enabling link beat monitoring */
2288 tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002289#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290 } else if (status & MII_GS_LINK) {
Joe Perches50624aa2011-03-01 06:56:33 +00002291 netdev_info(dev, "Link active\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002292 tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
2293 TLAN_LED_LINK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294 }
2295 }
2296
Sakari Ailusc659c382011-01-21 10:59:30 +00002297 if (priv->phy_num == 0) {
2298 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
2299 tlphy_ctl |= TLAN_TC_INTEN;
2300 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
2301 sio = tlan_dio_read8(dev->base_addr, TLAN_NET_SIO);
2302 sio |= TLAN_NET_SIO_MINTEN;
2303 tlan_dio_write8(dev->base_addr, TLAN_NET_SIO, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304 }
2305
Sakari Ailusc659c382011-01-21 10:59:30 +00002306 if (status & MII_GS_LINK) {
2307 tlan_set_mac(dev, 0, dev->dev_addr);
2308 priv->phy_online = 1;
2309 outb((TLAN_HC_INT_ON >> 8), dev->base_addr + TLAN_HOST_CMD + 1);
2310 if (debug >= 1 && debug != TLAN_DEBUG_PROBE)
2311 outb((TLAN_HC_REQ_INT >> 8),
2312 dev->base_addr + TLAN_HOST_CMD + 1);
2313 outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM);
2314 outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 netif_carrier_on(dev);
2316 } else {
Joe Perches50624aa2011-03-01 06:56:33 +00002317 netdev_info(dev, "Link inactive, will retry in 10 secs...\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002318 tlan_set_timer(dev, (10*HZ), TLAN_TIMER_FINISH_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 return;
2320 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002321 tlan_set_multicast_list(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322
Sakari Ailusc659c382011-01-21 10:59:30 +00002323}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324
2325
2326
2327
Sakari Ailusc659c382011-01-21 10:59:30 +00002328/***************************************************************
2329 * tlan_set_mac
2330 *
2331 * Returns:
2332 * Nothing
2333 * Parms:
2334 * dev Pointer to device structure of adapter
2335 * on which to change the AREG.
2336 * areg The AREG to set the address in (0 - 3).
2337 * mac A pointer to an array of chars. Each
2338 * element stores one byte of the address.
2339 * IE, it isn't in ascii.
2340 *
2341 * This function transfers a MAC address to one of the
2342 * TLAN AREGs (address registers). The TLAN chip locks
2343 * the register on writing to offset 0 and unlocks the
2344 * register after writing to offset 5. If NULL is passed
2345 * in mac, then the AREG is filled with 0's.
2346 *
2347 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348
Sakari Ailusc659c382011-01-21 10:59:30 +00002349static void tlan_set_mac(struct net_device *dev, int areg, char *mac)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350{
2351 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002352
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353 areg *= 6;
2354
Sakari Ailusc659c382011-01-21 10:59:30 +00002355 if (mac != NULL) {
2356 for (i = 0; i < 6; i++)
2357 tlan_dio_write8(dev->base_addr,
2358 TLAN_AREG_0 + areg + i, mac[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002360 for (i = 0; i < 6; i++)
2361 tlan_dio_write8(dev->base_addr,
2362 TLAN_AREG_0 + areg + i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363 }
2364
Sakari Ailusc659c382011-01-21 10:59:30 +00002365}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366
2367
2368
2369
2370/*****************************************************************************
2371******************************************************************************
2372
Sakari Ailusc659c382011-01-21 10:59:30 +00002373ThunderLAN driver PHY layer routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374
2375******************************************************************************
2376*****************************************************************************/
2377
2378
2379
Sakari Ailusc659c382011-01-21 10:59:30 +00002380/*********************************************************************
2381 * tlan_phy_print
2382 *
2383 * Returns:
2384 * Nothing
2385 * Parms:
2386 * dev A pointer to the device structure of the
2387 * TLAN device having the PHYs to be detailed.
2388 *
2389 * This function prints the registers a PHY (aka transceiver).
2390 *
2391 ********************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392
Sakari Ailusc659c382011-01-21 10:59:30 +00002393static void tlan_phy_print(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394{
Sakari Ailusc659c382011-01-21 10:59:30 +00002395 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396 u16 i, data0, data1, data2, data3, phy;
2397
Sakari Ailusc659c382011-01-21 10:59:30 +00002398 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399
Sakari Ailusc659c382011-01-21 10:59:30 +00002400 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
Joe Perches50624aa2011-03-01 06:56:33 +00002401 netdev_info(dev, "Unmanaged PHY\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002402 } else if (phy <= TLAN_PHY_MAX_ADDR) {
Joe Perches50624aa2011-03-01 06:56:33 +00002403 netdev_info(dev, "PHY 0x%02x\n", phy);
2404 pr_info(" Off. +0 +1 +2 +3\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002405 for (i = 0; i < 0x20; i += 4) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002406 tlan_mii_read_reg(dev, phy, i, &data0);
Sakari Ailusc659c382011-01-21 10:59:30 +00002407 tlan_mii_read_reg(dev, phy, i + 1, &data1);
Sakari Ailusc659c382011-01-21 10:59:30 +00002408 tlan_mii_read_reg(dev, phy, i + 2, &data2);
Sakari Ailusc659c382011-01-21 10:59:30 +00002409 tlan_mii_read_reg(dev, phy, i + 3, &data3);
Joe Perches50624aa2011-03-01 06:56:33 +00002410 pr_info(" 0x%02x 0x%04hx 0x%04hx 0x%04hx 0x%04hx\n",
2411 i, data0, data1, data2, data3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412 }
2413 } else {
Joe Perches50624aa2011-03-01 06:56:33 +00002414 netdev_info(dev, "Invalid PHY\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415 }
2416
Sakari Ailusc659c382011-01-21 10:59:30 +00002417}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418
2419
2420
2421
Sakari Ailusc659c382011-01-21 10:59:30 +00002422/*********************************************************************
2423 * tlan_phy_detect
2424 *
2425 * Returns:
2426 * Nothing
2427 * Parms:
2428 * dev A pointer to the device structure of the adapter
2429 * for which the PHY needs determined.
2430 *
2431 * So far I've found that adapters which have external PHYs
2432 * may also use the internal PHY for part of the functionality.
2433 * (eg, AUI/Thinnet). This function finds out if this TLAN
2434 * chip has an internal PHY, and then finds the first external
2435 * PHY (starting from address 0) if it exists).
2436 *
2437 ********************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438
Sakari Ailusc659c382011-01-21 10:59:30 +00002439static void tlan_phy_detect(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440{
Sakari Ailusc659c382011-01-21 10:59:30 +00002441 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442 u16 control;
2443 u16 hi;
2444 u16 lo;
2445 u32 phy;
2446
Sakari Ailusc659c382011-01-21 10:59:30 +00002447 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
2448 priv->phy_num = 0xffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449 return;
2450 }
2451
Sakari Ailusc659c382011-01-21 10:59:30 +00002452 tlan_mii_read_reg(dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002453
Sakari Ailusc659c382011-01-21 10:59:30 +00002454 if (hi != 0xffff)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455 priv->phy[0] = TLAN_PHY_MAX_ADDR;
Sakari Ailusc659c382011-01-21 10:59:30 +00002456 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457 priv->phy[0] = TLAN_PHY_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458
2459 priv->phy[1] = TLAN_PHY_NONE;
Sakari Ailusc659c382011-01-21 10:59:30 +00002460 for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) {
2461 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &control);
2462 tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &hi);
2463 tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &lo);
2464 if ((control != 0xffff) ||
2465 (hi != 0xffff) || (lo != 0xffff)) {
2466 TLAN_DBG(TLAN_DEBUG_GNRL,
2467 "PHY found at %02x %04x %04x %04x\n",
2468 phy, control, hi, lo);
2469 if ((priv->phy[1] == TLAN_PHY_NONE) &&
2470 (phy != TLAN_PHY_MAX_ADDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002471 priv->phy[1] = phy;
2472 }
2473 }
2474 }
2475
Sakari Ailusc659c382011-01-21 10:59:30 +00002476 if (priv->phy[1] != TLAN_PHY_NONE)
2477 priv->phy_num = 1;
2478 else if (priv->phy[0] != TLAN_PHY_NONE)
2479 priv->phy_num = 0;
2480 else
Joe Perches50624aa2011-03-01 06:56:33 +00002481 netdev_info(dev, "Cannot initialize device, no PHY was found!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482
Sakari Ailusc659c382011-01-21 10:59:30 +00002483}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002484
2485
2486
2487
Sakari Ailusc659c382011-01-21 10:59:30 +00002488static void tlan_phy_power_down(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489{
Sakari Ailusc659c382011-01-21 10:59:30 +00002490 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491 u16 value;
2492
Sakari Ailusc659c382011-01-21 10:59:30 +00002493 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494 value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
Sakari Ailusc659c382011-01-21 10:59:30 +00002495 tlan_mii_sync(dev->base_addr);
2496 tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
2497 if ((priv->phy_num == 0) &&
2498 (priv->phy[1] != TLAN_PHY_NONE) &&
2499 (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) {
2500 tlan_mii_sync(dev->base_addr);
2501 tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502 }
2503
2504 /* Wait for 50 ms and powerup
2505 * This is abitrary. It is intended to make sure the
2506 * transceiver settles.
2507 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002508 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_PUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509
Sakari Ailusc659c382011-01-21 10:59:30 +00002510}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002511
2512
2513
2514
Sakari Ailusc659c382011-01-21 10:59:30 +00002515static void tlan_phy_power_up(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516{
Sakari Ailusc659c382011-01-21 10:59:30 +00002517 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002518 u16 value;
2519
Sakari Ailusc659c382011-01-21 10:59:30 +00002520 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name);
2521 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522 value = MII_GC_LOOPBK;
Sakari Ailusc659c382011-01-21 10:59:30 +00002523 tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
2524 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525 /* Wait for 500 ms and reset the
2526 * transceiver. The TLAN docs say both 50 ms and
2527 * 500 ms, so do the longer, just in case.
2528 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002529 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530
Sakari Ailusc659c382011-01-21 10:59:30 +00002531}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532
2533
2534
2535
Sakari Ailusc659c382011-01-21 10:59:30 +00002536static void tlan_phy_reset(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537{
Sakari Ailusc659c382011-01-21 10:59:30 +00002538 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 u16 phy;
2540 u16 value;
2541
Sakari Ailusc659c382011-01-21 10:59:30 +00002542 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543
Masanari Iidafd9071e2012-04-13 04:33:20 +00002544 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Resetting PHY.\n", dev->name);
Sakari Ailusc659c382011-01-21 10:59:30 +00002545 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002546 value = MII_GC_LOOPBK | MII_GC_RESET;
Sakari Ailusc659c382011-01-21 10:59:30 +00002547 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value);
2548 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
2549 while (value & MII_GC_RESET)
2550 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551
2552 /* Wait for 500 ms and initialize.
2553 * I don't remember why I wait this long.
2554 * I've changed this to 50ms, as it seems long enough.
2555 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002556 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_START_LINK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557
Sakari Ailusc659c382011-01-21 10:59:30 +00002558}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559
2560
2561
2562
Sakari Ailusc659c382011-01-21 10:59:30 +00002563static void tlan_phy_start_link(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564{
Sakari Ailusc659c382011-01-21 10:59:30 +00002565 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566 u16 ability;
2567 u16 control;
2568 u16 data;
2569 u16 phy;
2570 u16 status;
2571 u16 tctl;
2572
Sakari Ailusc659c382011-01-21 10:59:30 +00002573 phy = priv->phy[priv->phy_num];
2574 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name);
2575 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2576 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &ability);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577
Sakari Ailusc659c382011-01-21 10:59:30 +00002578 if ((status & MII_GS_AUTONEG) &&
2579 (!priv->aui)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580 ability = status >> 11;
Sakari Ailusc659c382011-01-21 10:59:30 +00002581 if (priv->speed == TLAN_SPEED_10 &&
2582 priv->duplex == TLAN_DUPLEX_HALF) {
2583 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0000);
2584 } else if (priv->speed == TLAN_SPEED_10 &&
2585 priv->duplex == TLAN_DUPLEX_FULL) {
2586 priv->tlan_full_duplex = true;
2587 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0100);
2588 } else if (priv->speed == TLAN_SPEED_100 &&
2589 priv->duplex == TLAN_DUPLEX_HALF) {
2590 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2000);
2591 } else if (priv->speed == TLAN_SPEED_100 &&
2592 priv->duplex == TLAN_DUPLEX_FULL) {
2593 priv->tlan_full_duplex = true;
2594 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2100);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595 } else {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002596
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597 /* Set Auto-Neg advertisement */
Sakari Ailusc659c382011-01-21 10:59:30 +00002598 tlan_mii_write_reg(dev, phy, MII_AN_ADV,
2599 (ability << 5) | 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 /* Enablee Auto-Neg */
Sakari Ailusc659c382011-01-21 10:59:30 +00002601 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1000);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602 /* Restart Auto-Neg */
Sakari Ailusc659c382011-01-21 10:59:30 +00002603 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1200);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604 /* Wait for 4 sec for autonegotiation
Sakari Ailusc659c382011-01-21 10:59:30 +00002605 * to complete. The max spec time is less than this
2606 * but the card need additional time to start AN.
2607 * .5 sec should be plenty extra.
2608 */
Joe Perches50624aa2011-03-01 06:56:33 +00002609 netdev_info(dev, "Starting autonegotiation\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002610 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002611 return;
2612 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002613
2614 }
2615
Sakari Ailusc659c382011-01-21 10:59:30 +00002616 if ((priv->aui) && (priv->phy_num != 0)) {
2617 priv->phy_num = 0;
2618 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
2619 | TLAN_NET_CFG_PHY_EN;
2620 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
2621 tlan_set_timer(dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622 return;
Sakari Ailusc659c382011-01-21 10:59:30 +00002623 } else if (priv->phy_num == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624 control = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002625 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tctl);
2626 if (priv->aui) {
2627 tctl |= TLAN_TC_AUISEL;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002628 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002629 tctl &= ~TLAN_TC_AUISEL;
2630 if (priv->duplex == TLAN_DUPLEX_FULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631 control |= MII_GC_DUPLEX;
Sakari Ailusc659c382011-01-21 10:59:30 +00002632 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002634 if (priv->speed == TLAN_SPEED_100)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635 control |= MII_GC_SPEEDSEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002637 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, control);
2638 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639 }
2640
2641 /* Wait for 2 sec to give the transceiver time
2642 * to establish link.
2643 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002644 tlan_set_timer(dev, (4*HZ), TLAN_TIMER_FINISH_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645
Sakari Ailusc659c382011-01-21 10:59:30 +00002646}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002647
2648
2649
2650
Sakari Ailusc659c382011-01-21 10:59:30 +00002651static void tlan_phy_finish_auto_neg(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652{
Sakari Ailusc659c382011-01-21 10:59:30 +00002653 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654 u16 an_adv;
2655 u16 an_lpa;
2656 u16 data;
2657 u16 mode;
2658 u16 phy;
2659 u16 status;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002660
Sakari Ailusc659c382011-01-21 10:59:30 +00002661 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662
Sakari Ailusc659c382011-01-21 10:59:30 +00002663 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2664 udelay(1000);
2665 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666
Sakari Ailusc659c382011-01-21 10:59:30 +00002667 if (!(status & MII_GS_AUTOCMPLT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668 /* Wait for 8 sec to give the process
2669 * more time. Perhaps we should fail after a while.
2670 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002671 if (!priv->neg_be_verbose++) {
Joe Perches50624aa2011-03-01 06:56:33 +00002672 pr_info("Giving autonegotiation more time.\n");
2673 pr_info("Please check that your adapter has\n");
2674 pr_info("been properly connected to a HUB or Switch.\n");
2675 pr_info("Trying to establish link in the background...\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002676 }
2677 tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678 return;
2679 }
2680
Joe Perches50624aa2011-03-01 06:56:33 +00002681 netdev_info(dev, "Autonegotiation complete\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002682 tlan_mii_read_reg(dev, phy, MII_AN_ADV, &an_adv);
2683 tlan_mii_read_reg(dev, phy, MII_AN_LPA, &an_lpa);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684 mode = an_adv & an_lpa & 0x03E0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002685 if (mode & 0x0100)
2686 priv->tlan_full_duplex = true;
2687 else if (!(mode & 0x0080) && (mode & 0x0040))
2688 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002689
Sakari Ailusc659c382011-01-21 10:59:30 +00002690 if ((!(mode & 0x0180)) &&
2691 (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) &&
2692 (priv->phy_num != 0)) {
2693 priv->phy_num = 0;
2694 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
2695 | TLAN_NET_CFG_PHY_EN;
2696 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
2697 tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698 return;
2699 }
2700
Sakari Ailusc659c382011-01-21 10:59:30 +00002701 if (priv->phy_num == 0) {
2702 if ((priv->duplex == TLAN_DUPLEX_FULL) ||
2703 (an_adv & an_lpa & 0x0040)) {
2704 tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
2705 MII_GC_AUTOENB | MII_GC_DUPLEX);
Joe Perches50624aa2011-03-01 06:56:33 +00002706 netdev_info(dev, "Starting internal PHY with FULL-DUPLEX\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002707 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002708 tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
2709 MII_GC_AUTOENB);
Joe Perches50624aa2011-03-01 06:56:33 +00002710 netdev_info(dev, "Starting internal PHY with HALF-DUPLEX\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711 }
2712 }
2713
2714 /* Wait for 100 ms. No reason in partiticular.
2715 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002716 tlan_set_timer(dev, (HZ/10), TLAN_TIMER_FINISH_RESET);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002717
Sakari Ailusc659c382011-01-21 10:59:30 +00002718}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719
2720#ifdef MONITOR
2721
Sakari Ailusc659c382011-01-21 10:59:30 +00002722/*********************************************************************
2723 *
2724 * tlan_phy_monitor
2725 *
2726 * Returns:
2727 * None
2728 *
2729 * Params:
2730 * dev The device structure of this device.
2731 *
2732 *
2733 * This function monitors PHY condition by reading the status
2734 * register via the MII bus. This can be used to give info
2735 * about link changes (up/down), and possible switch to alternate
2736 * media.
2737 *
2738 *******************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002739
Sakari Ailusc659c382011-01-21 10:59:30 +00002740void tlan_phy_monitor(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002741{
Sakari Ailusc659c382011-01-21 10:59:30 +00002742 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002743 u16 phy;
2744 u16 phy_status;
2745
Sakari Ailusc659c382011-01-21 10:59:30 +00002746 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747
Sakari Ailusc659c382011-01-21 10:59:30 +00002748 /* Get PHY status register */
2749 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &phy_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002750
Sakari Ailusc659c382011-01-21 10:59:30 +00002751 /* Check if link has been lost */
2752 if (!(phy_status & MII_GS_LINK)) {
2753 if (priv->link) {
2754 priv->link = 0;
2755 printk(KERN_DEBUG "TLAN: %s has lost link\n",
2756 dev->name);
2757 netif_carrier_off(dev);
2758 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
2759 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760 }
2761 }
2762
Sakari Ailusc659c382011-01-21 10:59:30 +00002763 /* Link restablished? */
2764 if ((phy_status & MII_GS_LINK) && !priv->link) {
2765 priv->link = 1;
2766 printk(KERN_DEBUG "TLAN: %s has reestablished link\n",
2767 dev->name);
7d17c1d2005-05-12 19:45:25 -04002768 netif_carrier_on(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00002769 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002770
2771 /* Setup a new monitor */
Sakari Ailusc659c382011-01-21 10:59:30 +00002772 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002773}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002774
2775#endif /* MONITOR */
2776
2777
2778/*****************************************************************************
2779******************************************************************************
2780
Sakari Ailusc659c382011-01-21 10:59:30 +00002781ThunderLAN driver MII routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782
Sakari Ailusc659c382011-01-21 10:59:30 +00002783these routines are based on the information in chap. 2 of the
2784"ThunderLAN Programmer's Guide", pp. 15-24.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002785
2786******************************************************************************
2787*****************************************************************************/
2788
2789
Sakari Ailusc659c382011-01-21 10:59:30 +00002790/***************************************************************
2791 * tlan_mii_read_reg
2792 *
2793 * Returns:
2794 * false if ack received ok
2795 * true if no ack received or other error
2796 *
2797 * Parms:
2798 * dev The device structure containing
2799 * The io address and interrupt count
2800 * for this device.
2801 * phy The address of the PHY to be queried.
2802 * reg The register whose contents are to be
2803 * retrieved.
2804 * val A pointer to a variable to store the
2805 * retrieved value.
2806 *
2807 * This function uses the TLAN's MII bus to retrieve the contents
2808 * of a given register on a PHY. It sends the appropriate info
2809 * and then reads the 16-bit register value from the MII bus via
2810 * the TLAN SIO register.
2811 *
2812 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813
Sakari Ailusc659c382011-01-21 10:59:30 +00002814static bool
2815tlan_mii_read_reg(struct net_device *dev, u16 phy, u16 reg, u16 *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816{
2817 u8 nack;
2818 u16 sio, tmp;
Sakari Ailusc659c382011-01-21 10:59:30 +00002819 u32 i;
Joe Perches37fce432010-01-12 20:59:13 +00002820 bool err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 int minten;
Sakari Ailusc659c382011-01-21 10:59:30 +00002822 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823 unsigned long flags = 0;
2824
Joe Perches37fce432010-01-12 20:59:13 +00002825 err = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2827 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002828
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 if (!in_irq())
2830 spin_lock_irqsave(&priv->lock, flags);
2831
Sakari Ailusc659c382011-01-21 10:59:30 +00002832 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833
Sakari Ailusc659c382011-01-21 10:59:30 +00002834 minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
2835 if (minten)
2836 tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837
Sakari Ailusc659c382011-01-21 10:59:30 +00002838 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */
2839 tlan_mii_send_data(dev->base_addr, 0x2, 2); /* read (10b) */
2840 tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */
2841 tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842
2843
Sakari Ailusc659c382011-01-21 10:59:30 +00002844 tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio); /* change direction */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845
Sakari Ailusc659c382011-01-21 10:59:30 +00002846 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* clock idle bit */
2847 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
2848 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* wait 300ns */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849
Sakari Ailusc659c382011-01-21 10:59:30 +00002850 nack = tlan_get_bit(TLAN_NET_SIO_MDATA, sio); /* check for ACK */
2851 tlan_set_bit(TLAN_NET_SIO_MCLK, sio); /* finish ACK */
2852 if (nack) { /* no ACK, so fake it */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853 for (i = 0; i < 16; i++) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002854 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2855 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 }
2857 tmp = 0xffff;
Joe Perches37fce432010-01-12 20:59:13 +00002858 err = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 } else { /* ACK, so read data */
2860 for (tmp = 0, i = 0x8000; i; i >>= 1) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002861 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2862 if (tlan_get_bit(TLAN_NET_SIO_MDATA, sio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863 tmp |= i;
Sakari Ailusc659c382011-01-21 10:59:30 +00002864 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 }
2866 }
2867
2868
Sakari Ailusc659c382011-01-21 10:59:30 +00002869 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
2870 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871
Sakari Ailusc659c382011-01-21 10:59:30 +00002872 if (minten)
2873 tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874
2875 *val = tmp;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002876
Linus Torvalds1da177e2005-04-16 15:20:36 -07002877 if (!in_irq())
2878 spin_unlock_irqrestore(&priv->lock, flags);
2879
2880 return err;
2881
Sakari Ailusc659c382011-01-21 10:59:30 +00002882}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002883
2884
2885
2886
Sakari Ailusc659c382011-01-21 10:59:30 +00002887/***************************************************************
2888 * tlan_mii_send_data
2889 *
2890 * Returns:
2891 * Nothing
2892 * Parms:
2893 * base_port The base IO port of the adapter in
2894 * question.
2895 * dev The address of the PHY to be queried.
2896 * data The value to be placed on the MII bus.
2897 * num_bits The number of bits in data that are to
2898 * be placed on the MII bus.
2899 *
2900 * This function sends on sequence of bits on the MII
2901 * configuration bus.
2902 *
2903 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904
Sakari Ailusc659c382011-01-21 10:59:30 +00002905static void tlan_mii_send_data(u16 base_port, u32 data, unsigned num_bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906{
2907 u16 sio;
2908 u32 i;
2909
Sakari Ailusc659c382011-01-21 10:59:30 +00002910 if (num_bits == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 return;
2912
Sakari Ailusc659c382011-01-21 10:59:30 +00002913 outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
Sakari Ailusc659c382011-01-21 10:59:30 +00002915 tlan_set_bit(TLAN_NET_SIO_MTXEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002916
Sakari Ailusc659c382011-01-21 10:59:30 +00002917 for (i = (0x1 << (num_bits - 1)); i; i >>= 1) {
2918 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2919 (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
2920 if (data & i)
2921 tlan_set_bit(TLAN_NET_SIO_MDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922 else
Sakari Ailusc659c382011-01-21 10:59:30 +00002923 tlan_clear_bit(TLAN_NET_SIO_MDATA, sio);
2924 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
2925 (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 }
2927
Sakari Ailusc659c382011-01-21 10:59:30 +00002928}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929
2930
2931
2932
Sakari Ailusc659c382011-01-21 10:59:30 +00002933/***************************************************************
2934 * TLan_MiiSync
2935 *
2936 * Returns:
2937 * Nothing
2938 * Parms:
2939 * base_port The base IO port of the adapter in
2940 * question.
2941 *
2942 * This functions syncs all PHYs in terms of the MII configuration
2943 * bus.
2944 *
2945 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
Sakari Ailusc659c382011-01-21 10:59:30 +00002947static void tlan_mii_sync(u16 base_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948{
2949 int i;
2950 u16 sio;
2951
Sakari Ailusc659c382011-01-21 10:59:30 +00002952 outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
2954
Sakari Ailusc659c382011-01-21 10:59:30 +00002955 tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio);
2956 for (i = 0; i < 32; i++) {
2957 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2958 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959 }
2960
Sakari Ailusc659c382011-01-21 10:59:30 +00002961}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002962
2963
2964
2965
Sakari Ailusc659c382011-01-21 10:59:30 +00002966/***************************************************************
2967 * tlan_mii_write_reg
2968 *
2969 * Returns:
2970 * Nothing
2971 * Parms:
2972 * dev The device structure for the device
2973 * to write to.
2974 * phy The address of the PHY to be written to.
2975 * reg The register whose contents are to be
2976 * written.
2977 * val The value to be written to the register.
2978 *
2979 * This function uses the TLAN's MII bus to write the contents of a
2980 * given register on a PHY. It sends the appropriate info and then
2981 * writes the 16-bit register value from the MII configuration bus
2982 * via the TLAN SIO register.
2983 *
2984 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985
Sakari Ailusc659c382011-01-21 10:59:30 +00002986static void
2987tlan_mii_write_reg(struct net_device *dev, u16 phy, u16 reg, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988{
2989 u16 sio;
2990 int minten;
2991 unsigned long flags = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002992 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993
2994 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2995 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002996
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997 if (!in_irq())
2998 spin_lock_irqsave(&priv->lock, flags);
2999
Sakari Ailusc659c382011-01-21 10:59:30 +00003000 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001
Sakari Ailusc659c382011-01-21 10:59:30 +00003002 minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
3003 if (minten)
3004 tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005
Sakari Ailusc659c382011-01-21 10:59:30 +00003006 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */
3007 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* write (01b) */
3008 tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */
3009 tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010
Sakari Ailusc659c382011-01-21 10:59:30 +00003011 tlan_mii_send_data(dev->base_addr, 0x2, 2); /* send ACK */
3012 tlan_mii_send_data(dev->base_addr, val, 16); /* send data */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013
Sakari Ailusc659c382011-01-21 10:59:30 +00003014 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
3015 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016
Sakari Ailusc659c382011-01-21 10:59:30 +00003017 if (minten)
3018 tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003019
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020 if (!in_irq())
3021 spin_unlock_irqrestore(&priv->lock, flags);
3022
Sakari Ailusc659c382011-01-21 10:59:30 +00003023}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003024
3025
3026
3027
3028/*****************************************************************************
3029******************************************************************************
3030
Sakari Ailusc659c382011-01-21 10:59:30 +00003031ThunderLAN driver eeprom routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032
Sakari Ailusc659c382011-01-21 10:59:30 +00003033the Compaq netelligent 10 and 10/100 cards use a microchip 24C02A
3034EEPROM. these functions are based on information in microchip's
3035data sheet. I don't know how well this functions will work with
3036other Eeproms.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037
3038******************************************************************************
3039*****************************************************************************/
3040
3041
Sakari Ailusc659c382011-01-21 10:59:30 +00003042/***************************************************************
3043 * tlan_ee_send_start
3044 *
3045 * Returns:
3046 * Nothing
3047 * Parms:
3048 * io_base The IO port base address for the
3049 * TLAN device with the EEPROM to
3050 * use.
3051 *
3052 * This function sends a start cycle to an EEPROM attached
3053 * to a TLAN chip.
3054 *
3055 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003056
Sakari Ailusc659c382011-01-21 10:59:30 +00003057static void tlan_ee_send_start(u16 io_base)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003058{
3059 u16 sio;
3060
Sakari Ailusc659c382011-01-21 10:59:30 +00003061 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3063
Sakari Ailusc659c382011-01-21 10:59:30 +00003064 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3065 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
3066 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
3067 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3068 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069
Sakari Ailusc659c382011-01-21 10:59:30 +00003070}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071
3072
3073
3074
Sakari Ailusc659c382011-01-21 10:59:30 +00003075/***************************************************************
3076 * tlan_ee_send_byte
3077 *
3078 * Returns:
3079 * If the correct ack was received, 0, otherwise 1
3080 * Parms: io_base The IO port base address for the
3081 * TLAN device with the EEPROM to
3082 * use.
3083 * data The 8 bits of information to
3084 * send to the EEPROM.
3085 * stop If TLAN_EEPROM_STOP is passed, a
3086 * stop cycle is sent after the
3087 * byte is sent after the ack is
3088 * read.
3089 *
3090 * This function sends a byte on the serial EEPROM line,
3091 * driving the clock to send each bit. The function then
3092 * reverses transmission direction and reads an acknowledge
3093 * bit.
3094 *
3095 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003096
Sakari Ailusc659c382011-01-21 10:59:30 +00003097static int tlan_ee_send_byte(u16 io_base, u8 data, int stop)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098{
3099 int err;
3100 u8 place;
3101 u16 sio;
3102
Sakari Ailusc659c382011-01-21 10:59:30 +00003103 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003104 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3105
3106 /* Assume clock is low, tx is enabled; */
Sakari Ailusc659c382011-01-21 10:59:30 +00003107 for (place = 0x80; place != 0; place >>= 1) {
3108 if (place & data)
3109 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110 else
Sakari Ailusc659c382011-01-21 10:59:30 +00003111 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3112 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3113 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003115 tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
3116 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3117 err = tlan_get_bit(TLAN_NET_SIO_EDATA, sio);
3118 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
3119 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003120
Sakari Ailusc659c382011-01-21 10:59:30 +00003121 if ((!err) && stop) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003122 /* STOP, raise data while clock is high */
Sakari Ailusc659c382011-01-21 10:59:30 +00003123 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3124 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3125 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003126 }
3127
Eric Dumazet807540b2010-09-23 05:40:09 +00003128 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003129
Sakari Ailusc659c382011-01-21 10:59:30 +00003130}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131
3132
3133
3134
Sakari Ailusc659c382011-01-21 10:59:30 +00003135/***************************************************************
3136 * tlan_ee_receive_byte
3137 *
3138 * Returns:
3139 * Nothing
3140 * Parms:
3141 * io_base The IO port base address for the
3142 * TLAN device with the EEPROM to
3143 * use.
3144 * data An address to a char to hold the
3145 * data sent from the EEPROM.
3146 * stop If TLAN_EEPROM_STOP is passed, a
3147 * stop cycle is sent after the
3148 * byte is received, and no ack is
3149 * sent.
3150 *
3151 * This function receives 8 bits of data from the EEPROM
3152 * over the serial link. It then sends and ack bit, or no
3153 * ack and a stop bit. This function is used to retrieve
3154 * data after the address of a byte in the EEPROM has been
3155 * sent.
3156 *
3157 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158
Sakari Ailusc659c382011-01-21 10:59:30 +00003159static void tlan_ee_receive_byte(u16 io_base, u8 *data, int stop)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160{
3161 u8 place;
3162 u16 sio;
3163
Sakari Ailusc659c382011-01-21 10:59:30 +00003164 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3166 *data = 0;
3167
3168 /* Assume clock is low, tx is enabled; */
Sakari Ailusc659c382011-01-21 10:59:30 +00003169 tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
3170 for (place = 0x80; place; place >>= 1) {
3171 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3172 if (tlan_get_bit(TLAN_NET_SIO_EDATA, sio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173 *data |= place;
Sakari Ailusc659c382011-01-21 10:59:30 +00003174 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003175 }
3176
Sakari Ailusc659c382011-01-21 10:59:30 +00003177 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
3178 if (!stop) {
3179 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); /* ack = 0 */
3180 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3181 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003182 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00003183 tlan_set_bit(TLAN_NET_SIO_EDATA, sio); /* no ack = 1 (?) */
3184 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3185 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003186 /* STOP, raise data while clock is high */
Sakari Ailusc659c382011-01-21 10:59:30 +00003187 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3188 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3189 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190 }
3191
Sakari Ailusc659c382011-01-21 10:59:30 +00003192}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003193
3194
3195
3196
Sakari Ailusc659c382011-01-21 10:59:30 +00003197/***************************************************************
3198 * tlan_ee_read_byte
3199 *
3200 * Returns:
3201 * No error = 0, else, the stage at which the error
3202 * occurred.
3203 * Parms:
3204 * io_base The IO port base address for the
3205 * TLAN device with the EEPROM to
3206 * use.
3207 * ee_addr The address of the byte in the
3208 * EEPROM whose contents are to be
3209 * retrieved.
3210 * data An address to a char to hold the
3211 * data obtained from the EEPROM.
3212 *
3213 * This function reads a byte of information from an byte
3214 * cell in the EEPROM.
3215 *
3216 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003217
Sakari Ailusc659c382011-01-21 10:59:30 +00003218static int tlan_ee_read_byte(struct net_device *dev, u8 ee_addr, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003219{
3220 int err;
Sakari Ailusc659c382011-01-21 10:59:30 +00003221 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003222 unsigned long flags = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00003223 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003224
3225 spin_lock_irqsave(&priv->lock, flags);
3226
Sakari Ailusc659c382011-01-21 10:59:30 +00003227 tlan_ee_send_start(dev->base_addr);
3228 err = tlan_ee_send_byte(dev->base_addr, 0xa0, TLAN_EEPROM_ACK);
3229 if (err) {
3230 ret = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003231 goto fail;
3232 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003233 err = tlan_ee_send_byte(dev->base_addr, ee_addr, TLAN_EEPROM_ACK);
3234 if (err) {
3235 ret = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003236 goto fail;
3237 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003238 tlan_ee_send_start(dev->base_addr);
3239 err = tlan_ee_send_byte(dev->base_addr, 0xa1, TLAN_EEPROM_ACK);
3240 if (err) {
3241 ret = 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003242 goto fail;
3243 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003244 tlan_ee_receive_byte(dev->base_addr, data, TLAN_EEPROM_STOP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003245fail:
3246 spin_unlock_irqrestore(&priv->lock, flags);
3247
3248 return ret;
3249
Sakari Ailusc659c382011-01-21 10:59:30 +00003250}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003251
3252
3253