blob: efd36691ce5450881dd14114037071708df4e7c1 [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
Sakari Ailusc659c382011-01-21 10:59:30 +0000303static void __devexit tlan_remove_one(struct pci_dev *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304{
Sakari Ailusc659c382011-01-21 10:59:30 +0000305 struct net_device *dev = pci_get_drvdata(pdev);
306 struct tlan_priv *priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400307
Sakari Ailusc659c382011-01-21 10:59:30 +0000308 unregister_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309
Sakari Ailusc659c382011-01-21 10:59:30 +0000310 if (priv->dma_storage) {
311 pci_free_consistent(priv->pci_dev,
312 priv->dma_size, priv->dma_storage,
313 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 }
315
316#ifdef CONFIG_PCI
317 pci_release_regions(pdev);
318#endif
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400319
Sakari Ailusc659c382011-01-21 10:59:30 +0000320 free_netdev(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400321
Sakari Ailusc659c382011-01-21 10:59:30 +0000322 pci_set_drvdata(pdev, NULL);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400323}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000325static void tlan_start(struct net_device *dev)
326{
327 tlan_reset_lists(dev);
328 /* NOTE: It might not be necessary to read the stats before a
329 reset if you don't care what the values are.
330 */
331 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
332 tlan_reset_adapter(dev);
333 netif_wake_queue(dev);
334}
335
336static void tlan_stop(struct net_device *dev)
337{
338 struct tlan_priv *priv = netdev_priv(dev);
339
340 tlan_read_and_clear_stats(dev, TLAN_RECORD);
341 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
342 /* Reset and power down phy */
343 tlan_reset_adapter(dev);
344 if (priv->timer.function != NULL) {
345 del_timer_sync(&priv->timer);
346 priv->timer.function = NULL;
347 }
348}
349
350#ifdef CONFIG_PM
351
352static int tlan_suspend(struct pci_dev *pdev, pm_message_t state)
353{
354 struct net_device *dev = pci_get_drvdata(pdev);
355
356 if (netif_running(dev))
357 tlan_stop(dev);
358
359 netif_device_detach(dev);
360 pci_save_state(pdev);
361 pci_disable_device(pdev);
362 pci_wake_from_d3(pdev, false);
363 pci_set_power_state(pdev, PCI_D3hot);
364
365 return 0;
366}
367
368static int tlan_resume(struct pci_dev *pdev)
369{
370 struct net_device *dev = pci_get_drvdata(pdev);
371
372 pci_set_power_state(pdev, PCI_D0);
373 pci_restore_state(pdev);
374 pci_enable_wake(pdev, 0, 0);
375 netif_device_attach(dev);
376
377 if (netif_running(dev))
378 tlan_start(dev);
379
380 return 0;
381}
382
383#else /* CONFIG_PM */
384
385#define tlan_suspend NULL
386#define tlan_resume NULL
387
388#endif /* CONFIG_PM */
389
390
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391static struct pci_driver tlan_driver = {
392 .name = "tlan",
393 .id_table = tlan_pci_tbl,
394 .probe = tlan_init_one,
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400395 .remove = __devexit_p(tlan_remove_one),
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000396 .suspend = tlan_suspend,
397 .resume = tlan_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398};
399
400static int __init tlan_probe(void)
401{
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800402 int rc = -ENODEV;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400403
Joe Perches50624aa2011-03-01 06:56:33 +0000404 pr_info("%s", tlan_banner);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400405
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 /* Use new style PCI probing. Now the kernel will
409 do most of this for us */
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800410 rc = pci_register_driver(&tlan_driver);
411
412 if (rc != 0) {
Joe Perches50624aa2011-03-01 06:56:33 +0000413 pr_err("Could not register pci driver\n");
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800414 goto err_out_pci_free;
415 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
417 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000418 tlan_eisa_probe();
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400419
Joe Perches50624aa2011-03-01 06:56:33 +0000420 pr_info("%d device%s installed, PCI: %d EISA: %d\n",
421 tlan_devices_installed, tlan_devices_installed == 1 ? "" : "s",
422 tlan_have_pci, tlan_have_eisa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423
Sakari Ailusc659c382011-01-21 10:59:30 +0000424 if (tlan_devices_installed == 0) {
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800425 rc = -ENODEV;
426 goto err_out_pci_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 }
428 return 0;
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800429
430err_out_pci_unreg:
431 pci_unregister_driver(&tlan_driver);
432err_out_pci_free:
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800433 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400435
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436
Sakari Ailusc659c382011-01-21 10:59:30 +0000437static int __devinit tlan_init_one(struct pci_dev *pdev,
438 const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439{
Sakari Ailusc659c382011-01-21 10:59:30 +0000440 return tlan_probe1(pdev, -1, -1, 0, ent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441}
442
443
444/*
Sakari Ailusc659c382011-01-21 10:59:30 +0000445***************************************************************
446* tlan_probe1
447*
448* Returns:
449* 0 on success, error code on error
450* Parms:
451* none
452*
453* The name is lower case to fit in with all the rest of
454* the netcard_probe names. This function looks for
455* another TLan based adapter, setting it up with the
456* allocated device struct if one is found.
457* tlan_probe has been ported to the new net API and
458* now allocates its own device structure. This function
459* is also used by modules.
460*
461**************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462
Sakari Ailusc659c382011-01-21 10:59:30 +0000463static int __devinit tlan_probe1(struct pci_dev *pdev,
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700464 long ioaddr, int irq, int rev,
Sakari Ailusc659c382011-01-21 10:59:30 +0000465 const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466{
467
468 struct net_device *dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000469 struct tlan_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 u16 device_id;
471 int reg, rc = -ENODEV;
472
Adrian Bunkad9f6712006-02-05 00:37:47 +0100473#ifdef CONFIG_PCI
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 if (pdev) {
475 rc = pci_enable_device(pdev);
476 if (rc)
477 return rc;
478
Sakari Ailusc659c382011-01-21 10:59:30 +0000479 rc = pci_request_regions(pdev, tlan_signature);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000481 pr_err("Could not reserve IO regions\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 goto err_out;
483 }
484 }
Adrian Bunkad9f6712006-02-05 00:37:47 +0100485#endif /* CONFIG_PCI */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
Sakari Ailusc659c382011-01-21 10:59:30 +0000487 dev = alloc_etherdev(sizeof(struct tlan_priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488 if (dev == NULL) {
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);
536 priv->is_eisa = 1;
537 if (device_id == 0x20F1) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000538 priv->adapter = &board_info[13]; /* NetFlex-3/E */
539 priv->adapter_rev = 23; /* TLAN 2.3 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 } else {
541 priv->adapter = &board_info[14];
Sakari Ailusc659c382011-01-21 10:59:30 +0000542 priv->adapter_rev = 10; /* TLAN 1.0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 }
544 dev->base_addr = ioaddr;
545 dev->irq = irq;
546 }
547
548 /* Kernel parameters */
549 if (dev->mem_start) {
550 priv->aui = dev->mem_start & 0x01;
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700551 priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0
552 : (dev->mem_start & 0x06) >> 1;
553 priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0
554 : (dev->mem_start & 0x18) >> 3;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400555
Sakari Ailusc659c382011-01-21 10:59:30 +0000556 if (priv->speed == 0x1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 priv->speed = TLAN_SPEED_10;
Sakari Ailusc659c382011-01-21 10:59:30 +0000558 else if (priv->speed == 0x2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 priv->speed = TLAN_SPEED_100;
Sakari Ailusc659c382011-01-21 10:59:30 +0000560
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 debug = priv->debug = dev->mem_end;
562 } else {
563 priv->aui = aui[boards_found];
564 priv->speed = speed[boards_found];
565 priv->duplex = duplex[boards_found];
566 priv->debug = debug;
567 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400568
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 /* This will be used when we get an adapter error from
570 * within our irq handler */
Sakari Ailusc659c382011-01-21 10:59:30 +0000571 INIT_WORK(&priv->tlan_tqueue, tlan_tx_timeout_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572
573 spin_lock_init(&priv->lock);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400574
Sakari Ailusc659c382011-01-21 10:59:30 +0000575 rc = tlan_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000577 pr_err("Could not set up device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 goto err_out_free_dev;
579 }
580
581 rc = register_netdev(dev);
582 if (rc) {
Joe Perches50624aa2011-03-01 06:56:33 +0000583 pr_err("Could not register device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 goto err_out_uninit;
585 }
586
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400587
Sakari Ailusc659c382011-01-21 10:59:30 +0000588 tlan_devices_installed++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 boards_found++;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400590
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 /* pdev is NULL if this is an EISA device */
592 if (pdev)
593 tlan_have_pci++;
594 else {
Sakari Ailusc659c382011-01-21 10:59:30 +0000595 priv->next_device = tlan_eisa_devices;
596 tlan_eisa_devices = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 tlan_have_eisa++;
598 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400599
Joe Perches50624aa2011-03-01 06:56:33 +0000600 netdev_info(dev, "irq=%2d, io=%04x, %s, Rev. %d\n",
601 (int)dev->irq,
602 (int)dev->base_addr,
603 priv->adapter->device_label,
604 priv->adapter_rev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 return 0;
606
607err_out_uninit:
Sakari Ailusc659c382011-01-21 10:59:30 +0000608 pci_free_consistent(priv->pci_dev, priv->dma_size, priv->dma_storage,
609 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610err_out_free_dev:
611 free_netdev(dev);
612err_out_regions:
613#ifdef CONFIG_PCI
614 if (pdev)
615 pci_release_regions(pdev);
616#endif
617err_out:
618 if (pdev)
619 pci_disable_device(pdev);
620 return rc;
621}
622
623
Sakari Ailusc659c382011-01-21 10:59:30 +0000624static void tlan_eisa_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625{
626 struct net_device *dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000627 struct tlan_priv *priv;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400628
Sakari Ailusc659c382011-01-21 10:59:30 +0000629 while (tlan_have_eisa) {
630 dev = tlan_eisa_devices;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 priv = netdev_priv(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +0000632 if (priv->dma_storage) {
633 pci_free_consistent(priv->pci_dev, priv->dma_size,
634 priv->dma_storage,
635 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000637 release_region(dev->base_addr, 0x10);
638 unregister_netdev(dev);
639 tlan_eisa_devices = priv->next_device;
640 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 tlan_have_eisa--;
642 }
643}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400644
645
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646static void __exit tlan_exit(void)
647{
648 pci_unregister_driver(&tlan_driver);
649
650 if (tlan_have_eisa)
Sakari Ailusc659c382011-01-21 10:59:30 +0000651 tlan_eisa_cleanup();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653}
654
655
656/* Module loading/unloading */
657module_init(tlan_probe);
658module_exit(tlan_exit);
659
660
661
Sakari Ailusc659c382011-01-21 10:59:30 +0000662/**************************************************************
663 * tlan_eisa_probe
664 *
665 * Returns: 0 on success, 1 otherwise
666 *
667 * Parms: None
668 *
669 *
670 * This functions probes for EISA devices and calls
671 * TLan_probe1 when one is found.
672 *
673 *************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674
Sakari Ailusc659c382011-01-21 10:59:30 +0000675static void __init tlan_eisa_probe(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676{
Sakari Ailusc659c382011-01-21 10:59:30 +0000677 long ioaddr;
678 int rc = -ENODEV;
679 int irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 u16 device_id;
681
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400682 if (!EISA_bus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700683 TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
684 return;
685 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400686
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 /* Loop through all slots of the EISA bus */
688 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400689
Sakari Ailusc659c382011-01-21 10:59:30 +0000690 TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
691 (int) ioaddr + 0xc80, inw(ioaddr + EISA_ID));
692 TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
693 (int) ioaddr + 0xc82, inw(ioaddr + EISA_ID2));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694
695
Sakari Ailusc659c382011-01-21 10:59:30 +0000696 TLAN_DBG(TLAN_DEBUG_PROBE,
697 "Probing for EISA adapter at IO: 0x%4x : ",
698 (int) ioaddr);
699 if (request_region(ioaddr, 0x10, tlan_signature) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 goto out;
701
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400702 if (inw(ioaddr + EISA_ID) != 0x110E) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 release_region(ioaddr, 0x10);
704 goto out;
705 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400706
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 device_id = inw(ioaddr + EISA_ID2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400708 if (device_id != 0x20F1 && device_id != 0x40F1) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000709 release_region(ioaddr, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700710 goto out;
711 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400712
Sakari Ailusc659c382011-01-21 10:59:30 +0000713 /* check if adapter is enabled */
714 if (inb(ioaddr + EISA_CR) != 0x1) {
715 release_region(ioaddr, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 goto out2;
717 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400718
719 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000720 pr_info("Found one\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
722
723 /* Get irq from board */
Sakari Ailusc659c382011-01-21 10:59:30 +0000724 switch (inb(ioaddr + 0xcc0)) {
725 case(0x10):
726 irq = 5;
727 break;
728 case(0x20):
729 irq = 9;
730 break;
731 case(0x40):
732 irq = 10;
733 break;
734 case(0x80):
735 irq = 11;
736 break;
737 default:
738 goto out;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400739 }
740
741
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 /* Setup the newly found eisa adapter */
Sakari Ailusc659c382011-01-21 10:59:30 +0000743 rc = tlan_probe1(NULL, ioaddr, irq,
744 12, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400746
Sakari Ailusc659c382011-01-21 10:59:30 +0000747out:
748 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000749 pr_info("None found\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000750 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751
Sakari Ailusc659c382011-01-21 10:59:30 +0000752out2:
753 if (debug == 0x10)
Joe Perches50624aa2011-03-01 06:56:33 +0000754 pr_info("Card found but it is not enabled, skipping\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000755 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400756
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 }
758
Sakari Ailusc659c382011-01-21 10:59:30 +0000759}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760
761#ifdef CONFIG_NET_POLL_CONTROLLER
Sakari Ailusc659c382011-01-21 10:59:30 +0000762static void tlan_poll(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763{
764 disable_irq(dev->irq);
Sakari Ailusc659c382011-01-21 10:59:30 +0000765 tlan_handle_interrupt(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 enable_irq(dev->irq);
767}
768#endif
769
Sakari Ailusc659c382011-01-21 10:59:30 +0000770static const struct net_device_ops tlan_netdev_ops = {
771 .ndo_open = tlan_open,
772 .ndo_stop = tlan_close,
773 .ndo_start_xmit = tlan_start_tx,
774 .ndo_tx_timeout = tlan_tx_timeout,
775 .ndo_get_stats = tlan_get_stats,
Jiri Pirkoafc4b132011-08-16 06:29:01 +0000776 .ndo_set_rx_mode = tlan_set_multicast_list,
Sakari Ailusc659c382011-01-21 10:59:30 +0000777 .ndo_do_ioctl = tlan_ioctl,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800778 .ndo_change_mtu = eth_change_mtu,
Sakari Ailusc659c382011-01-21 10:59:30 +0000779 .ndo_set_mac_address = eth_mac_addr,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800780 .ndo_validate_addr = eth_validate_addr,
781#ifdef CONFIG_NET_POLL_CONTROLLER
Sakari Ailusc659c382011-01-21 10:59:30 +0000782 .ndo_poll_controller = tlan_poll,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800783#endif
784};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400785
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786
787
Sakari Ailusc659c382011-01-21 10:59:30 +0000788/***************************************************************
789 * tlan_init
790 *
791 * Returns:
792 * 0 on success, error code otherwise.
793 * Parms:
794 * dev The structure of the device to be
795 * init'ed.
796 *
797 * This function completes the initialization of the
798 * device structure and driver. It reserves the IO
799 * addresses, allocates memory for the lists and bounce
800 * buffers, retrieves the MAC address from the eeprom
801 * and assignes the device's methods.
802 *
803 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804
Sakari Ailusc659c382011-01-21 10:59:30 +0000805static int tlan_init(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806{
807 int dma_size;
Sakari Ailusc659c382011-01-21 10:59:30 +0000808 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +0000810 struct tlan_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
812 priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400813
Sakari Ailusc659c382011-01-21 10:59:30 +0000814 dma_size = (TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS)
815 * (sizeof(struct tlan_list));
816 priv->dma_storage = pci_alloc_consistent(priv->pci_dev,
817 dma_size,
818 &priv->dma_storage_dma);
819 priv->dma_size = dma_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400820
Sakari Ailusc659c382011-01-21 10:59:30 +0000821 if (priv->dma_storage == NULL) {
Joe Perches50624aa2011-03-01 06:56:33 +0000822 pr_err("Could not allocate lists and buffers for %s\n",
Sakari Ailusc659c382011-01-21 10:59:30 +0000823 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 return -ENOMEM;
825 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000826 memset(priv->dma_storage, 0, dma_size);
827 priv->rx_list = (struct tlan_list *)
828 ALIGN((unsigned long)priv->dma_storage, 8);
829 priv->rx_list_dma = ALIGN(priv->dma_storage_dma, 8);
830 priv->tx_list = priv->rx_list + TLAN_NUM_RX_LISTS;
831 priv->tx_list_dma =
832 priv->rx_list_dma + sizeof(struct tlan_list)*TLAN_NUM_RX_LISTS;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700833
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 err = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +0000835 for (i = 0; i < 6 ; i++)
836 err |= tlan_ee_read_byte(dev,
837 (u8) priv->adapter->addr_ofs + i,
838 (u8 *) &dev->dev_addr[i]);
839 if (err) {
Joe Perches50624aa2011-03-01 06:56:33 +0000840 pr_err("%s: Error reading MAC from eeprom: %d\n",
841 dev->name, err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 }
843 dev->addr_len = 6;
844
845 netif_carrier_off(dev);
846
847 /* Device methods */
Sakari Ailusc659c382011-01-21 10:59:30 +0000848 dev->netdev_ops = &tlan_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 dev->watchdog_timeo = TX_TIMEOUT;
850
851 return 0;
852
Sakari Ailusc659c382011-01-21 10:59:30 +0000853}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854
855
856
857
Sakari Ailusc659c382011-01-21 10:59:30 +0000858/***************************************************************
859 * tlan_open
860 *
861 * Returns:
862 * 0 on success, error code otherwise.
863 * Parms:
864 * dev Structure of device to be opened.
865 *
866 * This routine puts the driver and TLAN adapter in a
867 * state where it is ready to send and receive packets.
868 * It allocates the IRQ, resets and brings the adapter
869 * out of reset, and allows interrupts. It also delays
870 * the startup for autonegotiation or sends a Rx GO
871 * command to the adapter, as appropriate.
872 *
873 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874
Sakari Ailusc659c382011-01-21 10:59:30 +0000875static int tlan_open(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876{
Sakari Ailusc659c382011-01-21 10:59:30 +0000877 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878 int err;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400879
Sakari Ailusc659c382011-01-21 10:59:30 +0000880 priv->tlan_rev = tlan_dio_read8(dev->base_addr, TLAN_DEF_REVISION);
881 err = request_irq(dev->irq, tlan_handle_interrupt, IRQF_SHARED,
882 dev->name, dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400883
Sakari Ailusc659c382011-01-21 10:59:30 +0000884 if (err) {
Joe Perches50624aa2011-03-01 06:56:33 +0000885 netdev_err(dev, "Cannot open because IRQ %d is already in use\n",
886 dev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 return err;
888 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400889
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 init_timer(&priv->timer);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400891
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000892 tlan_start(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893
Sakari Ailusc659c382011-01-21 10:59:30 +0000894 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n",
895 dev->name, priv->tlan_rev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896
897 return 0;
898
Sakari Ailusc659c382011-01-21 10:59:30 +0000899}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900
901
902
Sakari Ailusc659c382011-01-21 10:59:30 +0000903/**************************************************************
904 * tlan_ioctl
905 *
906 * Returns:
907 * 0 on success, error code otherwise
908 * Params:
909 * dev structure of device to receive ioctl.
910 *
911 * rq ifreq structure to hold userspace data.
912 *
913 * cmd ioctl command.
914 *
915 *
916 *************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917
Sakari Ailusc659c382011-01-21 10:59:30 +0000918static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919{
Sakari Ailusc659c382011-01-21 10:59:30 +0000920 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 struct mii_ioctl_data *data = if_mii(rq);
Sakari Ailusc659c382011-01-21 10:59:30 +0000922 u32 phy = priv->phy[priv->phy_num];
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400923
Sakari Ailusc659c382011-01-21 10:59:30 +0000924 if (!priv->phy_online)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 return -EAGAIN;
926
Sakari Ailusc659c382011-01-21 10:59:30 +0000927 switch (cmd) {
928 case SIOCGMIIPHY: /* get address of MII PHY in use. */
929 data->phy_id = phy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
931
Sakari Ailusc659c382011-01-21 10:59:30 +0000932 case SIOCGMIIREG: /* read MII PHY register. */
933 tlan_mii_read_reg(dev, data->phy_id & 0x1f,
934 data->reg_num & 0x1f, &data->val_out);
935 return 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400936
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937
Sakari Ailusc659c382011-01-21 10:59:30 +0000938 case SIOCSMIIREG: /* write MII PHY register. */
939 tlan_mii_write_reg(dev, data->phy_id & 0x1f,
940 data->reg_num & 0x1f, data->val_in);
941 return 0;
942 default:
943 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000945}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946
947
Sakari Ailusc659c382011-01-21 10:59:30 +0000948/***************************************************************
949 * tlan_tx_timeout
950 *
951 * Returns: nothing
952 *
953 * Params:
954 * dev structure of device which timed out
955 * during transmit.
956 *
957 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958
Sakari Ailusc659c382011-01-21 10:59:30 +0000959static void tlan_tx_timeout(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960{
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400961
Sakari Ailusc659c382011-01-21 10:59:30 +0000962 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400963
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964 /* Ok so we timed out, lets see what we can do about it...*/
Sakari Ailusc659c382011-01-21 10:59:30 +0000965 tlan_free_lists(dev);
966 tlan_reset_lists(dev);
967 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
968 tlan_reset_adapter(dev);
Eric Dumazet1ae5dc32010-05-10 05:01:31 -0700969 dev->trans_start = jiffies; /* prevent tx timeout */
Sakari Ailusc659c382011-01-21 10:59:30 +0000970 netif_wake_queue(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971
972}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400973
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974
Sakari Ailusc659c382011-01-21 10:59:30 +0000975/***************************************************************
976 * tlan_tx_timeout_work
977 *
978 * Returns: nothing
979 *
980 * Params:
981 * work work item of device which timed out
982 *
983 **************************************************************/
David Howellsc4028952006-11-22 14:57:56 +0000984
Sakari Ailusc659c382011-01-21 10:59:30 +0000985static void tlan_tx_timeout_work(struct work_struct *work)
David Howellsc4028952006-11-22 14:57:56 +0000986{
Sakari Ailusc659c382011-01-21 10:59:30 +0000987 struct tlan_priv *priv =
988 container_of(work, struct tlan_priv, tlan_tqueue);
David Howellsc4028952006-11-22 14:57:56 +0000989
Sakari Ailusc659c382011-01-21 10:59:30 +0000990 tlan_tx_timeout(priv->dev);
David Howellsc4028952006-11-22 14:57:56 +0000991}
992
993
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994
Sakari Ailusc659c382011-01-21 10:59:30 +0000995/***************************************************************
996 * tlan_start_tx
997 *
998 * Returns:
999 * 0 on success, non-zero on failure.
1000 * Parms:
1001 * skb A pointer to the sk_buff containing the
1002 * frame to be sent.
1003 * dev The device to send the data on.
1004 *
1005 * This function adds a frame to the Tx list to be sent
1006 * ASAP. First it verifies that the adapter is ready and
1007 * there is room in the queue. Then it sets up the next
1008 * available list, copies the frame to the corresponding
1009 * buffer. If the adapter Tx channel is idle, it gives
1010 * the adapter a Tx Go command on the list, otherwise it
1011 * sets the forward address of the previous list to point
1012 * to this one. Then it frees the sk_buff.
1013 *
1014 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015
Sakari Ailusc659c382011-01-21 10:59:30 +00001016static netdev_tx_t tlan_start_tx(struct sk_buff *skb, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001017{
Sakari Ailusc659c382011-01-21 10:59:30 +00001018 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019 dma_addr_t tail_list_phys;
Sakari Ailusc659c382011-01-21 10:59:30 +00001020 struct tlan_list *tail_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 unsigned long flags;
Sakari Ailus8953f122008-12-16 01:44:05 -08001022 unsigned int txlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023
Sakari Ailusc659c382011-01-21 10:59:30 +00001024 if (!priv->phy_online) {
1025 TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n",
1026 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 dev_kfree_skb_any(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001028 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 }
1030
Stephen Hemminger41873e92008-05-30 09:49:52 -07001031 if (skb_padto(skb, TLAN_MIN_FRAME_SIZE))
Patrick McHardy6ed10652009-06-23 06:03:08 +00001032 return NETDEV_TX_OK;
Sakari Ailus8953f122008-12-16 01:44:05 -08001033 txlen = max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE);
Stephen Hemminger41873e92008-05-30 09:49:52 -07001034
Sakari Ailusc659c382011-01-21 10:59:30 +00001035 tail_list = priv->tx_list + priv->tx_tail;
1036 tail_list_phys =
1037 priv->tx_list_dma + sizeof(struct tlan_list)*priv->tx_tail;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001038
Sakari Ailusc659c382011-01-21 10:59:30 +00001039 if (tail_list->c_stat != TLAN_CSTAT_UNUSED) {
1040 TLAN_DBG(TLAN_DEBUG_TX,
1041 "TRANSMIT: %s is busy (Head=%d Tail=%d)\n",
1042 dev->name, priv->tx_head, priv->tx_tail);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043 netif_stop_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001044 priv->tx_busy_count++;
Patrick McHardy5b548142009-06-12 06:22:29 +00001045 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 }
1047
1048 tail_list->forward = 0;
1049
Sakari Ailusc659c382011-01-21 10:59:30 +00001050 tail_list->buffer[0].address = pci_map_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001051 skb->data, txlen,
1052 PCI_DMA_TODEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001053 tlan_store_skb(tail_list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054
Sakari Ailusc659c382011-01-21 10:59:30 +00001055 tail_list->frame_size = (u16) txlen;
Sakari Ailus8953f122008-12-16 01:44:05 -08001056 tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) txlen;
Stephen Hemminger41873e92008-05-30 09:49:52 -07001057 tail_list->buffer[1].count = 0;
1058 tail_list->buffer[1].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
1060 spin_lock_irqsave(&priv->lock, flags);
Sakari Ailusc659c382011-01-21 10:59:30 +00001061 tail_list->c_stat = TLAN_CSTAT_READY;
1062 if (!priv->tx_in_progress) {
1063 priv->tx_in_progress = 1;
1064 TLAN_DBG(TLAN_DEBUG_TX,
1065 "TRANSMIT: Starting TX on buffer %d\n",
1066 priv->tx_tail);
1067 outl(tail_list_phys, dev->base_addr + TLAN_CH_PARM);
1068 outl(TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001070 TLAN_DBG(TLAN_DEBUG_TX,
1071 "TRANSMIT: Adding buffer %d to TX channel\n",
1072 priv->tx_tail);
1073 if (priv->tx_tail == 0) {
1074 (priv->tx_list + (TLAN_NUM_TX_LISTS - 1))->forward
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001075 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001077 (priv->tx_list + (priv->tx_tail - 1))->forward
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001078 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 }
1080 }
1081 spin_unlock_irqrestore(&priv->lock, flags);
1082
Sakari Ailusc659c382011-01-21 10:59:30 +00001083 CIRC_INC(priv->tx_tail, TLAN_NUM_TX_LISTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084
Patrick McHardy6ed10652009-06-23 06:03:08 +00001085 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086
Sakari Ailusc659c382011-01-21 10:59:30 +00001087}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
1089
1090
1091
Sakari Ailusc659c382011-01-21 10:59:30 +00001092/***************************************************************
1093 * tlan_handle_interrupt
1094 *
1095 * Returns:
1096 * Nothing
1097 * Parms:
1098 * irq The line on which the interrupt
1099 * occurred.
1100 * dev_id A pointer to the device assigned to
1101 * this irq line.
1102 *
1103 * This function handles an interrupt generated by its
1104 * assigned TLAN adapter. The function deactivates
1105 * interrupts on its adapter, records the type of
1106 * interrupt, executes the appropriate subhandler, and
1107 * acknowdges the interrupt to the adapter (thus
1108 * re-enabling adapter interrupts.
1109 *
1110 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111
Sakari Ailusc659c382011-01-21 10:59:30 +00001112static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113{
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001114 struct net_device *dev = dev_id;
Sakari Ailusc659c382011-01-21 10:59:30 +00001115 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 u16 host_int;
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001117 u16 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118
1119 spin_lock(&priv->lock);
1120
Sakari Ailusc659c382011-01-21 10:59:30 +00001121 host_int = inw(dev->base_addr + TLAN_HOST_INT);
1122 type = (host_int & TLAN_HI_IT_MASK) >> 2;
1123 if (type) {
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001124 u32 ack;
1125 u32 host_cmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126
Sakari Ailusc659c382011-01-21 10:59:30 +00001127 outw(host_int, dev->base_addr + TLAN_HOST_INT);
1128 ack = tlan_int_vector[type](dev, host_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129
Sakari Ailusc659c382011-01-21 10:59:30 +00001130 if (ack) {
1131 host_cmd = TLAN_HC_ACK | ack | (type << 18);
1132 outl(host_cmd, dev->base_addr + TLAN_HOST_CMD);
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001133 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 }
1135
1136 spin_unlock(&priv->lock);
1137
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001138 return IRQ_RETVAL(type);
Sakari Ailusc659c382011-01-21 10:59:30 +00001139}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140
1141
1142
1143
Sakari Ailusc659c382011-01-21 10:59:30 +00001144/***************************************************************
1145 * tlan_close
1146 *
1147 * Returns:
1148 * An error code.
1149 * Parms:
1150 * dev The device structure of the device to
1151 * close.
1152 *
1153 * This function shuts down the adapter. It records any
1154 * stats, puts the adapter into reset state, deactivates
1155 * its time as needed, and frees the irq it is using.
1156 *
1157 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158
Sakari Ailusc659c382011-01-21 10:59:30 +00001159static int tlan_close(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160{
Sakari Ailusc659c382011-01-21 10:59:30 +00001161 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163 priv->neg_be_verbose = 0;
Sakari Ailusfa6d5d42011-01-21 10:59:31 +00001164 tlan_stop(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001165
Sakari Ailusc659c382011-01-21 10:59:30 +00001166 free_irq(dev->irq, dev);
1167 tlan_free_lists(dev);
1168 TLAN_DBG(TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169
1170 return 0;
1171
Sakari Ailusc659c382011-01-21 10:59:30 +00001172}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173
1174
1175
1176
Sakari Ailusc659c382011-01-21 10:59:30 +00001177/***************************************************************
1178 * tlan_get_stats
1179 *
1180 * Returns:
1181 * A pointer to the device's statistics structure.
1182 * Parms:
1183 * dev The device structure to return the
1184 * stats for.
1185 *
1186 * This function updates the devices statistics by reading
1187 * the TLAN chip's onboard registers. Then it returns the
1188 * address of the statistics structure.
1189 *
1190 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191
Sakari Ailusc659c382011-01-21 10:59:30 +00001192static struct net_device_stats *tlan_get_stats(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193{
Sakari Ailusc659c382011-01-21 10:59:30 +00001194 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 int i;
1196
1197 /* Should only read stats if open ? */
Sakari Ailusc659c382011-01-21 10:59:30 +00001198 tlan_read_and_clear_stats(dev, TLAN_RECORD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199
Sakari Ailusc659c382011-01-21 10:59:30 +00001200 TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name,
1201 priv->rx_eoc_count);
1202 TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name,
1203 priv->tx_busy_count);
1204 if (debug & TLAN_DEBUG_GNRL) {
1205 tlan_print_dio(dev->base_addr);
1206 tlan_phy_print(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001208 if (debug & TLAN_DEBUG_LIST) {
1209 for (i = 0; i < TLAN_NUM_RX_LISTS; i++)
1210 tlan_print_list(priv->rx_list + i, "RX", i);
1211 for (i = 0; i < TLAN_NUM_TX_LISTS; i++)
1212 tlan_print_list(priv->tx_list + i, "TX", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001214
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001215 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216
Sakari Ailusc659c382011-01-21 10:59:30 +00001217}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
1219
1220
1221
Sakari Ailusc659c382011-01-21 10:59:30 +00001222/***************************************************************
1223 * tlan_set_multicast_list
1224 *
1225 * Returns:
1226 * Nothing
1227 * Parms:
1228 * dev The device structure to set the
1229 * multicast list for.
1230 *
1231 * This function sets the TLAN adaptor to various receive
1232 * modes. If the IFF_PROMISC flag is set, promiscuous
1233 * mode is acitviated. Otherwise, promiscuous mode is
1234 * turned off. If the IFF_ALLMULTI flag is set, then
1235 * the hash table is set to receive all group addresses.
1236 * Otherwise, the first three multicast addresses are
1237 * stored in AREG_1-3, and the rest are selected via the
1238 * hash table, as necessary.
1239 *
1240 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241
Sakari Ailusc659c382011-01-21 10:59:30 +00001242static void tlan_set_multicast_list(struct net_device *dev)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001243{
Jiri Pirko22bedad32010-04-01 21:22:57 +00001244 struct netdev_hw_addr *ha;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 u32 hash1 = 0;
1246 u32 hash2 = 0;
1247 int i;
1248 u32 offset;
1249 u8 tmp;
1250
Sakari Ailusc659c382011-01-21 10:59:30 +00001251 if (dev->flags & IFF_PROMISC) {
1252 tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
1253 tlan_dio_write8(dev->base_addr,
1254 TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001256 tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
1257 tlan_dio_write8(dev->base_addr,
1258 TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF);
1259 if (dev->flags & IFF_ALLMULTI) {
1260 for (i = 0; i < 3; i++)
1261 tlan_set_mac(dev, i + 1, NULL);
1262 tlan_dio_write32(dev->base_addr, TLAN_HASH_1,
1263 0xffffffff);
1264 tlan_dio_write32(dev->base_addr, TLAN_HASH_2,
1265 0xffffffff);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 } else {
Jiri Pirko567ec872010-02-23 23:17:07 +00001267 i = 0;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001268 netdev_for_each_mc_addr(ha, dev) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001269 if (i < 3) {
1270 tlan_set_mac(dev, i + 1,
Jiri Pirko22bedad32010-04-01 21:22:57 +00001271 (char *) &ha->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001273 offset =
1274 tlan_hash_func((u8 *)&ha->addr);
1275 if (offset < 32)
1276 hash1 |= (1 << offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 else
Sakari Ailusc659c382011-01-21 10:59:30 +00001278 hash2 |= (1 << (offset - 32));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 }
Jiri Pirko567ec872010-02-23 23:17:07 +00001280 i++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001282 for ( ; i < 3; i++)
1283 tlan_set_mac(dev, i + 1, NULL);
1284 tlan_dio_write32(dev->base_addr, TLAN_HASH_1, hash1);
1285 tlan_dio_write32(dev->base_addr, TLAN_HASH_2, hash2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286 }
1287 }
1288
Sakari Ailusc659c382011-01-21 10:59:30 +00001289}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290
1291
1292
1293/*****************************************************************************
1294******************************************************************************
1295
Sakari Ailusc659c382011-01-21 10:59:30 +00001296ThunderLAN driver interrupt vectors and table
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297
Sakari Ailusc659c382011-01-21 10:59:30 +00001298please see chap. 4, "Interrupt Handling" of the "ThunderLAN
1299Programmer's Guide" for more informations on handling interrupts
1300generated by TLAN based adapters.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301
1302******************************************************************************
1303*****************************************************************************/
1304
1305
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306
1307
Sakari Ailusc659c382011-01-21 10:59:30 +00001308/***************************************************************
1309 * tlan_handle_tx_eof
1310 *
1311 * Returns:
1312 * 1
1313 * Parms:
1314 * dev Device assigned the IRQ that was
1315 * raised.
1316 * host_int The contents of the HOST_INT
1317 * port.
1318 *
1319 * This function handles Tx EOF interrupts which are raised
1320 * by the adapter when it has completed sending the
1321 * contents of a buffer. If detemines which list/buffer
1322 * was completed and resets it. If the buffer was the last
1323 * in the channel (EOC), then the function checks to see if
1324 * another buffer is ready to send, and if so, sends a Tx
1325 * Go command. Finally, the driver activates/continues the
1326 * activity LED.
1327 *
1328 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329
Sakari Ailusc659c382011-01-21 10:59:30 +00001330static u32 tlan_handle_tx_eof(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331{
Sakari Ailusc659c382011-01-21 10:59:30 +00001332 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 int eoc = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001334 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 dma_addr_t head_list_phys;
1336 u32 ack = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001337 u16 tmp_c_stat;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001338
Sakari Ailusc659c382011-01-21 10:59:30 +00001339 TLAN_DBG(TLAN_DEBUG_TX,
1340 "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n",
1341 priv->tx_head, priv->tx_tail);
1342 head_list = priv->tx_list + priv->tx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343
Sakari Ailusc659c382011-01-21 10:59:30 +00001344 while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
1345 && (ack < 255)) {
1346 struct sk_buff *skb = tlan_get_skb(head_list);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001347
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348 ack++;
Sakari Ailusc659c382011-01-21 10:59:30 +00001349 pci_unmap_single(priv->pci_dev, head_list->buffer[0].address,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001350 max(skb->len,
1351 (unsigned int)TLAN_MIN_FRAME_SIZE),
1352 PCI_DMA_TODEVICE);
1353 dev_kfree_skb_any(skb);
1354 head_list->buffer[8].address = 0;
1355 head_list->buffer[9].address = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001356
Sakari Ailusc659c382011-01-21 10:59:30 +00001357 if (tmp_c_stat & TLAN_CSTAT_EOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001359
Sakari Ailusc659c382011-01-21 10:59:30 +00001360 dev->stats.tx_bytes += head_list->frame_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
Sakari Ailusc659c382011-01-21 10:59:30 +00001362 head_list->c_stat = TLAN_CSTAT_UNUSED;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001363 netif_start_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001364 CIRC_INC(priv->tx_head, TLAN_NUM_TX_LISTS);
1365 head_list = priv->tx_list + priv->tx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 }
1367
1368 if (!ack)
Joe Perches50624aa2011-03-01 06:56:33 +00001369 netdev_info(dev,
1370 "Received interrupt for uncompleted TX frame\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001371
Sakari Ailusc659c382011-01-21 10:59:30 +00001372 if (eoc) {
1373 TLAN_DBG(TLAN_DEBUG_TX,
1374 "TRANSMIT: handling TX EOC (Head=%d Tail=%d)\n",
1375 priv->tx_head, priv->tx_tail);
1376 head_list = priv->tx_list + priv->tx_head;
1377 head_list_phys = priv->tx_list_dma
1378 + sizeof(struct tlan_list)*priv->tx_head;
Sakari Ailusf45437e2011-02-09 10:25:06 +00001379 if ((head_list->c_stat & TLAN_CSTAT_READY)
1380 == TLAN_CSTAT_READY) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001381 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 ack |= TLAN_HC_GO;
1383 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001384 priv->tx_in_progress = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 }
1386 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001387
Sakari Ailusc659c382011-01-21 10:59:30 +00001388 if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
1389 tlan_dio_write8(dev->base_addr,
1390 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
1391 if (priv->timer.function == NULL) {
1392 priv->timer.function = tlan_timer;
1393 priv->timer.data = (unsigned long) dev;
1394 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1395 priv->timer_set_at = jiffies;
1396 priv->timer_type = TLAN_TIMER_ACTIVITY;
1397 add_timer(&priv->timer);
1398 } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
1399 priv->timer_set_at = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 }
1401 }
1402
1403 return ack;
1404
Sakari Ailusc659c382011-01-21 10:59:30 +00001405}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
1407
1408
1409
Sakari Ailusc659c382011-01-21 10:59:30 +00001410/***************************************************************
1411 * TLan_HandleStatOverflow
1412 *
1413 * Returns:
1414 * 1
1415 * Parms:
1416 * dev Device assigned the IRQ that was
1417 * raised.
1418 * host_int The contents of the HOST_INT
1419 * port.
1420 *
1421 * This function handles the Statistics Overflow interrupt
1422 * which means that one or more of the TLAN statistics
1423 * registers has reached 1/2 capacity and needs to be read.
1424 *
1425 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
Sakari Ailusc659c382011-01-21 10:59:30 +00001427static u32 tlan_handle_stat_overflow(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428{
Sakari Ailusc659c382011-01-21 10:59:30 +00001429 tlan_read_and_clear_stats(dev, TLAN_RECORD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430
1431 return 1;
1432
Sakari Ailusc659c382011-01-21 10:59:30 +00001433}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434
1435
1436
1437
Sakari Ailusc659c382011-01-21 10:59:30 +00001438/***************************************************************
1439 * TLan_HandleRxEOF
1440 *
1441 * Returns:
1442 * 1
1443 * Parms:
1444 * dev Device assigned the IRQ that was
1445 * raised.
1446 * host_int The contents of the HOST_INT
1447 * port.
1448 *
1449 * This function handles the Rx EOF interrupt which
1450 * indicates a frame has been received by the adapter from
1451 * the net and the frame has been transferred to memory.
1452 * The function determines the bounce buffer the frame has
1453 * been loaded into, creates a new sk_buff big enough to
1454 * hold the frame, and sends it to protocol stack. It
1455 * then resets the used buffer and appends it to the end
1456 * of the list. If the frame was the last in the Rx
1457 * channel (EOC), the function restarts the receive channel
1458 * by sending an Rx Go command to the adapter. Then it
1459 * activates/continues the activity LED.
1460 *
1461 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462
Sakari Ailusc659c382011-01-21 10:59:30 +00001463static u32 tlan_handle_rx_eof(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464{
Sakari Ailusc659c382011-01-21 10:59:30 +00001465 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 u32 ack = 0;
1467 int eoc = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001468 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 struct sk_buff *skb;
Sakari Ailusc659c382011-01-21 10:59:30 +00001470 struct tlan_list *tail_list;
1471 u16 tmp_c_stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 dma_addr_t head_list_phys;
1473
Sakari Ailusc659c382011-01-21 10:59:30 +00001474 TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: handling RX EOF (Head=%d Tail=%d)\n",
1475 priv->rx_head, priv->rx_tail);
1476 head_list = priv->rx_list + priv->rx_head;
1477 head_list_phys =
1478 priv->rx_list_dma + sizeof(struct tlan_list)*priv->rx_head;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001479
Sakari Ailusc659c382011-01-21 10:59:30 +00001480 while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
1481 && (ack < 255)) {
1482 dma_addr_t frame_dma = head_list->buffer[0].address;
1483 u32 frame_size = head_list->frame_size;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001484 struct sk_buff *new_skb;
1485
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 ack++;
Sakari Ailusc659c382011-01-21 10:59:30 +00001487 if (tmp_c_stat & TLAN_CSTAT_EOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001489
Eric Dumazet89d71a62009-10-13 05:34:20 +00001490 new_skb = netdev_alloc_skb_ip_align(dev,
1491 TLAN_MAX_FRAME_SIZE + 5);
Sakari Ailusc659c382011-01-21 10:59:30 +00001492 if (!new_skb)
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001493 goto drop_and_reuse;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001494
Sakari Ailusc659c382011-01-21 10:59:30 +00001495 skb = tlan_get_skb(head_list);
1496 pci_unmap_single(priv->pci_dev, frame_dma,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001497 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001498 skb_put(skb, frame_size);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001499
Sakari Ailusc659c382011-01-21 10:59:30 +00001500 dev->stats.rx_bytes += frame_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001501
Sakari Ailusc659c382011-01-21 10:59:30 +00001502 skb->protocol = eth_type_trans(skb, dev);
1503 netif_rx(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504
Sakari Ailusc659c382011-01-21 10:59:30 +00001505 head_list->buffer[0].address =
1506 pci_map_single(priv->pci_dev, new_skb->data,
1507 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508
Sakari Ailusc659c382011-01-21 10:59:30 +00001509 tlan_store_skb(head_list, new_skb);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001510drop_and_reuse:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 head_list->forward = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001512 head_list->c_stat = 0;
1513 tail_list = priv->rx_list + priv->rx_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 tail_list->forward = head_list_phys;
1515
Sakari Ailusc659c382011-01-21 10:59:30 +00001516 CIRC_INC(priv->rx_head, TLAN_NUM_RX_LISTS);
1517 CIRC_INC(priv->rx_tail, TLAN_NUM_RX_LISTS);
1518 head_list = priv->rx_list + priv->rx_head;
1519 head_list_phys = priv->rx_list_dma
1520 + sizeof(struct tlan_list)*priv->rx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 }
1522
1523 if (!ack)
Joe Perches50624aa2011-03-01 06:56:33 +00001524 netdev_info(dev,
1525 "Received interrupt for uncompleted RX frame\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526
1527
Sakari Ailusc659c382011-01-21 10:59:30 +00001528 if (eoc) {
1529 TLAN_DBG(TLAN_DEBUG_RX,
1530 "RECEIVE: handling RX EOC (Head=%d Tail=%d)\n",
1531 priv->rx_head, priv->rx_tail);
1532 head_list = priv->rx_list + priv->rx_head;
1533 head_list_phys = priv->rx_list_dma
1534 + sizeof(struct tlan_list)*priv->rx_head;
1535 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 ack |= TLAN_HC_GO | TLAN_HC_RT;
Sakari Ailusc659c382011-01-21 10:59:30 +00001537 priv->rx_eoc_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 }
1539
Sakari Ailusc659c382011-01-21 10:59:30 +00001540 if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
1541 tlan_dio_write8(dev->base_addr,
1542 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
1543 if (priv->timer.function == NULL) {
1544 priv->timer.function = tlan_timer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 priv->timer.data = (unsigned long) dev;
1546 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
Sakari Ailusc659c382011-01-21 10:59:30 +00001547 priv->timer_set_at = jiffies;
1548 priv->timer_type = TLAN_TIMER_ACTIVITY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 add_timer(&priv->timer);
Sakari Ailusc659c382011-01-21 10:59:30 +00001550 } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
1551 priv->timer_set_at = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 }
1553 }
1554
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555 return ack;
1556
Sakari Ailusc659c382011-01-21 10:59:30 +00001557}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558
1559
1560
1561
Sakari Ailusc659c382011-01-21 10:59:30 +00001562/***************************************************************
1563 * tlan_handle_dummy
1564 *
1565 * Returns:
1566 * 1
1567 * Parms:
1568 * dev Device assigned the IRQ that was
1569 * raised.
1570 * host_int The contents of the HOST_INT
1571 * port.
1572 *
1573 * This function handles the Dummy interrupt, which is
1574 * raised whenever a test interrupt is generated by setting
1575 * the Req_Int bit of HOST_CMD to 1.
1576 *
1577 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578
Sakari Ailusc659c382011-01-21 10:59:30 +00001579static u32 tlan_handle_dummy(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580{
Joe Perches50624aa2011-03-01 06:56:33 +00001581 netdev_info(dev, "Test interrupt\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 return 1;
1583
Sakari Ailusc659c382011-01-21 10:59:30 +00001584}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585
1586
1587
1588
Sakari Ailusc659c382011-01-21 10:59:30 +00001589/***************************************************************
1590 * tlan_handle_tx_eoc
1591 *
1592 * Returns:
1593 * 1
1594 * Parms:
1595 * dev Device assigned the IRQ that was
1596 * raised.
1597 * host_int The contents of the HOST_INT
1598 * port.
1599 *
1600 * This driver is structured to determine EOC occurrences by
1601 * reading the CSTAT member of the list structure. Tx EOC
1602 * interrupts are disabled via the DIO INTDIS register.
1603 * However, TLAN chips before revision 3.0 didn't have this
1604 * functionality, so process EOC events if this is the
1605 * case.
1606 *
1607 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608
Sakari Ailusc659c382011-01-21 10:59:30 +00001609static u32 tlan_handle_tx_eoc(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001610{
Sakari Ailusc659c382011-01-21 10:59:30 +00001611 struct tlan_priv *priv = netdev_priv(dev);
1612 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 dma_addr_t head_list_phys;
1614 u32 ack = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001615
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 host_int = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001617 if (priv->tlan_rev < 0x30) {
1618 TLAN_DBG(TLAN_DEBUG_TX,
1619 "TRANSMIT: handling TX EOC (Head=%d Tail=%d) -- IRQ\n",
1620 priv->tx_head, priv->tx_tail);
1621 head_list = priv->tx_list + priv->tx_head;
1622 head_list_phys = priv->tx_list_dma
1623 + sizeof(struct tlan_list)*priv->tx_head;
Sakari Ailusf45437e2011-02-09 10:25:06 +00001624 if ((head_list->c_stat & TLAN_CSTAT_READY)
1625 == TLAN_CSTAT_READY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 netif_stop_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001627 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628 ack |= TLAN_HC_GO;
1629 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001630 priv->tx_in_progress = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631 }
1632 }
1633
1634 return ack;
1635
Sakari Ailusc659c382011-01-21 10:59:30 +00001636}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637
1638
1639
1640
Sakari Ailusc659c382011-01-21 10:59:30 +00001641/***************************************************************
1642 * tlan_handle_status_check
1643 *
1644 * Returns:
1645 * 0 if Adapter check, 1 if Network Status check.
1646 * Parms:
1647 * dev Device assigned the IRQ that was
1648 * raised.
1649 * host_int The contents of the HOST_INT
1650 * port.
1651 *
1652 * This function handles Adapter Check/Network Status
1653 * interrupts generated by the adapter. It checks the
1654 * vector in the HOST_INT register to determine if it is
1655 * an Adapter Check interrupt. If so, it resets the
1656 * adapter. Otherwise it clears the status registers
1657 * and services the PHY.
1658 *
1659 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660
Sakari Ailusc659c382011-01-21 10:59:30 +00001661static u32 tlan_handle_status_check(struct net_device *dev, u16 host_int)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001662{
Sakari Ailusc659c382011-01-21 10:59:30 +00001663 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 u32 ack;
1665 u32 error;
1666 u8 net_sts;
1667 u32 phy;
1668 u16 tlphy_ctl;
1669 u16 tlphy_sts;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001670
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 ack = 1;
Sakari Ailusc659c382011-01-21 10:59:30 +00001672 if (host_int & TLAN_HI_IV_MASK) {
1673 netif_stop_queue(dev);
1674 error = inl(dev->base_addr + TLAN_CH_PARM);
Joe Perches50624aa2011-03-01 06:56:33 +00001675 netdev_info(dev, "Adaptor Error = 0x%x\n", error);
Sakari Ailusc659c382011-01-21 10:59:30 +00001676 tlan_read_and_clear_stats(dev, TLAN_RECORD);
1677 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678
1679 schedule_work(&priv->tlan_tqueue);
1680
1681 netif_wake_queue(dev);
1682 ack = 0;
1683 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001684 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name);
1685 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686
Sakari Ailusc659c382011-01-21 10:59:30 +00001687 net_sts = tlan_dio_read8(dev->base_addr, TLAN_NET_STS);
1688 if (net_sts) {
1689 tlan_dio_write8(dev->base_addr, TLAN_NET_STS, net_sts);
1690 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n",
1691 dev->name, (unsigned) net_sts);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001693 if ((net_sts & TLAN_NET_STS_MIRQ) && (priv->phy_num == 0)) {
1694 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_STS, &tlphy_sts);
1695 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
1696 if (!(tlphy_sts & TLAN_TS_POLOK) &&
1697 !(tlphy_ctl & TLAN_TC_SWAPOL)) {
1698 tlphy_ctl |= TLAN_TC_SWAPOL;
1699 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
1700 tlphy_ctl);
1701 } else if ((tlphy_sts & TLAN_TS_POLOK) &&
1702 (tlphy_ctl & TLAN_TC_SWAPOL)) {
1703 tlphy_ctl &= ~TLAN_TC_SWAPOL;
1704 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
1705 tlphy_ctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001707
1708 if (debug)
1709 tlan_phy_print(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 }
1711 }
1712
1713 return ack;
1714
Sakari Ailusc659c382011-01-21 10:59:30 +00001715}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716
1717
1718
1719
Sakari Ailusc659c382011-01-21 10:59:30 +00001720/***************************************************************
1721 * tlan_handle_rx_eoc
1722 *
1723 * Returns:
1724 * 1
1725 * Parms:
1726 * dev Device assigned the IRQ that was
1727 * raised.
1728 * host_int The contents of the HOST_INT
1729 * port.
1730 *
1731 * This driver is structured to determine EOC occurrences by
1732 * reading the CSTAT member of the list structure. Rx EOC
1733 * interrupts are disabled via the DIO INTDIS register.
1734 * However, TLAN chips before revision 3.0 didn't have this
1735 * CSTAT member or a INTDIS register, so if this chip is
1736 * pre-3.0, process EOC interrupts normally.
1737 *
1738 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739
Sakari Ailusc659c382011-01-21 10:59:30 +00001740static u32 tlan_handle_rx_eoc(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741{
Sakari Ailusc659c382011-01-21 10:59:30 +00001742 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 dma_addr_t head_list_phys;
1744 u32 ack = 1;
1745
Sakari Ailusc659c382011-01-21 10:59:30 +00001746 if (priv->tlan_rev < 0x30) {
1747 TLAN_DBG(TLAN_DEBUG_RX,
1748 "RECEIVE: Handling RX EOC (head=%d tail=%d) -- IRQ\n",
1749 priv->rx_head, priv->rx_tail);
1750 head_list_phys = priv->rx_list_dma
1751 + sizeof(struct tlan_list)*priv->rx_head;
1752 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 ack |= TLAN_HC_GO | TLAN_HC_RT;
Sakari Ailusc659c382011-01-21 10:59:30 +00001754 priv->rx_eoc_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 }
1756
1757 return ack;
1758
Sakari Ailusc659c382011-01-21 10:59:30 +00001759}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
1761
1762
1763
1764/*****************************************************************************
1765******************************************************************************
1766
Sakari Ailusc659c382011-01-21 10:59:30 +00001767ThunderLAN driver timer function
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768
1769******************************************************************************
1770*****************************************************************************/
1771
1772
Sakari Ailusc659c382011-01-21 10:59:30 +00001773/***************************************************************
1774 * tlan_timer
1775 *
1776 * Returns:
1777 * Nothing
1778 * Parms:
1779 * data A value given to add timer when
1780 * add_timer was called.
1781 *
1782 * This function handles timed functionality for the
1783 * TLAN driver. The two current timer uses are for
1784 * delaying for autonegotionation and driving the ACT LED.
1785 * - Autonegotiation requires being allowed about
1786 * 2 1/2 seconds before attempting to transmit a
1787 * packet. It would be a very bad thing to hang
1788 * the kernel this long, so the driver doesn't
1789 * allow transmission 'til after this time, for
1790 * certain PHYs. It would be much nicer if all
1791 * PHYs were interrupt-capable like the internal
1792 * PHY.
1793 * - The ACT LED, which shows adapter activity, is
1794 * driven by the driver, and so must be left on
1795 * for a short period to power up the LED so it
1796 * can be seen. This delay can be changed by
1797 * changing the TLAN_TIMER_ACT_DELAY in tlan.h,
1798 * if desired. 100 ms produces a slightly
1799 * sluggish response.
1800 *
1801 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802
Sakari Ailusc659c382011-01-21 10:59:30 +00001803static void tlan_timer(unsigned long data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804{
1805 struct net_device *dev = (struct net_device *) data;
Sakari Ailusc659c382011-01-21 10:59:30 +00001806 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 u32 elapsed;
1808 unsigned long flags = 0;
1809
1810 priv->timer.function = NULL;
1811
Sakari Ailusc659c382011-01-21 10:59:30 +00001812 switch (priv->timer_type) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001813#ifdef MONITOR
Sakari Ailusc659c382011-01-21 10:59:30 +00001814 case TLAN_TIMER_LINK_BEAT:
1815 tlan_phy_monitor(dev);
1816 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817#endif
Sakari Ailusc659c382011-01-21 10:59:30 +00001818 case TLAN_TIMER_PHY_PDOWN:
1819 tlan_phy_power_down(dev);
1820 break;
1821 case TLAN_TIMER_PHY_PUP:
1822 tlan_phy_power_up(dev);
1823 break;
1824 case TLAN_TIMER_PHY_RESET:
1825 tlan_phy_reset(dev);
1826 break;
1827 case TLAN_TIMER_PHY_START_LINK:
1828 tlan_phy_start_link(dev);
1829 break;
1830 case TLAN_TIMER_PHY_FINISH_AN:
1831 tlan_phy_finish_auto_neg(dev);
1832 break;
1833 case TLAN_TIMER_FINISH_RESET:
1834 tlan_finish_reset(dev);
1835 break;
1836 case TLAN_TIMER_ACTIVITY:
1837 spin_lock_irqsave(&priv->lock, flags);
1838 if (priv->timer.function == NULL) {
1839 elapsed = jiffies - priv->timer_set_at;
1840 if (elapsed >= TLAN_TIMER_ACT_DELAY) {
1841 tlan_dio_write8(dev->base_addr,
1842 TLAN_LED_REG, TLAN_LED_LINK);
1843 } else {
1844 priv->timer.function = tlan_timer;
1845 priv->timer.expires = priv->timer_set_at
1846 + TLAN_TIMER_ACT_DELAY;
1847 spin_unlock_irqrestore(&priv->lock, flags);
1848 add_timer(&priv->timer);
1849 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001851 }
1852 spin_unlock_irqrestore(&priv->lock, flags);
1853 break;
1854 default:
1855 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 }
1857
Sakari Ailusc659c382011-01-21 10:59:30 +00001858}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859
1860
1861
1862
1863/*****************************************************************************
1864******************************************************************************
1865
Sakari Ailusc659c382011-01-21 10:59:30 +00001866ThunderLAN driver adapter related routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867
1868******************************************************************************
1869*****************************************************************************/
1870
1871
Sakari Ailusc659c382011-01-21 10:59:30 +00001872/***************************************************************
1873 * tlan_reset_lists
1874 *
1875 * Returns:
1876 * Nothing
1877 * Parms:
1878 * dev The device structure with the list
1879 * stuctures to be reset.
1880 *
1881 * This routine sets the variables associated with managing
1882 * the TLAN lists to their initial values.
1883 *
1884 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885
Sakari Ailusc659c382011-01-21 10:59:30 +00001886static void tlan_reset_lists(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887{
Sakari Ailusc659c382011-01-21 10:59:30 +00001888 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +00001890 struct tlan_list *list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 dma_addr_t list_phys;
1892 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893
Sakari Ailusc659c382011-01-21 10:59:30 +00001894 priv->tx_head = 0;
1895 priv->tx_tail = 0;
1896 for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
1897 list = priv->tx_list + i;
1898 list->c_stat = TLAN_CSTAT_UNUSED;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001899 list->buffer[0].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 list->buffer[2].count = 0;
1901 list->buffer[2].address = 0;
1902 list->buffer[8].address = 0;
1903 list->buffer[9].address = 0;
1904 }
1905
Sakari Ailusc659c382011-01-21 10:59:30 +00001906 priv->rx_head = 0;
1907 priv->rx_tail = TLAN_NUM_RX_LISTS - 1;
1908 for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
1909 list = priv->rx_list + i;
1910 list_phys = priv->rx_list_dma + sizeof(struct tlan_list)*i;
1911 list->c_stat = TLAN_CSTAT_READY;
1912 list->frame_size = TLAN_MAX_FRAME_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
Eric Dumazet89d71a62009-10-13 05:34:20 +00001914 skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5);
Sakari Ailusc659c382011-01-21 10:59:30 +00001915 if (!skb) {
Joe Perches50624aa2011-03-01 06:56:33 +00001916 netdev_err(dev, "Out of memory for received data\n");
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001917 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 }
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001919
Sakari Ailusc659c382011-01-21 10:59:30 +00001920 list->buffer[0].address = pci_map_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001921 skb->data,
1922 TLAN_MAX_FRAME_SIZE,
1923 PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001924 tlan_store_skb(list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 list->buffer[1].count = 0;
1926 list->buffer[1].address = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001927 list->forward = list_phys + sizeof(struct tlan_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 }
1929
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001930 /* in case ran out of memory early, clear bits */
1931 while (i < TLAN_NUM_RX_LISTS) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001932 tlan_store_skb(priv->rx_list + i, NULL);
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001933 ++i;
1934 }
1935 list->forward = 0;
1936
Sakari Ailusc659c382011-01-21 10:59:30 +00001937}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938
1939
Sakari Ailusc659c382011-01-21 10:59:30 +00001940static void tlan_free_lists(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001941{
Sakari Ailusc659c382011-01-21 10:59:30 +00001942 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +00001944 struct tlan_list *list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 struct sk_buff *skb;
1946
Sakari Ailusc659c382011-01-21 10:59:30 +00001947 for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
1948 list = priv->tx_list + i;
1949 skb = tlan_get_skb(list);
1950 if (skb) {
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001951 pci_unmap_single(
Sakari Ailusc659c382011-01-21 10:59:30 +00001952 priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001953 list->buffer[0].address,
1954 max(skb->len,
1955 (unsigned int)TLAN_MIN_FRAME_SIZE),
1956 PCI_DMA_TODEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001957 dev_kfree_skb_any(skb);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001958 list->buffer[8].address = 0;
1959 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 }
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001961 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962
Sakari Ailusc659c382011-01-21 10:59:30 +00001963 for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
1964 list = priv->rx_list + i;
1965 skb = tlan_get_skb(list);
1966 if (skb) {
1967 pci_unmap_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001968 list->buffer[0].address,
1969 TLAN_MAX_FRAME_SIZE,
1970 PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001971 dev_kfree_skb_any(skb);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001972 list->buffer[8].address = 0;
1973 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 }
1975 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001976}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977
1978
1979
1980
Sakari Ailusc659c382011-01-21 10:59:30 +00001981/***************************************************************
1982 * tlan_print_dio
1983 *
1984 * Returns:
1985 * Nothing
1986 * Parms:
1987 * io_base Base IO port of the device of
1988 * which to print DIO registers.
1989 *
1990 * This function prints out all the internal (DIO)
1991 * registers of a TLAN chip.
1992 *
1993 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994
Sakari Ailusc659c382011-01-21 10:59:30 +00001995static void tlan_print_dio(u16 io_base)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996{
1997 u32 data0, data1;
1998 int i;
1999
Joe Perches50624aa2011-03-01 06:56:33 +00002000 pr_info("Contents of internal registers for io base 0x%04hx\n",
2001 io_base);
2002 pr_info("Off. +0 +4\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002003 for (i = 0; i < 0x4C; i += 8) {
2004 data0 = tlan_dio_read32(io_base, i);
2005 data1 = tlan_dio_read32(io_base, i + 0x4);
Joe Perches50624aa2011-03-01 06:56:33 +00002006 pr_info("0x%02x 0x%08x 0x%08x\n", i, data0, data1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007 }
2008
Sakari Ailusc659c382011-01-21 10:59:30 +00002009}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010
2011
2012
2013
Sakari Ailusc659c382011-01-21 10:59:30 +00002014/***************************************************************
2015 * TLan_PrintList
2016 *
2017 * Returns:
2018 * Nothing
2019 * Parms:
2020 * list A pointer to the struct tlan_list structure to
2021 * be printed.
2022 * type A string to designate type of list,
2023 * "Rx" or "Tx".
2024 * num The index of the list.
2025 *
2026 * This function prints out the contents of the list
2027 * pointed to by the list parameter.
2028 *
2029 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030
Sakari Ailusc659c382011-01-21 10:59:30 +00002031static void tlan_print_list(struct tlan_list *list, char *type, int num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032{
2033 int i;
2034
Joe Perches50624aa2011-03-01 06:56:33 +00002035 pr_info("%s List %d at %p\n", type, num, list);
2036 pr_info(" Forward = 0x%08x\n", list->forward);
2037 pr_info(" CSTAT = 0x%04hx\n", list->c_stat);
2038 pr_info(" Frame Size = 0x%04hx\n", list->frame_size);
Sakari Ailusc659c382011-01-21 10:59:30 +00002039 /* for (i = 0; i < 10; i++) { */
2040 for (i = 0; i < 2; i++) {
Joe Perches50624aa2011-03-01 06:56:33 +00002041 pr_info(" Buffer[%d].count, addr = 0x%08x, 0x%08x\n",
2042 i, list->buffer[i].count, list->buffer[i].address);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 }
2044
Sakari Ailusc659c382011-01-21 10:59:30 +00002045}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046
2047
2048
2049
Sakari Ailusc659c382011-01-21 10:59:30 +00002050/***************************************************************
2051 * tlan_read_and_clear_stats
2052 *
2053 * Returns:
2054 * Nothing
2055 * Parms:
2056 * dev Pointer to device structure of adapter
2057 * to which to read stats.
2058 * record Flag indicating whether to add
2059 *
2060 * This functions reads all the internal status registers
2061 * of the TLAN chip, which clears them as a side effect.
2062 * It then either adds the values to the device's status
2063 * struct, or discards them, depending on whether record
2064 * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0).
2065 *
2066 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067
Sakari Ailusc659c382011-01-21 10:59:30 +00002068static void tlan_read_and_clear_stats(struct net_device *dev, int record)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070 u32 tx_good, tx_under;
2071 u32 rx_good, rx_over;
2072 u32 def_tx, crc, code;
2073 u32 multi_col, single_col;
2074 u32 excess_col, late_col, loss;
2075
Sakari Ailusc659c382011-01-21 10:59:30 +00002076 outw(TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR);
2077 tx_good = inb(dev->base_addr + TLAN_DIO_DATA);
2078 tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2079 tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
2080 tx_under = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002081
Sakari Ailusc659c382011-01-21 10:59:30 +00002082 outw(TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR);
2083 rx_good = inb(dev->base_addr + TLAN_DIO_DATA);
2084 rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2085 rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
2086 rx_over = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002087
Sakari Ailusc659c382011-01-21 10:59:30 +00002088 outw(TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR);
2089 def_tx = inb(dev->base_addr + TLAN_DIO_DATA);
2090 def_tx += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2091 crc = inb(dev->base_addr + TLAN_DIO_DATA + 2);
2092 code = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002093
Sakari Ailusc659c382011-01-21 10:59:30 +00002094 outw(TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
2095 multi_col = inb(dev->base_addr + TLAN_DIO_DATA);
2096 multi_col += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2097 single_col = inb(dev->base_addr + TLAN_DIO_DATA + 2);
2098 single_col += inb(dev->base_addr + TLAN_DIO_DATA + 3) << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099
Sakari Ailusc659c382011-01-21 10:59:30 +00002100 outw(TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
2101 excess_col = inb(dev->base_addr + TLAN_DIO_DATA);
2102 late_col = inb(dev->base_addr + TLAN_DIO_DATA + 1);
2103 loss = inb(dev->base_addr + TLAN_DIO_DATA + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104
Sakari Ailusc659c382011-01-21 10:59:30 +00002105 if (record) {
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002106 dev->stats.rx_packets += rx_good;
2107 dev->stats.rx_errors += rx_over + crc + code;
2108 dev->stats.tx_packets += tx_good;
2109 dev->stats.tx_errors += tx_under + loss;
Sakari Ailusc659c382011-01-21 10:59:30 +00002110 dev->stats.collisions += multi_col
2111 + single_col + excess_col + late_col;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002113 dev->stats.rx_over_errors += rx_over;
2114 dev->stats.rx_crc_errors += crc;
2115 dev->stats.rx_frame_errors += code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002116
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002117 dev->stats.tx_aborted_errors += tx_under;
2118 dev->stats.tx_carrier_errors += loss;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002119 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002120
Sakari Ailusc659c382011-01-21 10:59:30 +00002121}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122
2123
2124
2125
Sakari Ailusc659c382011-01-21 10:59:30 +00002126/***************************************************************
2127 * TLan_Reset
2128 *
2129 * Returns:
2130 * 0
2131 * Parms:
2132 * dev Pointer to device structure of adapter
2133 * to be reset.
2134 *
2135 * This function resets the adapter and it's physical
2136 * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
2137 * Programmer's Guide" for details. The routine tries to
2138 * implement what is detailed there, though adjustments
2139 * have been made.
2140 *
2141 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142
Harvey Harrison98e0f522008-02-18 10:04:38 -08002143static void
Sakari Ailusc659c382011-01-21 10:59:30 +00002144tlan_reset_adapter(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145{
Sakari Ailusc659c382011-01-21 10:59:30 +00002146 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147 int i;
2148 u32 addr;
2149 u32 data;
2150 u8 data8;
2151
Sakari Ailusc659c382011-01-21 10:59:30 +00002152 priv->tlan_full_duplex = false;
2153 priv->phy_online = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154 netif_carrier_off(dev);
2155
2156/* 1. Assert reset bit. */
2157
2158 data = inl(dev->base_addr + TLAN_HOST_CMD);
2159 data |= TLAN_HC_AD_RST;
2160 outl(data, dev->base_addr + TLAN_HOST_CMD);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002161
Linus Torvalds1da177e2005-04-16 15:20:36 -07002162 udelay(1000);
2163
Sakari Ailusc659c382011-01-21 10:59:30 +00002164/* 2. Turn off interrupts. (Probably isn't necessary) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002165
2166 data = inl(dev->base_addr + TLAN_HOST_CMD);
2167 data |= TLAN_HC_INT_OFF;
2168 outl(data, dev->base_addr + TLAN_HOST_CMD);
2169
2170/* 3. Clear AREGs and HASHs. */
2171
Sakari Ailusc659c382011-01-21 10:59:30 +00002172 for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4)
2173 tlan_dio_write32(dev->base_addr, (u16) i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174
2175/* 4. Setup NetConfig register. */
2176
2177 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
Sakari Ailusc659c382011-01-21 10:59:30 +00002178 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179
2180/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
2181
Sakari Ailusc659c382011-01-21 10:59:30 +00002182 outl(TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD);
2183 outl(TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184
2185/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
2186
Sakari Ailusc659c382011-01-21 10:59:30 +00002187 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188 addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Sakari Ailusc659c382011-01-21 10:59:30 +00002189 tlan_set_bit(TLAN_NET_SIO_NMRST, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002190
2191/* 7. Setup the remaining registers. */
2192
Sakari Ailusc659c382011-01-21 10:59:30 +00002193 if (priv->tlan_rev >= 0x30) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194 data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
Sakari Ailusc659c382011-01-21 10:59:30 +00002195 tlan_dio_write8(dev->base_addr, TLAN_INT_DIS, data8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002196 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002197 tlan_phy_detect(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002199
Sakari Ailusc659c382011-01-21 10:59:30 +00002200 if (priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002201 data |= TLAN_NET_CFG_BIT;
Sakari Ailusc659c382011-01-21 10:59:30 +00002202 if (priv->aui == 1) {
2203 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x0a);
2204 } else if (priv->duplex == TLAN_DUPLEX_FULL) {
2205 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x00);
2206 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002208 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x08);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 }
2210 }
2211
Sakari Ailusc659c382011-01-21 10:59:30 +00002212 if (priv->phy_num == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213 data |= TLAN_NET_CFG_PHY_EN;
Sakari Ailusc659c382011-01-21 10:59:30 +00002214 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215
Sakari Ailusc659c382011-01-21 10:59:30 +00002216 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY)
2217 tlan_finish_reset(dev);
2218 else
2219 tlan_phy_power_down(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002220
Sakari Ailusc659c382011-01-21 10:59:30 +00002221}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002222
2223
2224
2225
Harvey Harrison98e0f522008-02-18 10:04:38 -08002226static void
Sakari Ailusc659c382011-01-21 10:59:30 +00002227tlan_finish_reset(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228{
Sakari Ailusc659c382011-01-21 10:59:30 +00002229 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230 u8 data;
2231 u32 phy;
2232 u8 sio;
2233 u16 status;
2234 u16 partner;
2235 u16 tlphy_ctl;
Sakari Ailusc659c382011-01-21 10:59:30 +00002236 u16 tlphy_par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 u16 tlphy_id1, tlphy_id2;
Sakari Ailusc659c382011-01-21 10:59:30 +00002238 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239
Sakari Ailusc659c382011-01-21 10:59:30 +00002240 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241
2242 data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
Sakari Ailusc659c382011-01-21 10:59:30 +00002243 if (priv->tlan_full_duplex)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244 data |= TLAN_NET_CMD_DUPLEX;
Sakari Ailusc659c382011-01-21 10:59:30 +00002245 tlan_dio_write8(dev->base_addr, TLAN_NET_CMD, data);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002246 data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
Sakari Ailusc659c382011-01-21 10:59:30 +00002247 if (priv->phy_num == 0)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002248 data |= TLAN_NET_MASK_MASK7;
Sakari Ailusc659c382011-01-21 10:59:30 +00002249 tlan_dio_write8(dev->base_addr, TLAN_NET_MASK, data);
2250 tlan_dio_write16(dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7);
2251 tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &tlphy_id1);
2252 tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &tlphy_id2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002253
Sakari Ailusc659c382011-01-21 10:59:30 +00002254 if ((priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) ||
2255 (priv->aui)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256 status = MII_GS_LINK;
Joe Perches50624aa2011-03-01 06:56:33 +00002257 netdev_info(dev, "Link forced\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002259 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2260 udelay(1000);
2261 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2262 if ((status & MII_GS_LINK) &&
2263 /* We only support link info on Nat.Sem. PHY's */
2264 (tlphy_id1 == NAT_SEM_ID1) &&
2265 (tlphy_id2 == NAT_SEM_ID2)) {
2266 tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner);
2267 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002268
Joe Perches50624aa2011-03-01 06:56:33 +00002269 netdev_info(dev,
2270 "Link active with %s %uMbps %s-Duplex\n",
2271 !(tlphy_par & TLAN_PHY_AN_EN_STAT)
2272 ? "forced" : "Autonegotiation enabled,",
2273 tlphy_par & TLAN_PHY_SPEED_100
2274 ? 100 : 10,
2275 tlphy_par & TLAN_PHY_DUPLEX_FULL
2276 ? "Full" : "Half");
2277
2278 if (tlphy_par & TLAN_PHY_AN_EN_STAT) {
2279 netdev_info(dev, "Partner capability:");
2280 for (i = 5; i < 10; i++)
2281 if (partner & (1 << i))
2282 pr_cont(" %s", media[i-5]);
2283 pr_cont("\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 }
2285
Sakari Ailusc659c382011-01-21 10:59:30 +00002286 tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
2287 TLAN_LED_LINK);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002288#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289 /* We have link beat..for now anyway */
Sakari Ailusc659c382011-01-21 10:59:30 +00002290 priv->link = 1;
2291 /*Enabling link beat monitoring */
2292 tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002293#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294 } else if (status & MII_GS_LINK) {
Joe Perches50624aa2011-03-01 06:56:33 +00002295 netdev_info(dev, "Link active\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002296 tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
2297 TLAN_LED_LINK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298 }
2299 }
2300
Sakari Ailusc659c382011-01-21 10:59:30 +00002301 if (priv->phy_num == 0) {
2302 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
2303 tlphy_ctl |= TLAN_TC_INTEN;
2304 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
2305 sio = tlan_dio_read8(dev->base_addr, TLAN_NET_SIO);
2306 sio |= TLAN_NET_SIO_MINTEN;
2307 tlan_dio_write8(dev->base_addr, TLAN_NET_SIO, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 }
2309
Sakari Ailusc659c382011-01-21 10:59:30 +00002310 if (status & MII_GS_LINK) {
2311 tlan_set_mac(dev, 0, dev->dev_addr);
2312 priv->phy_online = 1;
2313 outb((TLAN_HC_INT_ON >> 8), dev->base_addr + TLAN_HOST_CMD + 1);
2314 if (debug >= 1 && debug != TLAN_DEBUG_PROBE)
2315 outb((TLAN_HC_REQ_INT >> 8),
2316 dev->base_addr + TLAN_HOST_CMD + 1);
2317 outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM);
2318 outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 netif_carrier_on(dev);
2320 } else {
Joe Perches50624aa2011-03-01 06:56:33 +00002321 netdev_info(dev, "Link inactive, will retry in 10 secs...\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002322 tlan_set_timer(dev, (10*HZ), TLAN_TIMER_FINISH_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 return;
2324 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002325 tlan_set_multicast_list(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326
Sakari Ailusc659c382011-01-21 10:59:30 +00002327}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328
2329
2330
2331
Sakari Ailusc659c382011-01-21 10:59:30 +00002332/***************************************************************
2333 * tlan_set_mac
2334 *
2335 * Returns:
2336 * Nothing
2337 * Parms:
2338 * dev Pointer to device structure of adapter
2339 * on which to change the AREG.
2340 * areg The AREG to set the address in (0 - 3).
2341 * mac A pointer to an array of chars. Each
2342 * element stores one byte of the address.
2343 * IE, it isn't in ascii.
2344 *
2345 * This function transfers a MAC address to one of the
2346 * TLAN AREGs (address registers). The TLAN chip locks
2347 * the register on writing to offset 0 and unlocks the
2348 * register after writing to offset 5. If NULL is passed
2349 * in mac, then the AREG is filled with 0's.
2350 *
2351 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352
Sakari Ailusc659c382011-01-21 10:59:30 +00002353static void tlan_set_mac(struct net_device *dev, int areg, char *mac)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002354{
2355 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002356
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357 areg *= 6;
2358
Sakari Ailusc659c382011-01-21 10:59:30 +00002359 if (mac != NULL) {
2360 for (i = 0; i < 6; i++)
2361 tlan_dio_write8(dev->base_addr,
2362 TLAN_AREG_0 + areg + i, mac[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002364 for (i = 0; i < 6; i++)
2365 tlan_dio_write8(dev->base_addr,
2366 TLAN_AREG_0 + areg + i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367 }
2368
Sakari Ailusc659c382011-01-21 10:59:30 +00002369}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370
2371
2372
2373
2374/*****************************************************************************
2375******************************************************************************
2376
Sakari Ailusc659c382011-01-21 10:59:30 +00002377ThunderLAN driver PHY layer routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378
2379******************************************************************************
2380*****************************************************************************/
2381
2382
2383
Sakari Ailusc659c382011-01-21 10:59:30 +00002384/*********************************************************************
2385 * tlan_phy_print
2386 *
2387 * Returns:
2388 * Nothing
2389 * Parms:
2390 * dev A pointer to the device structure of the
2391 * TLAN device having the PHYs to be detailed.
2392 *
2393 * This function prints the registers a PHY (aka transceiver).
2394 *
2395 ********************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002396
Sakari Ailusc659c382011-01-21 10:59:30 +00002397static void tlan_phy_print(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398{
Sakari Ailusc659c382011-01-21 10:59:30 +00002399 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400 u16 i, data0, data1, data2, data3, phy;
2401
Sakari Ailusc659c382011-01-21 10:59:30 +00002402 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002403
Sakari Ailusc659c382011-01-21 10:59:30 +00002404 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
Joe Perches50624aa2011-03-01 06:56:33 +00002405 netdev_info(dev, "Unmanaged PHY\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002406 } else if (phy <= TLAN_PHY_MAX_ADDR) {
Joe Perches50624aa2011-03-01 06:56:33 +00002407 netdev_info(dev, "PHY 0x%02x\n", phy);
2408 pr_info(" Off. +0 +1 +2 +3\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002409 for (i = 0; i < 0x20; i += 4) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002410 tlan_mii_read_reg(dev, phy, i, &data0);
Sakari Ailusc659c382011-01-21 10:59:30 +00002411 tlan_mii_read_reg(dev, phy, i + 1, &data1);
Sakari Ailusc659c382011-01-21 10:59:30 +00002412 tlan_mii_read_reg(dev, phy, i + 2, &data2);
Sakari Ailusc659c382011-01-21 10:59:30 +00002413 tlan_mii_read_reg(dev, phy, i + 3, &data3);
Joe Perches50624aa2011-03-01 06:56:33 +00002414 pr_info(" 0x%02x 0x%04hx 0x%04hx 0x%04hx 0x%04hx\n",
2415 i, data0, data1, data2, data3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 }
2417 } else {
Joe Perches50624aa2011-03-01 06:56:33 +00002418 netdev_info(dev, "Invalid PHY\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419 }
2420
Sakari Ailusc659c382011-01-21 10:59:30 +00002421}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422
2423
2424
2425
Sakari Ailusc659c382011-01-21 10:59:30 +00002426/*********************************************************************
2427 * tlan_phy_detect
2428 *
2429 * Returns:
2430 * Nothing
2431 * Parms:
2432 * dev A pointer to the device structure of the adapter
2433 * for which the PHY needs determined.
2434 *
2435 * So far I've found that adapters which have external PHYs
2436 * may also use the internal PHY for part of the functionality.
2437 * (eg, AUI/Thinnet). This function finds out if this TLAN
2438 * chip has an internal PHY, and then finds the first external
2439 * PHY (starting from address 0) if it exists).
2440 *
2441 ********************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442
Sakari Ailusc659c382011-01-21 10:59:30 +00002443static void tlan_phy_detect(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444{
Sakari Ailusc659c382011-01-21 10:59:30 +00002445 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446 u16 control;
2447 u16 hi;
2448 u16 lo;
2449 u32 phy;
2450
Sakari Ailusc659c382011-01-21 10:59:30 +00002451 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
2452 priv->phy_num = 0xffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002453 return;
2454 }
2455
Sakari Ailusc659c382011-01-21 10:59:30 +00002456 tlan_mii_read_reg(dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002457
Sakari Ailusc659c382011-01-21 10:59:30 +00002458 if (hi != 0xffff)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002459 priv->phy[0] = TLAN_PHY_MAX_ADDR;
Sakari Ailusc659c382011-01-21 10:59:30 +00002460 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002461 priv->phy[0] = TLAN_PHY_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002462
2463 priv->phy[1] = TLAN_PHY_NONE;
Sakari Ailusc659c382011-01-21 10:59:30 +00002464 for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) {
2465 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &control);
2466 tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &hi);
2467 tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &lo);
2468 if ((control != 0xffff) ||
2469 (hi != 0xffff) || (lo != 0xffff)) {
2470 TLAN_DBG(TLAN_DEBUG_GNRL,
2471 "PHY found at %02x %04x %04x %04x\n",
2472 phy, control, hi, lo);
2473 if ((priv->phy[1] == TLAN_PHY_NONE) &&
2474 (phy != TLAN_PHY_MAX_ADDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002475 priv->phy[1] = phy;
2476 }
2477 }
2478 }
2479
Sakari Ailusc659c382011-01-21 10:59:30 +00002480 if (priv->phy[1] != TLAN_PHY_NONE)
2481 priv->phy_num = 1;
2482 else if (priv->phy[0] != TLAN_PHY_NONE)
2483 priv->phy_num = 0;
2484 else
Joe Perches50624aa2011-03-01 06:56:33 +00002485 netdev_info(dev, "Cannot initialize device, no PHY was found!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486
Sakari Ailusc659c382011-01-21 10:59:30 +00002487}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488
2489
2490
2491
Sakari Ailusc659c382011-01-21 10:59:30 +00002492static void tlan_phy_power_down(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493{
Sakari Ailusc659c382011-01-21 10:59:30 +00002494 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495 u16 value;
2496
Sakari Ailusc659c382011-01-21 10:59:30 +00002497 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498 value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
Sakari Ailusc659c382011-01-21 10:59:30 +00002499 tlan_mii_sync(dev->base_addr);
2500 tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
2501 if ((priv->phy_num == 0) &&
2502 (priv->phy[1] != TLAN_PHY_NONE) &&
2503 (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) {
2504 tlan_mii_sync(dev->base_addr);
2505 tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506 }
2507
2508 /* Wait for 50 ms and powerup
2509 * This is abitrary. It is intended to make sure the
2510 * transceiver settles.
2511 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002512 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_PUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002513
Sakari Ailusc659c382011-01-21 10:59:30 +00002514}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515
2516
2517
2518
Sakari Ailusc659c382011-01-21 10:59:30 +00002519static void tlan_phy_power_up(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520{
Sakari Ailusc659c382011-01-21 10:59:30 +00002521 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522 u16 value;
2523
Sakari Ailusc659c382011-01-21 10:59:30 +00002524 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name);
2525 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002526 value = MII_GC_LOOPBK;
Sakari Ailusc659c382011-01-21 10:59:30 +00002527 tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
2528 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 /* Wait for 500 ms and reset the
2530 * transceiver. The TLAN docs say both 50 ms and
2531 * 500 ms, so do the longer, just in case.
2532 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002533 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534
Sakari Ailusc659c382011-01-21 10:59:30 +00002535}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536
2537
2538
2539
Sakari Ailusc659c382011-01-21 10:59:30 +00002540static void tlan_phy_reset(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541{
Sakari Ailusc659c382011-01-21 10:59:30 +00002542 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 u16 phy;
2544 u16 value;
2545
Sakari Ailusc659c382011-01-21 10:59:30 +00002546 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547
Sakari Ailusc659c382011-01-21 10:59:30 +00002548 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name);
2549 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550 value = MII_GC_LOOPBK | MII_GC_RESET;
Sakari Ailusc659c382011-01-21 10:59:30 +00002551 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value);
2552 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
2553 while (value & MII_GC_RESET)
2554 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555
2556 /* Wait for 500 ms and initialize.
2557 * I don't remember why I wait this long.
2558 * I've changed this to 50ms, as it seems long enough.
2559 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002560 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_START_LINK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561
Sakari Ailusc659c382011-01-21 10:59:30 +00002562}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563
2564
2565
2566
Sakari Ailusc659c382011-01-21 10:59:30 +00002567static void tlan_phy_start_link(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568{
Sakari Ailusc659c382011-01-21 10:59:30 +00002569 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570 u16 ability;
2571 u16 control;
2572 u16 data;
2573 u16 phy;
2574 u16 status;
2575 u16 tctl;
2576
Sakari Ailusc659c382011-01-21 10:59:30 +00002577 phy = priv->phy[priv->phy_num];
2578 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name);
2579 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2580 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &ability);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002581
Sakari Ailusc659c382011-01-21 10:59:30 +00002582 if ((status & MII_GS_AUTONEG) &&
2583 (!priv->aui)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584 ability = status >> 11;
Sakari Ailusc659c382011-01-21 10:59:30 +00002585 if (priv->speed == TLAN_SPEED_10 &&
2586 priv->duplex == TLAN_DUPLEX_HALF) {
2587 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0000);
2588 } else if (priv->speed == TLAN_SPEED_10 &&
2589 priv->duplex == TLAN_DUPLEX_FULL) {
2590 priv->tlan_full_duplex = true;
2591 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0100);
2592 } else if (priv->speed == TLAN_SPEED_100 &&
2593 priv->duplex == TLAN_DUPLEX_HALF) {
2594 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2000);
2595 } else if (priv->speed == TLAN_SPEED_100 &&
2596 priv->duplex == TLAN_DUPLEX_FULL) {
2597 priv->tlan_full_duplex = true;
2598 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2100);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599 } else {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002600
Linus Torvalds1da177e2005-04-16 15:20:36 -07002601 /* Set Auto-Neg advertisement */
Sakari Ailusc659c382011-01-21 10:59:30 +00002602 tlan_mii_write_reg(dev, phy, MII_AN_ADV,
2603 (ability << 5) | 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604 /* Enablee Auto-Neg */
Sakari Ailusc659c382011-01-21 10:59:30 +00002605 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1000);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606 /* Restart Auto-Neg */
Sakari Ailusc659c382011-01-21 10:59:30 +00002607 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1200);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002608 /* Wait for 4 sec for autonegotiation
Sakari Ailusc659c382011-01-21 10:59:30 +00002609 * to complete. The max spec time is less than this
2610 * but the card need additional time to start AN.
2611 * .5 sec should be plenty extra.
2612 */
Joe Perches50624aa2011-03-01 06:56:33 +00002613 netdev_info(dev, "Starting autonegotiation\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002614 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615 return;
2616 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002617
2618 }
2619
Sakari Ailusc659c382011-01-21 10:59:30 +00002620 if ((priv->aui) && (priv->phy_num != 0)) {
2621 priv->phy_num = 0;
2622 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
2623 | TLAN_NET_CFG_PHY_EN;
2624 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
2625 tlan_set_timer(dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626 return;
Sakari Ailusc659c382011-01-21 10:59:30 +00002627 } else if (priv->phy_num == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628 control = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002629 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tctl);
2630 if (priv->aui) {
2631 tctl |= TLAN_TC_AUISEL;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002632 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002633 tctl &= ~TLAN_TC_AUISEL;
2634 if (priv->duplex == TLAN_DUPLEX_FULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635 control |= MII_GC_DUPLEX;
Sakari Ailusc659c382011-01-21 10:59:30 +00002636 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002638 if (priv->speed == TLAN_SPEED_100)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639 control |= MII_GC_SPEEDSEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002641 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, control);
2642 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643 }
2644
2645 /* Wait for 2 sec to give the transceiver time
2646 * to establish link.
2647 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002648 tlan_set_timer(dev, (4*HZ), TLAN_TIMER_FINISH_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649
Sakari Ailusc659c382011-01-21 10:59:30 +00002650}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651
2652
2653
2654
Sakari Ailusc659c382011-01-21 10:59:30 +00002655static void tlan_phy_finish_auto_neg(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656{
Sakari Ailusc659c382011-01-21 10:59:30 +00002657 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658 u16 an_adv;
2659 u16 an_lpa;
2660 u16 data;
2661 u16 mode;
2662 u16 phy;
2663 u16 status;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002664
Sakari Ailusc659c382011-01-21 10:59:30 +00002665 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002666
Sakari Ailusc659c382011-01-21 10:59:30 +00002667 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2668 udelay(1000);
2669 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670
Sakari Ailusc659c382011-01-21 10:59:30 +00002671 if (!(status & MII_GS_AUTOCMPLT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002672 /* Wait for 8 sec to give the process
2673 * more time. Perhaps we should fail after a while.
2674 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002675 if (!priv->neg_be_verbose++) {
Joe Perches50624aa2011-03-01 06:56:33 +00002676 pr_info("Giving autonegotiation more time.\n");
2677 pr_info("Please check that your adapter has\n");
2678 pr_info("been properly connected to a HUB or Switch.\n");
2679 pr_info("Trying to establish link in the background...\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002680 }
2681 tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002682 return;
2683 }
2684
Joe Perches50624aa2011-03-01 06:56:33 +00002685 netdev_info(dev, "Autonegotiation complete\n");
Sakari Ailusc659c382011-01-21 10:59:30 +00002686 tlan_mii_read_reg(dev, phy, MII_AN_ADV, &an_adv);
2687 tlan_mii_read_reg(dev, phy, MII_AN_LPA, &an_lpa);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688 mode = an_adv & an_lpa & 0x03E0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002689 if (mode & 0x0100)
2690 priv->tlan_full_duplex = true;
2691 else if (!(mode & 0x0080) && (mode & 0x0040))
2692 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002693
Sakari Ailusc659c382011-01-21 10:59:30 +00002694 if ((!(mode & 0x0180)) &&
2695 (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) &&
2696 (priv->phy_num != 0)) {
2697 priv->phy_num = 0;
2698 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
2699 | TLAN_NET_CFG_PHY_EN;
2700 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
2701 tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702 return;
2703 }
2704
Sakari Ailusc659c382011-01-21 10:59:30 +00002705 if (priv->phy_num == 0) {
2706 if ((priv->duplex == TLAN_DUPLEX_FULL) ||
2707 (an_adv & an_lpa & 0x0040)) {
2708 tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
2709 MII_GC_AUTOENB | MII_GC_DUPLEX);
Joe Perches50624aa2011-03-01 06:56:33 +00002710 netdev_info(dev, "Starting internal PHY with FULL-DUPLEX\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002712 tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
2713 MII_GC_AUTOENB);
Joe Perches50624aa2011-03-01 06:56:33 +00002714 netdev_info(dev, "Starting internal PHY with HALF-DUPLEX\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715 }
2716 }
2717
2718 /* Wait for 100 ms. No reason in partiticular.
2719 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002720 tlan_set_timer(dev, (HZ/10), TLAN_TIMER_FINISH_RESET);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002721
Sakari Ailusc659c382011-01-21 10:59:30 +00002722}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723
2724#ifdef MONITOR
2725
Sakari Ailusc659c382011-01-21 10:59:30 +00002726/*********************************************************************
2727 *
2728 * tlan_phy_monitor
2729 *
2730 * Returns:
2731 * None
2732 *
2733 * Params:
2734 * dev The device structure of this device.
2735 *
2736 *
2737 * This function monitors PHY condition by reading the status
2738 * register via the MII bus. This can be used to give info
2739 * about link changes (up/down), and possible switch to alternate
2740 * media.
2741 *
2742 *******************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002743
Sakari Ailusc659c382011-01-21 10:59:30 +00002744void tlan_phy_monitor(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745{
Sakari Ailusc659c382011-01-21 10:59:30 +00002746 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002747 u16 phy;
2748 u16 phy_status;
2749
Sakari Ailusc659c382011-01-21 10:59:30 +00002750 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002751
Sakari Ailusc659c382011-01-21 10:59:30 +00002752 /* Get PHY status register */
2753 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &phy_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754
Sakari Ailusc659c382011-01-21 10:59:30 +00002755 /* Check if link has been lost */
2756 if (!(phy_status & MII_GS_LINK)) {
2757 if (priv->link) {
2758 priv->link = 0;
2759 printk(KERN_DEBUG "TLAN: %s has lost link\n",
2760 dev->name);
2761 netif_carrier_off(dev);
2762 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
2763 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002764 }
2765 }
2766
Sakari Ailusc659c382011-01-21 10:59:30 +00002767 /* Link restablished? */
2768 if ((phy_status & MII_GS_LINK) && !priv->link) {
2769 priv->link = 1;
2770 printk(KERN_DEBUG "TLAN: %s has reestablished link\n",
2771 dev->name);
7d17c1d2005-05-12 19:45:25 -04002772 netif_carrier_on(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00002773 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002774
2775 /* Setup a new monitor */
Sakari Ailusc659c382011-01-21 10:59:30 +00002776 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002777}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002778
2779#endif /* MONITOR */
2780
2781
2782/*****************************************************************************
2783******************************************************************************
2784
Sakari Ailusc659c382011-01-21 10:59:30 +00002785ThunderLAN driver MII routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07002786
Sakari Ailusc659c382011-01-21 10:59:30 +00002787these routines are based on the information in chap. 2 of the
2788"ThunderLAN Programmer's Guide", pp. 15-24.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002789
2790******************************************************************************
2791*****************************************************************************/
2792
2793
Sakari Ailusc659c382011-01-21 10:59:30 +00002794/***************************************************************
2795 * tlan_mii_read_reg
2796 *
2797 * Returns:
2798 * false if ack received ok
2799 * true if no ack received or other error
2800 *
2801 * Parms:
2802 * dev The device structure containing
2803 * The io address and interrupt count
2804 * for this device.
2805 * phy The address of the PHY to be queried.
2806 * reg The register whose contents are to be
2807 * retrieved.
2808 * val A pointer to a variable to store the
2809 * retrieved value.
2810 *
2811 * This function uses the TLAN's MII bus to retrieve the contents
2812 * of a given register on a PHY. It sends the appropriate info
2813 * and then reads the 16-bit register value from the MII bus via
2814 * the TLAN SIO register.
2815 *
2816 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817
Sakari Ailusc659c382011-01-21 10:59:30 +00002818static bool
2819tlan_mii_read_reg(struct net_device *dev, u16 phy, u16 reg, u16 *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820{
2821 u8 nack;
2822 u16 sio, tmp;
Sakari Ailusc659c382011-01-21 10:59:30 +00002823 u32 i;
Joe Perches37fce432010-01-12 20:59:13 +00002824 bool err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825 int minten;
Sakari Ailusc659c382011-01-21 10:59:30 +00002826 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 unsigned long flags = 0;
2828
Joe Perches37fce432010-01-12 20:59:13 +00002829 err = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2831 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002832
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 if (!in_irq())
2834 spin_lock_irqsave(&priv->lock, flags);
2835
Sakari Ailusc659c382011-01-21 10:59:30 +00002836 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837
Sakari Ailusc659c382011-01-21 10:59:30 +00002838 minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
2839 if (minten)
2840 tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841
Sakari Ailusc659c382011-01-21 10:59:30 +00002842 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */
2843 tlan_mii_send_data(dev->base_addr, 0x2, 2); /* read (10b) */
2844 tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */
2845 tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846
2847
Sakari Ailusc659c382011-01-21 10:59:30 +00002848 tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio); /* change direction */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849
Sakari Ailusc659c382011-01-21 10:59:30 +00002850 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* clock idle bit */
2851 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
2852 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* wait 300ns */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853
Sakari Ailusc659c382011-01-21 10:59:30 +00002854 nack = tlan_get_bit(TLAN_NET_SIO_MDATA, sio); /* check for ACK */
2855 tlan_set_bit(TLAN_NET_SIO_MCLK, sio); /* finish ACK */
2856 if (nack) { /* no ACK, so fake it */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857 for (i = 0; i < 16; i++) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002858 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2859 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860 }
2861 tmp = 0xffff;
Joe Perches37fce432010-01-12 20:59:13 +00002862 err = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863 } else { /* ACK, so read data */
2864 for (tmp = 0, i = 0x8000; i; i >>= 1) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002865 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2866 if (tlan_get_bit(TLAN_NET_SIO_MDATA, sio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 tmp |= i;
Sakari Ailusc659c382011-01-21 10:59:30 +00002868 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 }
2870 }
2871
2872
Sakari Ailusc659c382011-01-21 10:59:30 +00002873 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
2874 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002875
Sakari Ailusc659c382011-01-21 10:59:30 +00002876 if (minten)
2877 tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878
2879 *val = tmp;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002880
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881 if (!in_irq())
2882 spin_unlock_irqrestore(&priv->lock, flags);
2883
2884 return err;
2885
Sakari Ailusc659c382011-01-21 10:59:30 +00002886}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887
2888
2889
2890
Sakari Ailusc659c382011-01-21 10:59:30 +00002891/***************************************************************
2892 * tlan_mii_send_data
2893 *
2894 * Returns:
2895 * Nothing
2896 * Parms:
2897 * base_port The base IO port of the adapter in
2898 * question.
2899 * dev The address of the PHY to be queried.
2900 * data The value to be placed on the MII bus.
2901 * num_bits The number of bits in data that are to
2902 * be placed on the MII bus.
2903 *
2904 * This function sends on sequence of bits on the MII
2905 * configuration bus.
2906 *
2907 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002908
Sakari Ailusc659c382011-01-21 10:59:30 +00002909static void tlan_mii_send_data(u16 base_port, u32 data, unsigned num_bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910{
2911 u16 sio;
2912 u32 i;
2913
Sakari Ailusc659c382011-01-21 10:59:30 +00002914 if (num_bits == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915 return;
2916
Sakari Ailusc659c382011-01-21 10:59:30 +00002917 outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002918 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
Sakari Ailusc659c382011-01-21 10:59:30 +00002919 tlan_set_bit(TLAN_NET_SIO_MTXEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002920
Sakari Ailusc659c382011-01-21 10:59:30 +00002921 for (i = (0x1 << (num_bits - 1)); i; i >>= 1) {
2922 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2923 (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
2924 if (data & i)
2925 tlan_set_bit(TLAN_NET_SIO_MDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002926 else
Sakari Ailusc659c382011-01-21 10:59:30 +00002927 tlan_clear_bit(TLAN_NET_SIO_MDATA, sio);
2928 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
2929 (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 }
2931
Sakari Ailusc659c382011-01-21 10:59:30 +00002932}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002933
2934
2935
2936
Sakari Ailusc659c382011-01-21 10:59:30 +00002937/***************************************************************
2938 * TLan_MiiSync
2939 *
2940 * Returns:
2941 * Nothing
2942 * Parms:
2943 * base_port The base IO port of the adapter in
2944 * question.
2945 *
2946 * This functions syncs all PHYs in terms of the MII configuration
2947 * bus.
2948 *
2949 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950
Sakari Ailusc659c382011-01-21 10:59:30 +00002951static void tlan_mii_sync(u16 base_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952{
2953 int i;
2954 u16 sio;
2955
Sakari Ailusc659c382011-01-21 10:59:30 +00002956 outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002957 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
2958
Sakari Ailusc659c382011-01-21 10:59:30 +00002959 tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio);
2960 for (i = 0; i < 32; i++) {
2961 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2962 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002963 }
2964
Sakari Ailusc659c382011-01-21 10:59:30 +00002965}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966
2967
2968
2969
Sakari Ailusc659c382011-01-21 10:59:30 +00002970/***************************************************************
2971 * tlan_mii_write_reg
2972 *
2973 * Returns:
2974 * Nothing
2975 * Parms:
2976 * dev The device structure for the device
2977 * to write to.
2978 * phy The address of the PHY to be written to.
2979 * reg The register whose contents are to be
2980 * written.
2981 * val The value to be written to the register.
2982 *
2983 * This function uses the TLAN's MII bus to write the contents of a
2984 * given register on a PHY. It sends the appropriate info and then
2985 * writes the 16-bit register value from the MII configuration bus
2986 * via the TLAN SIO register.
2987 *
2988 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002989
Sakari Ailusc659c382011-01-21 10:59:30 +00002990static void
2991tlan_mii_write_reg(struct net_device *dev, u16 phy, u16 reg, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992{
2993 u16 sio;
2994 int minten;
2995 unsigned long flags = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002996 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997
2998 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2999 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003000
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001 if (!in_irq())
3002 spin_lock_irqsave(&priv->lock, flags);
3003
Sakari Ailusc659c382011-01-21 10:59:30 +00003004 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005
Sakari Ailusc659c382011-01-21 10:59:30 +00003006 minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
3007 if (minten)
3008 tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009
Sakari Ailusc659c382011-01-21 10:59:30 +00003010 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */
3011 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* write (01b) */
3012 tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */
3013 tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003014
Sakari Ailusc659c382011-01-21 10:59:30 +00003015 tlan_mii_send_data(dev->base_addr, 0x2, 2); /* send ACK */
3016 tlan_mii_send_data(dev->base_addr, val, 16); /* send data */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003017
Sakari Ailusc659c382011-01-21 10:59:30 +00003018 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
3019 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003020
Sakari Ailusc659c382011-01-21 10:59:30 +00003021 if (minten)
3022 tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003023
Linus Torvalds1da177e2005-04-16 15:20:36 -07003024 if (!in_irq())
3025 spin_unlock_irqrestore(&priv->lock, flags);
3026
Sakari Ailusc659c382011-01-21 10:59:30 +00003027}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028
3029
3030
3031
3032/*****************************************************************************
3033******************************************************************************
3034
Sakari Ailusc659c382011-01-21 10:59:30 +00003035ThunderLAN driver eeprom routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07003036
Sakari Ailusc659c382011-01-21 10:59:30 +00003037the Compaq netelligent 10 and 10/100 cards use a microchip 24C02A
3038EEPROM. these functions are based on information in microchip's
3039data sheet. I don't know how well this functions will work with
3040other Eeproms.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003041
3042******************************************************************************
3043*****************************************************************************/
3044
3045
Sakari Ailusc659c382011-01-21 10:59:30 +00003046/***************************************************************
3047 * tlan_ee_send_start
3048 *
3049 * Returns:
3050 * Nothing
3051 * Parms:
3052 * io_base The IO port base address for the
3053 * TLAN device with the EEPROM to
3054 * use.
3055 *
3056 * This function sends a start cycle to an EEPROM attached
3057 * to a TLAN chip.
3058 *
3059 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003060
Sakari Ailusc659c382011-01-21 10:59:30 +00003061static void tlan_ee_send_start(u16 io_base)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062{
3063 u16 sio;
3064
Sakari Ailusc659c382011-01-21 10:59:30 +00003065 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3067
Sakari Ailusc659c382011-01-21 10:59:30 +00003068 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3069 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
3070 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
3071 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3072 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003073
Sakari Ailusc659c382011-01-21 10:59:30 +00003074}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075
3076
3077
3078
Sakari Ailusc659c382011-01-21 10:59:30 +00003079/***************************************************************
3080 * tlan_ee_send_byte
3081 *
3082 * Returns:
3083 * If the correct ack was received, 0, otherwise 1
3084 * Parms: io_base The IO port base address for the
3085 * TLAN device with the EEPROM to
3086 * use.
3087 * data The 8 bits of information to
3088 * send to the EEPROM.
3089 * stop If TLAN_EEPROM_STOP is passed, a
3090 * stop cycle is sent after the
3091 * byte is sent after the ack is
3092 * read.
3093 *
3094 * This function sends a byte on the serial EEPROM line,
3095 * driving the clock to send each bit. The function then
3096 * reverses transmission direction and reads an acknowledge
3097 * bit.
3098 *
3099 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003100
Sakari Ailusc659c382011-01-21 10:59:30 +00003101static int tlan_ee_send_byte(u16 io_base, u8 data, int stop)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003102{
3103 int err;
3104 u8 place;
3105 u16 sio;
3106
Sakari Ailusc659c382011-01-21 10:59:30 +00003107 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003108 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3109
3110 /* Assume clock is low, tx is enabled; */
Sakari Ailusc659c382011-01-21 10:59:30 +00003111 for (place = 0x80; place != 0; place >>= 1) {
3112 if (place & data)
3113 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114 else
Sakari Ailusc659c382011-01-21 10:59:30 +00003115 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3116 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3117 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003118 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003119 tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
3120 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3121 err = tlan_get_bit(TLAN_NET_SIO_EDATA, sio);
3122 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
3123 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003124
Sakari Ailusc659c382011-01-21 10:59:30 +00003125 if ((!err) && stop) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003126 /* STOP, raise data while clock is high */
Sakari Ailusc659c382011-01-21 10:59:30 +00003127 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3128 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3129 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130 }
3131
Eric Dumazet807540b2010-09-23 05:40:09 +00003132 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133
Sakari Ailusc659c382011-01-21 10:59:30 +00003134}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003135
3136
3137
3138
Sakari Ailusc659c382011-01-21 10:59:30 +00003139/***************************************************************
3140 * tlan_ee_receive_byte
3141 *
3142 * Returns:
3143 * Nothing
3144 * Parms:
3145 * io_base The IO port base address for the
3146 * TLAN device with the EEPROM to
3147 * use.
3148 * data An address to a char to hold the
3149 * data sent from the EEPROM.
3150 * stop If TLAN_EEPROM_STOP is passed, a
3151 * stop cycle is sent after the
3152 * byte is received, and no ack is
3153 * sent.
3154 *
3155 * This function receives 8 bits of data from the EEPROM
3156 * over the serial link. It then sends and ack bit, or no
3157 * ack and a stop bit. This function is used to retrieve
3158 * data after the address of a byte in the EEPROM has been
3159 * sent.
3160 *
3161 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003162
Sakari Ailusc659c382011-01-21 10:59:30 +00003163static void tlan_ee_receive_byte(u16 io_base, u8 *data, int stop)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003164{
3165 u8 place;
3166 u16 sio;
3167
Sakari Ailusc659c382011-01-21 10:59:30 +00003168 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3170 *data = 0;
3171
3172 /* Assume clock is low, tx is enabled; */
Sakari Ailusc659c382011-01-21 10:59:30 +00003173 tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
3174 for (place = 0x80; place; place >>= 1) {
3175 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3176 if (tlan_get_bit(TLAN_NET_SIO_EDATA, sio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003177 *data |= place;
Sakari Ailusc659c382011-01-21 10:59:30 +00003178 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003179 }
3180
Sakari Ailusc659c382011-01-21 10:59:30 +00003181 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
3182 if (!stop) {
3183 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); /* ack = 0 */
3184 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3185 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00003187 tlan_set_bit(TLAN_NET_SIO_EDATA, sio); /* no ack = 1 (?) */
3188 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3189 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003190 /* STOP, raise data while clock is high */
Sakari Ailusc659c382011-01-21 10:59:30 +00003191 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3192 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3193 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194 }
3195
Sakari Ailusc659c382011-01-21 10:59:30 +00003196}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003197
3198
3199
3200
Sakari Ailusc659c382011-01-21 10:59:30 +00003201/***************************************************************
3202 * tlan_ee_read_byte
3203 *
3204 * Returns:
3205 * No error = 0, else, the stage at which the error
3206 * occurred.
3207 * Parms:
3208 * io_base The IO port base address for the
3209 * TLAN device with the EEPROM to
3210 * use.
3211 * ee_addr The address of the byte in the
3212 * EEPROM whose contents are to be
3213 * retrieved.
3214 * data An address to a char to hold the
3215 * data obtained from the EEPROM.
3216 *
3217 * This function reads a byte of information from an byte
3218 * cell in the EEPROM.
3219 *
3220 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003221
Sakari Ailusc659c382011-01-21 10:59:30 +00003222static int tlan_ee_read_byte(struct net_device *dev, u8 ee_addr, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003223{
3224 int err;
Sakari Ailusc659c382011-01-21 10:59:30 +00003225 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003226 unsigned long flags = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00003227 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003228
3229 spin_lock_irqsave(&priv->lock, flags);
3230
Sakari Ailusc659c382011-01-21 10:59:30 +00003231 tlan_ee_send_start(dev->base_addr);
3232 err = tlan_ee_send_byte(dev->base_addr, 0xa0, TLAN_EEPROM_ACK);
3233 if (err) {
3234 ret = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003235 goto fail;
3236 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003237 err = tlan_ee_send_byte(dev->base_addr, ee_addr, TLAN_EEPROM_ACK);
3238 if (err) {
3239 ret = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003240 goto fail;
3241 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003242 tlan_ee_send_start(dev->base_addr);
3243 err = tlan_ee_send_byte(dev->base_addr, 0xa1, TLAN_EEPROM_ACK);
3244 if (err) {
3245 ret = 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003246 goto fail;
3247 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003248 tlan_ee_receive_byte(dev->base_addr, data, TLAN_EEPROM_STOP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003249fail:
3250 spin_unlock_irqrestore(&priv->lock, flags);
3251
3252 return ret;
3253
Sakari Ailusc659c382011-01-21 10:59:30 +00003254}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003255
3256
3257