|
@@ -913,24 +913,14 @@ static int be_ipv6_tx_stall_chk(struct be_adapter *adapter,
|
|
|
return BE3_chip(adapter) && be_ipv6_exthdr_check(skb);
|
|
|
}
|
|
|
|
|
|
-static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
|
|
|
- struct sk_buff *skb,
|
|
|
- bool *skip_hw_vlan)
|
|
|
+static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter,
|
|
|
+ struct sk_buff *skb,
|
|
|
+ bool *skip_hw_vlan)
|
|
|
{
|
|
|
struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
|
|
|
unsigned int eth_hdr_len;
|
|
|
struct iphdr *ip;
|
|
|
|
|
|
- /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or less
|
|
|
- * may cause a transmit stall on that port. So the work-around is to
|
|
|
- * pad short packets (<= 32 bytes) to a 36-byte length.
|
|
|
- */
|
|
|
- if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) {
|
|
|
- if (skb_padto(skb, 36))
|
|
|
- goto err;
|
|
|
- skb->len = 36;
|
|
|
- }
|
|
|
-
|
|
|
/* For padded packets, BE HW modifies tot_len field in IP header
|
|
|
* incorrecly when VLAN tag is inserted by HW.
|
|
|
* For padded packets, Lancer computes incorrect checksum.
|
|
@@ -991,6 +981,29 @@ err:
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+static struct sk_buff *be_xmit_workarounds(struct be_adapter *adapter,
|
|
|
+ struct sk_buff *skb,
|
|
|
+ bool *skip_hw_vlan)
|
|
|
+{
|
|
|
+ /* Lancer, SH-R ASICs have a bug wherein Packets that are 32 bytes or
|
|
|
+ * less may cause a transmit stall on that port. So the work-around is
|
|
|
+ * to pad short packets (<= 32 bytes) to a 36-byte length.
|
|
|
+ */
|
|
|
+ if (unlikely(!BEx_chip(adapter) && skb->len <= 32)) {
|
|
|
+ if (skb_padto(skb, 36))
|
|
|
+ return NULL;
|
|
|
+ skb->len = 36;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (BEx_chip(adapter) || lancer_chip(adapter)) {
|
|
|
+ skb = be_lancer_xmit_workarounds(adapter, skb, skip_hw_vlan);
|
|
|
+ if (!skb)
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return skb;
|
|
|
+}
|
|
|
+
|
|
|
static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev)
|
|
|
{
|
|
|
struct be_adapter *adapter = netdev_priv(netdev);
|