aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/p54usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/p54/p54usb.c')
-rw-r--r--drivers/net/wireless/p54/p54usb.c74
1 files changed, 51 insertions, 23 deletions
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 68f1b80..88fb650 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_control_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_control_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_control_hdr *)skb->data)->req_id;
+ hdr->len = cpu_to_le16(skb->len + sizeof(struct p54_control_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);
}