aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/b43/b43.h7
-rw-r--r--drivers/net/wireless/b43/main.c65
2 files changed, 24 insertions, 48 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index f9c8161671d9..07d2825458ab 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -585,8 +585,6 @@ enum {
585struct b43_qos_params { 585struct b43_qos_params {
586 /* The QOS parameters */ 586 /* The QOS parameters */
587 struct ieee80211_tx_queue_params p; 587 struct ieee80211_tx_queue_params p;
588 /* Does this need to get uploaded to hardware? */
589 bool need_hw_update;
590}; 588};
591 589
592struct b43_wldev; 590struct b43_wldev;
@@ -648,11 +646,8 @@ struct b43_wl {
648 bool beacon_templates_virgin; /* Never wrote the templates? */ 646 bool beacon_templates_virgin; /* Never wrote the templates? */
649 struct work_struct beacon_update_trigger; 647 struct work_struct beacon_update_trigger;
650 648
651 /* The current QOS parameters for the 4 queues. 649 /* The current QOS parameters for the 4 queues. */
652 * This is protected by the irq_lock. */
653 struct b43_qos_params qos_params[4]; 650 struct b43_qos_params qos_params[4];
654 /* Workqueue for updating QOS parameters in hardware. */
655 struct work_struct qos_update_work;
656 651
657 /* Work for adjustment of the transmission power. 652 /* Work for adjustment of the transmission power.
658 * This is scheduled when we determine that the actual TX output 653 * This is scheduled when we determine that the actual TX output
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 79c25d6385ce..d4a356b11636 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3068,30 +3068,22 @@ static const u16 b43_qos_shm_offsets[] = {
3068 [3] = B43_QOS_BACKGROUND, 3068 [3] = B43_QOS_BACKGROUND,
3069}; 3069};
3070 3070
3071/* Update the QOS parameters in hardware. */ 3071/* Update all QOS parameters in hardware. */
3072static void b43_qos_update(struct b43_wldev *dev) 3072static void b43_qos_upload_all(struct b43_wldev *dev)
3073{ 3073{
3074 struct b43_wl *wl = dev->wl; 3074 struct b43_wl *wl = dev->wl;
3075 struct b43_qos_params *params; 3075 struct b43_qos_params *params;
3076 unsigned long flags;
3077 unsigned int i; 3076 unsigned int i;
3078 3077
3079 BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) != 3078 BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
3080 ARRAY_SIZE(wl->qos_params)); 3079 ARRAY_SIZE(wl->qos_params));
3081 3080
3082 b43_mac_suspend(dev); 3081 b43_mac_suspend(dev);
3083 spin_lock_irqsave(&wl->irq_lock, flags);
3084
3085 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) { 3082 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
3086 params = &(wl->qos_params[i]); 3083 params = &(wl->qos_params[i]);
3087 if (params->need_hw_update) { 3084 b43_qos_params_upload(dev, &(params->p),
3088 b43_qos_params_upload(dev, &(params->p), 3085 b43_qos_shm_offsets[i]);
3089 b43_qos_shm_offsets[i]);
3090 params->need_hw_update = 0;
3091 }
3092 } 3086 }
3093
3094 spin_unlock_irqrestore(&wl->irq_lock, flags);
3095 b43_mac_enable(dev); 3087 b43_mac_enable(dev);
3096} 3088}
3097 3089
@@ -3136,20 +3128,14 @@ static void b43_qos_clear(struct b43_wl *wl)
3136 default: 3128 default:
3137 B43_WARN_ON(1); 3129 B43_WARN_ON(1);
3138 } 3130 }
3139 params->need_hw_update = 1;
3140 } 3131 }
3141} 3132}
3142 3133
3143/* Initialize the core's QOS capabilities */ 3134/* Initialize the core's QOS capabilities */
3144static void b43_qos_init(struct b43_wldev *dev) 3135static void b43_qos_init(struct b43_wldev *dev)
3145{ 3136{
3146 struct b43_wl *wl = dev->wl;
3147 unsigned int i;
3148
3149 /* Upload the current QOS parameters. */ 3137 /* Upload the current QOS parameters. */
3150 for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) 3138 b43_qos_upload_all(dev);
3151 wl->qos_params[i].need_hw_update = 1;
3152 b43_qos_update(dev);
3153 3139
3154 /* Enable QOS support. */ 3140 /* Enable QOS support. */
3155 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF); 3141 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
@@ -3158,25 +3144,13 @@ static void b43_qos_init(struct b43_wldev *dev)
3158 | B43_MMIO_IFSCTL_USE_EDCF); 3144 | B43_MMIO_IFSCTL_USE_EDCF);
3159} 3145}
3160 3146
3161static void b43_qos_update_work(struct work_struct *work)
3162{
3163 struct b43_wl *wl = container_of(work, struct b43_wl, qos_update_work);
3164 struct b43_wldev *dev;
3165
3166 mutex_lock(&wl->mutex);
3167 dev = wl->current_dev;
3168 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED)))
3169 b43_qos_update(dev);
3170 mutex_unlock(&wl->mutex);
3171}
3172
3173static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue, 3147static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
3174 const struct ieee80211_tx_queue_params *params) 3148 const struct ieee80211_tx_queue_params *params)
3175{ 3149{
3176 struct b43_wl *wl = hw_to_b43_wl(hw); 3150 struct b43_wl *wl = hw_to_b43_wl(hw);
3177 unsigned long flags; 3151 struct b43_wldev *dev;
3178 unsigned int queue = (unsigned int)_queue; 3152 unsigned int queue = (unsigned int)_queue;
3179 struct b43_qos_params *p; 3153 int err = -ENODEV;
3180 3154
3181 if (queue >= ARRAY_SIZE(wl->qos_params)) { 3155 if (queue >= ARRAY_SIZE(wl->qos_params)) {
3182 /* Queue not available or don't support setting 3156 /* Queue not available or don't support setting
@@ -3184,16 +3158,25 @@ static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
3184 * confuse mac80211. */ 3158 * confuse mac80211. */
3185 return 0; 3159 return 0;
3186 } 3160 }
3161 BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
3162 ARRAY_SIZE(wl->qos_params));
3187 3163
3188 spin_lock_irqsave(&wl->irq_lock, flags); 3164 mutex_lock(&wl->mutex);
3189 p = &(wl->qos_params[queue]); 3165 dev = wl->current_dev;
3190 memcpy(&(p->p), params, sizeof(p->p)); 3166 if (unlikely(!dev || (b43_status(dev) < B43_STAT_INITIALIZED)))
3191 p->need_hw_update = 1; 3167 goto out_unlock;
3192 spin_unlock_irqrestore(&wl->irq_lock, flags);
3193 3168
3194 queue_work(hw->workqueue, &wl->qos_update_work); 3169 memcpy(&(wl->qos_params[queue].p), params, sizeof(*params));
3170 b43_mac_suspend(dev);
3171 b43_qos_params_upload(dev, &(wl->qos_params[queue].p),
3172 b43_qos_shm_offsets[queue]);
3173 b43_mac_enable(dev);
3174 err = 0;
3195 3175
3196 return 0; 3176out_unlock:
3177 mutex_unlock(&wl->mutex);
3178
3179 return err;
3197} 3180}
3198 3181
3199static int b43_op_get_tx_stats(struct ieee80211_hw *hw, 3182static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
@@ -4220,7 +4203,6 @@ static void b43_op_stop(struct ieee80211_hw *hw)
4220 struct b43_wldev *dev = wl->current_dev; 4203 struct b43_wldev *dev = wl->current_dev;
4221 4204
4222 b43_rfkill_exit(dev); 4205 b43_rfkill_exit(dev);
4223 cancel_work_sync(&(wl->qos_update_work));
4224 cancel_work_sync(&(wl->beacon_update_trigger)); 4206 cancel_work_sync(&(wl->beacon_update_trigger));
4225 4207
4226 mutex_lock(&wl->mutex); 4208 mutex_lock(&wl->mutex);
@@ -4619,7 +4601,6 @@ static int b43_wireless_init(struct ssb_device *dev)
4619 spin_lock_init(&wl->shm_lock); 4601 spin_lock_init(&wl->shm_lock);
4620 mutex_init(&wl->mutex); 4602 mutex_init(&wl->mutex);
4621 INIT_LIST_HEAD(&wl->devlist); 4603 INIT_LIST_HEAD(&wl->devlist);
4622 INIT_WORK(&wl->qos_update_work, b43_qos_update_work);
4623 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work); 4604 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
4624 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); 4605 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
4625 4606