blob: 74ec64a1625d2763ea8b03373b4f686055df51c1 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
2/*
3 Copyright (c) 2001, 2002 by D-Link Corporation
4 Written by Edward Peng.<edward_peng@dlink.com.tw>
5 Created 03-May-2001, base on Linux' sundance.c.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11*/
Linus Torvalds1da177e2005-04-16 15:20:36 -070012
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#define DRV_NAME "D-Link DL2000-based linux driver"
Jeff Garzik03a8c662006-06-27 07:57:22 -040014#define DRV_VERSION "v1.18"
15#define DRV_RELDATE "2006/06/27"
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include "dl2k.h"
Andrew Mortonc4694c72006-05-15 09:44:43 -070017#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
19static char version[] __devinitdata =
Jeff Garzik6aa20a22006-09-13 13:24:59 -040020 KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#define MAX_UNITS 8
22static int mtu[MAX_UNITS];
23static int vlan[MAX_UNITS];
24static int jumbo[MAX_UNITS];
25static char *media[MAX_UNITS];
26static int tx_flow=-1;
27static int rx_flow=-1;
28static int copy_thresh;
29static int rx_coalesce=10; /* Rx frame count each interrupt */
30static int rx_timeout=200; /* Rx DMA wait time in 640ns increments */
31static int tx_coalesce=16; /* HW xmit count each TxDMAComplete */
32
33
34MODULE_AUTHOR ("Edward Peng");
35MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter");
36MODULE_LICENSE("GPL");
37module_param_array(mtu, int, NULL, 0);
38module_param_array(media, charp, NULL, 0);
39module_param_array(vlan, int, NULL, 0);
40module_param_array(jumbo, int, NULL, 0);
41module_param(tx_flow, int, 0);
42module_param(rx_flow, int, 0);
43module_param(copy_thresh, int, 0);
44module_param(rx_coalesce, int, 0); /* Rx frame count each interrupt */
45module_param(rx_timeout, int, 0); /* Rx DMA wait time in 64ns increments */
46module_param(tx_coalesce, int, 0); /* HW xmit count each TxDMAComplete */
47
48
49/* Enable the default interrupts */
50#define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxDMAComplete| \
51 UpdateStats | LinkEvent)
52#define EnableInt() \
53writew(DEFAULT_INTR, ioaddr + IntEnable)
54
Arjan van de Venf71e1302006-03-03 21:33:57 -050055static const int max_intrloop = 50;
56static const int multicast_filter_limit = 0x40;
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
58static int rio_open (struct net_device *dev);
59static void rio_timer (unsigned long data);
60static void rio_tx_timeout (struct net_device *dev);
61static void alloc_list (struct net_device *dev);
62static int start_xmit (struct sk_buff *skb, struct net_device *dev);
David Howells7d12e782006-10-05 14:55:46 +010063static irqreturn_t rio_interrupt (int irq, void *dev_instance);
Linus Torvalds1da177e2005-04-16 15:20:36 -070064static void rio_free_tx (struct net_device *dev, int irq);
65static void tx_error (struct net_device *dev, int tx_status);
66static int receive_packet (struct net_device *dev);
67static void rio_error (struct net_device *dev, int int_status);
68static int change_mtu (struct net_device *dev, int new_mtu);
69static void set_multicast (struct net_device *dev);
70static struct net_device_stats *get_stats (struct net_device *dev);
71static int clear_stats (struct net_device *dev);
72static int rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
73static int rio_close (struct net_device *dev);
74static int find_miiphy (struct net_device *dev);
75static int parse_eeprom (struct net_device *dev);
76static int read_eeprom (long ioaddr, int eep_addr);
77static int mii_wait_link (struct net_device *dev, int wait);
78static int mii_set_media (struct net_device *dev);
79static int mii_get_media (struct net_device *dev);
80static int mii_set_media_pcs (struct net_device *dev);
81static int mii_get_media_pcs (struct net_device *dev);
82static int mii_read (struct net_device *dev, int phy_addr, int reg_num);
83static int mii_write (struct net_device *dev, int phy_addr, int reg_num,
84 u16 data);
85
Jeff Garzik7282d492006-09-13 14:30:00 -040086static const struct ethtool_ops ethtool_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
88static int __devinit
89rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
90{
91 struct net_device *dev;
92 struct netdev_private *np;
93 static int card_idx;
94 int chip_idx = ent->driver_data;
95 int err, irq;
96 long ioaddr;
97 static int version_printed;
98 void *ring_space;
99 dma_addr_t ring_dma;
100
101 if (!version_printed++)
102 printk ("%s", version);
103
104 err = pci_enable_device (pdev);
105 if (err)
106 return err;
107
108 irq = pdev->irq;
109 err = pci_request_regions (pdev, "dl2k");
110 if (err)
111 goto err_out_disable;
112
113 pci_set_master (pdev);
114 dev = alloc_etherdev (sizeof (*np));
115 if (!dev) {
116 err = -ENOMEM;
117 goto err_out_res;
118 }
119 SET_MODULE_OWNER (dev);
120 SET_NETDEV_DEV(dev, &pdev->dev);
121
122#ifdef MEM_MAPPING
123 ioaddr = pci_resource_start (pdev, 1);
124 ioaddr = (long) ioremap (ioaddr, RIO_IO_SIZE);
125 if (!ioaddr) {
126 err = -ENOMEM;
127 goto err_out_dev;
128 }
129#else
130 ioaddr = pci_resource_start (pdev, 0);
131#endif
132 dev->base_addr = ioaddr;
133 dev->irq = irq;
134 np = netdev_priv(dev);
135 np->chip_id = chip_idx;
136 np->pdev = pdev;
137 spin_lock_init (&np->tx_lock);
138 spin_lock_init (&np->rx_lock);
139
140 /* Parse manual configuration */
141 np->an_enable = 1;
142 np->tx_coalesce = 1;
143 if (card_idx < MAX_UNITS) {
144 if (media[card_idx] != NULL) {
145 np->an_enable = 0;
146 if (strcmp (media[card_idx], "auto") == 0 ||
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400147 strcmp (media[card_idx], "autosense") == 0 ||
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 strcmp (media[card_idx], "0") == 0 ) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400149 np->an_enable = 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 } else if (strcmp (media[card_idx], "100mbps_fd") == 0 ||
151 strcmp (media[card_idx], "4") == 0) {
152 np->speed = 100;
153 np->full_duplex = 1;
154 } else if (strcmp (media[card_idx], "100mbps_hd") == 0
155 || strcmp (media[card_idx], "3") == 0) {
156 np->speed = 100;
157 np->full_duplex = 0;
158 } else if (strcmp (media[card_idx], "10mbps_fd") == 0 ||
159 strcmp (media[card_idx], "2") == 0) {
160 np->speed = 10;
161 np->full_duplex = 1;
162 } else if (strcmp (media[card_idx], "10mbps_hd") == 0 ||
163 strcmp (media[card_idx], "1") == 0) {
164 np->speed = 10;
165 np->full_duplex = 0;
166 } else if (strcmp (media[card_idx], "1000mbps_fd") == 0 ||
167 strcmp (media[card_idx], "6") == 0) {
168 np->speed=1000;
169 np->full_duplex=1;
170 } else if (strcmp (media[card_idx], "1000mbps_hd") == 0 ||
171 strcmp (media[card_idx], "5") == 0) {
172 np->speed = 1000;
173 np->full_duplex = 0;
174 } else {
175 np->an_enable = 1;
176 }
177 }
178 if (jumbo[card_idx] != 0) {
179 np->jumbo = 1;
180 dev->mtu = MAX_JUMBO;
181 } else {
182 np->jumbo = 0;
183 if (mtu[card_idx] > 0 && mtu[card_idx] < PACKET_SIZE)
184 dev->mtu = mtu[card_idx];
185 }
186 np->vlan = (vlan[card_idx] > 0 && vlan[card_idx] < 4096) ?
187 vlan[card_idx] : 0;
188 if (rx_coalesce > 0 && rx_timeout > 0) {
189 np->rx_coalesce = rx_coalesce;
190 np->rx_timeout = rx_timeout;
191 np->coalesce = 1;
192 }
193 np->tx_flow = (tx_flow == 0) ? 0 : 1;
194 np->rx_flow = (rx_flow == 0) ? 0 : 1;
195
196 if (tx_coalesce < 1)
197 tx_coalesce = 1;
198 else if (tx_coalesce > TX_RING_SIZE-1)
199 tx_coalesce = TX_RING_SIZE - 1;
200 }
201 dev->open = &rio_open;
202 dev->hard_start_xmit = &start_xmit;
203 dev->stop = &rio_close;
204 dev->get_stats = &get_stats;
205 dev->set_multicast_list = &set_multicast;
206 dev->do_ioctl = &rio_ioctl;
207 dev->tx_timeout = &rio_tx_timeout;
208 dev->watchdog_timeo = TX_TIMEOUT;
209 dev->change_mtu = &change_mtu;
210 SET_ETHTOOL_OPS(dev, &ethtool_ops);
211#if 0
212 dev->features = NETIF_F_IP_CSUM;
213#endif
214 pci_set_drvdata (pdev, dev);
215
216 ring_space = pci_alloc_consistent (pdev, TX_TOTAL_SIZE, &ring_dma);
217 if (!ring_space)
218 goto err_out_iounmap;
219 np->tx_ring = (struct netdev_desc *) ring_space;
220 np->tx_ring_dma = ring_dma;
221
222 ring_space = pci_alloc_consistent (pdev, RX_TOTAL_SIZE, &ring_dma);
223 if (!ring_space)
224 goto err_out_unmap_tx;
225 np->rx_ring = (struct netdev_desc *) ring_space;
226 np->rx_ring_dma = ring_dma;
227
228 /* Parse eeprom data */
229 parse_eeprom (dev);
230
231 /* Find PHY address */
232 err = find_miiphy (dev);
233 if (err)
234 goto err_out_unmap_rx;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400235
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 /* Fiber device? */
237 np->phy_media = (readw(ioaddr + ASICCtrl) & PhyMedia) ? 1 : 0;
238 np->link_status = 0;
239 /* Set media and reset PHY */
240 if (np->phy_media) {
241 /* default Auto-Negotiation for fiber deivices */
242 if (np->an_enable == 2) {
243 np->an_enable = 1;
244 }
245 mii_set_media_pcs (dev);
246 } else {
247 /* Auto-Negotiation is mandatory for 1000BASE-T,
248 IEEE 802.3ab Annex 28D page 14 */
249 if (np->speed == 1000)
250 np->an_enable = 1;
251 mii_set_media (dev);
252 }
253 pci_read_config_byte(pdev, PCI_REVISION_ID, &np->pci_rev_id);
254
255 err = register_netdev (dev);
256 if (err)
257 goto err_out_unmap_rx;
258
259 card_idx++;
260
261 printk (KERN_INFO "%s: %s, %02x:%02x:%02x:%02x:%02x:%02x, IRQ %d\n",
262 dev->name, np->name,
263 dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
264 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], irq);
265 if (tx_coalesce > 1)
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400266 printk(KERN_INFO "tx_coalesce:\t%d packets\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 tx_coalesce);
268 if (np->coalesce)
269 printk(KERN_INFO "rx_coalesce:\t%d packets\n"
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400270 KERN_INFO "rx_timeout: \t%d ns\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 np->rx_coalesce, np->rx_timeout*640);
272 if (np->vlan)
273 printk(KERN_INFO "vlan(id):\t%d\n", np->vlan);
274 return 0;
275
276 err_out_unmap_rx:
277 pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
278 err_out_unmap_tx:
279 pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
280 err_out_iounmap:
281#ifdef MEM_MAPPING
282 iounmap ((void *) ioaddr);
283
284 err_out_dev:
285#endif
286 free_netdev (dev);
287
288 err_out_res:
289 pci_release_regions (pdev);
290
291 err_out_disable:
292 pci_disable_device (pdev);
293 return err;
294}
295
296int
297find_miiphy (struct net_device *dev)
298{
299 int i, phy_found = 0;
300 struct netdev_private *np;
301 long ioaddr;
302 np = netdev_priv(dev);
303 ioaddr = dev->base_addr;
304 np->phy_addr = 1;
305
306 for (i = 31; i >= 0; i--) {
307 int mii_status = mii_read (dev, i, 1);
308 if (mii_status != 0xffff && mii_status != 0x0000) {
309 np->phy_addr = i;
310 phy_found++;
311 }
312 }
313 if (!phy_found) {
314 printk (KERN_ERR "%s: No MII PHY found!\n", dev->name);
315 return -ENODEV;
316 }
317 return 0;
318}
319
320int
321parse_eeprom (struct net_device *dev)
322{
323 int i, j;
324 long ioaddr = dev->base_addr;
325 u8 sromdata[256];
326 u8 *psib;
327 u32 crc;
328 PSROM_t psrom = (PSROM_t) sromdata;
329 struct netdev_private *np = netdev_priv(dev);
330
331 int cid, next;
332
333#ifdef MEM_MAPPING
334 ioaddr = pci_resource_start (np->pdev, 0);
335#endif
336 /* Read eeprom */
337 for (i = 0; i < 128; i++) {
338 ((u16 *) sromdata)[i] = le16_to_cpu (read_eeprom (ioaddr, i));
339 }
340#ifdef MEM_MAPPING
341 ioaddr = dev->base_addr;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400342#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343 /* Check CRC */
344 crc = ~ether_crc_le (256 - 4, sromdata);
345 if (psrom->crc != crc) {
346 printk (KERN_ERR "%s: EEPROM data CRC error.\n", dev->name);
347 return -1;
348 }
349
350 /* Set MAC address */
351 for (i = 0; i < 6; i++)
352 dev->dev_addr[i] = psrom->mac_addr[i];
353
Adrian Bunk47bdd712006-06-30 18:25:18 +0200354 /* Parse Software Information Block */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 i = 0x30;
356 psib = (u8 *) sromdata;
357 do {
358 cid = psib[i++];
359 next = psib[i++];
360 if ((cid == 0 && next == 0) || (cid == 0xff && next == 0xff)) {
361 printk (KERN_ERR "Cell data error\n");
362 return -1;
363 }
364 switch (cid) {
365 case 0: /* Format version */
366 break;
367 case 1: /* End of cell */
368 return 0;
369 case 2: /* Duplex Polarity */
370 np->duplex_polarity = psib[i];
371 writeb (readb (ioaddr + PhyCtrl) | psib[i],
372 ioaddr + PhyCtrl);
373 break;
374 case 3: /* Wake Polarity */
375 np->wake_polarity = psib[i];
376 break;
377 case 9: /* Adapter description */
378 j = (next - i > 255) ? 255 : next - i;
379 memcpy (np->name, &(psib[i]), j);
380 break;
381 case 4:
382 case 5:
383 case 6:
384 case 7:
385 case 8: /* Reversed */
386 break;
387 default: /* Unknown cell */
388 return -1;
389 }
390 i = next;
391 } while (1);
392
393 return 0;
394}
395
396static int
397rio_open (struct net_device *dev)
398{
399 struct netdev_private *np = netdev_priv(dev);
400 long ioaddr = dev->base_addr;
401 int i;
402 u16 macctrl;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400403
Thomas Gleixner1fb9df52006-07-01 19:29:39 -0700404 i = request_irq (dev->irq, &rio_interrupt, IRQF_SHARED, dev->name, dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 if (i)
406 return i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 /* Reset all logic functions */
409 writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
410 ioaddr + ASICCtrl + 2);
411 mdelay(10);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400412
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 /* DebugCtrl bit 4, 5, 9 must set */
414 writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);
415
416 /* Jumbo frame */
417 if (np->jumbo != 0)
418 writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);
419
420 alloc_list (dev);
421
422 /* Get station address */
423 for (i = 0; i < 6; i++)
424 writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);
425
426 set_multicast (dev);
427 if (np->coalesce) {
428 writel (np->rx_coalesce | np->rx_timeout << 16,
429 ioaddr + RxDMAIntCtrl);
430 }
431 /* Set RIO to poll every N*320nsec. */
432 writeb (0x20, ioaddr + RxDMAPollPeriod);
433 writeb (0xff, ioaddr + TxDMAPollPeriod);
434 writeb (0x30, ioaddr + RxDMABurstThresh);
435 writeb (0x30, ioaddr + RxDMAUrgentThresh);
436 writel (0x0007ffff, ioaddr + RmonStatMask);
437 /* clear statistics */
438 clear_stats (dev);
439
440 /* VLAN supported */
441 if (np->vlan) {
442 /* priority field in RxDMAIntCtrl */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400443 writel (readl(ioaddr + RxDMAIntCtrl) | 0x7 << 10,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 ioaddr + RxDMAIntCtrl);
445 /* VLANId */
446 writew (np->vlan, ioaddr + VLANId);
447 /* Length/Type should be 0x8100 */
448 writel (0x8100 << 16 | np->vlan, ioaddr + VLANTag);
449 /* Enable AutoVLANuntagging, but disable AutoVLANtagging.
450 VLAN information tagged by TFC' VID, CFI fields. */
451 writel (readl (ioaddr + MACCtrl) | AutoVLANuntagging,
452 ioaddr + MACCtrl);
453 }
454
455 init_timer (&np->timer);
456 np->timer.expires = jiffies + 1*HZ;
457 np->timer.data = (unsigned long) dev;
458 np->timer.function = &rio_timer;
459 add_timer (&np->timer);
460
461 /* Start Tx/Rx */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400462 writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 ioaddr + MACCtrl);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400464
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465 macctrl = 0;
466 macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
467 macctrl |= (np->full_duplex) ? DuplexSelect : 0;
468 macctrl |= (np->tx_flow) ? TxFlowControlEnable : 0;
469 macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
470 writew(macctrl, ioaddr + MACCtrl);
471
472 netif_start_queue (dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400473
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 /* Enable default interrupts */
475 EnableInt ();
476 return 0;
477}
478
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400479static void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480rio_timer (unsigned long data)
481{
482 struct net_device *dev = (struct net_device *)data;
483 struct netdev_private *np = netdev_priv(dev);
484 unsigned int entry;
485 int next_tick = 1*HZ;
486 unsigned long flags;
487
488 spin_lock_irqsave(&np->rx_lock, flags);
489 /* Recover rx ring exhausted error */
490 if (np->cur_rx - np->old_rx >= RX_RING_SIZE) {
491 printk(KERN_INFO "Try to recover rx ring exhausted...\n");
492 /* Re-allocate skbuffs to fill the descriptor ring */
493 for (; np->cur_rx - np->old_rx > 0; np->old_rx++) {
494 struct sk_buff *skb;
495 entry = np->old_rx % RX_RING_SIZE;
496 /* Dropped packets don't need to re-allocate */
497 if (np->rx_skbuff[entry] == NULL) {
498 skb = dev_alloc_skb (np->rx_buf_sz);
499 if (skb == NULL) {
500 np->rx_ring[entry].fraginfo = 0;
501 printk (KERN_INFO
502 "%s: Still unable to re-allocate Rx skbuff.#%d\n",
503 dev->name, entry);
504 break;
505 }
506 np->rx_skbuff[entry] = skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 /* 16 byte align the IP header */
508 skb_reserve (skb, 2);
509 np->rx_ring[entry].fraginfo =
510 cpu_to_le64 (pci_map_single
David S. Miller689be432005-06-28 15:25:31 -0700511 (np->pdev, skb->data, np->rx_buf_sz,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 PCI_DMA_FROMDEVICE));
513 }
514 np->rx_ring[entry].fraginfo |=
515 cpu_to_le64 (np->rx_buf_sz) << 48;
516 np->rx_ring[entry].status = 0;
517 } /* end for */
518 } /* end if */
519 spin_unlock_irqrestore (&np->rx_lock, flags);
520 np->timer.expires = jiffies + next_tick;
521 add_timer(&np->timer);
522}
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400523
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524static void
525rio_tx_timeout (struct net_device *dev)
526{
527 long ioaddr = dev->base_addr;
528
529 printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
530 dev->name, readl (ioaddr + TxStatus));
531 rio_free_tx(dev, 0);
532 dev->if_port = 0;
533 dev->trans_start = jiffies;
534}
535
536 /* allocate and initialize Tx and Rx descriptors */
537static void
538alloc_list (struct net_device *dev)
539{
540 struct netdev_private *np = netdev_priv(dev);
541 int i;
542
543 np->cur_rx = np->cur_tx = 0;
544 np->old_rx = np->old_tx = 0;
545 np->rx_buf_sz = (dev->mtu <= 1500 ? PACKET_SIZE : dev->mtu + 32);
546
547 /* Initialize Tx descriptors, TFDListPtr leaves in start_xmit(). */
548 for (i = 0; i < TX_RING_SIZE; i++) {
549 np->tx_skbuff[i] = NULL;
550 np->tx_ring[i].status = cpu_to_le64 (TFDDone);
551 np->tx_ring[i].next_desc = cpu_to_le64 (np->tx_ring_dma +
552 ((i+1)%TX_RING_SIZE) *
553 sizeof (struct netdev_desc));
554 }
555
556 /* Initialize Rx descriptors */
557 for (i = 0; i < RX_RING_SIZE; i++) {
558 np->rx_ring[i].next_desc = cpu_to_le64 (np->rx_ring_dma +
559 ((i + 1) % RX_RING_SIZE) *
560 sizeof (struct netdev_desc));
561 np->rx_ring[i].status = 0;
562 np->rx_ring[i].fraginfo = 0;
563 np->rx_skbuff[i] = NULL;
564 }
565
566 /* Allocate the rx buffers */
567 for (i = 0; i < RX_RING_SIZE; i++) {
568 /* Allocated fixed size of skbuff */
569 struct sk_buff *skb = dev_alloc_skb (np->rx_buf_sz);
570 np->rx_skbuff[i] = skb;
571 if (skb == NULL) {
572 printk (KERN_ERR
573 "%s: alloc_list: allocate Rx buffer error! ",
574 dev->name);
575 break;
576 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 skb_reserve (skb, 2); /* 16 byte align the IP header. */
578 /* Rubicon now supports 40 bits of addressing space. */
579 np->rx_ring[i].fraginfo =
580 cpu_to_le64 ( pci_map_single (
David S. Miller689be432005-06-28 15:25:31 -0700581 np->pdev, skb->data, np->rx_buf_sz,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 PCI_DMA_FROMDEVICE));
583 np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48;
584 }
585
586 /* Set RFDListPtr */
587 writel (cpu_to_le32 (np->rx_ring_dma), dev->base_addr + RFDListPtr0);
588 writel (0, dev->base_addr + RFDListPtr1);
589
590 return;
591}
592
593static int
594start_xmit (struct sk_buff *skb, struct net_device *dev)
595{
596 struct netdev_private *np = netdev_priv(dev);
597 struct netdev_desc *txdesc;
598 unsigned entry;
599 u32 ioaddr;
600 u64 tfc_vlan_tag = 0;
601
602 if (np->link_status == 0) { /* Link Down */
603 dev_kfree_skb(skb);
604 return 0;
605 }
606 ioaddr = dev->base_addr;
607 entry = np->cur_tx % TX_RING_SIZE;
608 np->tx_skbuff[entry] = skb;
609 txdesc = &np->tx_ring[entry];
610
611#if 0
Patrick McHardy84fa7932006-08-29 16:44:56 -0700612 if (skb->ip_summed == CHECKSUM_PARTIAL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 txdesc->status |=
614 cpu_to_le64 (TCPChecksumEnable | UDPChecksumEnable |
615 IPChecksumEnable);
616 }
617#endif
618 if (np->vlan) {
619 tfc_vlan_tag =
620 cpu_to_le64 (VLANTagInsert) |
621 (cpu_to_le64 (np->vlan) << 32) |
622 (cpu_to_le64 (skb->priority) << 45);
623 }
624 txdesc->fraginfo = cpu_to_le64 (pci_map_single (np->pdev, skb->data,
625 skb->len,
626 PCI_DMA_TODEVICE));
627 txdesc->fraginfo |= cpu_to_le64 (skb->len) << 48;
628
629 /* DL2K bug: DMA fails to get next descriptor ptr in 10Mbps mode
630 * Work around: Always use 1 descriptor in 10Mbps mode */
631 if (entry % np->tx_coalesce == 0 || np->speed == 10)
632 txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400633 WordAlignDisable |
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 TxDMAIndicate |
635 (1 << FragCountShift));
636 else
637 txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400638 WordAlignDisable |
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 (1 << FragCountShift));
640
641 /* TxDMAPollNow */
642 writel (readl (ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl);
643 /* Schedule ISR */
644 writel(10000, ioaddr + CountDown);
645 np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE;
646 if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
647 < TX_QUEUE_LEN - 1 && np->speed != 10) {
648 /* do nothing */
649 } else if (!netif_queue_stopped(dev)) {
650 netif_stop_queue (dev);
651 }
652
653 /* The first TFDListPtr */
654 if (readl (dev->base_addr + TFDListPtr0) == 0) {
655 writel (np->tx_ring_dma + entry * sizeof (struct netdev_desc),
656 dev->base_addr + TFDListPtr0);
657 writel (0, dev->base_addr + TFDListPtr1);
658 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400659
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 /* NETDEV WATCHDOG timer */
661 dev->trans_start = jiffies;
662 return 0;
663}
664
665static irqreturn_t
David Howells7d12e782006-10-05 14:55:46 +0100666rio_interrupt (int irq, void *dev_instance)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667{
668 struct net_device *dev = dev_instance;
669 struct netdev_private *np;
670 unsigned int_status;
671 long ioaddr;
672 int cnt = max_intrloop;
673 int handled = 0;
674
675 ioaddr = dev->base_addr;
676 np = netdev_priv(dev);
677 while (1) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400678 int_status = readw (ioaddr + IntStatus);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 writew (int_status, ioaddr + IntStatus);
680 int_status &= DEFAULT_INTR;
681 if (int_status == 0 || --cnt < 0)
682 break;
683 handled = 1;
684 /* Processing received packets */
685 if (int_status & RxDMAComplete)
686 receive_packet (dev);
687 /* TxDMAComplete interrupt */
688 if ((int_status & (TxDMAComplete|IntRequested))) {
689 int tx_status;
690 tx_status = readl (ioaddr + TxStatus);
691 if (tx_status & 0x01)
692 tx_error (dev, tx_status);
693 /* Free used tx skbuffs */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400694 rio_free_tx (dev, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695 }
696
697 /* Handle uncommon events */
698 if (int_status &
699 (HostError | LinkEvent | UpdateStats))
700 rio_error (dev, int_status);
701 }
702 if (np->cur_tx != np->old_tx)
703 writel (100, ioaddr + CountDown);
704 return IRQ_RETVAL(handled);
705}
706
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400707static void
708rio_free_tx (struct net_device *dev, int irq)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709{
710 struct netdev_private *np = netdev_priv(dev);
711 int entry = np->old_tx % TX_RING_SIZE;
712 int tx_use = 0;
713 unsigned long flag = 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400714
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 if (irq)
716 spin_lock(&np->tx_lock);
717 else
718 spin_lock_irqsave(&np->tx_lock, flag);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400719
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 /* Free used tx skbuffs */
721 while (entry != np->cur_tx) {
722 struct sk_buff *skb;
723
724 if (!(np->tx_ring[entry].status & TFDDone))
725 break;
726 skb = np->tx_skbuff[entry];
727 pci_unmap_single (np->pdev,
Francois Romieu4c1b4622006-05-10 12:48:57 -0700728 np->tx_ring[entry].fraginfo & DMA_48BIT_MASK,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 skb->len, PCI_DMA_TODEVICE);
730 if (irq)
731 dev_kfree_skb_irq (skb);
732 else
733 dev_kfree_skb (skb);
734
735 np->tx_skbuff[entry] = NULL;
736 entry = (entry + 1) % TX_RING_SIZE;
737 tx_use++;
738 }
739 if (irq)
740 spin_unlock(&np->tx_lock);
741 else
742 spin_unlock_irqrestore(&np->tx_lock, flag);
743 np->old_tx = entry;
744
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400745 /* If the ring is no longer full, clear tx_full and
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 call netif_wake_queue() */
747
748 if (netif_queue_stopped(dev) &&
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400749 ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 < TX_QUEUE_LEN - 1 || np->speed == 10)) {
751 netif_wake_queue (dev);
752 }
753}
754
755static void
756tx_error (struct net_device *dev, int tx_status)
757{
758 struct netdev_private *np;
759 long ioaddr = dev->base_addr;
760 int frame_id;
761 int i;
762
763 np = netdev_priv(dev);
764
765 frame_id = (tx_status & 0xffff0000);
766 printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n",
767 dev->name, tx_status, frame_id);
768 np->stats.tx_errors++;
769 /* Ttransmit Underrun */
770 if (tx_status & 0x10) {
771 np->stats.tx_fifo_errors++;
772 writew (readw (ioaddr + TxStartThresh) + 0x10,
773 ioaddr + TxStartThresh);
774 /* Transmit Underrun need to set TxReset, DMARest, FIFOReset */
775 writew (TxReset | DMAReset | FIFOReset | NetworkReset,
776 ioaddr + ASICCtrl + 2);
777 /* Wait for ResetBusy bit clear */
778 for (i = 50; i > 0; i--) {
779 if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
780 break;
781 mdelay (1);
782 }
783 rio_free_tx (dev, 1);
784 /* Reset TFDListPtr */
785 writel (np->tx_ring_dma +
786 np->old_tx * sizeof (struct netdev_desc),
787 dev->base_addr + TFDListPtr0);
788 writel (0, dev->base_addr + TFDListPtr1);
789
790 /* Let TxStartThresh stay default value */
791 }
792 /* Late Collision */
793 if (tx_status & 0x04) {
794 np->stats.tx_fifo_errors++;
795 /* TxReset and clear FIFO */
796 writew (TxReset | FIFOReset, ioaddr + ASICCtrl + 2);
797 /* Wait reset done */
798 for (i = 50; i > 0; i--) {
799 if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
800 break;
801 mdelay (1);
802 }
803 /* Let TxStartThresh stay default value */
804 }
805 /* Maximum Collisions */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400806#ifdef ETHER_STATS
807 if (tx_status & 0x08)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 np->stats.collisions16++;
809#else
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400810 if (tx_status & 0x08)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811 np->stats.collisions++;
812#endif
813 /* Restart the Tx */
814 writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl);
815}
816
817static int
818receive_packet (struct net_device *dev)
819{
820 struct netdev_private *np = netdev_priv(dev);
821 int entry = np->cur_rx % RX_RING_SIZE;
822 int cnt = 30;
823
824 /* If RFDDone, FrameStart and FrameEnd set, there is a new packet in. */
825 while (1) {
826 struct netdev_desc *desc = &np->rx_ring[entry];
827 int pkt_len;
828 u64 frame_status;
829
830 if (!(desc->status & RFDDone) ||
831 !(desc->status & FrameStart) || !(desc->status & FrameEnd))
832 break;
833
834 /* Chip omits the CRC. */
835 pkt_len = le64_to_cpu (desc->status & 0xffff);
836 frame_status = le64_to_cpu (desc->status);
837 if (--cnt < 0)
838 break;
839 /* Update rx error statistics, drop packet. */
840 if (frame_status & RFS_Errors) {
841 np->stats.rx_errors++;
842 if (frame_status & (RxRuntFrame | RxLengthError))
843 np->stats.rx_length_errors++;
844 if (frame_status & RxFCSError)
845 np->stats.rx_crc_errors++;
846 if (frame_status & RxAlignmentError && np->speed != 1000)
847 np->stats.rx_frame_errors++;
848 if (frame_status & RxFIFOOverrun)
849 np->stats.rx_fifo_errors++;
850 } else {
851 struct sk_buff *skb;
852
853 /* Small skbuffs for short packets */
854 if (pkt_len > copy_thresh) {
Jon Mason9ee09d92006-03-10 15:12:10 -0600855 pci_unmap_single (np->pdev,
Francois Romieu4c1b4622006-05-10 12:48:57 -0700856 desc->fraginfo & DMA_48BIT_MASK,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 np->rx_buf_sz,
858 PCI_DMA_FROMDEVICE);
859 skb_put (skb = np->rx_skbuff[entry], pkt_len);
860 np->rx_skbuff[entry] = NULL;
861 } else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) {
862 pci_dma_sync_single_for_cpu(np->pdev,
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400863 desc->fraginfo &
Francois Romieu4c1b4622006-05-10 12:48:57 -0700864 DMA_48BIT_MASK,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 np->rx_buf_sz,
866 PCI_DMA_FROMDEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 /* 16 byte align the IP header */
868 skb_reserve (skb, 2);
869 eth_copy_and_sum (skb,
David S. Miller689be432005-06-28 15:25:31 -0700870 np->rx_skbuff[entry]->data,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 pkt_len, 0);
872 skb_put (skb, pkt_len);
873 pci_dma_sync_single_for_device(np->pdev,
Jon Mason9ee09d92006-03-10 15:12:10 -0600874 desc->fraginfo &
Francois Romieu4c1b4622006-05-10 12:48:57 -0700875 DMA_48BIT_MASK,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 np->rx_buf_sz,
877 PCI_DMA_FROMDEVICE);
878 }
879 skb->protocol = eth_type_trans (skb, dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400880#if 0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 /* Checksum done by hw, but csum value unavailable. */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400882 if (np->pci_rev_id >= 0x0c &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 !(frame_status & (TCPError | UDPError | IPError))) {
884 skb->ip_summed = CHECKSUM_UNNECESSARY;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400885 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886#endif
887 netif_rx (skb);
888 dev->last_rx = jiffies;
889 }
890 entry = (entry + 1) % RX_RING_SIZE;
891 }
892 spin_lock(&np->rx_lock);
893 np->cur_rx = entry;
894 /* Re-allocate skbuffs to fill the descriptor ring */
895 entry = np->old_rx;
896 while (entry != np->cur_rx) {
897 struct sk_buff *skb;
898 /* Dropped packets don't need to re-allocate */
899 if (np->rx_skbuff[entry] == NULL) {
900 skb = dev_alloc_skb (np->rx_buf_sz);
901 if (skb == NULL) {
902 np->rx_ring[entry].fraginfo = 0;
903 printk (KERN_INFO
904 "%s: receive_packet: "
905 "Unable to re-allocate Rx skbuff.#%d\n",
906 dev->name, entry);
907 break;
908 }
909 np->rx_skbuff[entry] = skb;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 /* 16 byte align the IP header */
911 skb_reserve (skb, 2);
912 np->rx_ring[entry].fraginfo =
913 cpu_to_le64 (pci_map_single
David S. Miller689be432005-06-28 15:25:31 -0700914 (np->pdev, skb->data, np->rx_buf_sz,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 PCI_DMA_FROMDEVICE));
916 }
917 np->rx_ring[entry].fraginfo |=
918 cpu_to_le64 (np->rx_buf_sz) << 48;
919 np->rx_ring[entry].status = 0;
920 entry = (entry + 1) % RX_RING_SIZE;
921 }
922 np->old_rx = entry;
923 spin_unlock(&np->rx_lock);
924 return 0;
925}
926
927static void
928rio_error (struct net_device *dev, int int_status)
929{
930 long ioaddr = dev->base_addr;
931 struct netdev_private *np = netdev_priv(dev);
932 u16 macctrl;
933
934 /* Link change event */
935 if (int_status & LinkEvent) {
936 if (mii_wait_link (dev, 10) == 0) {
937 printk (KERN_INFO "%s: Link up\n", dev->name);
938 if (np->phy_media)
939 mii_get_media_pcs (dev);
940 else
941 mii_get_media (dev);
942 if (np->speed == 1000)
943 np->tx_coalesce = tx_coalesce;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400944 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 np->tx_coalesce = 1;
946 macctrl = 0;
947 macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
948 macctrl |= (np->full_duplex) ? DuplexSelect : 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400949 macctrl |= (np->tx_flow) ?
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 TxFlowControlEnable : 0;
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400951 macctrl |= (np->rx_flow) ?
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952 RxFlowControlEnable : 0;
953 writew(macctrl, ioaddr + MACCtrl);
954 np->link_status = 1;
955 netif_carrier_on(dev);
956 } else {
957 printk (KERN_INFO "%s: Link off\n", dev->name);
958 np->link_status = 0;
959 netif_carrier_off(dev);
960 }
961 }
962
963 /* UpdateStats statistics registers */
964 if (int_status & UpdateStats) {
965 get_stats (dev);
966 }
967
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400968 /* PCI Error, a catastronphic error related to the bus interface
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 occurs, set GlobalReset and HostReset to reset. */
970 if (int_status & HostError) {
971 printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
972 dev->name, int_status);
973 writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
974 mdelay (500);
975 }
976}
977
978static struct net_device_stats *
979get_stats (struct net_device *dev)
980{
981 long ioaddr = dev->base_addr;
982 struct netdev_private *np = netdev_priv(dev);
983#ifdef MEM_MAPPING
984 int i;
985#endif
986 unsigned int stat_reg;
987
988 /* All statistics registers need to be acknowledged,
989 else statistic overflow could cause problems */
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400990
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991 np->stats.rx_packets += readl (ioaddr + FramesRcvOk);
992 np->stats.tx_packets += readl (ioaddr + FramesXmtOk);
993 np->stats.rx_bytes += readl (ioaddr + OctetRcvOk);
994 np->stats.tx_bytes += readl (ioaddr + OctetXmtOk);
995
996 np->stats.multicast = readl (ioaddr + McstFramesRcvdOk);
Jeff Garzik6aa20a22006-09-13 13:24:59 -0400997 np->stats.collisions += readl (ioaddr + SingleColFrames)
998 + readl (ioaddr + MultiColFrames);
999
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 /* detailed tx errors */
1001 stat_reg = readw (ioaddr + FramesAbortXSColls);
1002 np->stats.tx_aborted_errors += stat_reg;
1003 np->stats.tx_errors += stat_reg;
1004
1005 stat_reg = readw (ioaddr + CarrierSenseErrors);
1006 np->stats.tx_carrier_errors += stat_reg;
1007 np->stats.tx_errors += stat_reg;
1008
1009 /* Clear all other statistic register. */
1010 readl (ioaddr + McstOctetXmtOk);
1011 readw (ioaddr + BcstFramesXmtdOk);
1012 readl (ioaddr + McstFramesXmtdOk);
1013 readw (ioaddr + BcstFramesRcvdOk);
1014 readw (ioaddr + MacControlFramesRcvd);
1015 readw (ioaddr + FrameTooLongErrors);
1016 readw (ioaddr + InRangeLengthErrors);
1017 readw (ioaddr + FramesCheckSeqErrors);
1018 readw (ioaddr + FramesLostRxErrors);
1019 readl (ioaddr + McstOctetXmtOk);
1020 readl (ioaddr + BcstOctetXmtOk);
1021 readl (ioaddr + McstFramesXmtdOk);
1022 readl (ioaddr + FramesWDeferredXmt);
1023 readl (ioaddr + LateCollisions);
1024 readw (ioaddr + BcstFramesXmtdOk);
1025 readw (ioaddr + MacControlFramesXmtd);
1026 readw (ioaddr + FramesWEXDeferal);
1027
1028#ifdef MEM_MAPPING
1029 for (i = 0x100; i <= 0x150; i += 4)
1030 readl (ioaddr + i);
1031#endif
1032 readw (ioaddr + TxJumboFrames);
1033 readw (ioaddr + RxJumboFrames);
1034 readw (ioaddr + TCPCheckSumErrors);
1035 readw (ioaddr + UDPCheckSumErrors);
1036 readw (ioaddr + IPCheckSumErrors);
1037 return &np->stats;
1038}
1039
1040static int
1041clear_stats (struct net_device *dev)
1042{
1043 long ioaddr = dev->base_addr;
1044#ifdef MEM_MAPPING
1045 int i;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001046#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047
1048 /* All statistics registers need to be acknowledged,
1049 else statistic overflow could cause problems */
1050 readl (ioaddr + FramesRcvOk);
1051 readl (ioaddr + FramesXmtOk);
1052 readl (ioaddr + OctetRcvOk);
1053 readl (ioaddr + OctetXmtOk);
1054
1055 readl (ioaddr + McstFramesRcvdOk);
1056 readl (ioaddr + SingleColFrames);
1057 readl (ioaddr + MultiColFrames);
1058 readl (ioaddr + LateCollisions);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001059 /* detailed rx errors */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 readw (ioaddr + FrameTooLongErrors);
1061 readw (ioaddr + InRangeLengthErrors);
1062 readw (ioaddr + FramesCheckSeqErrors);
1063 readw (ioaddr + FramesLostRxErrors);
1064
1065 /* detailed tx errors */
1066 readw (ioaddr + FramesAbortXSColls);
1067 readw (ioaddr + CarrierSenseErrors);
1068
1069 /* Clear all other statistic register. */
1070 readl (ioaddr + McstOctetXmtOk);
1071 readw (ioaddr + BcstFramesXmtdOk);
1072 readl (ioaddr + McstFramesXmtdOk);
1073 readw (ioaddr + BcstFramesRcvdOk);
1074 readw (ioaddr + MacControlFramesRcvd);
1075 readl (ioaddr + McstOctetXmtOk);
1076 readl (ioaddr + BcstOctetXmtOk);
1077 readl (ioaddr + McstFramesXmtdOk);
1078 readl (ioaddr + FramesWDeferredXmt);
1079 readw (ioaddr + BcstFramesXmtdOk);
1080 readw (ioaddr + MacControlFramesXmtd);
1081 readw (ioaddr + FramesWEXDeferal);
1082#ifdef MEM_MAPPING
1083 for (i = 0x100; i <= 0x150; i += 4)
1084 readl (ioaddr + i);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001085#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001086 readw (ioaddr + TxJumboFrames);
1087 readw (ioaddr + RxJumboFrames);
1088 readw (ioaddr + TCPCheckSumErrors);
1089 readw (ioaddr + UDPCheckSumErrors);
1090 readw (ioaddr + IPCheckSumErrors);
1091 return 0;
1092}
1093
1094
1095int
1096change_mtu (struct net_device *dev, int new_mtu)
1097{
1098 struct netdev_private *np = netdev_priv(dev);
1099 int max = (np->jumbo) ? MAX_JUMBO : 1536;
1100
1101 if ((new_mtu < 68) || (new_mtu > max)) {
1102 return -EINVAL;
1103 }
1104
1105 dev->mtu = new_mtu;
1106
1107 return 0;
1108}
1109
1110static void
1111set_multicast (struct net_device *dev)
1112{
1113 long ioaddr = dev->base_addr;
1114 u32 hash_table[2];
1115 u16 rx_mode = 0;
1116 struct netdev_private *np = netdev_priv(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001117
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 hash_table[0] = hash_table[1] = 0;
1119 /* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
1120 hash_table[1] |= cpu_to_le32(0x02000000);
1121 if (dev->flags & IFF_PROMISC) {
1122 /* Receive all frames promiscuously. */
1123 rx_mode = ReceiveAllFrames;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001124 } else if ((dev->flags & IFF_ALLMULTI) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 (dev->mc_count > multicast_filter_limit)) {
1126 /* Receive broadcast and multicast frames */
1127 rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast;
1128 } else if (dev->mc_count > 0) {
1129 int i;
1130 struct dev_mc_list *mclist;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001131 /* Receive broadcast frames and multicast frames filtering
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132 by Hashtable */
1133 rx_mode =
1134 ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001135 for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count;
1136 i++, mclist=mclist->next)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 {
1138 int bit, index = 0;
1139 int crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
1140 /* The inverted high significant 6 bits of CRC are
1141 used as an index to hashtable */
1142 for (bit = 0; bit < 6; bit++)
1143 if (crc & (1 << (31 - bit)))
1144 index |= (1 << bit);
1145 hash_table[index / 32] |= (1 << (index % 32));
1146 }
1147 } else {
1148 rx_mode = ReceiveBroadcast | ReceiveUnicast;
1149 }
1150 if (np->vlan) {
1151 /* ReceiveVLANMatch field in ReceiveMode */
1152 rx_mode |= ReceiveVLANMatch;
1153 }
1154
1155 writel (hash_table[0], ioaddr + HashTable0);
1156 writel (hash_table[1], ioaddr + HashTable1);
1157 writew (rx_mode, ioaddr + ReceiveMode);
1158}
1159
1160static void rio_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
1161{
1162 struct netdev_private *np = netdev_priv(dev);
1163 strcpy(info->driver, "dl2k");
1164 strcpy(info->version, DRV_VERSION);
1165 strcpy(info->bus_info, pci_name(np->pdev));
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001166}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167
1168static int rio_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1169{
1170 struct netdev_private *np = netdev_priv(dev);
1171 if (np->phy_media) {
1172 /* fiber device */
1173 cmd->supported = SUPPORTED_Autoneg | SUPPORTED_FIBRE;
1174 cmd->advertising= ADVERTISED_Autoneg | ADVERTISED_FIBRE;
1175 cmd->port = PORT_FIBRE;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001176 cmd->transceiver = XCVR_INTERNAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 } else {
1178 /* copper device */
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001179 cmd->supported = SUPPORTED_10baseT_Half |
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half
1181 | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full |
1182 SUPPORTED_Autoneg | SUPPORTED_MII;
1183 cmd->advertising = ADVERTISED_10baseT_Half |
1184 ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Half |
1185 ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Full|
1186 ADVERTISED_Autoneg | ADVERTISED_MII;
1187 cmd->port = PORT_MII;
1188 cmd->transceiver = XCVR_INTERNAL;
1189 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001190 if ( np->link_status ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 cmd->speed = np->speed;
1192 cmd->duplex = np->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
1193 } else {
1194 cmd->speed = -1;
1195 cmd->duplex = -1;
1196 }
1197 if ( np->an_enable)
1198 cmd->autoneg = AUTONEG_ENABLE;
1199 else
1200 cmd->autoneg = AUTONEG_DISABLE;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001201
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 cmd->phy_address = np->phy_addr;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001203 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204}
1205
1206static int rio_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1207{
1208 struct netdev_private *np = netdev_priv(dev);
1209 netif_carrier_off(dev);
1210 if (cmd->autoneg == AUTONEG_ENABLE) {
1211 if (np->an_enable)
1212 return 0;
1213 else {
1214 np->an_enable = 1;
1215 mii_set_media(dev);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001216 return 0;
1217 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 } else {
1219 np->an_enable = 0;
1220 if (np->speed == 1000) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001221 cmd->speed = SPEED_100;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 cmd->duplex = DUPLEX_FULL;
1223 printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manual 100Mbps, Full duplex.\n");
1224 }
1225 switch(cmd->speed + cmd->duplex) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001226
Linus Torvalds1da177e2005-04-16 15:20:36 -07001227 case SPEED_10 + DUPLEX_HALF:
1228 np->speed = 10;
1229 np->full_duplex = 0;
1230 break;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001231
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 case SPEED_10 + DUPLEX_FULL:
1233 np->speed = 10;
1234 np->full_duplex = 1;
1235 break;
1236 case SPEED_100 + DUPLEX_HALF:
1237 np->speed = 100;
1238 np->full_duplex = 0;
1239 break;
1240 case SPEED_100 + DUPLEX_FULL:
1241 np->speed = 100;
1242 np->full_duplex = 1;
1243 break;
1244 case SPEED_1000 + DUPLEX_HALF:/* not supported */
1245 case SPEED_1000 + DUPLEX_FULL:/* not supported */
1246 default:
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001247 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 }
1249 mii_set_media(dev);
1250 }
1251 return 0;
1252}
1253
1254static u32 rio_get_link(struct net_device *dev)
1255{
1256 struct netdev_private *np = netdev_priv(dev);
1257 return np->link_status;
1258}
1259
Jeff Garzik7282d492006-09-13 14:30:00 -04001260static const struct ethtool_ops ethtool_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 .get_drvinfo = rio_get_drvinfo,
1262 .get_settings = rio_get_settings,
1263 .set_settings = rio_set_settings,
1264 .get_link = rio_get_link,
1265};
1266
1267static int
1268rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1269{
1270 int phy_addr;
1271 struct netdev_private *np = netdev_priv(dev);
1272 struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001273
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 struct netdev_desc *desc;
1275 int i;
1276
1277 phy_addr = np->phy_addr;
1278 switch (cmd) {
1279 case SIOCDEVPRIVATE:
1280 break;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001281
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 case SIOCDEVPRIVATE + 1:
1283 miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num);
1284 break;
1285 case SIOCDEVPRIVATE + 2:
1286 mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value);
1287 break;
1288 case SIOCDEVPRIVATE + 3:
1289 break;
1290 case SIOCDEVPRIVATE + 4:
1291 break;
1292 case SIOCDEVPRIVATE + 5:
1293 netif_stop_queue (dev);
1294 break;
1295 case SIOCDEVPRIVATE + 6:
1296 netif_wake_queue (dev);
1297 break;
1298 case SIOCDEVPRIVATE + 7:
1299 printk
1300 ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n",
1301 netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx,
1302 np->old_rx);
1303 break;
1304 case SIOCDEVPRIVATE + 8:
1305 printk("TX ring:\n");
1306 for (i = 0; i < TX_RING_SIZE; i++) {
1307 desc = &np->tx_ring[i];
1308 printk
1309 ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
1310 i,
1311 (u32) (np->tx_ring_dma + i * sizeof (*desc)),
1312 (u32) desc->next_desc,
1313 (u32) desc->status, (u32) (desc->fraginfo >> 32),
1314 (u32) desc->fraginfo);
1315 printk ("\n");
1316 }
1317 printk ("\n");
1318 break;
1319
1320 default:
1321 return -EOPNOTSUPP;
1322 }
1323 return 0;
1324}
1325
1326#define EEP_READ 0x0200
1327#define EEP_BUSY 0x8000
1328/* Read the EEPROM word */
1329/* We use I/O instruction to read/write eeprom to avoid fail on some machines */
1330int
1331read_eeprom (long ioaddr, int eep_addr)
1332{
1333 int i = 1000;
1334 outw (EEP_READ | (eep_addr & 0xff), ioaddr + EepromCtrl);
1335 while (i-- > 0) {
1336 if (!(inw (ioaddr + EepromCtrl) & EEP_BUSY)) {
1337 return inw (ioaddr + EepromData);
1338 }
1339 }
1340 return 0;
1341}
1342
1343enum phy_ctrl_bits {
1344 MII_READ = 0x00, MII_CLK = 0x01, MII_DATA1 = 0x02, MII_WRITE = 0x04,
1345 MII_DUPLEX = 0x08,
1346};
1347
1348#define mii_delay() readb(ioaddr)
1349static void
1350mii_sendbit (struct net_device *dev, u32 data)
1351{
1352 long ioaddr = dev->base_addr + PhyCtrl;
1353 data = (data) ? MII_DATA1 : 0;
1354 data |= MII_WRITE;
1355 data |= (readb (ioaddr) & 0xf8) | MII_WRITE;
1356 writeb (data, ioaddr);
1357 mii_delay ();
1358 writeb (data | MII_CLK, ioaddr);
1359 mii_delay ();
1360}
1361
1362static int
1363mii_getbit (struct net_device *dev)
1364{
1365 long ioaddr = dev->base_addr + PhyCtrl;
1366 u8 data;
1367
1368 data = (readb (ioaddr) & 0xf8) | MII_READ;
1369 writeb (data, ioaddr);
1370 mii_delay ();
1371 writeb (data | MII_CLK, ioaddr);
1372 mii_delay ();
1373 return ((readb (ioaddr) >> 1) & 1);
1374}
1375
1376static void
1377mii_send_bits (struct net_device *dev, u32 data, int len)
1378{
1379 int i;
1380 for (i = len - 1; i >= 0; i--) {
1381 mii_sendbit (dev, data & (1 << i));
1382 }
1383}
1384
1385static int
1386mii_read (struct net_device *dev, int phy_addr, int reg_num)
1387{
1388 u32 cmd;
1389 int i;
1390 u32 retval = 0;
1391
1392 /* Preamble */
1393 mii_send_bits (dev, 0xffffffff, 32);
1394 /* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */
1395 /* ST,OP = 0110'b for read operation */
1396 cmd = (0x06 << 10 | phy_addr << 5 | reg_num);
1397 mii_send_bits (dev, cmd, 14);
1398 /* Turnaround */
1399 if (mii_getbit (dev))
1400 goto err_out;
1401 /* Read data */
1402 for (i = 0; i < 16; i++) {
1403 retval |= mii_getbit (dev);
1404 retval <<= 1;
1405 }
1406 /* End cycle */
1407 mii_getbit (dev);
1408 return (retval >> 1) & 0xffff;
1409
1410 err_out:
1411 return 0;
1412}
1413static int
1414mii_write (struct net_device *dev, int phy_addr, int reg_num, u16 data)
1415{
1416 u32 cmd;
1417
1418 /* Preamble */
1419 mii_send_bits (dev, 0xffffffff, 32);
1420 /* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */
1421 /* ST,OP,AAAAA,RRRRR,TA = 0101xxxxxxxxxx10'b = 0x5002 for write */
1422 cmd = (0x5002 << 16) | (phy_addr << 23) | (reg_num << 18) | data;
1423 mii_send_bits (dev, cmd, 32);
1424 /* End cycle */
1425 mii_getbit (dev);
1426 return 0;
1427}
1428static int
1429mii_wait_link (struct net_device *dev, int wait)
1430{
1431 BMSR_t bmsr;
1432 int phy_addr;
1433 struct netdev_private *np;
1434
1435 np = netdev_priv(dev);
1436 phy_addr = np->phy_addr;
1437
1438 do {
1439 bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
1440 if (bmsr.bits.link_status)
1441 return 0;
1442 mdelay (1);
1443 } while (--wait > 0);
1444 return -1;
1445}
1446static int
1447mii_get_media (struct net_device *dev)
1448{
1449 ANAR_t negotiate;
1450 BMSR_t bmsr;
1451 BMCR_t bmcr;
1452 MSCR_t mscr;
1453 MSSR_t mssr;
1454 int phy_addr;
1455 struct netdev_private *np;
1456
1457 np = netdev_priv(dev);
1458 phy_addr = np->phy_addr;
1459
1460 bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
1461 if (np->an_enable) {
1462 if (!bmsr.bits.an_complete) {
1463 /* Auto-Negotiation not completed */
1464 return -1;
1465 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001466 negotiate.image = mii_read (dev, phy_addr, MII_ANAR) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 mii_read (dev, phy_addr, MII_ANLPAR);
1468 mscr.image = mii_read (dev, phy_addr, MII_MSCR);
1469 mssr.image = mii_read (dev, phy_addr, MII_MSSR);
1470 if (mscr.bits.media_1000BT_FD & mssr.bits.lp_1000BT_FD) {
1471 np->speed = 1000;
1472 np->full_duplex = 1;
1473 printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");
1474 } else if (mscr.bits.media_1000BT_HD & mssr.bits.lp_1000BT_HD) {
1475 np->speed = 1000;
1476 np->full_duplex = 0;
1477 printk (KERN_INFO "Auto 1000 Mbps, Half duplex\n");
1478 } else if (negotiate.bits.media_100BX_FD) {
1479 np->speed = 100;
1480 np->full_duplex = 1;
1481 printk (KERN_INFO "Auto 100 Mbps, Full duplex\n");
1482 } else if (negotiate.bits.media_100BX_HD) {
1483 np->speed = 100;
1484 np->full_duplex = 0;
1485 printk (KERN_INFO "Auto 100 Mbps, Half duplex\n");
1486 } else if (negotiate.bits.media_10BT_FD) {
1487 np->speed = 10;
1488 np->full_duplex = 1;
1489 printk (KERN_INFO "Auto 10 Mbps, Full duplex\n");
1490 } else if (negotiate.bits.media_10BT_HD) {
1491 np->speed = 10;
1492 np->full_duplex = 0;
1493 printk (KERN_INFO "Auto 10 Mbps, Half duplex\n");
1494 }
1495 if (negotiate.bits.pause) {
1496 np->tx_flow &= 1;
1497 np->rx_flow &= 1;
1498 } else if (negotiate.bits.asymmetric) {
1499 np->tx_flow = 0;
1500 np->rx_flow &= 1;
1501 }
1502 /* else tx_flow, rx_flow = user select */
1503 } else {
1504 bmcr.image = mii_read (dev, phy_addr, MII_BMCR);
1505 if (bmcr.bits.speed100 == 1 && bmcr.bits.speed1000 == 0) {
1506 printk (KERN_INFO "Operating at 100 Mbps, ");
1507 } else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 0) {
1508 printk (KERN_INFO "Operating at 10 Mbps, ");
1509 } else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 1) {
1510 printk (KERN_INFO "Operating at 1000 Mbps, ");
1511 }
1512 if (bmcr.bits.duplex_mode) {
1513 printk ("Full duplex\n");
1514 } else {
1515 printk ("Half duplex\n");
1516 }
1517 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001518 if (np->tx_flow)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519 printk(KERN_INFO "Enable Tx Flow Control\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001520 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 printk(KERN_INFO "Disable Tx Flow Control\n");
1522 if (np->rx_flow)
1523 printk(KERN_INFO "Enable Rx Flow Control\n");
1524 else
1525 printk(KERN_INFO "Disable Rx Flow Control\n");
1526
1527 return 0;
1528}
1529
1530static int
1531mii_set_media (struct net_device *dev)
1532{
1533 PHY_SCR_t pscr;
1534 BMCR_t bmcr;
1535 BMSR_t bmsr;
1536 ANAR_t anar;
1537 int phy_addr;
1538 struct netdev_private *np;
1539 np = netdev_priv(dev);
1540 phy_addr = np->phy_addr;
1541
1542 /* Does user set speed? */
1543 if (np->an_enable) {
1544 /* Advertise capabilities */
1545 bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
1546 anar.image = mii_read (dev, phy_addr, MII_ANAR);
1547 anar.bits.media_100BX_FD = bmsr.bits.media_100BX_FD;
1548 anar.bits.media_100BX_HD = bmsr.bits.media_100BX_HD;
1549 anar.bits.media_100BT4 = bmsr.bits.media_100BT4;
1550 anar.bits.media_10BT_FD = bmsr.bits.media_10BT_FD;
1551 anar.bits.media_10BT_HD = bmsr.bits.media_10BT_HD;
1552 anar.bits.pause = 1;
1553 anar.bits.asymmetric = 1;
1554 mii_write (dev, phy_addr, MII_ANAR, anar.image);
1555
1556 /* Enable Auto crossover */
1557 pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR);
1558 pscr.bits.mdi_crossover_mode = 3; /* 11'b */
1559 mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001560
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 /* Soft reset PHY */
1562 mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);
1563 bmcr.image = 0;
1564 bmcr.bits.an_enable = 1;
1565 bmcr.bits.restart_an = 1;
1566 bmcr.bits.reset = 1;
1567 mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
1568 mdelay(1);
1569 } else {
1570 /* Force speed setting */
1571 /* 1) Disable Auto crossover */
1572 pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR);
1573 pscr.bits.mdi_crossover_mode = 0;
1574 mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image);
1575
1576 /* 2) PHY Reset */
1577 bmcr.image = mii_read (dev, phy_addr, MII_BMCR);
1578 bmcr.bits.reset = 1;
1579 mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
1580
1581 /* 3) Power Down */
1582 bmcr.image = 0x1940; /* must be 0x1940 */
1583 mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
1584 mdelay (100); /* wait a certain time */
1585
1586 /* 4) Advertise nothing */
1587 mii_write (dev, phy_addr, MII_ANAR, 0);
1588
1589 /* 5) Set media and Power Up */
1590 bmcr.image = 0;
1591 bmcr.bits.power_down = 1;
1592 if (np->speed == 100) {
1593 bmcr.bits.speed100 = 1;
1594 bmcr.bits.speed1000 = 0;
1595 printk (KERN_INFO "Manual 100 Mbps, ");
1596 } else if (np->speed == 10) {
1597 bmcr.bits.speed100 = 0;
1598 bmcr.bits.speed1000 = 0;
1599 printk (KERN_INFO "Manual 10 Mbps, ");
1600 }
1601 if (np->full_duplex) {
1602 bmcr.bits.duplex_mode = 1;
1603 printk ("Full duplex\n");
1604 } else {
1605 bmcr.bits.duplex_mode = 0;
1606 printk ("Half duplex\n");
1607 }
1608#if 0
1609 /* Set 1000BaseT Master/Slave setting */
1610 mscr.image = mii_read (dev, phy_addr, MII_MSCR);
1611 mscr.bits.cfg_enable = 1;
1612 mscr.bits.cfg_value = 0;
1613#endif
1614 mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
1615 mdelay(10);
1616 }
1617 return 0;
1618}
1619
1620static int
1621mii_get_media_pcs (struct net_device *dev)
1622{
1623 ANAR_PCS_t negotiate;
1624 BMSR_t bmsr;
1625 BMCR_t bmcr;
1626 int phy_addr;
1627 struct netdev_private *np;
1628
1629 np = netdev_priv(dev);
1630 phy_addr = np->phy_addr;
1631
1632 bmsr.image = mii_read (dev, phy_addr, PCS_BMSR);
1633 if (np->an_enable) {
1634 if (!bmsr.bits.an_complete) {
1635 /* Auto-Negotiation not completed */
1636 return -1;
1637 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001638 negotiate.image = mii_read (dev, phy_addr, PCS_ANAR) &
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 mii_read (dev, phy_addr, PCS_ANLPAR);
1640 np->speed = 1000;
1641 if (negotiate.bits.full_duplex) {
1642 printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");
1643 np->full_duplex = 1;
1644 } else {
1645 printk (KERN_INFO "Auto 1000 Mbps, half duplex\n");
1646 np->full_duplex = 0;
1647 }
1648 if (negotiate.bits.pause) {
1649 np->tx_flow &= 1;
1650 np->rx_flow &= 1;
1651 } else if (negotiate.bits.asymmetric) {
1652 np->tx_flow = 0;
1653 np->rx_flow &= 1;
1654 }
1655 /* else tx_flow, rx_flow = user select */
1656 } else {
1657 bmcr.image = mii_read (dev, phy_addr, PCS_BMCR);
1658 printk (KERN_INFO "Operating at 1000 Mbps, ");
1659 if (bmcr.bits.duplex_mode) {
1660 printk ("Full duplex\n");
1661 } else {
1662 printk ("Half duplex\n");
1663 }
1664 }
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001665 if (np->tx_flow)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 printk(KERN_INFO "Enable Tx Flow Control\n");
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001667 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668 printk(KERN_INFO "Disable Tx Flow Control\n");
1669 if (np->rx_flow)
1670 printk(KERN_INFO "Enable Rx Flow Control\n");
1671 else
1672 printk(KERN_INFO "Disable Rx Flow Control\n");
1673
1674 return 0;
1675}
1676
1677static int
1678mii_set_media_pcs (struct net_device *dev)
1679{
1680 BMCR_t bmcr;
1681 ESR_t esr;
1682 ANAR_PCS_t anar;
1683 int phy_addr;
1684 struct netdev_private *np;
1685 np = netdev_priv(dev);
1686 phy_addr = np->phy_addr;
1687
1688 /* Auto-Negotiation? */
1689 if (np->an_enable) {
1690 /* Advertise capabilities */
1691 esr.image = mii_read (dev, phy_addr, PCS_ESR);
1692 anar.image = mii_read (dev, phy_addr, MII_ANAR);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001693 anar.bits.half_duplex =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 esr.bits.media_1000BT_HD | esr.bits.media_1000BX_HD;
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001695 anar.bits.full_duplex =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 esr.bits.media_1000BT_FD | esr.bits.media_1000BX_FD;
1697 anar.bits.pause = 1;
1698 anar.bits.asymmetric = 1;
1699 mii_write (dev, phy_addr, MII_ANAR, anar.image);
1700
1701 /* Soft reset PHY */
1702 mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);
1703 bmcr.image = 0;
1704 bmcr.bits.an_enable = 1;
1705 bmcr.bits.restart_an = 1;
1706 bmcr.bits.reset = 1;
1707 mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
1708 mdelay(1);
1709 } else {
1710 /* Force speed setting */
1711 /* PHY Reset */
1712 bmcr.image = 0;
1713 bmcr.bits.reset = 1;
1714 mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
1715 mdelay(10);
1716 bmcr.image = 0;
1717 bmcr.bits.an_enable = 0;
1718 if (np->full_duplex) {
1719 bmcr.bits.duplex_mode = 1;
1720 printk (KERN_INFO "Manual full duplex\n");
1721 } else {
1722 bmcr.bits.duplex_mode = 0;
1723 printk (KERN_INFO "Manual half duplex\n");
1724 }
1725 mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
1726 mdelay(10);
1727
1728 /* Advertise nothing */
1729 mii_write (dev, phy_addr, MII_ANAR, 0);
1730 }
1731 return 0;
1732}
1733
1734
1735static int
1736rio_close (struct net_device *dev)
1737{
1738 long ioaddr = dev->base_addr;
1739 struct netdev_private *np = netdev_priv(dev);
1740 struct sk_buff *skb;
1741 int i;
1742
1743 netif_stop_queue (dev);
1744
1745 /* Disable interrupts */
1746 writew (0, ioaddr + IntEnable);
1747
1748 /* Stop Tx and Rx logics */
1749 writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
1750 synchronize_irq (dev->irq);
1751 free_irq (dev->irq, dev);
1752 del_timer_sync (&np->timer);
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001753
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 /* Free all the skbuffs in the queue. */
1755 for (i = 0; i < RX_RING_SIZE; i++) {
1756 np->rx_ring[i].status = 0;
1757 np->rx_ring[i].fraginfo = 0;
1758 skb = np->rx_skbuff[i];
1759 if (skb) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001760 pci_unmap_single(np->pdev,
Francois Romieu4c1b4622006-05-10 12:48:57 -07001761 np->rx_ring[i].fraginfo & DMA_48BIT_MASK,
Jon Mason9ee09d92006-03-10 15:12:10 -06001762 skb->len, PCI_DMA_FROMDEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 dev_kfree_skb (skb);
1764 np->rx_skbuff[i] = NULL;
1765 }
1766 }
1767 for (i = 0; i < TX_RING_SIZE; i++) {
1768 skb = np->tx_skbuff[i];
1769 if (skb) {
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001770 pci_unmap_single(np->pdev,
Francois Romieu4c1b4622006-05-10 12:48:57 -07001771 np->tx_ring[i].fraginfo & DMA_48BIT_MASK,
Jon Mason9ee09d92006-03-10 15:12:10 -06001772 skb->len, PCI_DMA_TODEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 dev_kfree_skb (skb);
1774 np->tx_skbuff[i] = NULL;
1775 }
1776 }
1777
1778 return 0;
1779}
1780
1781static void __devexit
1782rio_remove1 (struct pci_dev *pdev)
1783{
1784 struct net_device *dev = pci_get_drvdata (pdev);
1785
1786 if (dev) {
1787 struct netdev_private *np = netdev_priv(dev);
1788
1789 unregister_netdev (dev);
1790 pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring,
1791 np->rx_ring_dma);
1792 pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring,
1793 np->tx_ring_dma);
1794#ifdef MEM_MAPPING
1795 iounmap ((char *) (dev->base_addr));
1796#endif
1797 free_netdev (dev);
1798 pci_release_regions (pdev);
1799 pci_disable_device (pdev);
1800 }
1801 pci_set_drvdata (pdev, NULL);
1802}
1803
1804static struct pci_driver rio_driver = {
1805 .name = "dl2k",
1806 .id_table = rio_pci_tbl,
1807 .probe = rio_probe1,
1808 .remove = __devexit_p(rio_remove1),
1809};
1810
1811static int __init
1812rio_init (void)
1813{
Jeff Garzik29917622006-08-19 17:48:59 -04001814 return pci_register_driver(&rio_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815}
1816
1817static void __exit
1818rio_exit (void)
1819{
1820 pci_unregister_driver (&rio_driver);
1821}
1822
1823module_init (rio_init);
1824module_exit (rio_exit);
1825
1826/*
Jeff Garzik6aa20a22006-09-13 13:24:59 -04001827
1828Compile command:
1829
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -c dl2k.c
1831
1832Read Documentation/networking/dl2k.txt for details.
1833
1834*/
1835