diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/main.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/main.c | 86 |
1 files changed, 33 insertions, 53 deletions
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 1df767bc8b6e..9c802ede9c3b 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -282,6 +282,7 @@ exit_main_proc: | |||
282 | mwifiex_shutdown_drv(adapter); | 282 | mwifiex_shutdown_drv(adapter); |
283 | return ret; | 283 | return ret; |
284 | } | 284 | } |
285 | EXPORT_SYMBOL_GPL(mwifiex_main_process); | ||
285 | 286 | ||
286 | /* | 287 | /* |
287 | * This function frees the adapter structure. | 288 | * This function frees the adapter structure. |
@@ -412,49 +413,6 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter) | |||
412 | } | 413 | } |
413 | 414 | ||
414 | /* | 415 | /* |
415 | * This function fills a driver buffer. | ||
416 | * | ||
417 | * The function associates a given SKB with the provided driver buffer | ||
418 | * and also updates some of the SKB parameters, including IP header, | ||
419 | * priority and timestamp. | ||
420 | */ | ||
421 | static void | ||
422 | mwifiex_fill_buffer(struct sk_buff *skb) | ||
423 | { | ||
424 | struct ethhdr *eth; | ||
425 | struct iphdr *iph; | ||
426 | struct timeval tv; | ||
427 | u8 tid = 0; | ||
428 | |||
429 | eth = (struct ethhdr *) skb->data; | ||
430 | switch (eth->h_proto) { | ||
431 | case __constant_htons(ETH_P_IP): | ||
432 | iph = ip_hdr(skb); | ||
433 | tid = IPTOS_PREC(iph->tos); | ||
434 | pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n", | ||
435 | eth->h_proto, tid, skb->priority); | ||
436 | break; | ||
437 | case __constant_htons(ETH_P_ARP): | ||
438 | pr_debug("data: ARP packet: %04x\n", eth->h_proto); | ||
439 | default: | ||
440 | break; | ||
441 | } | ||
442 | /* Offset for TOS field in the IP header */ | ||
443 | #define IPTOS_OFFSET 5 | ||
444 | tid = (tid >> IPTOS_OFFSET); | ||
445 | skb->priority = tid; | ||
446 | /* Record the current time the packet was queued; used to | ||
447 | determine the amount of time the packet was queued in | ||
448 | the driver before it was sent to the firmware. | ||
449 | The delay is then sent along with the packet to the | ||
450 | firmware for aggregate delay calculation for stats and | ||
451 | MSDU lifetime expiry. | ||
452 | */ | ||
453 | do_gettimeofday(&tv); | ||
454 | skb->tstamp = timeval_to_ktime(tv); | ||
455 | } | ||
456 | |||
457 | /* | ||
458 | * CFG802.11 network device handler for open. | 416 | * CFG802.11 network device handler for open. |
459 | * | 417 | * |
460 | * Starts the data queue. | 418 | * Starts the data queue. |
@@ -488,17 +446,23 @@ mwifiex_close(struct net_device *dev) | |||
488 | */ | 446 | */ |
489 | int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) | 447 | int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) |
490 | { | 448 | { |
491 | mwifiex_wmm_add_buf_txqueue(priv, skb); | 449 | struct netdev_queue *txq; |
450 | int index = mwifiex_1d_to_wmm_queue[skb->priority]; | ||
451 | |||
452 | if (atomic_inc_return(&priv->wmm_tx_pending[index]) >= MAX_TX_PENDING) { | ||
453 | txq = netdev_get_tx_queue(priv->netdev, index); | ||
454 | if (!netif_tx_queue_stopped(txq)) { | ||
455 | netif_tx_stop_queue(txq); | ||
456 | dev_dbg(priv->adapter->dev, "stop queue: %d\n", index); | ||
457 | } | ||
458 | } | ||
459 | |||
492 | atomic_inc(&priv->adapter->tx_pending); | 460 | atomic_inc(&priv->adapter->tx_pending); |
461 | mwifiex_wmm_add_buf_txqueue(priv, skb); | ||
493 | 462 | ||
494 | if (priv->adapter->scan_delay_cnt) | 463 | if (priv->adapter->scan_delay_cnt) |
495 | atomic_set(&priv->adapter->is_tx_received, true); | 464 | atomic_set(&priv->adapter->is_tx_received, true); |
496 | 465 | ||
497 | if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) { | ||
498 | mwifiex_set_trans_start(priv->netdev); | ||
499 | mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); | ||
500 | } | ||
501 | |||
502 | queue_work(priv->adapter->workqueue, &priv->adapter->main_work); | 466 | queue_work(priv->adapter->workqueue, &priv->adapter->main_work); |
503 | 467 | ||
504 | return 0; | 468 | return 0; |
@@ -513,6 +477,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
513 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 477 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
514 | struct sk_buff *new_skb; | 478 | struct sk_buff *new_skb; |
515 | struct mwifiex_txinfo *tx_info; | 479 | struct mwifiex_txinfo *tx_info; |
480 | struct timeval tv; | ||
516 | 481 | ||
517 | dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", | 482 | dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", |
518 | jiffies, priv->bss_type, priv->bss_num); | 483 | jiffies, priv->bss_type, priv->bss_num); |
@@ -550,7 +515,16 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
550 | tx_info = MWIFIEX_SKB_TXCB(skb); | 515 | tx_info = MWIFIEX_SKB_TXCB(skb); |
551 | tx_info->bss_num = priv->bss_num; | 516 | tx_info->bss_num = priv->bss_num; |
552 | tx_info->bss_type = priv->bss_type; | 517 | tx_info->bss_type = priv->bss_type; |
553 | mwifiex_fill_buffer(skb); | 518 | |
519 | /* Record the current time the packet was queued; used to | ||
520 | * determine the amount of time the packet was queued in | ||
521 | * the driver before it was sent to the firmware. | ||
522 | * The delay is then sent along with the packet to the | ||
523 | * firmware for aggregate delay calculation for stats and | ||
524 | * MSDU lifetime expiry. | ||
525 | */ | ||
526 | do_gettimeofday(&tv); | ||
527 | skb->tstamp = timeval_to_ktime(tv); | ||
554 | 528 | ||
555 | mwifiex_queue_tx_pkt(priv, skb); | 529 | mwifiex_queue_tx_pkt(priv, skb); |
556 | 530 | ||
@@ -630,6 +604,13 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev) | |||
630 | return &priv->stats; | 604 | return &priv->stats; |
631 | } | 605 | } |
632 | 606 | ||
607 | static u16 | ||
608 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb) | ||
609 | { | ||
610 | skb->priority = cfg80211_classify8021d(skb); | ||
611 | return mwifiex_1d_to_wmm_queue[skb->priority]; | ||
612 | } | ||
613 | |||
633 | /* Network device handlers */ | 614 | /* Network device handlers */ |
634 | static const struct net_device_ops mwifiex_netdev_ops = { | 615 | static const struct net_device_ops mwifiex_netdev_ops = { |
635 | .ndo_open = mwifiex_open, | 616 | .ndo_open = mwifiex_open, |
@@ -639,6 +620,7 @@ static const struct net_device_ops mwifiex_netdev_ops = { | |||
639 | .ndo_tx_timeout = mwifiex_tx_timeout, | 620 | .ndo_tx_timeout = mwifiex_tx_timeout, |
640 | .ndo_get_stats = mwifiex_get_stats, | 621 | .ndo_get_stats = mwifiex_get_stats, |
641 | .ndo_set_rx_mode = mwifiex_set_multicast_list, | 622 | .ndo_set_rx_mode = mwifiex_set_multicast_list, |
623 | .ndo_select_queue = mwifiex_netdev_select_wmm_queue, | ||
642 | }; | 624 | }; |
643 | 625 | ||
644 | /* | 626 | /* |
@@ -838,9 +820,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) | |||
838 | for (i = 0; i < adapter->priv_num; i++) { | 820 | for (i = 0; i < adapter->priv_num; i++) { |
839 | priv = adapter->priv[i]; | 821 | priv = adapter->priv[i]; |
840 | if (priv && priv->netdev) { | 822 | if (priv && priv->netdev) { |
841 | if (!netif_queue_stopped(priv->netdev)) | 823 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); |
842 | mwifiex_stop_net_dev_queue(priv->netdev, | ||
843 | adapter); | ||
844 | if (netif_carrier_ok(priv->netdev)) | 824 | if (netif_carrier_ok(priv->netdev)) |
845 | netif_carrier_off(priv->netdev); | 825 | netif_carrier_off(priv->netdev); |
846 | } | 826 | } |