|
@@ -75,6 +75,27 @@ void asix_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
|
|
|
value, index, data, size);
|
|
|
}
|
|
|
|
|
|
+static void reset_asix_rx_fixup_info(struct asix_rx_fixup_info *rx)
|
|
|
+{
|
|
|
+ /* Reset the variables that have a lifetime outside of
|
|
|
+ * asix_rx_fixup_internal() so that future processing starts from a
|
|
|
+ * known set of initial conditions.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (rx->ax_skb) {
|
|
|
+ /* Discard any incomplete Ethernet frame in the netdev buffer */
|
|
|
+ kfree_skb(rx->ax_skb);
|
|
|
+ rx->ax_skb = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Assume the Data header 32-bit word is at the start of the current
|
|
|
+ * or next URB socket buffer so reset all the state variables.
|
|
|
+ */
|
|
|
+ rx->remaining = 0;
|
|
|
+ rx->split_head = false;
|
|
|
+ rx->header = 0;
|
|
|
+}
|
|
|
+
|
|
|
int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
|
|
|
struct asix_rx_fixup_info *rx)
|
|
|
{
|
|
@@ -99,15 +120,7 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
|
|
|
if (size != ((~rx->header >> 16) & 0x7ff)) {
|
|
|
netdev_err(dev->net, "asix_rx_fixup() Data Header synchronisation was lost, remaining %d\n",
|
|
|
rx->remaining);
|
|
|
- if (rx->ax_skb) {
|
|
|
- kfree_skb(rx->ax_skb);
|
|
|
- rx->ax_skb = NULL;
|
|
|
- /* Discard the incomplete netdev Ethernet frame
|
|
|
- * and assume the Data header is at the start of
|
|
|
- * the current URB socket buffer.
|
|
|
- */
|
|
|
- }
|
|
|
- rx->remaining = 0;
|
|
|
+ reset_asix_rx_fixup_info(rx);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -139,11 +152,13 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
|
|
|
if (size != ((~rx->header >> 16) & 0x7ff)) {
|
|
|
netdev_err(dev->net, "asix_rx_fixup() Bad Header Length 0x%x, offset %d\n",
|
|
|
rx->header, offset);
|
|
|
+ reset_asix_rx_fixup_info(rx);
|
|
|
return 0;
|
|
|
}
|
|
|
if (size > dev->net->mtu + ETH_HLEN + VLAN_HLEN) {
|
|
|
netdev_dbg(dev->net, "asix_rx_fixup() Bad RX Length %d\n",
|
|
|
size);
|
|
|
+ reset_asix_rx_fixup_info(rx);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -180,6 +195,7 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
|
|
|
if (skb->len != offset) {
|
|
|
netdev_err(dev->net, "asix_rx_fixup() Bad SKB Length %d, %d\n",
|
|
|
skb->len, offset);
|
|
|
+ reset_asix_rx_fixup_info(rx);
|
|
|
return 0;
|
|
|
}
|
|
|
|