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 68f1b80f04d9..88fb65046c71 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)
135 usb_submit_urb(urb, GFP_ATOMIC); 135 usb_submit_urb(urb, GFP_ATOMIC);
136} 136}
137 137
138static void p54u_tx_reuse_skb_cb(struct urb *urb)
139{
140 struct sk_buff *skb = urb->context;
141 struct p54u_priv *priv = (struct p54u_priv *)((struct ieee80211_hw *)
142 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)))->priv;
143
144 skb_pull(skb, priv->common.tx_hdr_len);
145 usb_free_urb(urb);
146}
147
138static void p54u_tx_cb(struct urb *urb) 148static void p54u_tx_cb(struct urb *urb)
139{ 149{
140 usb_free_urb(urb); 150 usb_free_urb(urb);
@@ -146,6 +156,16 @@ static void p54u_tx_free_cb(struct urb *urb)
146 usb_free_urb(urb); 156 usb_free_urb(urb);
147} 157}
148 158
159static void p54u_tx_free_skb_cb(struct urb *urb)
160{
161 struct sk_buff *skb = urb->context;
162 struct ieee80211_hw *dev = (struct ieee80211_hw *)
163 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
164
165 p54_free_skb(dev, skb);
166 usb_free_urb(urb);
167}
168
149static int p54u_init_urbs(struct ieee80211_hw *dev) 169static int p54u_init_urbs(struct ieee80211_hw *dev)
150{ 170{
151 struct p54u_priv *priv = dev->priv; 171 struct p54u_priv *priv = dev->priv;
@@ -192,8 +212,8 @@ static void p54u_free_urbs(struct ieee80211_hw *dev)
192 } 212 }
193} 213}
194 214
195static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data, 215static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb,
196 size_t len, int free_on_tx) 216 int free_on_tx)
197{ 217{
198 struct p54u_priv *priv = dev->priv; 218 struct p54u_priv *priv = dev->priv;
199 struct urb *addr_urb, *data_urb; 219 struct urb *addr_urb, *data_urb;
@@ -209,11 +229,14 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
209 } 229 }
210 230
211 usb_fill_bulk_urb(addr_urb, priv->udev, 231 usb_fill_bulk_urb(addr_urb, priv->udev,
212 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id, 232 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
213 sizeof(data->req_id), p54u_tx_cb, dev); 233 &((struct p54_control_hdr *)skb->data)->req_id, 4,
234 p54u_tx_cb, dev);
214 usb_fill_bulk_urb(data_urb, priv->udev, 235 usb_fill_bulk_urb(data_urb, priv->udev,
215 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len, 236 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
216 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev); 237 skb->data, skb->len,
238 free_on_tx ? p54u_tx_free_skb_cb :
239 p54u_tx_reuse_skb_cb, skb);
217 240
218 usb_submit_urb(addr_urb, GFP_ATOMIC); 241 usb_submit_urb(addr_urb, GFP_ATOMIC);
219 usb_submit_urb(data_urb, GFP_ATOMIC); 242 usb_submit_urb(data_urb, GFP_ATOMIC);
@@ -232,31 +255,35 @@ static __le32 p54u_lm87_chksum(const u32 *data, size_t length)
232 return cpu_to_le32(chk); 255 return cpu_to_le32(chk);
233} 256}
234 257
235static void p54u_tx_lm87(struct ieee80211_hw *dev, 258static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb,
236 struct p54_control_hdr *data, 259 int free_on_tx)
237 size_t len, int free_on_tx)
238{ 260{
239 struct p54u_priv *priv = dev->priv; 261 struct p54u_priv *priv = dev->priv;
240 struct urb *data_urb; 262 struct urb *data_urb;
241 struct lm87_tx_hdr *hdr = (void *)data - sizeof(*hdr); 263 struct lm87_tx_hdr *hdr;
264 __le32 checksum;
265 __le32 addr = ((struct p54_control_hdr *)skb->data)->req_id;
242 266
243 data_urb = usb_alloc_urb(0, GFP_ATOMIC); 267 data_urb = usb_alloc_urb(0, GFP_ATOMIC);
244 if (!data_urb) 268 if (!data_urb)
245 return; 269 return;
246 270
247 hdr->chksum = p54u_lm87_chksum((u32 *)data, len); 271 checksum = p54u_lm87_chksum((u32 *)skb->data, skb->len);
248 hdr->device_addr = data->req_id; 272 hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr));
273 hdr->chksum = checksum;
274 hdr->device_addr = addr;
249 275
250 usb_fill_bulk_urb(data_urb, priv->udev, 276 usb_fill_bulk_urb(data_urb, priv->udev,
251 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, 277 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
252 len + sizeof(*hdr), free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, 278 skb->data, skb->len,
253 dev); 279 free_on_tx ? p54u_tx_free_skb_cb :
280 p54u_tx_reuse_skb_cb, skb);
254 281
255 usb_submit_urb(data_urb, GFP_ATOMIC); 282 usb_submit_urb(data_urb, GFP_ATOMIC);
256} 283}
257 284
258static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data, 285static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb,
259 size_t len, int free_on_tx) 286 int free_on_tx)
260{ 287{
261 struct p54u_priv *priv = dev->priv; 288 struct p54u_priv *priv = dev->priv;
262 struct urb *int_urb, *data_urb; 289 struct urb *int_urb, *data_urb;
@@ -284,11 +311,10 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *da
284 reg->addr = cpu_to_le32(P54U_DEV_BASE); 311 reg->addr = cpu_to_le32(P54U_DEV_BASE);
285 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA); 312 reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA);
286 313
287 len += sizeof(*data); 314 hdr = (void *)skb_push(skb, sizeof(*hdr));
288 hdr = (void *)data - sizeof(*hdr);
289 memset(hdr, 0, sizeof(*hdr)); 315 memset(hdr, 0, sizeof(*hdr));
290 hdr->device_addr = data->req_id; 316 hdr->device_addr = ((struct p54_control_hdr *)skb->data)->req_id;
291 hdr->len = cpu_to_le16(len); 317 hdr->len = cpu_to_le16(skb->len + sizeof(struct p54_control_hdr));
292 318
293 usb_fill_bulk_urb(int_urb, priv->udev, 319 usb_fill_bulk_urb(int_urb, priv->udev,
294 usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg), 320 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
296 usb_submit_urb(int_urb, GFP_ATOMIC); 322 usb_submit_urb(int_urb, GFP_ATOMIC);
297 323
298 usb_fill_bulk_urb(data_urb, priv->udev, 324 usb_fill_bulk_urb(data_urb, priv->udev,
299 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr), 325 usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
300 free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev); 326 skb->data, skb->len,
327 free_on_tx ? p54u_tx_free_skb_cb :
328 p54u_tx_reuse_skb_cb, skb);
301 usb_submit_urb(data_urb, GFP_ATOMIC); 329 usb_submit_urb(data_urb, GFP_ATOMIC);
302} 330}
303 331