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.c94
1 files changed, 41 insertions, 53 deletions
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index eb22dd248d54..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.
@@ -472,6 +430,14 @@ mwifiex_open(struct net_device *dev)
472static int 430static int
473mwifiex_close(struct net_device *dev) 431mwifiex_close(struct net_device *dev)
474{ 432{
433 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
434
435 if (priv->scan_request) {
436 dev_dbg(priv->adapter->dev, "aborting scan on ndo_stop\n");
437 cfg80211_scan_done(priv->scan_request, 1);
438 priv->scan_request = NULL;
439 }
440
475 return 0; 441 return 0;
476} 442}
477 443
@@ -480,17 +446,23 @@ mwifiex_close(struct net_device *dev)
480 */ 446 */
481int 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)
482{ 448{
483 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
484 atomic_inc(&priv->adapter->tx_pending); 460 atomic_inc(&priv->adapter->tx_pending);
461 mwifiex_wmm_add_buf_txqueue(priv, skb);
485 462
486 if (priv->adapter->scan_delay_cnt) 463 if (priv->adapter->scan_delay_cnt)
487 atomic_set(&priv->adapter->is_tx_received, true); 464 atomic_set(&priv->adapter->is_tx_received, true);
488 465
489 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
490 mwifiex_set_trans_start(priv->netdev);
491 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
492 }
493
494 queue_work(priv->adapter->workqueue, &priv->adapter->main_work); 466 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
495 467
496 return 0; 468 return 0;
@@ -505,6 +477,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
505 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 477 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
506 struct sk_buff *new_skb; 478 struct sk_buff *new_skb;
507 struct mwifiex_txinfo *tx_info; 479 struct mwifiex_txinfo *tx_info;
480 struct timeval tv;
508 481
509 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",
510 jiffies, priv->bss_type, priv->bss_num); 483 jiffies, priv->bss_type, priv->bss_num);
@@ -542,7 +515,16 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
542 tx_info = MWIFIEX_SKB_TXCB(skb); 515 tx_info = MWIFIEX_SKB_TXCB(skb);
543 tx_info->bss_num = priv->bss_num; 516 tx_info->bss_num = priv->bss_num;
544 tx_info->bss_type = priv->bss_type; 517 tx_info->bss_type = priv->bss_type;
545 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);
546 528
547 mwifiex_queue_tx_pkt(priv, skb); 529 mwifiex_queue_tx_pkt(priv, skb);
548 530
@@ -622,6 +604,13 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
622 return &priv->stats; 604 return &priv->stats;
623} 605}
624 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
625/* Network device handlers */ 614/* Network device handlers */
626static const struct net_device_ops mwifiex_netdev_ops = { 615static const struct net_device_ops mwifiex_netdev_ops = {
627 .ndo_open = mwifiex_open, 616 .ndo_open = mwifiex_open,
@@ -631,6 +620,7 @@ static const struct net_device_ops mwifiex_netdev_ops = {
631 .ndo_tx_timeout = mwifiex_tx_timeout, 620 .ndo_tx_timeout = mwifiex_tx_timeout,
632 .ndo_get_stats = mwifiex_get_stats, 621 .ndo_get_stats = mwifiex_get_stats,
633 .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,
634}; 624};
635 625
636/* 626/*
@@ -830,9 +820,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
830 for (i = 0; i < adapter->priv_num; i++) { 820 for (i = 0; i < adapter->priv_num; i++) {
831 priv = adapter->priv[i]; 821 priv = adapter->priv[i];
832 if (priv && priv->netdev) { 822 if (priv && priv->netdev) {
833 if (!netif_queue_stopped(priv->netdev)) 823 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
834 mwifiex_stop_net_dev_queue(priv->netdev,
835 adapter);
836 if (netif_carrier_ok(priv->netdev)) 824 if (netif_carrier_ok(priv->netdev))
837 netif_carrier_off(priv->netdev); 825 netif_carrier_off(priv->netdev);
838 } 826 }