diff options
45 files changed, 463 insertions, 235 deletions
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index a1d4188c430b..e7810b74f396 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c | |||
@@ -449,11 +449,10 @@ ks8695_rx_irq(int irq, void *dev_id) | |||
449 | } | 449 | } |
450 | 450 | ||
451 | /** | 451 | /** |
452 | * ks8695_rx - Receive packets called by NAPI poll method | 452 | * ks8695_rx - Receive packets called by NAPI poll method |
453 | * @ksp: Private data for the KS8695 Ethernet | 453 | * @ksp: Private data for the KS8695 Ethernet |
454 | * @budget: The max packets would be receive | 454 | * @budget: Number of packets allowed to process |
455 | */ | 455 | */ |
456 | |||
457 | static int ks8695_rx(struct ks8695_priv *ksp, int budget) | 456 | static int ks8695_rx(struct ks8695_priv *ksp, int budget) |
458 | { | 457 | { |
459 | struct net_device *ndev = ksp->ndev; | 458 | struct net_device *ndev = ksp->ndev; |
@@ -461,7 +460,6 @@ static int ks8695_rx(struct ks8695_priv *ksp, int budget) | |||
461 | int buff_n; | 460 | int buff_n; |
462 | u32 flags; | 461 | u32 flags; |
463 | int pktlen; | 462 | int pktlen; |
464 | int last_rx_processed = -1; | ||
465 | int received = 0; | 463 | int received = 0; |
466 | 464 | ||
467 | buff_n = ksp->next_rx_desc_read; | 465 | buff_n = ksp->next_rx_desc_read; |
@@ -471,6 +469,7 @@ static int ks8695_rx(struct ks8695_priv *ksp, int budget) | |||
471 | cpu_to_le32(RDES_OWN)))) { | 469 | cpu_to_le32(RDES_OWN)))) { |
472 | rmb(); | 470 | rmb(); |
473 | flags = le32_to_cpu(ksp->rx_ring[buff_n].status); | 471 | flags = le32_to_cpu(ksp->rx_ring[buff_n].status); |
472 | |||
474 | /* Found an SKB which we own, this means we | 473 | /* Found an SKB which we own, this means we |
475 | * received a packet | 474 | * received a packet |
476 | */ | 475 | */ |
@@ -533,23 +532,18 @@ rx_failure: | |||
533 | ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN); | 532 | ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN); |
534 | rx_finished: | 533 | rx_finished: |
535 | received++; | 534 | received++; |
536 | /* And note this as processed so we can start | ||
537 | * from here next time | ||
538 | */ | ||
539 | last_rx_processed = buff_n; | ||
540 | buff_n = (buff_n + 1) & MAX_RX_DESC_MASK; | 535 | buff_n = (buff_n + 1) & MAX_RX_DESC_MASK; |
541 | /*And note which RX descriptor we last did */ | ||
542 | if (likely(last_rx_processed != -1)) | ||
543 | ksp->next_rx_desc_read = | ||
544 | (last_rx_processed + 1) & | ||
545 | MAX_RX_DESC_MASK; | ||
546 | } | 536 | } |
537 | |||
538 | /* And note which RX descriptor we last did */ | ||
539 | ksp->next_rx_desc_read = buff_n; | ||
540 | |||
547 | /* And refill the buffers */ | 541 | /* And refill the buffers */ |
548 | ks8695_refill_rxbuffers(ksp); | 542 | ks8695_refill_rxbuffers(ksp); |
549 | 543 | ||
550 | /* Kick the RX DMA engine, in case it became | 544 | /* Kick the RX DMA engine, in case it became suspended */ |
551 | * suspended */ | ||
552 | ks8695_writereg(ksp, KS8695_DRSC, 0); | 545 | ks8695_writereg(ksp, KS8695_DRSC, 0); |
546 | |||
553 | return received; | 547 | return received; |
554 | } | 548 | } |
555 | 549 | ||
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 9d7fa2fb85ea..0bc990ec4a8e 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
@@ -94,6 +94,7 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
94 | case E1000_DEV_ID_82576_FIBER: | 94 | case E1000_DEV_ID_82576_FIBER: |
95 | case E1000_DEV_ID_82576_SERDES: | 95 | case E1000_DEV_ID_82576_SERDES: |
96 | case E1000_DEV_ID_82576_QUAD_COPPER: | 96 | case E1000_DEV_ID_82576_QUAD_COPPER: |
97 | case E1000_DEV_ID_82576_QUAD_COPPER_ET2: | ||
97 | case E1000_DEV_ID_82576_SERDES_QUAD: | 98 | case E1000_DEV_ID_82576_SERDES_QUAD: |
98 | mac->type = e1000_82576; | 99 | mac->type = e1000_82576; |
99 | break; | 100 | break; |
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index 448005276b26..82a533f5192a 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h | |||
@@ -41,6 +41,7 @@ struct e1000_hw; | |||
41 | #define E1000_DEV_ID_82576_FIBER 0x10E6 | 41 | #define E1000_DEV_ID_82576_FIBER 0x10E6 |
42 | #define E1000_DEV_ID_82576_SERDES 0x10E7 | 42 | #define E1000_DEV_ID_82576_SERDES 0x10E7 |
43 | #define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8 | 43 | #define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8 |
44 | #define E1000_DEV_ID_82576_QUAD_COPPER_ET2 0x1526 | ||
44 | #define E1000_DEV_ID_82576_NS 0x150A | 45 | #define E1000_DEV_ID_82576_NS 0x150A |
45 | #define E1000_DEV_ID_82576_NS_SERDES 0x1518 | 46 | #define E1000_DEV_ID_82576_NS_SERDES 0x1518 |
46 | #define E1000_DEV_ID_82576_SERDES_QUAD 0x150D | 47 | #define E1000_DEV_ID_82576_SERDES_QUAD 0x150D |
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 0ed25f059a00..45a0e4fd5871 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -72,6 +72,7 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = { | |||
72 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 }, | 72 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 }, |
73 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 }, | 73 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 }, |
74 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 }, | 74 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES_QUAD), board_82575 }, |
75 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER_ET2), board_82575 }, | ||
75 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 }, | 76 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_QUAD_COPPER), board_82575 }, |
76 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 }, | 77 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 }, |
77 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 }, | 78 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 }, |
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 1f30e163bd9c..b405a00817c6 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #define IXGBE_82599_MC_TBL_SIZE 128 | 39 | #define IXGBE_82599_MC_TBL_SIZE 128 |
40 | #define IXGBE_82599_VFT_TBL_SIZE 128 | 40 | #define IXGBE_82599_VFT_TBL_SIZE 128 |
41 | 41 | ||
42 | void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); | ||
42 | s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, | 43 | s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, |
43 | ixgbe_link_speed speed, | 44 | ixgbe_link_speed speed, |
44 | bool autoneg, | 45 | bool autoneg, |
@@ -68,7 +69,9 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) | |||
68 | if (hw->phy.multispeed_fiber) { | 69 | if (hw->phy.multispeed_fiber) { |
69 | /* Set up dual speed SFP+ support */ | 70 | /* Set up dual speed SFP+ support */ |
70 | mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; | 71 | mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; |
72 | mac->ops.flap_tx_laser = &ixgbe_flap_tx_laser_multispeed_fiber; | ||
71 | } else { | 73 | } else { |
74 | mac->ops.flap_tx_laser = NULL; | ||
72 | if ((mac->ops.get_media_type(hw) == | 75 | if ((mac->ops.get_media_type(hw) == |
73 | ixgbe_media_type_backplane) && | 76 | ixgbe_media_type_backplane) && |
74 | (hw->phy.smart_speed == ixgbe_smart_speed_auto || | 77 | (hw->phy.smart_speed == ixgbe_smart_speed_auto || |
@@ -413,6 +416,41 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, | |||
413 | } | 416 | } |
414 | 417 | ||
415 | /** | 418 | /** |
419 | * ixgbe_flap_tx_laser_multispeed_fiber - Flap Tx laser | ||
420 | * @hw: pointer to hardware structure | ||
421 | * | ||
422 | * When the driver changes the link speeds that it can support, | ||
423 | * it sets autotry_restart to true to indicate that we need to | ||
424 | * initiate a new autotry session with the link partner. To do | ||
425 | * so, we set the speed then disable and re-enable the tx laser, to | ||
426 | * alert the link partner that it also needs to restart autotry on its | ||
427 | * end. This is consistent with true clause 37 autoneg, which also | ||
428 | * involves a loss of signal. | ||
429 | **/ | ||
430 | void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) | ||
431 | { | ||
432 | u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); | ||
433 | |||
434 | hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n"); | ||
435 | |||
436 | if (hw->mac.autotry_restart) { | ||
437 | /* Disable tx laser; allow 100us to go dark per spec */ | ||
438 | esdp_reg |= IXGBE_ESDP_SDP3; | ||
439 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); | ||
440 | IXGBE_WRITE_FLUSH(hw); | ||
441 | udelay(100); | ||
442 | |||
443 | /* Enable tx laser; allow 100ms to light up */ | ||
444 | esdp_reg &= ~IXGBE_ESDP_SDP3; | ||
445 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); | ||
446 | IXGBE_WRITE_FLUSH(hw); | ||
447 | msleep(100); | ||
448 | |||
449 | hw->mac.autotry_restart = false; | ||
450 | } | ||
451 | } | ||
452 | |||
453 | /** | ||
416 | * ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed | 454 | * ixgbe_setup_mac_link_multispeed_fiber - Set MAC link speed |
417 | * @hw: pointer to hardware structure | 455 | * @hw: pointer to hardware structure |
418 | * @speed: new link speed | 456 | * @speed: new link speed |
@@ -440,16 +478,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, | |||
440 | speed &= phy_link_speed; | 478 | speed &= phy_link_speed; |
441 | 479 | ||
442 | /* | 480 | /* |
443 | * When the driver changes the link speeds that it can support, | ||
444 | * it sets autotry_restart to true to indicate that we need to | ||
445 | * initiate a new autotry session with the link partner. To do | ||
446 | * so, we set the speed then disable and re-enable the tx laser, to | ||
447 | * alert the link partner that it also needs to restart autotry on its | ||
448 | * end. This is consistent with true clause 37 autoneg, which also | ||
449 | * involves a loss of signal. | ||
450 | */ | ||
451 | |||
452 | /* | ||
453 | * Try each speed one by one, highest priority first. We do this in | 481 | * Try each speed one by one, highest priority first. We do this in |
454 | * software because 10gb fiber doesn't support speed autonegotiation. | 482 | * software because 10gb fiber doesn't support speed autonegotiation. |
455 | */ | 483 | */ |
@@ -466,6 +494,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, | |||
466 | /* Set the module link speed */ | 494 | /* Set the module link speed */ |
467 | esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5); | 495 | esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5); |
468 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); | 496 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); |
497 | IXGBE_WRITE_FLUSH(hw); | ||
469 | 498 | ||
470 | /* Allow module to change analog characteristics (1G->10G) */ | 499 | /* Allow module to change analog characteristics (1G->10G) */ |
471 | msleep(40); | 500 | msleep(40); |
@@ -478,19 +507,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, | |||
478 | return status; | 507 | return status; |
479 | 508 | ||
480 | /* Flap the tx laser if it has not already been done */ | 509 | /* Flap the tx laser if it has not already been done */ |
481 | if (hw->mac.autotry_restart) { | 510 | hw->mac.ops.flap_tx_laser(hw); |
482 | /* Disable tx laser; allow 100us to go dark per spec */ | ||
483 | esdp_reg |= IXGBE_ESDP_SDP3; | ||
484 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); | ||
485 | udelay(100); | ||
486 | |||
487 | /* Enable tx laser; allow 2ms to light up per spec */ | ||
488 | esdp_reg &= ~IXGBE_ESDP_SDP3; | ||
489 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); | ||
490 | msleep(2); | ||
491 | |||
492 | hw->mac.autotry_restart = false; | ||
493 | } | ||
494 | 511 | ||
495 | /* | 512 | /* |
496 | * Wait for the controller to acquire link. Per IEEE 802.3ap, | 513 | * Wait for the controller to acquire link. Per IEEE 802.3ap, |
@@ -525,6 +542,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, | |||
525 | esdp_reg &= ~IXGBE_ESDP_SDP5; | 542 | esdp_reg &= ~IXGBE_ESDP_SDP5; |
526 | esdp_reg |= IXGBE_ESDP_SDP5_DIR; | 543 | esdp_reg |= IXGBE_ESDP_SDP5_DIR; |
527 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); | 544 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); |
545 | IXGBE_WRITE_FLUSH(hw); | ||
528 | 546 | ||
529 | /* Allow module to change analog characteristics (10G->1G) */ | 547 | /* Allow module to change analog characteristics (10G->1G) */ |
530 | msleep(40); | 548 | msleep(40); |
@@ -537,19 +555,7 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, | |||
537 | return status; | 555 | return status; |
538 | 556 | ||
539 | /* Flap the tx laser if it has not already been done */ | 557 | /* Flap the tx laser if it has not already been done */ |
540 | if (hw->mac.autotry_restart) { | 558 | hw->mac.ops.flap_tx_laser(hw); |
541 | /* Disable tx laser; allow 100us to go dark per spec */ | ||
542 | esdp_reg |= IXGBE_ESDP_SDP3; | ||
543 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); | ||
544 | udelay(100); | ||
545 | |||
546 | /* Enable tx laser; allow 2ms to light up per spec */ | ||
547 | esdp_reg &= ~IXGBE_ESDP_SDP3; | ||
548 | IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg); | ||
549 | msleep(2); | ||
550 | |||
551 | hw->mac.autotry_restart = false; | ||
552 | } | ||
553 | 559 | ||
554 | /* Wait for the link partner to also set speed */ | 560 | /* Wait for the link partner to also set speed */ |
555 | msleep(100); | 561 | msleep(100); |
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 4123dec0dfb7..700cfc0aa1b9 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c | |||
@@ -614,9 +614,9 @@ int ixgbe_fcoe_enable(struct net_device *netdev) | |||
614 | netdev->vlan_features |= NETIF_F_FSO; | 614 | netdev->vlan_features |= NETIF_F_FSO; |
615 | netdev->vlan_features |= NETIF_F_FCOE_MTU; | 615 | netdev->vlan_features |= NETIF_F_FCOE_MTU; |
616 | netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; | 616 | netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; |
617 | netdev_features_change(netdev); | ||
618 | 617 | ||
619 | ixgbe_init_interrupt_scheme(adapter); | 618 | ixgbe_init_interrupt_scheme(adapter); |
619 | netdev_features_change(netdev); | ||
620 | 620 | ||
621 | if (netif_running(netdev)) | 621 | if (netif_running(netdev)) |
622 | netdev->netdev_ops->ndo_open(netdev); | 622 | netdev->netdev_ops->ndo_open(netdev); |
@@ -660,11 +660,11 @@ int ixgbe_fcoe_disable(struct net_device *netdev) | |||
660 | netdev->vlan_features &= ~NETIF_F_FSO; | 660 | netdev->vlan_features &= ~NETIF_F_FSO; |
661 | netdev->vlan_features &= ~NETIF_F_FCOE_MTU; | 661 | netdev->vlan_features &= ~NETIF_F_FCOE_MTU; |
662 | netdev->fcoe_ddp_xid = 0; | 662 | netdev->fcoe_ddp_xid = 0; |
663 | netdev_features_change(netdev); | ||
664 | 663 | ||
665 | ixgbe_cleanup_fcoe(adapter); | 664 | ixgbe_cleanup_fcoe(adapter); |
666 | |||
667 | ixgbe_init_interrupt_scheme(adapter); | 665 | ixgbe_init_interrupt_scheme(adapter); |
666 | netdev_features_change(netdev); | ||
667 | |||
668 | if (netif_running(netdev)) | 668 | if (netif_running(netdev)) |
669 | netdev->netdev_ops->ndo_open(netdev); | 669 | netdev->netdev_ops->ndo_open(netdev); |
670 | rc = 0; | 670 | rc = 0; |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 684af371462d..d75c46ff31f6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -935,10 +935,12 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | |||
935 | if (skb->prev) | 935 | if (skb->prev) |
936 | skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count)); | 936 | skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count)); |
937 | if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { | 937 | if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { |
938 | if (IXGBE_RSC_CB(skb)->dma) | 938 | if (IXGBE_RSC_CB(skb)->dma) { |
939 | pci_unmap_single(pdev, IXGBE_RSC_CB(skb)->dma, | 939 | pci_unmap_single(pdev, IXGBE_RSC_CB(skb)->dma, |
940 | rx_ring->rx_buf_len, | 940 | rx_ring->rx_buf_len, |
941 | PCI_DMA_FROMDEVICE); | 941 | PCI_DMA_FROMDEVICE); |
942 | IXGBE_RSC_CB(skb)->dma = 0; | ||
943 | } | ||
942 | if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) | 944 | if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) |
943 | rx_ring->rsc_count += skb_shinfo(skb)->nr_frags; | 945 | rx_ring->rsc_count += skb_shinfo(skb)->nr_frags; |
944 | else | 946 | else |
@@ -3126,10 +3128,12 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, | |||
3126 | rx_buffer_info->skb = NULL; | 3128 | rx_buffer_info->skb = NULL; |
3127 | do { | 3129 | do { |
3128 | struct sk_buff *this = skb; | 3130 | struct sk_buff *this = skb; |
3129 | if (IXGBE_RSC_CB(this)->dma) | 3131 | if (IXGBE_RSC_CB(this)->dma) { |
3130 | pci_unmap_single(pdev, IXGBE_RSC_CB(this)->dma, | 3132 | pci_unmap_single(pdev, IXGBE_RSC_CB(this)->dma, |
3131 | rx_ring->rx_buf_len, | 3133 | rx_ring->rx_buf_len, |
3132 | PCI_DMA_FROMDEVICE); | 3134 | PCI_DMA_FROMDEVICE); |
3135 | IXGBE_RSC_CB(this)->dma = 0; | ||
3136 | } | ||
3133 | skb = skb->prev; | 3137 | skb = skb->prev; |
3134 | dev_kfree_skb(this); | 3138 | dev_kfree_skb(this); |
3135 | } while (skb); | 3139 | } while (skb); |
@@ -5018,6 +5022,7 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work) | |||
5018 | autoneg = hw->phy.autoneg_advertised; | 5022 | autoneg = hw->phy.autoneg_advertised; |
5019 | if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) | 5023 | if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) |
5020 | hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation); | 5024 | hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation); |
5025 | hw->mac.autotry_restart = false; | ||
5021 | if (hw->mac.ops.setup_link) | 5026 | if (hw->mac.ops.setup_link) |
5022 | hw->mac.ops.setup_link(hw, autoneg, negotiation, true); | 5027 | hw->mac.ops.setup_link(hw, autoneg, negotiation, true); |
5023 | adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; | 5028 | adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; |
@@ -6245,9 +6250,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, | |||
6245 | case IXGBE_DEV_ID_82599_KX4: | 6250 | case IXGBE_DEV_ID_82599_KX4: |
6246 | adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | | 6251 | adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | |
6247 | IXGBE_WUFC_MC | IXGBE_WUFC_BC); | 6252 | IXGBE_WUFC_MC | IXGBE_WUFC_BC); |
6248 | /* Enable ACPI wakeup in GRC */ | ||
6249 | IXGBE_WRITE_REG(hw, IXGBE_GRC, | ||
6250 | (IXGBE_READ_REG(hw, IXGBE_GRC) & ~IXGBE_GRC_APME)); | ||
6251 | break; | 6253 | break; |
6252 | default: | 6254 | default: |
6253 | adapter->wol = 0; | 6255 | adapter->wol = 0; |
@@ -6380,6 +6382,16 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) | |||
6380 | del_timer_sync(&adapter->sfp_timer); | 6382 | del_timer_sync(&adapter->sfp_timer); |
6381 | cancel_work_sync(&adapter->watchdog_task); | 6383 | cancel_work_sync(&adapter->watchdog_task); |
6382 | cancel_work_sync(&adapter->sfp_task); | 6384 | cancel_work_sync(&adapter->sfp_task); |
6385 | if (adapter->hw.phy.multispeed_fiber) { | ||
6386 | struct ixgbe_hw *hw = &adapter->hw; | ||
6387 | /* | ||
6388 | * Restart clause 37 autoneg, disable and re-enable | ||
6389 | * the tx laser, to clear & alert the link partner | ||
6390 | * that it needs to restart autotry | ||
6391 | */ | ||
6392 | hw->mac.autotry_restart = true; | ||
6393 | hw->mac.ops.flap_tx_laser(hw); | ||
6394 | } | ||
6383 | cancel_work_sync(&adapter->multispeed_fiber_task); | 6395 | cancel_work_sync(&adapter->multispeed_fiber_task); |
6384 | cancel_work_sync(&adapter->sfp_config_module_task); | 6396 | cancel_work_sync(&adapter->sfp_config_module_task); |
6385 | if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || | 6397 | if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || |
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 2be907466593..0ed5ab37cc53 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h | |||
@@ -2397,6 +2397,7 @@ struct ixgbe_mac_operations { | |||
2397 | s32 (*enable_rx_dma)(struct ixgbe_hw *, u32); | 2397 | s32 (*enable_rx_dma)(struct ixgbe_hw *, u32); |
2398 | 2398 | ||
2399 | /* Link */ | 2399 | /* Link */ |
2400 | void (*flap_tx_laser)(struct ixgbe_hw *); | ||
2400 | s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool); | 2401 | s32 (*setup_link)(struct ixgbe_hw *, ixgbe_link_speed, bool, bool); |
2401 | s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); | 2402 | s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); |
2402 | s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *, | 2403 | s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *, |
diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c index 399be0c34c36..6fdd651abcd1 100644 --- a/drivers/net/ixgbevf/ethtool.c +++ b/drivers/net/ixgbevf/ethtool.c | |||
@@ -46,22 +46,32 @@ struct ixgbe_stats { | |||
46 | int sizeof_stat; | 46 | int sizeof_stat; |
47 | int stat_offset; | 47 | int stat_offset; |
48 | int base_stat_offset; | 48 | int base_stat_offset; |
49 | int saved_reset_offset; | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | #define IXGBEVF_STAT(m, b) sizeof(((struct ixgbevf_adapter *)0)->m), \ | 52 | #define IXGBEVF_STAT(m, b, r) sizeof(((struct ixgbevf_adapter *)0)->m), \ |
52 | offsetof(struct ixgbevf_adapter, m), \ | 53 | offsetof(struct ixgbevf_adapter, m), \ |
53 | offsetof(struct ixgbevf_adapter, b) | 54 | offsetof(struct ixgbevf_adapter, b), \ |
55 | offsetof(struct ixgbevf_adapter, r) | ||
54 | static struct ixgbe_stats ixgbe_gstrings_stats[] = { | 56 | static struct ixgbe_stats ixgbe_gstrings_stats[] = { |
55 | {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc)}, | 57 | {"rx_packets", IXGBEVF_STAT(stats.vfgprc, stats.base_vfgprc, |
56 | {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc)}, | 58 | stats.saved_reset_vfgprc)}, |
57 | {"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc)}, | 59 | {"tx_packets", IXGBEVF_STAT(stats.vfgptc, stats.base_vfgptc, |
58 | {"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc)}, | 60 | stats.saved_reset_vfgptc)}, |
59 | {"tx_busy", IXGBEVF_STAT(tx_busy, zero_base)}, | 61 | {"rx_bytes", IXGBEVF_STAT(stats.vfgorc, stats.base_vfgorc, |
60 | {"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc)}, | 62 | stats.saved_reset_vfgorc)}, |
61 | {"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base)}, | 63 | {"tx_bytes", IXGBEVF_STAT(stats.vfgotc, stats.base_vfgotc, |
62 | {"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base)}, | 64 | stats.saved_reset_vfgotc)}, |
63 | {"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base)}, | 65 | {"tx_busy", IXGBEVF_STAT(tx_busy, zero_base, zero_base)}, |
64 | {"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base)}, | 66 | {"multicast", IXGBEVF_STAT(stats.vfmprc, stats.base_vfmprc, |
67 | stats.saved_reset_vfmprc)}, | ||
68 | {"rx_csum_offload_good", IXGBEVF_STAT(hw_csum_rx_good, zero_base, | ||
69 | zero_base)}, | ||
70 | {"rx_csum_offload_errors", IXGBEVF_STAT(hw_csum_rx_error, zero_base, | ||
71 | zero_base)}, | ||
72 | {"tx_csum_offload_ctxt", IXGBEVF_STAT(hw_csum_tx_good, zero_base, | ||
73 | zero_base)}, | ||
74 | {"rx_header_split", IXGBEVF_STAT(rx_hdr_split, zero_base, zero_base)}, | ||
65 | }; | 75 | }; |
66 | 76 | ||
67 | #define IXGBE_QUEUE_STATS_LEN 0 | 77 | #define IXGBE_QUEUE_STATS_LEN 0 |
@@ -455,10 +465,14 @@ static void ixgbevf_get_ethtool_stats(struct net_device *netdev, | |||
455 | ixgbe_gstrings_stats[i].stat_offset; | 465 | ixgbe_gstrings_stats[i].stat_offset; |
456 | char *b = (char *)adapter + | 466 | char *b = (char *)adapter + |
457 | ixgbe_gstrings_stats[i].base_stat_offset; | 467 | ixgbe_gstrings_stats[i].base_stat_offset; |
468 | char *r = (char *)adapter + | ||
469 | ixgbe_gstrings_stats[i].saved_reset_offset; | ||
458 | data[i] = ((ixgbe_gstrings_stats[i].sizeof_stat == | 470 | data[i] = ((ixgbe_gstrings_stats[i].sizeof_stat == |
459 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p) - | 471 | sizeof(u64)) ? *(u64 *)p : *(u32 *)p) - |
460 | ((ixgbe_gstrings_stats[i].sizeof_stat == | 472 | ((ixgbe_gstrings_stats[i].sizeof_stat == |
461 | sizeof(u64)) ? *(u64 *)b : *(u32 *)b); | 473 | sizeof(u64)) ? *(u64 *)b : *(u32 *)b) + |
474 | ((ixgbe_gstrings_stats[i].sizeof_stat == | ||
475 | sizeof(u64)) ? *(u64 *)r : *(u32 *)r); | ||
462 | } | 476 | } |
463 | } | 477 | } |
464 | 478 | ||
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index ca653c49b765..d6cbd943a6f0 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c | |||
@@ -965,7 +965,7 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data) | |||
965 | 965 | ||
966 | if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG) | 966 | if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG) |
967 | mod_timer(&adapter->watchdog_timer, | 967 | mod_timer(&adapter->watchdog_timer, |
968 | round_jiffies(jiffies + 10)); | 968 | round_jiffies(jiffies + 1)); |
969 | 969 | ||
970 | return IRQ_HANDLED; | 970 | return IRQ_HANDLED; |
971 | } | 971 | } |
@@ -1610,6 +1610,44 @@ static inline void ixgbevf_rx_desc_queue_enable(struct ixgbevf_adapter *adapter, | |||
1610 | (adapter->rx_ring[rxr].count - 1)); | 1610 | (adapter->rx_ring[rxr].count - 1)); |
1611 | } | 1611 | } |
1612 | 1612 | ||
1613 | static void ixgbevf_save_reset_stats(struct ixgbevf_adapter *adapter) | ||
1614 | { | ||
1615 | /* Only save pre-reset stats if there are some */ | ||
1616 | if (adapter->stats.vfgprc || adapter->stats.vfgptc) { | ||
1617 | adapter->stats.saved_reset_vfgprc += adapter->stats.vfgprc - | ||
1618 | adapter->stats.base_vfgprc; | ||
1619 | adapter->stats.saved_reset_vfgptc += adapter->stats.vfgptc - | ||
1620 | adapter->stats.base_vfgptc; | ||
1621 | adapter->stats.saved_reset_vfgorc += adapter->stats.vfgorc - | ||
1622 | adapter->stats.base_vfgorc; | ||
1623 | adapter->stats.saved_reset_vfgotc += adapter->stats.vfgotc - | ||
1624 | adapter->stats.base_vfgotc; | ||
1625 | adapter->stats.saved_reset_vfmprc += adapter->stats.vfmprc - | ||
1626 | adapter->stats.base_vfmprc; | ||
1627 | } | ||
1628 | } | ||
1629 | |||
1630 | static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter) | ||
1631 | { | ||
1632 | struct ixgbe_hw *hw = &adapter->hw; | ||
1633 | |||
1634 | adapter->stats.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC); | ||
1635 | adapter->stats.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB); | ||
1636 | adapter->stats.last_vfgorc |= | ||
1637 | (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32); | ||
1638 | adapter->stats.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC); | ||
1639 | adapter->stats.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB); | ||
1640 | adapter->stats.last_vfgotc |= | ||
1641 | (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32); | ||
1642 | adapter->stats.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC); | ||
1643 | |||
1644 | adapter->stats.base_vfgprc = adapter->stats.last_vfgprc; | ||
1645 | adapter->stats.base_vfgorc = adapter->stats.last_vfgorc; | ||
1646 | adapter->stats.base_vfgptc = adapter->stats.last_vfgptc; | ||
1647 | adapter->stats.base_vfgotc = adapter->stats.last_vfgotc; | ||
1648 | adapter->stats.base_vfmprc = adapter->stats.last_vfmprc; | ||
1649 | } | ||
1650 | |||
1613 | static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter) | 1651 | static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter) |
1614 | { | 1652 | { |
1615 | struct net_device *netdev = adapter->netdev; | 1653 | struct net_device *netdev = adapter->netdev; |
@@ -1656,6 +1694,9 @@ static int ixgbevf_up_complete(struct ixgbevf_adapter *adapter) | |||
1656 | /* enable transmits */ | 1694 | /* enable transmits */ |
1657 | netif_tx_start_all_queues(netdev); | 1695 | netif_tx_start_all_queues(netdev); |
1658 | 1696 | ||
1697 | ixgbevf_save_reset_stats(adapter); | ||
1698 | ixgbevf_init_last_counter_stats(adapter); | ||
1699 | |||
1659 | /* bring the link up in the watchdog, this could race with our first | 1700 | /* bring the link up in the watchdog, this could race with our first |
1660 | * link up interrupt but shouldn't be a problem */ | 1701 | * link up interrupt but shouldn't be a problem */ |
1661 | adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; | 1702 | adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; |
@@ -2228,27 +2269,6 @@ out: | |||
2228 | return err; | 2269 | return err; |
2229 | } | 2270 | } |
2230 | 2271 | ||
2231 | static void ixgbevf_init_last_counter_stats(struct ixgbevf_adapter *adapter) | ||
2232 | { | ||
2233 | struct ixgbe_hw *hw = &adapter->hw; | ||
2234 | |||
2235 | adapter->stats.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC); | ||
2236 | adapter->stats.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB); | ||
2237 | adapter->stats.last_vfgorc |= | ||
2238 | (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32); | ||
2239 | adapter->stats.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC); | ||
2240 | adapter->stats.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB); | ||
2241 | adapter->stats.last_vfgotc |= | ||
2242 | (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32); | ||
2243 | adapter->stats.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC); | ||
2244 | |||
2245 | adapter->stats.base_vfgprc = adapter->stats.last_vfgprc; | ||
2246 | adapter->stats.base_vfgorc = adapter->stats.last_vfgorc; | ||
2247 | adapter->stats.base_vfgptc = adapter->stats.last_vfgptc; | ||
2248 | adapter->stats.base_vfgotc = adapter->stats.last_vfgotc; | ||
2249 | adapter->stats.base_vfmprc = adapter->stats.last_vfmprc; | ||
2250 | } | ||
2251 | |||
2252 | #define UPDATE_VF_COUNTER_32bit(reg, last_counter, counter) \ | 2272 | #define UPDATE_VF_COUNTER_32bit(reg, last_counter, counter) \ |
2253 | { \ | 2273 | { \ |
2254 | u32 current_counter = IXGBE_READ_REG(hw, reg); \ | 2274 | u32 current_counter = IXGBE_READ_REG(hw, reg); \ |
@@ -2399,7 +2419,7 @@ static void ixgbevf_watchdog_task(struct work_struct *work) | |||
2399 | if (!netif_carrier_ok(netdev)) { | 2419 | if (!netif_carrier_ok(netdev)) { |
2400 | hw_dbg(&adapter->hw, "NIC Link is Up %s, ", | 2420 | hw_dbg(&adapter->hw, "NIC Link is Up %s, ", |
2401 | ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? | 2421 | ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? |
2402 | "10 Gbps" : "1 Gbps")); | 2422 | "10 Gbps\n" : "1 Gbps\n")); |
2403 | netif_carrier_on(netdev); | 2423 | netif_carrier_on(netdev); |
2404 | netif_tx_wake_all_queues(netdev); | 2424 | netif_tx_wake_all_queues(netdev); |
2405 | } else { | 2425 | } else { |
@@ -2416,9 +2436,9 @@ static void ixgbevf_watchdog_task(struct work_struct *work) | |||
2416 | } | 2436 | } |
2417 | } | 2437 | } |
2418 | 2438 | ||
2419 | pf_has_reset: | ||
2420 | ixgbevf_update_stats(adapter); | 2439 | ixgbevf_update_stats(adapter); |
2421 | 2440 | ||
2441 | pf_has_reset: | ||
2422 | /* Force detection of hung controller every watchdog period */ | 2442 | /* Force detection of hung controller every watchdog period */ |
2423 | adapter->detect_tx_hung = true; | 2443 | adapter->detect_tx_hung = true; |
2424 | 2444 | ||
@@ -2675,7 +2695,7 @@ static int ixgbevf_open(struct net_device *netdev) | |||
2675 | if (hw->adapter_stopped) { | 2695 | if (hw->adapter_stopped) { |
2676 | err = IXGBE_ERR_MBX; | 2696 | err = IXGBE_ERR_MBX; |
2677 | printk(KERN_ERR "Unable to start - perhaps the PF" | 2697 | printk(KERN_ERR "Unable to start - perhaps the PF" |
2678 | "Driver isn't up yet\n"); | 2698 | " Driver isn't up yet\n"); |
2679 | goto err_setup_reset; | 2699 | goto err_setup_reset; |
2680 | } | 2700 | } |
2681 | } | 2701 | } |
@@ -3390,8 +3410,6 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, | |||
3390 | /* setup the private structure */ | 3410 | /* setup the private structure */ |
3391 | err = ixgbevf_sw_init(adapter); | 3411 | err = ixgbevf_sw_init(adapter); |
3392 | 3412 | ||
3393 | ixgbevf_init_last_counter_stats(adapter); | ||
3394 | |||
3395 | #ifdef MAX_SKB_FRAGS | 3413 | #ifdef MAX_SKB_FRAGS |
3396 | netdev->features = NETIF_F_SG | | 3414 | netdev->features = NETIF_F_SG | |
3397 | NETIF_F_IP_CSUM | | 3415 | NETIF_F_IP_CSUM | |
@@ -3449,6 +3467,8 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, | |||
3449 | 3467 | ||
3450 | adapter->netdev_registered = true; | 3468 | adapter->netdev_registered = true; |
3451 | 3469 | ||
3470 | ixgbevf_init_last_counter_stats(adapter); | ||
3471 | |||
3452 | /* print the MAC address */ | 3472 | /* print the MAC address */ |
3453 | hw_dbg(hw, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", | 3473 | hw_dbg(hw, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", |
3454 | netdev->dev_addr[0], | 3474 | netdev->dev_addr[0], |
diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h index 799600e92700..1f31b052d4b4 100644 --- a/drivers/net/ixgbevf/vf.h +++ b/drivers/net/ixgbevf/vf.h | |||
@@ -157,6 +157,12 @@ struct ixgbevf_hw_stats { | |||
157 | u64 vfgorc; | 157 | u64 vfgorc; |
158 | u64 vfgotc; | 158 | u64 vfgotc; |
159 | u64 vfmprc; | 159 | u64 vfmprc; |
160 | |||
161 | u64 saved_reset_vfgprc; | ||
162 | u64 saved_reset_vfgptc; | ||
163 | u64 saved_reset_vfgorc; | ||
164 | u64 saved_reset_vfgotc; | ||
165 | u64 saved_reset_vfmprc; | ||
160 | }; | 166 | }; |
161 | 167 | ||
162 | struct ixgbevf_info { | 168 | struct ixgbevf_info { |
diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 0f31497833df..c0b59a555384 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c | |||
@@ -946,6 +946,8 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) | |||
946 | jme->jme_vlan_rx(skb, jme->vlgrp, | 946 | jme->jme_vlan_rx(skb, jme->vlgrp, |
947 | le16_to_cpu(rxdesc->descwb.vlan)); | 947 | le16_to_cpu(rxdesc->descwb.vlan)); |
948 | NET_STAT(jme).rx_bytes += 4; | 948 | NET_STAT(jme).rx_bytes += 4; |
949 | } else { | ||
950 | dev_kfree_skb(skb); | ||
949 | } | 951 | } |
950 | } else { | 952 | } else { |
951 | jme->jme_rx(skb); | 953 | jme->jme_rx(skb); |
@@ -2081,12 +2083,45 @@ jme_tx_timeout(struct net_device *netdev) | |||
2081 | jme_reset_link(jme); | 2083 | jme_reset_link(jme); |
2082 | } | 2084 | } |
2083 | 2085 | ||
2086 | static inline void jme_pause_rx(struct jme_adapter *jme) | ||
2087 | { | ||
2088 | atomic_dec(&jme->link_changing); | ||
2089 | |||
2090 | jme_set_rx_pcc(jme, PCC_OFF); | ||
2091 | if (test_bit(JME_FLAG_POLL, &jme->flags)) { | ||
2092 | JME_NAPI_DISABLE(jme); | ||
2093 | } else { | ||
2094 | tasklet_disable(&jme->rxclean_task); | ||
2095 | tasklet_disable(&jme->rxempty_task); | ||
2096 | } | ||
2097 | } | ||
2098 | |||
2099 | static inline void jme_resume_rx(struct jme_adapter *jme) | ||
2100 | { | ||
2101 | struct dynpcc_info *dpi = &(jme->dpi); | ||
2102 | |||
2103 | if (test_bit(JME_FLAG_POLL, &jme->flags)) { | ||
2104 | JME_NAPI_ENABLE(jme); | ||
2105 | } else { | ||
2106 | tasklet_hi_enable(&jme->rxclean_task); | ||
2107 | tasklet_hi_enable(&jme->rxempty_task); | ||
2108 | } | ||
2109 | dpi->cur = PCC_P1; | ||
2110 | dpi->attempt = PCC_P1; | ||
2111 | dpi->cnt = 0; | ||
2112 | jme_set_rx_pcc(jme, PCC_P1); | ||
2113 | |||
2114 | atomic_inc(&jme->link_changing); | ||
2115 | } | ||
2116 | |||
2084 | static void | 2117 | static void |
2085 | jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) | 2118 | jme_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) |
2086 | { | 2119 | { |
2087 | struct jme_adapter *jme = netdev_priv(netdev); | 2120 | struct jme_adapter *jme = netdev_priv(netdev); |
2088 | 2121 | ||
2122 | jme_pause_rx(jme); | ||
2089 | jme->vlgrp = grp; | 2123 | jme->vlgrp = grp; |
2124 | jme_resume_rx(jme); | ||
2090 | } | 2125 | } |
2091 | 2126 | ||
2092 | static void | 2127 | static void |
diff --git a/drivers/net/jme.h b/drivers/net/jme.h index c19db9146a2f..07ad3a457185 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #define __JME_H_INCLUDED__ | 25 | #define __JME_H_INCLUDED__ |
26 | 26 | ||
27 | #define DRV_NAME "jme" | 27 | #define DRV_NAME "jme" |
28 | #define DRV_VERSION "1.0.5" | 28 | #define DRV_VERSION "1.0.6" |
29 | #define PFX DRV_NAME ": " | 29 | #define PFX DRV_NAME ": " |
30 | 30 | ||
31 | #define PCI_DEVICE_ID_JMICRON_JMC250 0x0250 | 31 | #define PCI_DEVICE_ID_JMICRON_JMC250 0x0250 |
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index 0573e0bb4444..13cc1ca261d9 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c | |||
@@ -976,7 +976,6 @@ static void ks8851_set_rx_mode(struct net_device *dev) | |||
976 | crc >>= (32 - 6); /* get top six bits */ | 976 | crc >>= (32 - 6); /* get top six bits */ |
977 | 977 | ||
978 | rxctrl.mchash[crc >> 4] |= (1 << (crc & 0xf)); | 978 | rxctrl.mchash[crc >> 4] |= (1 << (crc & 0xf)); |
979 | mcptr = mcptr->next; | ||
980 | } | 979 | } |
981 | 980 | ||
982 | rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXPAFMA; | 981 | rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXPAFMA; |
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index d222d7e25273..73f9a31cf94d 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c | |||
@@ -1189,9 +1189,21 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev, | |||
1189 | } | 1189 | } |
1190 | 1190 | ||
1191 | if (csum) { | 1191 | if (csum) { |
1192 | u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); | 1192 | if (skb->len <= 45) { |
1193 | skb_push(skb, 4); | 1193 | /* workaround - hardware tx checksum does not work |
1194 | memcpy(skb->data, &csum_preamble, 4); | 1194 | * properly with extremely small packets */ |
1195 | long csstart = skb->csum_start - skb_headroom(skb); | ||
1196 | __wsum calc = csum_partial(skb->data + csstart, | ||
1197 | skb->len - csstart, 0); | ||
1198 | *((__sum16 *)(skb->data + csstart | ||
1199 | + skb->csum_offset)) = csum_fold(calc); | ||
1200 | |||
1201 | csum = false; | ||
1202 | } else { | ||
1203 | u32 csum_preamble = smsc95xx_calc_csum_preamble(skb); | ||
1204 | skb_push(skb, 4); | ||
1205 | memcpy(skb->data, &csum_preamble, 4); | ||
1206 | } | ||
1195 | } | 1207 | } |
1196 | 1208 | ||
1197 | skb_push(skb, 4); | 1209 | skb_push(skb, 4); |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index b2c8207f7bc1..294b486bc3ed 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1353,25 +1353,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | |||
1353 | return htype; | 1353 | return htype; |
1354 | } | 1354 | } |
1355 | 1355 | ||
1356 | static bool is_pae(struct sk_buff *skb) | ||
1357 | { | ||
1358 | struct ieee80211_hdr *hdr; | ||
1359 | __le16 fc; | ||
1360 | |||
1361 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1362 | fc = hdr->frame_control; | ||
1363 | |||
1364 | if (ieee80211_is_data(fc)) { | ||
1365 | if (ieee80211_is_nullfunc(fc) || | ||
1366 | /* Port Access Entity (IEEE 802.1X) */ | ||
1367 | (skb->protocol == cpu_to_be16(ETH_P_PAE))) { | ||
1368 | return true; | ||
1369 | } | ||
1370 | } | ||
1371 | |||
1372 | return false; | ||
1373 | } | ||
1374 | |||
1375 | static int get_hw_crypto_keytype(struct sk_buff *skb) | 1356 | static int get_hw_crypto_keytype(struct sk_buff *skb) |
1376 | { | 1357 | { |
1377 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1358 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
@@ -1696,7 +1677,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1696 | goto tx_done; | 1677 | goto tx_done; |
1697 | } | 1678 | } |
1698 | 1679 | ||
1699 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) { | 1680 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { |
1700 | /* | 1681 | /* |
1701 | * Try aggregation if it's a unicast data frame | 1682 | * Try aggregation if it's a unicast data frame |
1702 | * and the destination is HT capable. | 1683 | * and the destination is HT capable. |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 1ed5206721ec..8c12311dbb0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -124,7 +124,7 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv, | |||
124 | if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) | 124 | if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) |
125 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 125 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
126 | else { | 126 | else { |
127 | IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n", | 127 | IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n", |
128 | priv->stations[sta_id].tid[tid].tfds_in_queue, | 128 | priv->stations[sta_id].tid[tid].tfds_in_queue, |
129 | freed); | 129 | freed); |
130 | priv->stations[sta_id].tid[tid].tfds_in_queue = 0; | 130 | priv->stations[sta_id].tid[tid].tfds_in_queue = 0; |
diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl12xx/wl1251_debugfs.c index 0ccba57fb9fb..05e4d68eb4cc 100644 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c +++ b/drivers/net/wireless/wl12xx/wl1251_debugfs.c | |||
@@ -466,7 +466,8 @@ out: | |||
466 | 466 | ||
467 | void wl1251_debugfs_reset(struct wl1251 *wl) | 467 | void wl1251_debugfs_reset(struct wl1251 *wl) |
468 | { | 468 | { |
469 | memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); | 469 | if (wl->stats.fw_stats != NULL) |
470 | memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); | ||
470 | wl->stats.retry_count = 0; | 471 | wl->stats.retry_count = 0; |
471 | wl->stats.excessive_retries = 0; | 472 | wl->stats.excessive_retries = 0; |
472 | } | 473 | } |
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index ad37da2b6cb5..a6a88dfd5029 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -125,7 +125,7 @@ static void handle_tx(struct vhost_net *net) | |||
125 | mutex_lock(&vq->mutex); | 125 | mutex_lock(&vq->mutex); |
126 | vhost_disable_notify(vq); | 126 | vhost_disable_notify(vq); |
127 | 127 | ||
128 | if (wmem < sock->sk->sk_sndbuf * 2) | 128 | if (wmem < sock->sk->sk_sndbuf / 2) |
129 | tx_poll_stop(net); | 129 | tx_poll_stop(net); |
130 | hdr_size = vq->hdr_size; | 130 | hdr_size = vq->hdr_size; |
131 | 131 | ||
@@ -508,12 +508,12 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) | |||
508 | /* Verify that ring has been setup correctly. */ | 508 | /* Verify that ring has been setup correctly. */ |
509 | if (!vhost_vq_access_ok(vq)) { | 509 | if (!vhost_vq_access_ok(vq)) { |
510 | r = -EFAULT; | 510 | r = -EFAULT; |
511 | goto err; | 511 | goto err_vq; |
512 | } | 512 | } |
513 | sock = get_socket(fd); | 513 | sock = get_socket(fd); |
514 | if (IS_ERR(sock)) { | 514 | if (IS_ERR(sock)) { |
515 | r = PTR_ERR(sock); | 515 | r = PTR_ERR(sock); |
516 | goto err; | 516 | goto err_vq; |
517 | } | 517 | } |
518 | 518 | ||
519 | /* start polling new socket */ | 519 | /* start polling new socket */ |
@@ -524,12 +524,14 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd) | |||
524 | vhost_net_disable_vq(n, vq); | 524 | vhost_net_disable_vq(n, vq); |
525 | rcu_assign_pointer(vq->private_data, sock); | 525 | rcu_assign_pointer(vq->private_data, sock); |
526 | vhost_net_enable_vq(n, vq); | 526 | vhost_net_enable_vq(n, vq); |
527 | mutex_unlock(&vq->mutex); | ||
528 | done: | 527 | done: |
529 | if (oldsock) { | 528 | if (oldsock) { |
530 | vhost_net_flush_vq(n, index); | 529 | vhost_net_flush_vq(n, index); |
531 | fput(oldsock->file); | 530 | fput(oldsock->file); |
532 | } | 531 | } |
532 | |||
533 | err_vq: | ||
534 | mutex_unlock(&vq->mutex); | ||
533 | err: | 535 | err: |
534 | mutex_unlock(&n->dev.mutex); | 536 | mutex_unlock(&n->dev.mutex); |
535 | return r; | 537 | return r; |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 7cd55e078794..7bd7a1e4409d 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -476,8 +476,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
476 | if (r < 0) | 476 | if (r < 0) |
477 | break; | 477 | break; |
478 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); | 478 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
479 | if (IS_ERR(eventfp)) | 479 | if (IS_ERR(eventfp)) { |
480 | return PTR_ERR(eventfp); | 480 | r = PTR_ERR(eventfp); |
481 | break; | ||
482 | } | ||
481 | if (eventfp != vq->kick) { | 483 | if (eventfp != vq->kick) { |
482 | pollstop = filep = vq->kick; | 484 | pollstop = filep = vq->kick; |
483 | pollstart = vq->kick = eventfp; | 485 | pollstart = vq->kick = eventfp; |
@@ -489,8 +491,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
489 | if (r < 0) | 491 | if (r < 0) |
490 | break; | 492 | break; |
491 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); | 493 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
492 | if (IS_ERR(eventfp)) | 494 | if (IS_ERR(eventfp)) { |
493 | return PTR_ERR(eventfp); | 495 | r = PTR_ERR(eventfp); |
496 | break; | ||
497 | } | ||
494 | if (eventfp != vq->call) { | 498 | if (eventfp != vq->call) { |
495 | filep = vq->call; | 499 | filep = vq->call; |
496 | ctx = vq->call_ctx; | 500 | ctx = vq->call_ctx; |
@@ -505,8 +509,10 @@ static long vhost_set_vring(struct vhost_dev *d, int ioctl, void __user *argp) | |||
505 | if (r < 0) | 509 | if (r < 0) |
506 | break; | 510 | break; |
507 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); | 511 | eventfp = f.fd == -1 ? NULL : eventfd_fget(f.fd); |
508 | if (IS_ERR(eventfp)) | 512 | if (IS_ERR(eventfp)) { |
509 | return PTR_ERR(eventfp); | 513 | r = PTR_ERR(eventfp); |
514 | break; | ||
515 | } | ||
510 | if (eventfp != vq->error) { | 516 | if (eventfp != vq->error) { |
511 | filep = vq->error; | 517 | filep = vq->error; |
512 | vq->error = eventfp; | 518 | vq->error = eventfp; |
diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h index 1822d635be6b..16b92d008bed 100644 --- a/include/linux/if_tunnel.h +++ b/include/linux/if_tunnel.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _IF_TUNNEL_H_ | 2 | #define _IF_TUNNEL_H_ |
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <asm/byteorder.h> | ||
5 | 6 | ||
6 | #ifdef __KERNEL__ | 7 | #ifdef __KERNEL__ |
7 | #include <linux/ip.h> | 8 | #include <linux/ip.h> |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c79a88be7c33..fa8b47637997 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -2059,12 +2059,12 @@ static inline void skb_bond_set_mac_by_master(struct sk_buff *skb, | |||
2059 | * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and | 2059 | * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and |
2060 | * ARP on active-backup slaves with arp_validate enabled. | 2060 | * ARP on active-backup slaves with arp_validate enabled. |
2061 | */ | 2061 | */ |
2062 | static inline int skb_bond_should_drop(struct sk_buff *skb) | 2062 | static inline int skb_bond_should_drop(struct sk_buff *skb, |
2063 | struct net_device *master) | ||
2063 | { | 2064 | { |
2064 | struct net_device *dev = skb->dev; | ||
2065 | struct net_device *master = dev->master; | ||
2066 | |||
2067 | if (master) { | 2065 | if (master) { |
2066 | struct net_device *dev = skb->dev; | ||
2067 | |||
2068 | if (master->priv_flags & IFF_MASTER_ARPMON) | 2068 | if (master->priv_flags & IFF_MASTER_ARPMON) |
2069 | dev->last_rx = jiffies; | 2069 | dev->last_rx = jiffies; |
2070 | 2070 | ||
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 53923868c9bd..361d6b5630ee 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h | |||
@@ -76,7 +76,7 @@ extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n); | |||
76 | extern int nfnetlink_has_listeners(struct net *net, unsigned int group); | 76 | extern int nfnetlink_has_listeners(struct net *net, unsigned int group); |
77 | extern int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, | 77 | extern int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, |
78 | int echo, gfp_t flags); | 78 | int echo, gfp_t flags); |
79 | extern void nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error); | 79 | extern int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error); |
80 | extern int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u_int32_t pid, int flags); | 80 | extern int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u_int32_t pid, int flags); |
81 | 81 | ||
82 | extern void nfnl_lock(void); | 82 | extern void nfnl_lock(void); |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index fde27c017326..6eaca5e1e8ca 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -188,7 +188,7 @@ extern int netlink_has_listeners(struct sock *sk, unsigned int group); | |||
188 | extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock); | 188 | extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock); |
189 | extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid, | 189 | extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid, |
190 | __u32 group, gfp_t allocation); | 190 | __u32 group, gfp_t allocation); |
191 | extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code); | 191 | extern int netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code); |
192 | extern int netlink_register_notifier(struct notifier_block *nb); | 192 | extern int netlink_register_notifier(struct notifier_block *nb); |
193 | extern int netlink_unregister_notifier(struct notifier_block *nb); | 193 | extern int netlink_unregister_notifier(struct notifier_block *nb); |
194 | 194 | ||
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 04a6908e38d2..ff77e8f882f1 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -176,6 +176,6 @@ extern void hci_sock_cleanup(void); | |||
176 | extern int bt_sysfs_init(void); | 176 | extern int bt_sysfs_init(void); |
177 | extern void bt_sysfs_cleanup(void); | 177 | extern void bt_sysfs_cleanup(void); |
178 | 178 | ||
179 | extern struct class *bt_class; | 179 | extern struct dentry *bt_debugfs; |
180 | 180 | ||
181 | #endif /* __BLUETOOTH_H */ | 181 | #endif /* __BLUETOOTH_H */ |
diff --git a/include/net/netlink.h b/include/net/netlink.h index f82e463c875a..4fc05b58503e 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h | |||
@@ -945,7 +945,11 @@ static inline u64 nla_get_u64(const struct nlattr *nla) | |||
945 | */ | 945 | */ |
946 | static inline __be64 nla_get_be64(const struct nlattr *nla) | 946 | static inline __be64 nla_get_be64(const struct nlattr *nla) |
947 | { | 947 | { |
948 | return *(__be64 *) nla_data(nla); | 948 | __be64 tmp; |
949 | |||
950 | nla_memcpy(&tmp, nla, sizeof(tmp)); | ||
951 | |||
952 | return tmp; | ||
949 | } | 953 | } |
950 | 954 | ||
951 | /** | 955 | /** |
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index c0316e0ca6e8..c584a0af77d3 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -11,7 +11,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, | |||
11 | if (netpoll_rx(skb)) | 11 | if (netpoll_rx(skb)) |
12 | return NET_RX_DROP; | 12 | return NET_RX_DROP; |
13 | 13 | ||
14 | if (skb_bond_should_drop(skb)) | 14 | if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) |
15 | goto drop; | 15 | goto drop; |
16 | 16 | ||
17 | skb->skb_iif = skb->dev->ifindex; | 17 | skb->skb_iif = skb->dev->ifindex; |
@@ -83,7 +83,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, | |||
83 | { | 83 | { |
84 | struct sk_buff *p; | 84 | struct sk_buff *p; |
85 | 85 | ||
86 | if (skb_bond_should_drop(skb)) | 86 | if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) |
87 | goto drop; | 87 | goto drop; |
88 | 88 | ||
89 | skb->skb_iif = skb->dev->ifindex; | 89 | skb->skb_iif = skb->dev->ifindex; |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index cafb55b0cea5..05fd125f74fe 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -8,8 +8,7 @@ | |||
8 | #include <net/bluetooth/bluetooth.h> | 8 | #include <net/bluetooth/bluetooth.h> |
9 | #include <net/bluetooth/hci_core.h> | 9 | #include <net/bluetooth/hci_core.h> |
10 | 10 | ||
11 | struct class *bt_class = NULL; | 11 | static struct class *bt_class; |
12 | EXPORT_SYMBOL_GPL(bt_class); | ||
13 | 12 | ||
14 | struct dentry *bt_debugfs = NULL; | 13 | struct dentry *bt_debugfs = NULL; |
15 | EXPORT_SYMBOL_GPL(bt_debugfs); | 14 | EXPORT_SYMBOL_GPL(bt_debugfs); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 4db7ae2fe07d..7794a2e2adce 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <linux/skbuff.h> | 40 | #include <linux/skbuff.h> |
41 | #include <linux/list.h> | 41 | #include <linux/list.h> |
42 | #include <linux/device.h> | 42 | #include <linux/device.h> |
43 | #include <linux/debugfs.h> | ||
44 | #include <linux/seq_file.h> | ||
43 | #include <linux/uaccess.h> | 45 | #include <linux/uaccess.h> |
44 | #include <linux/crc16.h> | 46 | #include <linux/crc16.h> |
45 | #include <net/sock.h> | 47 | #include <net/sock.h> |
@@ -2830,6 +2832,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2830 | int len = cmd->len - sizeof(*rsp); | 2832 | int len = cmd->len - sizeof(*rsp); |
2831 | char req[64]; | 2833 | char req[64]; |
2832 | 2834 | ||
2835 | if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { | ||
2836 | l2cap_send_disconn_req(conn, sk); | ||
2837 | goto done; | ||
2838 | } | ||
2839 | |||
2833 | /* throw out any old stored conf requests */ | 2840 | /* throw out any old stored conf requests */ |
2834 | result = L2CAP_CONF_SUCCESS; | 2841 | result = L2CAP_CONF_SUCCESS; |
2835 | len = l2cap_parse_conf_rsp(sk, rsp->data, | 2842 | len = l2cap_parse_conf_rsp(sk, rsp->data, |
@@ -3937,31 +3944,42 @@ drop: | |||
3937 | return 0; | 3944 | return 0; |
3938 | } | 3945 | } |
3939 | 3946 | ||
3940 | static ssize_t l2cap_sysfs_show(struct class *dev, | 3947 | static int l2cap_debugfs_show(struct seq_file *f, void *p) |
3941 | struct class_attribute *attr, | ||
3942 | char *buf) | ||
3943 | { | 3948 | { |
3944 | struct sock *sk; | 3949 | struct sock *sk; |
3945 | struct hlist_node *node; | 3950 | struct hlist_node *node; |
3946 | char *str = buf; | ||
3947 | 3951 | ||
3948 | read_lock_bh(&l2cap_sk_list.lock); | 3952 | read_lock_bh(&l2cap_sk_list.lock); |
3949 | 3953 | ||
3950 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 3954 | sk_for_each(sk, node, &l2cap_sk_list.head) { |
3951 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 3955 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
3952 | 3956 | ||
3953 | str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", | 3957 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", |
3954 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | 3958 | batostr(&bt_sk(sk)->src), |
3955 | sk->sk_state, __le16_to_cpu(pi->psm), pi->scid, | 3959 | batostr(&bt_sk(sk)->dst), |
3956 | pi->dcid, pi->imtu, pi->omtu, pi->sec_level); | 3960 | sk->sk_state, __le16_to_cpu(pi->psm), |
3961 | pi->scid, pi->dcid, | ||
3962 | pi->imtu, pi->omtu, pi->sec_level); | ||
3957 | } | 3963 | } |
3958 | 3964 | ||
3959 | read_unlock_bh(&l2cap_sk_list.lock); | 3965 | read_unlock_bh(&l2cap_sk_list.lock); |
3960 | 3966 | ||
3961 | return str - buf; | 3967 | return 0; |
3962 | } | 3968 | } |
3963 | 3969 | ||
3964 | static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL); | 3970 | static int l2cap_debugfs_open(struct inode *inode, struct file *file) |
3971 | { | ||
3972 | return single_open(file, l2cap_debugfs_show, inode->i_private); | ||
3973 | } | ||
3974 | |||
3975 | static const struct file_operations l2cap_debugfs_fops = { | ||
3976 | .open = l2cap_debugfs_open, | ||
3977 | .read = seq_read, | ||
3978 | .llseek = seq_lseek, | ||
3979 | .release = single_release, | ||
3980 | }; | ||
3981 | |||
3982 | static struct dentry *l2cap_debugfs; | ||
3965 | 3983 | ||
3966 | static const struct proto_ops l2cap_sock_ops = { | 3984 | static const struct proto_ops l2cap_sock_ops = { |
3967 | .family = PF_BLUETOOTH, | 3985 | .family = PF_BLUETOOTH, |
@@ -4021,8 +4039,12 @@ static int __init l2cap_init(void) | |||
4021 | goto error; | 4039 | goto error; |
4022 | } | 4040 | } |
4023 | 4041 | ||
4024 | if (class_create_file(bt_class, &class_attr_l2cap) < 0) | 4042 | if (bt_debugfs) { |
4025 | BT_ERR("Failed to create L2CAP info file"); | 4043 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, |
4044 | bt_debugfs, NULL, &l2cap_debugfs_fops); | ||
4045 | if (!l2cap_debugfs) | ||
4046 | BT_ERR("Failed to create L2CAP debug file"); | ||
4047 | } | ||
4026 | 4048 | ||
4027 | BT_INFO("L2CAP ver %s", VERSION); | 4049 | BT_INFO("L2CAP ver %s", VERSION); |
4028 | BT_INFO("L2CAP socket layer initialized"); | 4050 | BT_INFO("L2CAP socket layer initialized"); |
@@ -4036,7 +4058,7 @@ error: | |||
4036 | 4058 | ||
4037 | static void __exit l2cap_exit(void) | 4059 | static void __exit l2cap_exit(void) |
4038 | { | 4060 | { |
4039 | class_remove_file(bt_class, &class_attr_l2cap); | 4061 | debugfs_remove(l2cap_debugfs); |
4040 | 4062 | ||
4041 | if (bt_sock_unregister(BTPROTO_L2CAP) < 0) | 4063 | if (bt_sock_unregister(BTPROTO_L2CAP) < 0) |
4042 | BT_ERR("L2CAP socket unregistration failed"); | 4064 | BT_ERR("L2CAP socket unregistration failed"); |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index db8a68e1a5ba..13f114e8b0f9 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/wait.h> | 34 | #include <linux/wait.h> |
35 | #include <linux/device.h> | 35 | #include <linux/device.h> |
36 | #include <linux/debugfs.h> | ||
37 | #include <linux/seq_file.h> | ||
36 | #include <linux/net.h> | 38 | #include <linux/net.h> |
37 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
38 | #include <linux/kthread.h> | 40 | #include <linux/kthread.h> |
@@ -2098,13 +2100,10 @@ static struct hci_cb rfcomm_cb = { | |||
2098 | .security_cfm = rfcomm_security_cfm | 2100 | .security_cfm = rfcomm_security_cfm |
2099 | }; | 2101 | }; |
2100 | 2102 | ||
2101 | static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, | 2103 | static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) |
2102 | struct class_attribute *attr, | ||
2103 | char *buf) | ||
2104 | { | 2104 | { |
2105 | struct rfcomm_session *s; | 2105 | struct rfcomm_session *s; |
2106 | struct list_head *pp, *p; | 2106 | struct list_head *pp, *p; |
2107 | char *str = buf; | ||
2108 | 2107 | ||
2109 | rfcomm_lock(); | 2108 | rfcomm_lock(); |
2110 | 2109 | ||
@@ -2114,18 +2113,32 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, | |||
2114 | struct sock *sk = s->sock->sk; | 2113 | struct sock *sk = s->sock->sk; |
2115 | struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list); | 2114 | struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list); |
2116 | 2115 | ||
2117 | str += sprintf(str, "%s %s %ld %d %d %d %d\n", | 2116 | seq_printf(f, "%s %s %ld %d %d %d %d\n", |
2118 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | 2117 | batostr(&bt_sk(sk)->src), |
2119 | d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits); | 2118 | batostr(&bt_sk(sk)->dst), |
2119 | d->state, d->dlci, d->mtu, | ||
2120 | d->rx_credits, d->tx_credits); | ||
2120 | } | 2121 | } |
2121 | } | 2122 | } |
2122 | 2123 | ||
2123 | rfcomm_unlock(); | 2124 | rfcomm_unlock(); |
2124 | 2125 | ||
2125 | return (str - buf); | 2126 | return 0; |
2126 | } | 2127 | } |
2127 | 2128 | ||
2128 | static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL); | 2129 | static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file) |
2130 | { | ||
2131 | return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private); | ||
2132 | } | ||
2133 | |||
2134 | static const struct file_operations rfcomm_dlc_debugfs_fops = { | ||
2135 | .open = rfcomm_dlc_debugfs_open, | ||
2136 | .read = seq_read, | ||
2137 | .llseek = seq_lseek, | ||
2138 | .release = single_release, | ||
2139 | }; | ||
2140 | |||
2141 | static struct dentry *rfcomm_dlc_debugfs; | ||
2129 | 2142 | ||
2130 | /* ---- Initialization ---- */ | 2143 | /* ---- Initialization ---- */ |
2131 | static int __init rfcomm_init(void) | 2144 | static int __init rfcomm_init(void) |
@@ -2142,8 +2155,12 @@ static int __init rfcomm_init(void) | |||
2142 | goto unregister; | 2155 | goto unregister; |
2143 | } | 2156 | } |
2144 | 2157 | ||
2145 | if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0) | 2158 | if (bt_debugfs) { |
2146 | BT_ERR("Failed to create RFCOMM info file"); | 2159 | rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444, |
2160 | bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops); | ||
2161 | if (!rfcomm_dlc_debugfs) | ||
2162 | BT_ERR("Failed to create RFCOMM debug file"); | ||
2163 | } | ||
2147 | 2164 | ||
2148 | err = rfcomm_init_ttys(); | 2165 | err = rfcomm_init_ttys(); |
2149 | if (err < 0) | 2166 | if (err < 0) |
@@ -2171,7 +2188,7 @@ unregister: | |||
2171 | 2188 | ||
2172 | static void __exit rfcomm_exit(void) | 2189 | static void __exit rfcomm_exit(void) |
2173 | { | 2190 | { |
2174 | class_remove_file(bt_class, &class_attr_rfcomm_dlc); | 2191 | debugfs_remove(rfcomm_dlc_debugfs); |
2175 | 2192 | ||
2176 | hci_unregister_cb(&rfcomm_cb); | 2193 | hci_unregister_cb(&rfcomm_cb); |
2177 | 2194 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index ca87d6ac6a20..7f439765403d 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <linux/skbuff.h> | 40 | #include <linux/skbuff.h> |
41 | #include <linux/list.h> | 41 | #include <linux/list.h> |
42 | #include <linux/device.h> | 42 | #include <linux/device.h> |
43 | #include <linux/debugfs.h> | ||
44 | #include <linux/seq_file.h> | ||
43 | #include <net/sock.h> | 45 | #include <net/sock.h> |
44 | 46 | ||
45 | #include <asm/system.h> | 47 | #include <asm/system.h> |
@@ -1061,28 +1063,38 @@ done: | |||
1061 | return result; | 1063 | return result; |
1062 | } | 1064 | } |
1063 | 1065 | ||
1064 | static ssize_t rfcomm_sock_sysfs_show(struct class *dev, | 1066 | static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p) |
1065 | struct class_attribute *attr, | ||
1066 | char *buf) | ||
1067 | { | 1067 | { |
1068 | struct sock *sk; | 1068 | struct sock *sk; |
1069 | struct hlist_node *node; | 1069 | struct hlist_node *node; |
1070 | char *str = buf; | ||
1071 | 1070 | ||
1072 | read_lock_bh(&rfcomm_sk_list.lock); | 1071 | read_lock_bh(&rfcomm_sk_list.lock); |
1073 | 1072 | ||
1074 | sk_for_each(sk, node, &rfcomm_sk_list.head) { | 1073 | sk_for_each(sk, node, &rfcomm_sk_list.head) { |
1075 | str += sprintf(str, "%s %s %d %d\n", | 1074 | seq_printf(f, "%s %s %d %d\n", |
1076 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | 1075 | batostr(&bt_sk(sk)->src), |
1076 | batostr(&bt_sk(sk)->dst), | ||
1077 | sk->sk_state, rfcomm_pi(sk)->channel); | 1077 | sk->sk_state, rfcomm_pi(sk)->channel); |
1078 | } | 1078 | } |
1079 | 1079 | ||
1080 | read_unlock_bh(&rfcomm_sk_list.lock); | 1080 | read_unlock_bh(&rfcomm_sk_list.lock); |
1081 | 1081 | ||
1082 | return (str - buf); | 1082 | return 0; |
1083 | } | 1083 | } |
1084 | 1084 | ||
1085 | static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL); | 1085 | static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file) |
1086 | { | ||
1087 | return single_open(file, rfcomm_sock_debugfs_show, inode->i_private); | ||
1088 | } | ||
1089 | |||
1090 | static const struct file_operations rfcomm_sock_debugfs_fops = { | ||
1091 | .open = rfcomm_sock_debugfs_open, | ||
1092 | .read = seq_read, | ||
1093 | .llseek = seq_lseek, | ||
1094 | .release = single_release, | ||
1095 | }; | ||
1096 | |||
1097 | static struct dentry *rfcomm_sock_debugfs; | ||
1086 | 1098 | ||
1087 | static const struct proto_ops rfcomm_sock_ops = { | 1099 | static const struct proto_ops rfcomm_sock_ops = { |
1088 | .family = PF_BLUETOOTH, | 1100 | .family = PF_BLUETOOTH, |
@@ -1122,8 +1134,12 @@ int __init rfcomm_init_sockets(void) | |||
1122 | if (err < 0) | 1134 | if (err < 0) |
1123 | goto error; | 1135 | goto error; |
1124 | 1136 | ||
1125 | if (class_create_file(bt_class, &class_attr_rfcomm) < 0) | 1137 | if (bt_debugfs) { |
1126 | BT_ERR("Failed to create RFCOMM info file"); | 1138 | rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444, |
1139 | bt_debugfs, NULL, &rfcomm_sock_debugfs_fops); | ||
1140 | if (!rfcomm_sock_debugfs) | ||
1141 | BT_ERR("Failed to create RFCOMM debug file"); | ||
1142 | } | ||
1127 | 1143 | ||
1128 | BT_INFO("RFCOMM socket layer initialized"); | 1144 | BT_INFO("RFCOMM socket layer initialized"); |
1129 | 1145 | ||
@@ -1137,7 +1153,7 @@ error: | |||
1137 | 1153 | ||
1138 | void rfcomm_cleanup_sockets(void) | 1154 | void rfcomm_cleanup_sockets(void) |
1139 | { | 1155 | { |
1140 | class_remove_file(bt_class, &class_attr_rfcomm); | 1156 | debugfs_remove(rfcomm_sock_debugfs); |
1141 | 1157 | ||
1142 | if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) | 1158 | if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) |
1143 | BT_ERR("RFCOMM socket layer unregistration failed"); | 1159 | BT_ERR("RFCOMM socket layer unregistration failed"); |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index f93b939539bc..e5b16b76b22e 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <linux/socket.h> | 38 | #include <linux/socket.h> |
39 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
40 | #include <linux/device.h> | 40 | #include <linux/device.h> |
41 | #include <linux/debugfs.h> | ||
42 | #include <linux/seq_file.h> | ||
41 | #include <linux/list.h> | 43 | #include <linux/list.h> |
42 | #include <net/sock.h> | 44 | #include <net/sock.h> |
43 | 45 | ||
@@ -953,28 +955,36 @@ drop: | |||
953 | return 0; | 955 | return 0; |
954 | } | 956 | } |
955 | 957 | ||
956 | static ssize_t sco_sysfs_show(struct class *dev, | 958 | static int sco_debugfs_show(struct seq_file *f, void *p) |
957 | struct class_attribute *attr, | ||
958 | char *buf) | ||
959 | { | 959 | { |
960 | struct sock *sk; | 960 | struct sock *sk; |
961 | struct hlist_node *node; | 961 | struct hlist_node *node; |
962 | char *str = buf; | ||
963 | 962 | ||
964 | read_lock_bh(&sco_sk_list.lock); | 963 | read_lock_bh(&sco_sk_list.lock); |
965 | 964 | ||
966 | sk_for_each(sk, node, &sco_sk_list.head) { | 965 | sk_for_each(sk, node, &sco_sk_list.head) { |
967 | str += sprintf(str, "%s %s %d\n", | 966 | seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src), |
968 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | 967 | batostr(&bt_sk(sk)->dst), sk->sk_state); |
969 | sk->sk_state); | ||
970 | } | 968 | } |
971 | 969 | ||
972 | read_unlock_bh(&sco_sk_list.lock); | 970 | read_unlock_bh(&sco_sk_list.lock); |
973 | 971 | ||
974 | return (str - buf); | 972 | return 0; |
975 | } | 973 | } |
976 | 974 | ||
977 | static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL); | 975 | static int sco_debugfs_open(struct inode *inode, struct file *file) |
976 | { | ||
977 | return single_open(file, sco_debugfs_show, inode->i_private); | ||
978 | } | ||
979 | |||
980 | static const struct file_operations sco_debugfs_fops = { | ||
981 | .open = sco_debugfs_open, | ||
982 | .read = seq_read, | ||
983 | .llseek = seq_lseek, | ||
984 | .release = single_release, | ||
985 | }; | ||
986 | |||
987 | static struct dentry *sco_debugfs; | ||
978 | 988 | ||
979 | static const struct proto_ops sco_sock_ops = { | 989 | static const struct proto_ops sco_sock_ops = { |
980 | .family = PF_BLUETOOTH, | 990 | .family = PF_BLUETOOTH, |
@@ -1032,8 +1042,12 @@ static int __init sco_init(void) | |||
1032 | goto error; | 1042 | goto error; |
1033 | } | 1043 | } |
1034 | 1044 | ||
1035 | if (class_create_file(bt_class, &class_attr_sco) < 0) | 1045 | if (bt_debugfs) { |
1036 | BT_ERR("Failed to create SCO info file"); | 1046 | sco_debugfs = debugfs_create_file("sco", 0444, |
1047 | bt_debugfs, NULL, &sco_debugfs_fops); | ||
1048 | if (!sco_debugfs) | ||
1049 | BT_ERR("Failed to create SCO debug file"); | ||
1050 | } | ||
1037 | 1051 | ||
1038 | BT_INFO("SCO (Voice Link) ver %s", VERSION); | 1052 | BT_INFO("SCO (Voice Link) ver %s", VERSION); |
1039 | BT_INFO("SCO socket layer initialized"); | 1053 | BT_INFO("SCO socket layer initialized"); |
@@ -1047,7 +1061,7 @@ error: | |||
1047 | 1061 | ||
1048 | static void __exit sco_exit(void) | 1062 | static void __exit sco_exit(void) |
1049 | { | 1063 | { |
1050 | class_remove_file(bt_class, &class_attr_sco); | 1064 | debugfs_remove(sco_debugfs); |
1051 | 1065 | ||
1052 | if (bt_sock_unregister(BTPROTO_SCO) < 0) | 1066 | if (bt_sock_unregister(BTPROTO_SCO) < 0) |
1053 | BT_ERR("SCO socket unregistration failed"); | 1067 | BT_ERR("SCO socket unregistration failed"); |
diff --git a/net/core/dev.c b/net/core/dev.c index bcc490cc9452..59d4394d2ce8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2483,6 +2483,7 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2483 | { | 2483 | { |
2484 | struct packet_type *ptype, *pt_prev; | 2484 | struct packet_type *ptype, *pt_prev; |
2485 | struct net_device *orig_dev; | 2485 | struct net_device *orig_dev; |
2486 | struct net_device *master; | ||
2486 | struct net_device *null_or_orig; | 2487 | struct net_device *null_or_orig; |
2487 | struct net_device *null_or_bond; | 2488 | struct net_device *null_or_bond; |
2488 | int ret = NET_RX_DROP; | 2489 | int ret = NET_RX_DROP; |
@@ -2503,11 +2504,12 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2503 | 2504 | ||
2504 | null_or_orig = NULL; | 2505 | null_or_orig = NULL; |
2505 | orig_dev = skb->dev; | 2506 | orig_dev = skb->dev; |
2506 | if (orig_dev->master) { | 2507 | master = ACCESS_ONCE(orig_dev->master); |
2507 | if (skb_bond_should_drop(skb)) | 2508 | if (master) { |
2509 | if (skb_bond_should_drop(skb, master)) | ||
2508 | null_or_orig = orig_dev; /* deliver only exact match */ | 2510 | null_or_orig = orig_dev; /* deliver only exact match */ |
2509 | else | 2511 | else |
2510 | skb->dev = orig_dev->master; | 2512 | skb->dev = master; |
2511 | } | 2513 | } |
2512 | 2514 | ||
2513 | __get_cpu_var(netdev_rx_stat).total++; | 2515 | __get_cpu_var(netdev_rx_stat).total++; |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index af5d89792860..01ef8ba9025c 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -961,7 +961,9 @@ fib_find_node(struct trie *t, u32 key) | |||
961 | struct node *n; | 961 | struct node *n; |
962 | 962 | ||
963 | pos = 0; | 963 | pos = 0; |
964 | n = rcu_dereference(t->trie); | 964 | n = rcu_dereference_check(t->trie, |
965 | rcu_read_lock_held() || | ||
966 | lockdep_rtnl_is_held()); | ||
965 | 967 | ||
966 | while (n != NULL && NODE_TYPE(n) == T_TNODE) { | 968 | while (n != NULL && NODE_TYPE(n) == T_TNODE) { |
967 | tn = (struct tnode *) n; | 969 | tn = (struct tnode *) n; |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index f47c9f76754b..f78402d097b3 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -810,11 +810,13 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
810 | tunnel->err_count = 0; | 810 | tunnel->err_count = 0; |
811 | } | 811 | } |
812 | 812 | ||
813 | max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen; | 813 | max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + rt->u.dst.header_len; |
814 | 814 | ||
815 | if (skb_headroom(skb) < max_headroom || skb_shared(skb)|| | 815 | if (skb_headroom(skb) < max_headroom || skb_shared(skb)|| |
816 | (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { | 816 | (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { |
817 | struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); | 817 | struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); |
818 | if (max_headroom > dev->needed_headroom) | ||
819 | dev->needed_headroom = max_headroom; | ||
818 | if (!new_skb) { | 820 | if (!new_skb) { |
819 | ip_rt_put(rt); | 821 | ip_rt_put(rt); |
820 | txq->tx_dropped++; | 822 | txq->tx_dropped++; |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8582e12e4a62..0b9d03c54dc3 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -802,6 +802,9 @@ static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock) | |||
802 | int line; | 802 | int line; |
803 | struct mfc_cache *uc, *c, **cp; | 803 | struct mfc_cache *uc, *c, **cp; |
804 | 804 | ||
805 | if (mfc->mfcc_parent >= MAXVIFS) | ||
806 | return -ENFILE; | ||
807 | |||
805 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); | 808 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); |
806 | 809 | ||
807 | for (cp = &net->ipv4.mfc_cache_array[line]; | 810 | for (cp = &net->ipv4.mfc_cache_array[line]; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a770df2493d2..54fd68c14c87 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1441,7 +1441,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1441 | dev_hold(rt->u.dst.dev); | 1441 | dev_hold(rt->u.dst.dev); |
1442 | if (rt->idev) | 1442 | if (rt->idev) |
1443 | in_dev_hold(rt->idev); | 1443 | in_dev_hold(rt->idev); |
1444 | rt->u.dst.obsolete = 0; | 1444 | rt->u.dst.obsolete = -1; |
1445 | rt->u.dst.lastuse = jiffies; | 1445 | rt->u.dst.lastuse = jiffies; |
1446 | rt->u.dst.path = &rt->u.dst; | 1446 | rt->u.dst.path = &rt->u.dst; |
1447 | rt->u.dst.neighbour = NULL; | 1447 | rt->u.dst.neighbour = NULL; |
@@ -1506,11 +1506,12 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) | |||
1506 | struct dst_entry *ret = dst; | 1506 | struct dst_entry *ret = dst; |
1507 | 1507 | ||
1508 | if (rt) { | 1508 | if (rt) { |
1509 | if (dst->obsolete) { | 1509 | if (dst->obsolete > 0) { |
1510 | ip_rt_put(rt); | 1510 | ip_rt_put(rt); |
1511 | ret = NULL; | 1511 | ret = NULL; |
1512 | } else if ((rt->rt_flags & RTCF_REDIRECTED) || | 1512 | } else if ((rt->rt_flags & RTCF_REDIRECTED) || |
1513 | rt->u.dst.expires) { | 1513 | (rt->u.dst.expires && |
1514 | time_after_eq(jiffies, rt->u.dst.expires))) { | ||
1514 | unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, | 1515 | unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, |
1515 | rt->fl.oif, | 1516 | rt->fl.oif, |
1516 | rt_genid(dev_net(dst->dev))); | 1517 | rt_genid(dev_net(dst->dev))); |
@@ -1726,7 +1727,9 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
1726 | 1727 | ||
1727 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) | 1728 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) |
1728 | { | 1729 | { |
1729 | return NULL; | 1730 | if (rt_is_expired((struct rtable *)dst)) |
1731 | return NULL; | ||
1732 | return dst; | ||
1730 | } | 1733 | } |
1731 | 1734 | ||
1732 | static void ipv4_dst_destroy(struct dst_entry *dst) | 1735 | static void ipv4_dst_destroy(struct dst_entry *dst) |
@@ -1888,7 +1891,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1888 | if (!rth) | 1891 | if (!rth) |
1889 | goto e_nobufs; | 1892 | goto e_nobufs; |
1890 | 1893 | ||
1891 | rth->u.dst.output= ip_rt_bug; | 1894 | rth->u.dst.output = ip_rt_bug; |
1895 | rth->u.dst.obsolete = -1; | ||
1892 | 1896 | ||
1893 | atomic_set(&rth->u.dst.__refcnt, 1); | 1897 | atomic_set(&rth->u.dst.__refcnt, 1); |
1894 | rth->u.dst.flags= DST_HOST; | 1898 | rth->u.dst.flags= DST_HOST; |
@@ -2054,6 +2058,7 @@ static int __mkroute_input(struct sk_buff *skb, | |||
2054 | rth->fl.oif = 0; | 2058 | rth->fl.oif = 0; |
2055 | rth->rt_spec_dst= spec_dst; | 2059 | rth->rt_spec_dst= spec_dst; |
2056 | 2060 | ||
2061 | rth->u.dst.obsolete = -1; | ||
2057 | rth->u.dst.input = ip_forward; | 2062 | rth->u.dst.input = ip_forward; |
2058 | rth->u.dst.output = ip_output; | 2063 | rth->u.dst.output = ip_output; |
2059 | rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev)); | 2064 | rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev)); |
@@ -2218,6 +2223,7 @@ local_input: | |||
2218 | goto e_nobufs; | 2223 | goto e_nobufs; |
2219 | 2224 | ||
2220 | rth->u.dst.output= ip_rt_bug; | 2225 | rth->u.dst.output= ip_rt_bug; |
2226 | rth->u.dst.obsolete = -1; | ||
2221 | rth->rt_genid = rt_genid(net); | 2227 | rth->rt_genid = rt_genid(net); |
2222 | 2228 | ||
2223 | atomic_set(&rth->u.dst.__refcnt, 1); | 2229 | atomic_set(&rth->u.dst.__refcnt, 1); |
@@ -2444,6 +2450,7 @@ static int __mkroute_output(struct rtable **result, | |||
2444 | rth->rt_spec_dst= fl->fl4_src; | 2450 | rth->rt_spec_dst= fl->fl4_src; |
2445 | 2451 | ||
2446 | rth->u.dst.output=ip_output; | 2452 | rth->u.dst.output=ip_output; |
2453 | rth->u.dst.obsolete = -1; | ||
2447 | rth->rt_genid = rt_genid(dev_net(dev_out)); | 2454 | rth->rt_genid = rt_genid(dev_net(dev_out)); |
2448 | 2455 | ||
2449 | RT_CACHE_STAT_INC(out_slow_tot); | 2456 | RT_CACHE_STAT_INC(out_slow_tot); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 5901010fad55..6afb6d8662b2 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -429,7 +429,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
429 | if (tp->urg_seq == tp->copied_seq && | 429 | if (tp->urg_seq == tp->copied_seq && |
430 | !sock_flag(sk, SOCK_URGINLINE) && | 430 | !sock_flag(sk, SOCK_URGINLINE) && |
431 | tp->urg_data) | 431 | tp->urg_data) |
432 | target--; | 432 | target++; |
433 | 433 | ||
434 | /* Potential race condition. If read of tp below will | 434 | /* Potential race condition. If read of tp below will |
435 | * escape above sk->sk_state, we can be illegally awaken | 435 | * escape above sk->sk_state, we can be illegally awaken |
@@ -1254,6 +1254,39 @@ static void tcp_prequeue_process(struct sock *sk) | |||
1254 | tp->ucopy.memory = 0; | 1254 | tp->ucopy.memory = 0; |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | #ifdef CONFIG_NET_DMA | ||
1258 | static void tcp_service_net_dma(struct sock *sk, bool wait) | ||
1259 | { | ||
1260 | dma_cookie_t done, used; | ||
1261 | dma_cookie_t last_issued; | ||
1262 | struct tcp_sock *tp = tcp_sk(sk); | ||
1263 | |||
1264 | if (!tp->ucopy.dma_chan) | ||
1265 | return; | ||
1266 | |||
1267 | last_issued = tp->ucopy.dma_cookie; | ||
1268 | dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); | ||
1269 | |||
1270 | do { | ||
1271 | if (dma_async_memcpy_complete(tp->ucopy.dma_chan, | ||
1272 | last_issued, &done, | ||
1273 | &used) == DMA_SUCCESS) { | ||
1274 | /* Safe to free early-copied skbs now */ | ||
1275 | __skb_queue_purge(&sk->sk_async_wait_queue); | ||
1276 | break; | ||
1277 | } else { | ||
1278 | struct sk_buff *skb; | ||
1279 | while ((skb = skb_peek(&sk->sk_async_wait_queue)) && | ||
1280 | (dma_async_is_complete(skb->dma_cookie, done, | ||
1281 | used) == DMA_SUCCESS)) { | ||
1282 | __skb_dequeue(&sk->sk_async_wait_queue); | ||
1283 | kfree_skb(skb); | ||
1284 | } | ||
1285 | } | ||
1286 | } while (wait); | ||
1287 | } | ||
1288 | #endif | ||
1289 | |||
1257 | static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) | 1290 | static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) |
1258 | { | 1291 | { |
1259 | struct sk_buff *skb; | 1292 | struct sk_buff *skb; |
@@ -1546,6 +1579,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1546 | /* __ Set realtime policy in scheduler __ */ | 1579 | /* __ Set realtime policy in scheduler __ */ |
1547 | } | 1580 | } |
1548 | 1581 | ||
1582 | #ifdef CONFIG_NET_DMA | ||
1583 | if (tp->ucopy.dma_chan) | ||
1584 | dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); | ||
1585 | #endif | ||
1549 | if (copied >= target) { | 1586 | if (copied >= target) { |
1550 | /* Do not sleep, just process backlog. */ | 1587 | /* Do not sleep, just process backlog. */ |
1551 | release_sock(sk); | 1588 | release_sock(sk); |
@@ -1554,6 +1591,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1554 | sk_wait_data(sk, &timeo); | 1591 | sk_wait_data(sk, &timeo); |
1555 | 1592 | ||
1556 | #ifdef CONFIG_NET_DMA | 1593 | #ifdef CONFIG_NET_DMA |
1594 | tcp_service_net_dma(sk, false); /* Don't block */ | ||
1557 | tp->ucopy.wakeup = 0; | 1595 | tp->ucopy.wakeup = 0; |
1558 | #endif | 1596 | #endif |
1559 | 1597 | ||
@@ -1633,6 +1671,9 @@ do_prequeue: | |||
1633 | copied = -EFAULT; | 1671 | copied = -EFAULT; |
1634 | break; | 1672 | break; |
1635 | } | 1673 | } |
1674 | |||
1675 | dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); | ||
1676 | |||
1636 | if ((offset + used) == skb->len) | 1677 | if ((offset + used) == skb->len) |
1637 | copied_early = 1; | 1678 | copied_early = 1; |
1638 | 1679 | ||
@@ -1702,27 +1743,9 @@ skip_copy: | |||
1702 | } | 1743 | } |
1703 | 1744 | ||
1704 | #ifdef CONFIG_NET_DMA | 1745 | #ifdef CONFIG_NET_DMA |
1705 | if (tp->ucopy.dma_chan) { | 1746 | tcp_service_net_dma(sk, true); /* Wait for queue to drain */ |
1706 | dma_cookie_t done, used; | 1747 | tp->ucopy.dma_chan = NULL; |
1707 | |||
1708 | dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); | ||
1709 | |||
1710 | while (dma_async_memcpy_complete(tp->ucopy.dma_chan, | ||
1711 | tp->ucopy.dma_cookie, &done, | ||
1712 | &used) == DMA_IN_PROGRESS) { | ||
1713 | /* do partial cleanup of sk_async_wait_queue */ | ||
1714 | while ((skb = skb_peek(&sk->sk_async_wait_queue)) && | ||
1715 | (dma_async_is_complete(skb->dma_cookie, done, | ||
1716 | used) == DMA_SUCCESS)) { | ||
1717 | __skb_dequeue(&sk->sk_async_wait_queue); | ||
1718 | kfree_skb(skb); | ||
1719 | } | ||
1720 | } | ||
1721 | 1748 | ||
1722 | /* Safe to free early-copied skbs now */ | ||
1723 | __skb_queue_purge(&sk->sk_async_wait_queue); | ||
1724 | tp->ucopy.dma_chan = NULL; | ||
1725 | } | ||
1726 | if (tp->ucopy.pinned_list) { | 1749 | if (tp->ucopy.pinned_list) { |
1727 | dma_unpin_iovec_pages(tp->ucopy.pinned_list); | 1750 | dma_unpin_iovec_pages(tp->ucopy.pinned_list); |
1728 | tp->ucopy.pinned_list = NULL; | 1751 | tp->ucopy.pinned_list = NULL; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 788851ca8c5d..c096a4218b8f 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -2511,6 +2511,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) | |||
2511 | int err; | 2511 | int err; |
2512 | unsigned int mss; | 2512 | unsigned int mss; |
2513 | 2513 | ||
2514 | if (packets == 0) | ||
2515 | return; | ||
2516 | |||
2514 | WARN_ON(packets > tp->packets_out); | 2517 | WARN_ON(packets > tp->packets_out); |
2515 | if (tp->lost_skb_hint) { | 2518 | if (tp->lost_skb_hint) { |
2516 | skb = tp->lost_skb_hint; | 2519 | skb = tp->lost_skb_hint; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 70df40980a87..f4df5f931f36 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -370,6 +370,11 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
370 | if (sk->sk_state == TCP_CLOSE) | 370 | if (sk->sk_state == TCP_CLOSE) |
371 | goto out; | 371 | goto out; |
372 | 372 | ||
373 | if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { | ||
374 | NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); | ||
375 | goto out; | ||
376 | } | ||
377 | |||
373 | icsk = inet_csk(sk); | 378 | icsk = inet_csk(sk); |
374 | tp = tcp_sk(sk); | 379 | tp = tcp_sk(sk); |
375 | seq = ntohl(th->seq); | 380 | seq = ntohl(th->seq); |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 52e0f74fdfe0..23e4ac0cc30e 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1113,6 +1113,9 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock) | |||
1113 | unsigned char ttls[MAXMIFS]; | 1113 | unsigned char ttls[MAXMIFS]; |
1114 | int i; | 1114 | int i; |
1115 | 1115 | ||
1116 | if (mfc->mf6cc_parent >= MAXMIFS) | ||
1117 | return -ENFILE; | ||
1118 | |||
1116 | memset(ttls, 255, MAXMIFS); | 1119 | memset(ttls, 255, MAXMIFS); |
1117 | for (i = 0; i < MAXMIFS; i++) { | 1120 | for (i = 0; i < MAXMIFS; i++) { |
1118 | if (IF_ISSET(i, &mfc->mf6cc_ifset)) | 1121 | if (IF_ISSET(i, &mfc->mf6cc_ifset)) |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 52cd3eff31dc..7fcb0e5d1213 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -879,7 +879,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) | |||
879 | 879 | ||
880 | rt = (struct rt6_info *) dst; | 880 | rt = (struct rt6_info *) dst; |
881 | 881 | ||
882 | if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) | 882 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) |
883 | return dst; | 883 | return dst; |
884 | 884 | ||
885 | return NULL; | 885 | return NULL; |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 2b2af631d2b8..569410a85953 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -582,7 +582,9 @@ nla_put_failure: | |||
582 | nlmsg_failure: | 582 | nlmsg_failure: |
583 | kfree_skb(skb); | 583 | kfree_skb(skb); |
584 | errout: | 584 | errout: |
585 | nfnetlink_set_err(net, 0, group, -ENOBUFS); | 585 | if (nfnetlink_set_err(net, 0, group, -ENOBUFS) > 0) |
586 | return -ENOBUFS; | ||
587 | |||
586 | return 0; | 588 | return 0; |
587 | } | 589 | } |
588 | #endif /* CONFIG_NF_CONNTRACK_EVENTS */ | 590 | #endif /* CONFIG_NF_CONNTRACK_EVENTS */ |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 8eb0cc23ada3..6afa3d52ea5f 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -113,9 +113,9 @@ int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, | |||
113 | } | 113 | } |
114 | EXPORT_SYMBOL_GPL(nfnetlink_send); | 114 | EXPORT_SYMBOL_GPL(nfnetlink_send); |
115 | 115 | ||
116 | void nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error) | 116 | int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error) |
117 | { | 117 | { |
118 | netlink_set_err(net->nfnl, pid, group, error); | 118 | return netlink_set_err(net->nfnl, pid, group, error); |
119 | } | 119 | } |
120 | EXPORT_SYMBOL_GPL(nfnetlink_set_err); | 120 | EXPORT_SYMBOL_GPL(nfnetlink_set_err); |
121 | 121 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 320d0423a240..acbbae1e89b5 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1093,6 +1093,7 @@ static inline int do_one_set_err(struct sock *sk, | |||
1093 | struct netlink_set_err_data *p) | 1093 | struct netlink_set_err_data *p) |
1094 | { | 1094 | { |
1095 | struct netlink_sock *nlk = nlk_sk(sk); | 1095 | struct netlink_sock *nlk = nlk_sk(sk); |
1096 | int ret = 0; | ||
1096 | 1097 | ||
1097 | if (sk == p->exclude_sk) | 1098 | if (sk == p->exclude_sk) |
1098 | goto out; | 1099 | goto out; |
@@ -1104,10 +1105,15 @@ static inline int do_one_set_err(struct sock *sk, | |||
1104 | !test_bit(p->group - 1, nlk->groups)) | 1105 | !test_bit(p->group - 1, nlk->groups)) |
1105 | goto out; | 1106 | goto out; |
1106 | 1107 | ||
1108 | if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) { | ||
1109 | ret = 1; | ||
1110 | goto out; | ||
1111 | } | ||
1112 | |||
1107 | sk->sk_err = p->code; | 1113 | sk->sk_err = p->code; |
1108 | sk->sk_error_report(sk); | 1114 | sk->sk_error_report(sk); |
1109 | out: | 1115 | out: |
1110 | return 0; | 1116 | return ret; |
1111 | } | 1117 | } |
1112 | 1118 | ||
1113 | /** | 1119 | /** |
@@ -1116,12 +1122,16 @@ out: | |||
1116 | * @pid: the PID of a process that we want to skip (if any) | 1122 | * @pid: the PID of a process that we want to skip (if any) |
1117 | * @groups: the broadcast group that will notice the error | 1123 | * @groups: the broadcast group that will notice the error |
1118 | * @code: error code, must be negative (as usual in kernelspace) | 1124 | * @code: error code, must be negative (as usual in kernelspace) |
1125 | * | ||
1126 | * This function returns the number of broadcast listeners that have set the | ||
1127 | * NETLINK_RECV_NO_ENOBUFS socket option. | ||
1119 | */ | 1128 | */ |
1120 | void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) | 1129 | int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) |
1121 | { | 1130 | { |
1122 | struct netlink_set_err_data info; | 1131 | struct netlink_set_err_data info; |
1123 | struct hlist_node *node; | 1132 | struct hlist_node *node; |
1124 | struct sock *sk; | 1133 | struct sock *sk; |
1134 | int ret = 0; | ||
1125 | 1135 | ||
1126 | info.exclude_sk = ssk; | 1136 | info.exclude_sk = ssk; |
1127 | info.pid = pid; | 1137 | info.pid = pid; |
@@ -1132,9 +1142,10 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) | |||
1132 | read_lock(&nl_table_lock); | 1142 | read_lock(&nl_table_lock); |
1133 | 1143 | ||
1134 | sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) | 1144 | sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) |
1135 | do_one_set_err(sk, &info); | 1145 | ret += do_one_set_err(sk, &info); |
1136 | 1146 | ||
1137 | read_unlock(&nl_table_lock); | 1147 | read_unlock(&nl_table_lock); |
1148 | return ret; | ||
1138 | } | 1149 | } |
1139 | EXPORT_SYMBOL(netlink_set_err); | 1150 | EXPORT_SYMBOL(netlink_set_err); |
1140 | 1151 | ||