blob: 591437e59b9019c9fa0597a8342f63ae5357fcaa [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
Sakari Ailusc659c382011-01-21 10:59:30 +0000322 pci_set_drvdata(pdev, NULL);
Devendra Naga1e0a8b12013-04-16 01:30:38 +0000323 cancel_work_sync(&priv->tlan_tqueue);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400324}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000326static void tlan_start(struct net_device *dev)
327{
328 tlan_reset_lists(dev);
329 /* NOTE: It might not be necessary to read the stats before a
330 reset if you don't care what the values are.
331 */
332 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
333 tlan_reset_adapter(dev);
334 netif_wake_queue(dev);
335}
336
337static void tlan_stop(struct net_device *dev)
338{
339 struct tlan_priv *priv = netdev_priv(dev);
340
341 tlan_read_and_clear_stats(dev, TLAN_RECORD);
342 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
343 /* Reset and power down phy */
344 tlan_reset_adapter(dev);
345 if (priv->timer.function != NULL) {
346 del_timer_sync(&priv->timer);
347 priv->timer.function = NULL;
348 }
349}
350
351#ifdef CONFIG_PM
352
353static int tlan_suspend(struct pci_dev *pdev, pm_message_t state)
354{
355 struct net_device *dev = pci_get_drvdata(pdev);
356
357 if (netif_running(dev))
358 tlan_stop(dev);
359
360 netif_device_detach(dev);
361 pci_save_state(pdev);
362 pci_disable_device(pdev);
363 pci_wake_from_d3(pdev, false);
364 pci_set_power_state(pdev, PCI_D3hot);
365
366 return 0;
367}
368
369static int tlan_resume(struct pci_dev *pdev)
370{
371 struct net_device *dev = pci_get_drvdata(pdev);
372
373 pci_set_power_state(pdev, PCI_D0);
374 pci_restore_state(pdev);
Yijing Wang1ca01512013-06-27 20:53:42 +0800375 pci_enable_wake(pdev, PCI_D0, 0);
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000376 netif_device_attach(dev);
377
378 if (netif_running(dev))
379 tlan_start(dev);
380
381 return 0;
382}
383
384#else /* CONFIG_PM */
385
386#define tlan_suspend NULL
387#define tlan_resume NULL
388
389#endif /* CONFIG_PM */
390
391
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392static struct pci_driver tlan_driver = {
393 .name = "tlan",
394 .id_table = tlan_pci_tbl,
395 .probe = tlan_init_one,
Bill Pemberton36915872012-12-03 09:23:44 -0500396 .remove = tlan_remove_one,
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000397 .suspend = tlan_suspend,
398 .resume = tlan_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399};
400
401static int __init tlan_probe(void)
402{
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800403 int rc = -ENODEV;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400404
Joe Perches50624aa2011-03-01 06:56:33 +0000405 pr_info("%s", tlan_banner);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400406
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400408
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 /* Use new style PCI probing. Now the kernel will
410 do most of this for us */
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800411 rc = pci_register_driver(&tlan_driver);
412
413 if (rc != 0) {
Joe Perches50624aa2011-03-01 06:56:33 +0000414 pr_err("Could not register pci driver\n");
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800415 goto err_out_pci_free;
416 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
418 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000419 tlan_eisa_probe();
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400420
Joe Perches50624aa2011-03-01 06:56:33 +0000421 pr_info("%d device%s installed, PCI: %d EISA: %d\n",
422 tlan_devices_installed, tlan_devices_installed == 1 ? "" : "s",
423 tlan_have_pci, tlan_have_eisa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
Sakari Ailusc659c382011-01-21 10:59:30 +0000425 if (tlan_devices_installed == 0) {
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800426 rc = -ENODEV;
427 goto err_out_pci_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 }
429 return 0;
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800430
431err_out_pci_unreg:
432 pci_unregister_driver(&tlan_driver);
433err_out_pci_free:
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800434 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400436
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437
Bill Pemberton36915872012-12-03 09:23:44 -0500438static int tlan_init_one(struct pci_dev *pdev,
Sakari Ailusc659c382011-01-21 10:59:30 +0000439 const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440{
Sakari Ailusc659c382011-01-21 10:59:30 +0000441 return tlan_probe1(pdev, -1, -1, 0, ent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442}
443
444
445/*
Sakari Ailusc659c382011-01-21 10:59:30 +0000446***************************************************************
447* tlan_probe1
448*
449* Returns:
450* 0 on success, error code on error
451* Parms:
452* none
453*
454* The name is lower case to fit in with all the rest of
455* the netcard_probe names. This function looks for
456* another TLan based adapter, setting it up with the
457* allocated device struct if one is found.
458* tlan_probe has been ported to the new net API and
459* now allocates its own device structure. This function
460* is also used by modules.
461*
462**************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463
Greg Kroah-Hartman1dd06ae2012-12-06 14:30:56 +0000464static int tlan_probe1(struct pci_dev *pdev, long ioaddr, int irq, int rev,
465 const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466{
467
468 struct net_device *dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000469 struct tlan_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 u16 device_id;
471 int reg, rc = -ENODEV;
472
Adrian Bunkad9f6712006-02-05 00:37:47 +0100473#ifdef CONFIG_PCI
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 if (pdev) {
475 rc = pci_enable_device(pdev);
476 if (rc)
477 return rc;
478
Sakari Ailusc659c382011-01-21 10:59:30 +0000479 rc = pci_request_regions(pdev, tlan_signature);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000481 pr_err("Could not reserve IO regions\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 goto err_out;
483 }
484 }
Adrian Bunkad9f6712006-02-05 00:37:47 +0100485#endif /* CONFIG_PCI */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
Sakari Ailusc659c382011-01-21 10:59:30 +0000487 dev = alloc_etherdev(sizeof(struct tlan_priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 if (dev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 rc = -ENOMEM;
490 goto err_out_regions;
491 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 SET_NETDEV_DEV(dev, &pdev->dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400493
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 priv = netdev_priv(dev);
495
Sakari Ailusc659c382011-01-21 10:59:30 +0000496 priv->pci_dev = pdev;
David Howellsc4028952006-11-22 14:57:56 +0000497 priv->dev = dev;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400498
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499 /* Is this a PCI device? */
500 if (pdev) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000501 u32 pci_io_base = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502
503 priv->adapter = &board_info[ent->driver_data];
504
Yang Hongyang284901a2009-04-06 19:01:15 -0700505 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000507 pr_err("No suitable PCI mapping available\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 goto err_out_free_dev;
509 }
510
Sakari Ailusc659c382011-01-21 10:59:30 +0000511 for (reg = 0; reg <= 5; reg++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
513 pci_io_base = pci_resource_start(pdev, reg);
Sakari Ailusc659c382011-01-21 10:59:30 +0000514 TLAN_DBG(TLAN_DEBUG_GNRL,
515 "IO mapping is available at %x.\n",
516 pci_io_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 break;
518 }
519 }
520 if (!pci_io_base) {
Joe Perches50624aa2011-03-01 06:56:33 +0000521 pr_err("No IO mappings available\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 rc = -EIO;
523 goto err_out_free_dev;
524 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400525
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526 dev->base_addr = pci_io_base;
527 dev->irq = pdev->irq;
Sakari Ailusc659c382011-01-21 10:59:30 +0000528 priv->adapter_rev = pdev->revision;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 pci_set_master(pdev);
530 pci_set_drvdata(pdev, dev);
531
532 } else { /* EISA card */
533 /* This is a hack. We need to know which board structure
534 * is suited for this adapter */
535 device_id = inw(ioaddr + EISA_ID2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 if (device_id == 0x20F1) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000537 priv->adapter = &board_info[13]; /* NetFlex-3/E */
538 priv->adapter_rev = 23; /* TLAN 2.3 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 } else {
540 priv->adapter = &board_info[14];
Sakari Ailusc659c382011-01-21 10:59:30 +0000541 priv->adapter_rev = 10; /* TLAN 1.0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 }
543 dev->base_addr = ioaddr;
544 dev->irq = irq;
545 }
546
547 /* Kernel parameters */
548 if (dev->mem_start) {
549 priv->aui = dev->mem_start & 0x01;
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700550 priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0
551 : (dev->mem_start & 0x06) >> 1;
552 priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0
553 : (dev->mem_start & 0x18) >> 3;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400554
Sakari Ailusc659c382011-01-21 10:59:30 +0000555 if (priv->speed == 0x1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 priv->speed = TLAN_SPEED_10;
Sakari Ailusc659c382011-01-21 10:59:30 +0000557 else if (priv->speed == 0x2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 priv->speed = TLAN_SPEED_100;
Sakari Ailusc659c382011-01-21 10:59:30 +0000559
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 debug = priv->debug = dev->mem_end;
561 } else {
562 priv->aui = aui[boards_found];
563 priv->speed = speed[boards_found];
564 priv->duplex = duplex[boards_found];
565 priv->debug = debug;
566 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400567
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 /* This will be used when we get an adapter error from
569 * within our irq handler */
Sakari Ailusc659c382011-01-21 10:59:30 +0000570 INIT_WORK(&priv->tlan_tqueue, tlan_tx_timeout_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571
572 spin_lock_init(&priv->lock);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400573
Sakari Ailusc659c382011-01-21 10:59:30 +0000574 rc = tlan_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000576 pr_err("Could not set up device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 goto err_out_free_dev;
578 }
579
580 rc = register_netdev(dev);
581 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000582 pr_err("Could not register device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 goto err_out_uninit;
584 }
585
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400586
Sakari Ailusc659c382011-01-21 10:59:30 +0000587 tlan_devices_installed++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 boards_found++;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 /* pdev is NULL if this is an EISA device */
591 if (pdev)
592 tlan_have_pci++;
593 else {
Sakari Ailusc659c382011-01-21 10:59:30 +0000594 priv->next_device = tlan_eisa_devices;
595 tlan_eisa_devices = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 tlan_have_eisa++;
597 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400598
Joe Perches50624aa2011-03-01 06:56:33 +0000599 netdev_info(dev, "irq=%2d, io=%04x, %s, Rev. %d\n",
600 (int)dev->irq,
601 (int)dev->base_addr,
602 priv->adapter->device_label,
603 priv->adapter_rev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 return 0;
605
606err_out_uninit:
Sakari Ailusc659c382011-01-21 10:59:30 +0000607 pci_free_consistent(priv->pci_dev, priv->dma_size, priv->dma_storage,
608 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609err_out_free_dev:
610 free_netdev(dev);
611err_out_regions:
612#ifdef CONFIG_PCI
613 if (pdev)
614 pci_release_regions(pdev);
615#endif
616err_out:
617 if (pdev)
618 pci_disable_device(pdev);
619 return rc;
620}
621
622
Sakari Ailusc659c382011-01-21 10:59:30 +0000623static void tlan_eisa_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624{
625 struct net_device *dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000626 struct tlan_priv *priv;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400627
Sakari Ailusc659c382011-01-21 10:59:30 +0000628 while (tlan_have_eisa) {
629 dev = tlan_eisa_devices;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 priv = netdev_priv(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +0000631 if (priv->dma_storage) {
632 pci_free_consistent(priv->pci_dev, priv->dma_size,
633 priv->dma_storage,
634 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000636 release_region(dev->base_addr, 0x10);
637 unregister_netdev(dev);
638 tlan_eisa_devices = priv->next_device;
639 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 tlan_have_eisa--;
641 }
642}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400643
644
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645static void __exit tlan_exit(void)
646{
647 pci_unregister_driver(&tlan_driver);
648
649 if (tlan_have_eisa)
Sakari Ailusc659c382011-01-21 10:59:30 +0000650 tlan_eisa_cleanup();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652}
653
654
655/* Module loading/unloading */
656module_init(tlan_probe);
657module_exit(tlan_exit);
658
659
660
Sakari Ailusc659c382011-01-21 10:59:30 +0000661/**************************************************************
662 * tlan_eisa_probe
663 *
664 * Returns: 0 on success, 1 otherwise
665 *
666 * Parms: None
667 *
668 *
669 * This functions probes for EISA devices and calls
670 * TLan_probe1 when one is found.
671 *
672 *************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673
Sakari Ailusc659c382011-01-21 10:59:30 +0000674static void __init tlan_eisa_probe(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675{
Sakari Ailusc659c382011-01-21 10:59:30 +0000676 long ioaddr;
677 int rc = -ENODEV;
678 int irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 u16 device_id;
680
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400681 if (!EISA_bus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
683 return;
684 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400685
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 /* Loop through all slots of the EISA bus */
687 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400688
Sakari Ailusc659c382011-01-21 10:59:30 +0000689 TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
690 (int) ioaddr + 0xc80, inw(ioaddr + EISA_ID));
691 TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
692 (int) ioaddr + 0xc82, inw(ioaddr + EISA_ID2));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693
694
Sakari Ailusc659c382011-01-21 10:59:30 +0000695 TLAN_DBG(TLAN_DEBUG_PROBE,
696 "Probing for EISA adapter at IO: 0x%4x : ",
697 (int) ioaddr);
698 if (request_region(ioaddr, 0x10, tlan_signature) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 goto out;
700
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400701 if (inw(ioaddr + EISA_ID) != 0x110E) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 release_region(ioaddr, 0x10);
703 goto out;
704 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400705
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 device_id = inw(ioaddr + EISA_ID2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400707 if (device_id != 0x20F1 && device_id != 0x40F1) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000708 release_region(ioaddr, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 goto out;
710 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400711
Sakari Ailusc659c382011-01-21 10:59:30 +0000712 /* check if adapter is enabled */
713 if (inb(ioaddr + EISA_CR) != 0x1) {
714 release_region(ioaddr, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 goto out2;
716 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400717
718 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000719 pr_info("Found one\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720
721
722 /* Get irq from board */
Sakari Ailusc659c382011-01-21 10:59:30 +0000723 switch (inb(ioaddr + 0xcc0)) {
724 case(0x10):
725 irq = 5;
726 break;
727 case(0x20):
728 irq = 9;
729 break;
730 case(0x40):
731 irq = 10;
732 break;
733 case(0x80):
734 irq = 11;
735 break;
736 default:
737 goto out;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400738 }
739
740
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 /* Setup the newly found eisa adapter */
Sakari Ailusc659c382011-01-21 10:59:30 +0000742 rc = tlan_probe1(NULL, ioaddr, irq,
743 12, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400745
Sakari Ailusc659c382011-01-21 10:59:30 +0000746out:
747 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000748 pr_info("None found\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000749 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
Sakari Ailusc659c382011-01-21 10:59:30 +0000751out2:
752 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000753 pr_info("Card found but it is not enabled, skipping\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000754 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400755
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 }
757
Sakari Ailusc659c382011-01-21 10:59:30 +0000758}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759
760#ifdef CONFIG_NET_POLL_CONTROLLER
Sakari Ailusc659c382011-01-21 10:59:30 +0000761static void tlan_poll(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762{
763 disable_irq(dev->irq);
Sakari Ailusc659c382011-01-21 10:59:30 +0000764 tlan_handle_interrupt(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 enable_irq(dev->irq);
766}
767#endif
768
Sakari Ailusc659c382011-01-21 10:59:30 +0000769static const struct net_device_ops tlan_netdev_ops = {
770 .ndo_open = tlan_open,
771 .ndo_stop = tlan_close,
772 .ndo_start_xmit = tlan_start_tx,
773 .ndo_tx_timeout = tlan_tx_timeout,
774 .ndo_get_stats = tlan_get_stats,
Jiri Pirkoafc4b132011-08-16 06:29:01 +0000775 .ndo_set_rx_mode = tlan_set_multicast_list,
Sakari Ailusc659c382011-01-21 10:59:30 +0000776 .ndo_do_ioctl = tlan_ioctl,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800777 .ndo_change_mtu = eth_change_mtu,
Sakari Ailusc659c382011-01-21 10:59:30 +0000778 .ndo_set_mac_address = eth_mac_addr,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800779 .ndo_validate_addr = eth_validate_addr,
780#ifdef CONFIG_NET_POLL_CONTROLLER
Sakari Ailusc659c382011-01-21 10:59:30 +0000781 .ndo_poll_controller = tlan_poll,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800782#endif
783};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400784
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785
786
Sakari Ailusc659c382011-01-21 10:59:30 +0000787/***************************************************************
788 * tlan_init
789 *
790 * Returns:
791 * 0 on success, error code otherwise.
792 * Parms:
793 * dev The structure of the device to be
794 * init'ed.
795 *
796 * This function completes the initialization of the
797 * device structure and driver. It reserves the IO
798 * addresses, allocates memory for the lists and bounce
799 * buffers, retrieves the MAC address from the eeprom
800 * and assignes the device's methods.
801 *
802 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803
Sakari Ailusc659c382011-01-21 10:59:30 +0000804static int tlan_init(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805{
806 int dma_size;
Sakari Ailusc659c382011-01-21 10:59:30 +0000807 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +0000809 struct tlan_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
811 priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400812
Sakari Ailusc659c382011-01-21 10:59:30 +0000813 dma_size = (TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS)
814 * (sizeof(struct tlan_list));
815 priv->dma_storage = pci_alloc_consistent(priv->pci_dev,
816 dma_size,
817 &priv->dma_storage_dma);
818 priv->dma_size = dma_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400819
Sakari Ailusc659c382011-01-21 10:59:30 +0000820 if (priv->dma_storage == NULL) {
Joe Perches50624aa2011-03-01 06:56:33 +0000821 pr_err("Could not allocate lists and buffers for %s\n",
Sakari Ailusc659c382011-01-21 10:59:30 +0000822 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 return -ENOMEM;
824 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000825 memset(priv->dma_storage, 0, dma_size);
826 priv->rx_list = (struct tlan_list *)
827 ALIGN((unsigned long)priv->dma_storage, 8);
828 priv->rx_list_dma = ALIGN(priv->dma_storage_dma, 8);
829 priv->tx_list = priv->rx_list + TLAN_NUM_RX_LISTS;
830 priv->tx_list_dma =
831 priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700832
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 err = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +0000834 for (i = 0; i < 6 ; i++)
835 err |= tlan_ee_read_byte(dev,
836 (u8) priv->adapter->addr_ofs + i,
837 (u8 *) &dev->dev_addr[i]);
838 if (err) {
Joe Perches50624aa2011-03-01 06:56:33 +0000839 pr_err("%s: Error reading MAC from eeprom: %d\n",
840 dev->name, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 }
842 dev->addr_len = 6;
843
844 netif_carrier_off(dev);
845
846 /* Device methods */
Sakari Ailusc659c382011-01-21 10:59:30 +0000847 dev->netdev_ops = &tlan_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 dev->watchdog_timeo = TX_TIMEOUT;
849
850 return 0;
851
Sakari Ailusc659c382011-01-21 10:59:30 +0000852}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853
854
855
856
Sakari Ailusc659c382011-01-21 10:59:30 +0000857/***************************************************************
858 * tlan_open
859 *
860 * Returns:
861 * 0 on success, error code otherwise.
862 * Parms:
863 * dev Structure of device to be opened.
864 *
865 * This routine puts the driver and TLAN adapter in a
866 * state where it is ready to send and receive packets.
867 * It allocates the IRQ, resets and brings the adapter
868 * out of reset, and allows interrupts. It also delays
869 * the startup for autonegotiation or sends a Rx GO
870 * command to the adapter, as appropriate.
871 *
872 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873
Sakari Ailusc659c382011-01-21 10:59:30 +0000874static int tlan_open(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875{
Sakari Ailusc659c382011-01-21 10:59:30 +0000876 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 int err;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400878
Sakari Ailusc659c382011-01-21 10:59:30 +0000879 priv->tlan_rev = tlan_dio_read8(dev->base_addr, TLAN_DEF_REVISION);
880 err = request_irq(dev->irq, tlan_handle_interrupt, IRQF_SHARED,
881 dev->name, dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400882
Sakari Ailusc659c382011-01-21 10:59:30 +0000883 if (err) {
Joe Perches50624aa2011-03-01 06:56:33 +0000884 netdev_err(dev, "Cannot open because IRQ %d is already in use\n",
885 dev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 return err;
887 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400888
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 init_timer(&priv->timer);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400890
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000891 tlan_start(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892
Sakari Ailusc659c382011-01-21 10:59:30 +0000893 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n",
894 dev->name, priv->tlan_rev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895
896 return 0;
897
Sakari Ailusc659c382011-01-21 10:59:30 +0000898}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700899
900
901
Sakari Ailusc659c382011-01-21 10:59:30 +0000902/**************************************************************
903 * tlan_ioctl
904 *
905 * Returns:
906 * 0 on success, error code otherwise
907 * Params:
908 * dev structure of device to receive ioctl.
909 *
910 * rq ifreq structure to hold userspace data.
911 *
912 * cmd ioctl command.
913 *
914 *
915 *************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916
Sakari Ailusc659c382011-01-21 10:59:30 +0000917static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918{
Sakari Ailusc659c382011-01-21 10:59:30 +0000919 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 struct mii_ioctl_data *data = if_mii(rq);
Sakari Ailusc659c382011-01-21 10:59:30 +0000921 u32 phy = priv->phy[priv->phy_num];
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400922
Sakari Ailusc659c382011-01-21 10:59:30 +0000923 if (!priv->phy_online)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924 return -EAGAIN;
925
Sakari Ailusc659c382011-01-21 10:59:30 +0000926 switch (cmd) {
927 case SIOCGMIIPHY: /* get address of MII PHY in use. */
928 data->phy_id = phy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929
930
Sakari Ailusc659c382011-01-21 10:59:30 +0000931 case SIOCGMIIREG: /* read MII PHY register. */
932 tlan_mii_read_reg(dev, data->phy_id & 0x1f,
933 data->reg_num & 0x1f, &data->val_out);
934 return 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400935
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936
Sakari Ailusc659c382011-01-21 10:59:30 +0000937 case SIOCSMIIREG: /* write MII PHY register. */
938 tlan_mii_write_reg(dev, data->phy_id & 0x1f,
939 data->reg_num & 0x1f, data->val_in);
940 return 0;
941 default:
942 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000944}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945
946
Sakari Ailusc659c382011-01-21 10:59:30 +0000947/***************************************************************
948 * tlan_tx_timeout
949 *
950 * Returns: nothing
951 *
952 * Params:
953 * dev structure of device which timed out
954 * during transmit.
955 *
956 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957
Sakari Ailusc659c382011-01-21 10:59:30 +0000958static void tlan_tx_timeout(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959{
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400960
Sakari Ailusc659c382011-01-21 10:59:30 +0000961 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400962
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 /* Ok so we timed out, lets see what we can do about it...*/
Sakari Ailusc659c382011-01-21 10:59:30 +0000964 tlan_free_lists(dev);
965 tlan_reset_lists(dev);
966 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
967 tlan_reset_adapter(dev);
Eric Dumazet1ae5dc32010-05-10 05:01:31 -0700968 dev->trans_start = jiffies; /* prevent tx timeout */
Sakari Ailusc659c382011-01-21 10:59:30 +0000969 netif_wake_queue(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970
971}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400972
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973
Sakari Ailusc659c382011-01-21 10:59:30 +0000974/***************************************************************
975 * tlan_tx_timeout_work
976 *
977 * Returns: nothing
978 *
979 * Params:
980 * work work item of device which timed out
981 *
982 **************************************************************/
David Howellsc4028952006-11-22 14:57:56 +0000983
Sakari Ailusc659c382011-01-21 10:59:30 +0000984static void tlan_tx_timeout_work(struct work_struct *work)
David Howellsc4028952006-11-22 14:57:56 +0000985{
Sakari Ailusc659c382011-01-21 10:59:30 +0000986 struct tlan_priv *priv =
987 container_of(work, struct tlan_priv, tlan_tqueue);
David Howellsc4028952006-11-22 14:57:56 +0000988
Sakari Ailusc659c382011-01-21 10:59:30 +0000989 tlan_tx_timeout(priv->dev);
David Howellsc4028952006-11-22 14:57:56 +0000990}
991
992
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993
Sakari Ailusc659c382011-01-21 10:59:30 +0000994/***************************************************************
995 * tlan_start_tx
996 *
997 * Returns:
998 * 0 on success, non-zero on failure.
999 * Parms:
1000 * skb A pointer to the sk_buff containing the
1001 * frame to be sent.
1002 * dev The device to send the data on.
1003 *
1004 * This function adds a frame to the Tx list to be sent
1005 * ASAP. First it verifies that the adapter is ready and
1006 * there is room in the queue. Then it sets up the next
1007 * available list, copies the frame to the corresponding
1008 * buffer. If the adapter Tx channel is idle, it gives
1009 * the adapter a Tx Go command on the list, otherwise it
1010 * sets the forward address of the previous list to point
1011 * to this one. Then it frees the sk_buff.
1012 *
1013 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014
Sakari Ailusc659c382011-01-21 10:59:30 +00001015static netdev_tx_t tlan_start_tx(struct sk_buff *skb, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016{
Sakari Ailusc659c382011-01-21 10:59:30 +00001017 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018 dma_addr_t tail_list_phys;
Sakari Ailusc659c382011-01-21 10:59:30 +00001019 struct tlan_list *tail_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 unsigned long flags;
Sakari Ailus8953f122008-12-16 01:44:05 -08001021 unsigned int txlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022
Sakari Ailusc659c382011-01-21 10:59:30 +00001023 if (!priv->phy_online) {
1024 TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n",
1025 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 dev_kfree_skb_any(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001027 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 }
1029
Stephen Hemminger41873e92008-05-30 09:49:52 -07001030 if (skb_padto(skb, TLAN_MIN_FRAME_SIZE))
Patrick McHardy6ed10652009-06-23 06:03:08 +00001031 return NETDEV_TX_OK;
Sakari Ailus8953f122008-12-16 01:44:05 -08001032 txlen = max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE);
Stephen Hemminger41873e92008-05-30 09:49:52 -07001033
Sakari Ailusc659c382011-01-21 10:59:30 +00001034 tail_list = priv->tx_list + priv->tx_tail;
1035 tail_list_phys =
1036 priv->tx_list_dma + sizeof(struct tlan_list)*priv->tx_tail;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001037
Sakari Ailusc659c382011-01-21 10:59:30 +00001038 if (tail_list->c_stat != TLAN_CSTAT_UNUSED) {
1039 TLAN_DBG(TLAN_DEBUG_TX,
1040 "TRANSMIT: %s is busy (Head=%d Tail=%d)\n",
1041 dev->name, priv->tx_head, priv->tx_tail);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042 netif_stop_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001043 priv->tx_busy_count++;
Patrick McHardy5b548142009-06-12 06:22:29 +00001044 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 }
1046
1047 tail_list->forward = 0;
1048
Sakari Ailusc659c382011-01-21 10:59:30 +00001049 tail_list->buffer[0].address = pci_map_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001050 skb->data, txlen,
1051 PCI_DMA_TODEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001052 tlan_store_skb(tail_list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053
Sakari Ailusc659c382011-01-21 10:59:30 +00001054 tail_list->frame_size = (u16) txlen;
Sakari Ailus8953f122008-12-16 01:44:05 -08001055 tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) txlen;
Stephen Hemminger41873e92008-05-30 09:49:52 -07001056 tail_list->buffer[1].count = 0;
1057 tail_list->buffer[1].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058
1059 spin_lock_irqsave(&priv->lock, flags);
Sakari Ailusc659c382011-01-21 10:59:30 +00001060 tail_list->c_stat = TLAN_CSTAT_READY;
1061 if (!priv->tx_in_progress) {
1062 priv->tx_in_progress = 1;
1063 TLAN_DBG(TLAN_DEBUG_TX,
1064 "TRANSMIT: Starting TX on buffer %d\n",
1065 priv->tx_tail);
1066 outl(tail_list_phys, dev->base_addr + TLAN_CH_PARM);
1067 outl(TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001069 TLAN_DBG(TLAN_DEBUG_TX,
1070 "TRANSMIT: Adding buffer %d to TX channel\n",
1071 priv->tx_tail);
1072 if (priv->tx_tail == 0) {
1073 (priv->tx_list + (TLAN_NUM_TX_LISTS - 1))->forward
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001074 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001076 (priv->tx_list + (priv->tx_tail - 1))->forward
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001077 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 }
1079 }
1080 spin_unlock_irqrestore(&priv->lock, flags);
1081
Sakari Ailusc659c382011-01-21 10:59:30 +00001082 CIRC_INC(priv->tx_tail, TLAN_NUM_TX_LISTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083
Patrick McHardy6ed10652009-06-23 06:03:08 +00001084 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
Sakari Ailusc659c382011-01-21 10:59:30 +00001086}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
1088
1089
1090
Sakari Ailusc659c382011-01-21 10:59:30 +00001091/***************************************************************
1092 * tlan_handle_interrupt
1093 *
1094 * Returns:
1095 * Nothing
1096 * Parms:
1097 * irq The line on which the interrupt
1098 * occurred.
1099 * dev_id A pointer to the device assigned to
1100 * this irq line.
1101 *
1102 * This function handles an interrupt generated by its
1103 * assigned TLAN adapter. The function deactivates
1104 * interrupts on its adapter, records the type of
1105 * interrupt, executes the appropriate subhandler, and
1106 * acknowdges the interrupt to the adapter (thus
1107 * re-enabling adapter interrupts.
1108 *
1109 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110
Sakari Ailusc659c382011-01-21 10:59:30 +00001111static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112{
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001113 struct net_device *dev = dev_id;
Sakari Ailusc659c382011-01-21 10:59:30 +00001114 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 u16 host_int;
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001116 u16 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
1118 spin_lock(&priv->lock);
1119
Sakari Ailusc659c382011-01-21 10:59:30 +00001120 host_int = inw(dev->base_addr + TLAN_HOST_INT);
1121 type = (host_int & TLAN_HI_IT_MASK) >> 2;
1122 if (type) {
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001123 u32 ack;
1124 u32 host_cmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125
Sakari Ailusc659c382011-01-21 10:59:30 +00001126 outw(host_int, dev->base_addr + TLAN_HOST_INT);
1127 ack = tlan_int_vector[type](dev, host_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128
Sakari Ailusc659c382011-01-21 10:59:30 +00001129 if (ack) {
1130 host_cmd = TLAN_HC_ACK | ack | (type << 18);
1131 outl(host_cmd, dev->base_addr + TLAN_HOST_CMD);
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001132 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 }
1134
1135 spin_unlock(&priv->lock);
1136
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001137 return IRQ_RETVAL(type);
Sakari Ailusc659c382011-01-21 10:59:30 +00001138}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139
1140
1141
1142
Sakari Ailusc659c382011-01-21 10:59:30 +00001143/***************************************************************
1144 * tlan_close
1145 *
1146 * Returns:
1147 * An error code.
1148 * Parms:
1149 * dev The device structure of the device to
1150 * close.
1151 *
1152 * This function shuts down the adapter. It records any
1153 * stats, puts the adapter into reset state, deactivates
1154 * its time as needed, and frees the irq it is using.
1155 *
1156 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157
Sakari Ailusc659c382011-01-21 10:59:30 +00001158static int tlan_close(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159{
Sakari Ailusc659c382011-01-21 10:59:30 +00001160 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 priv->neg_be_verbose = 0;
Sakari Ailusfa6d5d42011-01-21 10:59:31 +00001163 tlan_stop(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001164
Sakari Ailusc659c382011-01-21 10:59:30 +00001165 free_irq(dev->irq, dev);
1166 tlan_free_lists(dev);
1167 TLAN_DBG(TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
1169 return 0;
1170
Sakari Ailusc659c382011-01-21 10:59:30 +00001171}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172
1173
1174
1175
Sakari Ailusc659c382011-01-21 10:59:30 +00001176/***************************************************************
1177 * tlan_get_stats
1178 *
1179 * Returns:
1180 * A pointer to the device's statistics structure.
1181 * Parms:
1182 * dev The device structure to return the
1183 * stats for.
1184 *
1185 * This function updates the devices statistics by reading
1186 * the TLAN chip's onboard registers. Then it returns the
1187 * address of the statistics structure.
1188 *
1189 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190
Sakari Ailusc659c382011-01-21 10:59:30 +00001191static struct net_device_stats *tlan_get_stats(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192{
Sakari Ailusc659c382011-01-21 10:59:30 +00001193 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 int i;
1195
1196 /* Should only read stats if open ? */
Sakari Ailusc659c382011-01-21 10:59:30 +00001197 tlan_read_and_clear_stats(dev, TLAN_RECORD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198
Sakari Ailusc659c382011-01-21 10:59:30 +00001199 TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name,
1200 priv->rx_eoc_count);
1201 TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name,
1202 priv->tx_busy_count);
1203 if (debug & TLAN_DEBUG_GNRL) {
1204 tlan_print_dio(dev->base_addr);
1205 tlan_phy_print(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001207 if (debug & TLAN_DEBUG_LIST) {
1208 for (i = 0; i < TLAN_NUM_RX_LISTS; i++)
1209 tlan_print_list(priv->rx_list + i, "RX", i);
1210 for (i = 0; i < TLAN_NUM_TX_LISTS; i++)
1211 tlan_print_list(priv->tx_list + i, "TX", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001213
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001214 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215
Sakari Ailusc659c382011-01-21 10:59:30 +00001216}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217
1218
1219
1220
Sakari Ailusc659c382011-01-21 10:59:30 +00001221/***************************************************************
1222 * tlan_set_multicast_list
1223 *
1224 * Returns:
1225 * Nothing
1226 * Parms:
1227 * dev The device structure to set the
1228 * multicast list for.
1229 *
1230 * This function sets the TLAN adaptor to various receive
1231 * modes. If the IFF_PROMISC flag is set, promiscuous
1232 * mode is acitviated. Otherwise, promiscuous mode is
1233 * turned off. If the IFF_ALLMULTI flag is set, then
1234 * the hash table is set to receive all group addresses.
1235 * Otherwise, the first three multicast addresses are
1236 * stored in AREG_1-3, and the rest are selected via the
1237 * hash table, as necessary.
1238 *
1239 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240
Sakari Ailusc659c382011-01-21 10:59:30 +00001241static void tlan_set_multicast_list(struct net_device *dev)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001242{
Jiri Pirko22bedad32010-04-01 21:22:57 +00001243 struct netdev_hw_addr *ha;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 u32 hash1 = 0;
1245 u32 hash2 = 0;
1246 int i;
1247 u32 offset;
1248 u8 tmp;
1249
Sakari Ailusc659c382011-01-21 10:59:30 +00001250 if (dev->flags & IFF_PROMISC) {
1251 tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
1252 tlan_dio_write8(dev->base_addr,
1253 TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001255 tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
1256 tlan_dio_write8(dev->base_addr,
1257 TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF);
1258 if (dev->flags & IFF_ALLMULTI) {
1259 for (i = 0; i < 3; i++)
1260 tlan_set_mac(dev, i + 1, NULL);
1261 tlan_dio_write32(dev->base_addr, TLAN_HASH_1,
1262 0xffffffff);
1263 tlan_dio_write32(dev->base_addr, TLAN_HASH_2,
1264 0xffffffff);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265 } else {
Jiri Pirko567ec872010-02-23 23:17:07 +00001266 i = 0;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001267 netdev_for_each_mc_addr(ha, dev) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001268 if (i < 3) {
1269 tlan_set_mac(dev, i + 1,
Jiri Pirko22bedad32010-04-01 21:22:57 +00001270 (char *) &ha->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001272 offset =
1273 tlan_hash_func((u8 *)&ha->addr);
1274 if (offset < 32)
1275 hash1 |= (1 << offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 else
Sakari Ailusc659c382011-01-21 10:59:30 +00001277 hash2 |= (1 << (offset - 32));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278 }
Jiri Pirko567ec872010-02-23 23:17:07 +00001279 i++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001281 for ( ; i < 3; i++)
1282 tlan_set_mac(dev, i + 1, NULL);
1283 tlan_dio_write32(dev->base_addr, TLAN_HASH_1, hash1);
1284 tlan_dio_write32(dev->base_addr, TLAN_HASH_2, hash2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 }
1286 }
1287
Sakari Ailusc659c382011-01-21 10:59:30 +00001288}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289
1290
1291
1292/*****************************************************************************
1293******************************************************************************
1294
Sakari Ailusc659c382011-01-21 10:59:30 +00001295ThunderLAN driver interrupt vectors and table
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296
Sakari Ailusc659c382011-01-21 10:59:30 +00001297please see chap. 4, "Interrupt Handling" of the "ThunderLAN
1298Programmer's Guide" for more informations on handling interrupts
1299generated by TLAN based adapters.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300
1301******************************************************************************
1302*****************************************************************************/
1303
1304
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305
1306
Sakari Ailusc659c382011-01-21 10:59:30 +00001307/***************************************************************
1308 * tlan_handle_tx_eof
1309 *
1310 * Returns:
1311 * 1
1312 * Parms:
1313 * dev Device assigned the IRQ that was
1314 * raised.
1315 * host_int The contents of the HOST_INT
1316 * port.
1317 *
1318 * This function handles Tx EOF interrupts which are raised
1319 * by the adapter when it has completed sending the
1320 * contents of a buffer. If detemines which list/buffer
1321 * was completed and resets it. If the buffer was the last
1322 * in the channel (EOC), then the function checks to see if
1323 * another buffer is ready to send, and if so, sends a Tx
1324 * Go command. Finally, the driver activates/continues the
1325 * activity LED.
1326 *
1327 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328
Sakari Ailusc659c382011-01-21 10:59:30 +00001329static u32 tlan_handle_tx_eof(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330{
Sakari Ailusc659c382011-01-21 10:59:30 +00001331 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 int eoc = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001333 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 dma_addr_t head_list_phys;
1335 u32 ack = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001336 u16 tmp_c_stat;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001337
Sakari Ailusc659c382011-01-21 10:59:30 +00001338 TLAN_DBG(TLAN_DEBUG_TX,
1339 "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n",
1340 priv->tx_head, priv->tx_tail);
1341 head_list = priv->tx_list + priv->tx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342
Sakari Ailusc659c382011-01-21 10:59:30 +00001343 while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
1344 && (ack < 255)) {
1345 struct sk_buff *skb = tlan_get_skb(head_list);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001346
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347 ack++;
Sakari Ailusc659c382011-01-21 10:59:30 +00001348 pci_unmap_single(priv->pci_dev, head_list->buffer[0].address,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001349 max(skb->len,
1350 (unsigned int)TLAN_MIN_FRAME_SIZE),
1351 PCI_DMA_TODEVICE);
1352 dev_kfree_skb_any(skb);
1353 head_list->buffer[8].address = 0;
1354 head_list->buffer[9].address = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001355
Sakari Ailusc659c382011-01-21 10:59:30 +00001356 if (tmp_c_stat & TLAN_CSTAT_EOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001358
Sakari Ailusc659c382011-01-21 10:59:30 +00001359 dev->stats.tx_bytes += head_list->frame_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360
Sakari Ailusc659c382011-01-21 10:59:30 +00001361 head_list->c_stat = TLAN_CSTAT_UNUSED;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001362 netif_start_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001363 CIRC_INC(priv->tx_head, TLAN_NUM_TX_LISTS);
1364 head_list = priv->tx_list + priv->tx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 }
1366
1367 if (!ack)
Joe Perches50624aa2011-03-01 06:56:33 +00001368 netdev_info(dev,
1369 "Received interrupt for uncompleted TX frame\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001370
Sakari Ailusc659c382011-01-21 10:59:30 +00001371 if (eoc) {
1372 TLAN_DBG(TLAN_DEBUG_TX,
1373 "TRANSMIT: handling TX EOC (Head=%d Tail=%d)\n",
1374 priv->tx_head, priv->tx_tail);
1375 head_list = priv->tx_list + priv->tx_head;
1376 head_list_phys = priv->tx_list_dma
1377 + sizeof(struct tlan_list)*priv->tx_head;
Sakari Ailusf45437e2011-02-09 10:25:06 +00001378 if ((head_list->c_stat & TLAN_CSTAT_READY)
1379 == TLAN_CSTAT_READY) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001380 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 ack |= TLAN_HC_GO;
1382 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001383 priv->tx_in_progress = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 }
1385 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001386
Sakari Ailusc659c382011-01-21 10:59:30 +00001387 if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
1388 tlan_dio_write8(dev->base_addr,
1389 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
1390 if (priv->timer.function == NULL) {
1391 priv->timer.function = tlan_timer;
1392 priv->timer.data = (unsigned long) dev;
1393 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1394 priv->timer_set_at = jiffies;
1395 priv->timer_type = TLAN_TIMER_ACTIVITY;
1396 add_timer(&priv->timer);
1397 } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
1398 priv->timer_set_at = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 }
1400 }
1401
1402 return ack;
1403
Sakari Ailusc659c382011-01-21 10:59:30 +00001404}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
1406
1407
1408
Sakari Ailusc659c382011-01-21 10:59:30 +00001409/***************************************************************
1410 * TLan_HandleStatOverflow
1411 *
1412 * Returns:
1413 * 1
1414 * Parms:
1415 * dev Device assigned the IRQ that was
1416 * raised.
1417 * host_int The contents of the HOST_INT
1418 * port.
1419 *
1420 * This function handles the Statistics Overflow interrupt
1421 * which means that one or more of the TLAN statistics
1422 * registers has reached 1/2 capacity and needs to be read.
1423 *
1424 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425
Sakari Ailusc659c382011-01-21 10:59:30 +00001426static u32 tlan_handle_stat_overflow(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427{
Sakari Ailusc659c382011-01-21 10:59:30 +00001428 tlan_read_and_clear_stats(dev, TLAN_RECORD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429
1430 return 1;
1431
Sakari Ailusc659c382011-01-21 10:59:30 +00001432}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001433
1434
1435
1436
Sakari Ailusc659c382011-01-21 10:59:30 +00001437/***************************************************************
1438 * TLan_HandleRxEOF
1439 *
1440 * Returns:
1441 * 1
1442 * Parms:
1443 * dev Device assigned the IRQ that was
1444 * raised.
1445 * host_int The contents of the HOST_INT
1446 * port.
1447 *
1448 * This function handles the Rx EOF interrupt which
1449 * indicates a frame has been received by the adapter from
1450 * the net and the frame has been transferred to memory.
1451 * The function determines the bounce buffer the frame has
1452 * been loaded into, creates a new sk_buff big enough to
1453 * hold the frame, and sends it to protocol stack. It
1454 * then resets the used buffer and appends it to the end
1455 * of the list. If the frame was the last in the Rx
1456 * channel (EOC), the function restarts the receive channel
1457 * by sending an Rx Go command to the adapter. Then it
1458 * activates/continues the activity LED.
1459 *
1460 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461
Sakari Ailusc659c382011-01-21 10:59:30 +00001462static u32 tlan_handle_rx_eof(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463{
Sakari Ailusc659c382011-01-21 10:59:30 +00001464 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 u32 ack = 0;
1466 int eoc = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001467 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 struct sk_buff *skb;
Sakari Ailusc659c382011-01-21 10:59:30 +00001469 struct tlan_list *tail_list;
1470 u16 tmp_c_stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471 dma_addr_t head_list_phys;
1472
Sakari Ailusc659c382011-01-21 10:59:30 +00001473 TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: handling RX EOF (Head=%d Tail=%d)\n",
1474 priv->rx_head, priv->rx_tail);
1475 head_list = priv->rx_list + priv->rx_head;
1476 head_list_phys =
1477 priv->rx_list_dma + sizeof(struct tlan_list)*priv->rx_head;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001478
Sakari Ailusc659c382011-01-21 10:59:30 +00001479 while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
1480 && (ack < 255)) {
1481 dma_addr_t frame_dma = head_list->buffer[0].address;
1482 u32 frame_size = head_list->frame_size;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001483 struct sk_buff *new_skb;
1484
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 ack++;
Sakari Ailusc659c382011-01-21 10:59:30 +00001486 if (tmp_c_stat & TLAN_CSTAT_EOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001488
Eric Dumazet89d71a62009-10-13 05:34:20 +00001489 new_skb = netdev_alloc_skb_ip_align(dev,
1490 TLAN_MAX_FRAME_SIZE + 5);
Sakari Ailusc659c382011-01-21 10:59:30 +00001491 if (!new_skb)
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001492 goto drop_and_reuse;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001493
Sakari Ailusc659c382011-01-21 10:59:30 +00001494 skb = tlan_get_skb(head_list);
1495 pci_unmap_single(priv->pci_dev, frame_dma,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001496 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001497 skb_put(skb, frame_size);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001498
Sakari Ailusc659c382011-01-21 10:59:30 +00001499 dev->stats.rx_bytes += frame_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001500
Sakari Ailusc659c382011-01-21 10:59:30 +00001501 skb->protocol = eth_type_trans(skb, dev);
1502 netif_rx(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503
Sakari Ailusc659c382011-01-21 10:59:30 +00001504 head_list->buffer[0].address =
1505 pci_map_single(priv->pci_dev, new_skb->data,
1506 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507
Sakari Ailusc659c382011-01-21 10:59:30 +00001508 tlan_store_skb(head_list, new_skb);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001509drop_and_reuse:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 head_list->forward = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001511 head_list->c_stat = 0;
1512 tail_list = priv->rx_list + priv->rx_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 tail_list->forward = head_list_phys;
1514
Sakari Ailusc659c382011-01-21 10:59:30 +00001515 CIRC_INC(priv->rx_head, TLAN_NUM_RX_LISTS);
1516 CIRC_INC(priv->rx_tail, TLAN_NUM_RX_LISTS);
1517 head_list = priv->rx_list + priv->rx_head;
1518 head_list_phys = priv->rx_list_dma
1519 + sizeof(struct tlan_list)*priv->rx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 }
1521
1522 if (!ack)
Joe Perches50624aa2011-03-01 06:56:33 +00001523 netdev_info(dev,
1524 "Received interrupt for uncompleted RX frame\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525
1526
Sakari Ailusc659c382011-01-21 10:59:30 +00001527 if (eoc) {
1528 TLAN_DBG(TLAN_DEBUG_RX,
1529 "RECEIVE: handling RX EOC (Head=%d Tail=%d)\n",
1530 priv->rx_head, priv->rx_tail);
1531 head_list = priv->rx_list + priv->rx_head;
1532 head_list_phys = priv->rx_list_dma
1533 + sizeof(struct tlan_list)*priv->rx_head;
1534 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 ack |= TLAN_HC_GO | TLAN_HC_RT;
Sakari Ailusc659c382011-01-21 10:59:30 +00001536 priv->rx_eoc_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 }
1538
Sakari Ailusc659c382011-01-21 10:59:30 +00001539 if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
1540 tlan_dio_write8(dev->base_addr,
1541 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
1542 if (priv->timer.function == NULL) {
1543 priv->timer.function = tlan_timer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 priv->timer.data = (unsigned long) dev;
1545 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
Sakari Ailusc659c382011-01-21 10:59:30 +00001546 priv->timer_set_at = jiffies;
1547 priv->timer_type = TLAN_TIMER_ACTIVITY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 add_timer(&priv->timer);
Sakari Ailusc659c382011-01-21 10:59:30 +00001549 } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
1550 priv->timer_set_at = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 }
1552 }
1553
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 return ack;
1555
Sakari Ailusc659c382011-01-21 10:59:30 +00001556}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557
1558
1559
1560
Sakari Ailusc659c382011-01-21 10:59:30 +00001561/***************************************************************
1562 * tlan_handle_dummy
1563 *
1564 * Returns:
1565 * 1
1566 * Parms:
1567 * dev Device assigned the IRQ that was
1568 * raised.
1569 * host_int The contents of the HOST_INT
1570 * port.
1571 *
1572 * This function handles the Dummy interrupt, which is
1573 * raised whenever a test interrupt is generated by setting
1574 * the Req_Int bit of HOST_CMD to 1.
1575 *
1576 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
Sakari Ailusc659c382011-01-21 10:59:30 +00001578static u32 tlan_handle_dummy(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579{
Joe Perches50624aa2011-03-01 06:56:33 +00001580 netdev_info(dev, "Test interrupt\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 return 1;
1582
Sakari Ailusc659c382011-01-21 10:59:30 +00001583}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584
1585
1586
1587
Sakari Ailusc659c382011-01-21 10:59:30 +00001588/***************************************************************
1589 * tlan_handle_tx_eoc
1590 *
1591 * Returns:
1592 * 1
1593 * Parms:
1594 * dev Device assigned the IRQ that was
1595 * raised.
1596 * host_int The contents of the HOST_INT
1597 * port.
1598 *
1599 * This driver is structured to determine EOC occurrences by
1600 * reading the CSTAT member of the list structure. Tx EOC
1601 * interrupts are disabled via the DIO INTDIS register.
1602 * However, TLAN chips before revision 3.0 didn't have this
1603 * functionality, so process EOC events if this is the
1604 * case.
1605 *
1606 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607
Sakari Ailusc659c382011-01-21 10:59:30 +00001608static u32 tlan_handle_tx_eoc(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609{
Sakari Ailusc659c382011-01-21 10:59:30 +00001610 struct tlan_priv *priv = netdev_priv(dev);
1611 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 dma_addr_t head_list_phys;
1613 u32 ack = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001614
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615 host_int = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001616 if (priv->tlan_rev < 0x30) {
1617 TLAN_DBG(TLAN_DEBUG_TX,
1618 "TRANSMIT: handling TX EOC (Head=%d Tail=%d) -- IRQ\n",
1619 priv->tx_head, priv->tx_tail);
1620 head_list = priv->tx_list + priv->tx_head;
1621 head_list_phys = priv->tx_list_dma
1622 + sizeof(struct tlan_list)*priv->tx_head;
Sakari Ailusf45437e2011-02-09 10:25:06 +00001623 if ((head_list->c_stat & TLAN_CSTAT_READY)
1624 == TLAN_CSTAT_READY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 netif_stop_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001626 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 ack |= TLAN_HC_GO;
1628 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001629 priv->tx_in_progress = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 }
1631 }
1632
1633 return ack;
1634
Sakari Ailusc659c382011-01-21 10:59:30 +00001635}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636
1637
1638
1639
Sakari Ailusc659c382011-01-21 10:59:30 +00001640/***************************************************************
1641 * tlan_handle_status_check
1642 *
1643 * Returns:
1644 * 0 if Adapter check, 1 if Network Status check.
1645 * Parms:
1646 * dev Device assigned the IRQ that was
1647 * raised.
1648 * host_int The contents of the HOST_INT
1649 * port.
1650 *
1651 * This function handles Adapter Check/Network Status
1652 * interrupts generated by the adapter. It checks the
1653 * vector in the HOST_INT register to determine if it is
1654 * an Adapter Check interrupt. If so, it resets the
1655 * adapter. Otherwise it clears the status registers
1656 * and services the PHY.
1657 *
1658 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
Sakari Ailusc659c382011-01-21 10:59:30 +00001660static u32 tlan_handle_status_check(struct net_device *dev, u16 host_int)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001661{
Sakari Ailusc659c382011-01-21 10:59:30 +00001662 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 u32 ack;
1664 u32 error;
1665 u8 net_sts;
1666 u32 phy;
1667 u16 tlphy_ctl;
1668 u16 tlphy_sts;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001669
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670 ack = 1;
Sakari Ailusc659c382011-01-21 10:59:30 +00001671 if (host_int & TLAN_HI_IV_MASK) {
1672 netif_stop_queue(dev);
1673 error = inl(dev->base_addr + TLAN_CH_PARM);
Joe Perches50624aa2011-03-01 06:56:33 +00001674 netdev_info(dev, "Adaptor Error = 0x%x\n", error);
Sakari Ailusc659c382011-01-21 10:59:30 +00001675 tlan_read_and_clear_stats(dev, TLAN_RECORD);
1676 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677
1678 schedule_work(&priv->tlan_tqueue);
1679
1680 netif_wake_queue(dev);
1681 ack = 0;
1682 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001683 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name);
1684 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685
Sakari Ailusc659c382011-01-21 10:59:30 +00001686 net_sts = tlan_dio_read8(dev->base_addr, TLAN_NET_STS);
1687 if (net_sts) {
1688 tlan_dio_write8(dev->base_addr, TLAN_NET_STS, net_sts);
1689 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n",
1690 dev->name, (unsigned) net_sts);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001692 if ((net_sts & TLAN_NET_STS_MIRQ) && (priv->phy_num == 0)) {
1693 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_STS, &tlphy_sts);
1694 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
1695 if (!(tlphy_sts & TLAN_TS_POLOK) &&
1696 !(tlphy_ctl & TLAN_TC_SWAPOL)) {
1697 tlphy_ctl |= TLAN_TC_SWAPOL;
1698 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
1699 tlphy_ctl);
1700 } else if ((tlphy_sts & TLAN_TS_POLOK) &&
1701 (tlphy_ctl & TLAN_TC_SWAPOL)) {
1702 tlphy_ctl &= ~TLAN_TC_SWAPOL;
1703 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
1704 tlphy_ctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001706
1707 if (debug)
1708 tlan_phy_print(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 }
1710 }
1711
1712 return ack;
1713
Sakari Ailusc659c382011-01-21 10:59:30 +00001714}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715
1716
1717
1718
Sakari Ailusc659c382011-01-21 10:59:30 +00001719/***************************************************************
1720 * tlan_handle_rx_eoc
1721 *
1722 * Returns:
1723 * 1
1724 * Parms:
1725 * dev Device assigned the IRQ that was
1726 * raised.
1727 * host_int The contents of the HOST_INT
1728 * port.
1729 *
1730 * This driver is structured to determine EOC occurrences by
1731 * reading the CSTAT member of the list structure. Rx EOC
1732 * interrupts are disabled via the DIO INTDIS register.
1733 * However, TLAN chips before revision 3.0 didn't have this
1734 * CSTAT member or a INTDIS register, so if this chip is
1735 * pre-3.0, process EOC interrupts normally.
1736 *
1737 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738
Sakari Ailusc659c382011-01-21 10:59:30 +00001739static u32 tlan_handle_rx_eoc(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740{
Sakari Ailusc659c382011-01-21 10:59:30 +00001741 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 dma_addr_t head_list_phys;
1743 u32 ack = 1;
1744
Sakari Ailusc659c382011-01-21 10:59:30 +00001745 if (priv->tlan_rev < 0x30) {
1746 TLAN_DBG(TLAN_DEBUG_RX,
1747 "RECEIVE: Handling RX EOC (head=%d tail=%d) -- IRQ\n",
1748 priv->rx_head, priv->rx_tail);
1749 head_list_phys = priv->rx_list_dma
1750 + sizeof(struct tlan_list)*priv->rx_head;
1751 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 ack |= TLAN_HC_GO | TLAN_HC_RT;
Sakari Ailusc659c382011-01-21 10:59:30 +00001753 priv->rx_eoc_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 }
1755
1756 return ack;
1757
Sakari Ailusc659c382011-01-21 10:59:30 +00001758}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001759
1760
1761
1762
1763/*****************************************************************************
1764******************************************************************************
1765
Sakari Ailusc659c382011-01-21 10:59:30 +00001766ThunderLAN driver timer function
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767
1768******************************************************************************
1769*****************************************************************************/
1770
1771
Sakari Ailusc659c382011-01-21 10:59:30 +00001772/***************************************************************
1773 * tlan_timer
1774 *
1775 * Returns:
1776 * Nothing
1777 * Parms:
1778 * data A value given to add timer when
1779 * add_timer was called.
1780 *
1781 * This function handles timed functionality for the
1782 * TLAN driver. The two current timer uses are for
1783 * delaying for autonegotionation and driving the ACT LED.
1784 * - Autonegotiation requires being allowed about
1785 * 2 1/2 seconds before attempting to transmit a
1786 * packet. It would be a very bad thing to hang
1787 * the kernel this long, so the driver doesn't
1788 * allow transmission 'til after this time, for
1789 * certain PHYs. It would be much nicer if all
1790 * PHYs were interrupt-capable like the internal
1791 * PHY.
1792 * - The ACT LED, which shows adapter activity, is
1793 * driven by the driver, and so must be left on
1794 * for a short period to power up the LED so it
1795 * can be seen. This delay can be changed by
1796 * changing the TLAN_TIMER_ACT_DELAY in tlan.h,
1797 * if desired. 100 ms produces a slightly
1798 * sluggish response.
1799 *
1800 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801
Sakari Ailusc659c382011-01-21 10:59:30 +00001802static void tlan_timer(unsigned long data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803{
1804 struct net_device *dev = (struct net_device *) data;
Sakari Ailusc659c382011-01-21 10:59:30 +00001805 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 u32 elapsed;
1807 unsigned long flags = 0;
1808
1809 priv->timer.function = NULL;
1810
Sakari Ailusc659c382011-01-21 10:59:30 +00001811 switch (priv->timer_type) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001812#ifdef MONITOR
Sakari Ailusc659c382011-01-21 10:59:30 +00001813 case TLAN_TIMER_LINK_BEAT:
1814 tlan_phy_monitor(dev);
1815 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816#endif
Sakari Ailusc659c382011-01-21 10:59:30 +00001817 case TLAN_TIMER_PHY_PDOWN:
1818 tlan_phy_power_down(dev);
1819 break;
1820 case TLAN_TIMER_PHY_PUP:
1821 tlan_phy_power_up(dev);
1822 break;
1823 case TLAN_TIMER_PHY_RESET:
1824 tlan_phy_reset(dev);
1825 break;
1826 case TLAN_TIMER_PHY_START_LINK:
1827 tlan_phy_start_link(dev);
1828 break;
1829 case TLAN_TIMER_PHY_FINISH_AN:
1830 tlan_phy_finish_auto_neg(dev);
1831 break;
1832 case TLAN_TIMER_FINISH_RESET:
1833 tlan_finish_reset(dev);
1834 break;
1835 case TLAN_TIMER_ACTIVITY:
1836 spin_lock_irqsave(&priv->lock, flags);
1837 if (priv->timer.function == NULL) {
1838 elapsed = jiffies - priv->timer_set_at;
1839 if (elapsed >= TLAN_TIMER_ACT_DELAY) {
1840 tlan_dio_write8(dev->base_addr,
1841 TLAN_LED_REG, TLAN_LED_LINK);
1842 } else {
1843 priv->timer.function = tlan_timer;
1844 priv->timer.expires = priv->timer_set_at
1845 + TLAN_TIMER_ACT_DELAY;
1846 spin_unlock_irqrestore(&priv->lock, flags);
1847 add_timer(&priv->timer);
1848 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001850 }
1851 spin_unlock_irqrestore(&priv->lock, flags);
1852 break;
1853 default:
1854 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 }
1856
Sakari Ailusc659c382011-01-21 10:59:30 +00001857}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858
1859
1860
1861
1862/*****************************************************************************
1863******************************************************************************
1864
Sakari Ailusc659c382011-01-21 10:59:30 +00001865ThunderLAN driver adapter related routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866
1867******************************************************************************
1868*****************************************************************************/
1869
1870
Sakari Ailusc659c382011-01-21 10:59:30 +00001871/***************************************************************
1872 * tlan_reset_lists
1873 *
1874 * Returns:
1875 * Nothing
1876 * Parms:
1877 * dev The device structure with the list
1878 * stuctures to be reset.
1879 *
1880 * This routine sets the variables associated with managing
1881 * the TLAN lists to their initial values.
1882 *
1883 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884
Sakari Ailusc659c382011-01-21 10:59:30 +00001885static void tlan_reset_lists(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886{
Sakari Ailusc659c382011-01-21 10:59:30 +00001887 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +00001889 struct tlan_list *list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 dma_addr_t list_phys;
1891 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892
Sakari Ailusc659c382011-01-21 10:59:30 +00001893 priv->tx_head = 0;
1894 priv->tx_tail = 0;
1895 for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
1896 list = priv->tx_list + i;
1897 list->c_stat = TLAN_CSTAT_UNUSED;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001898 list->buffer[0].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 list->buffer[2].count = 0;
1900 list->buffer[2].address = 0;
1901 list->buffer[8].address = 0;
1902 list->buffer[9].address = 0;
1903 }
1904
Sakari Ailusc659c382011-01-21 10:59:30 +00001905 priv->rx_head = 0;
1906 priv->rx_tail = TLAN_NUM_RX_LISTS - 1;
1907 for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
1908 list = priv->rx_list + i;
1909 list_phys = priv->rx_list_dma + sizeof(struct tlan_list)*i;
1910 list->c_stat = TLAN_CSTAT_READY;
1911 list->frame_size = TLAN_MAX_FRAME_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
Eric Dumazet89d71a62009-10-13 05:34:20 +00001913 skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5);
Joe Perches720a43e2013-03-08 15:03:25 +00001914 if (!skb)
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001915 break;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001916
Sakari Ailusc659c382011-01-21 10:59:30 +00001917 list->buffer[0].address = pci_map_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001918 skb->data,
1919 TLAN_MAX_FRAME_SIZE,
1920 PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001921 tlan_store_skb(list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 list->buffer[1].count = 0;
1923 list->buffer[1].address = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001924 list->forward = list_phys + sizeof(struct tlan_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 }
1926
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001927 /* in case ran out of memory early, clear bits */
1928 while (i < TLAN_NUM_RX_LISTS) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001929 tlan_store_skb(priv->rx_list + i, NULL);
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001930 ++i;
1931 }
1932 list->forward = 0;
1933
Sakari Ailusc659c382011-01-21 10:59:30 +00001934}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
1936
Sakari Ailusc659c382011-01-21 10:59:30 +00001937static void tlan_free_lists(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938{
Sakari Ailusc659c382011-01-21 10:59:30 +00001939 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001940 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +00001941 struct tlan_list *list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 struct sk_buff *skb;
1943
Sakari Ailusc659c382011-01-21 10:59:30 +00001944 for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
1945 list = priv->tx_list + i;
1946 skb = tlan_get_skb(list);
1947 if (skb) {
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001948 pci_unmap_single(
Sakari Ailusc659c382011-01-21 10:59:30 +00001949 priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001950 list->buffer[0].address,
1951 max(skb->len,
1952 (unsigned int)TLAN_MIN_FRAME_SIZE),
1953 PCI_DMA_TODEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001954 dev_kfree_skb_any(skb);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001955 list->buffer[8].address = 0;
1956 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 }
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001958 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959
Sakari Ailusc659c382011-01-21 10:59:30 +00001960 for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
1961 list = priv->rx_list + i;
1962 skb = tlan_get_skb(list);
1963 if (skb) {
1964 pci_unmap_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001965 list->buffer[0].address,
1966 TLAN_MAX_FRAME_SIZE,
1967 PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001968 dev_kfree_skb_any(skb);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001969 list->buffer[8].address = 0;
1970 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001971 }
1972 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001973}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974
1975
1976
1977
Sakari Ailusc659c382011-01-21 10:59:30 +00001978/***************************************************************
1979 * tlan_print_dio
1980 *
1981 * Returns:
1982 * Nothing
1983 * Parms:
1984 * io_base Base IO port of the device of
1985 * which to print DIO registers.
1986 *
1987 * This function prints out all the internal (DIO)
1988 * registers of a TLAN chip.
1989 *
1990 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991
Sakari Ailusc659c382011-01-21 10:59:30 +00001992static void tlan_print_dio(u16 io_base)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993{
1994 u32 data0, data1;
1995 int i;
1996
Joe Perches50624aa2011-03-01 06:56:33 +00001997 pr_info("Contents of internal registers for io base 0x%04hx\n",
1998 io_base);
1999 pr_info("Off. +0 +4\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002000 for (i = 0; i < 0x4C; i += 8) {
2001 data0 = tlan_dio_read32(io_base, i);
2002 data1 = tlan_dio_read32(io_base, i + 0x4);
Joe Perches50624aa2011-03-01 06:56:33 +00002003 pr_info("0x%02x 0x%08x 0x%08x\n", i, data0, data1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002004 }
2005
Sakari Ailusc659c382011-01-21 10:59:30 +00002006}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007
2008
2009
2010
Sakari Ailusc659c382011-01-21 10:59:30 +00002011/***************************************************************
2012 * TLan_PrintList
2013 *
2014 * Returns:
2015 * Nothing
2016 * Parms:
2017 * list A pointer to the struct tlan_list structure to
2018 * be printed.
2019 * type A string to designate type of list,
2020 * "Rx" or "Tx".
2021 * num The index of the list.
2022 *
2023 * This function prints out the contents of the list
2024 * pointed to by the list parameter.
2025 *
2026 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027
Sakari Ailusc659c382011-01-21 10:59:30 +00002028static void tlan_print_list(struct tlan_list *list, char *type, int num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029{
2030 int i;
2031
Joe Perches50624aa2011-03-01 06:56:33 +00002032 pr_info("%s List %d at %p\n", type, num, list);
2033 pr_info(" Forward = 0x%08x\n", list->forward);
2034 pr_info(" CSTAT = 0x%04hx\n", list->c_stat);
2035 pr_info(" Frame Size = 0x%04hx\n", list->frame_size);
Sakari Ailusc659c382011-01-21 10:59:30 +00002036 /* for (i = 0; i < 10; i++) { */
2037 for (i = 0; i < 2; i++) {
Joe Perches50624aa2011-03-01 06:56:33 +00002038 pr_info(" Buffer[%d].count, addr = 0x%08x, 0x%08x\n",
2039 i, list->buffer[i].count, list->buffer[i].address);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002040 }
2041
Sakari Ailusc659c382011-01-21 10:59:30 +00002042}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043
2044
2045
2046
Sakari Ailusc659c382011-01-21 10:59:30 +00002047/***************************************************************
2048 * tlan_read_and_clear_stats
2049 *
2050 * Returns:
2051 * Nothing
2052 * Parms:
2053 * dev Pointer to device structure of adapter
2054 * to which to read stats.
2055 * record Flag indicating whether to add
2056 *
2057 * This functions reads all the internal status registers
2058 * of the TLAN chip, which clears them as a side effect.
2059 * It then either adds the values to the device's status
2060 * struct, or discards them, depending on whether record
2061 * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0).
2062 *
2063 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064
Sakari Ailusc659c382011-01-21 10:59:30 +00002065static void tlan_read_and_clear_stats(struct net_device *dev, int record)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067 u32 tx_good, tx_under;
2068 u32 rx_good, rx_over;
2069 u32 def_tx, crc, code;
2070 u32 multi_col, single_col;
2071 u32 excess_col, late_col, loss;
2072
Sakari Ailusc659c382011-01-21 10:59:30 +00002073 outw(TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR);
2074 tx_good = inb(dev->base_addr + TLAN_DIO_DATA);
2075 tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2076 tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
2077 tx_under = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078
Sakari Ailusc659c382011-01-21 10:59:30 +00002079 outw(TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR);
2080 rx_good = inb(dev->base_addr + TLAN_DIO_DATA);
2081 rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2082 rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
2083 rx_over = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002084
Sakari Ailusc659c382011-01-21 10:59:30 +00002085 outw(TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR);
2086 def_tx = inb(dev->base_addr + TLAN_DIO_DATA);
2087 def_tx += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2088 crc = inb(dev->base_addr + TLAN_DIO_DATA + 2);
2089 code = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002090
Sakari Ailusc659c382011-01-21 10:59:30 +00002091 outw(TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
2092 multi_col = inb(dev->base_addr + TLAN_DIO_DATA);
2093 multi_col += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2094 single_col = inb(dev->base_addr + TLAN_DIO_DATA + 2);
2095 single_col += inb(dev->base_addr + TLAN_DIO_DATA + 3) << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002096
Sakari Ailusc659c382011-01-21 10:59:30 +00002097 outw(TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
2098 excess_col = inb(dev->base_addr + TLAN_DIO_DATA);
2099 late_col = inb(dev->base_addr + TLAN_DIO_DATA + 1);
2100 loss = inb(dev->base_addr + TLAN_DIO_DATA + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002101
Sakari Ailusc659c382011-01-21 10:59:30 +00002102 if (record) {
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002103 dev->stats.rx_packets += rx_good;
2104 dev->stats.rx_errors += rx_over + crc + code;
2105 dev->stats.tx_packets += tx_good;
2106 dev->stats.tx_errors += tx_under + loss;
Sakari Ailusc659c382011-01-21 10:59:30 +00002107 dev->stats.collisions += multi_col
2108 + single_col + excess_col + late_col;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002110 dev->stats.rx_over_errors += rx_over;
2111 dev->stats.rx_crc_errors += crc;
2112 dev->stats.rx_frame_errors += code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002114 dev->stats.tx_aborted_errors += tx_under;
2115 dev->stats.tx_carrier_errors += loss;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002116 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002117
Sakari Ailusc659c382011-01-21 10:59:30 +00002118}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119
2120
2121
2122
Sakari Ailusc659c382011-01-21 10:59:30 +00002123/***************************************************************
2124 * TLan_Reset
2125 *
2126 * Returns:
2127 * 0
2128 * Parms:
2129 * dev Pointer to device structure of adapter
2130 * to be reset.
2131 *
2132 * This function resets the adapter and it's physical
2133 * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
2134 * Programmer's Guide" for details. The routine tries to
2135 * implement what is detailed there, though adjustments
2136 * have been made.
2137 *
2138 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139
Harvey Harrison98e0f522008-02-18 10:04:38 -08002140static void
Sakari Ailusc659c382011-01-21 10:59:30 +00002141tlan_reset_adapter(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142{
Sakari Ailusc659c382011-01-21 10:59:30 +00002143 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 int i;
2145 u32 addr;
2146 u32 data;
2147 u8 data8;
2148
Sakari Ailusc659c382011-01-21 10:59:30 +00002149 priv->tlan_full_duplex = false;
2150 priv->phy_online = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002151 netif_carrier_off(dev);
2152
2153/* 1. Assert reset bit. */
2154
2155 data = inl(dev->base_addr + TLAN_HOST_CMD);
2156 data |= TLAN_HC_AD_RST;
2157 outl(data, dev->base_addr + TLAN_HOST_CMD);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002158
Linus Torvalds1da177e2005-04-16 15:20:36 -07002159 udelay(1000);
2160
Sakari Ailusc659c382011-01-21 10:59:30 +00002161/* 2. Turn off interrupts. (Probably isn't necessary) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002162
2163 data = inl(dev->base_addr + TLAN_HOST_CMD);
2164 data |= TLAN_HC_INT_OFF;
2165 outl(data, dev->base_addr + TLAN_HOST_CMD);
2166
2167/* 3. Clear AREGs and HASHs. */
2168
Sakari Ailusc659c382011-01-21 10:59:30 +00002169 for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4)
2170 tlan_dio_write32(dev->base_addr, (u16) i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171
2172/* 4. Setup NetConfig register. */
2173
2174 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
Sakari Ailusc659c382011-01-21 10:59:30 +00002175 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176
2177/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
2178
Sakari Ailusc659c382011-01-21 10:59:30 +00002179 outl(TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD);
2180 outl(TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002181
2182/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
2183
Sakari Ailusc659c382011-01-21 10:59:30 +00002184 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002185 addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Sakari Ailusc659c382011-01-21 10:59:30 +00002186 tlan_set_bit(TLAN_NET_SIO_NMRST, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187
2188/* 7. Setup the remaining registers. */
2189
Sakari Ailusc659c382011-01-21 10:59:30 +00002190 if (priv->tlan_rev >= 0x30) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
Sakari Ailusc659c382011-01-21 10:59:30 +00002192 tlan_dio_write8(dev->base_addr, TLAN_INT_DIS, data8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002194 tlan_phy_detect(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002196
Sakari Ailusc659c382011-01-21 10:59:30 +00002197 if (priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198 data |= TLAN_NET_CFG_BIT;
Sakari Ailusc659c382011-01-21 10:59:30 +00002199 if (priv->aui == 1) {
2200 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x0a);
2201 } else if (priv->duplex == TLAN_DUPLEX_FULL) {
2202 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x00);
2203 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002205 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x08);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206 }
2207 }
2208
Sakari Ailusc659c382011-01-21 10:59:30 +00002209 if (priv->phy_num == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210 data |= TLAN_NET_CFG_PHY_EN;
Sakari Ailusc659c382011-01-21 10:59:30 +00002211 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212
Sakari Ailusc659c382011-01-21 10:59:30 +00002213 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY)
2214 tlan_finish_reset(dev);
2215 else
2216 tlan_phy_power_down(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002217
Sakari Ailusc659c382011-01-21 10:59:30 +00002218}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219
2220
2221
2222
Harvey Harrison98e0f522008-02-18 10:04:38 -08002223static void
Sakari Ailusc659c382011-01-21 10:59:30 +00002224tlan_finish_reset(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002225{
Sakari Ailusc659c382011-01-21 10:59:30 +00002226 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 u8 data;
2228 u32 phy;
2229 u8 sio;
2230 u16 status;
2231 u16 partner;
2232 u16 tlphy_ctl;
Sakari Ailusc659c382011-01-21 10:59:30 +00002233 u16 tlphy_par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234 u16 tlphy_id1, tlphy_id2;
Sakari Ailusc659c382011-01-21 10:59:30 +00002235 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236
Sakari Ailusc659c382011-01-21 10:59:30 +00002237 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
2239 data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
Sakari Ailusc659c382011-01-21 10:59:30 +00002240 if (priv->tlan_full_duplex)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241 data |= TLAN_NET_CMD_DUPLEX;
Sakari Ailusc659c382011-01-21 10:59:30 +00002242 tlan_dio_write8(dev->base_addr, TLAN_NET_CMD, data);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002243 data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
Sakari Ailusc659c382011-01-21 10:59:30 +00002244 if (priv->phy_num == 0)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002245 data |= TLAN_NET_MASK_MASK7;
Sakari Ailusc659c382011-01-21 10:59:30 +00002246 tlan_dio_write8(dev->base_addr, TLAN_NET_MASK, data);
2247 tlan_dio_write16(dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7);
2248 tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &tlphy_id1);
2249 tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &tlphy_id2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002250
Sakari Ailusc659c382011-01-21 10:59:30 +00002251 if ((priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) ||
2252 (priv->aui)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002253 status = MII_GS_LINK;
Joe Perches50624aa2011-03-01 06:56:33 +00002254 netdev_info(dev, "Link forced\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002256 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2257 udelay(1000);
2258 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2259 if ((status & MII_GS_LINK) &&
2260 /* We only support link info on Nat.Sem. PHY's */
2261 (tlphy_id1 == NAT_SEM_ID1) &&
2262 (tlphy_id2 == NAT_SEM_ID2)) {
2263 tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner);
2264 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002265
Joe Perches50624aa2011-03-01 06:56:33 +00002266 netdev_info(dev,
2267 "Link active with %s %uMbps %s-Duplex\n",
2268 !(tlphy_par & TLAN_PHY_AN_EN_STAT)
2269 ? "forced" : "Autonegotiation enabled,",
2270 tlphy_par & TLAN_PHY_SPEED_100
2271 ? 100 : 10,
2272 tlphy_par & TLAN_PHY_DUPLEX_FULL
2273 ? "Full" : "Half");
2274
2275 if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
2276 netdev_info(dev, "Partner capability:");
2277 for (i = 5; i < 10; i++)
2278 if (partner & (1 << i))
2279 pr_cont(" %s", media[i-5]);
2280 pr_cont("\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281 }
2282
Sakari Ailusc659c382011-01-21 10:59:30 +00002283 tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
2284 TLAN_LED_LINK);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002285#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286 /* We have link beat..for now anyway */
Sakari Ailusc659c382011-01-21 10:59:30 +00002287 priv->link = 1;
2288 /*Enabling link beat monitoring */
2289 tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002290#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002291 } else if (status & MII_GS_LINK) {
Joe Perches50624aa2011-03-01 06:56:33 +00002292 netdev_info(dev, "Link active\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002293 tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
2294 TLAN_LED_LINK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002295 }
2296 }
2297
Sakari Ailusc659c382011-01-21 10:59:30 +00002298 if (priv->phy_num == 0) {
2299 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
2300 tlphy_ctl |= TLAN_TC_INTEN;
2301 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
2302 sio = tlan_dio_read8(dev->base_addr, TLAN_NET_SIO);
2303 sio |= TLAN_NET_SIO_MINTEN;
2304 tlan_dio_write8(dev->base_addr, TLAN_NET_SIO, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305 }
2306
Sakari Ailusc659c382011-01-21 10:59:30 +00002307 if (status & MII_GS_LINK) {
2308 tlan_set_mac(dev, 0, dev->dev_addr);
2309 priv->phy_online = 1;
2310 outb((TLAN_HC_INT_ON >> 8), dev->base_addr + TLAN_HOST_CMD + 1);
2311 if (debug >= 1 && debug != TLAN_DEBUG_PROBE)
2312 outb((TLAN_HC_REQ_INT >> 8),
2313 dev->base_addr + TLAN_HOST_CMD + 1);
2314 outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM);
2315 outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316 netif_carrier_on(dev);
2317 } else {
Joe Perches50624aa2011-03-01 06:56:33 +00002318 netdev_info(dev, "Link inactive, will retry in 10 secs...\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002319 tlan_set_timer(dev, (10*HZ), TLAN_TIMER_FINISH_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320 return;
2321 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002322 tlan_set_multicast_list(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323
Sakari Ailusc659c382011-01-21 10:59:30 +00002324}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325
2326
2327
2328
Sakari Ailusc659c382011-01-21 10:59:30 +00002329/***************************************************************
2330 * tlan_set_mac
2331 *
2332 * Returns:
2333 * Nothing
2334 * Parms:
2335 * dev Pointer to device structure of adapter
2336 * on which to change the AREG.
2337 * areg The AREG to set the address in (0 - 3).
2338 * mac A pointer to an array of chars. Each
2339 * element stores one byte of the address.
2340 * IE, it isn't in ascii.
2341 *
2342 * This function transfers a MAC address to one of the
2343 * TLAN AREGs (address registers). The TLAN chip locks
2344 * the register on writing to offset 0 and unlocks the
2345 * register after writing to offset 5. If NULL is passed
2346 * in mac, then the AREG is filled with 0's.
2347 *
2348 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349
Sakari Ailusc659c382011-01-21 10:59:30 +00002350static void tlan_set_mac(struct net_device *dev, int areg, char *mac)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351{
2352 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002353
Linus Torvalds1da177e2005-04-16 15:20:36 -07002354 areg *= 6;
2355
Sakari Ailusc659c382011-01-21 10:59:30 +00002356 if (mac != NULL) {
2357 for (i = 0; i < 6; i++)
2358 tlan_dio_write8(dev->base_addr,
2359 TLAN_AREG_0 + areg + i, mac[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002361 for (i = 0; i < 6; i++)
2362 tlan_dio_write8(dev->base_addr,
2363 TLAN_AREG_0 + areg + i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364 }
2365
Sakari Ailusc659c382011-01-21 10:59:30 +00002366}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367
2368
2369
2370
2371/*****************************************************************************
2372******************************************************************************
2373
Sakari Ailusc659c382011-01-21 10:59:30 +00002374ThunderLAN driver PHY layer routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375
2376******************************************************************************
2377*****************************************************************************/
2378
2379
2380
Sakari Ailusc659c382011-01-21 10:59:30 +00002381/*********************************************************************
2382 * tlan_phy_print
2383 *
2384 * Returns:
2385 * Nothing
2386 * Parms:
2387 * dev A pointer to the device structure of the
2388 * TLAN device having the PHYs to be detailed.
2389 *
2390 * This function prints the registers a PHY (aka transceiver).
2391 *
2392 ********************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002393
Sakari Ailusc659c382011-01-21 10:59:30 +00002394static void tlan_phy_print(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002395{
Sakari Ailusc659c382011-01-21 10:59:30 +00002396 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397 u16 i, data0, data1, data2, data3, phy;
2398
Sakari Ailusc659c382011-01-21 10:59:30 +00002399 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400
Sakari Ailusc659c382011-01-21 10:59:30 +00002401 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
Joe Perches50624aa2011-03-01 06:56:33 +00002402 netdev_info(dev, "Unmanaged PHY\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002403 } else if (phy <= TLAN_PHY_MAX_ADDR) {
Joe Perches50624aa2011-03-01 06:56:33 +00002404 netdev_info(dev, "PHY 0x%02x\n", phy);
2405 pr_info(" Off. +0 +1 +2 +3\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002406 for (i = 0; i < 0x20; i += 4) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002407 tlan_mii_read_reg(dev, phy, i, &data0);
Sakari Ailusc659c382011-01-21 10:59:30 +00002408 tlan_mii_read_reg(dev, phy, i + 1, &data1);
Sakari Ailusc659c382011-01-21 10:59:30 +00002409 tlan_mii_read_reg(dev, phy, i + 2, &data2);
Sakari Ailusc659c382011-01-21 10:59:30 +00002410 tlan_mii_read_reg(dev, phy, i + 3, &data3);
Joe Perches50624aa2011-03-01 06:56:33 +00002411 pr_info(" 0x%02x 0x%04hx 0x%04hx 0x%04hx 0x%04hx\n",
2412 i, data0, data1, data2, data3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413 }
2414 } else {
Joe Perches50624aa2011-03-01 06:56:33 +00002415 netdev_info(dev, "Invalid PHY\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 }
2417
Sakari Ailusc659c382011-01-21 10:59:30 +00002418}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419
2420
2421
2422
Sakari Ailusc659c382011-01-21 10:59:30 +00002423/*********************************************************************
2424 * tlan_phy_detect
2425 *
2426 * Returns:
2427 * Nothing
2428 * Parms:
2429 * dev A pointer to the device structure of the adapter
2430 * for which the PHY needs determined.
2431 *
2432 * So far I've found that adapters which have external PHYs
2433 * may also use the internal PHY for part of the functionality.
2434 * (eg, AUI/Thinnet). This function finds out if this TLAN
2435 * chip has an internal PHY, and then finds the first external
2436 * PHY (starting from address 0) if it exists).
2437 *
2438 ********************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439
Sakari Ailusc659c382011-01-21 10:59:30 +00002440static void tlan_phy_detect(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441{
Sakari Ailusc659c382011-01-21 10:59:30 +00002442 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443 u16 control;
2444 u16 hi;
2445 u16 lo;
2446 u32 phy;
2447
Sakari Ailusc659c382011-01-21 10:59:30 +00002448 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
2449 priv->phy_num = 0xffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450 return;
2451 }
2452
Sakari Ailusc659c382011-01-21 10:59:30 +00002453 tlan_mii_read_reg(dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002454
Sakari Ailusc659c382011-01-21 10:59:30 +00002455 if (hi != 0xffff)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456 priv->phy[0] = TLAN_PHY_MAX_ADDR;
Sakari Ailusc659c382011-01-21 10:59:30 +00002457 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458 priv->phy[0] = TLAN_PHY_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002459
2460 priv->phy[1] = TLAN_PHY_NONE;
Sakari Ailusc659c382011-01-21 10:59:30 +00002461 for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) {
2462 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &control);
2463 tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &hi);
2464 tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &lo);
2465 if ((control != 0xffff) ||
2466 (hi != 0xffff) || (lo != 0xffff)) {
2467 TLAN_DBG(TLAN_DEBUG_GNRL,
2468 "PHY found at %02x %04x %04x %04x\n",
2469 phy, control, hi, lo);
2470 if ((priv->phy[1] == TLAN_PHY_NONE) &&
2471 (phy != TLAN_PHY_MAX_ADDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472 priv->phy[1] = phy;
2473 }
2474 }
2475 }
2476
Sakari Ailusc659c382011-01-21 10:59:30 +00002477 if (priv->phy[1] != TLAN_PHY_NONE)
2478 priv->phy_num = 1;
2479 else if (priv->phy[0] != TLAN_PHY_NONE)
2480 priv->phy_num = 0;
2481 else
Joe Perches50624aa2011-03-01 06:56:33 +00002482 netdev_info(dev, "Cannot initialize device, no PHY was found!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483
Sakari Ailusc659c382011-01-21 10:59:30 +00002484}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485
2486
2487
2488
Sakari Ailusc659c382011-01-21 10:59:30 +00002489static void tlan_phy_power_down(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490{
Sakari Ailusc659c382011-01-21 10:59:30 +00002491 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492 u16 value;
2493
Sakari Ailusc659c382011-01-21 10:59:30 +00002494 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495 value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
Sakari Ailusc659c382011-01-21 10:59:30 +00002496 tlan_mii_sync(dev->base_addr);
2497 tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
2498 if ((priv->phy_num == 0) &&
2499 (priv->phy[1] != TLAN_PHY_NONE) &&
2500 (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) {
2501 tlan_mii_sync(dev->base_addr);
2502 tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503 }
2504
2505 /* Wait for 50 ms and powerup
2506 * This is abitrary. It is intended to make sure the
2507 * transceiver settles.
2508 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002509 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_PUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002510
Sakari Ailusc659c382011-01-21 10:59:30 +00002511}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512
2513
2514
2515
Sakari Ailusc659c382011-01-21 10:59:30 +00002516static void tlan_phy_power_up(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002517{
Sakari Ailusc659c382011-01-21 10:59:30 +00002518 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002519 u16 value;
2520
Sakari Ailusc659c382011-01-21 10:59:30 +00002521 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name);
2522 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523 value = MII_GC_LOOPBK;
Sakari Ailusc659c382011-01-21 10:59:30 +00002524 tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
2525 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526 /* Wait for 500 ms and reset the
2527 * transceiver. The TLAN docs say both 50 ms and
2528 * 500 ms, so do the longer, just in case.
2529 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002530 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531
Sakari Ailusc659c382011-01-21 10:59:30 +00002532}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002533
2534
2535
2536
Sakari Ailusc659c382011-01-21 10:59:30 +00002537static void tlan_phy_reset(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002538{
Sakari Ailusc659c382011-01-21 10:59:30 +00002539 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540 u16 phy;
2541 u16 value;
2542
Sakari Ailusc659c382011-01-21 10:59:30 +00002543 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544
Masanari Iidafd9071e2012-04-13 04:33:20 +00002545 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Resetting PHY.\n", dev->name);
Sakari Ailusc659c382011-01-21 10:59:30 +00002546 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547 value = MII_GC_LOOPBK | MII_GC_RESET;
Sakari Ailusc659c382011-01-21 10:59:30 +00002548 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value);
2549 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
2550 while (value & MII_GC_RESET)
2551 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002552
2553 /* Wait for 500 ms and initialize.
2554 * I don't remember why I wait this long.
2555 * I've changed this to 50ms, as it seems long enough.
2556 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002557 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_START_LINK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558
Sakari Ailusc659c382011-01-21 10:59:30 +00002559}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560
2561
2562
2563
Sakari Ailusc659c382011-01-21 10:59:30 +00002564static void tlan_phy_start_link(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565{
Sakari Ailusc659c382011-01-21 10:59:30 +00002566 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567 u16 ability;
2568 u16 control;
2569 u16 data;
2570 u16 phy;
2571 u16 status;
2572 u16 tctl;
2573
Sakari Ailusc659c382011-01-21 10:59:30 +00002574 phy = priv->phy[priv->phy_num];
2575 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name);
2576 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2577 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &ability);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578
Sakari Ailusc659c382011-01-21 10:59:30 +00002579 if ((status & MII_GS_AUTONEG) &&
2580 (!priv->aui)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581 ability = status >> 11;
Sakari Ailusc659c382011-01-21 10:59:30 +00002582 if (priv->speed == TLAN_SPEED_10 &&
2583 priv->duplex == TLAN_DUPLEX_HALF) {
2584 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0000);
2585 } else if (priv->speed == TLAN_SPEED_10 &&
2586 priv->duplex == TLAN_DUPLEX_FULL) {
2587 priv->tlan_full_duplex = true;
2588 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0100);
2589 } else if (priv->speed == TLAN_SPEED_100 &&
2590 priv->duplex == TLAN_DUPLEX_HALF) {
2591 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2000);
2592 } else if (priv->speed == TLAN_SPEED_100 &&
2593 priv->duplex == TLAN_DUPLEX_FULL) {
2594 priv->tlan_full_duplex = true;
2595 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2100);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596 } else {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002597
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598 /* Set Auto-Neg advertisement */
Sakari Ailusc659c382011-01-21 10:59:30 +00002599 tlan_mii_write_reg(dev, phy, MII_AN_ADV,
2600 (ability << 5) | 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002601 /* Enablee Auto-Neg */
Sakari Ailusc659c382011-01-21 10:59:30 +00002602 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1000);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603 /* Restart Auto-Neg */
Sakari Ailusc659c382011-01-21 10:59:30 +00002604 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1200);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605 /* Wait for 4 sec for autonegotiation
Sakari Ailusc659c382011-01-21 10:59:30 +00002606 * to complete. The max spec time is less than this
2607 * but the card need additional time to start AN.
2608 * .5 sec should be plenty extra.
2609 */
Joe Perches50624aa2011-03-01 06:56:33 +00002610 netdev_info(dev, "Starting autonegotiation\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002611 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612 return;
2613 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002614
2615 }
2616
Sakari Ailusc659c382011-01-21 10:59:30 +00002617 if ((priv->aui) && (priv->phy_num != 0)) {
2618 priv->phy_num = 0;
2619 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
2620 | TLAN_NET_CFG_PHY_EN;
2621 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
2622 tlan_set_timer(dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002623 return;
Sakari Ailusc659c382011-01-21 10:59:30 +00002624 } else if (priv->phy_num == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002625 control = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002626 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tctl);
2627 if (priv->aui) {
2628 tctl |= TLAN_TC_AUISEL;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002629 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002630 tctl &= ~TLAN_TC_AUISEL;
2631 if (priv->duplex == TLAN_DUPLEX_FULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002632 control |= MII_GC_DUPLEX;
Sakari Ailusc659c382011-01-21 10:59:30 +00002633 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002635 if (priv->speed == TLAN_SPEED_100)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 control |= MII_GC_SPEEDSEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002638 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, control);
2639 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640 }
2641
2642 /* Wait for 2 sec to give the transceiver time
2643 * to establish link.
2644 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002645 tlan_set_timer(dev, (4*HZ), TLAN_TIMER_FINISH_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646
Sakari Ailusc659c382011-01-21 10:59:30 +00002647}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648
2649
2650
2651
Sakari Ailusc659c382011-01-21 10:59:30 +00002652static void tlan_phy_finish_auto_neg(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653{
Sakari Ailusc659c382011-01-21 10:59:30 +00002654 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655 u16 an_adv;
2656 u16 an_lpa;
2657 u16 data;
2658 u16 mode;
2659 u16 phy;
2660 u16 status;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002661
Sakari Ailusc659c382011-01-21 10:59:30 +00002662 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663
Sakari Ailusc659c382011-01-21 10:59:30 +00002664 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2665 udelay(1000);
2666 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667
Sakari Ailusc659c382011-01-21 10:59:30 +00002668 if (!(status & MII_GS_AUTOCMPLT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 /* Wait for 8 sec to give the process
2670 * more time. Perhaps we should fail after a while.
2671 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002672 if (!priv->neg_be_verbose++) {
Joe Perches50624aa2011-03-01 06:56:33 +00002673 pr_info("Giving autonegotiation more time.\n");
2674 pr_info("Please check that your adapter has\n");
2675 pr_info("been properly connected to a HUB or Switch.\n");
2676 pr_info("Trying to establish link in the background...\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002677 }
2678 tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679 return;
2680 }
2681
Joe Perches50624aa2011-03-01 06:56:33 +00002682 netdev_info(dev, "Autonegotiation complete\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002683 tlan_mii_read_reg(dev, phy, MII_AN_ADV, &an_adv);
2684 tlan_mii_read_reg(dev, phy, MII_AN_LPA, &an_lpa);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685 mode = an_adv & an_lpa & 0x03E0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002686 if (mode & 0x0100)
2687 priv->tlan_full_duplex = true;
2688 else if (!(mode & 0x0080) && (mode & 0x0040))
2689 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690
Sakari Ailusc659c382011-01-21 10:59:30 +00002691 if ((!(mode & 0x0180)) &&
2692 (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) &&
2693 (priv->phy_num != 0)) {
2694 priv->phy_num = 0;
2695 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
2696 | TLAN_NET_CFG_PHY_EN;
2697 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
2698 tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699 return;
2700 }
2701
Sakari Ailusc659c382011-01-21 10:59:30 +00002702 if (priv->phy_num == 0) {
2703 if ((priv->duplex == TLAN_DUPLEX_FULL) ||
2704 (an_adv & an_lpa & 0x0040)) {
2705 tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
2706 MII_GC_AUTOENB | MII_GC_DUPLEX);
Joe Perches50624aa2011-03-01 06:56:33 +00002707 netdev_info(dev, "Starting internal PHY with FULL-DUPLEX\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002709 tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
2710 MII_GC_AUTOENB);
Joe Perches50624aa2011-03-01 06:56:33 +00002711 netdev_info(dev, "Starting internal PHY with HALF-DUPLEX\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002712 }
2713 }
2714
2715 /* Wait for 100 ms. No reason in partiticular.
2716 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002717 tlan_set_timer(dev, (HZ/10), TLAN_TIMER_FINISH_RESET);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002718
Sakari Ailusc659c382011-01-21 10:59:30 +00002719}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720
2721#ifdef MONITOR
2722
Sakari Ailusc659c382011-01-21 10:59:30 +00002723/*********************************************************************
2724 *
2725 * tlan_phy_monitor
2726 *
2727 * Returns:
2728 * None
2729 *
2730 * Params:
2731 * dev The device structure of this device.
2732 *
2733 *
2734 * This function monitors PHY condition by reading the status
2735 * register via the MII bus. This can be used to give info
2736 * about link changes (up/down), and possible switch to alternate
2737 * media.
2738 *
2739 *******************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740
Sakari Ailusc659c382011-01-21 10:59:30 +00002741void tlan_phy_monitor(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742{
Sakari Ailusc659c382011-01-21 10:59:30 +00002743 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744 u16 phy;
2745 u16 phy_status;
2746
Sakari Ailusc659c382011-01-21 10:59:30 +00002747 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748
Sakari Ailusc659c382011-01-21 10:59:30 +00002749 /* Get PHY status register */
2750 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &phy_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751
Sakari Ailusc659c382011-01-21 10:59:30 +00002752 /* Check if link has been lost */
2753 if (!(phy_status & MII_GS_LINK)) {
2754 if (priv->link) {
2755 priv->link = 0;
2756 printk(KERN_DEBUG "TLAN: %s has lost link\n",
2757 dev->name);
2758 netif_carrier_off(dev);
2759 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
2760 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002761 }
2762 }
2763
Sakari Ailusc659c382011-01-21 10:59:30 +00002764 /* Link restablished? */
2765 if ((phy_status & MII_GS_LINK) && !priv->link) {
2766 priv->link = 1;
2767 printk(KERN_DEBUG "TLAN: %s has reestablished link\n",
2768 dev->name);
7d17c1d2005-05-12 19:45:25 -04002769 netif_carrier_on(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00002770 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771
2772 /* Setup a new monitor */
Sakari Ailusc659c382011-01-21 10:59:30 +00002773 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002774}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002775
2776#endif /* MONITOR */
2777
2778
2779/*****************************************************************************
2780******************************************************************************
2781
Sakari Ailusc659c382011-01-21 10:59:30 +00002782ThunderLAN driver MII routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783
Sakari Ailusc659c382011-01-21 10:59:30 +00002784these routines are based on the information in chap. 2 of the
2785"ThunderLAN Programmer's Guide", pp. 15-24.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002786
2787******************************************************************************
2788*****************************************************************************/
2789
2790
Sakari Ailusc659c382011-01-21 10:59:30 +00002791/***************************************************************
2792 * tlan_mii_read_reg
2793 *
2794 * Returns:
2795 * false if ack received ok
2796 * true if no ack received or other error
2797 *
2798 * Parms:
2799 * dev The device structure containing
2800 * The io address and interrupt count
2801 * for this device.
2802 * phy The address of the PHY to be queried.
2803 * reg The register whose contents are to be
2804 * retrieved.
2805 * val A pointer to a variable to store the
2806 * retrieved value.
2807 *
2808 * This function uses the TLAN's MII bus to retrieve the contents
2809 * of a given register on a PHY. It sends the appropriate info
2810 * and then reads the 16-bit register value from the MII bus via
2811 * the TLAN SIO register.
2812 *
2813 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002814
Sakari Ailusc659c382011-01-21 10:59:30 +00002815static bool
2816tlan_mii_read_reg(struct net_device *dev, u16 phy, u16 reg, u16 *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817{
2818 u8 nack;
2819 u16 sio, tmp;
Sakari Ailusc659c382011-01-21 10:59:30 +00002820 u32 i;
Joe Perches37fce432010-01-12 20:59:13 +00002821 bool err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002822 int minten;
Sakari Ailusc659c382011-01-21 10:59:30 +00002823 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824 unsigned long flags = 0;
2825
Joe Perches37fce432010-01-12 20:59:13 +00002826 err = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2828 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002829
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 if (!in_irq())
2831 spin_lock_irqsave(&priv->lock, flags);
2832
Sakari Ailusc659c382011-01-21 10:59:30 +00002833 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834
Sakari Ailusc659c382011-01-21 10:59:30 +00002835 minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
2836 if (minten)
2837 tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838
Sakari Ailusc659c382011-01-21 10:59:30 +00002839 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */
2840 tlan_mii_send_data(dev->base_addr, 0x2, 2); /* read (10b) */
2841 tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */
2842 tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843
2844
Sakari Ailusc659c382011-01-21 10:59:30 +00002845 tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio); /* change direction */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846
Sakari Ailusc659c382011-01-21 10:59:30 +00002847 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* clock idle bit */
2848 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
2849 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* wait 300ns */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850
Sakari Ailusc659c382011-01-21 10:59:30 +00002851 nack = tlan_get_bit(TLAN_NET_SIO_MDATA, sio); /* check for ACK */
2852 tlan_set_bit(TLAN_NET_SIO_MCLK, sio); /* finish ACK */
2853 if (nack) { /* no ACK, so fake it */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854 for (i = 0; i < 16; i++) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002855 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2856 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857 }
2858 tmp = 0xffff;
Joe Perches37fce432010-01-12 20:59:13 +00002859 err = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 } else { /* ACK, so read data */
2861 for (tmp = 0, i = 0x8000; i; i >>= 1) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002862 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2863 if (tlan_get_bit(TLAN_NET_SIO_MDATA, sio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002864 tmp |= i;
Sakari Ailusc659c382011-01-21 10:59:30 +00002865 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 }
2867 }
2868
2869
Sakari Ailusc659c382011-01-21 10:59:30 +00002870 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
2871 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872
Sakari Ailusc659c382011-01-21 10:59:30 +00002873 if (minten)
2874 tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875
2876 *val = tmp;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002877
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 if (!in_irq())
2879 spin_unlock_irqrestore(&priv->lock, flags);
2880
2881 return err;
2882
Sakari Ailusc659c382011-01-21 10:59:30 +00002883}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884
2885
2886
2887
Sakari Ailusc659c382011-01-21 10:59:30 +00002888/***************************************************************
2889 * tlan_mii_send_data
2890 *
2891 * Returns:
2892 * Nothing
2893 * Parms:
2894 * base_port The base IO port of the adapter in
2895 * question.
2896 * dev The address of the PHY to be queried.
2897 * data The value to be placed on the MII bus.
2898 * num_bits The number of bits in data that are to
2899 * be placed on the MII bus.
2900 *
2901 * This function sends on sequence of bits on the MII
2902 * configuration bus.
2903 *
2904 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002905
Sakari Ailusc659c382011-01-21 10:59:30 +00002906static void tlan_mii_send_data(u16 base_port, u32 data, unsigned num_bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907{
2908 u16 sio;
2909 u32 i;
2910
Sakari Ailusc659c382011-01-21 10:59:30 +00002911 if (num_bits == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002912 return;
2913
Sakari Ailusc659c382011-01-21 10:59:30 +00002914 outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
Sakari Ailusc659c382011-01-21 10:59:30 +00002916 tlan_set_bit(TLAN_NET_SIO_MTXEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917
Sakari Ailusc659c382011-01-21 10:59:30 +00002918 for (i = (0x1 << (num_bits - 1)); i; i >>= 1) {
2919 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2920 (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
2921 if (data & i)
2922 tlan_set_bit(TLAN_NET_SIO_MDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923 else
Sakari Ailusc659c382011-01-21 10:59:30 +00002924 tlan_clear_bit(TLAN_NET_SIO_MDATA, sio);
2925 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
2926 (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 }
2928
Sakari Ailusc659c382011-01-21 10:59:30 +00002929}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930
2931
2932
2933
Sakari Ailusc659c382011-01-21 10:59:30 +00002934/***************************************************************
2935 * TLan_MiiSync
2936 *
2937 * Returns:
2938 * Nothing
2939 * Parms:
2940 * base_port The base IO port of the adapter in
2941 * question.
2942 *
2943 * This functions syncs all PHYs in terms of the MII configuration
2944 * bus.
2945 *
2946 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002947
Sakari Ailusc659c382011-01-21 10:59:30 +00002948static void tlan_mii_sync(u16 base_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002949{
2950 int i;
2951 u16 sio;
2952
Sakari Ailusc659c382011-01-21 10:59:30 +00002953 outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
2955
Sakari Ailusc659c382011-01-21 10:59:30 +00002956 tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio);
2957 for (i = 0; i < 32; i++) {
2958 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2959 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960 }
2961
Sakari Ailusc659c382011-01-21 10:59:30 +00002962}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963
2964
2965
2966
Sakari Ailusc659c382011-01-21 10:59:30 +00002967/***************************************************************
2968 * tlan_mii_write_reg
2969 *
2970 * Returns:
2971 * Nothing
2972 * Parms:
2973 * dev The device structure for the device
2974 * to write to.
2975 * phy The address of the PHY to be written to.
2976 * reg The register whose contents are to be
2977 * written.
2978 * val The value to be written to the register.
2979 *
2980 * This function uses the TLAN's MII bus to write the contents of a
2981 * given register on a PHY. It sends the appropriate info and then
2982 * writes the 16-bit register value from the MII configuration bus
2983 * via the TLAN SIO register.
2984 *
2985 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986
Sakari Ailusc659c382011-01-21 10:59:30 +00002987static void
2988tlan_mii_write_reg(struct net_device *dev, u16 phy, u16 reg, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002989{
2990 u16 sio;
2991 int minten;
2992 unsigned long flags = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002993 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994
2995 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2996 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002997
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998 if (!in_irq())
2999 spin_lock_irqsave(&priv->lock, flags);
3000
Sakari Ailusc659c382011-01-21 10:59:30 +00003001 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002
Sakari Ailusc659c382011-01-21 10:59:30 +00003003 minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
3004 if (minten)
3005 tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006
Sakari Ailusc659c382011-01-21 10:59:30 +00003007 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */
3008 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* write (01b) */
3009 tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */
3010 tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011
Sakari Ailusc659c382011-01-21 10:59:30 +00003012 tlan_mii_send_data(dev->base_addr, 0x2, 2); /* send ACK */
3013 tlan_mii_send_data(dev->base_addr, val, 16); /* send data */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003014
Sakari Ailusc659c382011-01-21 10:59:30 +00003015 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
3016 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017
Sakari Ailusc659c382011-01-21 10:59:30 +00003018 if (minten)
3019 tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003020
Linus Torvalds1da177e2005-04-16 15:20:36 -07003021 if (!in_irq())
3022 spin_unlock_irqrestore(&priv->lock, flags);
3023
Sakari Ailusc659c382011-01-21 10:59:30 +00003024}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003025
3026
3027
3028
3029/*****************************************************************************
3030******************************************************************************
3031
Sakari Ailusc659c382011-01-21 10:59:30 +00003032ThunderLAN driver eeprom routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033
Sakari Ailusc659c382011-01-21 10:59:30 +00003034the Compaq netelligent 10 and 10/100 cards use a microchip 24C02A
3035EEPROM. these functions are based on information in microchip's
3036data sheet. I don't know how well this functions will work with
3037other Eeproms.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003038
3039******************************************************************************
3040*****************************************************************************/
3041
3042
Sakari Ailusc659c382011-01-21 10:59:30 +00003043/***************************************************************
3044 * tlan_ee_send_start
3045 *
3046 * Returns:
3047 * Nothing
3048 * Parms:
3049 * io_base The IO port base address for the
3050 * TLAN device with the EEPROM to
3051 * use.
3052 *
3053 * This function sends a start cycle to an EEPROM attached
3054 * to a TLAN chip.
3055 *
3056 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003057
Sakari Ailusc659c382011-01-21 10:59:30 +00003058static void tlan_ee_send_start(u16 io_base)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003059{
3060 u16 sio;
3061
Sakari Ailusc659c382011-01-21 10:59:30 +00003062 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003063 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3064
Sakari Ailusc659c382011-01-21 10:59:30 +00003065 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3066 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
3067 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
3068 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3069 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003070
Sakari Ailusc659c382011-01-21 10:59:30 +00003071}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072
3073
3074
3075
Sakari Ailusc659c382011-01-21 10:59:30 +00003076/***************************************************************
3077 * tlan_ee_send_byte
3078 *
3079 * Returns:
3080 * If the correct ack was received, 0, otherwise 1
3081 * Parms: io_base The IO port base address for the
3082 * TLAN device with the EEPROM to
3083 * use.
3084 * data The 8 bits of information to
3085 * send to the EEPROM.
3086 * stop If TLAN_EEPROM_STOP is passed, a
3087 * stop cycle is sent after the
3088 * byte is sent after the ack is
3089 * read.
3090 *
3091 * This function sends a byte on the serial EEPROM line,
3092 * driving the clock to send each bit. The function then
3093 * reverses transmission direction and reads an acknowledge
3094 * bit.
3095 *
3096 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003097
Sakari Ailusc659c382011-01-21 10:59:30 +00003098static int tlan_ee_send_byte(u16 io_base, u8 data, int stop)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003099{
3100 int err;
3101 u8 place;
3102 u16 sio;
3103
Sakari Ailusc659c382011-01-21 10:59:30 +00003104 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3106
3107 /* Assume clock is low, tx is enabled; */
Sakari Ailusc659c382011-01-21 10:59:30 +00003108 for (place = 0x80; place != 0; place >>= 1) {
3109 if (place & data)
3110 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111 else
Sakari Ailusc659c382011-01-21 10:59:30 +00003112 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3113 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3114 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003115 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003116 tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
3117 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3118 err = tlan_get_bit(TLAN_NET_SIO_EDATA, sio);
3119 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
3120 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003121
Sakari Ailusc659c382011-01-21 10:59:30 +00003122 if ((!err) && stop) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003123 /* STOP, raise data while clock is high */
Sakari Ailusc659c382011-01-21 10:59:30 +00003124 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3125 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3126 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127 }
3128
Eric Dumazet807540b2010-09-23 05:40:09 +00003129 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130
Sakari Ailusc659c382011-01-21 10:59:30 +00003131}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003132
3133
3134
3135
Sakari Ailusc659c382011-01-21 10:59:30 +00003136/***************************************************************
3137 * tlan_ee_receive_byte
3138 *
3139 * Returns:
3140 * Nothing
3141 * Parms:
3142 * io_base The IO port base address for the
3143 * TLAN device with the EEPROM to
3144 * use.
3145 * data An address to a char to hold the
3146 * data sent from the EEPROM.
3147 * stop If TLAN_EEPROM_STOP is passed, a
3148 * stop cycle is sent after the
3149 * byte is received, and no ack is
3150 * sent.
3151 *
3152 * This function receives 8 bits of data from the EEPROM
3153 * over the serial link. It then sends and ack bit, or no
3154 * ack and a stop bit. This function is used to retrieve
3155 * data after the address of a byte in the EEPROM has been
3156 * sent.
3157 *
3158 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003159
Sakari Ailusc659c382011-01-21 10:59:30 +00003160static void tlan_ee_receive_byte(u16 io_base, u8 *data, int stop)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161{
3162 u8 place;
3163 u16 sio;
3164
Sakari Ailusc659c382011-01-21 10:59:30 +00003165 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003166 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3167 *data = 0;
3168
3169 /* Assume clock is low, tx is enabled; */
Sakari Ailusc659c382011-01-21 10:59:30 +00003170 tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
3171 for (place = 0x80; place; place >>= 1) {
3172 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3173 if (tlan_get_bit(TLAN_NET_SIO_EDATA, sio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003174 *data |= place;
Sakari Ailusc659c382011-01-21 10:59:30 +00003175 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003176 }
3177
Sakari Ailusc659c382011-01-21 10:59:30 +00003178 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
3179 if (!stop) {
3180 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); /* ack = 0 */
3181 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3182 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00003184 tlan_set_bit(TLAN_NET_SIO_EDATA, sio); /* no ack = 1 (?) */
3185 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3186 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003187 /* STOP, raise data while clock is high */
Sakari Ailusc659c382011-01-21 10:59:30 +00003188 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3189 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3190 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191 }
3192
Sakari Ailusc659c382011-01-21 10:59:30 +00003193}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194
3195
3196
3197
Sakari Ailusc659c382011-01-21 10:59:30 +00003198/***************************************************************
3199 * tlan_ee_read_byte
3200 *
3201 * Returns:
3202 * No error = 0, else, the stage at which the error
3203 * occurred.
3204 * Parms:
3205 * io_base The IO port base address for the
3206 * TLAN device with the EEPROM to
3207 * use.
3208 * ee_addr The address of the byte in the
3209 * EEPROM whose contents are to be
3210 * retrieved.
3211 * data An address to a char to hold the
3212 * data obtained from the EEPROM.
3213 *
3214 * This function reads a byte of information from an byte
3215 * cell in the EEPROM.
3216 *
3217 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003218
Sakari Ailusc659c382011-01-21 10:59:30 +00003219static int tlan_ee_read_byte(struct net_device *dev, u8 ee_addr, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003220{
3221 int err;
Sakari Ailusc659c382011-01-21 10:59:30 +00003222 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003223 unsigned long flags = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00003224 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003225
3226 spin_lock_irqsave(&priv->lock, flags);
3227
Sakari Ailusc659c382011-01-21 10:59:30 +00003228 tlan_ee_send_start(dev->base_addr);
3229 err = tlan_ee_send_byte(dev->base_addr, 0xa0, TLAN_EEPROM_ACK);
3230 if (err) {
3231 ret = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003232 goto fail;
3233 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003234 err = tlan_ee_send_byte(dev->base_addr, ee_addr, TLAN_EEPROM_ACK);
3235 if (err) {
3236 ret = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237 goto fail;
3238 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003239 tlan_ee_send_start(dev->base_addr);
3240 err = tlan_ee_send_byte(dev->base_addr, 0xa1, TLAN_EEPROM_ACK);
3241 if (err) {
3242 ret = 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003243 goto fail;
3244 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003245 tlan_ee_receive_byte(dev->base_addr, data, TLAN_EEPROM_STOP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003246fail:
3247 spin_unlock_irqrestore(&priv->lock, flags);
3248
3249 return ret;
3250
Sakari Ailusc659c382011-01-21 10:59:30 +00003251}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003252
3253
3254