aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/main.c')
-rw-r--r--drivers/net/wireless/mwifiex/main.c86
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}
285EXPORT_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 */
421static void
422mwifiex_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 */
489int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) 447int 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
607static u16
608mwifiex_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 */
634static const struct net_device_ops mwifiex_netdev_ops = { 615static 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 }