summaryrefslogtreecommitdiffstats
path: root/drivers/net/usb/lan78xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/usb/lan78xx.c')
-rw-r--r--drivers/net/usb/lan78xx.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 3d92ea6fcc02..f24a1b0b801f 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -1258,15 +1258,17 @@ static void lan78xx_status(struct lan78xx_net *dev, struct urb *urb)
return;
}
- memcpy(&intdata, urb->transfer_buffer, 4);
- le32_to_cpus(&intdata);
+ intdata = get_unaligned_le32(urb->transfer_buffer);
if (intdata & INT_ENP_PHY_INT) {
netif_dbg(dev, link, dev->net, "PHY INTR: 0x%08x\n", intdata);
lan78xx_defer_kevent(dev, EVENT_LINK_RESET);
- if (dev->domain_data.phyirq > 0)
+ if (dev->domain_data.phyirq > 0) {
+ local_irq_disable();
generic_handle_irq(dev->domain_data.phyirq);
+ local_irq_enable();
+ }
} else
netdev_warn(dev->net,
"unexpected interrupt: 0x%08x\n", intdata);
@@ -2730,6 +2732,7 @@ static struct sk_buff *lan78xx_tx_prep(struct lan78xx_net *dev,
struct sk_buff *skb, gfp_t flags)
{
u32 tx_cmd_a, tx_cmd_b;
+ void *ptr;
if (skb_cow_head(skb, TX_OVERHEAD)) {
dev_kfree_skb_any(skb);
@@ -2758,13 +2761,9 @@ static struct sk_buff *lan78xx_tx_prep(struct lan78xx_net *dev,
tx_cmd_b |= skb_vlan_tag_get(skb) & TX_CMD_B_VTAG_MASK_;
}
- skb_push(skb, 4);
- cpu_to_le32s(&tx_cmd_b);
- memcpy(skb->data, &tx_cmd_b, 4);
-
- skb_push(skb, 4);
- cpu_to_le32s(&tx_cmd_a);
- memcpy(skb->data, &tx_cmd_a, 4);
+ ptr = skb_push(skb, 8);
+ put_unaligned_le32(tx_cmd_a, ptr);
+ put_unaligned_le32(tx_cmd_b, ptr + 4);
return skb;
}
@@ -3105,16 +3104,13 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb)
struct sk_buff *skb2;
unsigned char *packet;
- memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a));
- le32_to_cpus(&rx_cmd_a);
+ rx_cmd_a = get_unaligned_le32(skb->data);
skb_pull(skb, sizeof(rx_cmd_a));
- memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
- le32_to_cpus(&rx_cmd_b);
+ rx_cmd_b = get_unaligned_le32(skb->data);
skb_pull(skb, sizeof(rx_cmd_b));
- memcpy(&rx_cmd_c, skb->data, sizeof(rx_cmd_c));
- le16_to_cpus(&rx_cmd_c);
+ rx_cmd_c = get_unaligned_le16(skb->data);
skb_pull(skb, sizeof(rx_cmd_c));
packet = skb->data;
@@ -3789,10 +3785,14 @@ static int lan78xx_probe(struct usb_interface *intf,
/* driver requires remote-wakeup capability during autosuspend. */
intf->needs_remote_wakeup = 1;
+ ret = lan78xx_phy_init(dev);
+ if (ret < 0)
+ goto out4;
+
ret = register_netdev(netdev);
if (ret != 0) {
netif_err(dev, probe, netdev, "couldn't register the device\n");
- goto out3;
+ goto out5;
}
usb_set_intfdata(intf, dev);
@@ -3805,14 +3805,12 @@ static int lan78xx_probe(struct usb_interface *intf,
pm_runtime_set_autosuspend_delay(&udev->dev,
DEFAULT_AUTOSUSPEND_DELAY);
- ret = lan78xx_phy_init(dev);
- if (ret < 0)
- goto out4;
-
return 0;
+out5:
+ phy_disconnect(netdev->phydev);
out4:
- unregister_netdev(netdev);
+ usb_free_urb(dev->urb_intr);
out3:
lan78xx_unbind(dev, intf);
out2:
OpenPOWER on IntegriCloud