diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/fec.c | 125 | ||||
-rw-r--r-- | drivers/net/fec.h | 4 | ||||
-rw-r--r-- | drivers/net/fec_mpc52xx.c | 97 | ||||
-rw-r--r-- | drivers/net/fec_mpc52xx.h | 19 | ||||
-rw-r--r-- | drivers/net/mlx4/mr.c | 2 | ||||
-rw-r--r-- | drivers/net/usb/asix.c | 4 | ||||
-rw-r--r-- | drivers/net/virtio_net.c | 96 | ||||
-rw-r--r-- | drivers/net/wireless/strip.c | 2 |
8 files changed, 207 insertions, 142 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index d7a3ea88eddb..32a4f17d35fc 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c | |||
@@ -67,6 +67,10 @@ | |||
67 | #define FEC_MAX_PORTS 1 | 67 | #define FEC_MAX_PORTS 1 |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | #if defined(CONFIG_FADS) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_M5272) | ||
71 | #define HAVE_mii_link_interrupt | ||
72 | #endif | ||
73 | |||
70 | /* | 74 | /* |
71 | * Define the fixed address of the FEC hardware. | 75 | * Define the fixed address of the FEC hardware. |
72 | */ | 76 | */ |
@@ -205,7 +209,10 @@ struct fec_enet_private { | |||
205 | cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ | 209 | cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ |
206 | cbd_t *dirty_tx; /* The ring entries to be free()ed. */ | 210 | cbd_t *dirty_tx; /* The ring entries to be free()ed. */ |
207 | uint tx_full; | 211 | uint tx_full; |
208 | spinlock_t lock; | 212 | /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ |
213 | spinlock_t hw_lock; | ||
214 | /* hold while accessing the mii_list_t() elements */ | ||
215 | spinlock_t mii_lock; | ||
209 | 216 | ||
210 | uint phy_id; | 217 | uint phy_id; |
211 | uint phy_id_done; | 218 | uint phy_id_done; |
@@ -309,6 +316,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
309 | volatile fec_t *fecp; | 316 | volatile fec_t *fecp; |
310 | volatile cbd_t *bdp; | 317 | volatile cbd_t *bdp; |
311 | unsigned short status; | 318 | unsigned short status; |
319 | unsigned long flags; | ||
312 | 320 | ||
313 | fep = netdev_priv(dev); | 321 | fep = netdev_priv(dev); |
314 | fecp = (volatile fec_t*)dev->base_addr; | 322 | fecp = (volatile fec_t*)dev->base_addr; |
@@ -318,6 +326,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
318 | return 1; | 326 | return 1; |
319 | } | 327 | } |
320 | 328 | ||
329 | spin_lock_irqsave(&fep->hw_lock, flags); | ||
321 | /* Fill in a Tx ring entry */ | 330 | /* Fill in a Tx ring entry */ |
322 | bdp = fep->cur_tx; | 331 | bdp = fep->cur_tx; |
323 | 332 | ||
@@ -328,6 +337,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
328 | * This should not happen, since dev->tbusy should be set. | 337 | * This should not happen, since dev->tbusy should be set. |
329 | */ | 338 | */ |
330 | printk("%s: tx queue full!.\n", dev->name); | 339 | printk("%s: tx queue full!.\n", dev->name); |
340 | spin_unlock_irqrestore(&fep->hw_lock, flags); | ||
331 | return 1; | 341 | return 1; |
332 | } | 342 | } |
333 | #endif | 343 | #endif |
@@ -366,8 +376,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
366 | flush_dcache_range((unsigned long)skb->data, | 376 | flush_dcache_range((unsigned long)skb->data, |
367 | (unsigned long)skb->data + skb->len); | 377 | (unsigned long)skb->data + skb->len); |
368 | 378 | ||
369 | spin_lock_irq(&fep->lock); | ||
370 | |||
371 | /* Send it on its way. Tell FEC it's ready, interrupt when done, | 379 | /* Send it on its way. Tell FEC it's ready, interrupt when done, |
372 | * it's the last BD of the frame, and to put the CRC on the end. | 380 | * it's the last BD of the frame, and to put the CRC on the end. |
373 | */ | 381 | */ |
@@ -396,7 +404,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
396 | 404 | ||
397 | fep->cur_tx = (cbd_t *)bdp; | 405 | fep->cur_tx = (cbd_t *)bdp; |
398 | 406 | ||
399 | spin_unlock_irq(&fep->lock); | 407 | spin_unlock_irqrestore(&fep->hw_lock, flags); |
400 | 408 | ||
401 | return 0; | 409 | return 0; |
402 | } | 410 | } |
@@ -454,19 +462,20 @@ fec_enet_interrupt(int irq, void * dev_id) | |||
454 | struct net_device *dev = dev_id; | 462 | struct net_device *dev = dev_id; |
455 | volatile fec_t *fecp; | 463 | volatile fec_t *fecp; |
456 | uint int_events; | 464 | uint int_events; |
457 | int handled = 0; | 465 | irqreturn_t ret = IRQ_NONE; |
458 | 466 | ||
459 | fecp = (volatile fec_t*)dev->base_addr; | 467 | fecp = (volatile fec_t*)dev->base_addr; |
460 | 468 | ||
461 | /* Get the interrupt events that caused us to be here. | 469 | /* Get the interrupt events that caused us to be here. |
462 | */ | 470 | */ |
463 | while ((int_events = fecp->fec_ievent) != 0) { | 471 | do { |
472 | int_events = fecp->fec_ievent; | ||
464 | fecp->fec_ievent = int_events; | 473 | fecp->fec_ievent = int_events; |
465 | 474 | ||
466 | /* Handle receive event in its own function. | 475 | /* Handle receive event in its own function. |
467 | */ | 476 | */ |
468 | if (int_events & FEC_ENET_RXF) { | 477 | if (int_events & FEC_ENET_RXF) { |
469 | handled = 1; | 478 | ret = IRQ_HANDLED; |
470 | fec_enet_rx(dev); | 479 | fec_enet_rx(dev); |
471 | } | 480 | } |
472 | 481 | ||
@@ -475,17 +484,18 @@ fec_enet_interrupt(int irq, void * dev_id) | |||
475 | them as part of the transmit process. | 484 | them as part of the transmit process. |
476 | */ | 485 | */ |
477 | if (int_events & FEC_ENET_TXF) { | 486 | if (int_events & FEC_ENET_TXF) { |
478 | handled = 1; | 487 | ret = IRQ_HANDLED; |
479 | fec_enet_tx(dev); | 488 | fec_enet_tx(dev); |
480 | } | 489 | } |
481 | 490 | ||
482 | if (int_events & FEC_ENET_MII) { | 491 | if (int_events & FEC_ENET_MII) { |
483 | handled = 1; | 492 | ret = IRQ_HANDLED; |
484 | fec_enet_mii(dev); | 493 | fec_enet_mii(dev); |
485 | } | 494 | } |
486 | 495 | ||
487 | } | 496 | } while (int_events); |
488 | return IRQ_RETVAL(handled); | 497 | |
498 | return ret; | ||
489 | } | 499 | } |
490 | 500 | ||
491 | 501 | ||
@@ -498,7 +508,7 @@ fec_enet_tx(struct net_device *dev) | |||
498 | struct sk_buff *skb; | 508 | struct sk_buff *skb; |
499 | 509 | ||
500 | fep = netdev_priv(dev); | 510 | fep = netdev_priv(dev); |
501 | spin_lock(&fep->lock); | 511 | spin_lock_irq(&fep->hw_lock); |
502 | bdp = fep->dirty_tx; | 512 | bdp = fep->dirty_tx; |
503 | 513 | ||
504 | while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { | 514 | while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { |
@@ -557,7 +567,7 @@ fec_enet_tx(struct net_device *dev) | |||
557 | } | 567 | } |
558 | } | 568 | } |
559 | fep->dirty_tx = (cbd_t *)bdp; | 569 | fep->dirty_tx = (cbd_t *)bdp; |
560 | spin_unlock(&fep->lock); | 570 | spin_unlock_irq(&fep->hw_lock); |
561 | } | 571 | } |
562 | 572 | ||
563 | 573 | ||
@@ -584,6 +594,8 @@ fec_enet_rx(struct net_device *dev) | |||
584 | fep = netdev_priv(dev); | 594 | fep = netdev_priv(dev); |
585 | fecp = (volatile fec_t*)dev->base_addr; | 595 | fecp = (volatile fec_t*)dev->base_addr; |
586 | 596 | ||
597 | spin_lock_irq(&fep->hw_lock); | ||
598 | |||
587 | /* First, grab all of the stats for the incoming packet. | 599 | /* First, grab all of the stats for the incoming packet. |
588 | * These get messed up if we get called due to a busy condition. | 600 | * These get messed up if we get called due to a busy condition. |
589 | */ | 601 | */ |
@@ -689,6 +701,8 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { | |||
689 | */ | 701 | */ |
690 | fecp->fec_r_des_active = 0; | 702 | fecp->fec_r_des_active = 0; |
691 | #endif | 703 | #endif |
704 | |||
705 | spin_unlock_irq(&fep->hw_lock); | ||
692 | } | 706 | } |
693 | 707 | ||
694 | 708 | ||
@@ -702,11 +716,11 @@ fec_enet_mii(struct net_device *dev) | |||
702 | uint mii_reg; | 716 | uint mii_reg; |
703 | 717 | ||
704 | fep = netdev_priv(dev); | 718 | fep = netdev_priv(dev); |
719 | spin_lock_irq(&fep->mii_lock); | ||
720 | |||
705 | ep = fep->hwp; | 721 | ep = fep->hwp; |
706 | mii_reg = ep->fec_mii_data; | 722 | mii_reg = ep->fec_mii_data; |
707 | 723 | ||
708 | spin_lock(&fep->lock); | ||
709 | |||
710 | if ((mip = mii_head) == NULL) { | 724 | if ((mip = mii_head) == NULL) { |
711 | printk("MII and no head!\n"); | 725 | printk("MII and no head!\n"); |
712 | goto unlock; | 726 | goto unlock; |
@@ -723,7 +737,7 @@ fec_enet_mii(struct net_device *dev) | |||
723 | ep->fec_mii_data = mip->mii_regval; | 737 | ep->fec_mii_data = mip->mii_regval; |
724 | 738 | ||
725 | unlock: | 739 | unlock: |
726 | spin_unlock(&fep->lock); | 740 | spin_unlock_irq(&fep->mii_lock); |
727 | } | 741 | } |
728 | 742 | ||
729 | static int | 743 | static int |
@@ -737,12 +751,11 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi | |||
737 | /* Add PHY address to register command. | 751 | /* Add PHY address to register command. |
738 | */ | 752 | */ |
739 | fep = netdev_priv(dev); | 753 | fep = netdev_priv(dev); |
740 | regval |= fep->phy_addr << 23; | 754 | spin_lock_irqsave(&fep->mii_lock, flags); |
741 | 755 | ||
756 | regval |= fep->phy_addr << 23; | ||
742 | retval = 0; | 757 | retval = 0; |
743 | 758 | ||
744 | spin_lock_irqsave(&fep->lock,flags); | ||
745 | |||
746 | if ((mip = mii_free) != NULL) { | 759 | if ((mip = mii_free) != NULL) { |
747 | mii_free = mip->mii_next; | 760 | mii_free = mip->mii_next; |
748 | mip->mii_regval = regval; | 761 | mip->mii_regval = regval; |
@@ -759,9 +772,8 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi | |||
759 | retval = 1; | 772 | retval = 1; |
760 | } | 773 | } |
761 | 774 | ||
762 | spin_unlock_irqrestore(&fep->lock,flags); | 775 | spin_unlock_irqrestore(&fep->mii_lock, flags); |
763 | 776 | return retval; | |
764 | return(retval); | ||
765 | } | 777 | } |
766 | 778 | ||
767 | static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c) | 779 | static void mii_do_cmd(struct net_device *dev, const phy_cmd_t *c) |
@@ -1222,7 +1234,7 @@ static phy_info_t const * const phy_info[] = { | |||
1222 | }; | 1234 | }; |
1223 | 1235 | ||
1224 | /* ------------------------------------------------------------------------- */ | 1236 | /* ------------------------------------------------------------------------- */ |
1225 | #if !defined(CONFIG_M532x) | 1237 | #ifdef HAVE_mii_link_interrupt |
1226 | #ifdef CONFIG_RPXCLASSIC | 1238 | #ifdef CONFIG_RPXCLASSIC |
1227 | static void | 1239 | static void |
1228 | mii_link_interrupt(void *dev_id); | 1240 | mii_link_interrupt(void *dev_id); |
@@ -1362,18 +1374,8 @@ static void __inline__ fec_request_intrs(struct net_device *dev) | |||
1362 | unsigned short irq; | 1374 | unsigned short irq; |
1363 | } *idp, id[] = { | 1375 | } *idp, id[] = { |
1364 | { "fec(TXF)", 23 }, | 1376 | { "fec(TXF)", 23 }, |
1365 | { "fec(TXB)", 24 }, | ||
1366 | { "fec(TXFIFO)", 25 }, | ||
1367 | { "fec(TXCR)", 26 }, | ||
1368 | { "fec(RXF)", 27 }, | 1377 | { "fec(RXF)", 27 }, |
1369 | { "fec(RXB)", 28 }, | ||
1370 | { "fec(MII)", 29 }, | 1378 | { "fec(MII)", 29 }, |
1371 | { "fec(LC)", 30 }, | ||
1372 | { "fec(HBERR)", 31 }, | ||
1373 | { "fec(GRA)", 32 }, | ||
1374 | { "fec(EBERR)", 33 }, | ||
1375 | { "fec(BABT)", 34 }, | ||
1376 | { "fec(BABR)", 35 }, | ||
1377 | { NULL }, | 1379 | { NULL }, |
1378 | }; | 1380 | }; |
1379 | 1381 | ||
@@ -1533,18 +1535,8 @@ static void __inline__ fec_request_intrs(struct net_device *dev) | |||
1533 | unsigned short irq; | 1535 | unsigned short irq; |
1534 | } *idp, id[] = { | 1536 | } *idp, id[] = { |
1535 | { "fec(TXF)", 23 }, | 1537 | { "fec(TXF)", 23 }, |
1536 | { "fec(TXB)", 24 }, | ||
1537 | { "fec(TXFIFO)", 25 }, | ||
1538 | { "fec(TXCR)", 26 }, | ||
1539 | { "fec(RXF)", 27 }, | 1538 | { "fec(RXF)", 27 }, |
1540 | { "fec(RXB)", 28 }, | ||
1541 | { "fec(MII)", 29 }, | 1539 | { "fec(MII)", 29 }, |
1542 | { "fec(LC)", 30 }, | ||
1543 | { "fec(HBERR)", 31 }, | ||
1544 | { "fec(GRA)", 32 }, | ||
1545 | { "fec(EBERR)", 33 }, | ||
1546 | { "fec(BABT)", 34 }, | ||
1547 | { "fec(BABR)", 35 }, | ||
1548 | { NULL }, | 1540 | { NULL }, |
1549 | }; | 1541 | }; |
1550 | 1542 | ||
@@ -1660,18 +1652,8 @@ static void __inline__ fec_request_intrs(struct net_device *dev) | |||
1660 | unsigned short irq; | 1652 | unsigned short irq; |
1661 | } *idp, id[] = { | 1653 | } *idp, id[] = { |
1662 | { "fec(TXF)", 36 }, | 1654 | { "fec(TXF)", 36 }, |
1663 | { "fec(TXB)", 37 }, | ||
1664 | { "fec(TXFIFO)", 38 }, | ||
1665 | { "fec(TXCR)", 39 }, | ||
1666 | { "fec(RXF)", 40 }, | 1655 | { "fec(RXF)", 40 }, |
1667 | { "fec(RXB)", 41 }, | ||
1668 | { "fec(MII)", 42 }, | 1656 | { "fec(MII)", 42 }, |
1669 | { "fec(LC)", 43 }, | ||
1670 | { "fec(HBERR)", 44 }, | ||
1671 | { "fec(GRA)", 45 }, | ||
1672 | { "fec(EBERR)", 46 }, | ||
1673 | { "fec(BABT)", 47 }, | ||
1674 | { "fec(BABR)", 48 }, | ||
1675 | { NULL }, | 1657 | { NULL }, |
1676 | }; | 1658 | }; |
1677 | 1659 | ||
@@ -2126,6 +2108,7 @@ mii_discover_phy(uint mii_reg, struct net_device *dev) | |||
2126 | 2108 | ||
2127 | /* This interrupt occurs when the PHY detects a link change. | 2109 | /* This interrupt occurs when the PHY detects a link change. |
2128 | */ | 2110 | */ |
2111 | #ifdef HAVE_mii_link_interrupt | ||
2129 | #ifdef CONFIG_RPXCLASSIC | 2112 | #ifdef CONFIG_RPXCLASSIC |
2130 | static void | 2113 | static void |
2131 | mii_link_interrupt(void *dev_id) | 2114 | mii_link_interrupt(void *dev_id) |
@@ -2148,6 +2131,7 @@ mii_link_interrupt(int irq, void * dev_id) | |||
2148 | 2131 | ||
2149 | return IRQ_HANDLED; | 2132 | return IRQ_HANDLED; |
2150 | } | 2133 | } |
2134 | #endif | ||
2151 | 2135 | ||
2152 | static int | 2136 | static int |
2153 | fec_enet_open(struct net_device *dev) | 2137 | fec_enet_open(struct net_device *dev) |
@@ -2243,13 +2227,13 @@ static void set_multicast_list(struct net_device *dev) | |||
2243 | /* Catch all multicast addresses, so set the | 2227 | /* Catch all multicast addresses, so set the |
2244 | * filter to all 1's. | 2228 | * filter to all 1's. |
2245 | */ | 2229 | */ |
2246 | ep->fec_hash_table_high = 0xffffffff; | 2230 | ep->fec_grp_hash_table_high = 0xffffffff; |
2247 | ep->fec_hash_table_low = 0xffffffff; | 2231 | ep->fec_grp_hash_table_low = 0xffffffff; |
2248 | } else { | 2232 | } else { |
2249 | /* Clear filter and add the addresses in hash register. | 2233 | /* Clear filter and add the addresses in hash register. |
2250 | */ | 2234 | */ |
2251 | ep->fec_hash_table_high = 0; | 2235 | ep->fec_grp_hash_table_high = 0; |
2252 | ep->fec_hash_table_low = 0; | 2236 | ep->fec_grp_hash_table_low = 0; |
2253 | 2237 | ||
2254 | dmi = dev->mc_list; | 2238 | dmi = dev->mc_list; |
2255 | 2239 | ||
@@ -2280,9 +2264,9 @@ static void set_multicast_list(struct net_device *dev) | |||
2280 | hash = (crc >> (32 - HASH_BITS)) & 0x3f; | 2264 | hash = (crc >> (32 - HASH_BITS)) & 0x3f; |
2281 | 2265 | ||
2282 | if (hash > 31) | 2266 | if (hash > 31) |
2283 | ep->fec_hash_table_high |= 1 << (hash - 32); | 2267 | ep->fec_grp_hash_table_high |= 1 << (hash - 32); |
2284 | else | 2268 | else |
2285 | ep->fec_hash_table_low |= 1 << hash; | 2269 | ep->fec_grp_hash_table_low |= 1 << hash; |
2286 | } | 2270 | } |
2287 | } | 2271 | } |
2288 | } | 2272 | } |
@@ -2332,6 +2316,9 @@ int __init fec_enet_init(struct net_device *dev) | |||
2332 | return -ENOMEM; | 2316 | return -ENOMEM; |
2333 | } | 2317 | } |
2334 | 2318 | ||
2319 | spin_lock_init(&fep->hw_lock); | ||
2320 | spin_lock_init(&fep->mii_lock); | ||
2321 | |||
2335 | /* Create an Ethernet device instance. | 2322 | /* Create an Ethernet device instance. |
2336 | */ | 2323 | */ |
2337 | fecp = (volatile fec_t *) fec_hw[index]; | 2324 | fecp = (volatile fec_t *) fec_hw[index]; |
@@ -2430,11 +2417,15 @@ int __init fec_enet_init(struct net_device *dev) | |||
2430 | */ | 2417 | */ |
2431 | fec_request_intrs(dev); | 2418 | fec_request_intrs(dev); |
2432 | 2419 | ||
2433 | fecp->fec_hash_table_high = 0; | 2420 | fecp->fec_grp_hash_table_high = 0; |
2434 | fecp->fec_hash_table_low = 0; | 2421 | fecp->fec_grp_hash_table_low = 0; |
2435 | fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; | 2422 | fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; |
2436 | fecp->fec_ecntrl = 2; | 2423 | fecp->fec_ecntrl = 2; |
2437 | fecp->fec_r_des_active = 0; | 2424 | fecp->fec_r_des_active = 0; |
2425 | #ifndef CONFIG_M5272 | ||
2426 | fecp->fec_hash_table_high = 0; | ||
2427 | fecp->fec_hash_table_low = 0; | ||
2428 | #endif | ||
2438 | 2429 | ||
2439 | dev->base_addr = (unsigned long)fecp; | 2430 | dev->base_addr = (unsigned long)fecp; |
2440 | 2431 | ||
@@ -2455,8 +2446,7 @@ int __init fec_enet_init(struct net_device *dev) | |||
2455 | 2446 | ||
2456 | /* Clear and enable interrupts */ | 2447 | /* Clear and enable interrupts */ |
2457 | fecp->fec_ievent = 0xffc00000; | 2448 | fecp->fec_ievent = 0xffc00000; |
2458 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | 2449 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); |
2459 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
2460 | 2450 | ||
2461 | /* Queue up command to detect the PHY and initialize the | 2451 | /* Queue up command to detect the PHY and initialize the |
2462 | * remainder of the interface. | 2452 | * remainder of the interface. |
@@ -2500,8 +2490,8 @@ fec_restart(struct net_device *dev, int duplex) | |||
2500 | 2490 | ||
2501 | /* Reset all multicast. | 2491 | /* Reset all multicast. |
2502 | */ | 2492 | */ |
2503 | fecp->fec_hash_table_high = 0; | 2493 | fecp->fec_grp_hash_table_high = 0; |
2504 | fecp->fec_hash_table_low = 0; | 2494 | fecp->fec_grp_hash_table_low = 0; |
2505 | 2495 | ||
2506 | /* Set maximum receive buffer size. | 2496 | /* Set maximum receive buffer size. |
2507 | */ | 2497 | */ |
@@ -2583,8 +2573,7 @@ fec_restart(struct net_device *dev, int duplex) | |||
2583 | 2573 | ||
2584 | /* Enable interrupts we wish to service. | 2574 | /* Enable interrupts we wish to service. |
2585 | */ | 2575 | */ |
2586 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | | 2576 | fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); |
2587 | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); | ||
2588 | } | 2577 | } |
2589 | 2578 | ||
2590 | static void | 2579 | static void |
@@ -2624,7 +2613,7 @@ fec_stop(struct net_device *dev) | |||
2624 | static int __init fec_enet_module_init(void) | 2613 | static int __init fec_enet_module_init(void) |
2625 | { | 2614 | { |
2626 | struct net_device *dev; | 2615 | struct net_device *dev; |
2627 | int i, j, err; | 2616 | int i, err; |
2628 | DECLARE_MAC_BUF(mac); | 2617 | DECLARE_MAC_BUF(mac); |
2629 | 2618 | ||
2630 | printk("FEC ENET Version 0.2\n"); | 2619 | printk("FEC ENET Version 0.2\n"); |
diff --git a/drivers/net/fec.h b/drivers/net/fec.h index 1d421606984f..292719daceff 100644 --- a/drivers/net/fec.h +++ b/drivers/net/fec.h | |||
@@ -88,8 +88,8 @@ typedef struct fec { | |||
88 | unsigned long fec_reserved7[158]; | 88 | unsigned long fec_reserved7[158]; |
89 | unsigned long fec_addr_low; /* Low 32bits MAC address */ | 89 | unsigned long fec_addr_low; /* Low 32bits MAC address */ |
90 | unsigned long fec_addr_high; /* High 16bits MAC address */ | 90 | unsigned long fec_addr_high; /* High 16bits MAC address */ |
91 | unsigned long fec_hash_table_high; /* High 32bits hash table */ | 91 | unsigned long fec_grp_hash_table_high;/* High 32bits hash table */ |
92 | unsigned long fec_hash_table_low; /* Low 32bits hash table */ | 92 | unsigned long fec_grp_hash_table_low; /* Low 32bits hash table */ |
93 | unsigned long fec_r_des_start; /* Receive descriptor ring */ | 93 | unsigned long fec_r_des_start; /* Receive descriptor ring */ |
94 | unsigned long fec_x_des_start; /* Transmit descriptor ring */ | 94 | unsigned long fec_x_des_start; /* Transmit descriptor ring */ |
95 | unsigned long fec_r_buff_size; /* Maximum receive buff size */ | 95 | unsigned long fec_r_buff_size; /* Maximum receive buff size */ |
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index d21b7ab64bd1..5f9c42e7a7f1 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c | |||
@@ -43,6 +43,29 @@ | |||
43 | 43 | ||
44 | #define DRIVER_NAME "mpc52xx-fec" | 44 | #define DRIVER_NAME "mpc52xx-fec" |
45 | 45 | ||
46 | #define FEC5200_PHYADDR_NONE (-1) | ||
47 | #define FEC5200_PHYADDR_7WIRE (-2) | ||
48 | |||
49 | /* Private driver data structure */ | ||
50 | struct mpc52xx_fec_priv { | ||
51 | int duplex; | ||
52 | int speed; | ||
53 | int r_irq; | ||
54 | int t_irq; | ||
55 | struct mpc52xx_fec __iomem *fec; | ||
56 | struct bcom_task *rx_dmatsk; | ||
57 | struct bcom_task *tx_dmatsk; | ||
58 | spinlock_t lock; | ||
59 | int msg_enable; | ||
60 | |||
61 | /* MDIO link details */ | ||
62 | int phy_addr; | ||
63 | unsigned int phy_speed; | ||
64 | struct phy_device *phydev; | ||
65 | enum phy_state link; | ||
66 | }; | ||
67 | |||
68 | |||
46 | static irqreturn_t mpc52xx_fec_interrupt(int, void *); | 69 | static irqreturn_t mpc52xx_fec_interrupt(int, void *); |
47 | static irqreturn_t mpc52xx_fec_rx_interrupt(int, void *); | 70 | static irqreturn_t mpc52xx_fec_rx_interrupt(int, void *); |
48 | static irqreturn_t mpc52xx_fec_tx_interrupt(int, void *); | 71 | static irqreturn_t mpc52xx_fec_tx_interrupt(int, void *); |
@@ -223,7 +246,7 @@ static int mpc52xx_fec_phy_start(struct net_device *dev) | |||
223 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); | 246 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); |
224 | int err; | 247 | int err; |
225 | 248 | ||
226 | if (!priv->has_phy) | 249 | if (priv->phy_addr < 0) |
227 | return 0; | 250 | return 0; |
228 | 251 | ||
229 | err = mpc52xx_fec_init_phy(dev); | 252 | err = mpc52xx_fec_init_phy(dev); |
@@ -243,7 +266,7 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev) | |||
243 | { | 266 | { |
244 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); | 267 | struct mpc52xx_fec_priv *priv = netdev_priv(dev); |
245 | 268 | ||
246 | if (!priv->has_phy) | 269 | if (!priv->phydev) |
247 | return; | 270 | return; |
248 | 271 | ||
249 | phy_disconnect(priv->phydev); | 272 | phy_disconnect(priv->phydev); |
@@ -255,7 +278,7 @@ static void mpc52xx_fec_phy_stop(struct net_device *dev) | |||
255 | static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv, | 278 | static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv, |
256 | struct mii_ioctl_data *mii_data, int cmd) | 279 | struct mii_ioctl_data *mii_data, int cmd) |
257 | { | 280 | { |
258 | if (!priv->has_phy) | 281 | if (!priv->phydev) |
259 | return -ENOTSUPP; | 282 | return -ENOTSUPP; |
260 | 283 | ||
261 | return phy_mii_ioctl(priv->phydev, mii_data, cmd); | 284 | return phy_mii_ioctl(priv->phydev, mii_data, cmd); |
@@ -265,7 +288,7 @@ static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv) | |||
265 | { | 288 | { |
266 | struct mpc52xx_fec __iomem *fec = priv->fec; | 289 | struct mpc52xx_fec __iomem *fec = priv->fec; |
267 | 290 | ||
268 | if (!priv->has_phy) | 291 | if (priv->phydev) |
269 | return; | 292 | return; |
270 | 293 | ||
271 | out_be32(&fec->mii_speed, priv->phy_speed); | 294 | out_be32(&fec->mii_speed, priv->phy_speed); |
@@ -704,7 +727,7 @@ static void mpc52xx_fec_start(struct net_device *dev) | |||
704 | rcntrl = FEC_RX_BUFFER_SIZE << 16; /* max frame length */ | 727 | rcntrl = FEC_RX_BUFFER_SIZE << 16; /* max frame length */ |
705 | rcntrl |= FEC_RCNTRL_FCE; | 728 | rcntrl |= FEC_RCNTRL_FCE; |
706 | 729 | ||
707 | if (priv->has_phy) | 730 | if (priv->phy_addr != FEC5200_PHYADDR_7WIRE) |
708 | rcntrl |= FEC_RCNTRL_MII_MODE; | 731 | rcntrl |= FEC_RCNTRL_MII_MODE; |
709 | 732 | ||
710 | if (priv->duplex == DUPLEX_FULL) | 733 | if (priv->duplex == DUPLEX_FULL) |
@@ -864,7 +887,10 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) | |||
864 | struct net_device *ndev; | 887 | struct net_device *ndev; |
865 | struct mpc52xx_fec_priv *priv = NULL; | 888 | struct mpc52xx_fec_priv *priv = NULL; |
866 | struct resource mem; | 889 | struct resource mem; |
867 | const phandle *ph; | 890 | struct device_node *phy_node; |
891 | const phandle *phy_handle; | ||
892 | const u32 *prop; | ||
893 | int prop_size; | ||
868 | 894 | ||
869 | phys_addr_t rx_fifo; | 895 | phys_addr_t rx_fifo; |
870 | phys_addr_t tx_fifo; | 896 | phys_addr_t tx_fifo; |
@@ -948,26 +974,37 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) | |||
948 | mpc52xx_fec_get_paddr(ndev, ndev->dev_addr); | 974 | mpc52xx_fec_get_paddr(ndev, ndev->dev_addr); |
949 | 975 | ||
950 | priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT); | 976 | priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT); |
951 | priv->duplex = DUPLEX_FULL; | ||
952 | |||
953 | /* is the phy present in device tree? */ | ||
954 | ph = of_get_property(op->node, "phy-handle", NULL); | ||
955 | if (ph) { | ||
956 | const unsigned int *prop; | ||
957 | struct device_node *phy_dn; | ||
958 | priv->has_phy = 1; | ||
959 | 977 | ||
960 | phy_dn = of_find_node_by_phandle(*ph); | 978 | /* |
961 | prop = of_get_property(phy_dn, "reg", NULL); | 979 | * Link mode configuration |
962 | priv->phy_addr = *prop; | 980 | */ |
963 | 981 | ||
964 | of_node_put(phy_dn); | 982 | /* Start with safe defaults for link connection */ |
983 | priv->phy_addr = FEC5200_PHYADDR_NONE; | ||
984 | priv->speed = 100; | ||
985 | priv->duplex = DUPLEX_HALF; | ||
986 | priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1; | ||
987 | |||
988 | /* the 7-wire property means don't use MII mode */ | ||
989 | if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) | ||
990 | priv->phy_addr = FEC5200_PHYADDR_7WIRE; | ||
991 | |||
992 | /* The current speed preconfigures the speed of the MII link */ | ||
993 | prop = of_get_property(op->node, "current-speed", &prop_size); | ||
994 | if (prop && (prop_size >= sizeof(u32) * 2)) { | ||
995 | priv->speed = prop[0]; | ||
996 | priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF; | ||
997 | } | ||
965 | 998 | ||
966 | /* Phy speed */ | 999 | /* If there is a phy handle, setup link to that phy */ |
967 | priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1; | 1000 | phy_handle = of_get_property(op->node, "phy-handle", &prop_size); |
968 | } else { | 1001 | if (phy_handle && (prop_size >= sizeof(phandle))) { |
969 | dev_info(&ndev->dev, "can't find \"phy-handle\" in device" | 1002 | phy_node = of_find_node_by_phandle(*phy_handle); |
970 | " tree, using 7-wire mode\n"); | 1003 | prop = of_get_property(phy_node, "reg", &prop_size); |
1004 | if (prop && (prop_size >= sizeof(u32))) | ||
1005 | if ((*prop >= 0) && (*prop < PHY_MAX_ADDR)) | ||
1006 | priv->phy_addr = *prop; | ||
1007 | of_node_put(phy_node); | ||
971 | } | 1008 | } |
972 | 1009 | ||
973 | /* Hardware init */ | 1010 | /* Hardware init */ |
@@ -982,6 +1019,20 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match) | |||
982 | if (rv < 0) | 1019 | if (rv < 0) |
983 | goto probe_error; | 1020 | goto probe_error; |
984 | 1021 | ||
1022 | /* Now report the link setup */ | ||
1023 | switch (priv->phy_addr) { | ||
1024 | case FEC5200_PHYADDR_NONE: | ||
1025 | dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n", | ||
1026 | priv->speed, priv->duplex ? 'F' : 'H'); | ||
1027 | break; | ||
1028 | case FEC5200_PHYADDR_7WIRE: | ||
1029 | dev_info(&ndev->dev, "using 7-wire PHY mode\n"); | ||
1030 | break; | ||
1031 | default: | ||
1032 | dev_info(&ndev->dev, "Using PHY at MDIO address %i\n", | ||
1033 | priv->phy_addr); | ||
1034 | } | ||
1035 | |||
985 | /* We're done ! */ | 1036 | /* We're done ! */ |
986 | dev_set_drvdata(&op->dev, ndev); | 1037 | dev_set_drvdata(&op->dev, ndev); |
987 | 1038 | ||
diff --git a/drivers/net/fec_mpc52xx.h b/drivers/net/fec_mpc52xx.h index 8b1f75397b9a..a227a525bdbb 100644 --- a/drivers/net/fec_mpc52xx.h +++ b/drivers/net/fec_mpc52xx.h | |||
@@ -26,25 +26,6 @@ | |||
26 | 26 | ||
27 | #define FEC_WATCHDOG_TIMEOUT ((400*HZ)/1000) | 27 | #define FEC_WATCHDOG_TIMEOUT ((400*HZ)/1000) |
28 | 28 | ||
29 | struct mpc52xx_fec_priv { | ||
30 | int duplex; | ||
31 | int r_irq; | ||
32 | int t_irq; | ||
33 | struct mpc52xx_fec __iomem *fec; | ||
34 | struct bcom_task *rx_dmatsk; | ||
35 | struct bcom_task *tx_dmatsk; | ||
36 | spinlock_t lock; | ||
37 | int msg_enable; | ||
38 | |||
39 | int has_phy; | ||
40 | unsigned int phy_speed; | ||
41 | unsigned int phy_addr; | ||
42 | struct phy_device *phydev; | ||
43 | enum phy_state link; | ||
44 | int speed; | ||
45 | }; | ||
46 | |||
47 | |||
48 | /* ======================================================================== */ | 29 | /* ======================================================================== */ |
49 | /* Hardware register sets & bits */ | 30 | /* Hardware register sets & bits */ |
50 | /* ======================================================================== */ | 31 | /* ======================================================================== */ |
diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index cb46446b2691..03a9abcce524 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c | |||
@@ -551,7 +551,7 @@ int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, | |||
551 | u64 mtt_seg; | 551 | u64 mtt_seg; |
552 | int err = -ENOMEM; | 552 | int err = -ENOMEM; |
553 | 553 | ||
554 | if (page_shift < 12 || page_shift >= 32) | 554 | if (page_shift < (ffs(dev->caps.page_size_cap) - 1) || page_shift >= 32) |
555 | return -EINVAL; | 555 | return -EINVAL; |
556 | 556 | ||
557 | /* All MTTs must fit in the same page */ | 557 | /* All MTTs must fit in the same page */ |
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6f245cfb6624..dc6f097062df 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -1381,6 +1381,10 @@ static const struct usb_device_id products [] = { | |||
1381 | USB_DEVICE (0x0411, 0x003d), | 1381 | USB_DEVICE (0x0411, 0x003d), |
1382 | .driver_info = (unsigned long) &ax8817x_info, | 1382 | .driver_info = (unsigned long) &ax8817x_info, |
1383 | }, { | 1383 | }, { |
1384 | // Buffalo LUA-U2-GT 10/100/1000 | ||
1385 | USB_DEVICE (0x0411, 0x006e), | ||
1386 | .driver_info = (unsigned long) &ax88178_info, | ||
1387 | }, { | ||
1384 | // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" | 1388 | // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" |
1385 | USB_DEVICE (0x6189, 0x182d), | 1389 | USB_DEVICE (0x6189, 0x182d), |
1386 | .driver_info = (unsigned long) &ax8817x_info, | 1390 | .driver_info = (unsigned long) &ax8817x_info, |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 555b70c8b863..f926b5ab3d09 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -41,6 +41,9 @@ struct virtnet_info | |||
41 | struct net_device *dev; | 41 | struct net_device *dev; |
42 | struct napi_struct napi; | 42 | struct napi_struct napi; |
43 | 43 | ||
44 | /* The skb we couldn't send because buffers were full. */ | ||
45 | struct sk_buff *last_xmit_skb; | ||
46 | |||
44 | /* Number of input buffers, and max we've ever had. */ | 47 | /* Number of input buffers, and max we've ever had. */ |
45 | unsigned int num, max; | 48 | unsigned int num, max; |
46 | 49 | ||
@@ -142,10 +145,10 @@ drop: | |||
142 | static void try_fill_recv(struct virtnet_info *vi) | 145 | static void try_fill_recv(struct virtnet_info *vi) |
143 | { | 146 | { |
144 | struct sk_buff *skb; | 147 | struct sk_buff *skb; |
145 | struct scatterlist sg[1+MAX_SKB_FRAGS]; | 148 | struct scatterlist sg[2+MAX_SKB_FRAGS]; |
146 | int num, err; | 149 | int num, err; |
147 | 150 | ||
148 | sg_init_table(sg, 1+MAX_SKB_FRAGS); | 151 | sg_init_table(sg, 2+MAX_SKB_FRAGS); |
149 | for (;;) { | 152 | for (;;) { |
150 | skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); | 153 | skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); |
151 | if (unlikely(!skb)) | 154 | if (unlikely(!skb)) |
@@ -221,23 +224,22 @@ static void free_old_xmit_skbs(struct virtnet_info *vi) | |||
221 | while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) { | 224 | while ((skb = vi->svq->vq_ops->get_buf(vi->svq, &len)) != NULL) { |
222 | pr_debug("Sent skb %p\n", skb); | 225 | pr_debug("Sent skb %p\n", skb); |
223 | __skb_unlink(skb, &vi->send); | 226 | __skb_unlink(skb, &vi->send); |
224 | vi->dev->stats.tx_bytes += len; | 227 | vi->dev->stats.tx_bytes += skb->len; |
225 | vi->dev->stats.tx_packets++; | 228 | vi->dev->stats.tx_packets++; |
226 | kfree_skb(skb); | 229 | kfree_skb(skb); |
227 | } | 230 | } |
228 | } | 231 | } |
229 | 232 | ||
230 | static int start_xmit(struct sk_buff *skb, struct net_device *dev) | 233 | static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) |
231 | { | 234 | { |
232 | struct virtnet_info *vi = netdev_priv(dev); | 235 | int num; |
233 | int num, err; | 236 | struct scatterlist sg[2+MAX_SKB_FRAGS]; |
234 | struct scatterlist sg[1+MAX_SKB_FRAGS]; | ||
235 | struct virtio_net_hdr *hdr; | 237 | struct virtio_net_hdr *hdr; |
236 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; | 238 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; |
237 | 239 | ||
238 | sg_init_table(sg, 1+MAX_SKB_FRAGS); | 240 | sg_init_table(sg, 2+MAX_SKB_FRAGS); |
239 | 241 | ||
240 | pr_debug("%s: xmit %p " MAC_FMT "\n", dev->name, skb, | 242 | pr_debug("%s: xmit %p " MAC_FMT "\n", vi->dev->name, skb, |
241 | dest[0], dest[1], dest[2], | 243 | dest[0], dest[1], dest[2], |
242 | dest[3], dest[4], dest[5]); | 244 | dest[3], dest[4], dest[5]); |
243 | 245 | ||
@@ -272,30 +274,51 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
272 | 274 | ||
273 | vnet_hdr_to_sg(sg, skb); | 275 | vnet_hdr_to_sg(sg, skb); |
274 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; | 276 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; |
275 | __skb_queue_head(&vi->send, skb); | 277 | |
278 | return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); | ||
279 | } | ||
280 | |||
281 | static int start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
282 | { | ||
283 | struct virtnet_info *vi = netdev_priv(dev); | ||
276 | 284 | ||
277 | again: | 285 | again: |
278 | /* Free up any pending old buffers before queueing new ones. */ | 286 | /* Free up any pending old buffers before queueing new ones. */ |
279 | free_old_xmit_skbs(vi); | 287 | free_old_xmit_skbs(vi); |
280 | err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); | 288 | |
281 | if (err) { | 289 | /* If we has a buffer left over from last time, send it now. */ |
282 | pr_debug("%s: virtio not prepared to send\n", dev->name); | 290 | if (vi->last_xmit_skb) { |
283 | netif_stop_queue(dev); | 291 | if (xmit_skb(vi, vi->last_xmit_skb) != 0) { |
284 | 292 | /* Drop this skb: we only queue one. */ | |
285 | /* Activate callback for using skbs: if this returns false it | 293 | vi->dev->stats.tx_dropped++; |
286 | * means some were used in the meantime. */ | 294 | kfree_skb(skb); |
287 | if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { | 295 | goto stop_queue; |
288 | vi->svq->vq_ops->disable_cb(vi->svq); | ||
289 | netif_start_queue(dev); | ||
290 | goto again; | ||
291 | } | 296 | } |
292 | __skb_unlink(skb, &vi->send); | 297 | vi->last_xmit_skb = NULL; |
298 | } | ||
293 | 299 | ||
294 | return NETDEV_TX_BUSY; | 300 | /* Put new one in send queue and do transmit */ |
301 | __skb_queue_head(&vi->send, skb); | ||
302 | if (xmit_skb(vi, skb) != 0) { | ||
303 | vi->last_xmit_skb = skb; | ||
304 | goto stop_queue; | ||
295 | } | 305 | } |
306 | done: | ||
296 | vi->svq->vq_ops->kick(vi->svq); | 307 | vi->svq->vq_ops->kick(vi->svq); |
297 | 308 | return NETDEV_TX_OK; | |
298 | return 0; | 309 | |
310 | stop_queue: | ||
311 | pr_debug("%s: virtio not prepared to send\n", dev->name); | ||
312 | netif_stop_queue(dev); | ||
313 | |||
314 | /* Activate callback for using skbs: if this returns false it | ||
315 | * means some were used in the meantime. */ | ||
316 | if (unlikely(!vi->svq->vq_ops->enable_cb(vi->svq))) { | ||
317 | vi->svq->vq_ops->disable_cb(vi->svq); | ||
318 | netif_start_queue(dev); | ||
319 | goto again; | ||
320 | } | ||
321 | goto done; | ||
299 | } | 322 | } |
300 | 323 | ||
301 | #ifdef CONFIG_NET_POLL_CONTROLLER | 324 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -355,17 +378,26 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
355 | SET_NETDEV_DEV(dev, &vdev->dev); | 378 | SET_NETDEV_DEV(dev, &vdev->dev); |
356 | 379 | ||
357 | /* Do we support "hardware" checksums? */ | 380 | /* Do we support "hardware" checksums? */ |
358 | if (csum && vdev->config->feature(vdev, VIRTIO_NET_F_CSUM)) { | 381 | if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) { |
359 | /* This opens up the world of extra features. */ | 382 | /* This opens up the world of extra features. */ |
360 | dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; | 383 | dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; |
361 | if (gso && vdev->config->feature(vdev, VIRTIO_NET_F_GSO)) { | 384 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) { |
362 | dev->features |= NETIF_F_TSO | NETIF_F_UFO | 385 | dev->features |= NETIF_F_TSO | NETIF_F_UFO |
363 | | NETIF_F_TSO_ECN | NETIF_F_TSO6; | 386 | | NETIF_F_TSO_ECN | NETIF_F_TSO6; |
364 | } | 387 | } |
388 | /* Individual feature bits: what can host handle? */ | ||
389 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4)) | ||
390 | dev->features |= NETIF_F_TSO; | ||
391 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6)) | ||
392 | dev->features |= NETIF_F_TSO6; | ||
393 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN)) | ||
394 | dev->features |= NETIF_F_TSO_ECN; | ||
395 | if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO)) | ||
396 | dev->features |= NETIF_F_UFO; | ||
365 | } | 397 | } |
366 | 398 | ||
367 | /* Configuration may specify what MAC to use. Otherwise random. */ | 399 | /* Configuration may specify what MAC to use. Otherwise random. */ |
368 | if (vdev->config->feature(vdev, VIRTIO_NET_F_MAC)) { | 400 | if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) { |
369 | vdev->config->get(vdev, | 401 | vdev->config->get(vdev, |
370 | offsetof(struct virtio_net_config, mac), | 402 | offsetof(struct virtio_net_config, mac), |
371 | dev->dev_addr, dev->addr_len); | 403 | dev->dev_addr, dev->addr_len); |
@@ -454,7 +486,15 @@ static struct virtio_device_id id_table[] = { | |||
454 | { 0 }, | 486 | { 0 }, |
455 | }; | 487 | }; |
456 | 488 | ||
489 | static unsigned int features[] = { | ||
490 | VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, | ||
491 | VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, | ||
492 | VIRTIO_NET_F_HOST_ECN, | ||
493 | }; | ||
494 | |||
457 | static struct virtio_driver virtio_net = { | 495 | static struct virtio_driver virtio_net = { |
496 | .feature_table = features, | ||
497 | .feature_table_size = ARRAY_SIZE(features), | ||
458 | .driver.name = KBUILD_MODNAME, | 498 | .driver.name = KBUILD_MODNAME, |
459 | .driver.owner = THIS_MODULE, | 499 | .driver.owner = THIS_MODULE, |
460 | .id_table = id_table, | 500 | .id_table = id_table, |
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 5dd23c93497d..883af891ebfb 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c | |||
@@ -2611,7 +2611,7 @@ static int strip_open(struct tty_struct *tty) | |||
2611 | * We need a write method. | 2611 | * We need a write method. |
2612 | */ | 2612 | */ |
2613 | 2613 | ||
2614 | if (tty->ops->write == NULL) | 2614 | if (tty->ops->write == NULL || tty->ops->set_termios == NULL) |
2615 | return -EOPNOTSUPP; | 2615 | return -EOPNOTSUPP; |
2616 | 2616 | ||
2617 | /* | 2617 | /* |