aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/wfx/sta.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/wfx/sta.c')
-rw-r--r--drivers/staging/wfx/sta.c118
1 files changed, 72 insertions, 46 deletions
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index cb7e8abdf43c..23c0425e3929 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -24,7 +24,7 @@ u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates)
{
int i;
u32 ret = 0;
- // WFx only support 2GHz
+ /* The device only supports 2GHz */
struct ieee80211_supported_band *sband = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ];
for (i = 0; i < sband->n_bitrates; i++) {
@@ -51,11 +51,11 @@ void wfx_cooling_timeout_work(struct work_struct *work)
void wfx_suspend_hot_dev(struct wfx_dev *wdev, enum sta_notify_cmd cmd)
{
if (cmd == STA_NOTIFY_AWAKE) {
- // Device recover normal temperature
+ /* Device recover normal temperature */
if (cancel_delayed_work(&wdev->cooling_timeout_work))
wfx_tx_unlock(wdev);
} else {
- // Device is too hot
+ /* Device is too hot */
schedule_delayed_work(&wdev->cooling_timeout_work, 10 * HZ);
wfx_tx_lock(wdev);
}
@@ -80,13 +80,18 @@ static void wfx_filter_beacon(struct wfx_vif *wvif, bool filter_beacon)
.has_changed = 1,
.no_longer = 1,
.has_appeared = 1,
+ }, {
+ .ie_id = WLAN_EID_CHANNEL_SWITCH,
+ .has_changed = 1,
+ .no_longer = 1,
+ .has_appeared = 1,
}
};
if (!filter_beacon) {
hif_beacon_filter_control(wvif, 0, 1);
} else {
- hif_set_beacon_filter_table(wvif, 3, filter_ies);
+ hif_set_beacon_filter_table(wvif, ARRAY_SIZE(filter_ies), filter_ies);
hif_beacon_filter_control(wvif, HIF_BEACON_FILTER_ENABLE, 0);
}
}
@@ -98,13 +103,14 @@ void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
struct wfx_dev *wdev = hw->priv;
bool filter_bssid, filter_prbreq, filter_beacon;
- // Notes:
- // - Probe responses (FIF_BCN_PRBRESP_PROMISC) are never filtered
- // - PS-Poll (FIF_PSPOLL) are never filtered
- // - RTS, CTS and Ack (FIF_CONTROL) are always filtered
- // - Broken frames (FIF_FCSFAIL and FIF_PLCPFAIL) are always filtered
- // - Firmware does (yet) allow to forward unicast traffic sent to
- // other stations (aka. promiscuous mode)
+ /* Notes:
+ * - Probe responses (FIF_BCN_PRBRESP_PROMISC) are never filtered
+ * - PS-Poll (FIF_PSPOLL) are never filtered
+ * - RTS, CTS and Ack (FIF_CONTROL) are always filtered
+ * - Broken frames (FIF_FCSFAIL and FIF_PLCPFAIL) are always filtered
+ * - Firmware does (yet) allow to forward unicast traffic sent to
+ * other stations (aka. promiscuous mode)
+ */
*total_flags &= FIF_BCN_PRBRESP_PROMISC | FIF_ALLMULTI | FIF_OTHER_BSS |
FIF_PROBE_REQ | FIF_PSPOLL;
@@ -112,8 +118,9 @@ void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
mutex_lock(&wvif->scan_lock);
- // Note: FIF_BCN_PRBRESP_PROMISC covers probe response and
- // beacons from other BSS
+ /* Note: FIF_BCN_PRBRESP_PROMISC covers probe response and
+ * beacons from other BSS
+ */
if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
filter_beacon = false;
else
@@ -125,7 +132,7 @@ void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
else
filter_bssid = true;
- // In AP mode, chip can reply to probe request itself
+ /* In AP mode, chip can reply to probe request itself */
if (*total_flags & FIF_PROBE_REQ &&
wvif->vif->type == NL80211_IFTYPE_AP) {
dev_dbg(wdev->dev, "do not forward probe request in AP mode\n");
@@ -154,10 +161,18 @@ static int wfx_get_ps_timeout(struct wfx_vif *wvif, bool *enable_ps)
chan0 = wdev_to_wvif(wvif->wdev, 0)->vif->bss_conf.chandef.chan;
if (wdev_to_wvif(wvif->wdev, 1))
chan1 = wdev_to_wvif(wvif->wdev, 1)->vif->bss_conf.chandef.chan;
- if (chan0 && chan1 && chan0->hw_value != chan1->hw_value &&
- wvif->vif->type != NL80211_IFTYPE_AP) {
- // It is necessary to enable powersave if channels
- // are different.
+ if (chan0 && chan1 && wvif->vif->type != NL80211_IFTYPE_AP) {
+ if (chan0->hw_value == chan1->hw_value) {
+ /* It is useless to enable PS if channels are the same. */
+ if (enable_ps)
+ *enable_ps = false;
+ if (wvif->vif->bss_conf.assoc && wvif->vif->bss_conf.ps)
+ dev_info(wvif->wdev->dev, "ignoring requested PS mode");
+ return -1;
+ }
+ /* It is necessary to enable PS if channels
+ * are different.
+ */
if (enable_ps)
*enable_ps = true;
if (wvif->wdev->force_ps_timeout > -1)
@@ -229,8 +244,6 @@ int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
return 0;
}
-/* WSM callbacks */
-
void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi)
{
/* RSSI: signed Q8.0, RCPI: unsigned Q7.1
@@ -294,7 +307,7 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (vif->type == NL80211_IFTYPE_STATION)
hif_set_mfp(wvif, sta->mfp, sta->mfp);
- // In station mode, the firmware interprets new link-id as a TDLS peer.
+ /* In station mode, the firmware interprets new link-id as a TDLS peer */
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
return 0;
sta_priv->link_id = ffz(wvif->link_id_map);
@@ -312,10 +325,10 @@ int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv;
struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
- // See note in wfx_sta_add()
+ /* See note in wfx_sta_add() */
if (!sta_priv->link_id)
return 0;
- // FIXME add a mutex?
+ /* FIXME add a mutex? */
hif_map_link(wvif, true, sta->addr, sta_priv->link_id, false);
wvif->link_id_map &= ~BIT(sta_priv->link_id);
return 0;
@@ -410,7 +423,7 @@ static void wfx_join(struct wfx_vif *wvif)
return;
}
- rcu_read_lock(); // protect ssidie
+ rcu_read_lock(); /* protect ssidie */
if (bss)
ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
if (ssidie) {
@@ -446,7 +459,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
int ampdu_density = 0;
bool greenfield = false;
- rcu_read_lock(); // protect sta
+ rcu_read_lock(); /* protect sta */
if (info->bssid && !info->ibss_joined)
sta = ieee80211_find_sta(wvif->vif, info->bssid);
if (sta && sta->ht_cap.ht_supported)
@@ -460,8 +473,9 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
hif_set_association_mode(wvif, ampdu_density, greenfield,
info->use_short_preamble);
hif_keep_alive_period(wvif, 0);
- // beacon_loss_count is defined to 7 in net/mac80211/mlme.c. Let's use
- // the same value.
+ /* beacon_loss_count is defined to 7 in net/mac80211/mlme.c. Let's use
+ * the same value.
+ */
hif_set_bss_params(wvif, info->aid, 7);
hif_set_beacon_wakeup_period(wvif, 1, 1);
wfx_update_pm(wvif);
@@ -485,10 +499,11 @@ void wfx_leave_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
static void wfx_enable_beacon(struct wfx_vif *wvif, bool enable)
{
- // Driver has Content After DTIM Beacon in queue. Driver is waiting for
- // a signal from the firmware. Since we are going to stop to send
- // beacons, this signal will never happens. See also
- // wfx_suspend_resume_mc()
+ /* Driver has Content After DTIM Beacon in queue. Driver is waiting for
+ * a signal from the firmware. Since we are going to stop to send
+ * beacons, this signal will never happens. See also
+ * wfx_suspend_resume_mc()
+ */
if (!enable && wfx_tx_queues_has_cab(wvif)) {
wvif->after_dtim_tx_allowed = true;
wfx_bh_request_tx(wvif->wdev);
@@ -528,8 +543,9 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
__func__);
hif_set_beacon_wakeup_period(wvif, info->dtim_period,
info->dtim_period);
- // We temporary forwarded beacon for join process. It is now no
- // more necessary.
+ /* We temporary forwarded beacon for join process. It is now no
+ * more necessary.
+ */
wfx_filter_beacon(wvif, true);
}
@@ -588,9 +604,7 @@ static int wfx_update_tim(struct wfx_vif *wvif)
tim_ptr = skb->data + tim_offset;
if (tim_offset && tim_length >= 6) {
- /* Ignore DTIM count from mac80211:
- * firmware handles DTIM internally.
- */
+ /* Firmware handles DTIM counter internally */
tim_ptr[2] = 0;
/* Set/reset aid0 bit */
@@ -629,10 +643,22 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd)
{
+ struct wfx_vif *wvif_it;
+
if (notify_cmd != STA_NOTIFY_AWAKE)
return;
- WARN(!wfx_tx_queues_has_cab(wvif), "incorrect sequence");
- WARN(wvif->after_dtim_tx_allowed, "incorrect sequence");
+
+ /* Device won't be able to honor CAB if a scan is in progress on any
+ * interface. Prefer to skip this DTIM and wait for the next one.
+ */
+ wvif_it = NULL;
+ while ((wvif_it = wvif_iterate(wvif->wdev, wvif_it)) != NULL)
+ if (mutex_is_locked(&wvif_it->scan_lock))
+ return;
+
+ if (!wfx_tx_queues_has_cab(wvif) || wvif->after_dtim_tx_allowed)
+ dev_warn(wvif->wdev->dev, "incorrect sequence (%d CAB in queue)",
+ wfx_tx_queues_has_cab(wvif));
wvif->after_dtim_tx_allowed = true;
wfx_bh_request_tx(wvif->wdev);
}
@@ -641,15 +667,15 @@ int wfx_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_ampdu_params *params)
{
- // Aggregation is implemented fully in firmware
+ /* Aggregation is implemented fully in firmware */
switch (params->action) {
case IEEE80211_AMPDU_RX_START:
case IEEE80211_AMPDU_RX_STOP:
- // Just acknowledge it to enable frame re-ordering
+ /* Just acknowledge it to enable frame re-ordering */
return 0;
default:
- // Leave the firmware doing its business for tx aggregation
- return -ENOTSUPP;
+ /* Leave the firmware doing its business for tx aggregation */
+ return -EOPNOTSUPP;
}
}
@@ -720,11 +746,11 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
return -EOPNOTSUPP;
}
- // FIXME: prefer use of container_of() to get vif
+ /* FIXME: prefer use of container_of() to get vif */
wvif->vif = vif;
wvif->wdev = wdev;
- wvif->link_id_map = 1; // link-id 0 is reserved for multicast
+ wvif->link_id_map = 1; /* link-id 0 is reserved for multicast */
INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work);
INIT_DELAYED_WORK(&wvif->beacon_loss_work, wfx_beacon_loss_work);
@@ -754,7 +780,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
wvif = NULL;
while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
- // Combo mode does not support Block Acks. We can re-enable them
+ /* Combo mode does not support Block Acks. We can re-enable them */
if (wvif_count(wdev) == 1)
hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
else
@@ -786,7 +812,7 @@ void wfx_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
wvif = NULL;
while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
- // Combo mode does not support Block Acks. We can re-enable them
+ /* Combo mode does not support Block Acks. We can re-enable them */
if (wvif_count(wdev) == 1)
hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
else