diff options
Diffstat (limited to 'drivers/net/r6040.c')
-rw-r--r-- | drivers/net/r6040.c | 445 |
1 files changed, 259 insertions, 186 deletions
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 504a48ff73c8..6531ff565c54 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -50,8 +50,8 @@ | |||
50 | #include <asm/processor.h> | 50 | #include <asm/processor.h> |
51 | 51 | ||
52 | #define DRV_NAME "r6040" | 52 | #define DRV_NAME "r6040" |
53 | #define DRV_VERSION "0.16" | 53 | #define DRV_VERSION "0.18" |
54 | #define DRV_RELDATE "10Nov2007" | 54 | #define DRV_RELDATE "13Jul2008" |
55 | 55 | ||
56 | /* PHY CHIP Address */ | 56 | /* PHY CHIP Address */ |
57 | #define PHY1_ADDR 1 /* For MAC1 */ | 57 | #define PHY1_ADDR 1 /* For MAC1 */ |
@@ -91,6 +91,14 @@ | |||
91 | #define MISR 0x3C /* Status register */ | 91 | #define MISR 0x3C /* Status register */ |
92 | #define MIER 0x40 /* INT enable register */ | 92 | #define MIER 0x40 /* INT enable register */ |
93 | #define MSK_INT 0x0000 /* Mask off interrupts */ | 93 | #define MSK_INT 0x0000 /* Mask off interrupts */ |
94 | #define RX_FINISH 0x0001 /* RX finished */ | ||
95 | #define RX_NO_DESC 0x0002 /* No RX descriptor available */ | ||
96 | #define RX_FIFO_FULL 0x0004 /* RX FIFO full */ | ||
97 | #define RX_EARLY 0x0008 /* RX early */ | ||
98 | #define TX_FINISH 0x0010 /* TX finished */ | ||
99 | #define TX_EARLY 0x0080 /* TX early */ | ||
100 | #define EVENT_OVRFL 0x0100 /* Event counter overflow */ | ||
101 | #define LINK_CHANGED 0x0200 /* PHY link changed */ | ||
94 | #define ME_CISR 0x44 /* Event counter INT status */ | 102 | #define ME_CISR 0x44 /* Event counter INT status */ |
95 | #define ME_CIER 0x48 /* Event counter INT enable */ | 103 | #define ME_CIER 0x48 /* Event counter INT enable */ |
96 | #define MR_CNT 0x50 /* Successfully received packet counter */ | 104 | #define MR_CNT 0x50 /* Successfully received packet counter */ |
@@ -130,6 +138,21 @@ | |||
130 | #define MBCR_DEFAULT 0x012A /* MAC Bus Control Register */ | 138 | #define MBCR_DEFAULT 0x012A /* MAC Bus Control Register */ |
131 | #define MCAST_MAX 4 /* Max number multicast addresses to filter */ | 139 | #define MCAST_MAX 4 /* Max number multicast addresses to filter */ |
132 | 140 | ||
141 | /* Descriptor status */ | ||
142 | #define DSC_OWNER_MAC 0x8000 /* MAC is the owner of this descriptor */ | ||
143 | #define DSC_RX_OK 0x4000 /* RX was successful */ | ||
144 | #define DSC_RX_ERR 0x0800 /* RX PHY error */ | ||
145 | #define DSC_RX_ERR_DRI 0x0400 /* RX dribble packet */ | ||
146 | #define DSC_RX_ERR_BUF 0x0200 /* RX length exceeds buffer size */ | ||
147 | #define DSC_RX_ERR_LONG 0x0100 /* RX length > maximum packet length */ | ||
148 | #define DSC_RX_ERR_RUNT 0x0080 /* RX packet length < 64 byte */ | ||
149 | #define DSC_RX_ERR_CRC 0x0040 /* RX CRC error */ | ||
150 | #define DSC_RX_BCAST 0x0020 /* RX broadcast (no error) */ | ||
151 | #define DSC_RX_MCAST 0x0010 /* RX multicast (no error) */ | ||
152 | #define DSC_RX_MCH_HIT 0x0008 /* RX multicast hit in hash table (no error) */ | ||
153 | #define DSC_RX_MIDH_HIT 0x0004 /* RX MID table hit (no error) */ | ||
154 | #define DSC_RX_IDX_MID_MASK 3 /* RX mask for the index of matched MIDx */ | ||
155 | |||
133 | /* PHY settings */ | 156 | /* PHY settings */ |
134 | #define ICPLUS_PHY_ID 0x0243 | 157 | #define ICPLUS_PHY_ID 0x0243 |
135 | 158 | ||
@@ -139,10 +162,10 @@ MODULE_AUTHOR("Sten Wang <sten.wang@rdc.com.tw>," | |||
139 | MODULE_LICENSE("GPL"); | 162 | MODULE_LICENSE("GPL"); |
140 | MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver"); | 163 | MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver"); |
141 | 164 | ||
142 | #define RX_INT 0x0001 | 165 | /* RX and TX interrupts that we handle */ |
143 | #define TX_INT 0x0010 | 166 | #define RX_INTS (RX_FIFO_FULL | RX_NO_DESC | RX_FINISH) |
144 | #define RX_NO_DESC_INT 0x0002 | 167 | #define TX_INTS (TX_FINISH) |
145 | #define INT_MASK (RX_INT | TX_INT) | 168 | #define INT_MASK (RX_INTS | TX_INTS) |
146 | 169 | ||
147 | struct r6040_descriptor { | 170 | struct r6040_descriptor { |
148 | u16 status, len; /* 0-3 */ | 171 | u16 status, len; /* 0-3 */ |
@@ -167,7 +190,7 @@ struct r6040_private { | |||
167 | struct r6040_descriptor *tx_ring; | 190 | struct r6040_descriptor *tx_ring; |
168 | dma_addr_t rx_ring_dma; | 191 | dma_addr_t rx_ring_dma; |
169 | dma_addr_t tx_ring_dma; | 192 | dma_addr_t tx_ring_dma; |
170 | u16 tx_free_desc, rx_free_desc, phy_addr, phy_mode; | 193 | u16 tx_free_desc, phy_addr, phy_mode; |
171 | u16 mcr0, mcr1; | 194 | u16 mcr0, mcr1; |
172 | u16 switch_sig; | 195 | u16 switch_sig; |
173 | struct net_device *dev; | 196 | struct net_device *dev; |
@@ -183,7 +206,7 @@ static char version[] __devinitdata = KERN_INFO DRV_NAME | |||
183 | static int phy_table[] = { PHY1_ADDR, PHY2_ADDR }; | 206 | static int phy_table[] = { PHY1_ADDR, PHY2_ADDR }; |
184 | 207 | ||
185 | /* Read a word data from PHY Chip */ | 208 | /* Read a word data from PHY Chip */ |
186 | static int phy_read(void __iomem *ioaddr, int phy_addr, int reg) | 209 | static int r6040_phy_read(void __iomem *ioaddr, int phy_addr, int reg) |
187 | { | 210 | { |
188 | int limit = 2048; | 211 | int limit = 2048; |
189 | u16 cmd; | 212 | u16 cmd; |
@@ -200,7 +223,7 @@ static int phy_read(void __iomem *ioaddr, int phy_addr, int reg) | |||
200 | } | 223 | } |
201 | 224 | ||
202 | /* Write a word data from PHY Chip */ | 225 | /* Write a word data from PHY Chip */ |
203 | static void phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val) | 226 | static void r6040_phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val) |
204 | { | 227 | { |
205 | int limit = 2048; | 228 | int limit = 2048; |
206 | u16 cmd; | 229 | u16 cmd; |
@@ -216,20 +239,20 @@ static void phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val) | |||
216 | } | 239 | } |
217 | } | 240 | } |
218 | 241 | ||
219 | static int mdio_read(struct net_device *dev, int mii_id, int reg) | 242 | static int r6040_mdio_read(struct net_device *dev, int mii_id, int reg) |
220 | { | 243 | { |
221 | struct r6040_private *lp = netdev_priv(dev); | 244 | struct r6040_private *lp = netdev_priv(dev); |
222 | void __iomem *ioaddr = lp->base; | 245 | void __iomem *ioaddr = lp->base; |
223 | 246 | ||
224 | return (phy_read(ioaddr, lp->phy_addr, reg)); | 247 | return (r6040_phy_read(ioaddr, lp->phy_addr, reg)); |
225 | } | 248 | } |
226 | 249 | ||
227 | static void mdio_write(struct net_device *dev, int mii_id, int reg, int val) | 250 | static void r6040_mdio_write(struct net_device *dev, int mii_id, int reg, int val) |
228 | { | 251 | { |
229 | struct r6040_private *lp = netdev_priv(dev); | 252 | struct r6040_private *lp = netdev_priv(dev); |
230 | void __iomem *ioaddr = lp->base; | 253 | void __iomem *ioaddr = lp->base; |
231 | 254 | ||
232 | phy_write(ioaddr, lp->phy_addr, reg, val); | 255 | r6040_phy_write(ioaddr, lp->phy_addr, reg, val); |
233 | } | 256 | } |
234 | 257 | ||
235 | static void r6040_free_txbufs(struct net_device *dev) | 258 | static void r6040_free_txbufs(struct net_device *dev) |
@@ -283,58 +306,101 @@ static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring, | |||
283 | desc->vndescp = desc_ring; | 306 | desc->vndescp = desc_ring; |
284 | } | 307 | } |
285 | 308 | ||
286 | /* Allocate skb buffer for rx descriptor */ | 309 | static void r6040_init_txbufs(struct net_device *dev) |
287 | static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) | ||
288 | { | 310 | { |
289 | struct r6040_descriptor *descptr; | 311 | struct r6040_private *lp = netdev_priv(dev); |
290 | void __iomem *ioaddr = lp->base; | ||
291 | 312 | ||
292 | descptr = lp->rx_insert_ptr; | 313 | lp->tx_free_desc = TX_DCNT; |
293 | while (lp->rx_free_desc < RX_DCNT) { | ||
294 | descptr->skb_ptr = netdev_alloc_skb(dev, MAX_BUF_SIZE); | ||
295 | 314 | ||
296 | if (!descptr->skb_ptr) | 315 | lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring; |
297 | break; | 316 | r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); |
298 | descptr->buf = cpu_to_le32(pci_map_single(lp->pdev, | ||
299 | descptr->skb_ptr->data, | ||
300 | MAX_BUF_SIZE, PCI_DMA_FROMDEVICE)); | ||
301 | descptr->status = 0x8000; | ||
302 | descptr = descptr->vndescp; | ||
303 | lp->rx_free_desc++; | ||
304 | /* Trigger RX DMA */ | ||
305 | iowrite16(lp->mcr0 | 0x0002, ioaddr); | ||
306 | } | ||
307 | lp->rx_insert_ptr = descptr; | ||
308 | } | 317 | } |
309 | 318 | ||
310 | static void r6040_alloc_txbufs(struct net_device *dev) | 319 | static int r6040_alloc_rxbufs(struct net_device *dev) |
311 | { | 320 | { |
312 | struct r6040_private *lp = netdev_priv(dev); | 321 | struct r6040_private *lp = netdev_priv(dev); |
313 | void __iomem *ioaddr = lp->base; | 322 | struct r6040_descriptor *desc; |
323 | struct sk_buff *skb; | ||
324 | int rc; | ||
314 | 325 | ||
315 | lp->tx_free_desc = TX_DCNT; | 326 | lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring; |
327 | r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); | ||
316 | 328 | ||
317 | lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring; | 329 | /* Allocate skbs for the rx descriptors */ |
318 | r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); | 330 | desc = lp->rx_ring; |
331 | do { | ||
332 | skb = netdev_alloc_skb(dev, MAX_BUF_SIZE); | ||
333 | if (!skb) { | ||
334 | printk(KERN_ERR "%s: failed to alloc skb for rx\n", dev->name); | ||
335 | rc = -ENOMEM; | ||
336 | goto err_exit; | ||
337 | } | ||
338 | desc->skb_ptr = skb; | ||
339 | desc->buf = cpu_to_le32(pci_map_single(lp->pdev, | ||
340 | desc->skb_ptr->data, | ||
341 | MAX_BUF_SIZE, PCI_DMA_FROMDEVICE)); | ||
342 | desc->status = DSC_OWNER_MAC; | ||
343 | desc = desc->vndescp; | ||
344 | } while (desc != lp->rx_ring); | ||
319 | 345 | ||
320 | iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0); | 346 | return 0; |
321 | iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1); | 347 | |
348 | err_exit: | ||
349 | /* Deallocate all previously allocated skbs */ | ||
350 | r6040_free_rxbufs(dev); | ||
351 | return rc; | ||
322 | } | 352 | } |
323 | 353 | ||
324 | static void r6040_alloc_rxbufs(struct net_device *dev) | 354 | static void r6040_init_mac_regs(struct net_device *dev) |
325 | { | 355 | { |
326 | struct r6040_private *lp = netdev_priv(dev); | 356 | struct r6040_private *lp = netdev_priv(dev); |
327 | void __iomem *ioaddr = lp->base; | 357 | void __iomem *ioaddr = lp->base; |
358 | int limit = 2048; | ||
359 | u16 cmd; | ||
328 | 360 | ||
329 | lp->rx_free_desc = 0; | 361 | /* Mask Off Interrupt */ |
362 | iowrite16(MSK_INT, ioaddr + MIER); | ||
330 | 363 | ||
331 | lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring; | 364 | /* Reset RDC MAC */ |
332 | r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); | 365 | iowrite16(MAC_RST, ioaddr + MCR1); |
366 | while (limit--) { | ||
367 | cmd = ioread16(ioaddr + MCR1); | ||
368 | if (cmd & 0x1) | ||
369 | break; | ||
370 | } | ||
371 | /* Reset internal state machine */ | ||
372 | iowrite16(2, ioaddr + MAC_SM); | ||
373 | iowrite16(0, ioaddr + MAC_SM); | ||
374 | udelay(5000); | ||
333 | 375 | ||
334 | rx_buf_alloc(lp, dev); | 376 | /* MAC Bus Control Register */ |
377 | iowrite16(MBCR_DEFAULT, ioaddr + MBCR); | ||
378 | |||
379 | /* Buffer Size Register */ | ||
380 | iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR); | ||
381 | |||
382 | /* Write TX ring start address */ | ||
383 | iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0); | ||
384 | iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1); | ||
335 | 385 | ||
386 | /* Write RX ring start address */ | ||
336 | iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0); | 387 | iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0); |
337 | iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1); | 388 | iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1); |
389 | |||
390 | /* Set interrupt waiting time and packet numbers */ | ||
391 | iowrite16(0, ioaddr + MT_ICR); | ||
392 | iowrite16(0, ioaddr + MR_ICR); | ||
393 | |||
394 | /* Enable interrupts */ | ||
395 | iowrite16(INT_MASK, ioaddr + MIER); | ||
396 | |||
397 | /* Enable TX and RX */ | ||
398 | iowrite16(lp->mcr0 | 0x0002, ioaddr); | ||
399 | |||
400 | /* Let TX poll the descriptors | ||
401 | * we may got called by r6040_tx_timeout which has left | ||
402 | * some unsent tx buffers */ | ||
403 | iowrite16(0x01, ioaddr + MTPR); | ||
338 | } | 404 | } |
339 | 405 | ||
340 | static void r6040_tx_timeout(struct net_device *dev) | 406 | static void r6040_tx_timeout(struct net_device *dev) |
@@ -342,27 +408,16 @@ static void r6040_tx_timeout(struct net_device *dev) | |||
342 | struct r6040_private *priv = netdev_priv(dev); | 408 | struct r6040_private *priv = netdev_priv(dev); |
343 | void __iomem *ioaddr = priv->base; | 409 | void __iomem *ioaddr = priv->base; |
344 | 410 | ||
345 | printk(KERN_WARNING "%s: transmit timed out, status %4.4x, PHY status " | 411 | printk(KERN_WARNING "%s: transmit timed out, int enable %4.4x " |
346 | "%4.4x\n", | 412 | "status %4.4x, PHY status %4.4x\n", |
347 | dev->name, ioread16(ioaddr + MIER), | 413 | dev->name, ioread16(ioaddr + MIER), |
348 | mdio_read(dev, priv->mii_if.phy_id, MII_BMSR)); | 414 | ioread16(ioaddr + MISR), |
349 | 415 | r6040_mdio_read(dev, priv->mii_if.phy_id, MII_BMSR)); | |
350 | disable_irq(dev->irq); | ||
351 | napi_disable(&priv->napi); | ||
352 | spin_lock(&priv->lock); | ||
353 | /* Clear all descriptors */ | ||
354 | r6040_free_txbufs(dev); | ||
355 | r6040_free_rxbufs(dev); | ||
356 | r6040_alloc_txbufs(dev); | ||
357 | r6040_alloc_rxbufs(dev); | ||
358 | |||
359 | /* Reset MAC */ | ||
360 | iowrite16(MAC_RST, ioaddr + MCR1); | ||
361 | spin_unlock(&priv->lock); | ||
362 | enable_irq(dev->irq); | ||
363 | 416 | ||
364 | dev->stats.tx_errors++; | 417 | dev->stats.tx_errors++; |
365 | netif_wake_queue(dev); | 418 | |
419 | /* Reset MAC and re-init all registers */ | ||
420 | r6040_init_mac_regs(dev); | ||
366 | } | 421 | } |
367 | 422 | ||
368 | static struct net_device_stats *r6040_get_stats(struct net_device *dev) | 423 | static struct net_device_stats *r6040_get_stats(struct net_device *dev) |
@@ -424,6 +479,7 @@ static int r6040_close(struct net_device *dev) | |||
424 | del_timer_sync(&lp->timer); | 479 | del_timer_sync(&lp->timer); |
425 | 480 | ||
426 | spin_lock_irq(&lp->lock); | 481 | spin_lock_irq(&lp->lock); |
482 | napi_disable(&lp->napi); | ||
427 | netif_stop_queue(dev); | 483 | netif_stop_queue(dev); |
428 | r6040_down(dev); | 484 | r6040_down(dev); |
429 | spin_unlock_irq(&lp->lock); | 485 | spin_unlock_irq(&lp->lock); |
@@ -432,23 +488,23 @@ static int r6040_close(struct net_device *dev) | |||
432 | } | 488 | } |
433 | 489 | ||
434 | /* Status of PHY CHIP */ | 490 | /* Status of PHY CHIP */ |
435 | static int phy_mode_chk(struct net_device *dev) | 491 | static int r6040_phy_mode_chk(struct net_device *dev) |
436 | { | 492 | { |
437 | struct r6040_private *lp = netdev_priv(dev); | 493 | struct r6040_private *lp = netdev_priv(dev); |
438 | void __iomem *ioaddr = lp->base; | 494 | void __iomem *ioaddr = lp->base; |
439 | int phy_dat; | 495 | int phy_dat; |
440 | 496 | ||
441 | /* PHY Link Status Check */ | 497 | /* PHY Link Status Check */ |
442 | phy_dat = phy_read(ioaddr, lp->phy_addr, 1); | 498 | phy_dat = r6040_phy_read(ioaddr, lp->phy_addr, 1); |
443 | if (!(phy_dat & 0x4)) | 499 | if (!(phy_dat & 0x4)) |
444 | phy_dat = 0x8000; /* Link Failed, full duplex */ | 500 | phy_dat = 0x8000; /* Link Failed, full duplex */ |
445 | 501 | ||
446 | /* PHY Chip Auto-Negotiation Status */ | 502 | /* PHY Chip Auto-Negotiation Status */ |
447 | phy_dat = phy_read(ioaddr, lp->phy_addr, 1); | 503 | phy_dat = r6040_phy_read(ioaddr, lp->phy_addr, 1); |
448 | if (phy_dat & 0x0020) { | 504 | if (phy_dat & 0x0020) { |
449 | /* Auto Negotiation Mode */ | 505 | /* Auto Negotiation Mode */ |
450 | phy_dat = phy_read(ioaddr, lp->phy_addr, 5); | 506 | phy_dat = r6040_phy_read(ioaddr, lp->phy_addr, 5); |
451 | phy_dat &= phy_read(ioaddr, lp->phy_addr, 4); | 507 | phy_dat &= r6040_phy_read(ioaddr, lp->phy_addr, 4); |
452 | if (phy_dat & 0x140) | 508 | if (phy_dat & 0x140) |
453 | /* Force full duplex */ | 509 | /* Force full duplex */ |
454 | phy_dat = 0x8000; | 510 | phy_dat = 0x8000; |
@@ -456,7 +512,7 @@ static int phy_mode_chk(struct net_device *dev) | |||
456 | phy_dat = 0; | 512 | phy_dat = 0; |
457 | } else { | 513 | } else { |
458 | /* Force Mode */ | 514 | /* Force Mode */ |
459 | phy_dat = phy_read(ioaddr, lp->phy_addr, 0); | 515 | phy_dat = r6040_phy_read(ioaddr, lp->phy_addr, 0); |
460 | if (phy_dat & 0x100) | 516 | if (phy_dat & 0x100) |
461 | phy_dat = 0x8000; | 517 | phy_dat = 0x8000; |
462 | else | 518 | else |
@@ -468,12 +524,12 @@ static int phy_mode_chk(struct net_device *dev) | |||
468 | 524 | ||
469 | static void r6040_set_carrier(struct mii_if_info *mii) | 525 | static void r6040_set_carrier(struct mii_if_info *mii) |
470 | { | 526 | { |
471 | if (phy_mode_chk(mii->dev)) { | 527 | if (r6040_phy_mode_chk(mii->dev)) { |
472 | /* autoneg is off: Link is always assumed to be up */ | 528 | /* autoneg is off: Link is always assumed to be up */ |
473 | if (!netif_carrier_ok(mii->dev)) | 529 | if (!netif_carrier_ok(mii->dev)) |
474 | netif_carrier_on(mii->dev); | 530 | netif_carrier_on(mii->dev); |
475 | } else | 531 | } else |
476 | phy_mode_chk(mii->dev); | 532 | r6040_phy_mode_chk(mii->dev); |
477 | } | 533 | } |
478 | 534 | ||
479 | static int r6040_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | 535 | static int r6040_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
@@ -494,73 +550,72 @@ static int r6040_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
494 | static int r6040_rx(struct net_device *dev, int limit) | 550 | static int r6040_rx(struct net_device *dev, int limit) |
495 | { | 551 | { |
496 | struct r6040_private *priv = netdev_priv(dev); | 552 | struct r6040_private *priv = netdev_priv(dev); |
497 | int count; | 553 | struct r6040_descriptor *descptr = priv->rx_remove_ptr; |
498 | void __iomem *ioaddr = priv->base; | 554 | struct sk_buff *skb_ptr, *new_skb; |
555 | int count = 0; | ||
499 | u16 err; | 556 | u16 err; |
500 | 557 | ||
501 | for (count = 0; count < limit; ++count) { | 558 | /* Limit not reached and the descriptor belongs to the CPU */ |
502 | struct r6040_descriptor *descptr = priv->rx_remove_ptr; | 559 | while (count < limit && !(descptr->status & DSC_OWNER_MAC)) { |
503 | struct sk_buff *skb_ptr; | 560 | /* Read the descriptor status */ |
504 | 561 | err = descptr->status; | |
505 | /* Disable RX interrupt */ | 562 | /* Global error status set */ |
506 | iowrite16(ioread16(ioaddr + MIER) & (~RX_INT), ioaddr + MIER); | 563 | if (err & DSC_RX_ERR) { |
507 | descptr = priv->rx_remove_ptr; | 564 | /* RX dribble */ |
508 | 565 | if (err & DSC_RX_ERR_DRI) | |
509 | /* Check for errors */ | 566 | dev->stats.rx_frame_errors++; |
510 | err = ioread16(ioaddr + MLSR); | 567 | /* Buffer lenght exceeded */ |
511 | if (err & 0x0400) | 568 | if (err & DSC_RX_ERR_BUF) |
512 | dev->stats.rx_errors++; | 569 | dev->stats.rx_length_errors++; |
513 | /* RX FIFO over-run */ | 570 | /* Packet too long */ |
514 | if (err & 0x8000) | 571 | if (err & DSC_RX_ERR_LONG) |
515 | dev->stats.rx_fifo_errors++; | 572 | dev->stats.rx_length_errors++; |
516 | /* RX descriptor unavailable */ | 573 | /* Packet < 64 bytes */ |
517 | if (err & 0x0080) | 574 | if (err & DSC_RX_ERR_RUNT) |
518 | dev->stats.rx_frame_errors++; | 575 | dev->stats.rx_length_errors++; |
519 | /* Received packet with length over buffer lenght */ | 576 | /* CRC error */ |
520 | if (err & 0x0020) | 577 | if (err & DSC_RX_ERR_CRC) { |
521 | dev->stats.rx_over_errors++; | 578 | spin_lock(&priv->lock); |
522 | /* Received packet with too long or short */ | 579 | dev->stats.rx_crc_errors++; |
523 | if (err & (0x0010 | 0x0008)) | 580 | spin_unlock(&priv->lock); |
524 | dev->stats.rx_length_errors++; | ||
525 | /* Received packet with CRC errors */ | ||
526 | if (err & 0x0004) { | ||
527 | spin_lock(&priv->lock); | ||
528 | dev->stats.rx_crc_errors++; | ||
529 | spin_unlock(&priv->lock); | ||
530 | } | ||
531 | |||
532 | while (priv->rx_free_desc) { | ||
533 | /* No RX packet */ | ||
534 | if (descptr->status & 0x8000) | ||
535 | break; | ||
536 | skb_ptr = descptr->skb_ptr; | ||
537 | if (!skb_ptr) { | ||
538 | printk(KERN_ERR "%s: Inconsistent RX" | ||
539 | "descriptor chain\n", | ||
540 | dev->name); | ||
541 | break; | ||
542 | } | 581 | } |
543 | descptr->skb_ptr = NULL; | 582 | goto next_descr; |
544 | skb_ptr->dev = priv->dev; | 583 | } |
545 | /* Do not count the CRC */ | 584 | |
546 | skb_put(skb_ptr, descptr->len - 4); | 585 | /* Packet successfully received */ |
547 | pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), | 586 | new_skb = netdev_alloc_skb(dev, MAX_BUF_SIZE); |
548 | MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 587 | if (!new_skb) { |
549 | skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev); | 588 | dev->stats.rx_dropped++; |
550 | /* Send to upper layer */ | 589 | goto next_descr; |
551 | netif_receive_skb(skb_ptr); | ||
552 | dev->last_rx = jiffies; | ||
553 | dev->stats.rx_packets++; | ||
554 | dev->stats.rx_bytes += descptr->len; | ||
555 | /* To next descriptor */ | ||
556 | descptr = descptr->vndescp; | ||
557 | priv->rx_free_desc--; | ||
558 | } | 590 | } |
559 | priv->rx_remove_ptr = descptr; | 591 | skb_ptr = descptr->skb_ptr; |
592 | skb_ptr->dev = priv->dev; | ||
593 | |||
594 | /* Do not count the CRC */ | ||
595 | skb_put(skb_ptr, descptr->len - 4); | ||
596 | pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), | ||
597 | MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); | ||
598 | skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev); | ||
599 | |||
600 | /* Send to upper layer */ | ||
601 | netif_receive_skb(skb_ptr); | ||
602 | dev->last_rx = jiffies; | ||
603 | dev->stats.rx_packets++; | ||
604 | dev->stats.rx_bytes += descptr->len - 4; | ||
605 | |||
606 | /* put new skb into descriptor */ | ||
607 | descptr->skb_ptr = new_skb; | ||
608 | descptr->buf = cpu_to_le32(pci_map_single(priv->pdev, | ||
609 | descptr->skb_ptr->data, | ||
610 | MAX_BUF_SIZE, PCI_DMA_FROMDEVICE)); | ||
611 | |||
612 | next_descr: | ||
613 | /* put the descriptor back to the MAC */ | ||
614 | descptr->status = DSC_OWNER_MAC; | ||
615 | descptr = descptr->vndescp; | ||
616 | count++; | ||
560 | } | 617 | } |
561 | /* Allocate new RX buffer */ | 618 | priv->rx_remove_ptr = descptr; |
562 | if (priv->rx_free_desc < RX_DCNT) | ||
563 | rx_buf_alloc(priv, priv->dev); | ||
564 | 619 | ||
565 | return count; | 620 | return count; |
566 | } | 621 | } |
@@ -584,7 +639,7 @@ static void r6040_tx(struct net_device *dev) | |||
584 | if (err & (0x2000 | 0x4000)) | 639 | if (err & (0x2000 | 0x4000)) |
585 | dev->stats.tx_carrier_errors++; | 640 | dev->stats.tx_carrier_errors++; |
586 | 641 | ||
587 | if (descptr->status & 0x8000) | 642 | if (descptr->status & DSC_OWNER_MAC) |
588 | break; /* Not complete */ | 643 | break; /* Not complete */ |
589 | skb_ptr = descptr->skb_ptr; | 644 | skb_ptr = descptr->skb_ptr; |
590 | pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), | 645 | pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), |
@@ -616,7 +671,7 @@ static int r6040_poll(struct napi_struct *napi, int budget) | |||
616 | if (work_done < budget) { | 671 | if (work_done < budget) { |
617 | netif_rx_complete(dev, napi); | 672 | netif_rx_complete(dev, napi); |
618 | /* Enable RX interrupt */ | 673 | /* Enable RX interrupt */ |
619 | iowrite16(ioread16(ioaddr + MIER) | RX_INT, ioaddr + MIER); | 674 | iowrite16(ioread16(ioaddr + MIER) | RX_INTS, ioaddr + MIER); |
620 | } | 675 | } |
621 | return work_done; | 676 | return work_done; |
622 | } | 677 | } |
@@ -638,13 +693,22 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id) | |||
638 | return IRQ_NONE; | 693 | return IRQ_NONE; |
639 | 694 | ||
640 | /* RX interrupt request */ | 695 | /* RX interrupt request */ |
641 | if (status & 0x01) { | 696 | if (status & RX_INTS) { |
697 | if (status & RX_NO_DESC) { | ||
698 | /* RX descriptor unavailable */ | ||
699 | dev->stats.rx_dropped++; | ||
700 | dev->stats.rx_missed_errors++; | ||
701 | } | ||
702 | if (status & RX_FIFO_FULL) | ||
703 | dev->stats.rx_fifo_errors++; | ||
704 | |||
705 | /* Mask off RX interrupt */ | ||
706 | iowrite16(ioread16(ioaddr + MIER) & ~RX_INTS, ioaddr + MIER); | ||
642 | netif_rx_schedule(dev, &lp->napi); | 707 | netif_rx_schedule(dev, &lp->napi); |
643 | iowrite16(TX_INT, ioaddr + MIER); | ||
644 | } | 708 | } |
645 | 709 | ||
646 | /* TX interrupt request */ | 710 | /* TX interrupt request */ |
647 | if (status & 0x10) | 711 | if (status & TX_INTS) |
648 | r6040_tx(dev); | 712 | r6040_tx(dev); |
649 | 713 | ||
650 | return IRQ_HANDLED; | 714 | return IRQ_HANDLED; |
@@ -660,52 +724,48 @@ static void r6040_poll_controller(struct net_device *dev) | |||
660 | #endif | 724 | #endif |
661 | 725 | ||
662 | /* Init RDC MAC */ | 726 | /* Init RDC MAC */ |
663 | static void r6040_up(struct net_device *dev) | 727 | static int r6040_up(struct net_device *dev) |
664 | { | 728 | { |
665 | struct r6040_private *lp = netdev_priv(dev); | 729 | struct r6040_private *lp = netdev_priv(dev); |
666 | void __iomem *ioaddr = lp->base; | 730 | void __iomem *ioaddr = lp->base; |
731 | int ret; | ||
667 | 732 | ||
668 | /* Initialise and alloc RX/TX buffers */ | 733 | /* Initialise and alloc RX/TX buffers */ |
669 | r6040_alloc_txbufs(dev); | 734 | r6040_init_txbufs(dev); |
670 | r6040_alloc_rxbufs(dev); | 735 | ret = r6040_alloc_rxbufs(dev); |
736 | if (ret) | ||
737 | return ret; | ||
671 | 738 | ||
672 | /* Buffer Size Register */ | ||
673 | iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR); | ||
674 | /* Read the PHY ID */ | 739 | /* Read the PHY ID */ |
675 | lp->switch_sig = phy_read(ioaddr, 0, 2); | 740 | lp->switch_sig = r6040_phy_read(ioaddr, 0, 2); |
676 | 741 | ||
677 | if (lp->switch_sig == ICPLUS_PHY_ID) { | 742 | if (lp->switch_sig == ICPLUS_PHY_ID) { |
678 | phy_write(ioaddr, 29, 31, 0x175C); /* Enable registers */ | 743 | r6040_phy_write(ioaddr, 29, 31, 0x175C); /* Enable registers */ |
679 | lp->phy_mode = 0x8000; | 744 | lp->phy_mode = 0x8000; |
680 | } else { | 745 | } else { |
681 | /* PHY Mode Check */ | 746 | /* PHY Mode Check */ |
682 | phy_write(ioaddr, lp->phy_addr, 4, PHY_CAP); | 747 | r6040_phy_write(ioaddr, lp->phy_addr, 4, PHY_CAP); |
683 | phy_write(ioaddr, lp->phy_addr, 0, PHY_MODE); | 748 | r6040_phy_write(ioaddr, lp->phy_addr, 0, PHY_MODE); |
684 | 749 | ||
685 | if (PHY_MODE == 0x3100) | 750 | if (PHY_MODE == 0x3100) |
686 | lp->phy_mode = phy_mode_chk(dev); | 751 | lp->phy_mode = r6040_phy_mode_chk(dev); |
687 | else | 752 | else |
688 | lp->phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0; | 753 | lp->phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0; |
689 | } | 754 | } |
690 | /* MAC Bus Control Register */ | ||
691 | iowrite16(MBCR_DEFAULT, ioaddr + MBCR); | ||
692 | 755 | ||
693 | /* MAC TX/RX Enable */ | 756 | /* Set duplex mode */ |
694 | lp->mcr0 |= lp->phy_mode; | 757 | lp->mcr0 |= lp->phy_mode; |
695 | iowrite16(lp->mcr0, ioaddr); | ||
696 | |||
697 | /* set interrupt waiting time and packet numbers */ | ||
698 | iowrite16(0x0F06, ioaddr + MT_ICR); | ||
699 | iowrite16(0x0F06, ioaddr + MR_ICR); | ||
700 | 758 | ||
701 | /* improve performance (by RDC guys) */ | 759 | /* improve performance (by RDC guys) */ |
702 | phy_write(ioaddr, 30, 17, (phy_read(ioaddr, 30, 17) | 0x4000)); | 760 | r6040_phy_write(ioaddr, 30, 17, (r6040_phy_read(ioaddr, 30, 17) | 0x4000)); |
703 | phy_write(ioaddr, 30, 17, ~((~phy_read(ioaddr, 30, 17)) | 0x2000)); | 761 | r6040_phy_write(ioaddr, 30, 17, ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000)); |
704 | phy_write(ioaddr, 0, 19, 0x0000); | 762 | r6040_phy_write(ioaddr, 0, 19, 0x0000); |
705 | phy_write(ioaddr, 0, 30, 0x01F0); | 763 | r6040_phy_write(ioaddr, 0, 30, 0x01F0); |
706 | 764 | ||
707 | /* Interrupt Mask Register */ | 765 | /* Initialize all MAC registers */ |
708 | iowrite16(INT_MASK, ioaddr + MIER); | 766 | r6040_init_mac_regs(dev); |
767 | |||
768 | return 0; | ||
709 | } | 769 | } |
710 | 770 | ||
711 | /* | 771 | /* |
@@ -721,7 +781,7 @@ static void r6040_timer(unsigned long data) | |||
721 | 781 | ||
722 | /* Polling PHY Chip Status */ | 782 | /* Polling PHY Chip Status */ |
723 | if (PHY_MODE == 0x3100) | 783 | if (PHY_MODE == 0x3100) |
724 | phy_mode = phy_mode_chk(dev); | 784 | phy_mode = r6040_phy_mode_chk(dev); |
725 | else | 785 | else |
726 | phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0; | 786 | phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0; |
727 | 787 | ||
@@ -784,7 +844,14 @@ static int r6040_open(struct net_device *dev) | |||
784 | return -ENOMEM; | 844 | return -ENOMEM; |
785 | } | 845 | } |
786 | 846 | ||
787 | r6040_up(dev); | 847 | ret = r6040_up(dev); |
848 | if (ret) { | ||
849 | pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring, | ||
850 | lp->tx_ring_dma); | ||
851 | pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring, | ||
852 | lp->rx_ring_dma); | ||
853 | return ret; | ||
854 | } | ||
788 | 855 | ||
789 | napi_enable(&lp->napi); | 856 | napi_enable(&lp->napi); |
790 | netif_start_queue(dev); | 857 | netif_start_queue(dev); |
@@ -830,7 +897,7 @@ static int r6040_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
830 | descptr->skb_ptr = skb; | 897 | descptr->skb_ptr = skb; |
831 | descptr->buf = cpu_to_le32(pci_map_single(lp->pdev, | 898 | descptr->buf = cpu_to_le32(pci_map_single(lp->pdev, |
832 | skb->data, skb->len, PCI_DMA_TODEVICE)); | 899 | skb->data, skb->len, PCI_DMA_TODEVICE)); |
833 | descptr->status = 0x8000; | 900 | descptr->status = DSC_OWNER_MAC; |
834 | /* Trigger the MAC to check the TX descriptor */ | 901 | /* Trigger the MAC to check the TX descriptor */ |
835 | iowrite16(0x01, ioaddr + MTPR); | 902 | iowrite16(0x01, ioaddr + MTPR); |
836 | lp->tx_insert_ptr = descptr->vndescp; | 903 | lp->tx_insert_ptr = descptr->vndescp; |
@@ -987,24 +1054,27 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, | |||
987 | 1054 | ||
988 | err = pci_enable_device(pdev); | 1055 | err = pci_enable_device(pdev); |
989 | if (err) | 1056 | if (err) |
990 | return err; | 1057 | goto err_out; |
991 | 1058 | ||
992 | /* this should always be supported */ | 1059 | /* this should always be supported */ |
993 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | 1060 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
1061 | if (err) { | ||
994 | printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses" | 1062 | printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses" |
995 | "not supported by the card\n"); | 1063 | "not supported by the card\n"); |
996 | return -ENODEV; | 1064 | goto err_out; |
997 | } | 1065 | } |
998 | if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { | 1066 | err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); |
1067 | if (err) { | ||
999 | printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses" | 1068 | printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses" |
1000 | "not supported by the card\n"); | 1069 | "not supported by the card\n"); |
1001 | return -ENODEV; | 1070 | goto err_out; |
1002 | } | 1071 | } |
1003 | 1072 | ||
1004 | /* IO Size check */ | 1073 | /* IO Size check */ |
1005 | if (pci_resource_len(pdev, 0) < io_size) { | 1074 | if (pci_resource_len(pdev, 0) < io_size) { |
1006 | printk(KERN_ERR "Insufficient PCI resources, aborting\n"); | 1075 | printk(KERN_ERR DRV_NAME "Insufficient PCI resources, aborting\n"); |
1007 | return -EIO; | 1076 | err = -EIO; |
1077 | goto err_out; | ||
1008 | } | 1078 | } |
1009 | 1079 | ||
1010 | pioaddr = pci_resource_start(pdev, 0); /* IO map base address */ | 1080 | pioaddr = pci_resource_start(pdev, 0); /* IO map base address */ |
@@ -1012,24 +1082,26 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, | |||
1012 | 1082 | ||
1013 | dev = alloc_etherdev(sizeof(struct r6040_private)); | 1083 | dev = alloc_etherdev(sizeof(struct r6040_private)); |
1014 | if (!dev) { | 1084 | if (!dev) { |
1015 | printk(KERN_ERR "Failed to allocate etherdev\n"); | 1085 | printk(KERN_ERR DRV_NAME "Failed to allocate etherdev\n"); |
1016 | return -ENOMEM; | 1086 | err = -ENOMEM; |
1087 | goto err_out; | ||
1017 | } | 1088 | } |
1018 | SET_NETDEV_DEV(dev, &pdev->dev); | 1089 | SET_NETDEV_DEV(dev, &pdev->dev); |
1019 | lp = netdev_priv(dev); | 1090 | lp = netdev_priv(dev); |
1020 | lp->pdev = pdev; | ||
1021 | 1091 | ||
1022 | if (pci_request_regions(pdev, DRV_NAME)) { | 1092 | err = pci_request_regions(pdev, DRV_NAME); |
1093 | |||
1094 | if (err) { | ||
1023 | printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n"); | 1095 | printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n"); |
1024 | err = -ENODEV; | 1096 | goto err_out_free_dev; |
1025 | goto err_out_disable; | ||
1026 | } | 1097 | } |
1027 | 1098 | ||
1028 | ioaddr = pci_iomap(pdev, bar, io_size); | 1099 | ioaddr = pci_iomap(pdev, bar, io_size); |
1029 | if (!ioaddr) { | 1100 | if (!ioaddr) { |
1030 | printk(KERN_ERR "ioremap failed for device %s\n", | 1101 | printk(KERN_ERR "ioremap failed for device %s\n", |
1031 | pci_name(pdev)); | 1102 | pci_name(pdev)); |
1032 | return -EIO; | 1103 | err = -EIO; |
1104 | goto err_out_free_res; | ||
1033 | } | 1105 | } |
1034 | 1106 | ||
1035 | /* Init system & device */ | 1107 | /* Init system & device */ |
@@ -1049,6 +1121,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, | |||
1049 | 1121 | ||
1050 | /* Link new device into r6040_root_dev */ | 1122 | /* Link new device into r6040_root_dev */ |
1051 | lp->pdev = pdev; | 1123 | lp->pdev = pdev; |
1124 | lp->dev = dev; | ||
1052 | 1125 | ||
1053 | /* Init RDC private data */ | 1126 | /* Init RDC private data */ |
1054 | lp->mcr0 = 0x1002; | 1127 | lp->mcr0 = 0x1002; |
@@ -1070,8 +1143,8 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, | |||
1070 | #endif | 1143 | #endif |
1071 | netif_napi_add(dev, &lp->napi, r6040_poll, 64); | 1144 | netif_napi_add(dev, &lp->napi, r6040_poll, 64); |
1072 | lp->mii_if.dev = dev; | 1145 | lp->mii_if.dev = dev; |
1073 | lp->mii_if.mdio_read = mdio_read; | 1146 | lp->mii_if.mdio_read = r6040_mdio_read; |
1074 | lp->mii_if.mdio_write = mdio_write; | 1147 | lp->mii_if.mdio_write = r6040_mdio_write; |
1075 | lp->mii_if.phy_id = lp->phy_addr; | 1148 | lp->mii_if.phy_id = lp->phy_addr; |
1076 | lp->mii_if.phy_id_mask = 0x1f; | 1149 | lp->mii_if.phy_id_mask = 0x1f; |
1077 | lp->mii_if.reg_num_mask = 0x1f; | 1150 | lp->mii_if.reg_num_mask = 0x1f; |
@@ -1080,17 +1153,17 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, | |||
1080 | err = register_netdev(dev); | 1153 | err = register_netdev(dev); |
1081 | if (err) { | 1154 | if (err) { |
1082 | printk(KERN_ERR DRV_NAME ": Failed to register net device\n"); | 1155 | printk(KERN_ERR DRV_NAME ": Failed to register net device\n"); |
1083 | goto err_out_res; | 1156 | goto err_out_unmap; |
1084 | } | 1157 | } |
1085 | return 0; | 1158 | return 0; |
1086 | 1159 | ||
1087 | err_out_res: | 1160 | err_out_unmap: |
1161 | pci_iounmap(pdev, ioaddr); | ||
1162 | err_out_free_res: | ||
1088 | pci_release_regions(pdev); | 1163 | pci_release_regions(pdev); |
1089 | err_out_disable: | 1164 | err_out_free_dev: |
1090 | pci_disable_device(pdev); | ||
1091 | pci_set_drvdata(pdev, NULL); | ||
1092 | free_netdev(dev); | 1165 | free_netdev(dev); |
1093 | 1166 | err_out: | |
1094 | return err; | 1167 | return err; |
1095 | } | 1168 | } |
1096 | 1169 | ||