blob: 7721e6cf96f8dd8cfeb7ad02753ab3001446d2f9 [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
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/ioport.h>
33#include <linux/eisa.h>
34#include <linux/pci.h>
Domen Puncer1e7f0bd2005-06-26 18:22:14 -040035#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include <linux/netdevice.h>
37#include <linux/etherdevice.h>
38#include <linux/delay.h>
39#include <linux/spinlock.h>
40#include <linux/workqueue.h>
41#include <linux/mii.h>
42
43#include "tlan.h"
44
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
46/* For removing EISA devices */
Sakari Ailusc659c382011-01-21 10:59:30 +000047static struct net_device *tlan_eisa_devices;
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Sakari Ailusc659c382011-01-21 10:59:30 +000049static int tlan_devices_installed;
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
51/* Set speed, duplex and aui settings */
52static int aui[MAX_TLAN_BOARDS];
53static int duplex[MAX_TLAN_BOARDS];
54static int speed[MAX_TLAN_BOARDS];
55static int boards_found;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -070056module_param_array(aui, int, NULL, 0);
57module_param_array(duplex, int, NULL, 0);
58module_param_array(speed, int, NULL, 0);
59MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
Sakari Ailusc659c382011-01-21 10:59:30 +000060MODULE_PARM_DESC(duplex,
61 "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
Stephen Hemminger15efa9b2005-05-04 15:33:11 -070062MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)");
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
64MODULE_AUTHOR("Maintainer: Samuel Chessman <chessman@tux.org>");
65MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
66MODULE_LICENSE("GPL");
67
68
69/* Define this to enable Link beat monitoring */
70#undef MONITOR
71
72/* Turn on debugging. See Documentation/networking/tlan.txt for details */
73static int debug;
Stephen Hemminger15efa9b2005-05-04 15:33:11 -070074module_param(debug, int, 0);
75MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
Sakari Ailusc659c382011-01-21 10:59:30 +000077static const char tlan_signature[] = "TLAN";
Sakari Ailusfa6d5d42011-01-21 10:59:31 +000078static const char tlan_banner[] = "ThunderLAN driver v1.17\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -070079static int tlan_have_pci;
80static int tlan_have_eisa;
81
Sakari Ailusc659c382011-01-21 10:59:30 +000082static const char * const media[] = {
83 "10BaseT-HD", "10BaseT-FD", "100baseTx-HD",
84 "100BaseTx-FD", "100BaseT4", NULL
Linus Torvalds1da177e2005-04-16 15:20:36 -070085};
86
87static struct board {
Sakari Ailusc659c382011-01-21 10:59:30 +000088 const char *device_label;
89 u32 flags;
90 u16 addr_ofs;
Linus Torvalds1da177e2005-04-16 15:20:36 -070091} board_info[] = {
92 { "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
Sakari Ailusc659c382011-01-21 10:59:30 +000093 { "Compaq Netelligent 10/100 TX PCI UTP",
94 TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 { "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -070096 { "Compaq NetFlex-3/P",
97 TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 { "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -070099 { "Compaq Netelligent Integrated 10/100 TX UTP",
100 TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
Sakari Ailusc659c382011-01-21 10:59:30 +0000101 { "Compaq Netelligent Dual 10/100 TX PCI UTP",
102 TLAN_ADAPTER_NONE, 0x83 },
103 { "Compaq Netelligent 10/100 TX Embedded UTP",
104 TLAN_ADAPTER_NONE, 0x83 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
Sakari Ailusc659c382011-01-21 10:59:30 +0000106 { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xf8 },
107 { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xf8 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
Sakari Ailusc659c382011-01-21 10:59:30 +0000109 { "Compaq Netelligent 10 T/2 PCI UTP/coax", TLAN_ADAPTER_NONE, 0x83 },
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700110 { "Compaq NetFlex-3/E",
Sakari Ailusc659c382011-01-21 10:59:30 +0000111 TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700112 TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
Sakari Ailusc659c382011-01-21 10:59:30 +0000113 { "Compaq NetFlex-3/E",
114 TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115};
116
Alexey Dobriyana3aa1882010-01-07 11:58:11 +0000117static DEFINE_PCI_DEVICE_TABLE(tlan_pci_tbl) = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
Sakari Ailusc659c382011-01-21 10:59:30 +0000119 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
Sakari Ailusc659c382011-01-21 10:59:30 +0000121 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3I,
Sakari Ailusc659c382011-01-21 10:59:30 +0000123 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_THUNDER,
Sakari Ailusc659c382011-01-21 10:59:30 +0000125 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3B,
Sakari Ailusc659c382011-01-21 10:59:30 +0000127 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100PI,
Sakari Ailusc659c382011-01-21 10:59:30 +0000129 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100D,
Sakari Ailusc659c382011-01-21 10:59:30 +0000131 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100I,
Sakari Ailusc659c382011-01-21 10:59:30 +0000133 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183,
Sakari Ailusc659c382011-01-21 10:59:30 +0000135 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325,
Sakari Ailusc659c382011-01-21 10:59:30 +0000137 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
Sakari Ailusc659c382011-01-21 10:59:30 +0000139 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,
Sakari Ailusc659c382011-01-21 10:59:30 +0000141 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2,
Sakari Ailusc659c382011-01-21 10:59:30 +0000143 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 { 0,}
145};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400146MODULE_DEVICE_TABLE(pci, tlan_pci_tbl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147
Sakari Ailusc659c382011-01-21 10:59:30 +0000148static void tlan_eisa_probe(void);
149static void tlan_eisa_cleanup(void);
150static int tlan_init(struct net_device *);
151static int tlan_open(struct net_device *dev);
152static netdev_tx_t tlan_start_tx(struct sk_buff *, struct net_device *);
153static irqreturn_t tlan_handle_interrupt(int, void *);
154static int tlan_close(struct net_device *);
155static struct net_device_stats *tlan_get_stats(struct net_device *);
156static void tlan_set_multicast_list(struct net_device *);
157static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
158static int tlan_probe1(struct pci_dev *pdev, long ioaddr,
159 int irq, int rev, const struct pci_device_id *ent);
160static void tlan_tx_timeout(struct net_device *dev);
161static void tlan_tx_timeout_work(struct work_struct *work);
162static int tlan_init_one(struct pci_dev *pdev,
163 const struct pci_device_id *ent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164
Sakari Ailusc659c382011-01-21 10:59:30 +0000165static u32 tlan_handle_tx_eof(struct net_device *, u16);
166static u32 tlan_handle_stat_overflow(struct net_device *, u16);
167static u32 tlan_handle_rx_eof(struct net_device *, u16);
168static u32 tlan_handle_dummy(struct net_device *, u16);
169static u32 tlan_handle_tx_eoc(struct net_device *, u16);
170static u32 tlan_handle_status_check(struct net_device *, u16);
171static u32 tlan_handle_rx_eoc(struct net_device *, u16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172
Sakari Ailusc659c382011-01-21 10:59:30 +0000173static void tlan_timer(unsigned long);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174
Sakari Ailusc659c382011-01-21 10:59:30 +0000175static void tlan_reset_lists(struct net_device *);
176static void tlan_free_lists(struct net_device *);
177static void tlan_print_dio(u16);
178static void tlan_print_list(struct tlan_list *, char *, int);
179static void tlan_read_and_clear_stats(struct net_device *, int);
180static void tlan_reset_adapter(struct net_device *);
181static void tlan_finish_reset(struct net_device *);
182static void tlan_set_mac(struct net_device *, int areg, char *mac);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183
Sakari Ailusc659c382011-01-21 10:59:30 +0000184static void tlan_phy_print(struct net_device *);
185static void tlan_phy_detect(struct net_device *);
186static void tlan_phy_power_down(struct net_device *);
187static void tlan_phy_power_up(struct net_device *);
188static void tlan_phy_reset(struct net_device *);
189static void tlan_phy_start_link(struct net_device *);
190static void tlan_phy_finish_auto_neg(struct net_device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191#ifdef MONITOR
Sakari Ailusc659c382011-01-21 10:59:30 +0000192static void tlan_phy_monitor(struct net_device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193#endif
194
195/*
Sakari Ailusc659c382011-01-21 10:59:30 +0000196 static int tlan_phy_nop(struct net_device *);
197 static int tlan_phy_internal_check(struct net_device *);
198 static int tlan_phy_internal_service(struct net_device *);
199 static int tlan_phy_dp83840a_check(struct net_device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200*/
201
Sakari Ailusc659c382011-01-21 10:59:30 +0000202static bool tlan_mii_read_reg(struct net_device *, u16, u16, u16 *);
203static void tlan_mii_send_data(u16, u32, unsigned);
204static void tlan_mii_sync(u16);
205static void tlan_mii_write_reg(struct net_device *, u16, u16, u16);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206
Sakari Ailusc659c382011-01-21 10:59:30 +0000207static void tlan_ee_send_start(u16);
208static int tlan_ee_send_byte(u16, u8, int);
209static void tlan_ee_receive_byte(u16, u8 *, int);
210static int tlan_ee_read_byte(struct net_device *, u8, u8 *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
212
Stephen Hemminger93e16842008-05-30 09:49:55 -0700213static inline void
Sakari Ailusc659c382011-01-21 10:59:30 +0000214tlan_store_skb(struct tlan_list *tag, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215{
216 unsigned long addr = (unsigned long)skb;
Stephen Hemminger93e16842008-05-30 09:49:55 -0700217 tag->buffer[9].address = addr;
218 tag->buffer[8].address = upper_32_bits(addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219}
220
Stephen Hemminger93e16842008-05-30 09:49:55 -0700221static inline struct sk_buff *
Sakari Ailusc659c382011-01-21 10:59:30 +0000222tlan_get_skb(const struct tlan_list *tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223{
Stephen Hemminger93e16842008-05-30 09:49:55 -0700224 unsigned long addr;
225
Robert Fitzsimons0d63bea2008-08-09 17:54:02 +0100226 addr = tag->buffer[9].address;
227 addr |= (tag->buffer[8].address << 16) << 16;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 return (struct sk_buff *) addr;
229}
230
Sakari Ailusc659c382011-01-21 10:59:30 +0000231static u32
232(*tlan_int_vector[TLAN_INT_NUMBER_OF_INTS])(struct net_device *, u16) = {
Stephen Hemmingera3ccc782008-05-30 09:49:57 -0700233 NULL,
Sakari Ailusc659c382011-01-21 10:59:30 +0000234 tlan_handle_tx_eof,
235 tlan_handle_stat_overflow,
236 tlan_handle_rx_eof,
237 tlan_handle_dummy,
238 tlan_handle_tx_eoc,
239 tlan_handle_status_check,
240 tlan_handle_rx_eoc
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241};
242
243static inline void
Sakari Ailusc659c382011-01-21 10:59:30 +0000244tlan_set_timer(struct net_device *dev, u32 ticks, u32 type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245{
Sakari Ailusc659c382011-01-21 10:59:30 +0000246 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 unsigned long flags = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400248
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 if (!in_irq())
250 spin_lock_irqsave(&priv->lock, flags);
Sakari Ailusc659c382011-01-21 10:59:30 +0000251 if (priv->timer.function != NULL &&
252 priv->timer_type != TLAN_TIMER_ACTIVITY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 if (!in_irq())
254 spin_unlock_irqrestore(&priv->lock, flags);
255 return;
256 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000257 priv->timer.function = tlan_timer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 if (!in_irq())
259 spin_unlock_irqrestore(&priv->lock, flags);
260
261 priv->timer.data = (unsigned long) dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000262 priv->timer_set_at = jiffies;
263 priv->timer_type = type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 mod_timer(&priv->timer, jiffies + ticks);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400265
Sakari Ailusc659c382011-01-21 10:59:30 +0000266}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267
268
269/*****************************************************************************
270******************************************************************************
271
Sakari Ailusc659c382011-01-21 10:59:30 +0000272ThunderLAN driver primary functions
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273
Sakari Ailusc659c382011-01-21 10:59:30 +0000274these functions are more or less common to all linux network drivers.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275
276******************************************************************************
277*****************************************************************************/
278
279
280
281
282
Sakari Ailusc659c382011-01-21 10:59:30 +0000283/***************************************************************
284 * tlan_remove_one
285 *
286 * Returns:
287 * Nothing
288 * Parms:
289 * None
290 *
291 * Goes through the TLanDevices list and frees the device
292 * structs and memory associated with each device (lists
293 * and buffers). It also ureserves the IO port regions
294 * associated with this device.
295 *
296 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297
298
Sakari Ailusc659c382011-01-21 10:59:30 +0000299static void __devexit tlan_remove_one(struct pci_dev *pdev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300{
Sakari Ailusc659c382011-01-21 10:59:30 +0000301 struct net_device *dev = pci_get_drvdata(pdev);
302 struct tlan_priv *priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400303
Sakari Ailusc659c382011-01-21 10:59:30 +0000304 unregister_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305
Sakari Ailusc659c382011-01-21 10:59:30 +0000306 if (priv->dma_storage) {
307 pci_free_consistent(priv->pci_dev,
308 priv->dma_size, priv->dma_storage,
309 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 }
311
312#ifdef CONFIG_PCI
313 pci_release_regions(pdev);
314#endif
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400315
Sakari Ailusc659c382011-01-21 10:59:30 +0000316 free_netdev(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400317
Sakari Ailusc659c382011-01-21 10:59:30 +0000318 pci_set_drvdata(pdev, NULL);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400319}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000321static void tlan_start(struct net_device *dev)
322{
323 tlan_reset_lists(dev);
324 /* NOTE: It might not be necessary to read the stats before a
325 reset if you don't care what the values are.
326 */
327 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
328 tlan_reset_adapter(dev);
329 netif_wake_queue(dev);
330}
331
332static void tlan_stop(struct net_device *dev)
333{
334 struct tlan_priv *priv = netdev_priv(dev);
335
336 tlan_read_and_clear_stats(dev, TLAN_RECORD);
337 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
338 /* Reset and power down phy */
339 tlan_reset_adapter(dev);
340 if (priv->timer.function != NULL) {
341 del_timer_sync(&priv->timer);
342 priv->timer.function = NULL;
343 }
344}
345
346#ifdef CONFIG_PM
347
348static int tlan_suspend(struct pci_dev *pdev, pm_message_t state)
349{
350 struct net_device *dev = pci_get_drvdata(pdev);
351
352 if (netif_running(dev))
353 tlan_stop(dev);
354
355 netif_device_detach(dev);
356 pci_save_state(pdev);
357 pci_disable_device(pdev);
358 pci_wake_from_d3(pdev, false);
359 pci_set_power_state(pdev, PCI_D3hot);
360
361 return 0;
362}
363
364static int tlan_resume(struct pci_dev *pdev)
365{
366 struct net_device *dev = pci_get_drvdata(pdev);
367
368 pci_set_power_state(pdev, PCI_D0);
369 pci_restore_state(pdev);
370 pci_enable_wake(pdev, 0, 0);
371 netif_device_attach(dev);
372
373 if (netif_running(dev))
374 tlan_start(dev);
375
376 return 0;
377}
378
379#else /* CONFIG_PM */
380
381#define tlan_suspend NULL
382#define tlan_resume NULL
383
384#endif /* CONFIG_PM */
385
386
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387static struct pci_driver tlan_driver = {
388 .name = "tlan",
389 .id_table = tlan_pci_tbl,
390 .probe = tlan_init_one,
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400391 .remove = __devexit_p(tlan_remove_one),
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000392 .suspend = tlan_suspend,
393 .resume = tlan_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394};
395
396static int __init tlan_probe(void)
397{
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800398 int rc = -ENODEV;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400399
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400 printk(KERN_INFO "%s", tlan_banner);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400401
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400403
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 /* Use new style PCI probing. Now the kernel will
405 do most of this for us */
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800406 rc = pci_register_driver(&tlan_driver);
407
408 if (rc != 0) {
409 printk(KERN_ERR "TLAN: Could not register pci driver.\n");
410 goto err_out_pci_free;
411 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412
413 TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
Sakari Ailusc659c382011-01-21 10:59:30 +0000414 tlan_eisa_probe();
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400415
416 printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d EISA: %d\n",
Sakari Ailusc659c382011-01-21 10:59:30 +0000417 tlan_devices_installed, tlan_devices_installed == 1 ? "" : "s",
418 tlan_have_pci, tlan_have_eisa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419
Sakari Ailusc659c382011-01-21 10:59:30 +0000420 if (tlan_devices_installed == 0) {
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800421 rc = -ENODEV;
422 goto err_out_pci_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 }
424 return 0;
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800425
426err_out_pci_unreg:
427 pci_unregister_driver(&tlan_driver);
428err_out_pci_free:
Leonardo Potenza6c04a512008-02-04 23:47:16 -0800429 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400431
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
Sakari Ailusc659c382011-01-21 10:59:30 +0000433static int __devinit tlan_init_one(struct pci_dev *pdev,
434 const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435{
Sakari Ailusc659c382011-01-21 10:59:30 +0000436 return tlan_probe1(pdev, -1, -1, 0, ent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437}
438
439
440/*
Sakari Ailusc659c382011-01-21 10:59:30 +0000441***************************************************************
442* tlan_probe1
443*
444* Returns:
445* 0 on success, error code on error
446* Parms:
447* none
448*
449* The name is lower case to fit in with all the rest of
450* the netcard_probe names. This function looks for
451* another TLan based adapter, setting it up with the
452* allocated device struct if one is found.
453* tlan_probe has been ported to the new net API and
454* now allocates its own device structure. This function
455* is also used by modules.
456*
457**************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
Sakari Ailusc659c382011-01-21 10:59:30 +0000459static int __devinit tlan_probe1(struct pci_dev *pdev,
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700460 long ioaddr, int irq, int rev,
Sakari Ailusc659c382011-01-21 10:59:30 +0000461 const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462{
463
464 struct net_device *dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000465 struct tlan_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 u16 device_id;
467 int reg, rc = -ENODEV;
468
Adrian Bunkad9f6712006-02-05 00:37:47 +0100469#ifdef CONFIG_PCI
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 if (pdev) {
471 rc = pci_enable_device(pdev);
472 if (rc)
473 return rc;
474
Sakari Ailusc659c382011-01-21 10:59:30 +0000475 rc = pci_request_regions(pdev, tlan_signature);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 if (rc) {
477 printk(KERN_ERR "TLAN: Could not reserve IO regions\n");
478 goto err_out;
479 }
480 }
Adrian Bunkad9f6712006-02-05 00:37:47 +0100481#endif /* CONFIG_PCI */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482
Sakari Ailusc659c382011-01-21 10:59:30 +0000483 dev = alloc_etherdev(sizeof(struct tlan_priv));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 if (dev == NULL) {
485 printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");
486 rc = -ENOMEM;
487 goto err_out_regions;
488 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 SET_NETDEV_DEV(dev, &pdev->dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400490
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 priv = netdev_priv(dev);
492
Sakari Ailusc659c382011-01-21 10:59:30 +0000493 priv->pci_dev = pdev;
David Howellsc4028952006-11-22 14:57:56 +0000494 priv->dev = dev;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400495
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 /* Is this a PCI device? */
497 if (pdev) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000498 u32 pci_io_base = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499
500 priv->adapter = &board_info[ent->driver_data];
501
Yang Hongyang284901a2009-04-06 19:01:15 -0700502 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503 if (rc) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000504 printk(KERN_ERR
505 "TLAN: No suitable PCI mapping available.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 goto err_out_free_dev;
507 }
508
Sakari Ailusc659c382011-01-21 10:59:30 +0000509 for (reg = 0; reg <= 5; reg++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
511 pci_io_base = pci_resource_start(pdev, reg);
Sakari Ailusc659c382011-01-21 10:59:30 +0000512 TLAN_DBG(TLAN_DEBUG_GNRL,
513 "IO mapping is available at %x.\n",
514 pci_io_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700515 break;
516 }
517 }
518 if (!pci_io_base) {
519 printk(KERN_ERR "TLAN: No IO mappings available\n");
520 rc = -EIO;
521 goto err_out_free_dev;
522 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400523
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 dev->base_addr = pci_io_base;
525 dev->irq = pdev->irq;
Sakari Ailusc659c382011-01-21 10:59:30 +0000526 priv->adapter_rev = pdev->revision;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 pci_set_master(pdev);
528 pci_set_drvdata(pdev, dev);
529
530 } else { /* EISA card */
531 /* This is a hack. We need to know which board structure
532 * is suited for this adapter */
533 device_id = inw(ioaddr + EISA_ID2);
534 priv->is_eisa = 1;
535 if (device_id == 0x20F1) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000536 priv->adapter = &board_info[13]; /* NetFlex-3/E */
537 priv->adapter_rev = 23; /* TLAN 2.3 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 } else {
539 priv->adapter = &board_info[14];
Sakari Ailusc659c382011-01-21 10:59:30 +0000540 priv->adapter_rev = 10; /* TLAN 1.0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541 }
542 dev->base_addr = ioaddr;
543 dev->irq = irq;
544 }
545
546 /* Kernel parameters */
547 if (dev->mem_start) {
548 priv->aui = dev->mem_start & 0x01;
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700549 priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0
550 : (dev->mem_start & 0x06) >> 1;
551 priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0
552 : (dev->mem_start & 0x18) >> 3;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400553
Sakari Ailusc659c382011-01-21 10:59:30 +0000554 if (priv->speed == 0x1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 priv->speed = TLAN_SPEED_10;
Sakari Ailusc659c382011-01-21 10:59:30 +0000556 else if (priv->speed == 0x2)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 priv->speed = TLAN_SPEED_100;
Sakari Ailusc659c382011-01-21 10:59:30 +0000558
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 debug = priv->debug = dev->mem_end;
560 } else {
561 priv->aui = aui[boards_found];
562 priv->speed = speed[boards_found];
563 priv->duplex = duplex[boards_found];
564 priv->debug = debug;
565 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400566
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 /* This will be used when we get an adapter error from
568 * within our irq handler */
Sakari Ailusc659c382011-01-21 10:59:30 +0000569 INIT_WORK(&priv->tlan_tqueue, tlan_tx_timeout_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
571 spin_lock_init(&priv->lock);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400572
Sakari Ailusc659c382011-01-21 10:59:30 +0000573 rc = tlan_init(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 if (rc) {
575 printk(KERN_ERR "TLAN: Could not set up device.\n");
576 goto err_out_free_dev;
577 }
578
579 rc = register_netdev(dev);
580 if (rc) {
581 printk(KERN_ERR "TLAN: Could not register device.\n");
582 goto err_out_uninit;
583 }
584
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400585
Sakari Ailusc659c382011-01-21 10:59:30 +0000586 tlan_devices_installed++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 boards_found++;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400588
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 /* pdev is NULL if this is an EISA device */
590 if (pdev)
591 tlan_have_pci++;
592 else {
Sakari Ailusc659c382011-01-21 10:59:30 +0000593 priv->next_device = tlan_eisa_devices;
594 tlan_eisa_devices = dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 tlan_have_eisa++;
596 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400597
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n",
Sakari Ailusc659c382011-01-21 10:59:30 +0000599 dev->name,
600 (int) dev->irq,
601 (int) dev->base_addr,
602 priv->adapter->device_label,
603 priv->adapter_rev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 return 0;
605
606err_out_uninit:
Sakari Ailusc659c382011-01-21 10:59:30 +0000607 pci_free_consistent(priv->pci_dev, priv->dma_size, priv->dma_storage,
608 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609err_out_free_dev:
610 free_netdev(dev);
611err_out_regions:
612#ifdef CONFIG_PCI
613 if (pdev)
614 pci_release_regions(pdev);
615#endif
616err_out:
617 if (pdev)
618 pci_disable_device(pdev);
619 return rc;
620}
621
622
Sakari Ailusc659c382011-01-21 10:59:30 +0000623static void tlan_eisa_cleanup(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624{
625 struct net_device *dev;
Sakari Ailusc659c382011-01-21 10:59:30 +0000626 struct tlan_priv *priv;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400627
Sakari Ailusc659c382011-01-21 10:59:30 +0000628 while (tlan_have_eisa) {
629 dev = tlan_eisa_devices;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 priv = netdev_priv(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +0000631 if (priv->dma_storage) {
632 pci_free_consistent(priv->pci_dev, priv->dma_size,
633 priv->dma_storage,
634 priv->dma_storage_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000636 release_region(dev->base_addr, 0x10);
637 unregister_netdev(dev);
638 tlan_eisa_devices = priv->next_device;
639 free_netdev(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 tlan_have_eisa--;
641 }
642}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400643
644
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645static void __exit tlan_exit(void)
646{
647 pci_unregister_driver(&tlan_driver);
648
649 if (tlan_have_eisa)
Sakari Ailusc659c382011-01-21 10:59:30 +0000650 tlan_eisa_cleanup();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652}
653
654
655/* Module loading/unloading */
656module_init(tlan_probe);
657module_exit(tlan_exit);
658
659
660
Sakari Ailusc659c382011-01-21 10:59:30 +0000661/**************************************************************
662 * tlan_eisa_probe
663 *
664 * Returns: 0 on success, 1 otherwise
665 *
666 * Parms: None
667 *
668 *
669 * This functions probes for EISA devices and calls
670 * TLan_probe1 when one is found.
671 *
672 *************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673
Sakari Ailusc659c382011-01-21 10:59:30 +0000674static void __init tlan_eisa_probe(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675{
Sakari Ailusc659c382011-01-21 10:59:30 +0000676 long ioaddr;
677 int rc = -ENODEV;
678 int irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 u16 device_id;
680
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400681 if (!EISA_bus) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
683 return;
684 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400685
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 /* Loop through all slots of the EISA bus */
687 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400688
Sakari Ailusc659c382011-01-21 10:59:30 +0000689 TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
690 (int) ioaddr + 0xc80, inw(ioaddr + EISA_ID));
691 TLAN_DBG(TLAN_DEBUG_PROBE, "EISA_ID 0x%4x: 0x%4x\n",
692 (int) ioaddr + 0xc82, inw(ioaddr + EISA_ID2));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693
694
Sakari Ailusc659c382011-01-21 10:59:30 +0000695 TLAN_DBG(TLAN_DEBUG_PROBE,
696 "Probing for EISA adapter at IO: 0x%4x : ",
697 (int) ioaddr);
698 if (request_region(ioaddr, 0x10, tlan_signature) == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 goto out;
700
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400701 if (inw(ioaddr + EISA_ID) != 0x110E) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 release_region(ioaddr, 0x10);
703 goto out;
704 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400705
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 device_id = inw(ioaddr + EISA_ID2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400707 if (device_id != 0x20F1 && device_id != 0x40F1) {
Sakari Ailusc659c382011-01-21 10:59:30 +0000708 release_region(ioaddr, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 goto out;
710 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400711
Sakari Ailusc659c382011-01-21 10:59:30 +0000712 /* check if adapter is enabled */
713 if (inb(ioaddr + EISA_CR) != 0x1) {
714 release_region(ioaddr, 0x10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 goto out2;
716 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400717
718 if (debug == 0x10)
Sakari Ailusc659c382011-01-21 10:59:30 +0000719 printk(KERN_INFO "Found one\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720
721
722 /* Get irq from board */
Sakari Ailusc659c382011-01-21 10:59:30 +0000723 switch (inb(ioaddr + 0xcc0)) {
724 case(0x10):
725 irq = 5;
726 break;
727 case(0x20):
728 irq = 9;
729 break;
730 case(0x40):
731 irq = 10;
732 break;
733 case(0x80):
734 irq = 11;
735 break;
736 default:
737 goto out;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400738 }
739
740
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 /* Setup the newly found eisa adapter */
Sakari Ailusc659c382011-01-21 10:59:30 +0000742 rc = tlan_probe1(NULL, ioaddr, irq,
743 12, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400745
Sakari Ailusc659c382011-01-21 10:59:30 +0000746out:
747 if (debug == 0x10)
748 printk(KERN_INFO "None found\n");
749 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
Sakari Ailusc659c382011-01-21 10:59:30 +0000751out2:
752 if (debug == 0x10)
753 printk(KERN_INFO "Card found but it is not enabled, skipping\n");
754 continue;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400755
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 }
757
Sakari Ailusc659c382011-01-21 10:59:30 +0000758}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759
760#ifdef CONFIG_NET_POLL_CONTROLLER
Sakari Ailusc659c382011-01-21 10:59:30 +0000761static void tlan_poll(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762{
763 disable_irq(dev->irq);
Sakari Ailusc659c382011-01-21 10:59:30 +0000764 tlan_handle_interrupt(dev->irq, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700765 enable_irq(dev->irq);
766}
767#endif
768
Sakari Ailusc659c382011-01-21 10:59:30 +0000769static const struct net_device_ops tlan_netdev_ops = {
770 .ndo_open = tlan_open,
771 .ndo_stop = tlan_close,
772 .ndo_start_xmit = tlan_start_tx,
773 .ndo_tx_timeout = tlan_tx_timeout,
774 .ndo_get_stats = tlan_get_stats,
775 .ndo_set_multicast_list = tlan_set_multicast_list,
776 .ndo_do_ioctl = tlan_ioctl,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800777 .ndo_change_mtu = eth_change_mtu,
Sakari Ailusc659c382011-01-21 10:59:30 +0000778 .ndo_set_mac_address = eth_mac_addr,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800779 .ndo_validate_addr = eth_validate_addr,
780#ifdef CONFIG_NET_POLL_CONTROLLER
Sakari Ailusc659c382011-01-21 10:59:30 +0000781 .ndo_poll_controller = tlan_poll,
Stephen Hemminger391c5e62009-01-07 17:27:15 -0800782#endif
783};
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400784
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785
786
Sakari Ailusc659c382011-01-21 10:59:30 +0000787/***************************************************************
788 * tlan_init
789 *
790 * Returns:
791 * 0 on success, error code otherwise.
792 * Parms:
793 * dev The structure of the device to be
794 * init'ed.
795 *
796 * This function completes the initialization of the
797 * device structure and driver. It reserves the IO
798 * addresses, allocates memory for the lists and bounce
799 * buffers, retrieves the MAC address from the eeprom
800 * and assignes the device's methods.
801 *
802 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803
Sakari Ailusc659c382011-01-21 10:59:30 +0000804static int tlan_init(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805{
806 int dma_size;
Sakari Ailusc659c382011-01-21 10:59:30 +0000807 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +0000809 struct tlan_priv *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
811 priv = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400812
Sakari Ailusc659c382011-01-21 10:59:30 +0000813 dma_size = (TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS)
814 * (sizeof(struct tlan_list));
815 priv->dma_storage = pci_alloc_consistent(priv->pci_dev,
816 dma_size,
817 &priv->dma_storage_dma);
818 priv->dma_size = dma_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400819
Sakari Ailusc659c382011-01-21 10:59:30 +0000820 if (priv->dma_storage == NULL) {
821 printk(KERN_ERR
822 "TLAN: Could not allocate lists and buffers for %s.\n",
823 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) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n",
Sakari Ailusc659c382011-01-21 10:59:30 +0000841 dev->name,
842 err);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 }
844 dev->addr_len = 6;
845
846 netif_carrier_off(dev);
847
848 /* Device methods */
Sakari Ailusc659c382011-01-21 10:59:30 +0000849 dev->netdev_ops = &tlan_netdev_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850 dev->watchdog_timeo = TX_TIMEOUT;
851
852 return 0;
853
Sakari Ailusc659c382011-01-21 10:59:30 +0000854}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855
856
857
858
Sakari Ailusc659c382011-01-21 10:59:30 +0000859/***************************************************************
860 * tlan_open
861 *
862 * Returns:
863 * 0 on success, error code otherwise.
864 * Parms:
865 * dev Structure of device to be opened.
866 *
867 * This routine puts the driver and TLAN adapter in a
868 * state where it is ready to send and receive packets.
869 * It allocates the IRQ, resets and brings the adapter
870 * out of reset, and allows interrupts. It also delays
871 * the startup for autonegotiation or sends a Rx GO
872 * command to the adapter, as appropriate.
873 *
874 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875
Sakari Ailusc659c382011-01-21 10:59:30 +0000876static int tlan_open(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877{
Sakari Ailusc659c382011-01-21 10:59:30 +0000878 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 int err;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400880
Sakari Ailusc659c382011-01-21 10:59:30 +0000881 priv->tlan_rev = tlan_dio_read8(dev->base_addr, TLAN_DEF_REVISION);
882 err = request_irq(dev->irq, tlan_handle_interrupt, IRQF_SHARED,
883 dev->name, dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400884
Sakari Ailusc659c382011-01-21 10:59:30 +0000885 if (err) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -0700886 pr_err("TLAN: Cannot open %s because IRQ %d is already in use.\n",
Sakari Ailusc659c382011-01-21 10:59:30 +0000887 dev->name, dev->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 return err;
889 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400890
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 init_timer(&priv->timer);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400892
Sakari Ailusfa6d5d42011-01-21 10:59:31 +0000893 tlan_start(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894
Sakari Ailusc659c382011-01-21 10:59:30 +0000895 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n",
896 dev->name, priv->tlan_rev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897
898 return 0;
899
Sakari Ailusc659c382011-01-21 10:59:30 +0000900}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901
902
903
Sakari Ailusc659c382011-01-21 10:59:30 +0000904/**************************************************************
905 * tlan_ioctl
906 *
907 * Returns:
908 * 0 on success, error code otherwise
909 * Params:
910 * dev structure of device to receive ioctl.
911 *
912 * rq ifreq structure to hold userspace data.
913 *
914 * cmd ioctl command.
915 *
916 *
917 *************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918
Sakari Ailusc659c382011-01-21 10:59:30 +0000919static int tlan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920{
Sakari Ailusc659c382011-01-21 10:59:30 +0000921 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 struct mii_ioctl_data *data = if_mii(rq);
Sakari Ailusc659c382011-01-21 10:59:30 +0000923 u32 phy = priv->phy[priv->phy_num];
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400924
Sakari Ailusc659c382011-01-21 10:59:30 +0000925 if (!priv->phy_online)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 return -EAGAIN;
927
Sakari Ailusc659c382011-01-21 10:59:30 +0000928 switch (cmd) {
929 case SIOCGMIIPHY: /* get address of MII PHY in use. */
930 data->phy_id = phy;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
932
Sakari Ailusc659c382011-01-21 10:59:30 +0000933 case SIOCGMIIREG: /* read MII PHY register. */
934 tlan_mii_read_reg(dev, data->phy_id & 0x1f,
935 data->reg_num & 0x1f, &data->val_out);
936 return 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400937
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938
Sakari Ailusc659c382011-01-21 10:59:30 +0000939 case SIOCSMIIREG: /* write MII PHY register. */
940 tlan_mii_write_reg(dev, data->phy_id & 0x1f,
941 data->reg_num & 0x1f, data->val_in);
942 return 0;
943 default:
944 return -EOPNOTSUPP;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 }
Sakari Ailusc659c382011-01-21 10:59:30 +0000946}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
948
Sakari Ailusc659c382011-01-21 10:59:30 +0000949/***************************************************************
950 * tlan_tx_timeout
951 *
952 * Returns: nothing
953 *
954 * Params:
955 * dev structure of device which timed out
956 * during transmit.
957 *
958 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959
Sakari Ailusc659c382011-01-21 10:59:30 +0000960static void tlan_tx_timeout(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700961{
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400962
Sakari Ailusc659c382011-01-21 10:59:30 +0000963 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400964
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965 /* Ok so we timed out, lets see what we can do about it...*/
Sakari Ailusc659c382011-01-21 10:59:30 +0000966 tlan_free_lists(dev);
967 tlan_reset_lists(dev);
968 tlan_read_and_clear_stats(dev, TLAN_IGNORE);
969 tlan_reset_adapter(dev);
Eric Dumazet1ae5dc32010-05-10 05:01:31 -0700970 dev->trans_start = jiffies; /* prevent tx timeout */
Sakari Ailusc659c382011-01-21 10:59:30 +0000971 netif_wake_queue(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
973}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400974
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975
Sakari Ailusc659c382011-01-21 10:59:30 +0000976/***************************************************************
977 * tlan_tx_timeout_work
978 *
979 * Returns: nothing
980 *
981 * Params:
982 * work work item of device which timed out
983 *
984 **************************************************************/
David Howellsc4028952006-11-22 14:57:56 +0000985
Sakari Ailusc659c382011-01-21 10:59:30 +0000986static void tlan_tx_timeout_work(struct work_struct *work)
David Howellsc4028952006-11-22 14:57:56 +0000987{
Sakari Ailusc659c382011-01-21 10:59:30 +0000988 struct tlan_priv *priv =
989 container_of(work, struct tlan_priv, tlan_tqueue);
David Howellsc4028952006-11-22 14:57:56 +0000990
Sakari Ailusc659c382011-01-21 10:59:30 +0000991 tlan_tx_timeout(priv->dev);
David Howellsc4028952006-11-22 14:57:56 +0000992}
993
994
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995
Sakari Ailusc659c382011-01-21 10:59:30 +0000996/***************************************************************
997 * tlan_start_tx
998 *
999 * Returns:
1000 * 0 on success, non-zero on failure.
1001 * Parms:
1002 * skb A pointer to the sk_buff containing the
1003 * frame to be sent.
1004 * dev The device to send the data on.
1005 *
1006 * This function adds a frame to the Tx list to be sent
1007 * ASAP. First it verifies that the adapter is ready and
1008 * there is room in the queue. Then it sets up the next
1009 * available list, copies the frame to the corresponding
1010 * buffer. If the adapter Tx channel is idle, it gives
1011 * the adapter a Tx Go command on the list, otherwise it
1012 * sets the forward address of the previous list to point
1013 * to this one. Then it frees the sk_buff.
1014 *
1015 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016
Sakari Ailusc659c382011-01-21 10:59:30 +00001017static netdev_tx_t tlan_start_tx(struct sk_buff *skb, struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018{
Sakari Ailusc659c382011-01-21 10:59:30 +00001019 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 dma_addr_t tail_list_phys;
Sakari Ailusc659c382011-01-21 10:59:30 +00001021 struct tlan_list *tail_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 unsigned long flags;
Sakari Ailus8953f122008-12-16 01:44:05 -08001023 unsigned int txlen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024
Sakari Ailusc659c382011-01-21 10:59:30 +00001025 if (!priv->phy_online) {
1026 TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n",
1027 dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 dev_kfree_skb_any(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001029 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 }
1031
Stephen Hemminger41873e92008-05-30 09:49:52 -07001032 if (skb_padto(skb, TLAN_MIN_FRAME_SIZE))
Patrick McHardy6ed10652009-06-23 06:03:08 +00001033 return NETDEV_TX_OK;
Sakari Ailus8953f122008-12-16 01:44:05 -08001034 txlen = max(skb->len, (unsigned int)TLAN_MIN_FRAME_SIZE);
Stephen Hemminger41873e92008-05-30 09:49:52 -07001035
Sakari Ailusc659c382011-01-21 10:59:30 +00001036 tail_list = priv->tx_list + priv->tx_tail;
1037 tail_list_phys =
1038 priv->tx_list_dma + sizeof(struct tlan_list)*priv->tx_tail;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001039
Sakari Ailusc659c382011-01-21 10:59:30 +00001040 if (tail_list->c_stat != TLAN_CSTAT_UNUSED) {
1041 TLAN_DBG(TLAN_DEBUG_TX,
1042 "TRANSMIT: %s is busy (Head=%d Tail=%d)\n",
1043 dev->name, priv->tx_head, priv->tx_tail);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 netif_stop_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001045 priv->tx_busy_count++;
Patrick McHardy5b548142009-06-12 06:22:29 +00001046 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 }
1048
1049 tail_list->forward = 0;
1050
Sakari Ailusc659c382011-01-21 10:59:30 +00001051 tail_list->buffer[0].address = pci_map_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001052 skb->data, txlen,
1053 PCI_DMA_TODEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001054 tlan_store_skb(tail_list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055
Sakari Ailusc659c382011-01-21 10:59:30 +00001056 tail_list->frame_size = (u16) txlen;
Sakari Ailus8953f122008-12-16 01:44:05 -08001057 tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) txlen;
Stephen Hemminger41873e92008-05-30 09:49:52 -07001058 tail_list->buffer[1].count = 0;
1059 tail_list->buffer[1].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
1061 spin_lock_irqsave(&priv->lock, flags);
Sakari Ailusc659c382011-01-21 10:59:30 +00001062 tail_list->c_stat = TLAN_CSTAT_READY;
1063 if (!priv->tx_in_progress) {
1064 priv->tx_in_progress = 1;
1065 TLAN_DBG(TLAN_DEBUG_TX,
1066 "TRANSMIT: Starting TX on buffer %d\n",
1067 priv->tx_tail);
1068 outl(tail_list_phys, dev->base_addr + TLAN_CH_PARM);
1069 outl(TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001071 TLAN_DBG(TLAN_DEBUG_TX,
1072 "TRANSMIT: Adding buffer %d to TX channel\n",
1073 priv->tx_tail);
1074 if (priv->tx_tail == 0) {
1075 (priv->tx_list + (TLAN_NUM_TX_LISTS - 1))->forward
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001076 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001078 (priv->tx_list + (priv->tx_tail - 1))->forward
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001079 = tail_list_phys;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 }
1081 }
1082 spin_unlock_irqrestore(&priv->lock, flags);
1083
Sakari Ailusc659c382011-01-21 10:59:30 +00001084 CIRC_INC(priv->tx_tail, TLAN_NUM_TX_LISTS);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
Patrick McHardy6ed10652009-06-23 06:03:08 +00001086 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001087
Sakari Ailusc659c382011-01-21 10:59:30 +00001088}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
1090
1091
1092
Sakari Ailusc659c382011-01-21 10:59:30 +00001093/***************************************************************
1094 * tlan_handle_interrupt
1095 *
1096 * Returns:
1097 * Nothing
1098 * Parms:
1099 * irq The line on which the interrupt
1100 * occurred.
1101 * dev_id A pointer to the device assigned to
1102 * this irq line.
1103 *
1104 * This function handles an interrupt generated by its
1105 * assigned TLAN adapter. The function deactivates
1106 * interrupts on its adapter, records the type of
1107 * interrupt, executes the appropriate subhandler, and
1108 * acknowdges the interrupt to the adapter (thus
1109 * re-enabling adapter interrupts.
1110 *
1111 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112
Sakari Ailusc659c382011-01-21 10:59:30 +00001113static irqreturn_t tlan_handle_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114{
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001115 struct net_device *dev = dev_id;
Sakari Ailusc659c382011-01-21 10:59:30 +00001116 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117 u16 host_int;
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001118 u16 type;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
1120 spin_lock(&priv->lock);
1121
Sakari Ailusc659c382011-01-21 10:59:30 +00001122 host_int = inw(dev->base_addr + TLAN_HOST_INT);
1123 type = (host_int & TLAN_HI_IT_MASK) >> 2;
1124 if (type) {
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001125 u32 ack;
1126 u32 host_cmd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127
Sakari Ailusc659c382011-01-21 10:59:30 +00001128 outw(host_int, dev->base_addr + TLAN_HOST_INT);
1129 ack = tlan_int_vector[type](dev, host_int);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001130
Sakari Ailusc659c382011-01-21 10:59:30 +00001131 if (ack) {
1132 host_cmd = TLAN_HC_ACK | ack | (type << 18);
1133 outl(host_cmd, dev->base_addr + TLAN_HOST_CMD);
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001134 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 }
1136
1137 spin_unlock(&priv->lock);
1138
Stephen Hemmingera3ccc782008-05-30 09:49:57 -07001139 return IRQ_RETVAL(type);
Sakari Ailusc659c382011-01-21 10:59:30 +00001140}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141
1142
1143
1144
Sakari Ailusc659c382011-01-21 10:59:30 +00001145/***************************************************************
1146 * tlan_close
1147 *
1148 * Returns:
1149 * An error code.
1150 * Parms:
1151 * dev The device structure of the device to
1152 * close.
1153 *
1154 * This function shuts down the adapter. It records any
1155 * stats, puts the adapter into reset state, deactivates
1156 * its time as needed, and frees the irq it is using.
1157 *
1158 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159
Sakari Ailusc659c382011-01-21 10:59:30 +00001160static int tlan_close(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161{
Sakari Ailusc659c382011-01-21 10:59:30 +00001162 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001163
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 priv->neg_be_verbose = 0;
Sakari Ailusfa6d5d42011-01-21 10:59:31 +00001165 tlan_stop(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001166
Sakari Ailusc659c382011-01-21 10:59:30 +00001167 free_irq(dev->irq, dev);
1168 tlan_free_lists(dev);
1169 TLAN_DBG(TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170
1171 return 0;
1172
Sakari Ailusc659c382011-01-21 10:59:30 +00001173}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174
1175
1176
1177
Sakari Ailusc659c382011-01-21 10:59:30 +00001178/***************************************************************
1179 * tlan_get_stats
1180 *
1181 * Returns:
1182 * A pointer to the device's statistics structure.
1183 * Parms:
1184 * dev The device structure to return the
1185 * stats for.
1186 *
1187 * This function updates the devices statistics by reading
1188 * the TLAN chip's onboard registers. Then it returns the
1189 * address of the statistics structure.
1190 *
1191 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192
Sakari Ailusc659c382011-01-21 10:59:30 +00001193static struct net_device_stats *tlan_get_stats(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194{
Sakari Ailusc659c382011-01-21 10:59:30 +00001195 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 int i;
1197
1198 /* Should only read stats if open ? */
Sakari Ailusc659c382011-01-21 10:59:30 +00001199 tlan_read_and_clear_stats(dev, TLAN_RECORD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
Sakari Ailusc659c382011-01-21 10:59:30 +00001201 TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name,
1202 priv->rx_eoc_count);
1203 TLAN_DBG(TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name,
1204 priv->tx_busy_count);
1205 if (debug & TLAN_DEBUG_GNRL) {
1206 tlan_print_dio(dev->base_addr);
1207 tlan_phy_print(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001209 if (debug & TLAN_DEBUG_LIST) {
1210 for (i = 0; i < TLAN_NUM_RX_LISTS; i++)
1211 tlan_print_list(priv->rx_list + i, "RX", i);
1212 for (i = 0; i < TLAN_NUM_TX_LISTS; i++)
1213 tlan_print_list(priv->tx_list + i, "TX", i);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001215
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07001216 return &dev->stats;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217
Sakari Ailusc659c382011-01-21 10:59:30 +00001218}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219
1220
1221
1222
Sakari Ailusc659c382011-01-21 10:59:30 +00001223/***************************************************************
1224 * tlan_set_multicast_list
1225 *
1226 * Returns:
1227 * Nothing
1228 * Parms:
1229 * dev The device structure to set the
1230 * multicast list for.
1231 *
1232 * This function sets the TLAN adaptor to various receive
1233 * modes. If the IFF_PROMISC flag is set, promiscuous
1234 * mode is acitviated. Otherwise, promiscuous mode is
1235 * turned off. If the IFF_ALLMULTI flag is set, then
1236 * the hash table is set to receive all group addresses.
1237 * Otherwise, the first three multicast addresses are
1238 * stored in AREG_1-3, and the rest are selected via the
1239 * hash table, as necessary.
1240 *
1241 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
Sakari Ailusc659c382011-01-21 10:59:30 +00001243static void tlan_set_multicast_list(struct net_device *dev)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001244{
Jiri Pirko22bedad32010-04-01 21:22:57 +00001245 struct netdev_hw_addr *ha;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246 u32 hash1 = 0;
1247 u32 hash2 = 0;
1248 int i;
1249 u32 offset;
1250 u8 tmp;
1251
Sakari Ailusc659c382011-01-21 10:59:30 +00001252 if (dev->flags & IFF_PROMISC) {
1253 tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
1254 tlan_dio_write8(dev->base_addr,
1255 TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001257 tmp = tlan_dio_read8(dev->base_addr, TLAN_NET_CMD);
1258 tlan_dio_write8(dev->base_addr,
1259 TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF);
1260 if (dev->flags & IFF_ALLMULTI) {
1261 for (i = 0; i < 3; i++)
1262 tlan_set_mac(dev, i + 1, NULL);
1263 tlan_dio_write32(dev->base_addr, TLAN_HASH_1,
1264 0xffffffff);
1265 tlan_dio_write32(dev->base_addr, TLAN_HASH_2,
1266 0xffffffff);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 } else {
Jiri Pirko567ec872010-02-23 23:17:07 +00001268 i = 0;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001269 netdev_for_each_mc_addr(ha, dev) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001270 if (i < 3) {
1271 tlan_set_mac(dev, i + 1,
Jiri Pirko22bedad32010-04-01 21:22:57 +00001272 (char *) &ha->addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001274 offset =
1275 tlan_hash_func((u8 *)&ha->addr);
1276 if (offset < 32)
1277 hash1 |= (1 << offset);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278 else
Sakari Ailusc659c382011-01-21 10:59:30 +00001279 hash2 |= (1 << (offset - 32));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 }
Jiri Pirko567ec872010-02-23 23:17:07 +00001281 i++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001283 for ( ; i < 3; i++)
1284 tlan_set_mac(dev, i + 1, NULL);
1285 tlan_dio_write32(dev->base_addr, TLAN_HASH_1, hash1);
1286 tlan_dio_write32(dev->base_addr, TLAN_HASH_2, hash2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001287 }
1288 }
1289
Sakari Ailusc659c382011-01-21 10:59:30 +00001290}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291
1292
1293
1294/*****************************************************************************
1295******************************************************************************
1296
Sakari Ailusc659c382011-01-21 10:59:30 +00001297ThunderLAN driver interrupt vectors and table
Linus Torvalds1da177e2005-04-16 15:20:36 -07001298
Sakari Ailusc659c382011-01-21 10:59:30 +00001299please see chap. 4, "Interrupt Handling" of the "ThunderLAN
1300Programmer's Guide" for more informations on handling interrupts
1301generated by TLAN based adapters.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302
1303******************************************************************************
1304*****************************************************************************/
1305
1306
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307
1308
Sakari Ailusc659c382011-01-21 10:59:30 +00001309/***************************************************************
1310 * tlan_handle_tx_eof
1311 *
1312 * Returns:
1313 * 1
1314 * Parms:
1315 * dev Device assigned the IRQ that was
1316 * raised.
1317 * host_int The contents of the HOST_INT
1318 * port.
1319 *
1320 * This function handles Tx EOF interrupts which are raised
1321 * by the adapter when it has completed sending the
1322 * contents of a buffer. If detemines which list/buffer
1323 * was completed and resets it. If the buffer was the last
1324 * in the channel (EOC), then the function checks to see if
1325 * another buffer is ready to send, and if so, sends a Tx
1326 * Go command. Finally, the driver activates/continues the
1327 * activity LED.
1328 *
1329 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330
Sakari Ailusc659c382011-01-21 10:59:30 +00001331static u32 tlan_handle_tx_eof(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332{
Sakari Ailusc659c382011-01-21 10:59:30 +00001333 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 int eoc = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001335 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 dma_addr_t head_list_phys;
1337 u32 ack = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001338 u16 tmp_c_stat;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001339
Sakari Ailusc659c382011-01-21 10:59:30 +00001340 TLAN_DBG(TLAN_DEBUG_TX,
1341 "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n",
1342 priv->tx_head, priv->tx_tail);
1343 head_list = priv->tx_list + priv->tx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344
Sakari Ailusc659c382011-01-21 10:59:30 +00001345 while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
1346 && (ack < 255)) {
1347 struct sk_buff *skb = tlan_get_skb(head_list);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001348
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 ack++;
Sakari Ailusc659c382011-01-21 10:59:30 +00001350 pci_unmap_single(priv->pci_dev, head_list->buffer[0].address,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001351 max(skb->len,
1352 (unsigned int)TLAN_MIN_FRAME_SIZE),
1353 PCI_DMA_TODEVICE);
1354 dev_kfree_skb_any(skb);
1355 head_list->buffer[8].address = 0;
1356 head_list->buffer[9].address = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001357
Sakari Ailusc659c382011-01-21 10:59:30 +00001358 if (tmp_c_stat & TLAN_CSTAT_EOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001360
Sakari Ailusc659c382011-01-21 10:59:30 +00001361 dev->stats.tx_bytes += head_list->frame_size;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362
Sakari Ailusc659c382011-01-21 10:59:30 +00001363 head_list->c_stat = TLAN_CSTAT_UNUSED;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001364 netif_start_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001365 CIRC_INC(priv->tx_head, TLAN_NUM_TX_LISTS);
1366 head_list = priv->tx_list + priv->tx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367 }
1368
1369 if (!ack)
Sakari Ailusc659c382011-01-21 10:59:30 +00001370 printk(KERN_INFO
1371 "TLAN: Received interrupt for uncompleted TX frame.\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001372
Sakari Ailusc659c382011-01-21 10:59:30 +00001373 if (eoc) {
1374 TLAN_DBG(TLAN_DEBUG_TX,
1375 "TRANSMIT: handling TX EOC (Head=%d Tail=%d)\n",
1376 priv->tx_head, priv->tx_tail);
1377 head_list = priv->tx_list + priv->tx_head;
1378 head_list_phys = priv->tx_list_dma
1379 + sizeof(struct tlan_list)*priv->tx_head;
Sakari Ailusf45437e2011-02-09 10:25:06 +00001380 if ((head_list->c_stat & TLAN_CSTAT_READY)
1381 == TLAN_CSTAT_READY) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001382 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 ack |= TLAN_HC_GO;
1384 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001385 priv->tx_in_progress = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 }
1387 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001388
Sakari Ailusc659c382011-01-21 10:59:30 +00001389 if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
1390 tlan_dio_write8(dev->base_addr,
1391 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
1392 if (priv->timer.function == NULL) {
1393 priv->timer.function = tlan_timer;
1394 priv->timer.data = (unsigned long) dev;
1395 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
1396 priv->timer_set_at = jiffies;
1397 priv->timer_type = TLAN_TIMER_ACTIVITY;
1398 add_timer(&priv->timer);
1399 } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
1400 priv->timer_set_at = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 }
1402 }
1403
1404 return ack;
1405
Sakari Ailusc659c382011-01-21 10:59:30 +00001406}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
1408
1409
1410
Sakari Ailusc659c382011-01-21 10:59:30 +00001411/***************************************************************
1412 * TLan_HandleStatOverflow
1413 *
1414 * Returns:
1415 * 1
1416 * Parms:
1417 * dev Device assigned the IRQ that was
1418 * raised.
1419 * host_int The contents of the HOST_INT
1420 * port.
1421 *
1422 * This function handles the Statistics Overflow interrupt
1423 * which means that one or more of the TLAN statistics
1424 * registers has reached 1/2 capacity and needs to be read.
1425 *
1426 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427
Sakari Ailusc659c382011-01-21 10:59:30 +00001428static u32 tlan_handle_stat_overflow(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429{
Sakari Ailusc659c382011-01-21 10:59:30 +00001430 tlan_read_and_clear_stats(dev, TLAN_RECORD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431
1432 return 1;
1433
Sakari Ailusc659c382011-01-21 10:59:30 +00001434}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435
1436
1437
1438
Sakari Ailusc659c382011-01-21 10:59:30 +00001439/***************************************************************
1440 * TLan_HandleRxEOF
1441 *
1442 * Returns:
1443 * 1
1444 * Parms:
1445 * dev Device assigned the IRQ that was
1446 * raised.
1447 * host_int The contents of the HOST_INT
1448 * port.
1449 *
1450 * This function handles the Rx EOF interrupt which
1451 * indicates a frame has been received by the adapter from
1452 * the net and the frame has been transferred to memory.
1453 * The function determines the bounce buffer the frame has
1454 * been loaded into, creates a new sk_buff big enough to
1455 * hold the frame, and sends it to protocol stack. It
1456 * then resets the used buffer and appends it to the end
1457 * of the list. If the frame was the last in the Rx
1458 * channel (EOC), the function restarts the receive channel
1459 * by sending an Rx Go command to the adapter. Then it
1460 * activates/continues the activity LED.
1461 *
1462 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463
Sakari Ailusc659c382011-01-21 10:59:30 +00001464static u32 tlan_handle_rx_eof(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465{
Sakari Ailusc659c382011-01-21 10:59:30 +00001466 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 u32 ack = 0;
1468 int eoc = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001469 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 struct sk_buff *skb;
Sakari Ailusc659c382011-01-21 10:59:30 +00001471 struct tlan_list *tail_list;
1472 u16 tmp_c_stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 dma_addr_t head_list_phys;
1474
Sakari Ailusc659c382011-01-21 10:59:30 +00001475 TLAN_DBG(TLAN_DEBUG_RX, "RECEIVE: handling RX EOF (Head=%d Tail=%d)\n",
1476 priv->rx_head, priv->rx_tail);
1477 head_list = priv->rx_list + priv->rx_head;
1478 head_list_phys =
1479 priv->rx_list_dma + sizeof(struct tlan_list)*priv->rx_head;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001480
Sakari Ailusc659c382011-01-21 10:59:30 +00001481 while (((tmp_c_stat = head_list->c_stat) & TLAN_CSTAT_FRM_CMP)
1482 && (ack < 255)) {
1483 dma_addr_t frame_dma = head_list->buffer[0].address;
1484 u32 frame_size = head_list->frame_size;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001485 struct sk_buff *new_skb;
1486
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 ack++;
Sakari Ailusc659c382011-01-21 10:59:30 +00001488 if (tmp_c_stat & TLAN_CSTAT_EOC)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 eoc = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001490
Eric Dumazet89d71a62009-10-13 05:34:20 +00001491 new_skb = netdev_alloc_skb_ip_align(dev,
1492 TLAN_MAX_FRAME_SIZE + 5);
Sakari Ailusc659c382011-01-21 10:59:30 +00001493 if (!new_skb)
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001494 goto drop_and_reuse;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001495
Sakari Ailusc659c382011-01-21 10:59:30 +00001496 skb = tlan_get_skb(head_list);
1497 pci_unmap_single(priv->pci_dev, frame_dma,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001498 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001499 skb_put(skb, frame_size);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001500
Sakari Ailusc659c382011-01-21 10:59:30 +00001501 dev->stats.rx_bytes += frame_size;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001502
Sakari Ailusc659c382011-01-21 10:59:30 +00001503 skb->protocol = eth_type_trans(skb, dev);
1504 netif_rx(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505
Sakari Ailusc659c382011-01-21 10:59:30 +00001506 head_list->buffer[0].address =
1507 pci_map_single(priv->pci_dev, new_skb->data,
1508 TLAN_MAX_FRAME_SIZE, PCI_DMA_FROMDEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509
Sakari Ailusc659c382011-01-21 10:59:30 +00001510 tlan_store_skb(head_list, new_skb);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07001511drop_and_reuse:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 head_list->forward = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001513 head_list->c_stat = 0;
1514 tail_list = priv->rx_list + priv->rx_tail;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 tail_list->forward = head_list_phys;
1516
Sakari Ailusc659c382011-01-21 10:59:30 +00001517 CIRC_INC(priv->rx_head, TLAN_NUM_RX_LISTS);
1518 CIRC_INC(priv->rx_tail, TLAN_NUM_RX_LISTS);
1519 head_list = priv->rx_list + priv->rx_head;
1520 head_list_phys = priv->rx_list_dma
1521 + sizeof(struct tlan_list)*priv->rx_head;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 }
1523
1524 if (!ack)
Sakari Ailusc659c382011-01-21 10:59:30 +00001525 printk(KERN_INFO
1526 "TLAN: Received interrupt for uncompleted RX frame.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527
1528
Sakari Ailusc659c382011-01-21 10:59:30 +00001529 if (eoc) {
1530 TLAN_DBG(TLAN_DEBUG_RX,
1531 "RECEIVE: handling RX EOC (Head=%d Tail=%d)\n",
1532 priv->rx_head, priv->rx_tail);
1533 head_list = priv->rx_list + priv->rx_head;
1534 head_list_phys = priv->rx_list_dma
1535 + sizeof(struct tlan_list)*priv->rx_head;
1536 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 ack |= TLAN_HC_GO | TLAN_HC_RT;
Sakari Ailusc659c382011-01-21 10:59:30 +00001538 priv->rx_eoc_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 }
1540
Sakari Ailusc659c382011-01-21 10:59:30 +00001541 if (priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED) {
1542 tlan_dio_write8(dev->base_addr,
1543 TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT);
1544 if (priv->timer.function == NULL) {
1545 priv->timer.function = tlan_timer;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 priv->timer.data = (unsigned long) dev;
1547 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
Sakari Ailusc659c382011-01-21 10:59:30 +00001548 priv->timer_set_at = jiffies;
1549 priv->timer_type = TLAN_TIMER_ACTIVITY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001550 add_timer(&priv->timer);
Sakari Ailusc659c382011-01-21 10:59:30 +00001551 } else if (priv->timer_type == TLAN_TIMER_ACTIVITY) {
1552 priv->timer_set_at = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 }
1554 }
1555
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 return ack;
1557
Sakari Ailusc659c382011-01-21 10:59:30 +00001558}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
1560
1561
1562
Sakari Ailusc659c382011-01-21 10:59:30 +00001563/***************************************************************
1564 * tlan_handle_dummy
1565 *
1566 * Returns:
1567 * 1
1568 * Parms:
1569 * dev Device assigned the IRQ that was
1570 * raised.
1571 * host_int The contents of the HOST_INT
1572 * port.
1573 *
1574 * This function handles the Dummy interrupt, which is
1575 * raised whenever a test interrupt is generated by setting
1576 * the Req_Int bit of HOST_CMD to 1.
1577 *
1578 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579
Sakari Ailusc659c382011-01-21 10:59:30 +00001580static u32 tlan_handle_dummy(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581{
Sakari Ailusc659c382011-01-21 10:59:30 +00001582 pr_info("TLAN: Test interrupt on %s.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583 return 1;
1584
Sakari Ailusc659c382011-01-21 10:59:30 +00001585}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586
1587
1588
1589
Sakari Ailusc659c382011-01-21 10:59:30 +00001590/***************************************************************
1591 * tlan_handle_tx_eoc
1592 *
1593 * Returns:
1594 * 1
1595 * Parms:
1596 * dev Device assigned the IRQ that was
1597 * raised.
1598 * host_int The contents of the HOST_INT
1599 * port.
1600 *
1601 * This driver is structured to determine EOC occurrences by
1602 * reading the CSTAT member of the list structure. Tx EOC
1603 * interrupts are disabled via the DIO INTDIS register.
1604 * However, TLAN chips before revision 3.0 didn't have this
1605 * functionality, so process EOC events if this is the
1606 * case.
1607 *
1608 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609
Sakari Ailusc659c382011-01-21 10:59:30 +00001610static u32 tlan_handle_tx_eoc(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611{
Sakari Ailusc659c382011-01-21 10:59:30 +00001612 struct tlan_priv *priv = netdev_priv(dev);
1613 struct tlan_list *head_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 dma_addr_t head_list_phys;
1615 u32 ack = 1;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001616
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 host_int = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001618 if (priv->tlan_rev < 0x30) {
1619 TLAN_DBG(TLAN_DEBUG_TX,
1620 "TRANSMIT: handling TX EOC (Head=%d Tail=%d) -- IRQ\n",
1621 priv->tx_head, priv->tx_tail);
1622 head_list = priv->tx_list + priv->tx_head;
1623 head_list_phys = priv->tx_list_dma
1624 + sizeof(struct tlan_list)*priv->tx_head;
Sakari Ailusf45437e2011-02-09 10:25:06 +00001625 if ((head_list->c_stat & TLAN_CSTAT_READY)
1626 == TLAN_CSTAT_READY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 netif_stop_queue(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00001628 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 ack |= TLAN_HC_GO;
1630 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001631 priv->tx_in_progress = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001632 }
1633 }
1634
1635 return ack;
1636
Sakari Ailusc659c382011-01-21 10:59:30 +00001637}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638
1639
1640
1641
Sakari Ailusc659c382011-01-21 10:59:30 +00001642/***************************************************************
1643 * tlan_handle_status_check
1644 *
1645 * Returns:
1646 * 0 if Adapter check, 1 if Network Status check.
1647 * Parms:
1648 * dev Device assigned the IRQ that was
1649 * raised.
1650 * host_int The contents of the HOST_INT
1651 * port.
1652 *
1653 * This function handles Adapter Check/Network Status
1654 * interrupts generated by the adapter. It checks the
1655 * vector in the HOST_INT register to determine if it is
1656 * an Adapter Check interrupt. If so, it resets the
1657 * adapter. Otherwise it clears the status registers
1658 * and services the PHY.
1659 *
1660 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661
Sakari Ailusc659c382011-01-21 10:59:30 +00001662static u32 tlan_handle_status_check(struct net_device *dev, u16 host_int)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001663{
Sakari Ailusc659c382011-01-21 10:59:30 +00001664 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 u32 ack;
1666 u32 error;
1667 u8 net_sts;
1668 u32 phy;
1669 u16 tlphy_ctl;
1670 u16 tlphy_sts;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001671
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 ack = 1;
Sakari Ailusc659c382011-01-21 10:59:30 +00001673 if (host_int & TLAN_HI_IV_MASK) {
1674 netif_stop_queue(dev);
1675 error = inl(dev->base_addr + TLAN_CH_PARM);
1676 pr_info("TLAN: %s: Adaptor Error = 0x%x\n", dev->name, error);
1677 tlan_read_and_clear_stats(dev, TLAN_RECORD);
1678 outl(TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679
1680 schedule_work(&priv->tlan_tqueue);
1681
1682 netif_wake_queue(dev);
1683 ack = 0;
1684 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00001685 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name);
1686 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
Sakari Ailusc659c382011-01-21 10:59:30 +00001688 net_sts = tlan_dio_read8(dev->base_addr, TLAN_NET_STS);
1689 if (net_sts) {
1690 tlan_dio_write8(dev->base_addr, TLAN_NET_STS, net_sts);
1691 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n",
1692 dev->name, (unsigned) net_sts);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001694 if ((net_sts & TLAN_NET_STS_MIRQ) && (priv->phy_num == 0)) {
1695 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_STS, &tlphy_sts);
1696 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
1697 if (!(tlphy_sts & TLAN_TS_POLOK) &&
1698 !(tlphy_ctl & TLAN_TC_SWAPOL)) {
1699 tlphy_ctl |= TLAN_TC_SWAPOL;
1700 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
1701 tlphy_ctl);
1702 } else if ((tlphy_sts & TLAN_TS_POLOK) &&
1703 (tlphy_ctl & TLAN_TC_SWAPOL)) {
1704 tlphy_ctl &= ~TLAN_TC_SWAPOL;
1705 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL,
1706 tlphy_ctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001708
1709 if (debug)
1710 tlan_phy_print(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 }
1712 }
1713
1714 return ack;
1715
Sakari Ailusc659c382011-01-21 10:59:30 +00001716}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717
1718
1719
1720
Sakari Ailusc659c382011-01-21 10:59:30 +00001721/***************************************************************
1722 * tlan_handle_rx_eoc
1723 *
1724 * Returns:
1725 * 1
1726 * Parms:
1727 * dev Device assigned the IRQ that was
1728 * raised.
1729 * host_int The contents of the HOST_INT
1730 * port.
1731 *
1732 * This driver is structured to determine EOC occurrences by
1733 * reading the CSTAT member of the list structure. Rx EOC
1734 * interrupts are disabled via the DIO INTDIS register.
1735 * However, TLAN chips before revision 3.0 didn't have this
1736 * CSTAT member or a INTDIS register, so if this chip is
1737 * pre-3.0, process EOC interrupts normally.
1738 *
1739 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740
Sakari Ailusc659c382011-01-21 10:59:30 +00001741static u32 tlan_handle_rx_eoc(struct net_device *dev, u16 host_int)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742{
Sakari Ailusc659c382011-01-21 10:59:30 +00001743 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 dma_addr_t head_list_phys;
1745 u32 ack = 1;
1746
Sakari Ailusc659c382011-01-21 10:59:30 +00001747 if (priv->tlan_rev < 0x30) {
1748 TLAN_DBG(TLAN_DEBUG_RX,
1749 "RECEIVE: Handling RX EOC (head=%d tail=%d) -- IRQ\n",
1750 priv->rx_head, priv->rx_tail);
1751 head_list_phys = priv->rx_list_dma
1752 + sizeof(struct tlan_list)*priv->rx_head;
1753 outl(head_list_phys, dev->base_addr + TLAN_CH_PARM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 ack |= TLAN_HC_GO | TLAN_HC_RT;
Sakari Ailusc659c382011-01-21 10:59:30 +00001755 priv->rx_eoc_count++;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 }
1757
1758 return ack;
1759
Sakari Ailusc659c382011-01-21 10:59:30 +00001760}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761
1762
1763
1764
1765/*****************************************************************************
1766******************************************************************************
1767
Sakari Ailusc659c382011-01-21 10:59:30 +00001768ThunderLAN driver timer function
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
1770******************************************************************************
1771*****************************************************************************/
1772
1773
Sakari Ailusc659c382011-01-21 10:59:30 +00001774/***************************************************************
1775 * tlan_timer
1776 *
1777 * Returns:
1778 * Nothing
1779 * Parms:
1780 * data A value given to add timer when
1781 * add_timer was called.
1782 *
1783 * This function handles timed functionality for the
1784 * TLAN driver. The two current timer uses are for
1785 * delaying for autonegotionation and driving the ACT LED.
1786 * - Autonegotiation requires being allowed about
1787 * 2 1/2 seconds before attempting to transmit a
1788 * packet. It would be a very bad thing to hang
1789 * the kernel this long, so the driver doesn't
1790 * allow transmission 'til after this time, for
1791 * certain PHYs. It would be much nicer if all
1792 * PHYs were interrupt-capable like the internal
1793 * PHY.
1794 * - The ACT LED, which shows adapter activity, is
1795 * driven by the driver, and so must be left on
1796 * for a short period to power up the LED so it
1797 * can be seen. This delay can be changed by
1798 * changing the TLAN_TIMER_ACT_DELAY in tlan.h,
1799 * if desired. 100 ms produces a slightly
1800 * sluggish response.
1801 *
1802 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803
Sakari Ailusc659c382011-01-21 10:59:30 +00001804static void tlan_timer(unsigned long data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805{
1806 struct net_device *dev = (struct net_device *) data;
Sakari Ailusc659c382011-01-21 10:59:30 +00001807 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 u32 elapsed;
1809 unsigned long flags = 0;
1810
1811 priv->timer.function = NULL;
1812
Sakari Ailusc659c382011-01-21 10:59:30 +00001813 switch (priv->timer_type) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001814#ifdef MONITOR
Sakari Ailusc659c382011-01-21 10:59:30 +00001815 case TLAN_TIMER_LINK_BEAT:
1816 tlan_phy_monitor(dev);
1817 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818#endif
Sakari Ailusc659c382011-01-21 10:59:30 +00001819 case TLAN_TIMER_PHY_PDOWN:
1820 tlan_phy_power_down(dev);
1821 break;
1822 case TLAN_TIMER_PHY_PUP:
1823 tlan_phy_power_up(dev);
1824 break;
1825 case TLAN_TIMER_PHY_RESET:
1826 tlan_phy_reset(dev);
1827 break;
1828 case TLAN_TIMER_PHY_START_LINK:
1829 tlan_phy_start_link(dev);
1830 break;
1831 case TLAN_TIMER_PHY_FINISH_AN:
1832 tlan_phy_finish_auto_neg(dev);
1833 break;
1834 case TLAN_TIMER_FINISH_RESET:
1835 tlan_finish_reset(dev);
1836 break;
1837 case TLAN_TIMER_ACTIVITY:
1838 spin_lock_irqsave(&priv->lock, flags);
1839 if (priv->timer.function == NULL) {
1840 elapsed = jiffies - priv->timer_set_at;
1841 if (elapsed >= TLAN_TIMER_ACT_DELAY) {
1842 tlan_dio_write8(dev->base_addr,
1843 TLAN_LED_REG, TLAN_LED_LINK);
1844 } else {
1845 priv->timer.function = tlan_timer;
1846 priv->timer.expires = priv->timer_set_at
1847 + TLAN_TIMER_ACT_DELAY;
1848 spin_unlock_irqrestore(&priv->lock, flags);
1849 add_timer(&priv->timer);
1850 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001852 }
1853 spin_unlock_irqrestore(&priv->lock, flags);
1854 break;
1855 default:
1856 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857 }
1858
Sakari Ailusc659c382011-01-21 10:59:30 +00001859}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860
1861
1862
1863
1864/*****************************************************************************
1865******************************************************************************
1866
Sakari Ailusc659c382011-01-21 10:59:30 +00001867ThunderLAN driver adapter related routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868
1869******************************************************************************
1870*****************************************************************************/
1871
1872
Sakari Ailusc659c382011-01-21 10:59:30 +00001873/***************************************************************
1874 * tlan_reset_lists
1875 *
1876 * Returns:
1877 * Nothing
1878 * Parms:
1879 * dev The device structure with the list
1880 * stuctures to be reset.
1881 *
1882 * This routine sets the variables associated with managing
1883 * the TLAN lists to their initial values.
1884 *
1885 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886
Sakari Ailusc659c382011-01-21 10:59:30 +00001887static void tlan_reset_lists(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888{
Sakari Ailusc659c382011-01-21 10:59:30 +00001889 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +00001891 struct tlan_list *list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 dma_addr_t list_phys;
1893 struct sk_buff *skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894
Sakari Ailusc659c382011-01-21 10:59:30 +00001895 priv->tx_head = 0;
1896 priv->tx_tail = 0;
1897 for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
1898 list = priv->tx_list + i;
1899 list->c_stat = TLAN_CSTAT_UNUSED;
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001900 list->buffer[0].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 list->buffer[2].count = 0;
1902 list->buffer[2].address = 0;
1903 list->buffer[8].address = 0;
1904 list->buffer[9].address = 0;
1905 }
1906
Sakari Ailusc659c382011-01-21 10:59:30 +00001907 priv->rx_head = 0;
1908 priv->rx_tail = TLAN_NUM_RX_LISTS - 1;
1909 for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
1910 list = priv->rx_list + i;
1911 list_phys = priv->rx_list_dma + sizeof(struct tlan_list)*i;
1912 list->c_stat = TLAN_CSTAT_READY;
1913 list->frame_size = TLAN_MAX_FRAME_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
Eric Dumazet89d71a62009-10-13 05:34:20 +00001915 skb = netdev_alloc_skb_ip_align(dev, TLAN_MAX_FRAME_SIZE + 5);
Sakari Ailusc659c382011-01-21 10:59:30 +00001916 if (!skb) {
1917 pr_err("TLAN: out of memory for received data.\n");
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001918 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001919 }
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001920
Sakari Ailusc659c382011-01-21 10:59:30 +00001921 list->buffer[0].address = pci_map_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001922 skb->data,
1923 TLAN_MAX_FRAME_SIZE,
1924 PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001925 tlan_store_skb(list, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001926 list->buffer[1].count = 0;
1927 list->buffer[1].address = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00001928 list->forward = list_phys + sizeof(struct tlan_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 }
1930
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001931 /* in case ran out of memory early, clear bits */
1932 while (i < TLAN_NUM_RX_LISTS) {
Sakari Ailusc659c382011-01-21 10:59:30 +00001933 tlan_store_skb(priv->rx_list + i, NULL);
Stephen Hemminger9ded65a2008-05-30 09:49:56 -07001934 ++i;
1935 }
1936 list->forward = 0;
1937
Sakari Ailusc659c382011-01-21 10:59:30 +00001938}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939
1940
Sakari Ailusc659c382011-01-21 10:59:30 +00001941static void tlan_free_lists(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942{
Sakari Ailusc659c382011-01-21 10:59:30 +00001943 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944 int i;
Sakari Ailusc659c382011-01-21 10:59:30 +00001945 struct tlan_list *list;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 struct sk_buff *skb;
1947
Sakari Ailusc659c382011-01-21 10:59:30 +00001948 for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
1949 list = priv->tx_list + i;
1950 skb = tlan_get_skb(list);
1951 if (skb) {
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001952 pci_unmap_single(
Sakari Ailusc659c382011-01-21 10:59:30 +00001953 priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001954 list->buffer[0].address,
1955 max(skb->len,
1956 (unsigned int)TLAN_MIN_FRAME_SIZE),
1957 PCI_DMA_TODEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001958 dev_kfree_skb_any(skb);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001959 list->buffer[8].address = 0;
1960 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 }
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001962 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963
Sakari Ailusc659c382011-01-21 10:59:30 +00001964 for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
1965 list = priv->rx_list + i;
1966 skb = tlan_get_skb(list);
1967 if (skb) {
1968 pci_unmap_single(priv->pci_dev,
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001969 list->buffer[0].address,
1970 TLAN_MAX_FRAME_SIZE,
1971 PCI_DMA_FROMDEVICE);
Sakari Ailusc659c382011-01-21 10:59:30 +00001972 dev_kfree_skb_any(skb);
Sakari Ailus5eeabf52008-12-16 15:24:05 -08001973 list->buffer[8].address = 0;
1974 list->buffer[9].address = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975 }
1976 }
Sakari Ailusc659c382011-01-21 10:59:30 +00001977}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001978
1979
1980
1981
Sakari Ailusc659c382011-01-21 10:59:30 +00001982/***************************************************************
1983 * tlan_print_dio
1984 *
1985 * Returns:
1986 * Nothing
1987 * Parms:
1988 * io_base Base IO port of the device of
1989 * which to print DIO registers.
1990 *
1991 * This function prints out all the internal (DIO)
1992 * registers of a TLAN chip.
1993 *
1994 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07001995
Sakari Ailusc659c382011-01-21 10:59:30 +00001996static void tlan_print_dio(u16 io_base)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997{
1998 u32 data0, data1;
1999 int i;
2000
Sakari Ailusc659c382011-01-21 10:59:30 +00002001 pr_info("TLAN: Contents of internal registers for io base 0x%04hx.\n",
2002 io_base);
2003 pr_info("TLAN: Off. +0 +4\n");
2004 for (i = 0; i < 0x4C; i += 8) {
2005 data0 = tlan_dio_read32(io_base, i);
2006 data1 = tlan_dio_read32(io_base, i + 0x4);
2007 pr_info("TLAN: 0x%02x 0x%08x 0x%08x\n", i, data0, data1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008 }
2009
Sakari Ailusc659c382011-01-21 10:59:30 +00002010}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011
2012
2013
2014
Sakari Ailusc659c382011-01-21 10:59:30 +00002015/***************************************************************
2016 * TLan_PrintList
2017 *
2018 * Returns:
2019 * Nothing
2020 * Parms:
2021 * list A pointer to the struct tlan_list structure to
2022 * be printed.
2023 * type A string to designate type of list,
2024 * "Rx" or "Tx".
2025 * num The index of the list.
2026 *
2027 * This function prints out the contents of the list
2028 * pointed to by the list parameter.
2029 *
2030 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031
Sakari Ailusc659c382011-01-21 10:59:30 +00002032static void tlan_print_list(struct tlan_list *list, char *type, int num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033{
2034 int i;
2035
Sakari Ailusc659c382011-01-21 10:59:30 +00002036 pr_info("TLAN: %s List %d at %p\n", type, num, list);
2037 pr_info("TLAN: Forward = 0x%08x\n", list->forward);
2038 pr_info("TLAN: CSTAT = 0x%04hx\n", list->c_stat);
2039 pr_info("TLAN: Frame Size = 0x%04hx\n", list->frame_size);
2040 /* for (i = 0; i < 10; i++) { */
2041 for (i = 0; i < 2; i++) {
2042 pr_info("TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n",
2043 i, list->buffer[i].count, list->buffer[i].address);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044 }
2045
Sakari Ailusc659c382011-01-21 10:59:30 +00002046}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047
2048
2049
2050
Sakari Ailusc659c382011-01-21 10:59:30 +00002051/***************************************************************
2052 * tlan_read_and_clear_stats
2053 *
2054 * Returns:
2055 * Nothing
2056 * Parms:
2057 * dev Pointer to device structure of adapter
2058 * to which to read stats.
2059 * record Flag indicating whether to add
2060 *
2061 * This functions reads all the internal status registers
2062 * of the TLAN chip, which clears them as a side effect.
2063 * It then either adds the values to the device's status
2064 * struct, or discards them, depending on whether record
2065 * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0).
2066 *
2067 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068
Sakari Ailusc659c382011-01-21 10:59:30 +00002069static void tlan_read_and_clear_stats(struct net_device *dev, int record)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002070{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 u32 tx_good, tx_under;
2072 u32 rx_good, rx_over;
2073 u32 def_tx, crc, code;
2074 u32 multi_col, single_col;
2075 u32 excess_col, late_col, loss;
2076
Sakari Ailusc659c382011-01-21 10:59:30 +00002077 outw(TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR);
2078 tx_good = inb(dev->base_addr + TLAN_DIO_DATA);
2079 tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2080 tx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
2081 tx_under = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082
Sakari Ailusc659c382011-01-21 10:59:30 +00002083 outw(TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR);
2084 rx_good = inb(dev->base_addr + TLAN_DIO_DATA);
2085 rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2086 rx_good += inb(dev->base_addr + TLAN_DIO_DATA + 2) << 16;
2087 rx_over = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002088
Sakari Ailusc659c382011-01-21 10:59:30 +00002089 outw(TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR);
2090 def_tx = inb(dev->base_addr + TLAN_DIO_DATA);
2091 def_tx += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2092 crc = inb(dev->base_addr + TLAN_DIO_DATA + 2);
2093 code = inb(dev->base_addr + TLAN_DIO_DATA + 3);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002094
Sakari Ailusc659c382011-01-21 10:59:30 +00002095 outw(TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
2096 multi_col = inb(dev->base_addr + TLAN_DIO_DATA);
2097 multi_col += inb(dev->base_addr + TLAN_DIO_DATA + 1) << 8;
2098 single_col = inb(dev->base_addr + TLAN_DIO_DATA + 2);
2099 single_col += inb(dev->base_addr + TLAN_DIO_DATA + 3) << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100
Sakari Ailusc659c382011-01-21 10:59:30 +00002101 outw(TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR);
2102 excess_col = inb(dev->base_addr + TLAN_DIO_DATA);
2103 late_col = inb(dev->base_addr + TLAN_DIO_DATA + 1);
2104 loss = inb(dev->base_addr + TLAN_DIO_DATA + 2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105
Sakari Ailusc659c382011-01-21 10:59:30 +00002106 if (record) {
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002107 dev->stats.rx_packets += rx_good;
2108 dev->stats.rx_errors += rx_over + crc + code;
2109 dev->stats.tx_packets += tx_good;
2110 dev->stats.tx_errors += tx_under + loss;
Sakari Ailusc659c382011-01-21 10:59:30 +00002111 dev->stats.collisions += multi_col
2112 + single_col + excess_col + late_col;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002114 dev->stats.rx_over_errors += rx_over;
2115 dev->stats.rx_crc_errors += crc;
2116 dev->stats.rx_frame_errors += code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117
Stephen Hemmingerf8f31542008-05-30 09:49:53 -07002118 dev->stats.tx_aborted_errors += tx_under;
2119 dev->stats.tx_carrier_errors += loss;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002121
Sakari Ailusc659c382011-01-21 10:59:30 +00002122}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123
2124
2125
2126
Sakari Ailusc659c382011-01-21 10:59:30 +00002127/***************************************************************
2128 * TLan_Reset
2129 *
2130 * Returns:
2131 * 0
2132 * Parms:
2133 * dev Pointer to device structure of adapter
2134 * to be reset.
2135 *
2136 * This function resets the adapter and it's physical
2137 * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
2138 * Programmer's Guide" for details. The routine tries to
2139 * implement what is detailed there, though adjustments
2140 * have been made.
2141 *
2142 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143
Harvey Harrison98e0f522008-02-18 10:04:38 -08002144static void
Sakari Ailusc659c382011-01-21 10:59:30 +00002145tlan_reset_adapter(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146{
Sakari Ailusc659c382011-01-21 10:59:30 +00002147 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 int i;
2149 u32 addr;
2150 u32 data;
2151 u8 data8;
2152
Sakari Ailusc659c382011-01-21 10:59:30 +00002153 priv->tlan_full_duplex = false;
2154 priv->phy_online = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 netif_carrier_off(dev);
2156
2157/* 1. Assert reset bit. */
2158
2159 data = inl(dev->base_addr + TLAN_HOST_CMD);
2160 data |= TLAN_HC_AD_RST;
2161 outl(data, dev->base_addr + TLAN_HOST_CMD);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002162
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163 udelay(1000);
2164
Sakari Ailusc659c382011-01-21 10:59:30 +00002165/* 2. Turn off interrupts. (Probably isn't necessary) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166
2167 data = inl(dev->base_addr + TLAN_HOST_CMD);
2168 data |= TLAN_HC_INT_OFF;
2169 outl(data, dev->base_addr + TLAN_HOST_CMD);
2170
2171/* 3. Clear AREGs and HASHs. */
2172
Sakari Ailusc659c382011-01-21 10:59:30 +00002173 for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4)
2174 tlan_dio_write32(dev->base_addr, (u16) i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175
2176/* 4. Setup NetConfig register. */
2177
2178 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
Sakari Ailusc659c382011-01-21 10:59:30 +00002179 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180
2181/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
2182
Sakari Ailusc659c382011-01-21 10:59:30 +00002183 outl(TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD);
2184 outl(TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002185
2186/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
2187
Sakari Ailusc659c382011-01-21 10:59:30 +00002188 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002189 addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Sakari Ailusc659c382011-01-21 10:59:30 +00002190 tlan_set_bit(TLAN_NET_SIO_NMRST, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191
2192/* 7. Setup the remaining registers. */
2193
Sakari Ailusc659c382011-01-21 10:59:30 +00002194 if (priv->tlan_rev >= 0x30) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195 data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
Sakari Ailusc659c382011-01-21 10:59:30 +00002196 tlan_dio_write8(dev->base_addr, TLAN_INT_DIS, data8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002198 tlan_phy_detect(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002200
Sakari Ailusc659c382011-01-21 10:59:30 +00002201 if (priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202 data |= TLAN_NET_CFG_BIT;
Sakari Ailusc659c382011-01-21 10:59:30 +00002203 if (priv->aui == 1) {
2204 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x0a);
2205 } else if (priv->duplex == TLAN_DUPLEX_FULL) {
2206 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x00);
2207 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002209 tlan_dio_write8(dev->base_addr, TLAN_ACOMMIT, 0x08);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210 }
2211 }
2212
Sakari Ailusc659c382011-01-21 10:59:30 +00002213 if (priv->phy_num == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214 data |= TLAN_NET_CFG_PHY_EN;
Sakari Ailusc659c382011-01-21 10:59:30 +00002215 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, (u16) data);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216
Sakari Ailusc659c382011-01-21 10:59:30 +00002217 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY)
2218 tlan_finish_reset(dev);
2219 else
2220 tlan_phy_power_down(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221
Sakari Ailusc659c382011-01-21 10:59:30 +00002222}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002223
2224
2225
2226
Harvey Harrison98e0f522008-02-18 10:04:38 -08002227static void
Sakari Ailusc659c382011-01-21 10:59:30 +00002228tlan_finish_reset(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229{
Sakari Ailusc659c382011-01-21 10:59:30 +00002230 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 u8 data;
2232 u32 phy;
2233 u8 sio;
2234 u16 status;
2235 u16 partner;
2236 u16 tlphy_ctl;
Sakari Ailusc659c382011-01-21 10:59:30 +00002237 u16 tlphy_par;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238 u16 tlphy_id1, tlphy_id2;
Sakari Ailusc659c382011-01-21 10:59:30 +00002239 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240
Sakari Ailusc659c382011-01-21 10:59:30 +00002241 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242
2243 data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
Sakari Ailusc659c382011-01-21 10:59:30 +00002244 if (priv->tlan_full_duplex)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 data |= TLAN_NET_CMD_DUPLEX;
Sakari Ailusc659c382011-01-21 10:59:30 +00002246 tlan_dio_write8(dev->base_addr, TLAN_NET_CMD, data);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002247 data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
Sakari Ailusc659c382011-01-21 10:59:30 +00002248 if (priv->phy_num == 0)
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002249 data |= TLAN_NET_MASK_MASK7;
Sakari Ailusc659c382011-01-21 10:59:30 +00002250 tlan_dio_write8(dev->base_addr, TLAN_NET_MASK, data);
2251 tlan_dio_write16(dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7);
2252 tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &tlphy_id1);
2253 tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &tlphy_id2);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002254
Sakari Ailusc659c382011-01-21 10:59:30 +00002255 if ((priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) ||
2256 (priv->aui)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 status = MII_GS_LINK;
Sakari Ailusc659c382011-01-21 10:59:30 +00002258 pr_info("TLAN: %s: Link forced.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002260 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2261 udelay(1000);
2262 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2263 if ((status & MII_GS_LINK) &&
2264 /* We only support link info on Nat.Sem. PHY's */
2265 (tlphy_id1 == NAT_SEM_ID1) &&
2266 (tlphy_id2 == NAT_SEM_ID2)) {
2267 tlan_mii_read_reg(dev, phy, MII_AN_LPA, &partner);
2268 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_PAR, &tlphy_par);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002269
Sakari Ailusc659c382011-01-21 10:59:30 +00002270 pr_info("TLAN: %s: Link active with ", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271 if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002272 pr_info("forced 10%sMbps %s-Duplex\n",
2273 tlphy_par & TLAN_PHY_SPEED_100
2274 ? "" : "0",
2275 tlphy_par & TLAN_PHY_DUPLEX_FULL
2276 ? "Full" : "Half");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002278 pr_info("Autonegotiation enabled, at 10%sMbps %s-Duplex\n",
2279 tlphy_par & TLAN_PHY_SPEED_100
2280 ? "" : "0",
2281 tlphy_par & TLAN_PHY_DUPLEX_FULL
2282 ? "Full" : "half");
2283 pr_info("TLAN: Partner capability: ");
2284 for (i = 5; i <= 10; i++)
2285 if (partner & (1<<i))
2286 printk("%s", media[i-5]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002287 printk("\n");
2288 }
2289
Sakari Ailusc659c382011-01-21 10:59:30 +00002290 tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
2291 TLAN_LED_LINK);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002292#ifdef MONITOR
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 /* We have link beat..for now anyway */
Sakari Ailusc659c382011-01-21 10:59:30 +00002294 priv->link = 1;
2295 /*Enabling link beat monitoring */
2296 tlan_set_timer(dev, (10*HZ), TLAN_TIMER_LINK_BEAT);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002297#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298 } else if (status & MII_GS_LINK) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002299 pr_info("TLAN: %s: Link active\n", dev->name);
2300 tlan_dio_write8(dev->base_addr, TLAN_LED_REG,
2301 TLAN_LED_LINK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302 }
2303 }
2304
Sakari Ailusc659c382011-01-21 10:59:30 +00002305 if (priv->phy_num == 0) {
2306 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
2307 tlphy_ctl |= TLAN_TC_INTEN;
2308 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
2309 sio = tlan_dio_read8(dev->base_addr, TLAN_NET_SIO);
2310 sio |= TLAN_NET_SIO_MINTEN;
2311 tlan_dio_write8(dev->base_addr, TLAN_NET_SIO, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312 }
2313
Sakari Ailusc659c382011-01-21 10:59:30 +00002314 if (status & MII_GS_LINK) {
2315 tlan_set_mac(dev, 0, dev->dev_addr);
2316 priv->phy_online = 1;
2317 outb((TLAN_HC_INT_ON >> 8), dev->base_addr + TLAN_HOST_CMD + 1);
2318 if (debug >= 1 && debug != TLAN_DEBUG_PROBE)
2319 outb((TLAN_HC_REQ_INT >> 8),
2320 dev->base_addr + TLAN_HOST_CMD + 1);
2321 outl(priv->rx_list_dma, dev->base_addr + TLAN_CH_PARM);
2322 outl(TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002323 netif_carrier_on(dev);
2324 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002325 pr_info("TLAN: %s: Link inactive, will retry in 10 secs...\n",
2326 dev->name);
2327 tlan_set_timer(dev, (10*HZ), TLAN_TIMER_FINISH_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328 return;
2329 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002330 tlan_set_multicast_list(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331
Sakari Ailusc659c382011-01-21 10:59:30 +00002332}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333
2334
2335
2336
Sakari Ailusc659c382011-01-21 10:59:30 +00002337/***************************************************************
2338 * tlan_set_mac
2339 *
2340 * Returns:
2341 * Nothing
2342 * Parms:
2343 * dev Pointer to device structure of adapter
2344 * on which to change the AREG.
2345 * areg The AREG to set the address in (0 - 3).
2346 * mac A pointer to an array of chars. Each
2347 * element stores one byte of the address.
2348 * IE, it isn't in ascii.
2349 *
2350 * This function transfers a MAC address to one of the
2351 * TLAN AREGs (address registers). The TLAN chip locks
2352 * the register on writing to offset 0 and unlocks the
2353 * register after writing to offset 5. If NULL is passed
2354 * in mac, then the AREG is filled with 0's.
2355 *
2356 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357
Sakari Ailusc659c382011-01-21 10:59:30 +00002358static void tlan_set_mac(struct net_device *dev, int areg, char *mac)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359{
2360 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002361
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362 areg *= 6;
2363
Sakari Ailusc659c382011-01-21 10:59:30 +00002364 if (mac != NULL) {
2365 for (i = 0; i < 6; i++)
2366 tlan_dio_write8(dev->base_addr,
2367 TLAN_AREG_0 + areg + i, mac[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002368 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002369 for (i = 0; i < 6; i++)
2370 tlan_dio_write8(dev->base_addr,
2371 TLAN_AREG_0 + areg + i, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372 }
2373
Sakari Ailusc659c382011-01-21 10:59:30 +00002374}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375
2376
2377
2378
2379/*****************************************************************************
2380******************************************************************************
2381
Sakari Ailusc659c382011-01-21 10:59:30 +00002382ThunderLAN driver PHY layer routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383
2384******************************************************************************
2385*****************************************************************************/
2386
2387
2388
Sakari Ailusc659c382011-01-21 10:59:30 +00002389/*********************************************************************
2390 * tlan_phy_print
2391 *
2392 * Returns:
2393 * Nothing
2394 * Parms:
2395 * dev A pointer to the device structure of the
2396 * TLAN device having the PHYs to be detailed.
2397 *
2398 * This function prints the registers a PHY (aka transceiver).
2399 *
2400 ********************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401
Sakari Ailusc659c382011-01-21 10:59:30 +00002402static void tlan_phy_print(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002403{
Sakari Ailusc659c382011-01-21 10:59:30 +00002404 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405 u16 i, data0, data1, data2, data3, phy;
2406
Sakari Ailusc659c382011-01-21 10:59:30 +00002407 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408
Sakari Ailusc659c382011-01-21 10:59:30 +00002409 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
2410 pr_info("TLAN: Device %s, Unmanaged PHY.\n", dev->name);
2411 } else if (phy <= TLAN_PHY_MAX_ADDR) {
2412 pr_info("TLAN: Device %s, PHY 0x%02x.\n", dev->name, phy);
2413 pr_info("TLAN: Off. +0 +1 +2 +3\n");
2414 for (i = 0; i < 0x20; i += 4) {
2415 pr_info("TLAN: 0x%02x", i);
2416 tlan_mii_read_reg(dev, phy, i, &data0);
2417 printk(" 0x%04hx", data0);
2418 tlan_mii_read_reg(dev, phy, i + 1, &data1);
2419 printk(" 0x%04hx", data1);
2420 tlan_mii_read_reg(dev, phy, i + 2, &data2);
2421 printk(" 0x%04hx", data2);
2422 tlan_mii_read_reg(dev, phy, i + 3, &data3);
2423 printk(" 0x%04hx\n", data3);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424 }
2425 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002426 pr_info("TLAN: Device %s, Invalid PHY.\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 }
2428
Sakari Ailusc659c382011-01-21 10:59:30 +00002429}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430
2431
2432
2433
Sakari Ailusc659c382011-01-21 10:59:30 +00002434/*********************************************************************
2435 * tlan_phy_detect
2436 *
2437 * Returns:
2438 * Nothing
2439 * Parms:
2440 * dev A pointer to the device structure of the adapter
2441 * for which the PHY needs determined.
2442 *
2443 * So far I've found that adapters which have external PHYs
2444 * may also use the internal PHY for part of the functionality.
2445 * (eg, AUI/Thinnet). This function finds out if this TLAN
2446 * chip has an internal PHY, and then finds the first external
2447 * PHY (starting from address 0) if it exists).
2448 *
2449 ********************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450
Sakari Ailusc659c382011-01-21 10:59:30 +00002451static void tlan_phy_detect(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452{
Sakari Ailusc659c382011-01-21 10:59:30 +00002453 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454 u16 control;
2455 u16 hi;
2456 u16 lo;
2457 u32 phy;
2458
Sakari Ailusc659c382011-01-21 10:59:30 +00002459 if (priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY) {
2460 priv->phy_num = 0xffff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002461 return;
2462 }
2463
Sakari Ailusc659c382011-01-21 10:59:30 +00002464 tlan_mii_read_reg(dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002465
Sakari Ailusc659c382011-01-21 10:59:30 +00002466 if (hi != 0xffff)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467 priv->phy[0] = TLAN_PHY_MAX_ADDR;
Sakari Ailusc659c382011-01-21 10:59:30 +00002468 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002469 priv->phy[0] = TLAN_PHY_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002470
2471 priv->phy[1] = TLAN_PHY_NONE;
Sakari Ailusc659c382011-01-21 10:59:30 +00002472 for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) {
2473 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &control);
2474 tlan_mii_read_reg(dev, phy, MII_GEN_ID_HI, &hi);
2475 tlan_mii_read_reg(dev, phy, MII_GEN_ID_LO, &lo);
2476 if ((control != 0xffff) ||
2477 (hi != 0xffff) || (lo != 0xffff)) {
2478 TLAN_DBG(TLAN_DEBUG_GNRL,
2479 "PHY found at %02x %04x %04x %04x\n",
2480 phy, control, hi, lo);
2481 if ((priv->phy[1] == TLAN_PHY_NONE) &&
2482 (phy != TLAN_PHY_MAX_ADDR)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483 priv->phy[1] = phy;
2484 }
2485 }
2486 }
2487
Sakari Ailusc659c382011-01-21 10:59:30 +00002488 if (priv->phy[1] != TLAN_PHY_NONE)
2489 priv->phy_num = 1;
2490 else if (priv->phy[0] != TLAN_PHY_NONE)
2491 priv->phy_num = 0;
2492 else
2493 pr_info("TLAN: Cannot initialize device, no PHY was found!\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494
Sakari Ailusc659c382011-01-21 10:59:30 +00002495}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496
2497
2498
2499
Sakari Ailusc659c382011-01-21 10:59:30 +00002500static void tlan_phy_power_down(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501{
Sakari Ailusc659c382011-01-21 10:59:30 +00002502 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503 u16 value;
2504
Sakari Ailusc659c382011-01-21 10:59:30 +00002505 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506 value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
Sakari Ailusc659c382011-01-21 10:59:30 +00002507 tlan_mii_sync(dev->base_addr);
2508 tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
2509 if ((priv->phy_num == 0) &&
2510 (priv->phy[1] != TLAN_PHY_NONE) &&
2511 (!(priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10))) {
2512 tlan_mii_sync(dev->base_addr);
2513 tlan_mii_write_reg(dev, priv->phy[1], MII_GEN_CTL, value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514 }
2515
2516 /* Wait for 50 ms and powerup
2517 * This is abitrary. It is intended to make sure the
2518 * transceiver settles.
2519 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002520 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_PUP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002521
Sakari Ailusc659c382011-01-21 10:59:30 +00002522}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002523
2524
2525
2526
Sakari Ailusc659c382011-01-21 10:59:30 +00002527static void tlan_phy_power_up(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002528{
Sakari Ailusc659c382011-01-21 10:59:30 +00002529 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 u16 value;
2531
Sakari Ailusc659c382011-01-21 10:59:30 +00002532 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name);
2533 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534 value = MII_GC_LOOPBK;
Sakari Ailusc659c382011-01-21 10:59:30 +00002535 tlan_mii_write_reg(dev, priv->phy[priv->phy_num], MII_GEN_CTL, value);
2536 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537 /* Wait for 500 ms and reset the
2538 * transceiver. The TLAN docs say both 50 ms and
2539 * 500 ms, so do the longer, just in case.
2540 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002541 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002542
Sakari Ailusc659c382011-01-21 10:59:30 +00002543}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544
2545
2546
2547
Sakari Ailusc659c382011-01-21 10:59:30 +00002548static void tlan_phy_reset(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549{
Sakari Ailusc659c382011-01-21 10:59:30 +00002550 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 u16 phy;
2552 u16 value;
2553
Sakari Ailusc659c382011-01-21 10:59:30 +00002554 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555
Sakari Ailusc659c382011-01-21 10:59:30 +00002556 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name);
2557 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558 value = MII_GC_LOOPBK | MII_GC_RESET;
Sakari Ailusc659c382011-01-21 10:59:30 +00002559 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, value);
2560 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
2561 while (value & MII_GC_RESET)
2562 tlan_mii_read_reg(dev, phy, MII_GEN_CTL, &value);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002563
2564 /* Wait for 500 ms and initialize.
2565 * I don't remember why I wait this long.
2566 * I've changed this to 50ms, as it seems long enough.
2567 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002568 tlan_set_timer(dev, (HZ/20), TLAN_TIMER_PHY_START_LINK);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569
Sakari Ailusc659c382011-01-21 10:59:30 +00002570}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571
2572
2573
2574
Sakari Ailusc659c382011-01-21 10:59:30 +00002575static void tlan_phy_start_link(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576{
Sakari Ailusc659c382011-01-21 10:59:30 +00002577 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578 u16 ability;
2579 u16 control;
2580 u16 data;
2581 u16 phy;
2582 u16 status;
2583 u16 tctl;
2584
Sakari Ailusc659c382011-01-21 10:59:30 +00002585 phy = priv->phy[priv->phy_num];
2586 TLAN_DBG(TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name);
2587 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2588 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &ability);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589
Sakari Ailusc659c382011-01-21 10:59:30 +00002590 if ((status & MII_GS_AUTONEG) &&
2591 (!priv->aui)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592 ability = status >> 11;
Sakari Ailusc659c382011-01-21 10:59:30 +00002593 if (priv->speed == TLAN_SPEED_10 &&
2594 priv->duplex == TLAN_DUPLEX_HALF) {
2595 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0000);
2596 } else if (priv->speed == TLAN_SPEED_10 &&
2597 priv->duplex == TLAN_DUPLEX_FULL) {
2598 priv->tlan_full_duplex = true;
2599 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x0100);
2600 } else if (priv->speed == TLAN_SPEED_100 &&
2601 priv->duplex == TLAN_DUPLEX_HALF) {
2602 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2000);
2603 } else if (priv->speed == TLAN_SPEED_100 &&
2604 priv->duplex == TLAN_DUPLEX_FULL) {
2605 priv->tlan_full_duplex = true;
2606 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x2100);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607 } else {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002608
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609 /* Set Auto-Neg advertisement */
Sakari Ailusc659c382011-01-21 10:59:30 +00002610 tlan_mii_write_reg(dev, phy, MII_AN_ADV,
2611 (ability << 5) | 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612 /* Enablee Auto-Neg */
Sakari Ailusc659c382011-01-21 10:59:30 +00002613 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1000);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614 /* Restart Auto-Neg */
Sakari Ailusc659c382011-01-21 10:59:30 +00002615 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, 0x1200);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002616 /* Wait for 4 sec for autonegotiation
Sakari Ailusc659c382011-01-21 10:59:30 +00002617 * to complete. The max spec time is less than this
2618 * but the card need additional time to start AN.
2619 * .5 sec should be plenty extra.
2620 */
2621 pr_info("TLAN: %s: Starting autonegotiation.\n",
2622 dev->name);
2623 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624 return;
2625 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002626
2627 }
2628
Sakari Ailusc659c382011-01-21 10:59:30 +00002629 if ((priv->aui) && (priv->phy_num != 0)) {
2630 priv->phy_num = 0;
2631 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
2632 | TLAN_NET_CFG_PHY_EN;
2633 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
2634 tlan_set_timer(dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002635 return;
Sakari Ailusc659c382011-01-21 10:59:30 +00002636 } else if (priv->phy_num == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637 control = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002638 tlan_mii_read_reg(dev, phy, TLAN_TLPHY_CTL, &tctl);
2639 if (priv->aui) {
2640 tctl |= TLAN_TC_AUISEL;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002641 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002642 tctl &= ~TLAN_TC_AUISEL;
2643 if (priv->duplex == TLAN_DUPLEX_FULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644 control |= MII_GC_DUPLEX;
Sakari Ailusc659c382011-01-21 10:59:30 +00002645 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002647 if (priv->speed == TLAN_SPEED_100)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648 control |= MII_GC_SPEEDSEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 }
Sakari Ailusc659c382011-01-21 10:59:30 +00002650 tlan_mii_write_reg(dev, phy, MII_GEN_CTL, control);
2651 tlan_mii_write_reg(dev, phy, TLAN_TLPHY_CTL, tctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652 }
2653
2654 /* Wait for 2 sec to give the transceiver time
2655 * to establish link.
2656 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002657 tlan_set_timer(dev, (4*HZ), TLAN_TIMER_FINISH_RESET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658
Sakari Ailusc659c382011-01-21 10:59:30 +00002659}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660
2661
2662
2663
Sakari Ailusc659c382011-01-21 10:59:30 +00002664static void tlan_phy_finish_auto_neg(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665{
Sakari Ailusc659c382011-01-21 10:59:30 +00002666 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002667 u16 an_adv;
2668 u16 an_lpa;
2669 u16 data;
2670 u16 mode;
2671 u16 phy;
2672 u16 status;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002673
Sakari Ailusc659c382011-01-21 10:59:30 +00002674 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002675
Sakari Ailusc659c382011-01-21 10:59:30 +00002676 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
2677 udelay(1000);
2678 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679
Sakari Ailusc659c382011-01-21 10:59:30 +00002680 if (!(status & MII_GS_AUTOCMPLT)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681 /* Wait for 8 sec to give the process
2682 * more time. Perhaps we should fail after a while.
2683 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002684 if (!priv->neg_be_verbose++) {
2685 pr_info("TLAN: Giving autonegotiation more time.\n");
2686 pr_info("TLAN: Please check that your adapter has\n");
2687 pr_info("TLAN: been properly connected to a HUB or Switch.\n");
2688 pr_info("TLAN: Trying to establish link in the background...\n");
2689 }
2690 tlan_set_timer(dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691 return;
2692 }
2693
Sakari Ailusc659c382011-01-21 10:59:30 +00002694 pr_info("TLAN: %s: Autonegotiation complete.\n", dev->name);
2695 tlan_mii_read_reg(dev, phy, MII_AN_ADV, &an_adv);
2696 tlan_mii_read_reg(dev, phy, MII_AN_LPA, &an_lpa);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697 mode = an_adv & an_lpa & 0x03E0;
Sakari Ailusc659c382011-01-21 10:59:30 +00002698 if (mode & 0x0100)
2699 priv->tlan_full_duplex = true;
2700 else if (!(mode & 0x0080) && (mode & 0x0040))
2701 priv->tlan_full_duplex = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002702
Sakari Ailusc659c382011-01-21 10:59:30 +00002703 if ((!(mode & 0x0180)) &&
2704 (priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10) &&
2705 (priv->phy_num != 0)) {
2706 priv->phy_num = 0;
2707 data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN
2708 | TLAN_NET_CFG_PHY_EN;
2709 tlan_dio_write16(dev->base_addr, TLAN_NET_CONFIG, data);
2710 tlan_set_timer(dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711 return;
2712 }
2713
Sakari Ailusc659c382011-01-21 10:59:30 +00002714 if (priv->phy_num == 0) {
2715 if ((priv->duplex == TLAN_DUPLEX_FULL) ||
2716 (an_adv & an_lpa & 0x0040)) {
2717 tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
2718 MII_GC_AUTOENB | MII_GC_DUPLEX);
2719 pr_info("TLAN: Starting internal PHY with FULL-DUPLEX\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00002721 tlan_mii_write_reg(dev, phy, MII_GEN_CTL,
2722 MII_GC_AUTOENB);
2723 pr_info("TLAN: Starting internal PHY with HALF-DUPLEX\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002724 }
2725 }
2726
2727 /* Wait for 100 ms. No reason in partiticular.
2728 */
Sakari Ailusc659c382011-01-21 10:59:30 +00002729 tlan_set_timer(dev, (HZ/10), TLAN_TIMER_FINISH_RESET);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002730
Sakari Ailusc659c382011-01-21 10:59:30 +00002731}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732
2733#ifdef MONITOR
2734
Sakari Ailusc659c382011-01-21 10:59:30 +00002735/*********************************************************************
2736 *
2737 * tlan_phy_monitor
2738 *
2739 * Returns:
2740 * None
2741 *
2742 * Params:
2743 * dev The device structure of this device.
2744 *
2745 *
2746 * This function monitors PHY condition by reading the status
2747 * register via the MII bus. This can be used to give info
2748 * about link changes (up/down), and possible switch to alternate
2749 * media.
2750 *
2751 *******************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752
Sakari Ailusc659c382011-01-21 10:59:30 +00002753void tlan_phy_monitor(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002754{
Sakari Ailusc659c382011-01-21 10:59:30 +00002755 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756 u16 phy;
2757 u16 phy_status;
2758
Sakari Ailusc659c382011-01-21 10:59:30 +00002759 phy = priv->phy[priv->phy_num];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002760
Sakari Ailusc659c382011-01-21 10:59:30 +00002761 /* Get PHY status register */
2762 tlan_mii_read_reg(dev, phy, MII_GEN_STS, &phy_status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763
Sakari Ailusc659c382011-01-21 10:59:30 +00002764 /* Check if link has been lost */
2765 if (!(phy_status & MII_GS_LINK)) {
2766 if (priv->link) {
2767 priv->link = 0;
2768 printk(KERN_DEBUG "TLAN: %s has lost link\n",
2769 dev->name);
2770 netif_carrier_off(dev);
2771 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
2772 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002773 }
2774 }
2775
Sakari Ailusc659c382011-01-21 10:59:30 +00002776 /* Link restablished? */
2777 if ((phy_status & MII_GS_LINK) && !priv->link) {
2778 priv->link = 1;
2779 printk(KERN_DEBUG "TLAN: %s has reestablished link\n",
2780 dev->name);
7d17c1d2005-05-12 19:45:25 -04002781 netif_carrier_on(dev);
Sakari Ailusc659c382011-01-21 10:59:30 +00002782 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783
2784 /* Setup a new monitor */
Sakari Ailusc659c382011-01-21 10:59:30 +00002785 tlan_set_timer(dev, (2*HZ), TLAN_TIMER_LINK_BEAT);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002786}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002787
2788#endif /* MONITOR */
2789
2790
2791/*****************************************************************************
2792******************************************************************************
2793
Sakari Ailusc659c382011-01-21 10:59:30 +00002794ThunderLAN driver MII routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07002795
Sakari Ailusc659c382011-01-21 10:59:30 +00002796these routines are based on the information in chap. 2 of the
2797"ThunderLAN Programmer's Guide", pp. 15-24.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002798
2799******************************************************************************
2800*****************************************************************************/
2801
2802
Sakari Ailusc659c382011-01-21 10:59:30 +00002803/***************************************************************
2804 * tlan_mii_read_reg
2805 *
2806 * Returns:
2807 * false if ack received ok
2808 * true if no ack received or other error
2809 *
2810 * Parms:
2811 * dev The device structure containing
2812 * The io address and interrupt count
2813 * for this device.
2814 * phy The address of the PHY to be queried.
2815 * reg The register whose contents are to be
2816 * retrieved.
2817 * val A pointer to a variable to store the
2818 * retrieved value.
2819 *
2820 * This function uses the TLAN's MII bus to retrieve the contents
2821 * of a given register on a PHY. It sends the appropriate info
2822 * and then reads the 16-bit register value from the MII bus via
2823 * the TLAN SIO register.
2824 *
2825 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826
Sakari Ailusc659c382011-01-21 10:59:30 +00002827static bool
2828tlan_mii_read_reg(struct net_device *dev, u16 phy, u16 reg, u16 *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829{
2830 u8 nack;
2831 u16 sio, tmp;
Sakari Ailusc659c382011-01-21 10:59:30 +00002832 u32 i;
Joe Perches37fce432010-01-12 20:59:13 +00002833 bool err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 int minten;
Sakari Ailusc659c382011-01-21 10:59:30 +00002835 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836 unsigned long flags = 0;
2837
Joe Perches37fce432010-01-12 20:59:13 +00002838 err = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002839 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
2840 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002841
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842 if (!in_irq())
2843 spin_lock_irqsave(&priv->lock, flags);
2844
Sakari Ailusc659c382011-01-21 10:59:30 +00002845 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846
Sakari Ailusc659c382011-01-21 10:59:30 +00002847 minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
2848 if (minten)
2849 tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850
Sakari Ailusc659c382011-01-21 10:59:30 +00002851 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */
2852 tlan_mii_send_data(dev->base_addr, 0x2, 2); /* read (10b) */
2853 tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */
2854 tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002855
2856
Sakari Ailusc659c382011-01-21 10:59:30 +00002857 tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio); /* change direction */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858
Sakari Ailusc659c382011-01-21 10:59:30 +00002859 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* clock idle bit */
2860 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
2861 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* wait 300ns */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862
Sakari Ailusc659c382011-01-21 10:59:30 +00002863 nack = tlan_get_bit(TLAN_NET_SIO_MDATA, sio); /* check for ACK */
2864 tlan_set_bit(TLAN_NET_SIO_MCLK, sio); /* finish ACK */
2865 if (nack) { /* no ACK, so fake it */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 for (i = 0; i < 16; i++) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002867 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2868 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002869 }
2870 tmp = 0xffff;
Joe Perches37fce432010-01-12 20:59:13 +00002871 err = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872 } else { /* ACK, so read data */
2873 for (tmp = 0, i = 0x8000; i; i >>= 1) {
Sakari Ailusc659c382011-01-21 10:59:30 +00002874 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2875 if (tlan_get_bit(TLAN_NET_SIO_MDATA, sio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876 tmp |= i;
Sakari Ailusc659c382011-01-21 10:59:30 +00002877 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878 }
2879 }
2880
2881
Sakari Ailusc659c382011-01-21 10:59:30 +00002882 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
2883 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884
Sakari Ailusc659c382011-01-21 10:59:30 +00002885 if (minten)
2886 tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002887
2888 *val = tmp;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04002889
Linus Torvalds1da177e2005-04-16 15:20:36 -07002890 if (!in_irq())
2891 spin_unlock_irqrestore(&priv->lock, flags);
2892
2893 return err;
2894
Sakari Ailusc659c382011-01-21 10:59:30 +00002895}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896
2897
2898
2899
Sakari Ailusc659c382011-01-21 10:59:30 +00002900/***************************************************************
2901 * tlan_mii_send_data
2902 *
2903 * Returns:
2904 * Nothing
2905 * Parms:
2906 * base_port The base IO port of the adapter in
2907 * question.
2908 * dev The address of the PHY to be queried.
2909 * data The value to be placed on the MII bus.
2910 * num_bits The number of bits in data that are to
2911 * be placed on the MII bus.
2912 *
2913 * This function sends on sequence of bits on the MII
2914 * configuration bus.
2915 *
2916 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917
Sakari Ailusc659c382011-01-21 10:59:30 +00002918static void tlan_mii_send_data(u16 base_port, u32 data, unsigned num_bits)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919{
2920 u16 sio;
2921 u32 i;
2922
Sakari Ailusc659c382011-01-21 10:59:30 +00002923 if (num_bits == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924 return;
2925
Sakari Ailusc659c382011-01-21 10:59:30 +00002926 outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
Sakari Ailusc659c382011-01-21 10:59:30 +00002928 tlan_set_bit(TLAN_NET_SIO_MTXEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929
Sakari Ailusc659c382011-01-21 10:59:30 +00002930 for (i = (0x1 << (num_bits - 1)); i; i >>= 1) {
2931 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2932 (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
2933 if (data & i)
2934 tlan_set_bit(TLAN_NET_SIO_MDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 else
Sakari Ailusc659c382011-01-21 10:59:30 +00002936 tlan_clear_bit(TLAN_NET_SIO_MDATA, sio);
2937 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
2938 (void) tlan_get_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939 }
2940
Sakari Ailusc659c382011-01-21 10:59:30 +00002941}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942
2943
2944
2945
Sakari Ailusc659c382011-01-21 10:59:30 +00002946/***************************************************************
2947 * TLan_MiiSync
2948 *
2949 * Returns:
2950 * Nothing
2951 * Parms:
2952 * base_port The base IO port of the adapter in
2953 * question.
2954 *
2955 * This functions syncs all PHYs in terms of the MII configuration
2956 * bus.
2957 *
2958 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959
Sakari Ailusc659c382011-01-21 10:59:30 +00002960static void tlan_mii_sync(u16 base_port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961{
2962 int i;
2963 u16 sio;
2964
Sakari Ailusc659c382011-01-21 10:59:30 +00002965 outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966 sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
2967
Sakari Ailusc659c382011-01-21 10:59:30 +00002968 tlan_clear_bit(TLAN_NET_SIO_MTXEN, sio);
2969 for (i = 0; i < 32; i++) {
2970 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio);
2971 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972 }
2973
Sakari Ailusc659c382011-01-21 10:59:30 +00002974}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002975
2976
2977
2978
Sakari Ailusc659c382011-01-21 10:59:30 +00002979/***************************************************************
2980 * tlan_mii_write_reg
2981 *
2982 * Returns:
2983 * Nothing
2984 * Parms:
2985 * dev The device structure for the device
2986 * to write to.
2987 * phy The address of the PHY to be written to.
2988 * reg The register whose contents are to be
2989 * written.
2990 * val The value to be written to the register.
2991 *
2992 * This function uses the TLAN's MII bus to write the contents of a
2993 * given register on a PHY. It sends the appropriate info and then
2994 * writes the 16-bit register value from the MII configuration bus
2995 * via the TLAN SIO register.
2996 *
2997 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998
Sakari Ailusc659c382011-01-21 10:59:30 +00002999static void
3000tlan_mii_write_reg(struct net_device *dev, u16 phy, u16 reg, u16 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001{
3002 u16 sio;
3003 int minten;
3004 unsigned long flags = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00003005 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006
3007 outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
3008 sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003009
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010 if (!in_irq())
3011 spin_lock_irqsave(&priv->lock, flags);
3012
Sakari Ailusc659c382011-01-21 10:59:30 +00003013 tlan_mii_sync(dev->base_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003014
Sakari Ailusc659c382011-01-21 10:59:30 +00003015 minten = tlan_get_bit(TLAN_NET_SIO_MINTEN, sio);
3016 if (minten)
3017 tlan_clear_bit(TLAN_NET_SIO_MINTEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018
Sakari Ailusc659c382011-01-21 10:59:30 +00003019 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* start (01b) */
3020 tlan_mii_send_data(dev->base_addr, 0x1, 2); /* write (01b) */
3021 tlan_mii_send_data(dev->base_addr, phy, 5); /* device # */
3022 tlan_mii_send_data(dev->base_addr, reg, 5); /* register # */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003023
Sakari Ailusc659c382011-01-21 10:59:30 +00003024 tlan_mii_send_data(dev->base_addr, 0x2, 2); /* send ACK */
3025 tlan_mii_send_data(dev->base_addr, val, 16); /* send data */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003026
Sakari Ailusc659c382011-01-21 10:59:30 +00003027 tlan_clear_bit(TLAN_NET_SIO_MCLK, sio); /* idle cycle */
3028 tlan_set_bit(TLAN_NET_SIO_MCLK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003029
Sakari Ailusc659c382011-01-21 10:59:30 +00003030 if (minten)
3031 tlan_set_bit(TLAN_NET_SIO_MINTEN, sio);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04003032
Linus Torvalds1da177e2005-04-16 15:20:36 -07003033 if (!in_irq())
3034 spin_unlock_irqrestore(&priv->lock, flags);
3035
Sakari Ailusc659c382011-01-21 10:59:30 +00003036}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003037
3038
3039
3040
3041/*****************************************************************************
3042******************************************************************************
3043
Sakari Ailusc659c382011-01-21 10:59:30 +00003044ThunderLAN driver eeprom routines
Linus Torvalds1da177e2005-04-16 15:20:36 -07003045
Sakari Ailusc659c382011-01-21 10:59:30 +00003046the Compaq netelligent 10 and 10/100 cards use a microchip 24C02A
3047EEPROM. these functions are based on information in microchip's
3048data sheet. I don't know how well this functions will work with
3049other Eeproms.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003050
3051******************************************************************************
3052*****************************************************************************/
3053
3054
Sakari Ailusc659c382011-01-21 10:59:30 +00003055/***************************************************************
3056 * tlan_ee_send_start
3057 *
3058 * Returns:
3059 * Nothing
3060 * Parms:
3061 * io_base The IO port base address for the
3062 * TLAN device with the EEPROM to
3063 * use.
3064 *
3065 * This function sends a start cycle to an EEPROM attached
3066 * to a TLAN chip.
3067 *
3068 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069
Sakari Ailusc659c382011-01-21 10:59:30 +00003070static void tlan_ee_send_start(u16 io_base)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071{
3072 u16 sio;
3073
Sakari Ailusc659c382011-01-21 10:59:30 +00003074 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3076
Sakari Ailusc659c382011-01-21 10:59:30 +00003077 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3078 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
3079 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
3080 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3081 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082
Sakari Ailusc659c382011-01-21 10:59:30 +00003083}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003084
3085
3086
3087
Sakari Ailusc659c382011-01-21 10:59:30 +00003088/***************************************************************
3089 * tlan_ee_send_byte
3090 *
3091 * Returns:
3092 * If the correct ack was received, 0, otherwise 1
3093 * Parms: io_base The IO port base address for the
3094 * TLAN device with the EEPROM to
3095 * use.
3096 * data The 8 bits of information to
3097 * send to the EEPROM.
3098 * stop If TLAN_EEPROM_STOP is passed, a
3099 * stop cycle is sent after the
3100 * byte is sent after the ack is
3101 * read.
3102 *
3103 * This function sends a byte on the serial EEPROM line,
3104 * driving the clock to send each bit. The function then
3105 * reverses transmission direction and reads an acknowledge
3106 * bit.
3107 *
3108 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003109
Sakari Ailusc659c382011-01-21 10:59:30 +00003110static int tlan_ee_send_byte(u16 io_base, u8 data, int stop)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111{
3112 int err;
3113 u8 place;
3114 u16 sio;
3115
Sakari Ailusc659c382011-01-21 10:59:30 +00003116 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003117 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3118
3119 /* Assume clock is low, tx is enabled; */
Sakari Ailusc659c382011-01-21 10:59:30 +00003120 for (place = 0x80; place != 0; place >>= 1) {
3121 if (place & data)
3122 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123 else
Sakari Ailusc659c382011-01-21 10:59:30 +00003124 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3125 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3126 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003128 tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
3129 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3130 err = tlan_get_bit(TLAN_NET_SIO_EDATA, sio);
3131 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
3132 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003133
Sakari Ailusc659c382011-01-21 10:59:30 +00003134 if ((!err) && stop) {
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003135 /* STOP, raise data while clock is high */
Sakari Ailusc659c382011-01-21 10:59:30 +00003136 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3137 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3138 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003139 }
3140
Eric Dumazet807540b2010-09-23 05:40:09 +00003141 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142
Sakari Ailusc659c382011-01-21 10:59:30 +00003143}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144
3145
3146
3147
Sakari Ailusc659c382011-01-21 10:59:30 +00003148/***************************************************************
3149 * tlan_ee_receive_byte
3150 *
3151 * Returns:
3152 * Nothing
3153 * Parms:
3154 * io_base The IO port base address for the
3155 * TLAN device with the EEPROM to
3156 * use.
3157 * data An address to a char to hold the
3158 * data sent from the EEPROM.
3159 * stop If TLAN_EEPROM_STOP is passed, a
3160 * stop cycle is sent after the
3161 * byte is received, and no ack is
3162 * sent.
3163 *
3164 * This function receives 8 bits of data from the EEPROM
3165 * over the serial link. It then sends and ack bit, or no
3166 * ack and a stop bit. This function is used to retrieve
3167 * data after the address of a byte in the EEPROM has been
3168 * sent.
3169 *
3170 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003171
Sakari Ailusc659c382011-01-21 10:59:30 +00003172static void tlan_ee_receive_byte(u16 io_base, u8 *data, int stop)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173{
3174 u8 place;
3175 u16 sio;
3176
Sakari Ailusc659c382011-01-21 10:59:30 +00003177 outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178 sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
3179 *data = 0;
3180
3181 /* Assume clock is low, tx is enabled; */
Sakari Ailusc659c382011-01-21 10:59:30 +00003182 tlan_clear_bit(TLAN_NET_SIO_ETXEN, sio);
3183 for (place = 0x80; place; place >>= 1) {
3184 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3185 if (tlan_get_bit(TLAN_NET_SIO_EDATA, sio))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186 *data |= place;
Sakari Ailusc659c382011-01-21 10:59:30 +00003187 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188 }
3189
Sakari Ailusc659c382011-01-21 10:59:30 +00003190 tlan_set_bit(TLAN_NET_SIO_ETXEN, sio);
3191 if (!stop) {
3192 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio); /* ack = 0 */
3193 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3194 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003195 } else {
Sakari Ailusc659c382011-01-21 10:59:30 +00003196 tlan_set_bit(TLAN_NET_SIO_EDATA, sio); /* no ack = 1 (?) */
3197 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3198 tlan_clear_bit(TLAN_NET_SIO_ECLOK, sio);
Stephen Hemmingerdfc2c0a2008-05-30 09:49:58 -07003199 /* STOP, raise data while clock is high */
Sakari Ailusc659c382011-01-21 10:59:30 +00003200 tlan_clear_bit(TLAN_NET_SIO_EDATA, sio);
3201 tlan_set_bit(TLAN_NET_SIO_ECLOK, sio);
3202 tlan_set_bit(TLAN_NET_SIO_EDATA, sio);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203 }
3204
Sakari Ailusc659c382011-01-21 10:59:30 +00003205}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003206
3207
3208
3209
Sakari Ailusc659c382011-01-21 10:59:30 +00003210/***************************************************************
3211 * tlan_ee_read_byte
3212 *
3213 * Returns:
3214 * No error = 0, else, the stage at which the error
3215 * occurred.
3216 * Parms:
3217 * io_base The IO port base address for the
3218 * TLAN device with the EEPROM to
3219 * use.
3220 * ee_addr The address of the byte in the
3221 * EEPROM whose contents are to be
3222 * retrieved.
3223 * data An address to a char to hold the
3224 * data obtained from the EEPROM.
3225 *
3226 * This function reads a byte of information from an byte
3227 * cell in the EEPROM.
3228 *
3229 **************************************************************/
Linus Torvalds1da177e2005-04-16 15:20:36 -07003230
Sakari Ailusc659c382011-01-21 10:59:30 +00003231static int tlan_ee_read_byte(struct net_device *dev, u8 ee_addr, u8 *data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003232{
3233 int err;
Sakari Ailusc659c382011-01-21 10:59:30 +00003234 struct tlan_priv *priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003235 unsigned long flags = 0;
Sakari Ailusc659c382011-01-21 10:59:30 +00003236 int ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003237
3238 spin_lock_irqsave(&priv->lock, flags);
3239
Sakari Ailusc659c382011-01-21 10:59:30 +00003240 tlan_ee_send_start(dev->base_addr);
3241 err = tlan_ee_send_byte(dev->base_addr, 0xa0, TLAN_EEPROM_ACK);
3242 if (err) {
3243 ret = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003244 goto fail;
3245 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003246 err = tlan_ee_send_byte(dev->base_addr, ee_addr, TLAN_EEPROM_ACK);
3247 if (err) {
3248 ret = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003249 goto fail;
3250 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003251 tlan_ee_send_start(dev->base_addr);
3252 err = tlan_ee_send_byte(dev->base_addr, 0xa1, TLAN_EEPROM_ACK);
3253 if (err) {
3254 ret = 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003255 goto fail;
3256 }
Sakari Ailusc659c382011-01-21 10:59:30 +00003257 tlan_ee_receive_byte(dev->base_addr, data, TLAN_EEPROM_STOP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003258fail:
3259 spin_unlock_irqrestore(&priv->lock, flags);
3260
3261 return ret;
3262
Sakari Ailusc659c382011-01-21 10:59:30 +00003263}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003264
3265
3266