diff options
Diffstat (limited to 'drivers/net/wireless/rtl818x/rtl8187_dev.c')
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187_dev.c | 124 |
1 files changed, 66 insertions, 58 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index dbf52e8bbd7a..74f5449b7924 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -99,7 +99,6 @@ static const struct ieee80211_channel rtl818x_channels[] = { | |||
99 | static void rtl8187_iowrite_async_cb(struct urb *urb) | 99 | static void rtl8187_iowrite_async_cb(struct urb *urb) |
100 | { | 100 | { |
101 | kfree(urb->context); | 101 | kfree(urb->context); |
102 | usb_free_urb(urb); | ||
103 | } | 102 | } |
104 | 103 | ||
105 | static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, | 104 | static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, |
@@ -136,11 +135,13 @@ static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, | |||
136 | usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0), | 135 | usb_fill_control_urb(urb, priv->udev, usb_sndctrlpipe(priv->udev, 0), |
137 | (unsigned char *)dr, buf, len, | 136 | (unsigned char *)dr, buf, len, |
138 | rtl8187_iowrite_async_cb, buf); | 137 | rtl8187_iowrite_async_cb, buf); |
138 | usb_anchor_urb(urb, &priv->anchored); | ||
139 | rc = usb_submit_urb(urb, GFP_ATOMIC); | 139 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
140 | if (rc < 0) { | 140 | if (rc < 0) { |
141 | kfree(buf); | 141 | kfree(buf); |
142 | usb_free_urb(urb); | 142 | usb_unanchor_urb(urb); |
143 | } | 143 | } |
144 | usb_free_urb(urb); | ||
144 | } | 145 | } |
145 | 146 | ||
146 | static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv, | 147 | static inline void rtl818x_iowrite32_async(struct rtl8187_priv *priv, |
@@ -172,7 +173,6 @@ static void rtl8187_tx_cb(struct urb *urb) | |||
172 | struct ieee80211_hw *hw = info->rate_driver_data[0]; | 173 | struct ieee80211_hw *hw = info->rate_driver_data[0]; |
173 | struct rtl8187_priv *priv = hw->priv; | 174 | struct rtl8187_priv *priv = hw->priv; |
174 | 175 | ||
175 | usb_free_urb(info->rate_driver_data[1]); | ||
176 | skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) : | 176 | skb_pull(skb, priv->is_rtl8187b ? sizeof(struct rtl8187b_tx_hdr) : |
177 | sizeof(struct rtl8187_tx_hdr)); | 177 | sizeof(struct rtl8187_tx_hdr)); |
178 | ieee80211_tx_info_clear_status(info); | 178 | ieee80211_tx_info_clear_status(info); |
@@ -273,11 +273,13 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
273 | 273 | ||
274 | usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep), | 274 | usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep), |
275 | buf, skb->len, rtl8187_tx_cb, skb); | 275 | buf, skb->len, rtl8187_tx_cb, skb); |
276 | usb_anchor_urb(urb, &priv->anchored); | ||
276 | rc = usb_submit_urb(urb, GFP_ATOMIC); | 277 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
277 | if (rc < 0) { | 278 | if (rc < 0) { |
278 | usb_free_urb(urb); | 279 | usb_unanchor_urb(urb); |
279 | kfree_skb(skb); | 280 | kfree_skb(skb); |
280 | } | 281 | } |
282 | usb_free_urb(urb); | ||
281 | 283 | ||
282 | return 0; | 284 | return 0; |
283 | } | 285 | } |
@@ -301,41 +303,25 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
301 | return; | 303 | return; |
302 | } | 304 | } |
303 | spin_unlock(&priv->rx_queue.lock); | 305 | spin_unlock(&priv->rx_queue.lock); |
306 | skb_put(skb, urb->actual_length); | ||
304 | 307 | ||
305 | if (unlikely(urb->status)) { | 308 | if (unlikely(urb->status)) { |
306 | usb_free_urb(urb); | ||
307 | dev_kfree_skb_irq(skb); | 309 | dev_kfree_skb_irq(skb); |
308 | return; | 310 | return; |
309 | } | 311 | } |
310 | 312 | ||
311 | skb_put(skb, urb->actual_length); | ||
312 | if (!priv->is_rtl8187b) { | 313 | if (!priv->is_rtl8187b) { |
313 | struct rtl8187_rx_hdr *hdr = | 314 | struct rtl8187_rx_hdr *hdr = |
314 | (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); | 315 | (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); |
315 | flags = le32_to_cpu(hdr->flags); | 316 | flags = le32_to_cpu(hdr->flags); |
316 | signal = hdr->signal & 0x7f; | 317 | /* As with the RTL8187B below, the AGC is used to calculate |
318 | * signal strength and quality. In this case, the scaling | ||
319 | * constants are derived from the output of p54usb. | ||
320 | */ | ||
321 | quality = 130 - ((41 * hdr->agc) >> 6); | ||
322 | signal = -4 - ((27 * hdr->agc) >> 6); | ||
317 | rx_status.antenna = (hdr->signal >> 7) & 1; | 323 | rx_status.antenna = (hdr->signal >> 7) & 1; |
318 | rx_status.noise = hdr->noise; | ||
319 | rx_status.mactime = le64_to_cpu(hdr->mac_time); | 324 | rx_status.mactime = le64_to_cpu(hdr->mac_time); |
320 | priv->quality = signal; | ||
321 | rx_status.qual = priv->quality; | ||
322 | priv->noise = hdr->noise; | ||
323 | rate = (flags >> 20) & 0xF; | ||
324 | if (rate > 3) { /* OFDM rate */ | ||
325 | if (signal > 90) | ||
326 | signal = 90; | ||
327 | else if (signal < 25) | ||
328 | signal = 25; | ||
329 | signal = 90 - signal; | ||
330 | } else { /* CCK rate */ | ||
331 | if (signal > 95) | ||
332 | signal = 95; | ||
333 | else if (signal < 30) | ||
334 | signal = 30; | ||
335 | signal = 95 - signal; | ||
336 | } | ||
337 | rx_status.signal = signal; | ||
338 | priv->signal = signal; | ||
339 | } else { | 325 | } else { |
340 | struct rtl8187b_rx_hdr *hdr = | 326 | struct rtl8187b_rx_hdr *hdr = |
341 | (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); | 327 | (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); |
@@ -353,18 +339,18 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
353 | */ | 339 | */ |
354 | flags = le32_to_cpu(hdr->flags); | 340 | flags = le32_to_cpu(hdr->flags); |
355 | quality = 170 - hdr->agc; | 341 | quality = 170 - hdr->agc; |
356 | if (quality > 100) | ||
357 | quality = 100; | ||
358 | signal = 14 - hdr->agc / 2; | 342 | signal = 14 - hdr->agc / 2; |
359 | rx_status.qual = quality; | ||
360 | priv->quality = quality; | ||
361 | rx_status.signal = signal; | ||
362 | priv->signal = signal; | ||
363 | rx_status.antenna = (hdr->rssi >> 7) & 1; | 343 | rx_status.antenna = (hdr->rssi >> 7) & 1; |
364 | rx_status.mactime = le64_to_cpu(hdr->mac_time); | 344 | rx_status.mactime = le64_to_cpu(hdr->mac_time); |
365 | rate = (flags >> 20) & 0xF; | ||
366 | } | 345 | } |
367 | 346 | ||
347 | if (quality > 100) | ||
348 | quality = 100; | ||
349 | rx_status.qual = quality; | ||
350 | priv->quality = quality; | ||
351 | rx_status.signal = signal; | ||
352 | priv->signal = signal; | ||
353 | rate = (flags >> 20) & 0xF; | ||
368 | skb_trim(skb, flags & 0x0FFF); | 354 | skb_trim(skb, flags & 0x0FFF); |
369 | rx_status.rate_idx = rate; | 355 | rx_status.rate_idx = rate; |
370 | rx_status.freq = dev->conf.channel->center_freq; | 356 | rx_status.freq = dev->conf.channel->center_freq; |
@@ -376,7 +362,6 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
376 | 362 | ||
377 | skb = dev_alloc_skb(RTL8187_MAX_RX); | 363 | skb = dev_alloc_skb(RTL8187_MAX_RX); |
378 | if (unlikely(!skb)) { | 364 | if (unlikely(!skb)) { |
379 | usb_free_urb(urb); | ||
380 | /* TODO check rx queue length and refill *somewhere* */ | 365 | /* TODO check rx queue length and refill *somewhere* */ |
381 | return; | 366 | return; |
382 | } | 367 | } |
@@ -388,24 +373,32 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
388 | urb->context = skb; | 373 | urb->context = skb; |
389 | skb_queue_tail(&priv->rx_queue, skb); | 374 | skb_queue_tail(&priv->rx_queue, skb); |
390 | 375 | ||
391 | usb_submit_urb(urb, GFP_ATOMIC); | 376 | usb_anchor_urb(urb, &priv->anchored); |
377 | if (usb_submit_urb(urb, GFP_ATOMIC)) { | ||
378 | usb_unanchor_urb(urb); | ||
379 | skb_unlink(skb, &priv->rx_queue); | ||
380 | dev_kfree_skb_irq(skb); | ||
381 | } | ||
392 | } | 382 | } |
393 | 383 | ||
394 | static int rtl8187_init_urbs(struct ieee80211_hw *dev) | 384 | static int rtl8187_init_urbs(struct ieee80211_hw *dev) |
395 | { | 385 | { |
396 | struct rtl8187_priv *priv = dev->priv; | 386 | struct rtl8187_priv *priv = dev->priv; |
397 | struct urb *entry; | 387 | struct urb *entry = NULL; |
398 | struct sk_buff *skb; | 388 | struct sk_buff *skb; |
399 | struct rtl8187_rx_info *info; | 389 | struct rtl8187_rx_info *info; |
390 | int ret = 0; | ||
400 | 391 | ||
401 | while (skb_queue_len(&priv->rx_queue) < 8) { | 392 | while (skb_queue_len(&priv->rx_queue) < 8) { |
402 | skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); | 393 | skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); |
403 | if (!skb) | 394 | if (!skb) { |
404 | break; | 395 | ret = -ENOMEM; |
396 | goto err; | ||
397 | } | ||
405 | entry = usb_alloc_urb(0, GFP_KERNEL); | 398 | entry = usb_alloc_urb(0, GFP_KERNEL); |
406 | if (!entry) { | 399 | if (!entry) { |
407 | kfree_skb(skb); | 400 | ret = -ENOMEM; |
408 | break; | 401 | goto err; |
409 | } | 402 | } |
410 | usb_fill_bulk_urb(entry, priv->udev, | 403 | usb_fill_bulk_urb(entry, priv->udev, |
411 | usb_rcvbulkpipe(priv->udev, | 404 | usb_rcvbulkpipe(priv->udev, |
@@ -416,10 +409,22 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev) | |||
416 | info->urb = entry; | 409 | info->urb = entry; |
417 | info->dev = dev; | 410 | info->dev = dev; |
418 | skb_queue_tail(&priv->rx_queue, skb); | 411 | skb_queue_tail(&priv->rx_queue, skb); |
419 | usb_submit_urb(entry, GFP_KERNEL); | 412 | usb_anchor_urb(entry, &priv->anchored); |
413 | ret = usb_submit_urb(entry, GFP_KERNEL); | ||
414 | if (ret) { | ||
415 | skb_unlink(skb, &priv->rx_queue); | ||
416 | usb_unanchor_urb(entry); | ||
417 | goto err; | ||
418 | } | ||
419 | usb_free_urb(entry); | ||
420 | } | 420 | } |
421 | return ret; | ||
421 | 422 | ||
422 | return 0; | 423 | err: |
424 | usb_free_urb(entry); | ||
425 | kfree_skb(skb); | ||
426 | usb_kill_anchored_urbs(&priv->anchored); | ||
427 | return ret; | ||
423 | } | 428 | } |
424 | 429 | ||
425 | static void rtl8187b_status_cb(struct urb *urb) | 430 | static void rtl8187b_status_cb(struct urb *urb) |
@@ -429,10 +434,8 @@ static void rtl8187b_status_cb(struct urb *urb) | |||
429 | u64 val; | 434 | u64 val; |
430 | unsigned int cmd_type; | 435 | unsigned int cmd_type; |
431 | 436 | ||
432 | if (unlikely(urb->status)) { | 437 | if (unlikely(urb->status)) |
433 | usb_free_urb(urb); | ||
434 | return; | 438 | return; |
435 | } | ||
436 | 439 | ||
437 | /* | 440 | /* |
438 | * Read from status buffer: | 441 | * Read from status buffer: |
@@ -503,26 +506,32 @@ static void rtl8187b_status_cb(struct urb *urb) | |||
503 | spin_unlock_irqrestore(&priv->b_tx_status.queue.lock, flags); | 506 | spin_unlock_irqrestore(&priv->b_tx_status.queue.lock, flags); |
504 | } | 507 | } |
505 | 508 | ||
506 | usb_submit_urb(urb, GFP_ATOMIC); | 509 | usb_anchor_urb(urb, &priv->anchored); |
510 | if (usb_submit_urb(urb, GFP_ATOMIC)) | ||
511 | usb_unanchor_urb(urb); | ||
507 | } | 512 | } |
508 | 513 | ||
509 | static int rtl8187b_init_status_urb(struct ieee80211_hw *dev) | 514 | static int rtl8187b_init_status_urb(struct ieee80211_hw *dev) |
510 | { | 515 | { |
511 | struct rtl8187_priv *priv = dev->priv; | 516 | struct rtl8187_priv *priv = dev->priv; |
512 | struct urb *entry; | 517 | struct urb *entry; |
518 | int ret = 0; | ||
513 | 519 | ||
514 | entry = usb_alloc_urb(0, GFP_KERNEL); | 520 | entry = usb_alloc_urb(0, GFP_KERNEL); |
515 | if (!entry) | 521 | if (!entry) |
516 | return -ENOMEM; | 522 | return -ENOMEM; |
517 | priv->b_tx_status.urb = entry; | ||
518 | 523 | ||
519 | usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, 9), | 524 | usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, 9), |
520 | &priv->b_tx_status.buf, sizeof(priv->b_tx_status.buf), | 525 | &priv->b_tx_status.buf, sizeof(priv->b_tx_status.buf), |
521 | rtl8187b_status_cb, dev); | 526 | rtl8187b_status_cb, dev); |
522 | 527 | ||
523 | usb_submit_urb(entry, GFP_KERNEL); | 528 | usb_anchor_urb(entry, &priv->anchored); |
529 | ret = usb_submit_urb(entry, GFP_KERNEL); | ||
530 | if (ret) | ||
531 | usb_unanchor_urb(entry); | ||
532 | usb_free_urb(entry); | ||
524 | 533 | ||
525 | return 0; | 534 | return ret; |
526 | } | 535 | } |
527 | 536 | ||
528 | static int rtl8187_cmd_reset(struct ieee80211_hw *dev) | 537 | static int rtl8187_cmd_reset(struct ieee80211_hw *dev) |
@@ -856,6 +865,9 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
856 | return ret; | 865 | return ret; |
857 | 866 | ||
858 | mutex_lock(&priv->conf_mutex); | 867 | mutex_lock(&priv->conf_mutex); |
868 | |||
869 | init_usb_anchor(&priv->anchored); | ||
870 | |||
859 | if (priv->is_rtl8187b) { | 871 | if (priv->is_rtl8187b) { |
860 | reg = RTL818X_RX_CONF_MGMT | | 872 | reg = RTL818X_RX_CONF_MGMT | |
861 | RTL818X_RX_CONF_DATA | | 873 | RTL818X_RX_CONF_DATA | |
@@ -951,12 +963,12 @@ static void rtl8187_stop(struct ieee80211_hw *dev) | |||
951 | 963 | ||
952 | while ((skb = skb_dequeue(&priv->rx_queue))) { | 964 | while ((skb = skb_dequeue(&priv->rx_queue))) { |
953 | info = (struct rtl8187_rx_info *)skb->cb; | 965 | info = (struct rtl8187_rx_info *)skb->cb; |
954 | usb_kill_urb(info->urb); | ||
955 | kfree_skb(skb); | 966 | kfree_skb(skb); |
956 | } | 967 | } |
957 | while ((skb = skb_dequeue(&priv->b_tx_status.queue))) | 968 | while ((skb = skb_dequeue(&priv->b_tx_status.queue))) |
958 | dev_kfree_skb_any(skb); | 969 | dev_kfree_skb_any(skb); |
959 | usb_kill_urb(priv->b_tx_status.urb); | 970 | |
971 | usb_kill_anchored_urbs(&priv->anchored); | ||
960 | mutex_unlock(&priv->conf_mutex); | 972 | mutex_unlock(&priv->conf_mutex); |
961 | } | 973 | } |
962 | 974 | ||
@@ -1293,6 +1305,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1293 | 1305 | ||
1294 | priv->mode = NL80211_IFTYPE_MONITOR; | 1306 | priv->mode = NL80211_IFTYPE_MONITOR; |
1295 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 1307 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1308 | IEEE80211_HW_SIGNAL_DBM | | ||
1296 | IEEE80211_HW_RX_INCLUDES_FCS; | 1309 | IEEE80211_HW_RX_INCLUDES_FCS; |
1297 | 1310 | ||
1298 | eeprom.data = dev; | 1311 | eeprom.data = dev; |
@@ -1408,13 +1421,8 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1408 | (*channel++).hw_value = txpwr >> 8; | 1421 | (*channel++).hw_value = txpwr >> 8; |
1409 | } | 1422 | } |
1410 | 1423 | ||
1411 | if (priv->is_rtl8187b) { | 1424 | if (priv->is_rtl8187b) |
1412 | printk(KERN_WARNING "rtl8187: 8187B chip detected.\n"); | 1425 | printk(KERN_WARNING "rtl8187: 8187B chip detected.\n"); |
1413 | dev->flags |= IEEE80211_HW_SIGNAL_DBM; | ||
1414 | } else { | ||
1415 | dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC; | ||
1416 | dev->max_signal = 65; | ||
1417 | } | ||
1418 | 1426 | ||
1419 | /* | 1427 | /* |
1420 | * XXX: Once this driver supports anything that requires | 1428 | * XXX: Once this driver supports anything that requires |