summaryrefslogtreecommitdiff
path: root/drivers/net/usb/aqc111.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/aqc111.c')
-rw-r--r--drivers/net/usb/aqc111.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 7e44110746dd..9201ee10a13f 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -30,11 +30,14 @@ static int aqc111_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
ret = usbnet_read_cmd_nopm(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR |
USB_RECIP_DEVICE, value, index, data, size);
- if (unlikely(ret < 0))
+ if (unlikely(ret < size)) {
netdev_warn(dev->net,
"Failed to read(0x%x) reg index 0x%04x: %d\n",
cmd, index, ret);
+ ret = ret < 0 ? ret : -ENODATA;
+ }
+
return ret;
}
@@ -46,11 +49,14 @@ static int aqc111_read_cmd(struct usbnet *dev, u8 cmd, u16 value,
ret = usbnet_read_cmd(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR |
USB_RECIP_DEVICE, value, index, data, size);
- if (unlikely(ret < 0))
+ if (unlikely(ret < size)) {
netdev_warn(dev->net,
"Failed to read(0x%x) reg index 0x%04x: %d\n",
cmd, index, ret);
+ ret = ret < 0 ? ret : -ENODATA;
+ }
+
return ret;
}
@@ -119,7 +125,7 @@ static int aqc111_write_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
}
static int aqc111_write_cmd(struct usbnet *dev, u8 cmd, u16 value,
- u16 index, u16 size, void *data)
+ u16 index, u16 size, const void *data)
{
int ret;
@@ -201,7 +207,7 @@ static void aqc111_get_drvinfo(struct net_device *net,
/* Inherit standard device info */
usbnet_get_drvinfo(net, info);
- strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver));
+ strscpy(info->driver, DRIVER_NAME, sizeof(info->driver));
snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u.%u",
aqc111_data->fw_ver.major,
aqc111_data->fw_ver.minor,
@@ -333,13 +339,13 @@ static void aqc111_set_phy_speed(struct usbnet *dev, u8 autoneg, u16 speed)
switch (speed) {
case SPEED_5000:
aqc111_data->phy_cfg |= AQ_ADV_5G;
- /* fall-through */
+ fallthrough;
case SPEED_2500:
aqc111_data->phy_cfg |= AQ_ADV_2G5;
- /* fall-through */
+ fallthrough;
case SPEED_1000:
aqc111_data->phy_cfg |= AQ_ADV_1G;
- /* fall-through */
+ fallthrough;
case SPEED_100:
aqc111_data->phy_cfg |= AQ_ADV_100M;
/* fall-through */
@@ -424,7 +430,7 @@ static int aqc111_change_mtu(struct net_device *net, int new_mtu)
u16 reg16 = 0;
u8 buf[5];
- net->mtu = new_mtu;
+ WRITE_ONCE(net->mtu, new_mtu);
dev->hard_mtu = net->mtu + net->hard_header_len;
aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
@@ -641,7 +647,7 @@ static const struct net_device_ops aqc111_netdev_ops = {
.ndo_stop = usbnet_stop,
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
- .ndo_get_stats64 = usbnet_get_stats64,
+ .ndo_get_stats64 = dev_get_tstats64,
.ndo_change_mtu = aqc111_change_mtu,
.ndo_set_mac_address = aqc111_set_mac_addr,
.ndo_validate_addr = eth_validate_addr,
@@ -714,7 +720,7 @@ static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf)
if (ret)
goto out;
- ether_addr_copy(dev->net->dev_addr, dev->net->perm_addr);
+ eth_hw_addr_set(dev->net, dev->net->perm_addr);
/* Set Rx urb size */
dev->rx_urb_size = URB_SIZE;
@@ -735,7 +741,7 @@ static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->features |= AQ_SUPPORT_FEATURE;
dev->net->vlan_features |= AQ_SUPPORT_VLAN_FEATURE;
- netif_set_gso_max_size(dev->net, 65535);
+ netif_set_tso_max_size(dev->net, 65535);
aqc111_read_fw_version(dev, aqc111_data);
aqc111_data->autoneg = AUTONEG_ENABLE;
@@ -1079,17 +1085,17 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
u16 pkt_count = 0;
u64 desc_hdr = 0;
u16 vlan_tag = 0;
- u32 skb_len = 0;
+ u32 skb_len;
if (!skb)
goto err;
- if (skb->len == 0)
+ skb_len = skb->len;
+ if (skb_len < sizeof(desc_hdr))
goto err;
- skb_len = skb->len;
/* RX Descriptor Header */
- skb_trim(skb, skb->len - sizeof(desc_hdr));
+ skb_trim(skb, skb_len - sizeof(desc_hdr));
desc_hdr = le64_to_cpup((u64 *)skb_tail_pointer(skb));
/* Check these packets */
@@ -1102,10 +1108,15 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
if (start_of_descs != desc_offset)
goto err;
- /* self check desc_offset from header*/
- if (desc_offset >= skb_len)
+ /* self check desc_offset from header and make sure that the
+ * bounds of the metadata array are inside the SKB
+ */
+ if (pkt_count * 2 + desc_offset >= skb_len)
goto err;
+ /* Packets must not overlap the metadata array */
+ skb_trim(skb, desc_offset);
+
if (pkt_count == 0)
goto err;
@@ -1136,17 +1147,15 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
continue;
}
- /* Clone SKB */
- new_skb = skb_clone(skb, GFP_ATOMIC);
+ new_skb = netdev_alloc_skb_ip_align(dev->net, pkt_len);
if (!new_skb)
goto err;
- new_skb->len = pkt_len;
+ skb_put(new_skb, pkt_len);
+ memcpy(new_skb->data, skb->data, pkt_len);
skb_pull(new_skb, AQ_RX_HW_PAD);
- skb_set_tail_pointer(new_skb, new_skb->len);
- new_skb->truesize = SKB_TRUESIZE(new_skb->len);
if (aqc111_data->rx_checksum)
aqc111_rx_checksum(new_skb, pkt_desc);