diff options
Diffstat (limited to 'drivers/net')
23 files changed, 229 insertions, 185 deletions
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 5f9a7ad9b964..8aeec0b4601a 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c | |||
@@ -625,6 +625,7 @@ static int ems_usb_start(struct ems_usb *dev) | |||
625 | usb_unanchor_urb(urb); | 625 | usb_unanchor_urb(urb); |
626 | usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, | 626 | usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, |
627 | urb->transfer_dma); | 627 | urb->transfer_dma); |
628 | usb_free_urb(urb); | ||
628 | break; | 629 | break; |
629 | } | 630 | } |
630 | 631 | ||
@@ -798,8 +799,8 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne | |||
798 | * allowed (MAX_TX_URBS). | 799 | * allowed (MAX_TX_URBS). |
799 | */ | 800 | */ |
800 | if (!context) { | 801 | if (!context) { |
801 | usb_unanchor_urb(urb); | ||
802 | usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); | 802 | usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); |
803 | usb_free_urb(urb); | ||
803 | 804 | ||
804 | netdev_warn(netdev, "couldn't find free context\n"); | 805 | netdev_warn(netdev, "couldn't find free context\n"); |
805 | 806 | ||
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 8ee9d1556e6e..263dd921edc4 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c | |||
@@ -927,6 +927,9 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) | |||
927 | /* set LED in default state (end of init phase) */ | 927 | /* set LED in default state (end of init phase) */ |
928 | pcan_usb_pro_set_led(dev, 0, 1); | 928 | pcan_usb_pro_set_led(dev, 0, 1); |
929 | 929 | ||
930 | kfree(bi); | ||
931 | kfree(fi); | ||
932 | |||
930 | return 0; | 933 | return 0; |
931 | 934 | ||
932 | err_out: | 935 | err_out: |
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 50b853a79d77..46dfb1378c17 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c | |||
@@ -717,8 +717,7 @@ static int emac_open(struct net_device *dev) | |||
717 | if (netif_msg_ifup(db)) | 717 | if (netif_msg_ifup(db)) |
718 | dev_dbg(db->dev, "enabling %s\n", dev->name); | 718 | dev_dbg(db->dev, "enabling %s\n", dev->name); |
719 | 719 | ||
720 | if (devm_request_irq(db->dev, dev->irq, &emac_interrupt, | 720 | if (request_irq(dev->irq, &emac_interrupt, 0, dev->name, dev)) |
721 | 0, dev->name, dev)) | ||
722 | return -EAGAIN; | 721 | return -EAGAIN; |
723 | 722 | ||
724 | /* Initialize EMAC board */ | 723 | /* Initialize EMAC board */ |
@@ -774,6 +773,8 @@ static int emac_stop(struct net_device *ndev) | |||
774 | 773 | ||
775 | emac_shutdown(ndev); | 774 | emac_shutdown(ndev); |
776 | 775 | ||
776 | free_irq(ndev->irq, ndev); | ||
777 | |||
777 | return 0; | 778 | return 0; |
778 | } | 779 | } |
779 | 780 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 9a4a601ae6cf..a8def93f6b6b 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -16581,6 +16581,9 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent) | |||
16581 | /* Clear this out for sanity. */ | 16581 | /* Clear this out for sanity. */ |
16582 | tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); | 16582 | tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0); |
16583 | 16583 | ||
16584 | /* Clear TG3PCI_REG_BASE_ADDR to prevent hangs. */ | ||
16585 | tw32(TG3PCI_REG_BASE_ADDR, 0); | ||
16586 | |||
16584 | pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, | 16587 | pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, |
16585 | &pci_state_reg); | 16588 | &pci_state_reg); |
16586 | if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 && | 16589 | if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 && |
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 92ef4e5eddf7..05cd81aa9813 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -98,10 +98,6 @@ static void set_multicast_list(struct net_device *ndev); | |||
98 | * detected as not set during a prior frame transmission, then the | 98 | * detected as not set during a prior frame transmission, then the |
99 | * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs | 99 | * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs |
100 | * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in | 100 | * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in |
101 | * If the ready bit in the transmit buffer descriptor (TxBD[R]) is previously | ||
102 | * detected as not set during a prior frame transmission, then the | ||
103 | * ENET_TDAR[TDAR] bit is cleared at a later time, even if additional TxBDs | ||
104 | * were added to the ring and the ENET_TDAR[TDAR] bit is set. This results in | ||
105 | * frames not being transmitted until there is a 0-to-1 transition on | 101 | * frames not being transmitted until there is a 0-to-1 transition on |
106 | * ENET_TDAR[TDAR]. | 102 | * ENET_TDAR[TDAR]. |
107 | */ | 103 | */ |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index da5e8e441e26..efdf8a261b9a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
@@ -354,9 +354,13 @@ static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct( | |||
354 | struct rtnl_link_stats64 *vsi_stats = i40e_get_vsi_stats_struct(vsi); | 354 | struct rtnl_link_stats64 *vsi_stats = i40e_get_vsi_stats_struct(vsi); |
355 | int i; | 355 | int i; |
356 | 356 | ||
357 | |||
357 | if (test_bit(__I40E_DOWN, &vsi->state)) | 358 | if (test_bit(__I40E_DOWN, &vsi->state)) |
358 | return stats; | 359 | return stats; |
359 | 360 | ||
361 | if (!vsi->tx_rings) | ||
362 | return stats; | ||
363 | |||
360 | rcu_read_lock(); | 364 | rcu_read_lock(); |
361 | for (i = 0; i < vsi->num_queue_pairs; i++) { | 365 | for (i = 0; i < vsi->num_queue_pairs; i++) { |
362 | struct i40e_ring *tx_ring, *rx_ring; | 366 | struct i40e_ring *tx_ring, *rx_ring; |
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c index c4c4fe332c7e..ad2b74d95138 100644 --- a/drivers/net/ethernet/intel/igb/e1000_phy.c +++ b/drivers/net/ethernet/intel/igb/e1000_phy.c | |||
@@ -1728,7 +1728,10 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations, | |||
1728 | * ownership of the resources, wait and try again to | 1728 | * ownership of the resources, wait and try again to |
1729 | * see if they have relinquished the resources yet. | 1729 | * see if they have relinquished the resources yet. |
1730 | */ | 1730 | */ |
1731 | udelay(usec_interval); | 1731 | if (usec_interval >= 1000) |
1732 | mdelay(usec_interval/1000); | ||
1733 | else | ||
1734 | udelay(usec_interval); | ||
1732 | } | 1735 | } |
1733 | ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); | 1736 | ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); |
1734 | if (ret_val) | 1737 | if (ret_val) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 76a80a3b16c1..23a761fb3e29 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | |||
@@ -449,8 +449,9 @@ irqreturn_t qlcnic_83xx_intr(int irq, void *data) | |||
449 | 449 | ||
450 | qlcnic_83xx_poll_process_aen(adapter); | 450 | qlcnic_83xx_poll_process_aen(adapter); |
451 | 451 | ||
452 | if (ahw->diag_test == QLCNIC_INTERRUPT_TEST) { | 452 | if (ahw->diag_test) { |
453 | ahw->diag_cnt++; | 453 | if (ahw->diag_test == QLCNIC_INTERRUPT_TEST) |
454 | ahw->diag_cnt++; | ||
454 | qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter); | 455 | qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter); |
455 | return IRQ_HANDLED; | 456 | return IRQ_HANDLED; |
456 | } | 457 | } |
@@ -1347,11 +1348,6 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test, | |||
1347 | } | 1348 | } |
1348 | 1349 | ||
1349 | if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { | 1350 | if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { |
1350 | /* disable and free mailbox interrupt */ | ||
1351 | if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { | ||
1352 | qlcnic_83xx_enable_mbx_poll(adapter); | ||
1353 | qlcnic_83xx_free_mbx_intr(adapter); | ||
1354 | } | ||
1355 | adapter->ahw->loopback_state = 0; | 1351 | adapter->ahw->loopback_state = 0; |
1356 | adapter->ahw->hw_ops->setup_link_event(adapter, 1); | 1352 | adapter->ahw->hw_ops->setup_link_event(adapter, 1); |
1357 | } | 1353 | } |
@@ -1365,33 +1361,20 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev, | |||
1365 | { | 1361 | { |
1366 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1362 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1367 | struct qlcnic_host_sds_ring *sds_ring; | 1363 | struct qlcnic_host_sds_ring *sds_ring; |
1368 | int ring, err; | 1364 | int ring; |
1369 | 1365 | ||
1370 | clear_bit(__QLCNIC_DEV_UP, &adapter->state); | 1366 | clear_bit(__QLCNIC_DEV_UP, &adapter->state); |
1371 | if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { | 1367 | if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { |
1372 | for (ring = 0; ring < adapter->drv_sds_rings; ring++) { | 1368 | for (ring = 0; ring < adapter->drv_sds_rings; ring++) { |
1373 | sds_ring = &adapter->recv_ctx->sds_rings[ring]; | 1369 | sds_ring = &adapter->recv_ctx->sds_rings[ring]; |
1374 | qlcnic_83xx_disable_intr(adapter, sds_ring); | 1370 | if (adapter->flags & QLCNIC_MSIX_ENABLED) |
1375 | if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) | 1371 | qlcnic_83xx_disable_intr(adapter, sds_ring); |
1376 | qlcnic_83xx_enable_mbx_poll(adapter); | ||
1377 | } | 1372 | } |
1378 | } | 1373 | } |
1379 | 1374 | ||
1380 | qlcnic_fw_destroy_ctx(adapter); | 1375 | qlcnic_fw_destroy_ctx(adapter); |
1381 | qlcnic_detach(adapter); | 1376 | qlcnic_detach(adapter); |
1382 | 1377 | ||
1383 | if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { | ||
1384 | if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { | ||
1385 | err = qlcnic_83xx_setup_mbx_intr(adapter); | ||
1386 | qlcnic_83xx_disable_mbx_poll(adapter); | ||
1387 | if (err) { | ||
1388 | dev_err(&adapter->pdev->dev, | ||
1389 | "%s: failed to setup mbx interrupt\n", | ||
1390 | __func__); | ||
1391 | goto out; | ||
1392 | } | ||
1393 | } | ||
1394 | } | ||
1395 | adapter->ahw->diag_test = 0; | 1378 | adapter->ahw->diag_test = 0; |
1396 | adapter->drv_sds_rings = drv_sds_rings; | 1379 | adapter->drv_sds_rings = drv_sds_rings; |
1397 | 1380 | ||
@@ -1401,9 +1384,6 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev, | |||
1401 | if (netif_running(netdev)) | 1384 | if (netif_running(netdev)) |
1402 | __qlcnic_up(adapter, netdev); | 1385 | __qlcnic_up(adapter, netdev); |
1403 | 1386 | ||
1404 | if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST && | ||
1405 | !(adapter->flags & QLCNIC_MSIX_ENABLED)) | ||
1406 | qlcnic_83xx_disable_mbx_poll(adapter); | ||
1407 | out: | 1387 | out: |
1408 | netif_device_attach(netdev); | 1388 | netif_device_attach(netdev); |
1409 | } | 1389 | } |
@@ -3792,6 +3772,19 @@ static void qlcnic_83xx_decode_mbx_rsp(struct qlcnic_adapter *adapter, | |||
3792 | return; | 3772 | return; |
3793 | } | 3773 | } |
3794 | 3774 | ||
3775 | static inline void qlcnic_dump_mailbox_registers(struct qlcnic_adapter *adapter) | ||
3776 | { | ||
3777 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
3778 | u32 offset; | ||
3779 | |||
3780 | offset = QLCRDX(ahw, QLCNIC_DEF_INT_MASK); | ||
3781 | dev_info(&adapter->pdev->dev, "Mbx interrupt mask=0x%x, Mbx interrupt enable=0x%x, Host mbx control=0x%x, Fw mbx control=0x%x", | ||
3782 | readl(ahw->pci_base0 + offset), | ||
3783 | QLCRDX(ahw, QLCNIC_MBX_INTR_ENBL), | ||
3784 | QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL), | ||
3785 | QLCRDX(ahw, QLCNIC_FW_MBX_CTRL)); | ||
3786 | } | ||
3787 | |||
3795 | static void qlcnic_83xx_mailbox_worker(struct work_struct *work) | 3788 | static void qlcnic_83xx_mailbox_worker(struct work_struct *work) |
3796 | { | 3789 | { |
3797 | struct qlcnic_mailbox *mbx = container_of(work, struct qlcnic_mailbox, | 3790 | struct qlcnic_mailbox *mbx = container_of(work, struct qlcnic_mailbox, |
@@ -3836,6 +3829,8 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work) | |||
3836 | __func__, cmd->cmd_op, cmd->type, ahw->pci_func, | 3829 | __func__, cmd->cmd_op, cmd->type, ahw->pci_func, |
3837 | ahw->op_mode); | 3830 | ahw->op_mode); |
3838 | clear_bit(QLC_83XX_MBX_READY, &mbx->status); | 3831 | clear_bit(QLC_83XX_MBX_READY, &mbx->status); |
3832 | qlcnic_dump_mailbox_registers(adapter); | ||
3833 | qlcnic_83xx_get_mbx_data(adapter, cmd); | ||
3839 | qlcnic_dump_mbx(adapter, cmd); | 3834 | qlcnic_dump_mbx(adapter, cmd); |
3840 | qlcnic_83xx_idc_request_reset(adapter, | 3835 | qlcnic_83xx_idc_request_reset(adapter, |
3841 | QLCNIC_FORCE_FW_DUMP_KEY); | 3836 | QLCNIC_FORCE_FW_DUMP_KEY); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 7288f7399bc1..34d291168b79 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | |||
@@ -672,4 +672,5 @@ pci_ers_result_t qlcnic_83xx_io_error_detected(struct pci_dev *, | |||
672 | pci_channel_state_t); | 672 | pci_channel_state_t); |
673 | pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *); | 673 | pci_ers_result_t qlcnic_83xx_io_slot_reset(struct pci_dev *); |
674 | void qlcnic_83xx_io_resume(struct pci_dev *); | 674 | void qlcnic_83xx_io_resume(struct pci_dev *); |
675 | void qlcnic_83xx_stop_hw(struct qlcnic_adapter *); | ||
675 | #endif | 676 | #endif |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 70767c137c7a..22ae884728b8 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -739,6 +739,7 @@ static int qlcnic_83xx_idc_unknown_state(struct qlcnic_adapter *adapter) | |||
739 | adapter->ahw->idc.err_code = -EIO; | 739 | adapter->ahw->idc.err_code = -EIO; |
740 | dev_err(&adapter->pdev->dev, | 740 | dev_err(&adapter->pdev->dev, |
741 | "%s: Device in unknown state\n", __func__); | 741 | "%s: Device in unknown state\n", __func__); |
742 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | ||
742 | return 0; | 743 | return 0; |
743 | } | 744 | } |
744 | 745 | ||
@@ -817,7 +818,6 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) | |||
817 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 818 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
818 | struct qlcnic_mailbox *mbx = ahw->mailbox; | 819 | struct qlcnic_mailbox *mbx = ahw->mailbox; |
819 | int ret = 0; | 820 | int ret = 0; |
820 | u32 owner; | ||
821 | u32 val; | 821 | u32 val; |
822 | 822 | ||
823 | /* Perform NIC configuration based ready state entry actions */ | 823 | /* Perform NIC configuration based ready state entry actions */ |
@@ -847,9 +847,9 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) | |||
847 | set_bit(__QLCNIC_RESETTING, &adapter->state); | 847 | set_bit(__QLCNIC_RESETTING, &adapter->state); |
848 | qlcnic_83xx_idc_enter_need_reset_state(adapter, 1); | 848 | qlcnic_83xx_idc_enter_need_reset_state(adapter, 1); |
849 | } else { | 849 | } else { |
850 | owner = qlcnic_83xx_idc_find_reset_owner_id(adapter); | 850 | netdev_info(adapter->netdev, "%s: Auto firmware recovery is disabled\n", |
851 | if (ahw->pci_func == owner) | 851 | __func__); |
852 | qlcnic_dump_fw(adapter); | 852 | qlcnic_83xx_idc_enter_failed_state(adapter, 1); |
853 | } | 853 | } |
854 | return -EIO; | 854 | return -EIO; |
855 | } | 855 | } |
@@ -947,13 +947,26 @@ static int qlcnic_83xx_idc_need_quiesce_state(struct qlcnic_adapter *adapter) | |||
947 | return 0; | 947 | return 0; |
948 | } | 948 | } |
949 | 949 | ||
950 | static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter) | 950 | static void qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter) |
951 | { | 951 | { |
952 | dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__); | 952 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
953 | u32 val, owner; | ||
954 | |||
955 | val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL); | ||
956 | if (val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY) { | ||
957 | owner = qlcnic_83xx_idc_find_reset_owner_id(adapter); | ||
958 | if (ahw->pci_func == owner) { | ||
959 | qlcnic_83xx_stop_hw(adapter); | ||
960 | qlcnic_dump_fw(adapter); | ||
961 | } | ||
962 | } | ||
963 | |||
964 | netdev_warn(adapter->netdev, "%s: Reboot will be required to recover the adapter!!\n", | ||
965 | __func__); | ||
953 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | 966 | clear_bit(__QLCNIC_RESETTING, &adapter->state); |
954 | adapter->ahw->idc.err_code = -EIO; | 967 | ahw->idc.err_code = -EIO; |
955 | 968 | ||
956 | return 0; | 969 | return; |
957 | } | 970 | } |
958 | 971 | ||
959 | static int qlcnic_83xx_idc_quiesce_state(struct qlcnic_adapter *adapter) | 972 | static int qlcnic_83xx_idc_quiesce_state(struct qlcnic_adapter *adapter) |
@@ -1062,12 +1075,6 @@ void qlcnic_83xx_idc_poll_dev_state(struct work_struct *work) | |||
1062 | adapter->ahw->idc.prev_state = adapter->ahw->idc.curr_state; | 1075 | adapter->ahw->idc.prev_state = adapter->ahw->idc.curr_state; |
1063 | qlcnic_83xx_periodic_tasks(adapter); | 1076 | qlcnic_83xx_periodic_tasks(adapter); |
1064 | 1077 | ||
1065 | /* Do not reschedule if firmaware is in hanged state and auto | ||
1066 | * recovery is disabled | ||
1067 | */ | ||
1068 | if ((adapter->flags & QLCNIC_FW_HANG) && !qlcnic_auto_fw_reset) | ||
1069 | return; | ||
1070 | |||
1071 | /* Re-schedule the function */ | 1078 | /* Re-schedule the function */ |
1072 | if (test_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status)) | 1079 | if (test_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status)) |
1073 | qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state, | 1080 | qlcnic_schedule_work(adapter, qlcnic_83xx_idc_poll_dev_state, |
@@ -1218,10 +1225,10 @@ void qlcnic_83xx_idc_request_reset(struct qlcnic_adapter *adapter, u32 key) | |||
1218 | } | 1225 | } |
1219 | 1226 | ||
1220 | val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL); | 1227 | val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL); |
1221 | if ((val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY) || | 1228 | if (val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY) { |
1222 | !qlcnic_auto_fw_reset) { | 1229 | netdev_info(adapter->netdev, "%s: Auto firmware recovery is disabled\n", |
1223 | dev_err(&adapter->pdev->dev, | 1230 | __func__); |
1224 | "%s:failed, device in non reset mode\n", __func__); | 1231 | qlcnic_83xx_idc_enter_failed_state(adapter, 0); |
1225 | qlcnic_83xx_unlock_driver(adapter); | 1232 | qlcnic_83xx_unlock_driver(adapter); |
1226 | return; | 1233 | return; |
1227 | } | 1234 | } |
@@ -1253,24 +1260,24 @@ static int qlcnic_83xx_copy_bootloader(struct qlcnic_adapter *adapter) | |||
1253 | if (size & 0xF) | 1260 | if (size & 0xF) |
1254 | size = (size + 16) & ~0xF; | 1261 | size = (size + 16) & ~0xF; |
1255 | 1262 | ||
1256 | p_cache = kzalloc(size, GFP_KERNEL); | 1263 | p_cache = vzalloc(size); |
1257 | if (p_cache == NULL) | 1264 | if (p_cache == NULL) |
1258 | return -ENOMEM; | 1265 | return -ENOMEM; |
1259 | 1266 | ||
1260 | ret = qlcnic_83xx_lockless_flash_read32(adapter, src, p_cache, | 1267 | ret = qlcnic_83xx_lockless_flash_read32(adapter, src, p_cache, |
1261 | size / sizeof(u32)); | 1268 | size / sizeof(u32)); |
1262 | if (ret) { | 1269 | if (ret) { |
1263 | kfree(p_cache); | 1270 | vfree(p_cache); |
1264 | return ret; | 1271 | return ret; |
1265 | } | 1272 | } |
1266 | /* 16 byte write to MS memory */ | 1273 | /* 16 byte write to MS memory */ |
1267 | ret = qlcnic_83xx_ms_mem_write128(adapter, dest, (u32 *)p_cache, | 1274 | ret = qlcnic_83xx_ms_mem_write128(adapter, dest, (u32 *)p_cache, |
1268 | size / 16); | 1275 | size / 16); |
1269 | if (ret) { | 1276 | if (ret) { |
1270 | kfree(p_cache); | 1277 | vfree(p_cache); |
1271 | return ret; | 1278 | return ret; |
1272 | } | 1279 | } |
1273 | kfree(p_cache); | 1280 | vfree(p_cache); |
1274 | 1281 | ||
1275 | return ret; | 1282 | return ret; |
1276 | } | 1283 | } |
@@ -1938,7 +1945,7 @@ static void qlcnic_83xx_exec_template_cmd(struct qlcnic_adapter *p_dev, | |||
1938 | p_dev->ahw->reset.seq_index = index; | 1945 | p_dev->ahw->reset.seq_index = index; |
1939 | } | 1946 | } |
1940 | 1947 | ||
1941 | static void qlcnic_83xx_stop_hw(struct qlcnic_adapter *p_dev) | 1948 | void qlcnic_83xx_stop_hw(struct qlcnic_adapter *p_dev) |
1942 | { | 1949 | { |
1943 | p_dev->ahw->reset.seq_index = 0; | 1950 | p_dev->ahw->reset.seq_index = 0; |
1944 | 1951 | ||
@@ -1993,6 +2000,14 @@ static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter) | |||
1993 | val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL); | 2000 | val = QLCRDX(adapter->ahw, QLC_83XX_IDC_CTRL); |
1994 | if (!(val & QLC_83XX_IDC_GRACEFULL_RESET)) | 2001 | if (!(val & QLC_83XX_IDC_GRACEFULL_RESET)) |
1995 | qlcnic_dump_fw(adapter); | 2002 | qlcnic_dump_fw(adapter); |
2003 | |||
2004 | if (val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY) { | ||
2005 | netdev_info(adapter->netdev, "%s: Auto firmware recovery is disabled\n", | ||
2006 | __func__); | ||
2007 | qlcnic_83xx_idc_enter_failed_state(adapter, 1); | ||
2008 | return err; | ||
2009 | } | ||
2010 | |||
1996 | qlcnic_83xx_init_hw(adapter); | 2011 | qlcnic_83xx_init_hw(adapter); |
1997 | 2012 | ||
1998 | if (qlcnic_83xx_copy_bootloader(adapter)) | 2013 | if (qlcnic_83xx_copy_bootloader(adapter)) |
@@ -2072,8 +2087,8 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter) | |||
2072 | ahw->nic_mode = QLCNIC_DEFAULT_MODE; | 2087 | ahw->nic_mode = QLCNIC_DEFAULT_MODE; |
2073 | adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver; | 2088 | adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver; |
2074 | ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry; | 2089 | ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry; |
2075 | adapter->max_sds_rings = ahw->max_rx_ques; | 2090 | adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS; |
2076 | adapter->max_tx_rings = ahw->max_tx_ques; | 2091 | adapter->max_tx_rings = QLCNIC_MAX_TX_RINGS; |
2077 | } else { | 2092 | } else { |
2078 | return -EIO; | 2093 | return -EIO; |
2079 | } | 2094 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 022401f80065..45fa6eff56c9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | |||
@@ -670,30 +670,25 @@ qlcnic_set_ringparam(struct net_device *dev, | |||
670 | static int qlcnic_validate_ring_count(struct qlcnic_adapter *adapter, | 670 | static int qlcnic_validate_ring_count(struct qlcnic_adapter *adapter, |
671 | u8 rx_ring, u8 tx_ring) | 671 | u8 rx_ring, u8 tx_ring) |
672 | { | 672 | { |
673 | if (rx_ring == 0 || tx_ring == 0) | ||
674 | return -EINVAL; | ||
675 | |||
673 | if (rx_ring != 0) { | 676 | if (rx_ring != 0) { |
674 | if (rx_ring > adapter->max_sds_rings) { | 677 | if (rx_ring > adapter->max_sds_rings) { |
675 | netdev_err(adapter->netdev, "Invalid ring count, SDS ring count %d should not be greater than max %d driver sds rings.\n", | 678 | netdev_err(adapter->netdev, |
679 | "Invalid ring count, SDS ring count %d should not be greater than max %d driver sds rings.\n", | ||
676 | rx_ring, adapter->max_sds_rings); | 680 | rx_ring, adapter->max_sds_rings); |
677 | return -EINVAL; | 681 | return -EINVAL; |
678 | } | 682 | } |
679 | } | 683 | } |
680 | 684 | ||
681 | if (tx_ring != 0) { | 685 | if (tx_ring != 0) { |
682 | if (qlcnic_82xx_check(adapter) && | 686 | if (tx_ring > adapter->max_tx_rings) { |
683 | (tx_ring > adapter->max_tx_rings)) { | ||
684 | netdev_err(adapter->netdev, | 687 | netdev_err(adapter->netdev, |
685 | "Invalid ring count, Tx ring count %d should not be greater than max %d driver Tx rings.\n", | 688 | "Invalid ring count, Tx ring count %d should not be greater than max %d driver Tx rings.\n", |
686 | tx_ring, adapter->max_tx_rings); | 689 | tx_ring, adapter->max_tx_rings); |
687 | return -EINVAL; | 690 | return -EINVAL; |
688 | } | 691 | } |
689 | |||
690 | if (qlcnic_83xx_check(adapter) && | ||
691 | (tx_ring > QLCNIC_SINGLE_RING)) { | ||
692 | netdev_err(adapter->netdev, | ||
693 | "Invalid ring count, Tx ring count %d should not be greater than %d driver Tx rings.\n", | ||
694 | tx_ring, QLCNIC_SINGLE_RING); | ||
695 | return -EINVAL; | ||
696 | } | ||
697 | } | 692 | } |
698 | 693 | ||
699 | return 0; | 694 | return 0; |
@@ -951,6 +946,7 @@ static int qlcnic_irq_test(struct net_device *netdev) | |||
951 | struct qlcnic_hardware_context *ahw = adapter->ahw; | 946 | struct qlcnic_hardware_context *ahw = adapter->ahw; |
952 | struct qlcnic_cmd_args cmd; | 947 | struct qlcnic_cmd_args cmd; |
953 | int ret, drv_sds_rings = adapter->drv_sds_rings; | 948 | int ret, drv_sds_rings = adapter->drv_sds_rings; |
949 | int drv_tx_rings = adapter->drv_tx_rings; | ||
954 | 950 | ||
955 | if (qlcnic_83xx_check(adapter)) | 951 | if (qlcnic_83xx_check(adapter)) |
956 | return qlcnic_83xx_interrupt_test(netdev); | 952 | return qlcnic_83xx_interrupt_test(netdev); |
@@ -983,6 +979,7 @@ free_diag_res: | |||
983 | 979 | ||
984 | clear_diag_irq: | 980 | clear_diag_irq: |
985 | adapter->drv_sds_rings = drv_sds_rings; | 981 | adapter->drv_sds_rings = drv_sds_rings; |
982 | adapter->drv_tx_rings = drv_tx_rings; | ||
986 | clear_bit(__QLCNIC_RESETTING, &adapter->state); | 983 | clear_bit(__QLCNIC_RESETTING, &adapter->state); |
987 | 984 | ||
988 | return ret; | 985 | return ret; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index 9e1494aab4d7..9484248a8540 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | |||
@@ -687,17 +687,11 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup) | |||
687 | if (adapter->ahw->linkup && !linkup) { | 687 | if (adapter->ahw->linkup && !linkup) { |
688 | netdev_info(netdev, "NIC Link is down\n"); | 688 | netdev_info(netdev, "NIC Link is down\n"); |
689 | adapter->ahw->linkup = 0; | 689 | adapter->ahw->linkup = 0; |
690 | if (netif_running(netdev)) { | 690 | netif_carrier_off(netdev); |
691 | netif_carrier_off(netdev); | ||
692 | netif_tx_stop_all_queues(netdev); | ||
693 | } | ||
694 | } else if (!adapter->ahw->linkup && linkup) { | 691 | } else if (!adapter->ahw->linkup && linkup) { |
695 | netdev_info(netdev, "NIC Link is up\n"); | 692 | netdev_info(netdev, "NIC Link is up\n"); |
696 | adapter->ahw->linkup = 1; | 693 | adapter->ahw->linkup = 1; |
697 | if (netif_running(netdev)) { | 694 | netif_carrier_on(netdev); |
698 | netif_carrier_on(netdev); | ||
699 | netif_wake_queue(netdev); | ||
700 | } | ||
701 | } | 695 | } |
702 | } | 696 | } |
703 | 697 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 7bfbd428eb7f..bf132c9f916f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -1179,6 +1179,7 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter) | |||
1179 | } else { | 1179 | } else { |
1180 | adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE; | 1180 | adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE; |
1181 | adapter->max_tx_rings = QLCNIC_MAX_HW_TX_RINGS; | 1181 | adapter->max_tx_rings = QLCNIC_MAX_HW_TX_RINGS; |
1182 | adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS; | ||
1182 | adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; | 1183 | adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; |
1183 | } | 1184 | } |
1184 | 1185 | ||
@@ -1941,7 +1942,6 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test) | |||
1941 | qlcnic_detach(adapter); | 1942 | qlcnic_detach(adapter); |
1942 | 1943 | ||
1943 | adapter->drv_sds_rings = QLCNIC_SINGLE_RING; | 1944 | adapter->drv_sds_rings = QLCNIC_SINGLE_RING; |
1944 | adapter->drv_tx_rings = QLCNIC_SINGLE_RING; | ||
1945 | adapter->ahw->diag_test = test; | 1945 | adapter->ahw->diag_test = test; |
1946 | adapter->ahw->linkup = 0; | 1946 | adapter->ahw->linkup = 0; |
1947 | 1947 | ||
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index b84c4ddf7add..96f79f7c4395 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c | |||
@@ -81,6 +81,7 @@ static const char version[] = | |||
81 | #include <linux/mii.h> | 81 | #include <linux/mii.h> |
82 | #include <linux/workqueue.h> | 82 | #include <linux/workqueue.h> |
83 | #include <linux/of.h> | 83 | #include <linux/of.h> |
84 | #include <linux/of_device.h> | ||
84 | 85 | ||
85 | #include <linux/netdevice.h> | 86 | #include <linux/netdevice.h> |
86 | #include <linux/etherdevice.h> | 87 | #include <linux/etherdevice.h> |
@@ -2183,6 +2184,15 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device * | |||
2183 | } | 2184 | } |
2184 | } | 2185 | } |
2185 | 2186 | ||
2187 | #if IS_BUILTIN(CONFIG_OF) | ||
2188 | static const struct of_device_id smc91x_match[] = { | ||
2189 | { .compatible = "smsc,lan91c94", }, | ||
2190 | { .compatible = "smsc,lan91c111", }, | ||
2191 | {}, | ||
2192 | }; | ||
2193 | MODULE_DEVICE_TABLE(of, smc91x_match); | ||
2194 | #endif | ||
2195 | |||
2186 | /* | 2196 | /* |
2187 | * smc_init(void) | 2197 | * smc_init(void) |
2188 | * Input parameters: | 2198 | * Input parameters: |
@@ -2197,6 +2207,7 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device * | |||
2197 | static int smc_drv_probe(struct platform_device *pdev) | 2207 | static int smc_drv_probe(struct platform_device *pdev) |
2198 | { | 2208 | { |
2199 | struct smc91x_platdata *pd = dev_get_platdata(&pdev->dev); | 2209 | struct smc91x_platdata *pd = dev_get_platdata(&pdev->dev); |
2210 | const struct of_device_id *match = NULL; | ||
2200 | struct smc_local *lp; | 2211 | struct smc_local *lp; |
2201 | struct net_device *ndev; | 2212 | struct net_device *ndev; |
2202 | struct resource *res, *ires; | 2213 | struct resource *res, *ires; |
@@ -2216,11 +2227,34 @@ static int smc_drv_probe(struct platform_device *pdev) | |||
2216 | */ | 2227 | */ |
2217 | 2228 | ||
2218 | lp = netdev_priv(ndev); | 2229 | lp = netdev_priv(ndev); |
2230 | lp->cfg.flags = 0; | ||
2219 | 2231 | ||
2220 | if (pd) { | 2232 | if (pd) { |
2221 | memcpy(&lp->cfg, pd, sizeof(lp->cfg)); | 2233 | memcpy(&lp->cfg, pd, sizeof(lp->cfg)); |
2222 | lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags); | 2234 | lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags); |
2223 | } else { | 2235 | } |
2236 | |||
2237 | #if IS_BUILTIN(CONFIG_OF) | ||
2238 | match = of_match_device(of_match_ptr(smc91x_match), &pdev->dev); | ||
2239 | if (match) { | ||
2240 | struct device_node *np = pdev->dev.of_node; | ||
2241 | u32 val; | ||
2242 | |||
2243 | /* Combination of IO widths supported, default to 16-bit */ | ||
2244 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | ||
2245 | if (val & 1) | ||
2246 | lp->cfg.flags |= SMC91X_USE_8BIT; | ||
2247 | if ((val == 0) || (val & 2)) | ||
2248 | lp->cfg.flags |= SMC91X_USE_16BIT; | ||
2249 | if (val & 4) | ||
2250 | lp->cfg.flags |= SMC91X_USE_32BIT; | ||
2251 | } else { | ||
2252 | lp->cfg.flags |= SMC91X_USE_16BIT; | ||
2253 | } | ||
2254 | } | ||
2255 | #endif | ||
2256 | |||
2257 | if (!pd && !match) { | ||
2224 | lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0; | 2258 | lp->cfg.flags |= (SMC_CAN_USE_8BIT) ? SMC91X_USE_8BIT : 0; |
2225 | lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0; | 2259 | lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0; |
2226 | lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0; | 2260 | lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0; |
@@ -2369,15 +2403,6 @@ static int smc_drv_resume(struct device *dev) | |||
2369 | return 0; | 2403 | return 0; |
2370 | } | 2404 | } |
2371 | 2405 | ||
2372 | #ifdef CONFIG_OF | ||
2373 | static const struct of_device_id smc91x_match[] = { | ||
2374 | { .compatible = "smsc,lan91c94", }, | ||
2375 | { .compatible = "smsc,lan91c111", }, | ||
2376 | {}, | ||
2377 | }; | ||
2378 | MODULE_DEVICE_TABLE(of, smc91x_match); | ||
2379 | #endif | ||
2380 | |||
2381 | static struct dev_pm_ops smc_drv_pm_ops = { | 2406 | static struct dev_pm_ops smc_drv_pm_ops = { |
2382 | .suspend = smc_drv_suspend, | 2407 | .suspend = smc_drv_suspend, |
2383 | .resume = smc_drv_resume, | 2408 | .resume = smc_drv_resume, |
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 915eca910569..243fffbe18e8 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c | |||
@@ -1151,6 +1151,12 @@ static int cpsw_ndo_open(struct net_device *ndev) | |||
1151 | * receive descs | 1151 | * receive descs |
1152 | */ | 1152 | */ |
1153 | cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i); | 1153 | cpsw_info(priv, ifup, "submitted %d rx descriptors\n", i); |
1154 | |||
1155 | if (cpts_register(&priv->pdev->dev, priv->cpts, | ||
1156 | priv->data.cpts_clock_mult, | ||
1157 | priv->data.cpts_clock_shift)) | ||
1158 | dev_err(priv->dev, "error registering cpts device\n"); | ||
1159 | |||
1154 | } | 1160 | } |
1155 | 1161 | ||
1156 | /* Enable Interrupt pacing if configured */ | 1162 | /* Enable Interrupt pacing if configured */ |
@@ -1197,6 +1203,7 @@ static int cpsw_ndo_stop(struct net_device *ndev) | |||
1197 | netif_carrier_off(priv->ndev); | 1203 | netif_carrier_off(priv->ndev); |
1198 | 1204 | ||
1199 | if (cpsw_common_res_usage_state(priv) <= 1) { | 1205 | if (cpsw_common_res_usage_state(priv) <= 1) { |
1206 | cpts_unregister(priv->cpts); | ||
1200 | cpsw_intr_disable(priv); | 1207 | cpsw_intr_disable(priv); |
1201 | cpdma_ctlr_int_ctrl(priv->dma, false); | 1208 | cpdma_ctlr_int_ctrl(priv->dma, false); |
1202 | cpdma_ctlr_stop(priv->dma); | 1209 | cpdma_ctlr_stop(priv->dma); |
@@ -2005,9 +2012,15 @@ static int cpsw_probe(struct platform_device *pdev) | |||
2005 | goto clean_runtime_disable_ret; | 2012 | goto clean_runtime_disable_ret; |
2006 | } | 2013 | } |
2007 | priv->regs = ss_regs; | 2014 | priv->regs = ss_regs; |
2008 | priv->version = __raw_readl(&priv->regs->id_ver); | ||
2009 | priv->host_port = HOST_PORT_NUM; | 2015 | priv->host_port = HOST_PORT_NUM; |
2010 | 2016 | ||
2017 | /* Need to enable clocks with runtime PM api to access module | ||
2018 | * registers | ||
2019 | */ | ||
2020 | pm_runtime_get_sync(&pdev->dev); | ||
2021 | priv->version = readl(&priv->regs->id_ver); | ||
2022 | pm_runtime_put_sync(&pdev->dev); | ||
2023 | |||
2011 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 2024 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
2012 | priv->wr_regs = devm_ioremap_resource(&pdev->dev, res); | 2025 | priv->wr_regs = devm_ioremap_resource(&pdev->dev, res); |
2013 | if (IS_ERR(priv->wr_regs)) { | 2026 | if (IS_ERR(priv->wr_regs)) { |
@@ -2177,8 +2190,6 @@ static int cpsw_remove(struct platform_device *pdev) | |||
2177 | unregister_netdev(cpsw_get_slave_ndev(priv, 1)); | 2190 | unregister_netdev(cpsw_get_slave_ndev(priv, 1)); |
2178 | unregister_netdev(ndev); | 2191 | unregister_netdev(ndev); |
2179 | 2192 | ||
2180 | cpts_unregister(priv->cpts); | ||
2181 | |||
2182 | cpsw_ale_destroy(priv->ale); | 2193 | cpsw_ale_destroy(priv->ale); |
2183 | cpdma_chan_destroy(priv->txch); | 2194 | cpdma_chan_destroy(priv->txch); |
2184 | cpdma_chan_destroy(priv->rxch); | 2195 | cpdma_chan_destroy(priv->rxch); |
diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 74234a51c851..fefb8cd5eb65 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c | |||
@@ -163,26 +163,9 @@ static void xemaclite_enable_interrupts(struct net_local *drvdata) | |||
163 | __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, | 163 | __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, |
164 | drvdata->base_addr + XEL_TSR_OFFSET); | 164 | drvdata->base_addr + XEL_TSR_OFFSET); |
165 | 165 | ||
166 | /* Enable the Tx interrupts for the second Buffer if | ||
167 | * configured in HW */ | ||
168 | if (drvdata->tx_ping_pong != 0) { | ||
169 | reg_data = __raw_readl(drvdata->base_addr + | ||
170 | XEL_BUFFER_OFFSET + XEL_TSR_OFFSET); | ||
171 | __raw_writel(reg_data | XEL_TSR_XMIT_IE_MASK, | ||
172 | drvdata->base_addr + XEL_BUFFER_OFFSET + | ||
173 | XEL_TSR_OFFSET); | ||
174 | } | ||
175 | |||
176 | /* Enable the Rx interrupts for the first buffer */ | 166 | /* Enable the Rx interrupts for the first buffer */ |
177 | __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET); | 167 | __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + XEL_RSR_OFFSET); |
178 | 168 | ||
179 | /* Enable the Rx interrupts for the second Buffer if | ||
180 | * configured in HW */ | ||
181 | if (drvdata->rx_ping_pong != 0) { | ||
182 | __raw_writel(XEL_RSR_RECV_IE_MASK, drvdata->base_addr + | ||
183 | XEL_BUFFER_OFFSET + XEL_RSR_OFFSET); | ||
184 | } | ||
185 | |||
186 | /* Enable the Global Interrupt Enable */ | 169 | /* Enable the Global Interrupt Enable */ |
187 | __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); | 170 | __raw_writel(XEL_GIER_GIE_MASK, drvdata->base_addr + XEL_GIER_OFFSET); |
188 | } | 171 | } |
@@ -206,31 +189,10 @@ static void xemaclite_disable_interrupts(struct net_local *drvdata) | |||
206 | __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), | 189 | __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), |
207 | drvdata->base_addr + XEL_TSR_OFFSET); | 190 | drvdata->base_addr + XEL_TSR_OFFSET); |
208 | 191 | ||
209 | /* Disable the Tx interrupts for the second Buffer | ||
210 | * if configured in HW */ | ||
211 | if (drvdata->tx_ping_pong != 0) { | ||
212 | reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET + | ||
213 | XEL_TSR_OFFSET); | ||
214 | __raw_writel(reg_data & (~XEL_TSR_XMIT_IE_MASK), | ||
215 | drvdata->base_addr + XEL_BUFFER_OFFSET + | ||
216 | XEL_TSR_OFFSET); | ||
217 | } | ||
218 | |||
219 | /* Disable the Rx interrupts for the first buffer */ | 192 | /* Disable the Rx interrupts for the first buffer */ |
220 | reg_data = __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET); | 193 | reg_data = __raw_readl(drvdata->base_addr + XEL_RSR_OFFSET); |
221 | __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), | 194 | __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), |
222 | drvdata->base_addr + XEL_RSR_OFFSET); | 195 | drvdata->base_addr + XEL_RSR_OFFSET); |
223 | |||
224 | /* Disable the Rx interrupts for the second buffer | ||
225 | * if configured in HW */ | ||
226 | if (drvdata->rx_ping_pong != 0) { | ||
227 | |||
228 | reg_data = __raw_readl(drvdata->base_addr + XEL_BUFFER_OFFSET + | ||
229 | XEL_RSR_OFFSET); | ||
230 | __raw_writel(reg_data & (~XEL_RSR_RECV_IE_MASK), | ||
231 | drvdata->base_addr + XEL_BUFFER_OFFSET + | ||
232 | XEL_RSR_OFFSET); | ||
233 | } | ||
234 | } | 196 | } |
235 | 197 | ||
236 | /** | 198 | /** |
@@ -258,6 +220,13 @@ static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr, | |||
258 | *to_u16_ptr++ = *from_u16_ptr++; | 220 | *to_u16_ptr++ = *from_u16_ptr++; |
259 | *to_u16_ptr++ = *from_u16_ptr++; | 221 | *to_u16_ptr++ = *from_u16_ptr++; |
260 | 222 | ||
223 | /* This barrier resolves occasional issues seen around | ||
224 | * cases where the data is not properly flushed out | ||
225 | * from the processor store buffers to the destination | ||
226 | * memory locations. | ||
227 | */ | ||
228 | wmb(); | ||
229 | |||
261 | /* Output a word */ | 230 | /* Output a word */ |
262 | *to_u32_ptr++ = align_buffer; | 231 | *to_u32_ptr++ = align_buffer; |
263 | } | 232 | } |
@@ -273,6 +242,12 @@ static void xemaclite_aligned_write(void *src_ptr, u32 *dest_ptr, | |||
273 | for (; length > 0; length--) | 242 | for (; length > 0; length--) |
274 | *to_u8_ptr++ = *from_u8_ptr++; | 243 | *to_u8_ptr++ = *from_u8_ptr++; |
275 | 244 | ||
245 | /* This barrier resolves occasional issues seen around | ||
246 | * cases where the data is not properly flushed out | ||
247 | * from the processor store buffers to the destination | ||
248 | * memory locations. | ||
249 | */ | ||
250 | wmb(); | ||
276 | *to_u32_ptr = align_buffer; | 251 | *to_u32_ptr = align_buffer; |
277 | } | 252 | } |
278 | } | 253 | } |
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 9184c82d5c50..f80bd0c90f1e 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -326,7 +326,6 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) | |||
326 | return -EINVAL; | 326 | return -EINVAL; |
327 | 327 | ||
328 | nvdev->start_remove = true; | 328 | nvdev->start_remove = true; |
329 | cancel_delayed_work_sync(&ndevctx->dwork); | ||
330 | cancel_work_sync(&ndevctx->work); | 329 | cancel_work_sync(&ndevctx->work); |
331 | netif_tx_disable(ndev); | 330 | netif_tx_disable(ndev); |
332 | rndis_filter_device_remove(hdev); | 331 | rndis_filter_device_remove(hdev); |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 431f58cb2ceb..a2c3a897206e 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -772,7 +772,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
772 | int ret; | 772 | int ret; |
773 | int vnet_hdr_len = 0; | 773 | int vnet_hdr_len = 0; |
774 | int vlan_offset = 0; | 774 | int vlan_offset = 0; |
775 | int copied; | 775 | int copied, total; |
776 | 776 | ||
777 | if (q->flags & IFF_VNET_HDR) { | 777 | if (q->flags & IFF_VNET_HDR) { |
778 | struct virtio_net_hdr vnet_hdr; | 778 | struct virtio_net_hdr vnet_hdr; |
@@ -785,7 +785,8 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
785 | if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) | 785 | if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr))) |
786 | return -EFAULT; | 786 | return -EFAULT; |
787 | } | 787 | } |
788 | copied = vnet_hdr_len; | 788 | total = copied = vnet_hdr_len; |
789 | total += skb->len; | ||
789 | 790 | ||
790 | if (!vlan_tx_tag_present(skb)) | 791 | if (!vlan_tx_tag_present(skb)) |
791 | len = min_t(int, skb->len, len); | 792 | len = min_t(int, skb->len, len); |
@@ -800,6 +801,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
800 | 801 | ||
801 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); | 802 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); |
802 | len = min_t(int, skb->len + VLAN_HLEN, len); | 803 | len = min_t(int, skb->len + VLAN_HLEN, len); |
804 | total += VLAN_HLEN; | ||
803 | 805 | ||
804 | copy = min_t(int, vlan_offset, len); | 806 | copy = min_t(int, vlan_offset, len); |
805 | ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); | 807 | ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); |
@@ -817,10 +819,9 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
817 | } | 819 | } |
818 | 820 | ||
819 | ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); | 821 | ret = skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); |
820 | copied += len; | ||
821 | 822 | ||
822 | done: | 823 | done: |
823 | return ret ? ret : copied; | 824 | return ret ? ret : total; |
824 | } | 825 | } |
825 | 826 | ||
826 | static ssize_t macvtap_do_read(struct macvtap_queue *q, | 827 | static ssize_t macvtap_do_read(struct macvtap_queue *q, |
@@ -875,7 +876,7 @@ static ssize_t macvtap_aio_read(struct kiocb *iocb, const struct iovec *iv, | |||
875 | } | 876 | } |
876 | 877 | ||
877 | ret = macvtap_do_read(q, iv, len, file->f_flags & O_NONBLOCK); | 878 | ret = macvtap_do_read(q, iv, len, file->f_flags & O_NONBLOCK); |
878 | ret = min_t(ssize_t, ret, len); /* XXX copied from tun.c. Why? */ | 879 | ret = min_t(ssize_t, ret, len); |
879 | if (ret > 0) | 880 | if (ret > 0) |
880 | iocb->ki_pos = ret; | 881 | iocb->ki_pos = ret; |
881 | out: | 882 | out: |
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 2a470e521f4e..5a8993b0cafc 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
@@ -336,6 +336,21 @@ static struct phy_driver ksphy_driver[] = { | |||
336 | .resume = genphy_resume, | 336 | .resume = genphy_resume, |
337 | .driver = { .owner = THIS_MODULE,}, | 337 | .driver = { .owner = THIS_MODULE,}, |
338 | }, { | 338 | }, { |
339 | .phy_id = PHY_ID_KSZ8041RNLI, | ||
340 | .phy_id_mask = 0x00fffff0, | ||
341 | .name = "Micrel KSZ8041RNLI", | ||
342 | .features = PHY_BASIC_FEATURES | | ||
343 | SUPPORTED_Pause | SUPPORTED_Asym_Pause, | ||
344 | .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, | ||
345 | .config_init = kszphy_config_init, | ||
346 | .config_aneg = genphy_config_aneg, | ||
347 | .read_status = genphy_read_status, | ||
348 | .ack_interrupt = kszphy_ack_interrupt, | ||
349 | .config_intr = kszphy_config_intr, | ||
350 | .suspend = genphy_suspend, | ||
351 | .resume = genphy_resume, | ||
352 | .driver = { .owner = THIS_MODULE,}, | ||
353 | }, { | ||
339 | .phy_id = PHY_ID_KSZ8051, | 354 | .phy_id = PHY_ID_KSZ8051, |
340 | .phy_id_mask = 0x00fffff0, | 355 | .phy_id_mask = 0x00fffff0, |
341 | .name = "Micrel KSZ8051", | 356 | .name = "Micrel KSZ8051", |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 8569da248336..a17a7018db19 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -1184,7 +1184,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, | |||
1184 | { | 1184 | { |
1185 | struct tun_pi pi = { 0, skb->protocol }; | 1185 | struct tun_pi pi = { 0, skb->protocol }; |
1186 | ssize_t total = 0; | 1186 | ssize_t total = 0; |
1187 | int vlan_offset = 0; | 1187 | int vlan_offset = 0, copied; |
1188 | 1188 | ||
1189 | if (!(tun->flags & TUN_NO_PI)) { | 1189 | if (!(tun->flags & TUN_NO_PI)) { |
1190 | if ((len -= sizeof(pi)) < 0) | 1190 | if ((len -= sizeof(pi)) < 0) |
@@ -1248,6 +1248,8 @@ static ssize_t tun_put_user(struct tun_struct *tun, | |||
1248 | total += tun->vnet_hdr_sz; | 1248 | total += tun->vnet_hdr_sz; |
1249 | } | 1249 | } |
1250 | 1250 | ||
1251 | copied = total; | ||
1252 | total += skb->len; | ||
1251 | if (!vlan_tx_tag_present(skb)) { | 1253 | if (!vlan_tx_tag_present(skb)) { |
1252 | len = min_t(int, skb->len, len); | 1254 | len = min_t(int, skb->len, len); |
1253 | } else { | 1255 | } else { |
@@ -1262,24 +1264,24 @@ static ssize_t tun_put_user(struct tun_struct *tun, | |||
1262 | 1264 | ||
1263 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); | 1265 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); |
1264 | len = min_t(int, skb->len + VLAN_HLEN, len); | 1266 | len = min_t(int, skb->len + VLAN_HLEN, len); |
1267 | total += VLAN_HLEN; | ||
1265 | 1268 | ||
1266 | copy = min_t(int, vlan_offset, len); | 1269 | copy = min_t(int, vlan_offset, len); |
1267 | ret = skb_copy_datagram_const_iovec(skb, 0, iv, total, copy); | 1270 | ret = skb_copy_datagram_const_iovec(skb, 0, iv, copied, copy); |
1268 | len -= copy; | 1271 | len -= copy; |
1269 | total += copy; | 1272 | copied += copy; |
1270 | if (ret || !len) | 1273 | if (ret || !len) |
1271 | goto done; | 1274 | goto done; |
1272 | 1275 | ||
1273 | copy = min_t(int, sizeof(veth), len); | 1276 | copy = min_t(int, sizeof(veth), len); |
1274 | ret = memcpy_toiovecend(iv, (void *)&veth, total, copy); | 1277 | ret = memcpy_toiovecend(iv, (void *)&veth, copied, copy); |
1275 | len -= copy; | 1278 | len -= copy; |
1276 | total += copy; | 1279 | copied += copy; |
1277 | if (ret || !len) | 1280 | if (ret || !len) |
1278 | goto done; | 1281 | goto done; |
1279 | } | 1282 | } |
1280 | 1283 | ||
1281 | skb_copy_datagram_const_iovec(skb, vlan_offset, iv, total, len); | 1284 | skb_copy_datagram_const_iovec(skb, vlan_offset, iv, copied, len); |
1282 | total += len; | ||
1283 | 1285 | ||
1284 | done: | 1286 | done: |
1285 | tun->dev->stats.tx_packets++; | 1287 | tun->dev->stats.tx_packets++; |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index b247a7a29366..ea203c1aaa24 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -1683,7 +1683,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
1683 | netdev_dbg(dev, "circular route to %pI4\n", | 1683 | netdev_dbg(dev, "circular route to %pI4\n", |
1684 | &dst->sin.sin_addr.s_addr); | 1684 | &dst->sin.sin_addr.s_addr); |
1685 | dev->stats.collisions++; | 1685 | dev->stats.collisions++; |
1686 | goto tx_error; | 1686 | goto rt_tx_error; |
1687 | } | 1687 | } |
1688 | 1688 | ||
1689 | /* Bypass encapsulation if the destination is local */ | 1689 | /* Bypass encapsulation if the destination is local */ |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 24846d91554b..a907bc94800d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1276,6 +1276,10 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, | |||
1276 | if (!rts_thresh || (len > rts_thresh)) | 1276 | if (!rts_thresh || (len > rts_thresh)) |
1277 | rts = true; | 1277 | rts = true; |
1278 | } | 1278 | } |
1279 | |||
1280 | if (!aggr) | ||
1281 | len = fi->framelen; | ||
1282 | |||
1279 | ath_buf_set_rate(sc, bf, &info, len, rts); | 1283 | ath_buf_set_rate(sc, bf, &info, len, rts); |
1280 | } | 1284 | } |
1281 | 1285 | ||
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 43341b82649c..773b731e3e52 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
@@ -355,7 +355,7 @@ static int xenvif_gop_skb(struct sk_buff *skb, | |||
355 | } | 355 | } |
356 | 356 | ||
357 | /* Set up a GSO prefix descriptor, if necessary */ | 357 | /* Set up a GSO prefix descriptor, if necessary */ |
358 | if ((1 << skb_shinfo(skb)->gso_type) & vif->gso_prefix_mask) { | 358 | if ((1 << gso_type) & vif->gso_prefix_mask) { |
359 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); | 359 | req = RING_GET_REQUEST(&vif->rx, vif->rx.req_cons++); |
360 | meta = npo->meta + npo->meta_prod++; | 360 | meta = npo->meta + npo->meta_prod++; |
361 | meta->gso_type = gso_type; | 361 | meta->gso_type = gso_type; |
@@ -1099,44 +1099,45 @@ static int checksum_setup_ip(struct xenvif *vif, struct sk_buff *skb, | |||
1099 | 1099 | ||
1100 | err = -EPROTO; | 1100 | err = -EPROTO; |
1101 | 1101 | ||
1102 | if (fragment) | ||
1103 | goto out; | ||
1104 | |||
1102 | switch (ip_hdr(skb)->protocol) { | 1105 | switch (ip_hdr(skb)->protocol) { |
1103 | case IPPROTO_TCP: | 1106 | case IPPROTO_TCP: |
1107 | err = maybe_pull_tail(skb, | ||
1108 | off + sizeof(struct tcphdr), | ||
1109 | MAX_IP_HDR_LEN); | ||
1110 | if (err < 0) | ||
1111 | goto out; | ||
1112 | |||
1104 | if (!skb_partial_csum_set(skb, off, | 1113 | if (!skb_partial_csum_set(skb, off, |
1105 | offsetof(struct tcphdr, check))) | 1114 | offsetof(struct tcphdr, check))) |
1106 | goto out; | 1115 | goto out; |
1107 | 1116 | ||
1108 | if (recalculate_partial_csum) { | 1117 | if (recalculate_partial_csum) |
1109 | err = maybe_pull_tail(skb, | ||
1110 | off + sizeof(struct tcphdr), | ||
1111 | MAX_IP_HDR_LEN); | ||
1112 | if (err < 0) | ||
1113 | goto out; | ||
1114 | |||
1115 | tcp_hdr(skb)->check = | 1118 | tcp_hdr(skb)->check = |
1116 | ~csum_tcpudp_magic(ip_hdr(skb)->saddr, | 1119 | ~csum_tcpudp_magic(ip_hdr(skb)->saddr, |
1117 | ip_hdr(skb)->daddr, | 1120 | ip_hdr(skb)->daddr, |
1118 | skb->len - off, | 1121 | skb->len - off, |
1119 | IPPROTO_TCP, 0); | 1122 | IPPROTO_TCP, 0); |
1120 | } | ||
1121 | break; | 1123 | break; |
1122 | case IPPROTO_UDP: | 1124 | case IPPROTO_UDP: |
1125 | err = maybe_pull_tail(skb, | ||
1126 | off + sizeof(struct udphdr), | ||
1127 | MAX_IP_HDR_LEN); | ||
1128 | if (err < 0) | ||
1129 | goto out; | ||
1130 | |||
1123 | if (!skb_partial_csum_set(skb, off, | 1131 | if (!skb_partial_csum_set(skb, off, |
1124 | offsetof(struct udphdr, check))) | 1132 | offsetof(struct udphdr, check))) |
1125 | goto out; | 1133 | goto out; |
1126 | 1134 | ||
1127 | if (recalculate_partial_csum) { | 1135 | if (recalculate_partial_csum) |
1128 | err = maybe_pull_tail(skb, | ||
1129 | off + sizeof(struct udphdr), | ||
1130 | MAX_IP_HDR_LEN); | ||
1131 | if (err < 0) | ||
1132 | goto out; | ||
1133 | |||
1134 | udp_hdr(skb)->check = | 1136 | udp_hdr(skb)->check = |
1135 | ~csum_tcpudp_magic(ip_hdr(skb)->saddr, | 1137 | ~csum_tcpudp_magic(ip_hdr(skb)->saddr, |
1136 | ip_hdr(skb)->daddr, | 1138 | ip_hdr(skb)->daddr, |
1137 | skb->len - off, | 1139 | skb->len - off, |
1138 | IPPROTO_UDP, 0); | 1140 | IPPROTO_UDP, 0); |
1139 | } | ||
1140 | break; | 1141 | break; |
1141 | default: | 1142 | default: |
1142 | goto out; | 1143 | goto out; |
@@ -1244,42 +1245,40 @@ static int checksum_setup_ipv6(struct xenvif *vif, struct sk_buff *skb, | |||
1244 | 1245 | ||
1245 | switch (nexthdr) { | 1246 | switch (nexthdr) { |
1246 | case IPPROTO_TCP: | 1247 | case IPPROTO_TCP: |
1248 | err = maybe_pull_tail(skb, | ||
1249 | off + sizeof(struct tcphdr), | ||
1250 | MAX_IPV6_HDR_LEN); | ||
1251 | if (err < 0) | ||
1252 | goto out; | ||
1253 | |||
1247 | if (!skb_partial_csum_set(skb, off, | 1254 | if (!skb_partial_csum_set(skb, off, |
1248 | offsetof(struct tcphdr, check))) | 1255 | offsetof(struct tcphdr, check))) |
1249 | goto out; | 1256 | goto out; |
1250 | 1257 | ||
1251 | if (recalculate_partial_csum) { | 1258 | if (recalculate_partial_csum) |
1252 | err = maybe_pull_tail(skb, | ||
1253 | off + sizeof(struct tcphdr), | ||
1254 | MAX_IPV6_HDR_LEN); | ||
1255 | if (err < 0) | ||
1256 | goto out; | ||
1257 | |||
1258 | tcp_hdr(skb)->check = | 1259 | tcp_hdr(skb)->check = |
1259 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | 1260 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, |
1260 | &ipv6_hdr(skb)->daddr, | 1261 | &ipv6_hdr(skb)->daddr, |
1261 | skb->len - off, | 1262 | skb->len - off, |
1262 | IPPROTO_TCP, 0); | 1263 | IPPROTO_TCP, 0); |
1263 | } | ||
1264 | break; | 1264 | break; |
1265 | case IPPROTO_UDP: | 1265 | case IPPROTO_UDP: |
1266 | err = maybe_pull_tail(skb, | ||
1267 | off + sizeof(struct udphdr), | ||
1268 | MAX_IPV6_HDR_LEN); | ||
1269 | if (err < 0) | ||
1270 | goto out; | ||
1271 | |||
1266 | if (!skb_partial_csum_set(skb, off, | 1272 | if (!skb_partial_csum_set(skb, off, |
1267 | offsetof(struct udphdr, check))) | 1273 | offsetof(struct udphdr, check))) |
1268 | goto out; | 1274 | goto out; |
1269 | 1275 | ||
1270 | if (recalculate_partial_csum) { | 1276 | if (recalculate_partial_csum) |
1271 | err = maybe_pull_tail(skb, | ||
1272 | off + sizeof(struct udphdr), | ||
1273 | MAX_IPV6_HDR_LEN); | ||
1274 | if (err < 0) | ||
1275 | goto out; | ||
1276 | |||
1277 | udp_hdr(skb)->check = | 1277 | udp_hdr(skb)->check = |
1278 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, | 1278 | ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, |
1279 | &ipv6_hdr(skb)->daddr, | 1279 | &ipv6_hdr(skb)->daddr, |
1280 | skb->len - off, | 1280 | skb->len - off, |
1281 | IPPROTO_UDP, 0); | 1281 | IPPROTO_UDP, 0); |
1282 | } | ||
1283 | break; | 1282 | break; |
1284 | default: | 1283 | default: |
1285 | goto out; | 1284 | goto out; |
@@ -1351,14 +1350,15 @@ static bool tx_credit_exceeded(struct xenvif *vif, unsigned size) | |||
1351 | return false; | 1350 | return false; |
1352 | } | 1351 | } |
1353 | 1352 | ||
1354 | static unsigned xenvif_tx_build_gops(struct xenvif *vif) | 1353 | static unsigned xenvif_tx_build_gops(struct xenvif *vif, int budget) |
1355 | { | 1354 | { |
1356 | struct gnttab_copy *gop = vif->tx_copy_ops, *request_gop; | 1355 | struct gnttab_copy *gop = vif->tx_copy_ops, *request_gop; |
1357 | struct sk_buff *skb; | 1356 | struct sk_buff *skb; |
1358 | int ret; | 1357 | int ret; |
1359 | 1358 | ||
1360 | while ((nr_pending_reqs(vif) + XEN_NETBK_LEGACY_SLOTS_MAX | 1359 | while ((nr_pending_reqs(vif) + XEN_NETBK_LEGACY_SLOTS_MAX |
1361 | < MAX_PENDING_REQS)) { | 1360 | < MAX_PENDING_REQS) && |
1361 | (skb_queue_len(&vif->tx_queue) < budget)) { | ||
1362 | struct xen_netif_tx_request txreq; | 1362 | struct xen_netif_tx_request txreq; |
1363 | struct xen_netif_tx_request txfrags[XEN_NETBK_LEGACY_SLOTS_MAX]; | 1363 | struct xen_netif_tx_request txfrags[XEN_NETBK_LEGACY_SLOTS_MAX]; |
1364 | struct page *page; | 1364 | struct page *page; |
@@ -1380,7 +1380,7 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif) | |||
1380 | continue; | 1380 | continue; |
1381 | } | 1381 | } |
1382 | 1382 | ||
1383 | RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do); | 1383 | work_to_do = RING_HAS_UNCONSUMED_REQUESTS(&vif->tx); |
1384 | if (!work_to_do) | 1384 | if (!work_to_do) |
1385 | break; | 1385 | break; |
1386 | 1386 | ||
@@ -1520,14 +1520,13 @@ static unsigned xenvif_tx_build_gops(struct xenvif *vif) | |||
1520 | } | 1520 | } |
1521 | 1521 | ||
1522 | 1522 | ||
1523 | static int xenvif_tx_submit(struct xenvif *vif, int budget) | 1523 | static int xenvif_tx_submit(struct xenvif *vif) |
1524 | { | 1524 | { |
1525 | struct gnttab_copy *gop = vif->tx_copy_ops; | 1525 | struct gnttab_copy *gop = vif->tx_copy_ops; |
1526 | struct sk_buff *skb; | 1526 | struct sk_buff *skb; |
1527 | int work_done = 0; | 1527 | int work_done = 0; |
1528 | 1528 | ||
1529 | while (work_done < budget && | 1529 | while ((skb = __skb_dequeue(&vif->tx_queue)) != NULL) { |
1530 | (skb = __skb_dequeue(&vif->tx_queue)) != NULL) { | ||
1531 | struct xen_netif_tx_request *txp; | 1530 | struct xen_netif_tx_request *txp; |
1532 | u16 pending_idx; | 1531 | u16 pending_idx; |
1533 | unsigned data_len; | 1532 | unsigned data_len; |
@@ -1602,14 +1601,14 @@ int xenvif_tx_action(struct xenvif *vif, int budget) | |||
1602 | if (unlikely(!tx_work_todo(vif))) | 1601 | if (unlikely(!tx_work_todo(vif))) |
1603 | return 0; | 1602 | return 0; |
1604 | 1603 | ||
1605 | nr_gops = xenvif_tx_build_gops(vif); | 1604 | nr_gops = xenvif_tx_build_gops(vif, budget); |
1606 | 1605 | ||
1607 | if (nr_gops == 0) | 1606 | if (nr_gops == 0) |
1608 | return 0; | 1607 | return 0; |
1609 | 1608 | ||
1610 | gnttab_batch_copy(vif->tx_copy_ops, nr_gops); | 1609 | gnttab_batch_copy(vif->tx_copy_ops, nr_gops); |
1611 | 1610 | ||
1612 | work_done = xenvif_tx_submit(vif, nr_gops); | 1611 | work_done = xenvif_tx_submit(vif); |
1613 | 1612 | ||
1614 | return work_done; | 1613 | return work_done; |
1615 | } | 1614 | } |