diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 3ac5d23454a8..ba499489969a 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -6918,7 +6918,8 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) | |||
6918 | skb->protocol = eth_type_trans(skb, tp->dev); | 6918 | skb->protocol = eth_type_trans(skb, tp->dev); |
6919 | 6919 | ||
6920 | if (len > (tp->dev->mtu + ETH_HLEN) && | 6920 | if (len > (tp->dev->mtu + ETH_HLEN) && |
6921 | skb->protocol != htons(ETH_P_8021Q)) { | 6921 | skb->protocol != htons(ETH_P_8021Q) && |
6922 | skb->protocol != htons(ETH_P_8021AD)) { | ||
6922 | dev_kfree_skb_any(skb); | 6923 | dev_kfree_skb_any(skb); |
6923 | goto drop_it_no_recycle; | 6924 | goto drop_it_no_recycle; |
6924 | } | 6925 | } |
@@ -7914,8 +7915,6 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
7914 | 7915 | ||
7915 | entry = tnapi->tx_prod; | 7916 | entry = tnapi->tx_prod; |
7916 | base_flags = 0; | 7917 | base_flags = 0; |
7917 | if (skb->ip_summed == CHECKSUM_PARTIAL) | ||
7918 | base_flags |= TXD_FLAG_TCPUDP_CSUM; | ||
7919 | 7918 | ||
7920 | mss = skb_shinfo(skb)->gso_size; | 7919 | mss = skb_shinfo(skb)->gso_size; |
7921 | if (mss) { | 7920 | if (mss) { |
@@ -7929,6 +7928,13 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
7929 | 7928 | ||
7930 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN; | 7929 | hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN; |
7931 | 7930 | ||
7931 | /* HW/FW can not correctly segment packets that have been | ||
7932 | * vlan encapsulated. | ||
7933 | */ | ||
7934 | if (skb->protocol == htons(ETH_P_8021Q) || | ||
7935 | skb->protocol == htons(ETH_P_8021AD)) | ||
7936 | return tg3_tso_bug(tp, tnapi, txq, skb); | ||
7937 | |||
7932 | if (!skb_is_gso_v6(skb)) { | 7938 | if (!skb_is_gso_v6(skb)) { |
7933 | if (unlikely((ETH_HLEN + hdr_len) > 80) && | 7939 | if (unlikely((ETH_HLEN + hdr_len) > 80) && |
7934 | tg3_flag(tp, TSO_BUG)) | 7940 | tg3_flag(tp, TSO_BUG)) |
@@ -7979,6 +7985,17 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
7979 | base_flags |= tsflags << 12; | 7985 | base_flags |= tsflags << 12; |
7980 | } | 7986 | } |
7981 | } | 7987 | } |
7988 | } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | ||
7989 | /* HW/FW can not correctly checksum packets that have been | ||
7990 | * vlan encapsulated. | ||
7991 | */ | ||
7992 | if (skb->protocol == htons(ETH_P_8021Q) || | ||
7993 | skb->protocol == htons(ETH_P_8021AD)) { | ||
7994 | if (skb_checksum_help(skb)) | ||
7995 | goto drop; | ||
7996 | } else { | ||
7997 | base_flags |= TXD_FLAG_TCPUDP_CSUM; | ||
7998 | } | ||
7982 | } | 7999 | } |
7983 | 8000 | ||
7984 | if (tg3_flag(tp, USE_JUMBO_BDFLAG) && | 8001 | if (tg3_flag(tp, USE_JUMBO_BDFLAG) && |
@@ -11617,6 +11634,12 @@ static int tg3_open(struct net_device *dev) | |||
11617 | struct tg3 *tp = netdev_priv(dev); | 11634 | struct tg3 *tp = netdev_priv(dev); |
11618 | int err; | 11635 | int err; |
11619 | 11636 | ||
11637 | if (tp->pcierr_recovery) { | ||
11638 | netdev_err(dev, "Failed to open device. PCI error recovery " | ||
11639 | "in progress\n"); | ||
11640 | return -EAGAIN; | ||
11641 | } | ||
11642 | |||
11620 | if (tp->fw_needed) { | 11643 | if (tp->fw_needed) { |
11621 | err = tg3_request_firmware(tp); | 11644 | err = tg3_request_firmware(tp); |
11622 | if (tg3_asic_rev(tp) == ASIC_REV_57766) { | 11645 | if (tg3_asic_rev(tp) == ASIC_REV_57766) { |
@@ -11674,6 +11697,12 @@ static int tg3_close(struct net_device *dev) | |||
11674 | { | 11697 | { |
11675 | struct tg3 *tp = netdev_priv(dev); | 11698 | struct tg3 *tp = netdev_priv(dev); |
11676 | 11699 | ||
11700 | if (tp->pcierr_recovery) { | ||
11701 | netdev_err(dev, "Failed to close device. PCI error recovery " | ||
11702 | "in progress\n"); | ||
11703 | return -EAGAIN; | ||
11704 | } | ||
11705 | |||
11677 | tg3_ptp_fini(tp); | 11706 | tg3_ptp_fini(tp); |
11678 | 11707 | ||
11679 | tg3_stop(tp); | 11708 | tg3_stop(tp); |
@@ -17561,6 +17590,7 @@ static int tg3_init_one(struct pci_dev *pdev, | |||
17561 | tp->rx_mode = TG3_DEF_RX_MODE; | 17590 | tp->rx_mode = TG3_DEF_RX_MODE; |
17562 | tp->tx_mode = TG3_DEF_TX_MODE; | 17591 | tp->tx_mode = TG3_DEF_TX_MODE; |
17563 | tp->irq_sync = 1; | 17592 | tp->irq_sync = 1; |
17593 | tp->pcierr_recovery = false; | ||
17564 | 17594 | ||
17565 | if (tg3_debug > 0) | 17595 | if (tg3_debug > 0) |
17566 | tp->msg_enable = tg3_debug; | 17596 | tp->msg_enable = tg3_debug; |
@@ -18071,6 +18101,8 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev, | |||
18071 | 18101 | ||
18072 | rtnl_lock(); | 18102 | rtnl_lock(); |
18073 | 18103 | ||
18104 | tp->pcierr_recovery = true; | ||
18105 | |||
18074 | /* We probably don't have netdev yet */ | 18106 | /* We probably don't have netdev yet */ |
18075 | if (!netdev || !netif_running(netdev)) | 18107 | if (!netdev || !netif_running(netdev)) |
18076 | goto done; | 18108 | goto done; |
@@ -18195,6 +18227,7 @@ static void tg3_io_resume(struct pci_dev *pdev) | |||
18195 | tg3_phy_start(tp); | 18227 | tg3_phy_start(tp); |
18196 | 18228 | ||
18197 | done: | 18229 | done: |
18230 | tp->pcierr_recovery = false; | ||
18198 | rtnl_unlock(); | 18231 | rtnl_unlock(); |
18199 | } | 18232 | } |
18200 | 18233 | ||