aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ti
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2014-12-29 01:24:03 -0500
committerKalle Valo <kvalo@codeaurora.org>2015-01-09 08:47:52 -0500
commit7d3b29e5c86e0da38052d33fdd1f195d4591c6b2 (patch)
tree7449e1c4ced2087e4fab31d9fd3d88374cf21f73 /drivers/net/wireless/ti
parent16129d1d59be0f330f80b33fef8a7a7d7b18394d (diff)
wlcore/wl18xx: handle rc updates in a separate work
sta_rc_update runs in atomic context. thus, a new work should be scheduled in order to configure the fw with the required configuration. Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ti')
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c18
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h5
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c35
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h4
5 files changed, 44 insertions, 21 deletions
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 8e562610bf16..96dbe71662c1 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -1559,26 +1559,19 @@ static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1559} 1559}
1560 1560
1561static void wl18xx_sta_rc_update(struct wl1271 *wl, 1561static void wl18xx_sta_rc_update(struct wl1271 *wl,
1562 struct wl12xx_vif *wlvif, 1562 struct wl12xx_vif *wlvif)
1563 struct ieee80211_sta *sta,
1564 u32 changed)
1565{ 1563{
1566 bool wide = sta->bandwidth >= IEEE80211_STA_RX_BW_40; 1564 bool wide = wlvif->rc_update_bw >= IEEE80211_STA_RX_BW_40;
1567 1565
1568 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide); 1566 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
1569 1567
1570 if (!(changed & IEEE80211_RC_BW_CHANGED))
1571 return;
1572
1573 mutex_lock(&wl->mutex);
1574
1575 /* sanity */ 1568 /* sanity */
1576 if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS)) 1569 if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
1577 goto out; 1570 return;
1578 1571
1579 /* ignore the change before association */ 1572 /* ignore the change before association */
1580 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 1573 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1581 goto out; 1574 return;
1582 1575
1583 /* 1576 /*
1584 * If we started out as wide, we can change the operation mode. If we 1577 * If we started out as wide, we can change the operation mode. If we
@@ -1589,9 +1582,6 @@ static void wl18xx_sta_rc_update(struct wl1271 *wl,
1589 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide); 1582 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
1590 else 1583 else
1591 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif)); 1584 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
1592
1593out:
1594 mutex_unlock(&wl->mutex);
1595} 1585}
1596 1586
1597static int wl18xx_set_peer_cap(struct wl1271 *wl, 1587static int wl18xx_set_peer_cap(struct wl1271 *wl,
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
index aa9f82c72296..29ce55ff8823 100644
--- a/drivers/net/wireless/ti/wlcore/hw_ops.h
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -211,11 +211,10 @@ wlcore_hw_pre_pkt_send(struct wl1271 *wl, u32 buf_offset, u32 last_len)
211} 211}
212 212
213static inline void 213static inline void
214wlcore_hw_sta_rc_update(struct wl1271 *wl, struct wl12xx_vif *wlvif, 214wlcore_hw_sta_rc_update(struct wl1271 *wl, struct wl12xx_vif *wlvif)
215 struct ieee80211_sta *sta, u32 changed)
216{ 215{
217 if (wl->ops->sta_rc_update) 216 if (wl->ops->sta_rc_update)
218 wl->ops->sta_rc_update(wl, wlvif, sta, changed); 217 wl->ops->sta_rc_update(wl, wlvif);
219} 218}
220 219
221static inline int 220static inline int
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 6ad3fcedab9b..7b32b4536fff 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -226,6 +226,29 @@ void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl)
226 msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout)); 226 msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout));
227} 227}
228 228
229static void wlcore_rc_update_work(struct work_struct *work)
230{
231 int ret;
232 struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
233 rc_update_work);
234 struct wl1271 *wl = wlvif->wl;
235
236 mutex_lock(&wl->mutex);
237
238 if (unlikely(wl->state != WLCORE_STATE_ON))
239 goto out;
240
241 ret = wl1271_ps_elp_wakeup(wl);
242 if (ret < 0)
243 goto out;
244
245 wlcore_hw_sta_rc_update(wl, wlvif);
246
247 wl1271_ps_elp_sleep(wl);
248out:
249 mutex_unlock(&wl->mutex);
250}
251
229static void wl12xx_tx_watchdog_work(struct work_struct *work) 252static void wl12xx_tx_watchdog_work(struct work_struct *work)
230{ 253{
231 struct delayed_work *dwork; 254 struct delayed_work *dwork;
@@ -2279,6 +2302,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
2279 wl1271_rx_streaming_enable_work); 2302 wl1271_rx_streaming_enable_work);
2280 INIT_WORK(&wlvif->rx_streaming_disable_work, 2303 INIT_WORK(&wlvif->rx_streaming_disable_work,
2281 wl1271_rx_streaming_disable_work); 2304 wl1271_rx_streaming_disable_work);
2305 INIT_WORK(&wlvif->rc_update_work, wlcore_rc_update_work);
2282 INIT_DELAYED_WORK(&wlvif->channel_switch_work, 2306 INIT_DELAYED_WORK(&wlvif->channel_switch_work,
2283 wlcore_channel_switch_work); 2307 wlcore_channel_switch_work);
2284 INIT_DELAYED_WORK(&wlvif->connection_loss_work, 2308 INIT_DELAYED_WORK(&wlvif->connection_loss_work,
@@ -2723,6 +2747,7 @@ unlock:
2723 del_timer_sync(&wlvif->rx_streaming_timer); 2747 del_timer_sync(&wlvif->rx_streaming_timer);
2724 cancel_work_sync(&wlvif->rx_streaming_enable_work); 2748 cancel_work_sync(&wlvif->rx_streaming_enable_work);
2725 cancel_work_sync(&wlvif->rx_streaming_disable_work); 2749 cancel_work_sync(&wlvif->rx_streaming_disable_work);
2750 cancel_work_sync(&wlvif->rc_update_work);
2726 cancel_delayed_work_sync(&wlvif->connection_loss_work); 2751 cancel_delayed_work_sync(&wlvif->connection_loss_work);
2727 cancel_delayed_work_sync(&wlvif->channel_switch_work); 2752 cancel_delayed_work_sync(&wlvif->channel_switch_work);
2728 cancel_delayed_work_sync(&wlvif->pending_auth_complete_work); 2753 cancel_delayed_work_sync(&wlvif->pending_auth_complete_work);
@@ -5370,9 +5395,15 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
5370 u32 changed) 5395 u32 changed)
5371{ 5396{
5372 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 5397 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5373 struct wl1271 *wl = hw->priv;
5374 5398
5375 wlcore_hw_sta_rc_update(wl, wlvif, sta, changed); 5399 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update");
5400
5401 if (!(changed & IEEE80211_RC_BW_CHANGED))
5402 return;
5403
5404 /* this callback is atomic, so schedule a new work */
5405 wlvif->rc_update_bw = sta->bandwidth;
5406 ieee80211_queue_work(hw, &wlvif->rc_update_work);
5376} 5407}
5377 5408
5378static int wlcore_op_get_rssi(struct ieee80211_hw *hw, 5409static int wlcore_op_get_rssi(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index df78cf12ef15..2440ebe8a8d6 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -106,8 +106,7 @@ struct wlcore_ops {
106 struct wl12xx_vif *wlvif, 106 struct wl12xx_vif *wlvif,
107 struct ieee80211_channel_switch *ch_switch); 107 struct ieee80211_channel_switch *ch_switch);
108 u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len); 108 u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len);
109 void (*sta_rc_update)(struct wl1271 *wl, struct wl12xx_vif *wlvif, 109 void (*sta_rc_update)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
110 struct ieee80211_sta *sta, u32 changed);
111 int (*set_peer_cap)(struct wl1271 *wl, 110 int (*set_peer_cap)(struct wl1271 *wl,
112 struct ieee80211_sta_ht_cap *ht_cap, 111 struct ieee80211_sta_ht_cap *ht_cap,
113 bool allow_ht_operation, 112 bool allow_ht_operation,
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 0e52556044d9..811851d00b33 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -463,6 +463,10 @@ struct wl12xx_vif {
463 /* work for canceling ROC after pending auth reply */ 463 /* work for canceling ROC after pending auth reply */
464 struct delayed_work pending_auth_complete_work; 464 struct delayed_work pending_auth_complete_work;
465 465
466 /* update rate conrol */
467 enum ieee80211_sta_rx_bandwidth rc_update_bw;
468 struct work_struct rc_update_work;
469
466 /* 470 /*
467 * total freed FW packets on the link. 471 * total freed FW packets on the link.
468 * For STA this holds the PN of the link to the AP. 472 * For STA this holds the PN of the link to the AP.