diff options
Diffstat (limited to 'drivers/net/ethernet/emulex')
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_hw.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 76 |
4 files changed, 46 insertions, 52 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index f544b297c9ab..0a510684e468 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h | |||
@@ -262,6 +262,7 @@ struct be_rx_compl_info { | |||
262 | u8 ipv6; | 262 | u8 ipv6; |
263 | u8 vtm; | 263 | u8 vtm; |
264 | u8 pkt_type; | 264 | u8 pkt_type; |
265 | u8 ip_frag; | ||
265 | }; | 266 | }; |
266 | 267 | ||
267 | struct be_rx_obj { | 268 | struct be_rx_obj { |
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index fd7b547698ab..1db2df61b8af 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c | |||
@@ -562,7 +562,7 @@ int lancer_test_and_set_rdy_state(struct be_adapter *adapter) | |||
562 | 562 | ||
563 | resource_error = lancer_provisioning_error(adapter); | 563 | resource_error = lancer_provisioning_error(adapter); |
564 | if (resource_error) | 564 | if (resource_error) |
565 | return -1; | 565 | return -EAGAIN; |
566 | 566 | ||
567 | status = lancer_wait_ready(adapter); | 567 | status = lancer_wait_ready(adapter); |
568 | if (!status) { | 568 | if (!status) { |
@@ -590,8 +590,8 @@ int lancer_test_and_set_rdy_state(struct be_adapter *adapter) | |||
590 | * when PF provisions resources. | 590 | * when PF provisions resources. |
591 | */ | 591 | */ |
592 | resource_error = lancer_provisioning_error(adapter); | 592 | resource_error = lancer_provisioning_error(adapter); |
593 | if (status == -1 && !resource_error) | 593 | if (resource_error) |
594 | adapter->eeh_error = true; | 594 | status = -EAGAIN; |
595 | 595 | ||
596 | return status; | 596 | return status; |
597 | } | 597 | } |
@@ -2976,22 +2976,17 @@ static struct be_nic_resource_desc *be_get_nic_desc(u8 *buf, u32 desc_count, | |||
2976 | for (i = 0; i < desc_count; i++) { | 2976 | for (i = 0; i < desc_count; i++) { |
2977 | desc->desc_len = desc->desc_len ? : RESOURCE_DESC_SIZE; | 2977 | desc->desc_len = desc->desc_len ? : RESOURCE_DESC_SIZE; |
2978 | if (((void *)desc + desc->desc_len) > | 2978 | if (((void *)desc + desc->desc_len) > |
2979 | (void *)(buf + max_buf_size)) { | 2979 | (void *)(buf + max_buf_size)) |
2980 | desc = NULL; | 2980 | return NULL; |
2981 | break; | ||
2982 | } | ||
2983 | 2981 | ||
2984 | if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_V0 || | 2982 | if (desc->desc_type == NIC_RESOURCE_DESC_TYPE_V0 || |
2985 | desc->desc_type == NIC_RESOURCE_DESC_TYPE_V1) | 2983 | desc->desc_type == NIC_RESOURCE_DESC_TYPE_V1) |
2986 | break; | 2984 | return desc; |
2987 | 2985 | ||
2988 | desc = (void *)desc + desc->desc_len; | 2986 | desc = (void *)desc + desc->desc_len; |
2989 | } | 2987 | } |
2990 | 2988 | ||
2991 | if (!desc || i == MAX_RESOURCE_DESC) | 2989 | return NULL; |
2992 | return NULL; | ||
2993 | |||
2994 | return desc; | ||
2995 | } | 2990 | } |
2996 | 2991 | ||
2997 | /* Uses Mbox */ | 2992 | /* Uses Mbox */ |
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index 3c1099b47f2a..8780183c6d1c 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h | |||
@@ -356,7 +356,7 @@ struct amap_eth_rx_compl_v0 { | |||
356 | u8 ip_version; /* dword 1 */ | 356 | u8 ip_version; /* dword 1 */ |
357 | u8 macdst[6]; /* dword 1 */ | 357 | u8 macdst[6]; /* dword 1 */ |
358 | u8 vtp; /* dword 1 */ | 358 | u8 vtp; /* dword 1 */ |
359 | u8 rsvd0; /* dword 1 */ | 359 | u8 ip_frag; /* dword 1 */ |
360 | u8 fragndx[10]; /* dword 1 */ | 360 | u8 fragndx[10]; /* dword 1 */ |
361 | u8 ct[2]; /* dword 1 */ | 361 | u8 ct[2]; /* dword 1 */ |
362 | u8 sw; /* dword 1 */ | 362 | u8 sw; /* dword 1 */ |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index a444110b060f..a0b4be51f0d1 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
@@ -780,26 +780,18 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, | |||
780 | if (unlikely(!skb)) | 780 | if (unlikely(!skb)) |
781 | return skb; | 781 | return skb; |
782 | 782 | ||
783 | if (vlan_tx_tag_present(skb)) { | 783 | if (vlan_tx_tag_present(skb)) |
784 | vlan_tag = be_get_tx_vlan_tag(adapter, skb); | 784 | vlan_tag = be_get_tx_vlan_tag(adapter, skb); |
785 | skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); | 785 | else if (qnq_async_evt_rcvd(adapter) && adapter->pvid) |
786 | if (skb) | 786 | vlan_tag = adapter->pvid; |
787 | skb->vlan_tci = 0; | ||
788 | } | ||
789 | |||
790 | if (qnq_async_evt_rcvd(adapter) && adapter->pvid) { | ||
791 | if (!vlan_tag) | ||
792 | vlan_tag = adapter->pvid; | ||
793 | if (skip_hw_vlan) | ||
794 | *skip_hw_vlan = true; | ||
795 | } | ||
796 | 787 | ||
797 | if (vlan_tag) { | 788 | if (vlan_tag) { |
798 | skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); | 789 | skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); |
799 | if (unlikely(!skb)) | 790 | if (unlikely(!skb)) |
800 | return skb; | 791 | return skb; |
801 | |||
802 | skb->vlan_tci = 0; | 792 | skb->vlan_tci = 0; |
793 | if (skip_hw_vlan) | ||
794 | *skip_hw_vlan = true; | ||
803 | } | 795 | } |
804 | 796 | ||
805 | /* Insert the outer VLAN, if any */ | 797 | /* Insert the outer VLAN, if any */ |
@@ -1607,6 +1599,8 @@ static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl, | |||
1607 | compl); | 1599 | compl); |
1608 | } | 1600 | } |
1609 | rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl); | 1601 | rxcp->port = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, port, compl); |
1602 | rxcp->ip_frag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, | ||
1603 | ip_frag, compl); | ||
1610 | } | 1604 | } |
1611 | 1605 | ||
1612 | static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) | 1606 | static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) |
@@ -1628,6 +1622,9 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) | |||
1628 | else | 1622 | else |
1629 | be_parse_rx_compl_v0(compl, rxcp); | 1623 | be_parse_rx_compl_v0(compl, rxcp); |
1630 | 1624 | ||
1625 | if (rxcp->ip_frag) | ||
1626 | rxcp->l4_csum = 0; | ||
1627 | |||
1631 | if (rxcp->vlanf) { | 1628 | if (rxcp->vlanf) { |
1632 | /* vlanf could be wrongly set in some cards. | 1629 | /* vlanf could be wrongly set in some cards. |
1633 | * ignore if vtm is not set */ | 1630 | * ignore if vtm is not set */ |
@@ -2176,7 +2173,7 @@ static irqreturn_t be_msix(int irq, void *dev) | |||
2176 | 2173 | ||
2177 | static inline bool do_gro(struct be_rx_compl_info *rxcp) | 2174 | static inline bool do_gro(struct be_rx_compl_info *rxcp) |
2178 | { | 2175 | { |
2179 | return (rxcp->tcpf && !rxcp->err) ? true : false; | 2176 | return (rxcp->tcpf && !rxcp->err && rxcp->l4_csum) ? true : false; |
2180 | } | 2177 | } |
2181 | 2178 | ||
2182 | static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi, | 2179 | static int be_process_rx(struct be_rx_obj *rxo, struct napi_struct *napi, |
@@ -4101,6 +4098,7 @@ static int be_get_initial_config(struct be_adapter *adapter) | |||
4101 | 4098 | ||
4102 | static int lancer_recover_func(struct be_adapter *adapter) | 4099 | static int lancer_recover_func(struct be_adapter *adapter) |
4103 | { | 4100 | { |
4101 | struct device *dev = &adapter->pdev->dev; | ||
4104 | int status; | 4102 | int status; |
4105 | 4103 | ||
4106 | status = lancer_test_and_set_rdy_state(adapter); | 4104 | status = lancer_test_and_set_rdy_state(adapter); |
@@ -4112,8 +4110,7 @@ static int lancer_recover_func(struct be_adapter *adapter) | |||
4112 | 4110 | ||
4113 | be_clear(adapter); | 4111 | be_clear(adapter); |
4114 | 4112 | ||
4115 | adapter->hw_error = false; | 4113 | be_clear_all_error(adapter); |
4116 | adapter->fw_timeout = false; | ||
4117 | 4114 | ||
4118 | status = be_setup(adapter); | 4115 | status = be_setup(adapter); |
4119 | if (status) | 4116 | if (status) |
@@ -4125,13 +4122,13 @@ static int lancer_recover_func(struct be_adapter *adapter) | |||
4125 | goto err; | 4122 | goto err; |
4126 | } | 4123 | } |
4127 | 4124 | ||
4128 | dev_err(&adapter->pdev->dev, | 4125 | dev_err(dev, "Error recovery successful\n"); |
4129 | "Adapter SLIPORT recovery succeeded\n"); | ||
4130 | return 0; | 4126 | return 0; |
4131 | err: | 4127 | err: |
4132 | if (adapter->eeh_error) | 4128 | if (status == -EAGAIN) |
4133 | dev_err(&adapter->pdev->dev, | 4129 | dev_err(dev, "Waiting for resource provisioning\n"); |
4134 | "Adapter SLIPORT recovery failed\n"); | 4130 | else |
4131 | dev_err(dev, "Error recovery failed\n"); | ||
4135 | 4132 | ||
4136 | return status; | 4133 | return status; |
4137 | } | 4134 | } |
@@ -4140,28 +4137,27 @@ static void be_func_recovery_task(struct work_struct *work) | |||
4140 | { | 4137 | { |
4141 | struct be_adapter *adapter = | 4138 | struct be_adapter *adapter = |
4142 | container_of(work, struct be_adapter, func_recovery_work.work); | 4139 | container_of(work, struct be_adapter, func_recovery_work.work); |
4143 | int status; | 4140 | int status = 0; |
4144 | 4141 | ||
4145 | be_detect_error(adapter); | 4142 | be_detect_error(adapter); |
4146 | 4143 | ||
4147 | if (adapter->hw_error && lancer_chip(adapter)) { | 4144 | if (adapter->hw_error && lancer_chip(adapter)) { |
4148 | 4145 | ||
4149 | if (adapter->eeh_error) | ||
4150 | goto out; | ||
4151 | |||
4152 | rtnl_lock(); | 4146 | rtnl_lock(); |
4153 | netif_device_detach(adapter->netdev); | 4147 | netif_device_detach(adapter->netdev); |
4154 | rtnl_unlock(); | 4148 | rtnl_unlock(); |
4155 | 4149 | ||
4156 | status = lancer_recover_func(adapter); | 4150 | status = lancer_recover_func(adapter); |
4157 | |||
4158 | if (!status) | 4151 | if (!status) |
4159 | netif_device_attach(adapter->netdev); | 4152 | netif_device_attach(adapter->netdev); |
4160 | } | 4153 | } |
4161 | 4154 | ||
4162 | out: | 4155 | /* In Lancer, for all errors other than provisioning error (-EAGAIN), |
4163 | schedule_delayed_work(&adapter->func_recovery_work, | 4156 | * no need to attempt further recovery. |
4164 | msecs_to_jiffies(1000)); | 4157 | */ |
4158 | if (!status || status == -EAGAIN) | ||
4159 | schedule_delayed_work(&adapter->func_recovery_work, | ||
4160 | msecs_to_jiffies(1000)); | ||
4165 | } | 4161 | } |
4166 | 4162 | ||
4167 | static void be_worker(struct work_struct *work) | 4163 | static void be_worker(struct work_struct *work) |
@@ -4266,6 +4262,9 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) | |||
4266 | netdev->features |= NETIF_F_HIGHDMA; | 4262 | netdev->features |= NETIF_F_HIGHDMA; |
4267 | } else { | 4263 | } else { |
4268 | status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); | 4264 | status = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); |
4265 | if (!status) | ||
4266 | status = dma_set_coherent_mask(&pdev->dev, | ||
4267 | DMA_BIT_MASK(32)); | ||
4269 | if (status) { | 4268 | if (status) { |
4270 | dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); | 4269 | dev_err(&pdev->dev, "Could not set PCI DMA Mask\n"); |
4271 | goto free_netdev; | 4270 | goto free_netdev; |
@@ -4444,20 +4443,19 @@ static pci_ers_result_t be_eeh_err_detected(struct pci_dev *pdev, | |||
4444 | 4443 | ||
4445 | dev_err(&adapter->pdev->dev, "EEH error detected\n"); | 4444 | dev_err(&adapter->pdev->dev, "EEH error detected\n"); |
4446 | 4445 | ||
4447 | adapter->eeh_error = true; | 4446 | if (!adapter->eeh_error) { |
4447 | adapter->eeh_error = true; | ||
4448 | 4448 | ||
4449 | cancel_delayed_work_sync(&adapter->func_recovery_work); | 4449 | cancel_delayed_work_sync(&adapter->func_recovery_work); |
4450 | 4450 | ||
4451 | rtnl_lock(); | ||
4452 | netif_device_detach(netdev); | ||
4453 | rtnl_unlock(); | ||
4454 | |||
4455 | if (netif_running(netdev)) { | ||
4456 | rtnl_lock(); | 4451 | rtnl_lock(); |
4457 | be_close(netdev); | 4452 | netif_device_detach(netdev); |
4453 | if (netif_running(netdev)) | ||
4454 | be_close(netdev); | ||
4458 | rtnl_unlock(); | 4455 | rtnl_unlock(); |
4456 | |||
4457 | be_clear(adapter); | ||
4459 | } | 4458 | } |
4460 | be_clear(adapter); | ||
4461 | 4459 | ||
4462 | if (state == pci_channel_io_perm_failure) | 4460 | if (state == pci_channel_io_perm_failure) |
4463 | return PCI_ERS_RESULT_DISCONNECT; | 4461 | return PCI_ERS_RESULT_DISCONNECT; |
@@ -4482,7 +4480,6 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev) | |||
4482 | int status; | 4480 | int status; |
4483 | 4481 | ||
4484 | dev_info(&adapter->pdev->dev, "EEH reset\n"); | 4482 | dev_info(&adapter->pdev->dev, "EEH reset\n"); |
4485 | be_clear_all_error(adapter); | ||
4486 | 4483 | ||
4487 | status = pci_enable_device(pdev); | 4484 | status = pci_enable_device(pdev); |
4488 | if (status) | 4485 | if (status) |
@@ -4500,6 +4497,7 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev) | |||
4500 | return PCI_ERS_RESULT_DISCONNECT; | 4497 | return PCI_ERS_RESULT_DISCONNECT; |
4501 | 4498 | ||
4502 | pci_cleanup_aer_uncorrect_error_status(pdev); | 4499 | pci_cleanup_aer_uncorrect_error_status(pdev); |
4500 | be_clear_all_error(adapter); | ||
4503 | return PCI_ERS_RESULT_RECOVERED; | 4501 | return PCI_ERS_RESULT_RECOVERED; |
4504 | } | 4502 | } |
4505 | 4503 | ||