diff options
author | David S. Miller <davem@davemloft.net> | 2008-06-10 04:54:31 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-10 04:54:31 -0400 |
commit | 788c0a53164c05c5ccdb1472474372b72ba74644 (patch) | |
tree | 5f274102e3dc4bcca6cb3a695aa2c8228ad5fc4f /drivers/net/wireless/zd1211rw | |
parent | e64bda89b8fe81cce9b4a20885d2c204c2d52532 (diff) | |
parent | 78cf07472f0ede8394bacc4bc02354505080cfe1 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts:
drivers/net/ps3_gelic_wireless.c
drivers/net/wireless/libertas/main.c
Diffstat (limited to 'drivers/net/wireless/zd1211rw')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 161 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.h | 16 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 29 |
3 files changed, 64 insertions, 142 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index c99d4a4fde05..d2378d083a35 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -224,36 +224,6 @@ out: | |||
224 | return r; | 224 | return r; |
225 | } | 225 | } |
226 | 226 | ||
227 | /** | ||
228 | * clear_tx_skb_control_block - clears the control block of tx skbuffs | ||
229 | * @skb: a &struct sk_buff pointer | ||
230 | * | ||
231 | * This clears the control block of skbuff buffers, which were transmitted to | ||
232 | * the device. Notify that the function is not thread-safe, so prevent | ||
233 | * multiple calls. | ||
234 | */ | ||
235 | static void clear_tx_skb_control_block(struct sk_buff *skb) | ||
236 | { | ||
237 | struct zd_tx_skb_control_block *cb = | ||
238 | (struct zd_tx_skb_control_block *)skb->cb; | ||
239 | |||
240 | kfree(cb->control); | ||
241 | cb->control = NULL; | ||
242 | } | ||
243 | |||
244 | /** | ||
245 | * kfree_tx_skb - frees a tx skbuff | ||
246 | * @skb: a &struct sk_buff pointer | ||
247 | * | ||
248 | * Frees the tx skbuff. Frees also the allocated control structure in the | ||
249 | * control block if necessary. | ||
250 | */ | ||
251 | static void kfree_tx_skb(struct sk_buff *skb) | ||
252 | { | ||
253 | clear_tx_skb_control_block(skb); | ||
254 | dev_kfree_skb_any(skb); | ||
255 | } | ||
256 | |||
257 | static void zd_op_stop(struct ieee80211_hw *hw) | 227 | static void zd_op_stop(struct ieee80211_hw *hw) |
258 | { | 228 | { |
259 | struct zd_mac *mac = zd_hw_mac(hw); | 229 | struct zd_mac *mac = zd_hw_mac(hw); |
@@ -276,40 +246,15 @@ static void zd_op_stop(struct ieee80211_hw *hw) | |||
276 | 246 | ||
277 | 247 | ||
278 | while ((skb = skb_dequeue(ack_wait_queue))) | 248 | while ((skb = skb_dequeue(ack_wait_queue))) |
279 | kfree_tx_skb(skb); | 249 | dev_kfree_skb_any(skb); |
280 | } | ||
281 | |||
282 | /** | ||
283 | * init_tx_skb_control_block - initializes skb control block | ||
284 | * @skb: a &sk_buff pointer | ||
285 | * @dev: pointer to the mac80221 device | ||
286 | * @control: mac80211 tx control applying for the frame in @skb | ||
287 | * | ||
288 | * Initializes the control block of the skbuff to be transmitted. | ||
289 | */ | ||
290 | static int init_tx_skb_control_block(struct sk_buff *skb, | ||
291 | struct ieee80211_hw *hw, | ||
292 | struct ieee80211_tx_control *control) | ||
293 | { | ||
294 | struct zd_tx_skb_control_block *cb = | ||
295 | (struct zd_tx_skb_control_block *)skb->cb; | ||
296 | |||
297 | ZD_ASSERT(sizeof(*cb) <= sizeof(skb->cb)); | ||
298 | memset(cb, 0, sizeof(*cb)); | ||
299 | cb->hw= hw; | ||
300 | cb->control = kmalloc(sizeof(*control), GFP_ATOMIC); | ||
301 | if (cb->control == NULL) | ||
302 | return -ENOMEM; | ||
303 | memcpy(cb->control, control, sizeof(*control)); | ||
304 | |||
305 | return 0; | ||
306 | } | 250 | } |
307 | 251 | ||
308 | /** | 252 | /** |
309 | * tx_status - reports tx status of a packet if required | 253 | * tx_status - reports tx status of a packet if required |
310 | * @hw - a &struct ieee80211_hw pointer | 254 | * @hw - a &struct ieee80211_hw pointer |
311 | * @skb - a sk-buffer | 255 | * @skb - a sk-buffer |
312 | * @status - the tx status of the packet without control information | 256 | * @flags: extra flags to set in the TX status info |
257 | * @ackssi: ACK signal strength | ||
313 | * @success - True for successfull transmission of the frame | 258 | * @success - True for successfull transmission of the frame |
314 | * | 259 | * |
315 | * This information calls ieee80211_tx_status_irqsafe() if required by the | 260 | * This information calls ieee80211_tx_status_irqsafe() if required by the |
@@ -319,18 +264,17 @@ static int init_tx_skb_control_block(struct sk_buff *skb, | |||
319 | * If no status information has been requested, the skb is freed. | 264 | * If no status information has been requested, the skb is freed. |
320 | */ | 265 | */ |
321 | static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 266 | static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, |
322 | struct ieee80211_tx_status *status, | 267 | u32 flags, int ackssi, bool success) |
323 | bool success) | ||
324 | { | 268 | { |
325 | struct zd_tx_skb_control_block *cb = (struct zd_tx_skb_control_block *) | 269 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
326 | skb->cb; | 270 | |
271 | memset(&info->status, 0, sizeof(info->status)); | ||
327 | 272 | ||
328 | ZD_ASSERT(cb->control != NULL); | ||
329 | memcpy(&status->control, cb->control, sizeof(status->control)); | ||
330 | if (!success) | 273 | if (!success) |
331 | status->excessive_retries = 1; | 274 | info->status.excessive_retries = 1; |
332 | clear_tx_skb_control_block(skb); | 275 | info->flags |= flags; |
333 | ieee80211_tx_status_irqsafe(hw, skb, status); | 276 | info->status.ack_signal = ackssi; |
277 | ieee80211_tx_status_irqsafe(hw, skb); | ||
334 | } | 278 | } |
335 | 279 | ||
336 | /** | 280 | /** |
@@ -345,15 +289,12 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw) | |||
345 | { | 289 | { |
346 | struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue; | 290 | struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue; |
347 | struct sk_buff *skb; | 291 | struct sk_buff *skb; |
348 | struct ieee80211_tx_status status; | ||
349 | 292 | ||
350 | skb = skb_dequeue(q); | 293 | skb = skb_dequeue(q); |
351 | if (skb == NULL) | 294 | if (skb == NULL) |
352 | return; | 295 | return; |
353 | 296 | ||
354 | memset(&status, 0, sizeof(status)); | 297 | tx_status(hw, skb, 0, 0, 0); |
355 | |||
356 | tx_status(hw, skb, &status, 0); | ||
357 | } | 298 | } |
358 | 299 | ||
359 | /** | 300 | /** |
@@ -368,28 +309,20 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw) | |||
368 | */ | 309 | */ |
369 | void zd_mac_tx_to_dev(struct sk_buff *skb, int error) | 310 | void zd_mac_tx_to_dev(struct sk_buff *skb, int error) |
370 | { | 311 | { |
371 | struct zd_tx_skb_control_block *cb = | 312 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
372 | (struct zd_tx_skb_control_block *)skb->cb; | 313 | struct ieee80211_hw *hw = info->driver_data[0]; |
373 | struct ieee80211_hw *hw = cb->hw; | ||
374 | |||
375 | if (likely(cb->control)) { | ||
376 | skb_pull(skb, sizeof(struct zd_ctrlset)); | ||
377 | if (unlikely(error || | ||
378 | (cb->control->flags & IEEE80211_TXCTL_NO_ACK))) | ||
379 | { | ||
380 | struct ieee80211_tx_status status; | ||
381 | memset(&status, 0, sizeof(status)); | ||
382 | tx_status(hw, skb, &status, !error); | ||
383 | } else { | ||
384 | struct sk_buff_head *q = | ||
385 | &zd_hw_mac(hw)->ack_wait_queue; | ||
386 | 314 | ||
387 | skb_queue_tail(q, skb); | 315 | skb_pull(skb, sizeof(struct zd_ctrlset)); |
388 | while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) | 316 | if (unlikely(error || |
389 | zd_mac_tx_failed(hw); | 317 | (info->flags & IEEE80211_TX_CTL_NO_ACK))) { |
390 | } | 318 | tx_status(hw, skb, 0, 0, !error); |
391 | } else { | 319 | } else { |
392 | kfree_tx_skb(skb); | 320 | struct sk_buff_head *q = |
321 | &zd_hw_mac(hw)->ack_wait_queue; | ||
322 | |||
323 | skb_queue_tail(q, skb); | ||
324 | while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) | ||
325 | zd_mac_tx_failed(hw); | ||
393 | } | 326 | } |
394 | } | 327 | } |
395 | 328 | ||
@@ -454,7 +387,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
454 | cs->control = 0; | 387 | cs->control = 0; |
455 | 388 | ||
456 | /* First fragment */ | 389 | /* First fragment */ |
457 | if (flags & IEEE80211_TXCTL_FIRST_FRAGMENT) | 390 | if (flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
458 | cs->control |= ZD_CS_NEED_RANDOM_BACKOFF; | 391 | cs->control |= ZD_CS_NEED_RANDOM_BACKOFF; |
459 | 392 | ||
460 | /* Multicast */ | 393 | /* Multicast */ |
@@ -466,10 +399,10 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
466 | (IEEE80211_FTYPE_CTL|IEEE80211_STYPE_PSPOLL)) | 399 | (IEEE80211_FTYPE_CTL|IEEE80211_STYPE_PSPOLL)) |
467 | cs->control |= ZD_CS_PS_POLL_FRAME; | 400 | cs->control |= ZD_CS_PS_POLL_FRAME; |
468 | 401 | ||
469 | if (flags & IEEE80211_TXCTL_USE_RTS_CTS) | 402 | if (flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
470 | cs->control |= ZD_CS_RTS; | 403 | cs->control |= ZD_CS_RTS; |
471 | 404 | ||
472 | if (flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 405 | if (flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) |
473 | cs->control |= ZD_CS_SELF_CTS; | 406 | cs->control |= ZD_CS_SELF_CTS; |
474 | 407 | ||
475 | /* FIXME: Management frame? */ | 408 | /* FIXME: Management frame? */ |
@@ -516,25 +449,28 @@ void zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon) | |||
516 | } | 449 | } |
517 | 450 | ||
518 | static int fill_ctrlset(struct zd_mac *mac, | 451 | static int fill_ctrlset(struct zd_mac *mac, |
519 | struct sk_buff *skb, | 452 | struct sk_buff *skb) |
520 | struct ieee80211_tx_control *control) | ||
521 | { | 453 | { |
522 | int r; | 454 | int r; |
523 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 455 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
524 | unsigned int frag_len = skb->len + FCS_LEN; | 456 | unsigned int frag_len = skb->len + FCS_LEN; |
525 | unsigned int packet_length; | 457 | unsigned int packet_length; |
458 | struct ieee80211_rate *txrate; | ||
526 | struct zd_ctrlset *cs = (struct zd_ctrlset *) | 459 | struct zd_ctrlset *cs = (struct zd_ctrlset *) |
527 | skb_push(skb, sizeof(struct zd_ctrlset)); | 460 | skb_push(skb, sizeof(struct zd_ctrlset)); |
461 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
528 | 462 | ||
529 | ZD_ASSERT(frag_len <= 0xffff); | 463 | ZD_ASSERT(frag_len <= 0xffff); |
530 | 464 | ||
531 | cs->modulation = control->tx_rate->hw_value; | 465 | txrate = ieee80211_get_tx_rate(mac->hw, info); |
532 | if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) | 466 | |
533 | cs->modulation = control->tx_rate->hw_value_short; | 467 | cs->modulation = txrate->hw_value; |
468 | if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) | ||
469 | cs->modulation = txrate->hw_value_short; | ||
534 | 470 | ||
535 | cs->tx_length = cpu_to_le16(frag_len); | 471 | cs->tx_length = cpu_to_le16(frag_len); |
536 | 472 | ||
537 | cs_set_control(mac, cs, hdr, control->flags); | 473 | cs_set_control(mac, cs, hdr, info->flags); |
538 | 474 | ||
539 | packet_length = frag_len + sizeof(struct zd_ctrlset) + 10; | 475 | packet_length = frag_len + sizeof(struct zd_ctrlset) + 10; |
540 | ZD_ASSERT(packet_length <= 0xffff); | 476 | ZD_ASSERT(packet_length <= 0xffff); |
@@ -579,24 +515,21 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
579 | * control block of the skbuff will be initialized. If necessary the incoming | 515 | * control block of the skbuff will be initialized. If necessary the incoming |
580 | * mac80211 queues will be stopped. | 516 | * mac80211 queues will be stopped. |
581 | */ | 517 | */ |
582 | static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | 518 | static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
583 | struct ieee80211_tx_control *control) | ||
584 | { | 519 | { |
585 | struct zd_mac *mac = zd_hw_mac(hw); | 520 | struct zd_mac *mac = zd_hw_mac(hw); |
521 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
586 | int r; | 522 | int r; |
587 | 523 | ||
588 | r = fill_ctrlset(mac, skb, control); | 524 | r = fill_ctrlset(mac, skb); |
589 | if (r) | 525 | if (r) |
590 | return r; | 526 | return r; |
591 | 527 | ||
592 | r = init_tx_skb_control_block(skb, hw, control); | 528 | info->driver_data[0] = hw; |
593 | if (r) | 529 | |
594 | return r; | ||
595 | r = zd_usb_tx(&mac->chip.usb, skb); | 530 | r = zd_usb_tx(&mac->chip.usb, skb); |
596 | if (r) { | 531 | if (r) |
597 | clear_tx_skb_control_block(skb); | ||
598 | return r; | 532 | return r; |
599 | } | ||
600 | return 0; | 533 | return 0; |
601 | } | 534 | } |
602 | 535 | ||
@@ -634,13 +567,8 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, | |||
634 | tx_hdr = (struct ieee80211_hdr *)skb->data; | 567 | tx_hdr = (struct ieee80211_hdr *)skb->data; |
635 | if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) | 568 | if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) |
636 | { | 569 | { |
637 | struct ieee80211_tx_status status; | ||
638 | |||
639 | memset(&status, 0, sizeof(status)); | ||
640 | status.flags = IEEE80211_TX_STATUS_ACK; | ||
641 | status.ack_signal = stats->signal; | ||
642 | __skb_unlink(skb, q); | 570 | __skb_unlink(skb, q); |
643 | tx_status(hw, skb, &status, 1); | 571 | tx_status(hw, skb, IEEE80211_TX_STAT_ACK, stats->signal, 1); |
644 | goto out; | 572 | goto out; |
645 | } | 573 | } |
646 | } | 574 | } |
@@ -944,8 +872,7 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw, | |||
944 | } | 872 | } |
945 | 873 | ||
946 | static int zd_op_beacon_update(struct ieee80211_hw *hw, | 874 | static int zd_op_beacon_update(struct ieee80211_hw *hw, |
947 | struct sk_buff *skb, | 875 | struct sk_buff *skb) |
948 | struct ieee80211_tx_control *ctl) | ||
949 | { | 876 | { |
950 | struct zd_mac *mac = zd_hw_mac(hw); | 877 | struct zd_mac *mac = zd_hw_mac(hw); |
951 | zd_mac_config_beacon(hw, skb); | 878 | zd_mac_config_beacon(hw, skb); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 71170244d2c9..18c1d56d3dd7 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h | |||
@@ -149,22 +149,6 @@ struct housekeeping { | |||
149 | struct delayed_work link_led_work; | 149 | struct delayed_work link_led_work; |
150 | }; | 150 | }; |
151 | 151 | ||
152 | /** | ||
153 | * struct zd_tx_skb_control_block - control block for tx skbuffs | ||
154 | * @control: &struct ieee80211_tx_control pointer | ||
155 | * @context: context pointer | ||
156 | * | ||
157 | * This structure is used to fill the cb field in an &sk_buff to transmit. | ||
158 | * The control field is NULL, if there is no requirement from the mac80211 | ||
159 | * stack to report about the packet ACK. This is the case if the flag | ||
160 | * IEEE80211_TXCTL_NO_ACK is not set in &struct ieee80211_tx_control. | ||
161 | */ | ||
162 | struct zd_tx_skb_control_block { | ||
163 | struct ieee80211_tx_control *control; | ||
164 | struct ieee80211_hw *hw; | ||
165 | void *context; | ||
166 | }; | ||
167 | |||
168 | #define ZD_MAC_STATS_BUFFER_SIZE 16 | 152 | #define ZD_MAC_STATS_BUFFER_SIZE 16 |
169 | 153 | ||
170 | #define ZD_MAC_MAX_ACK_WAITERS 10 | 154 | #define ZD_MAC_MAX_ACK_WAITERS 10 |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 8941f5eb96c2..1ccff240bf97 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -169,10 +169,11 @@ static int upload_code(struct usb_device *udev, | |||
169 | if (flags & REBOOT) { | 169 | if (flags & REBOOT) { |
170 | u8 ret; | 170 | u8 ret; |
171 | 171 | ||
172 | /* Use "DMA-aware" buffer. */ | ||
172 | r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | 173 | r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
173 | USB_REQ_FIRMWARE_CONFIRM, | 174 | USB_REQ_FIRMWARE_CONFIRM, |
174 | USB_DIR_IN | USB_TYPE_VENDOR, | 175 | USB_DIR_IN | USB_TYPE_VENDOR, |
175 | 0, 0, &ret, sizeof(ret), 5000 /* ms */); | 176 | 0, 0, p, sizeof(ret), 5000 /* ms */); |
176 | if (r != sizeof(ret)) { | 177 | if (r != sizeof(ret)) { |
177 | dev_err(&udev->dev, | 178 | dev_err(&udev->dev, |
178 | "control request firmeware confirmation failed." | 179 | "control request firmeware confirmation failed." |
@@ -181,6 +182,7 @@ static int upload_code(struct usb_device *udev, | |||
181 | r = -ENODEV; | 182 | r = -ENODEV; |
182 | goto error; | 183 | goto error; |
183 | } | 184 | } |
185 | ret = p[0]; | ||
184 | if (ret & 0x80) { | 186 | if (ret & 0x80) { |
185 | dev_err(&udev->dev, | 187 | dev_err(&udev->dev, |
186 | "Internal error while downloading." | 188 | "Internal error while downloading." |
@@ -312,22 +314,31 @@ int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len) | |||
312 | { | 314 | { |
313 | int r; | 315 | int r; |
314 | struct usb_device *udev = zd_usb_to_usbdev(usb); | 316 | struct usb_device *udev = zd_usb_to_usbdev(usb); |
317 | u8 *buf; | ||
315 | 318 | ||
319 | /* Use "DMA-aware" buffer. */ | ||
320 | buf = kmalloc(len, GFP_KERNEL); | ||
321 | if (!buf) | ||
322 | return -ENOMEM; | ||
316 | r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | 323 | r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
317 | USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0, | 324 | USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0, |
318 | data, len, 5000); | 325 | buf, len, 5000); |
319 | if (r < 0) { | 326 | if (r < 0) { |
320 | dev_err(&udev->dev, | 327 | dev_err(&udev->dev, |
321 | "read over firmware interface failed: %d\n", r); | 328 | "read over firmware interface failed: %d\n", r); |
322 | return r; | 329 | goto exit; |
323 | } else if (r != len) { | 330 | } else if (r != len) { |
324 | dev_err(&udev->dev, | 331 | dev_err(&udev->dev, |
325 | "incomplete read over firmware interface: %d/%d\n", | 332 | "incomplete read over firmware interface: %d/%d\n", |
326 | r, len); | 333 | r, len); |
327 | return -EIO; | 334 | r = -EIO; |
335 | goto exit; | ||
328 | } | 336 | } |
329 | 337 | r = 0; | |
330 | return 0; | 338 | memcpy(data, buf, len); |
339 | exit: | ||
340 | kfree(buf); | ||
341 | return r; | ||
331 | } | 342 | } |
332 | 343 | ||
333 | #define urb_dev(urb) (&(urb)->dev->dev) | 344 | #define urb_dev(urb) (&(urb)->dev->dev) |
@@ -869,7 +880,7 @@ static void tx_urb_complete(struct urb *urb) | |||
869 | { | 880 | { |
870 | int r; | 881 | int r; |
871 | struct sk_buff *skb; | 882 | struct sk_buff *skb; |
872 | struct zd_tx_skb_control_block *cb; | 883 | struct ieee80211_tx_info *info; |
873 | struct zd_usb *usb; | 884 | struct zd_usb *usb; |
874 | 885 | ||
875 | switch (urb->status) { | 886 | switch (urb->status) { |
@@ -893,8 +904,8 @@ free_urb: | |||
893 | * grab 'usb' pointer before handing off the skb (since | 904 | * grab 'usb' pointer before handing off the skb (since |
894 | * it might be freed by zd_mac_tx_to_dev or mac80211) | 905 | * it might be freed by zd_mac_tx_to_dev or mac80211) |
895 | */ | 906 | */ |
896 | cb = (struct zd_tx_skb_control_block *)skb->cb; | 907 | info = IEEE80211_SKB_CB(skb); |
897 | usb = &zd_hw_mac(cb->hw)->chip.usb; | 908 | usb = &zd_hw_mac(info->driver_data[0])->chip.usb; |
898 | zd_mac_tx_to_dev(skb, urb->status); | 909 | zd_mac_tx_to_dev(skb, urb->status); |
899 | free_tx_urb(usb, urb); | 910 | free_tx_urb(usb, urb); |
900 | tx_dec_submitted_urbs(usb); | 911 | tx_dec_submitted_urbs(usb); |