aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/main.c')
-rw-r--r--drivers/net/wireless/wl12xx/main.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index a2171a4e9413..15d8166fbf66 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -366,6 +366,7 @@ static struct conf_drv_settings default_conf = {
366 .duration = 150, 366 .duration = 150,
367 .queues = 0x1, 367 .queues = 0x1,
368 .interval = 20, 368 .interval = 20,
369 .always = 0,
369 }, 370 },
370 .hci_io_ds = HCI_IO_DS_6MA, 371 .hci_io_ds = HCI_IO_DS_6MA,
371}; 372};
@@ -478,6 +479,117 @@ static int wl1271_reg_notify(struct wiphy *wiphy,
478 return 0; 479 return 0;
479} 480}
480 481
482static int wl1271_set_rx_streaming(struct wl1271 *wl, bool enable)
483{
484 int ret = 0;
485
486 /* we should hold wl->mutex */
487 ret = wl1271_acx_ps_rx_streaming(wl, enable);
488 if (ret < 0)
489 goto out;
490
491 if (enable)
492 set_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags);
493 else
494 clear_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags);
495out:
496 return ret;
497}
498
499/*
500 * this function is being called when the rx_streaming interval
501 * has beed changed or rx_streaming should be disabled
502 */
503int wl1271_recalc_rx_streaming(struct wl1271 *wl)
504{
505 int ret = 0;
506 int period = wl->conf.rx_streaming.interval;
507
508 /* don't reconfigure if rx_streaming is disabled */
509 if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags))
510 goto out;
511
512 /* reconfigure/disable according to new streaming_period */
513 if (period &&
514 test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) &&
515 (wl->conf.rx_streaming.always ||
516 test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags)))
517 ret = wl1271_set_rx_streaming(wl, true);
518 else {
519 ret = wl1271_set_rx_streaming(wl, false);
520 /* don't cancel_work_sync since we might deadlock */
521 del_timer_sync(&wl->rx_streaming_timer);
522 }
523out:
524 return ret;
525}
526
527static void wl1271_rx_streaming_enable_work(struct work_struct *work)
528{
529 int ret;
530 struct wl1271 *wl =
531 container_of(work, struct wl1271, rx_streaming_enable_work);
532
533 mutex_lock(&wl->mutex);
534
535 if (test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags) ||
536 !test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) ||
537 (!wl->conf.rx_streaming.always &&
538 !test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags)))
539 goto out;
540
541 if (!wl->conf.rx_streaming.interval)
542 goto out;
543
544 ret = wl1271_ps_elp_wakeup(wl);
545 if (ret < 0)
546 goto out;
547
548 ret = wl1271_set_rx_streaming(wl, true);
549 if (ret < 0)
550 goto out_sleep;
551
552 /* stop it after some time of inactivity */
553 mod_timer(&wl->rx_streaming_timer,
554 jiffies + msecs_to_jiffies(wl->conf.rx_streaming.duration));
555
556out_sleep:
557 wl1271_ps_elp_sleep(wl);
558out:
559 mutex_unlock(&wl->mutex);
560}
561
562static void wl1271_rx_streaming_disable_work(struct work_struct *work)
563{
564 int ret;
565 struct wl1271 *wl =
566 container_of(work, struct wl1271, rx_streaming_disable_work);
567
568 mutex_lock(&wl->mutex);
569
570 if (!test_bit(WL1271_FLAG_RX_STREAMING_STARTED, &wl->flags))
571 goto out;
572
573 ret = wl1271_ps_elp_wakeup(wl);
574 if (ret < 0)
575 goto out;
576
577 ret = wl1271_set_rx_streaming(wl, false);
578 if (ret)
579 goto out_sleep;
580
581out_sleep:
582 wl1271_ps_elp_sleep(wl);
583out:
584 mutex_unlock(&wl->mutex);
585}
586
587static void wl1271_rx_streaming_timer(unsigned long data)
588{
589 struct wl1271 *wl = (struct wl1271 *)data;
590 ieee80211_queue_work(wl->hw, &wl->rx_streaming_disable_work);
591}
592
481static void wl1271_conf_init(struct wl1271 *wl) 593static void wl1271_conf_init(struct wl1271 *wl)
482{ 594{
483 595
@@ -1699,6 +1811,9 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
1699 cancel_delayed_work_sync(&wl->scan_complete_work); 1811 cancel_delayed_work_sync(&wl->scan_complete_work);
1700 cancel_work_sync(&wl->netstack_work); 1812 cancel_work_sync(&wl->netstack_work);
1701 cancel_work_sync(&wl->tx_work); 1813 cancel_work_sync(&wl->tx_work);
1814 del_timer_sync(&wl->rx_streaming_timer);
1815 cancel_work_sync(&wl->rx_streaming_enable_work);
1816 cancel_work_sync(&wl->rx_streaming_disable_work);
1702 cancel_delayed_work_sync(&wl->pspoll_work); 1817 cancel_delayed_work_sync(&wl->pspoll_work);
1703 cancel_delayed_work_sync(&wl->elp_work); 1818 cancel_delayed_work_sync(&wl->elp_work);
1704 1819
@@ -3969,6 +4084,11 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
3969 INIT_WORK(&wl->tx_work, wl1271_tx_work); 4084 INIT_WORK(&wl->tx_work, wl1271_tx_work);
3970 INIT_WORK(&wl->recovery_work, wl1271_recovery_work); 4085 INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
3971 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); 4086 INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
4087 INIT_WORK(&wl->rx_streaming_enable_work,
4088 wl1271_rx_streaming_enable_work);
4089 INIT_WORK(&wl->rx_streaming_disable_work,
4090 wl1271_rx_streaming_disable_work);
4091
3972 wl->channel = WL1271_DEFAULT_CHANNEL; 4092 wl->channel = WL1271_DEFAULT_CHANNEL;
3973 wl->beacon_int = WL1271_DEFAULT_BEACON_INT; 4093 wl->beacon_int = WL1271_DEFAULT_BEACON_INT;
3974 wl->default_key = 0; 4094 wl->default_key = 0;
@@ -3994,6 +4114,8 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
3994 wl->quirks = 0; 4114 wl->quirks = 0;
3995 wl->platform_quirks = 0; 4115 wl->platform_quirks = 0;
3996 wl->sched_scanning = false; 4116 wl->sched_scanning = false;
4117 setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer,
4118 (unsigned long) wl);
3997 4119
3998 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); 4120 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
3999 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 4121 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)