aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2009-07-16 19:48:41 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-20 11:38:08 -0400
commit950d5b0191dc3e71017f336017f75f6189f39f08 (patch)
tree1e61d8d2795ab278ea415e7228c289bf33fb29f2 /drivers
parent23b339062f247e0be84eaabb15e17b403c4388b6 (diff)
mwl8k: mwl8k_queue_work() cleanup
Delete most of the mwl8k_work_struct fields and options, since most of them are unused or never changed from their defaults: - We always use priv->config_wq, so delete the wqueue argument from mwl8k_queue_work(). - MWL8K_WQ_SPIN and MWL8K_WQ_POST_REQUEST are never used, as all callers sleep for request completion, so sleep unconditionally. - MWL8K_WQ_FREE_WORKSTRUCT is never used. - MWL8K_WQ_TX_WAIT_EMPTY is always set, so assume it unconditionally. - timeout_ms/txwait_attempts/tx_timeout_ms are never changed from their defaults, so just hardcode these in the workqueue worker. - step is never used. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/mwl8k.c204
1 files changed, 33 insertions, 171 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 88ba52e13af2..7bbdca418314 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1113,7 +1113,7 @@ static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
1113 return ndescs; 1113 return ndescs;
1114} 1114}
1115 1115
1116static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms) 1116static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1117{ 1117{
1118 struct mwl8k_priv *priv = hw->priv; 1118 struct mwl8k_priv *priv = hw->priv;
1119 DECLARE_COMPLETION_ONSTACK(cmd_wait); 1119 DECLARE_COMPLETION_ONSTACK(cmd_wait);
@@ -1140,7 +1140,7 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
1140 int newcount; 1140 int newcount;
1141 1141
1142 timeout = wait_for_completion_timeout(&cmd_wait, 1142 timeout = wait_for_completion_timeout(&cmd_wait,
1143 msecs_to_jiffies(delay_ms)); 1143 msecs_to_jiffies(1000));
1144 if (timeout) 1144 if (timeout)
1145 return 0; 1145 return 0;
1146 1146
@@ -1149,8 +1149,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
1149 newcount = mwl8k_txq_busy(priv); 1149 newcount = mwl8k_txq_busy(priv);
1150 spin_unlock_bh(&priv->tx_lock); 1150 spin_unlock_bh(&priv->tx_lock);
1151 1151
1152 printk(KERN_ERR "%s(%u) TIMEDOUT:%ums Pend:%u-->%u\n", 1152 printk(KERN_ERR "%s(%u) TIMEDOUT:1000ms Pend:%u-->%u\n",
1153 __func__, __LINE__, delay_ms, count, newcount); 1153 __func__, __LINE__, count, newcount);
1154 1154
1155 mwl8k_scan_tx_ring(priv, txinfo); 1155 mwl8k_scan_tx_ring(priv, txinfo);
1156 for (index = 0; index < MWL8K_TX_QUEUES; index++) 1156 for (index = 0; index < MWL8K_TX_QUEUES; index++)
@@ -2389,84 +2389,15 @@ struct mwl8k_work_struct {
2389 2389
2390 /* Result code. */ 2390 /* Result code. */
2391 int rc; 2391 int rc;
2392
2393 /*
2394 * Optional field. Refer to explanation of MWL8K_WQ_XXX_XXX
2395 * flags for explanation. Defaults to MWL8K_WQ_DEFAULT_OPTIONS.
2396 */
2397 u32 options;
2398
2399 /* Optional field. Defaults to MWL8K_CONFIG_TIMEOUT_MS. */
2400 unsigned long timeout_ms;
2401
2402 /* Optional field. Defaults to MWL8K_WQ_TXWAIT_ATTEMPTS. */
2403 u32 txwait_attempts;
2404
2405 /* Optional field. Defaults to MWL8K_TXWAIT_MS. */
2406 u32 tx_timeout_ms;
2407 u32 step;
2408}; 2392};
2409 2393
2410/* Flags controlling behavior of config queue requests */
2411
2412/* Caller spins while waiting for completion. */
2413#define MWL8K_WQ_SPIN 0x00000001
2414
2415/* Wait for TX queues to empty before proceeding with configuration. */
2416#define MWL8K_WQ_TX_WAIT_EMPTY 0x00000002
2417
2418/* Queue request and return immediately. */
2419#define MWL8K_WQ_POST_REQUEST 0x00000004
2420
2421/*
2422 * Caller sleeps and waits for task complete notification.
2423 * Do not use in atomic context.
2424 */
2425#define MWL8K_WQ_SLEEP 0x00000008
2426
2427/* Free work struct when task is done. */
2428#define MWL8K_WQ_FREE_WORKSTRUCT 0x00000010
2429
2430/*
2431 * Config request is queued and returns to caller imediately. Use
2432 * this in atomic context. Work struct is freed by mwl8k_queue_work()
2433 * when this flag is set.
2434 */
2435#define MWL8K_WQ_QUEUE_ONLY (MWL8K_WQ_POST_REQUEST | \
2436 MWL8K_WQ_FREE_WORKSTRUCT)
2437
2438/* Default work queue behavior is to sleep and wait for tx completion. */
2439#define MWL8K_WQ_DEFAULT_OPTIONS (MWL8K_WQ_SLEEP | MWL8K_WQ_TX_WAIT_EMPTY)
2440
2441/*
2442 * Default config request timeout. Add adjustments to make sure the
2443 * config thread waits long enough for both tx wait and cmd wait before
2444 * timing out.
2445 */
2446
2447/* Time to wait for all TXQs to drain. TX Doorbell is pressed each time. */
2448#define MWL8K_TXWAIT_TIMEOUT_MS 1000
2449
2450/* Default number of TX wait attempts. */
2451#define MWL8K_WQ_TXWAIT_ATTEMPTS 4
2452
2453/* Total time to wait for TXQ to drain. */
2454#define MWL8K_TXWAIT_MS (MWL8K_TXWAIT_TIMEOUT_MS * \
2455 MWL8K_WQ_TXWAIT_ATTEMPTS)
2456
2457/* Scheduling slop. */
2458#define MWL8K_OS_SCHEDULE_OVERHEAD_MS 200
2459
2460#define MWL8K_CONFIG_TIMEOUT_MS (MWL8K_CMD_TIMEOUT_MS + \
2461 MWL8K_TXWAIT_MS + \
2462 MWL8K_OS_SCHEDULE_OVERHEAD_MS)
2463
2464static void mwl8k_config_thread(struct work_struct *wt) 2394static void mwl8k_config_thread(struct work_struct *wt)
2465{ 2395{
2466 struct mwl8k_work_struct *worker = (struct mwl8k_work_struct *)wt; 2396 struct mwl8k_work_struct *worker = (struct mwl8k_work_struct *)wt;
2467 struct ieee80211_hw *hw = worker->hw; 2397 struct ieee80211_hw *hw = worker->hw;
2468 struct mwl8k_priv *priv = hw->priv; 2398 struct mwl8k_priv *priv = hw->priv;
2469 int rc = 0; 2399 int rc = 0;
2400 int iter;
2470 2401
2471 spin_lock_irq(&priv->tx_lock); 2402 spin_lock_irq(&priv->tx_lock);
2472 priv->inconfig = true; 2403 priv->inconfig = true;
@@ -2479,44 +2410,16 @@ static void mwl8k_config_thread(struct work_struct *wt)
2479 * reconfiguration. This avoids interrupting any in-flight 2410 * reconfiguration. This avoids interrupting any in-flight
2480 * DMA transfers to the hardware. 2411 * DMA transfers to the hardware.
2481 */ 2412 */
2482 if (worker->options & MWL8K_WQ_TX_WAIT_EMPTY) { 2413 iter = 4;
2483 u32 timeout; 2414 do {
2484 u32 time_remaining; 2415 rc = mwl8k_tx_wait_empty(hw);
2485 u32 iter; 2416 if (rc)
2486 u32 tx_wait_attempts = worker->txwait_attempts; 2417 printk(KERN_ERR "%s() txwait timeout=1000ms "
2487 2418 "Retry:%u/%u\n", __func__, 4 - iter + 1, 4);
2488 time_remaining = worker->tx_timeout_ms; 2419 } while (rc && --iter);
2489 if (!tx_wait_attempts)
2490 tx_wait_attempts = 1;
2491
2492 timeout = worker->tx_timeout_ms/tx_wait_attempts;
2493 if (!timeout)
2494 timeout = 1;
2495
2496 iter = tx_wait_attempts;
2497 do {
2498 int wait_time;
2499
2500 if (time_remaining > timeout) {
2501 time_remaining -= timeout;
2502 wait_time = timeout;
2503 } else
2504 wait_time = time_remaining;
2505
2506 if (!wait_time)
2507 wait_time = 1;
2508
2509 rc = mwl8k_tx_wait_empty(hw, wait_time);
2510 if (rc)
2511 printk(KERN_ERR "%s() txwait timeout=%ums "
2512 "Retry:%u/%u\n", __func__, timeout,
2513 tx_wait_attempts - iter + 1,
2514 tx_wait_attempts);
2515 2420
2516 } while (rc && --iter); 2421 rc = iter ? 0 : -ETIMEDOUT;
2517 2422
2518 rc = iter ? 0 : -ETIMEDOUT;
2519 }
2520 if (!rc) 2423 if (!rc)
2521 rc = worker->wfunc(wt); 2424 rc = worker->wfunc(wt);
2522 2425
@@ -2525,65 +2428,39 @@ static void mwl8k_config_thread(struct work_struct *wt)
2525 if (priv->pending_tx_pkts && priv->radio_on) 2428 if (priv->pending_tx_pkts && priv->radio_on)
2526 mwl8k_tx_start(priv); 2429 mwl8k_tx_start(priv);
2527 spin_unlock_irq(&priv->tx_lock); 2430 spin_unlock_irq(&priv->tx_lock);
2431
2528 ieee80211_wake_queues(hw); 2432 ieee80211_wake_queues(hw);
2529 2433
2530 worker->rc = rc; 2434 worker->rc = rc;
2531 if (worker->options & MWL8K_WQ_SLEEP) 2435 complete(worker->cmd_wait);
2532 complete(worker->cmd_wait);
2533
2534 if (worker->options & MWL8K_WQ_FREE_WORKSTRUCT)
2535 kfree(wt);
2536} 2436}
2537 2437
2538static int mwl8k_queue_work(struct ieee80211_hw *hw, 2438static int mwl8k_queue_work(struct ieee80211_hw *hw,
2539 struct mwl8k_work_struct *worker, 2439 struct mwl8k_work_struct *worker,
2540 struct workqueue_struct *wqueue,
2541 int (*wfunc)(struct work_struct *w)) 2440 int (*wfunc)(struct work_struct *w))
2542{ 2441{
2442 struct mwl8k_priv *priv = hw->priv;
2543 unsigned long timeout = 0; 2443 unsigned long timeout = 0;
2544 int rc = 0; 2444 int rc = 0;
2545 2445
2546 DECLARE_COMPLETION_ONSTACK(cmd_wait); 2446 DECLARE_COMPLETION_ONSTACK(cmd_wait);
2547 2447
2548 if (!worker->timeout_ms)
2549 worker->timeout_ms = MWL8K_CONFIG_TIMEOUT_MS;
2550
2551 if (!worker->options)
2552 worker->options = MWL8K_WQ_DEFAULT_OPTIONS;
2553
2554 if (!worker->txwait_attempts)
2555 worker->txwait_attempts = MWL8K_WQ_TXWAIT_ATTEMPTS;
2556
2557 if (!worker->tx_timeout_ms)
2558 worker->tx_timeout_ms = MWL8K_TXWAIT_MS;
2559
2560 worker->hw = hw; 2448 worker->hw = hw;
2561 worker->cmd_wait = &cmd_wait; 2449 worker->cmd_wait = &cmd_wait;
2562 worker->rc = 1; 2450 worker->rc = 1;
2563 worker->wfunc = wfunc; 2451 worker->wfunc = wfunc;
2564 2452
2565 INIT_WORK(&worker->wt, mwl8k_config_thread); 2453 INIT_WORK(&worker->wt, mwl8k_config_thread);
2566 queue_work(wqueue, &worker->wt); 2454 queue_work(priv->config_wq, &worker->wt);
2567 2455
2568 if (worker->options & MWL8K_WQ_POST_REQUEST) { 2456 timeout = wait_for_completion_timeout(&cmd_wait,
2569 rc = 0; 2457 msecs_to_jiffies(10000));
2570 } else {
2571 if (worker->options & MWL8K_WQ_SPIN) {
2572 timeout = worker->timeout_ms;
2573 while (timeout && (worker->rc > 0)) {
2574 mdelay(1);
2575 timeout--;
2576 }
2577 } else if (worker->options & MWL8K_WQ_SLEEP)
2578 timeout = wait_for_completion_timeout(&cmd_wait,
2579 msecs_to_jiffies(worker->timeout_ms));
2580 2458
2581 if (timeout) 2459 if (timeout)
2582 rc = worker->rc; 2460 rc = worker->rc;
2583 else { 2461 else {
2584 cancel_work_sync(&worker->wt); 2462 cancel_work_sync(&worker->wt);
2585 rc = -ETIMEDOUT; 2463 rc = -ETIMEDOUT;
2586 }
2587 } 2464 }
2588 2465
2589 return rc; 2466 return rc;
@@ -2669,8 +2546,7 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2669 goto mwl8k_start_disable_irq; 2546 goto mwl8k_start_disable_irq;
2670 } 2547 }
2671 2548
2672 rc = mwl8k_queue_work(hw, &worker->header, 2549 rc = mwl8k_queue_work(hw, &worker->header, mwl8k_start_wt);
2673 priv->config_wq, mwl8k_start_wt);
2674 kfree(worker); 2550 kfree(worker);
2675 if (!rc) 2551 if (!rc)
2676 return rc; 2552 return rc;
@@ -2720,8 +2596,7 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
2720 if (worker == NULL) 2596 if (worker == NULL)
2721 return; 2597 return;
2722 2598
2723 rc = mwl8k_queue_work(hw, &worker->header, 2599 rc = mwl8k_queue_work(hw, &worker->header, mwl8k_stop_wt);
2724 priv->config_wq, mwl8k_stop_wt);
2725 kfree(worker); 2600 kfree(worker);
2726 if (rc == -ETIMEDOUT) 2601 if (rc == -ETIMEDOUT)
2727 printk(KERN_ERR "%s() timed out\n", __func__); 2602 printk(KERN_ERR "%s() timed out\n", __func__);
@@ -2849,15 +2724,14 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
2849{ 2724{
2850 int rc = 0; 2725 int rc = 0;
2851 struct mwl8k_config_worker *worker; 2726 struct mwl8k_config_worker *worker;
2852 struct mwl8k_priv *priv = hw->priv;
2853 2727
2854 worker = kzalloc(sizeof(*worker), GFP_KERNEL); 2728 worker = kzalloc(sizeof(*worker), GFP_KERNEL);
2855 if (worker == NULL) 2729 if (worker == NULL)
2856 return -ENOMEM; 2730 return -ENOMEM;
2857 2731
2858 worker->changed = changed; 2732 worker->changed = changed;
2859 rc = mwl8k_queue_work(hw, &worker->header, 2733
2860 priv->config_wq, mwl8k_config_wt); 2734 rc = mwl8k_queue_work(hw, &worker->header, mwl8k_config_wt);
2861 if (rc == -ETIMEDOUT) { 2735 if (rc == -ETIMEDOUT) {
2862 printk(KERN_ERR "%s() timed out.\n", __func__); 2736 printk(KERN_ERR "%s() timed out.\n", __func__);
2863 rc = -EINVAL; 2737 rc = -EINVAL;
@@ -2950,7 +2824,6 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
2950 u32 changed) 2824 u32 changed)
2951{ 2825{
2952 struct mwl8k_bss_info_changed_worker *worker; 2826 struct mwl8k_bss_info_changed_worker *worker;
2953 struct mwl8k_priv *priv = hw->priv;
2954 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif); 2827 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
2955 int rc; 2828 int rc;
2956 2829
@@ -2967,9 +2840,7 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
2967 worker->vif = vif; 2840 worker->vif = vif;
2968 worker->info = info; 2841 worker->info = info;
2969 worker->changed = changed; 2842 worker->changed = changed;
2970 rc = mwl8k_queue_work(hw, &worker->header, 2843 rc = mwl8k_queue_work(hw, &worker->header, mwl8k_bss_info_changed_wt);
2971 priv->config_wq,
2972 mwl8k_bss_info_changed_wt);
2973 kfree(worker); 2844 kfree(worker);
2974 if (rc == -ETIMEDOUT) 2845 if (rc == -ETIMEDOUT)
2975 printk(KERN_ERR "%s() timed out\n", __func__); 2846 printk(KERN_ERR "%s() timed out\n", __func__);
@@ -3028,7 +2899,6 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3028 unsigned int *total_flags, 2899 unsigned int *total_flags,
3029 u64 multicast) 2900 u64 multicast)
3030{ 2901{
3031 struct mwl8k_priv *priv = hw->priv;
3032 struct mwl8k_configure_filter_worker *worker; 2902 struct mwl8k_configure_filter_worker *worker;
3033 2903
3034 /* Clear unsupported feature flags */ 2904 /* Clear unsupported feature flags */
@@ -3045,8 +2915,7 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3045 worker->total_flags = *total_flags; 2915 worker->total_flags = *total_flags;
3046 worker->multicast_adr_cmd = (void *)(unsigned long)multicast; 2916 worker->multicast_adr_cmd = (void *)(unsigned long)multicast;
3047 2917
3048 mwl8k_queue_work(hw, &worker->header, priv->config_wq, 2918 mwl8k_queue_work(hw, &worker->header, mwl8k_configure_filter_wt);
3049 mwl8k_configure_filter_wt);
3050} 2919}
3051 2920
3052struct mwl8k_set_rts_threshold_worker { 2921struct mwl8k_set_rts_threshold_worker {
@@ -3072,7 +2941,6 @@ static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3072{ 2941{
3073 int rc; 2942 int rc;
3074 struct mwl8k_set_rts_threshold_worker *worker; 2943 struct mwl8k_set_rts_threshold_worker *worker;
3075 struct mwl8k_priv *priv = hw->priv;
3076 2944
3077 worker = kzalloc(sizeof(*worker), GFP_KERNEL); 2945 worker = kzalloc(sizeof(*worker), GFP_KERNEL);
3078 if (worker == NULL) 2946 if (worker == NULL)
@@ -3080,9 +2948,7 @@ static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3080 2948
3081 worker->value = value; 2949 worker->value = value;
3082 2950
3083 rc = mwl8k_queue_work(hw, &worker->header, 2951 rc = mwl8k_queue_work(hw, &worker->header, mwl8k_set_rts_threshold_wt);
3084 priv->config_wq,
3085 mwl8k_set_rts_threshold_wt);
3086 kfree(worker); 2952 kfree(worker);
3087 2953
3088 if (rc == -ETIMEDOUT) { 2954 if (rc == -ETIMEDOUT) {
@@ -3130,7 +2996,6 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
3130{ 2996{
3131 int rc; 2997 int rc;
3132 struct mwl8k_conf_tx_worker *worker; 2998 struct mwl8k_conf_tx_worker *worker;
3133 struct mwl8k_priv *priv = hw->priv;
3134 2999
3135 worker = kzalloc(sizeof(*worker), GFP_KERNEL); 3000 worker = kzalloc(sizeof(*worker), GFP_KERNEL);
3136 if (worker == NULL) 3001 if (worker == NULL)
@@ -3138,8 +3003,7 @@ static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
3138 3003
3139 worker->queue = queue; 3004 worker->queue = queue;
3140 worker->params = params; 3005 worker->params = params;
3141 rc = mwl8k_queue_work(hw, &worker->header, 3006 rc = mwl8k_queue_work(hw, &worker->header, mwl8k_conf_tx_wt);
3142 priv->config_wq, mwl8k_conf_tx_wt);
3143 kfree(worker); 3007 kfree(worker);
3144 if (rc == -ETIMEDOUT) { 3008 if (rc == -ETIMEDOUT) {
3145 printk(KERN_ERR "%s() timed out\n", __func__); 3009 printk(KERN_ERR "%s() timed out\n", __func__);
@@ -3183,15 +3047,13 @@ static int mwl8k_get_stats(struct ieee80211_hw *hw,
3183{ 3047{
3184 int rc; 3048 int rc;
3185 struct mwl8k_get_stats_worker *worker; 3049 struct mwl8k_get_stats_worker *worker;
3186 struct mwl8k_priv *priv = hw->priv;
3187 3050
3188 worker = kzalloc(sizeof(*worker), GFP_KERNEL); 3051 worker = kzalloc(sizeof(*worker), GFP_KERNEL);
3189 if (worker == NULL) 3052 if (worker == NULL)
3190 return -ENOMEM; 3053 return -ENOMEM;
3191 3054
3192 worker->stats = stats; 3055 worker->stats = stats;
3193 rc = mwl8k_queue_work(hw, &worker->header, 3056 rc = mwl8k_queue_work(hw, &worker->header, mwl8k_get_stats_wt);
3194 priv->config_wq, mwl8k_get_stats_wt);
3195 3057
3196 kfree(worker); 3058 kfree(worker);
3197 if (rc == -ETIMEDOUT) { 3059 if (rc == -ETIMEDOUT) {