diff options
Diffstat (limited to 'drivers/net/wireless/p54/p54usb.c')
-rw-r--r-- | drivers/net/wireless/p54/p54usb.c | 75 |
1 files changed, 51 insertions, 24 deletions
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 75d749bccb0..49739c36a44 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -135,6 +135,16 @@ static void p54u_rx_cb(struct urb *urb) usb_submit_urb(urb, GFP_ATOMIC); } +static void p54u_tx_reuse_skb_cb(struct urb *urb) +{ + struct sk_buff *skb = urb->context; + struct p54u_priv *priv = (struct p54u_priv *)((struct ieee80211_hw *) + usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)))->priv; + + skb_pull(skb, priv->common.tx_hdr_len); + usb_free_urb(urb); +} + static void p54u_tx_cb(struct urb *urb) { usb_free_urb(urb); @@ -146,6 +156,16 @@ static void p54u_tx_free_cb(struct urb *urb) usb_free_urb(urb); } +static void p54u_tx_free_skb_cb(struct urb *urb) +{ + struct sk_buff *skb = urb->context; + struct ieee80211_hw *dev = (struct ieee80211_hw *) + usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + + p54_free_skb(dev, skb); + usb_free_urb(urb); +} + static int p54u_init_urbs(struct ieee80211_hw *dev) { struct p54u_priv *priv = dev->priv; @@ -192,8 +212,8 @@ static void p54u_free_urbs(struct ieee80211_hw *dev) } } -static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data, - size_t len, int free_on_tx) +static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb, + int free_on_tx) { struct p54u_priv *priv = dev->priv; struct urb *addr_urb, *data_urb; @@ -209,11 +229,14 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data, } usb_fill_bulk_urb(addr_urb, priv->udev, - usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id, - sizeof(data->req_id), p54u_tx_cb, dev); + usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), + &((struct p54_hdr *)skb->data)->req_id, 4, + p54u_tx_cb, dev); usb_fill_bulk_urb(data_urb, priv->udev, - usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len, - free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev); + usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), + skb->data, skb->len, + free_on_tx ? p54u_tx_free_skb_cb : + p54u_tx_reuse_skb_cb, skb); usb_submit_urb(addr_urb, GFP_ATOMIC); usb_submit_urb(data_urb, GFP_ATOMIC); @@ -232,31 +255,35 @@ static __le32 p54u_lm87_chksum(const u32 *data, size_t length) return cpu_to_le32(chk); } -static void p54u_tx_lm87(struct ieee80211_hw *dev, - struct p54_control_hdr *data, - size_t len, int free_on_tx) +static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb, + int free_on_tx) { struct p54u_priv *priv = dev->priv; struct urb *data_urb; - struct lm87_tx_hdr *hdr = (void *)data - sizeof(*hdr); + struct lm87_tx_hdr *hdr; + __le32 checksum; + __le32 addr = ((struct p54_hdr *)skb->data)->req_id; data_urb = usb_alloc_urb(0, GFP_ATOMIC); if (!data_urb) return; - hdr->chksum = p54u_lm87_chksum((u32 *)data, len); - hdr->device_addr = data->req_id; + checksum = p54u_lm87_chksum((u32 *)skb->data, skb->len); + hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr)); + hdr->chksum = checksum; + hdr->device_addr = addr; usb_fill_bulk_urb(data_urb, priv->udev, - usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, - len + sizeof(*hdr), free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, - dev); + usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), + skb->data, skb->len, + free_on_tx ? p54u_tx_free_skb_cb : + p54u_tx_reuse_skb_cb, skb); usb_submit_urb(data_urb, GFP_ATOMIC); } -static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data, - size_t len, int free_on_tx) +static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb, + int free_on_tx) { struct p54u_priv *priv = dev->priv; struct urb *int_urb, *data_urb; @@ -284,11 +311,10 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *da reg->addr = cpu_to_le32(P54U_DEV_BASE); reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA); - len += sizeof(*data); - hdr = (void *)data - sizeof(*hdr); + hdr = (void *)skb_push(skb, sizeof(*hdr)); memset(hdr, 0, sizeof(*hdr)); - hdr->device_addr = data->req_id; - hdr->len = cpu_to_le16(len); + hdr->device_addr = ((struct p54_hdr *)skb->data)->req_id; + hdr->len = cpu_to_le16(skb->len + sizeof(struct p54_hdr)); usb_fill_bulk_urb(int_urb, priv->udev, usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg), @@ -296,8 +322,10 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *da usb_submit_urb(int_urb, GFP_ATOMIC); usb_fill_bulk_urb(data_urb, priv->udev, - usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr), - free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev); + usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), + skb->data, skb->len, + free_on_tx ? p54u_tx_free_skb_cb : + p54u_tx_reuse_skb_cb, skb); usb_submit_urb(data_urb, GFP_ATOMIC); } @@ -786,7 +814,6 @@ static int __devinit p54u_probe(struct usb_interface *intf, struct p54u_priv *priv; int err; unsigned int i, recognized_pipes; - DECLARE_MAC_BUF(mac); dev = p54_init_common(sizeof(*priv)); if (!dev) { |