linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/65] Simplify and improve the wfx driver
@ 2020-01-15 12:12 Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 01/65] staging: wfx: revert unexpected change in debugfs output Jérôme Pouiller
                   ` (65 more replies)
  0 siblings, 66 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Hello all,

This pull request is finally bigger than I expected, sorry.

It contains 2 main topics:
  - Simplify handling of stations in power save mode. Most of the work
    was redundant with mac80211. I have saved plenty of lines of code
    by using the mac80211 API better.
  - Continue to clearly separate hardware interface from the rest of
    the driver. The biggest part of this clean-up is done. It is now
    possible to look at the warning raised by sparse and fix
    support for big endian hosts.

Jérôme Pouiller (65):
  staging: wfx: revert unexpected change in debugfs output
  staging: wfx: make hif_scan() usage clearer
  staging: wfx: add missing PROBE_RESP_OFFLOAD feature
  staging: wfx: send rate policies one by one
  staging: wfx: simplify hif_set_tx_rate_retry_policy() usage
  staging: wfx: simplify hif_set_output_power() usage
  staging: wfx: simplify hif_set_rcpi_rssi_threshold() usage
  staging: wfx: simplify hif_set_arp_ipv4_filter() usage
  staging: wfx: simplify hif_start() usage
  staging: wfx: use specialized structs for HIF arguments
  staging: wfx: retrieve ampdu_density from sta->ht_cap
  staging: wfx: retrieve greenfield mode from sta->ht_cap and bss_conf
  staging: wfx: drop struct wfx_ht_info
  staging: wfx: drop wdev->output_power
  staging: wfx: simplify wfx_config()
  staging: wfx: rename wfx_upload_beacon()
  staging: wfx: simplify wfx_upload_ap_templates()
  staging: wfx: simplify wfx_update_beaconing()
  staging: wfx: fix __wfx_flush() when drop == false
  staging: wfx: simplify wfx_flush()
  staging: wfx: simplify update of DTIM period
  staging: wfx: drop wvif->dtim_period
  staging: wfx: drop wvif->enable_beacon
  staging: wfx: drop wvif->cqm_rssi_thold
  staging: wfx: drop wvif->setbssparams_done
  staging: wfx: drop wfx_set_cts_work()
  staging: wfx: SSID should be provided to hif_start() even if hidden
  staging: wfx: simplify hif_update_ie()
  staging: wfx: simplify hif_join()
  staging: wfx: simplify hif_set_association_mode()
  staging: wfx: simplify hif_set_uc_mc_bc_condition()
  staging: wfx: simplify hif_mib_uc_mc_bc_data_frame_condition
  staging: wfx: simplify hif_mib_set_data_filtering
  staging: wfx: simplify hif_set_data_filtering()
  staging: wfx: simplify hif_set_mac_addr_condition()
  staging: wfx: simplify hif_set_config_data_filter()
  staging: wfx: simplify wfx_set_mcast_filter()
  staging: wfx: simplify wfx_update_filtering()
  staging: wfx: simplify wfx_scan_complete()
  staging: wfx: update power-save per interface
  staging: wfx: with multiple vifs, force PS only if channels differs
  staging: wfx: do not update uapsd if not necessary
  staging: wfx: fix case where RTS threshold is 0
  staging: wfx: fix possible overflow on jiffies comparaison
  staging: wfx: remove handling of "early_data"
  staging: wfx: relocate "buffered" information to sta_priv
  staging: wfx: fix bss_loss
  staging: wfx: fix RCU usage
  staging: wfx: simplify wfx_set_tim_impl()
  staging: wfx: simplify the link-id allocation
  staging: wfx: check that no tx is pending before release sta
  staging: wfx: replace wfx_tx_get_tid() with ieee80211_get_tid()
  staging: wfx: pspoll_mask make no sense
  staging: wfx: sta and dtim
  staging: wfx: firmware never return PS status for stations
  staging: wfx: simplify wfx_suspend_resume_mc()
  staging: wfx: simplify handling of IEEE80211_TX_CTL_SEND_AFTER_DTIM
  staging: wfx: simplify wfx_ps_notify_sta()
  staging: wfx: ensure that packet_id is unique
  staging: wfx: remove unused do_probe
  staging: wfx: remove check for interface state
  staging: wfx: simplify hif_handle_tx_data()
  staging: wfx: simplify wfx_tx_queue_get_num_queued()
  staging: wfx: simplify hif_multi_tx_confirm()
  staging: wfx: update TODO

 drivers/staging/wfx/TODO          |  12 +-
 drivers/staging/wfx/data_rx.c     |  77 +---
 drivers/staging/wfx/data_tx.c     | 315 +++----------
 drivers/staging/wfx/data_tx.h     |  25 -
 drivers/staging/wfx/debug.c       |   2 +-
 drivers/staging/wfx/hif_api_cmd.h |   3 +-
 drivers/staging/wfx/hif_api_mib.h |  22 +-
 drivers/staging/wfx/hif_rx.c      |  20 +-
 drivers/staging/wfx/hif_tx.c      |  49 +-
 drivers/staging/wfx/hif_tx.h      |  11 +-
 drivers/staging/wfx/hif_tx_mib.h  | 157 +++++--
 drivers/staging/wfx/main.c        |   7 +-
 drivers/staging/wfx/queue.c       | 206 +++------
 drivers/staging/wfx/queue.h       |  10 +-
 drivers/staging/wfx/scan.c        |  14 +-
 drivers/staging/wfx/scan.h        |   5 +-
 drivers/staging/wfx/sta.c         | 735 ++++++++----------------------
 drivers/staging/wfx/sta.h         |  13 +-
 drivers/staging/wfx/wfx.h         |  25 +-
 19 files changed, 526 insertions(+), 1182 deletions(-)

-- 
2.25.0


^ permalink raw reply	[flat|nested] 68+ messages in thread

* [PATCH 01/65] staging: wfx: revert unexpected change in debugfs output
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 02/65] staging: wfx: make hif_scan() usage clearer Jérôme Pouiller
                   ` (64 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller, Pascal Prime,
	Jules Irenge

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

It appears that commit 8c7128c4cf4e ("staging: align to fix warnings of
line over 80 characters") do slightly more than what is explained in
commit log.

Especially, it changes the output of the file rx_stats from debugfs.
From some point of view, this file can be considered as a part of the
API. Any change on it should be clearly announced.

Since the change introduced does not seems to have any justification,
revert it.

Reported-by: Pascal Prime <pascal.prime@silabs.com>
Cc: Jules Irenge <jbi.octave@gmail.com>
Fixes: 8c7128c4cf4e ("staging: align to fix warnings of line over 80 characters")
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/debug.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c
index d17a75242365..1164aba118a1 100644
--- a/drivers/staging/wfx/debug.c
+++ b/drivers/staging/wfx/debug.c
@@ -145,7 +145,7 @@ static int wfx_rx_stats_show(struct seq_file *seq, void *v)
 		   st->pwr_clk_freq,
 		   st->is_ext_pwr_clk ? "yes" : "no");
 	seq_printf(seq,
-		   "N. of frames: %d, PER (x10e4): %d, Throughput: %dKbps/s\n",
+		   "Num. of frames: %d, PER (x10e4): %d, Throughput: %dKbps/s\n",
 		   st->nb_rx_frame, st->per_total, st->throughput);
 	seq_puts(seq, "       Num. of      PER     RSSI      SNR      CFO\n");
 	seq_puts(seq, "        frames  (x10e4)    (dBm)     (dB)    (kHz)\n");
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 02/65] staging: wfx: make hif_scan() usage clearer
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 01/65] staging: wfx: revert unexpected change in debugfs output Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 03/65] staging: wfx: add missing PROBE_RESP_OFFLOAD feature Jérôme Pouiller
                   ` (63 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

hif_scan() return max number of jiffies to wait before the completion
indication. However, if this value is negative, an error has occurred.

Reword the code to reflect that behavior.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/scan.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c
index 24061d09c404..9b3674b3226a 100644
--- a/drivers/staging/wfx/scan.c
+++ b/drivers/staging/wfx/scan.c
@@ -56,10 +56,9 @@ static int send_scan_req(struct wfx_vif *wvif,
 	wfx_tx_lock_flush(wvif->wdev);
 	wvif->scan_abort = false;
 	reinit_completion(&wvif->scan_complete);
-	ret = hif_scan(wvif, req, start_idx, i - start_idx);
-	if (ret < 0)
-		return ret;
-	timeout = ret;
+	timeout = hif_scan(wvif, req, start_idx, i - start_idx);
+	if (timeout < 0)
+		return timeout;
 	ret = wait_for_completion_timeout(&wvif->scan_complete, timeout);
 	if (req->channels[start_idx]->max_power != wvif->wdev->output_power)
 		hif_set_output_power(wvif, wvif->wdev->output_power * 10);
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 03/65] staging: wfx: add missing PROBE_RESP_OFFLOAD feature
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 01/65] staging: wfx: revert unexpected change in debugfs output Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 02/65] staging: wfx: make hif_scan() usage clearer Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 04/65] staging: wfx: send rate policies one by one Jérôme Pouiller
                   ` (62 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Some userspace tools (hostapd) rely on probe_resp_offload fields for
certain features.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/main.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c
index 45c9939b7e62..1904890c03fe 100644
--- a/drivers/staging/wfx/main.c
+++ b/drivers/staging/wfx/main.c
@@ -298,6 +298,11 @@ struct wfx_dev *wfx_init_common(struct device *dev,
 	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 				     BIT(NL80211_IFTYPE_ADHOC) |
 				     BIT(NL80211_IFTYPE_AP);
+	hw->wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
+					NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
+					NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
+					NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
+	hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
 	hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
 	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 	hw->wiphy->max_ap_assoc_sta = WFX_MAX_STA_IN_AP_MODE;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 04/65] staging: wfx: send rate policies one by one
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (2 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 03/65] staging: wfx: add missing PROBE_RESP_OFFLOAD feature Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 05/65] staging: wfx: simplify hif_set_tx_rate_retry_policy() usage Jérôme Pouiller
                   ` (61 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Rate policies (aka. tx_rate_retry_policy in hardware API) are sent to
device asynchronously from tx requests. So, the device maintains a list
of active rate policies and the tx requests only reference an existent
rate policy.

The device API allows to send multiple rate policies at once. However,
this property is very rarely used. We prefer to send rate policies one
by one and simplify the architecture.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_tx.c | 53 +++++++++++++++++------------------
 1 file changed, 25 insertions(+), 28 deletions(-)

diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index b2a325c47b2d..fb51c5910ace 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -217,37 +217,34 @@ static void wfx_tx_policy_put(struct wfx_vif *wvif, int idx)
 
 static int wfx_tx_policy_upload(struct wfx_vif *wvif)
 {
-	int i;
-	struct tx_policy_cache *cache = &wvif->tx_policy_cache;
 	struct hif_mib_set_tx_rate_retry_policy *arg =
-		kzalloc(struct_size(arg,
-				    tx_rate_retry_policy,
-				    HIF_MIB_NUM_TX_RATE_RETRY_POLICIES),
-			GFP_KERNEL);
-	struct hif_mib_tx_rate_retry_policy *dst;
+		kzalloc(struct_size(arg, tx_rate_retry_policy, 1), GFP_KERNEL);
+	struct tx_policy *policies = wvif->tx_policy_cache.cache;
+	int i;
 
-	spin_lock_bh(&cache->lock);
-	/* Upload only modified entries. */
-	for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i) {
-		struct tx_policy *src = &cache->cache[i];
-
-		if (!src->uploaded && memzcmp(src->rates, sizeof(src->rates))) {
-			dst = arg->tx_rate_retry_policy +
-				arg->num_tx_rate_policies;
-
-			dst->policy_index = i;
-			dst->short_retry_count = 255;
-			dst->long_retry_count = 255;
-			dst->first_rate_sel = 1;
-			dst->terminate = 1;
-			dst->count_init = 1;
-			memcpy(&dst->rates, src->rates, sizeof(src->rates));
-			src->uploaded = true;
-			arg->num_tx_rate_policies++;
+	do {
+		spin_lock_bh(&wvif->tx_policy_cache.lock);
+		for (i = 0; i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES; ++i)
+			if (!policies[i].uploaded &&
+			    memzcmp(policies[i].rates, sizeof(policies[i].rates)))
+				break;
+		if (i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES) {
+			policies[i].uploaded = 1;
+			arg->num_tx_rate_policies = 1;
+			arg->tx_rate_retry_policy[0].policy_index = i;
+			arg->tx_rate_retry_policy[0].short_retry_count = 255;
+			arg->tx_rate_retry_policy[0].long_retry_count = 255;
+			arg->tx_rate_retry_policy[0].first_rate_sel = 1;
+			arg->tx_rate_retry_policy[0].terminate = 1;
+			arg->tx_rate_retry_policy[0].count_init = 1;
+			memcpy(&arg->tx_rate_retry_policy[0].rates,
+			       policies[i].rates, sizeof(policies[i].rates));
+			spin_unlock_bh(&wvif->tx_policy_cache.lock);
+			hif_set_tx_rate_retry_policy(wvif, arg);
+		} else {
+			spin_unlock_bh(&wvif->tx_policy_cache.lock);
 		}
-	}
-	spin_unlock_bh(&cache->lock);
-	hif_set_tx_rate_retry_policy(wvif, arg);
+	} while (i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES);
 	kfree(arg);
 	return 0;
 }
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 05/65] staging: wfx: simplify hif_set_tx_rate_retry_policy() usage
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (3 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 04/65] staging: wfx: send rate policies one by one Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 06/65] staging: wfx: simplify hif_set_output_power() usage Jérôme Pouiller
                   ` (60 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The structure hif_mib_set_tx_rate_retry_policy come from hardware
API. It is not intended to be manipulated in upper layers of the driver.

So, this patch relocate handling of this structure to
hif_set_tx_rate_retry_policy() (the low level function).

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_tx.c    | 16 +++-------------
 drivers/staging/wfx/hif_tx_mib.h | 23 ++++++++++++++++++-----
 drivers/staging/wfx/sta.c        |  2 +-
 drivers/staging/wfx/sta.h        |  1 +
 4 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index fb51c5910ace..60459299a3a9 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -217,9 +217,8 @@ static void wfx_tx_policy_put(struct wfx_vif *wvif, int idx)
 
 static int wfx_tx_policy_upload(struct wfx_vif *wvif)
 {
-	struct hif_mib_set_tx_rate_retry_policy *arg =
-		kzalloc(struct_size(arg, tx_rate_retry_policy, 1), GFP_KERNEL);
 	struct tx_policy *policies = wvif->tx_policy_cache.cache;
+	u8 tmp_rates[12];
 	int i;
 
 	do {
@@ -230,22 +229,13 @@ static int wfx_tx_policy_upload(struct wfx_vif *wvif)
 				break;
 		if (i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES) {
 			policies[i].uploaded = 1;
-			arg->num_tx_rate_policies = 1;
-			arg->tx_rate_retry_policy[0].policy_index = i;
-			arg->tx_rate_retry_policy[0].short_retry_count = 255;
-			arg->tx_rate_retry_policy[0].long_retry_count = 255;
-			arg->tx_rate_retry_policy[0].first_rate_sel = 1;
-			arg->tx_rate_retry_policy[0].terminate = 1;
-			arg->tx_rate_retry_policy[0].count_init = 1;
-			memcpy(&arg->tx_rate_retry_policy[0].rates,
-			       policies[i].rates, sizeof(policies[i].rates));
+			memcpy(tmp_rates, policies[i].rates, sizeof(tmp_rates));
 			spin_unlock_bh(&wvif->tx_policy_cache.lock);
-			hif_set_tx_rate_retry_policy(wvif, arg);
+			hif_set_tx_rate_retry_policy(wvif, i, tmp_rates);
 		} else {
 			spin_unlock_bh(&wvif->tx_policy_cache.lock);
 		}
 	} while (i < HIF_MIB_NUM_TX_RATE_RETRY_POLICIES);
-	kfree(arg);
 	return 0;
 }
 
diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index b1eeda2a3ab3..ef033a409381 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -181,13 +181,26 @@ static inline int hif_set_association_mode(struct wfx_vif *wvif,
 }
 
 static inline int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif,
-					       struct hif_mib_set_tx_rate_retry_policy *arg)
+					       int policy_index, uint8_t *rates)
 {
-	size_t size = struct_size(arg, tx_rate_retry_policy,
-				  arg->num_tx_rate_policies);
+	struct hif_mib_set_tx_rate_retry_policy *arg;
+	size_t size = struct_size(arg, tx_rate_retry_policy, 1);
+	int ret;
 
-	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY, arg, size);
+	arg = kzalloc(size, GFP_KERNEL);
+	arg->num_tx_rate_policies = 1;
+	arg->tx_rate_retry_policy[0].policy_index = policy_index;
+	arg->tx_rate_retry_policy[0].short_retry_count = 255;
+	arg->tx_rate_retry_policy[0].long_retry_count = 255;
+	arg->tx_rate_retry_policy[0].first_rate_sel = 1;
+	arg->tx_rate_retry_policy[0].terminate = 1;
+	arg->tx_rate_retry_policy[0].count_init = 1;
+	memcpy(&arg->tx_rate_retry_policy[0].rates, rates,
+	       sizeof(arg->tx_rate_retry_policy[0].rates));
+	ret = hif_write_mib(wvif->wdev, wvif->id,
+			    HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY, arg, size);
+	kfree(arg);
+	return ret;
 }
 
 static inline int hif_set_mac_addr_condition(struct wfx_vif *wvif,
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 9011b5d78706..8f53a78d7215 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -19,7 +19,7 @@
 
 #define HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES 2
 
-static u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates)
+u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates)
 {
 	int i;
 	u32 ret = 0;
diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h
index 9595e1fc60db..b5d8d6494157 100644
--- a/drivers/staging/wfx/sta.h
+++ b/drivers/staging/wfx/sta.h
@@ -92,5 +92,6 @@ void wfx_suspend_resume(struct wfx_vif *wvif,
 void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad);
 void wfx_update_filtering(struct wfx_vif *wvif);
 int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable);
+u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates);
 
 #endif /* WFX_STA_H */
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 06/65] staging: wfx: simplify hif_set_output_power() usage
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (4 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 05/65] staging: wfx: simplify hif_set_tx_rate_retry_policy() usage Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 07/65] staging: wfx: simplify hif_set_rcpi_rssi_threshold() usage Jérôme Pouiller
                   ` (59 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Hardware API use 10th of dBm for output power unit. Upper layers should
use same units than mac80211 and the conversion should be done by low
level layer of the driver (hif_set_output_power())

In add, current code of hif_set_output_power() use a __le32 while the
device API specify a specific structure for this.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx_mib.h | 8 +++++---
 drivers/staging/wfx/scan.c       | 2 +-
 drivers/staging/wfx/sta.c        | 6 +++---
 3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index ef033a409381..749df67131c3 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -15,13 +15,15 @@
 #include "hif_tx.h"
 #include "hif_api_mib.h"
 
-static inline int hif_set_output_power(struct wfx_vif *wvif, int power_level)
+static inline int hif_set_output_power(struct wfx_vif *wvif, int val)
 {
-	__le32 val = cpu_to_le32(power_level);
+	struct hif_mib_current_tx_power_level arg = {
+		.power_level = cpu_to_le32(val * 10),
+	};
 
 	return hif_write_mib(wvif->wdev, wvif->id,
 			     HIF_MIB_ID_CURRENT_TX_POWER_LEVEL,
-			     &val, sizeof(val));
+			     &arg, sizeof(arg));
 }
 
 static inline int hif_set_beacon_wakeup_period(struct wfx_vif *wvif,
diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c
index 9b3674b3226a..8e0ac89fd28f 100644
--- a/drivers/staging/wfx/scan.c
+++ b/drivers/staging/wfx/scan.c
@@ -61,7 +61,7 @@ static int send_scan_req(struct wfx_vif *wvif,
 		return timeout;
 	ret = wait_for_completion_timeout(&wvif->scan_complete, timeout);
 	if (req->channels[start_idx]->max_power != wvif->wdev->output_power)
-		hif_set_output_power(wvif, wvif->wdev->output_power * 10);
+		hif_set_output_power(wvif, wvif->wdev->output_power);
 	wfx_tx_unlock(wvif->wdev);
 	if (!ret) {
 		dev_notice(wvif->wdev->dev, "scan timeout\n");
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 8f53a78d7215..11e33a6d5bb5 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -503,7 +503,7 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
 	hif_keep_alive_period(wvif, 0);
 	hif_reset(wvif, false);
 	wfx_tx_policy_init(wvif);
-	hif_set_output_power(wvif, wvif->wdev->output_power * 10);
+	hif_set_output_power(wvif, wvif->wdev->output_power);
 	wvif->dtim_period = 0;
 	hif_set_macaddr(wvif, wvif->vif->addr);
 	wfx_free_event_queue(wvif);
@@ -1063,7 +1063,7 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 	if (changed & BSS_CHANGED_TXPOWER &&
 	    info->txpower != wdev->output_power) {
 		wdev->output_power = info->txpower;
-		hif_set_output_power(wvif, wdev->output_power * 10);
+		hif_set_output_power(wvif, wdev->output_power);
 	}
 	mutex_unlock(&wdev->conf_mutex);
 
@@ -1317,7 +1317,7 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed)
 	mutex_lock(&wdev->conf_mutex);
 	if (changed & IEEE80211_CONF_CHANGE_POWER) {
 		wdev->output_power = conf->power_level;
-		hif_set_output_power(wvif, wdev->output_power * 10);
+		hif_set_output_power(wvif, wdev->output_power);
 	}
 
 	if (changed & IEEE80211_CONF_CHANGE_PS) {
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 07/65] staging: wfx: simplify hif_set_rcpi_rssi_threshold() usage
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (5 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 06/65] staging: wfx: simplify hif_set_output_power() usage Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 08/65] staging: wfx: simplify hif_set_arp_ipv4_filter() usage Jérôme Pouiller
                   ` (58 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The structure hif_mib_rcpi_rssi_threshold come from hardware API. It is
not intended to be manipulated in upper layers of the driver.

In add, current code for hif_set_rcpi_rssi_threshold() is dumb. It
should pack data using the hardware representation instead of leaving
all work to the caller.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx_mib.h | 19 +++++++++++++++++--
 drivers/staging/wfx/sta.c        | 26 ++------------------------
 2 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index 749df67131c3..a8082508fbfd 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -44,10 +44,25 @@ static inline int hif_set_beacon_wakeup_period(struct wfx_vif *wvif,
 }
 
 static inline int hif_set_rcpi_rssi_threshold(struct wfx_vif *wvif,
-					      struct hif_mib_rcpi_rssi_threshold *arg)
+					      int rssi_thold, int rssi_hyst)
 {
+	struct hif_mib_rcpi_rssi_threshold arg = {
+		.rolling_average_count = 8,
+		.detection = 1,
+	};
+
+	if (!rssi_thold && !rssi_hyst) {
+		arg.upperthresh = 1;
+		arg.lowerthresh = 1;
+	} else {
+		arg.upper_threshold = rssi_thold + rssi_hyst;
+		arg.upper_threshold = (arg.upper_threshold + 110) * 2;
+		arg.lower_threshold = rssi_thold;
+		arg.lower_threshold = (arg.lower_threshold + 110) * 2;
+	}
+
 	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_RCPI_RSSI_THRESHOLD, arg, sizeof(*arg));
+			     HIF_MIB_ID_RCPI_RSSI_THRESHOLD, &arg, sizeof(arg));
 }
 
 static inline int hif_get_counters_table(struct wfx_dev *wdev,
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 11e33a6d5bb5..339acbce96fb 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -1033,31 +1033,9 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 		hif_slot_time(wvif, info->use_short_slot ? 9 : 20);
 
 	if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_CQM) {
-		struct hif_mib_rcpi_rssi_threshold th = {
-			.rolling_average_count = 8,
-			.detection = 1,
-		};
-
 		wvif->cqm_rssi_thold = info->cqm_rssi_thold;
-
-		if (!info->cqm_rssi_thold && !info->cqm_rssi_hyst) {
-			th.upperthresh = 1;
-			th.lowerthresh = 1;
-		} else {
-			/* FIXME It's not a correct way of setting threshold.
-			 * Upper and lower must be set equal here and adjusted
-			 * in callback. However current implementation is much
-			 * more reliable and stable.
-			 */
-			/* RSSI: signed Q8.0, RCPI: unsigned Q7.1
-			 * RSSI = RCPI / 2 - 110
-			 */
-			th.upper_threshold = info->cqm_rssi_thold + info->cqm_rssi_hyst;
-			th.upper_threshold = (th.upper_threshold + 110) * 2;
-			th.lower_threshold = info->cqm_rssi_thold;
-			th.lower_threshold = (th.lower_threshold + 110) * 2;
-		}
-		hif_set_rcpi_rssi_threshold(wvif, &th);
+		hif_set_rcpi_rssi_threshold(wvif, info->cqm_rssi_thold,
+					    info->cqm_rssi_hyst);
 	}
 
 	if (changed & BSS_CHANGED_TXPOWER &&
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 08/65] staging: wfx: simplify hif_set_arp_ipv4_filter() usage
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (6 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 07/65] staging: wfx: simplify hif_set_rcpi_rssi_threshold() usage Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 09/65] staging: wfx: simplify hif_start() usage Jérôme Pouiller
                   ` (57 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The structure hif_mib_arp_ip_addr_table come from hardware API. It is
not intended to be manipulated in upper layers of the driver.

In add, current code for hif_set_arp_ipv4_filter() is too dumb. It
should pack data using the hardware representation instead of leaving
all work to the caller.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx_mib.h | 16 +++++++++++++---
 drivers/staging/wfx/sta.c        | 25 +++++++------------------
 2 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index a8082508fbfd..a325c870b4ea 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -260,12 +260,22 @@ static inline int hif_keep_alive_period(struct wfx_vif *wvif, int period)
 			     &arg, sizeof(arg));
 };
 
-static inline int hif_set_arp_ipv4_filter(struct wfx_vif *wvif,
-					  struct hif_mib_arp_ip_addr_table *fp)
+static inline int hif_set_arp_ipv4_filter(struct wfx_vif *wvif, int idx,
+					  __be32 *addr)
 {
+	struct hif_mib_arp_ip_addr_table arg = {
+		.condition_idx = idx,
+		.arp_enable = HIF_ARP_NS_FILTERING_DISABLE,
+	};
+
+	if (addr) {
+		// Caution: type of addr is __be32
+		memcpy(arg.ipv4_address, addr, sizeof(arg.ipv4_address));
+		arg.arp_enable = HIF_ARP_NS_FILTERING_ENABLE;
+	}
 	return hif_write_mib(wvif->wdev, wvif->id,
 			     HIF_MIB_ID_ARP_IP_ADDRESSES_TABLE,
-			     fp, sizeof(*fp));
+			     &arg, sizeof(arg));
 }
 
 static inline int hif_use_multi_tx_conf(struct wfx_dev *wdev,
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 339acbce96fb..8c55089b1ea4 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -915,30 +915,19 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 	struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
 	bool do_join = false;
 	int i;
-	int nb_arp_addr;
 
 	mutex_lock(&wdev->conf_mutex);
 
 	/* TODO: BSS_CHANGED_QOS */
 	if (changed & BSS_CHANGED_ARP_FILTER) {
-		struct hif_mib_arp_ip_addr_table filter = { };
-
-		nb_arp_addr = info->arp_addr_cnt;
-		if (nb_arp_addr <= 0 || nb_arp_addr > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES)
-			nb_arp_addr = 0;
-
 		for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) {
-			filter.condition_idx = i;
-			if (i < nb_arp_addr) {
-				// Caution: type of arp_addr_list[i] is __be32
-				memcpy(filter.ipv4_address,
-				       &info->arp_addr_list[i],
-				       sizeof(filter.ipv4_address));
-				filter.arp_enable = HIF_ARP_NS_FILTERING_ENABLE;
-			} else {
-				filter.arp_enable = HIF_ARP_NS_FILTERING_DISABLE;
-			}
-			hif_set_arp_ipv4_filter(wvif, &filter);
+			__be32 *arp_addr = &info->arp_addr_list[i];
+
+			if (info->arp_addr_cnt > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES)
+				arp_addr = NULL;
+			if (i >= info->arp_addr_cnt)
+				arp_addr = NULL;
+			hif_set_arp_ipv4_filter(wvif, i, arp_addr);
 		}
 	}
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 09/65] staging: wfx: simplify hif_start() usage
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (7 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 08/65] staging: wfx: simplify hif_set_arp_ipv4_filter() usage Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 10/65] staging: wfx: use specialized structs for HIF arguments Jérôme Pouiller
                   ` (56 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The structure hif_req_start come from hardware API. It is not intended
to be manipulated in upper layers of the driver.

In add, current code for hif_start() is too dumb. It should pack data
with hardware representation instead of leaving all work to the caller.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx.c | 17 ++++++++++-----
 drivers/staging/wfx/hif_tx.h |  5 ++++-
 drivers/staging/wfx/sta.c    | 40 ++++++++++++------------------------
 3 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c
index d8e159670eae..be3138590a4f 100644
--- a/drivers/staging/wfx/hif_tx.c
+++ b/drivers/staging/wfx/hif_tx.c
@@ -409,16 +409,23 @@ int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout)
 	return ret;
 }
 
-int hif_start(struct wfx_vif *wvif, const struct hif_req_start *arg)
+int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
+	      const struct ieee80211_channel *channel)
 {
 	int ret;
 	struct hif_msg *hif;
 	struct hif_req_start *body = wfx_alloc_hif(sizeof(*body), &hif);
 
-	memcpy(body, arg, sizeof(*body));
-	cpu_to_le16s(&body->channel_number);
-	cpu_to_le32s(&body->beacon_interval);
-	cpu_to_le32s(&body->basic_rate_set);
+	body->dtim_period = conf->dtim_period,
+	body->short_preamble = conf->use_short_preamble,
+	body->channel_number = cpu_to_le16(channel->hw_value),
+	body->beacon_interval = cpu_to_le32(conf->beacon_int);
+	body->basic_rate_set =
+		cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates));
+	if (!conf->hidden_ssid) {
+		body->ssid_length = conf->ssid_len;
+		memcpy(body->ssid, conf->ssid, conf->ssid_len);
+	}
 	wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START, sizeof(*body));
 	ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
 	kfree(hif);
diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h
index e8855ead3a18..fbaed991b112 100644
--- a/drivers/staging/wfx/hif_tx.h
+++ b/drivers/staging/wfx/hif_tx.h
@@ -12,6 +12,8 @@
 
 #include "hif_api_cmd.h"
 
+struct ieee80211_channel;
+struct ieee80211_bss_conf;
 struct ieee80211_tx_queue_params;
 struct cfg80211_scan_request;
 struct wfx_dev;
@@ -51,7 +53,8 @@ int hif_add_key(struct wfx_dev *wdev, const struct hif_req_add_key *arg);
 int hif_remove_key(struct wfx_dev *wdev, int idx);
 int hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue,
 			      const struct ieee80211_tx_queue_params *arg);
-int hif_start(struct wfx_vif *wvif, const struct hif_req_start *arg);
+int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
+	      const struct ieee80211_channel *channel);
 int hif_beacon_transmit(struct wfx_vif *wvif, bool enable);
 int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id);
 int hif_update_ie(struct wfx_vif *wvif, const struct hif_ie_flags *target_frame,
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 8c55089b1ea4..660a75024f4b 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -740,38 +740,24 @@ static void wfx_set_cts_work(struct work_struct *work)
 static int wfx_start_ap(struct wfx_vif *wvif)
 {
 	int ret;
-	struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
-	struct hif_req_start start = {
-		.channel_number = wvif->channel->hw_value,
-		.beacon_interval = conf->beacon_int,
-		.dtim_period = conf->dtim_period,
-		.short_preamble = conf->use_short_preamble,
-		.basic_rate_set = wfx_rate_mask_to_hw(wvif->wdev,
-						      conf->basic_rates),
-	};
 
-	memset(start.ssid, 0, sizeof(start.ssid));
-	if (!conf->hidden_ssid) {
-		start.ssid_length = conf->ssid_len;
-		memcpy(start.ssid, conf->ssid, start.ssid_length);
-	}
-
-	wvif->beacon_int = conf->beacon_int;
-	wvif->dtim_period = conf->dtim_period;
+	wvif->beacon_int = wvif->vif->bss_conf.beacon_int;
+	wvif->dtim_period = wvif->vif->bss_conf.dtim_period;
 
 	memset(&wvif->link_id_db, 0, sizeof(wvif->link_id_db));
 
 	wvif->wdev->tx_burst_idx = -1;
-	ret = hif_start(wvif, &start);
-	if (!ret)
-		ret = wfx_upload_keys(wvif);
-	if (!ret) {
-		if (wvif_count(wvif->wdev) <= 1)
-			hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
-		wvif->state = WFX_STATE_AP;
-		wfx_update_filtering(wvif);
-	}
-	return ret;
+	ret = hif_start(wvif, &wvif->vif->bss_conf, wvif->channel);
+	if (ret)
+		return ret;
+	ret = wfx_upload_keys(wvif);
+	if (ret)
+		return ret;
+	if (wvif_count(wvif->wdev) <= 1)
+		hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
+	wvif->state = WFX_STATE_AP;
+	wfx_update_filtering(wvif);
+	return 0;
 }
 
 static int wfx_update_beaconing(struct wfx_vif *wvif)
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 10/65] staging: wfx: use specialized structs for HIF arguments
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (8 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 09/65] staging: wfx: simplify hif_start() usage Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 11/65] staging: wfx: retrieve ampdu_density from sta->ht_cap Jérôme Pouiller
                   ` (55 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Most of the commands that are sent to device should take struct in
argument. In the current code, when this struct is binary compatible
with a __le32, the driver use a __le32. This behavior is error prone.
This patch fixes that and uses the specialized structs instead.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx.c     |  4 ++--
 drivers/staging/wfx/hif_tx_mib.h | 27 ++++++++++++++++++---------
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c
index be3138590a4f..2d541601e224 100644
--- a/drivers/staging/wfx/hif_tx.c
+++ b/drivers/staging/wfx/hif_tx.c
@@ -432,14 +432,14 @@ int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
 	return ret;
 }
 
-int hif_beacon_transmit(struct wfx_vif *wvif, bool enable_beaconing)
+int hif_beacon_transmit(struct wfx_vif *wvif, bool enable)
 {
 	int ret;
 	struct hif_msg *hif;
 	struct hif_req_beacon_transmit *body = wfx_alloc_hif(sizeof(*body),
 							     &hif);
 
-	body->enable_beaconing = enable_beaconing ? 1 : 0;
+	body->enable_beaconing = enable ? 1 : 0;
 	wfx_fill_header(hif, wvif->id, HIF_REQ_ID_BEACON_TRANSMIT,
 			sizeof(*body));
 	ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index a325c870b4ea..5b39200bd697 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -278,10 +278,11 @@ static inline int hif_set_arp_ipv4_filter(struct wfx_vif *wvif, int idx,
 			     &arg, sizeof(arg));
 }
 
-static inline int hif_use_multi_tx_conf(struct wfx_dev *wdev,
-					bool enabled)
+static inline int hif_use_multi_tx_conf(struct wfx_dev *wdev, bool enable)
 {
-	__le32 arg = enabled ? cpu_to_le32(1) : 0;
+	struct hif_mib_gl_set_multi_msg arg = {
+		.enable_multi_tx_conf = enable,
+	};
 
 	return hif_write_mib(wdev, -1, HIF_MIB_ID_GL_SET_MULTI_MSG,
 			     &arg, sizeof(arg));
@@ -306,7 +307,9 @@ static inline int hif_set_uapsd_info(struct wfx_vif *wvif, unsigned long val)
 
 static inline int hif_erp_use_protection(struct wfx_vif *wvif, bool enable)
 {
-	__le32 arg = enable ? cpu_to_le32(1) : 0;
+	struct hif_mib_non_erp_protection arg = {
+		.use_cts_to_self = enable,
+	};
 
 	return hif_write_mib(wvif->wdev, wvif->id,
 			     HIF_MIB_ID_NON_ERP_PROTECTION, &arg, sizeof(arg));
@@ -314,16 +317,18 @@ static inline int hif_erp_use_protection(struct wfx_vif *wvif, bool enable)
 
 static inline int hif_slot_time(struct wfx_vif *wvif, int val)
 {
-	__le32 arg = cpu_to_le32(val);
+	struct hif_mib_slot_time arg = {
+		.slot_time = cpu_to_le32(val),
+	};
 
 	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SLOT_TIME,
 			     &arg, sizeof(arg));
 }
 
-static inline int hif_dual_cts_protection(struct wfx_vif *wvif, bool val)
+static inline int hif_dual_cts_protection(struct wfx_vif *wvif, bool enable)
 {
 	struct hif_mib_set_ht_protection arg = {
-		.dual_cts_prot = val,
+		.dual_cts_prot = enable,
 	};
 
 	return hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SET_HT_PROTECTION,
@@ -332,7 +337,9 @@ static inline int hif_dual_cts_protection(struct wfx_vif *wvif, bool val)
 
 static inline int hif_wep_default_key_id(struct wfx_vif *wvif, int val)
 {
-	__le32 arg = cpu_to_le32(val);
+	struct hif_mib_wep_default_key_id arg = {
+		.wep_default_key_id = val,
+	};
 
 	return hif_write_mib(wvif->wdev, wvif->id,
 			     HIF_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID,
@@ -341,7 +348,9 @@ static inline int hif_wep_default_key_id(struct wfx_vif *wvif, int val)
 
 static inline int hif_rts_threshold(struct wfx_vif *wvif, int val)
 {
-	__le32 arg = cpu_to_le32(val > 0 ? val : 0xFFFF);
+	struct hif_mib_dot11_rts_threshold arg = {
+		.threshold = cpu_to_le32(val > 0 ? val : 0xFFFF),
+	};
 
 	return hif_write_mib(wvif->wdev, wvif->id,
 			     HIF_MIB_ID_DOT11_RTS_THRESHOLD, &arg, sizeof(arg));
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 11/65] staging: wfx: retrieve ampdu_density from sta->ht_cap
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (9 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 10/65] staging: wfx: use specialized structs for HIF arguments Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 12/65] staging: wfx: retrieve greenfield mode from sta->ht_cap and bss_conf Jérôme Pouiller
                   ` (54 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wvif->ht_info.ht_cap is a useless copy of sta->ht_cap. It makes no sense
to rely on it.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 660a75024f4b..f13a5b41735c 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -825,13 +825,6 @@ static int wfx_ht_greenfield(const struct wfx_ht_info *ht_info)
 		  IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
 }
 
-static int wfx_ht_ampdu_density(const struct wfx_ht_info *ht_info)
-{
-	if (!wfx_is_ht(ht_info))
-		return 0;
-	return ht_info->ht_cap.ampdu_density;
-}
-
 static void wfx_join_finalize(struct wfx_vif *wvif,
 			      struct ieee80211_bss_conf *info)
 {
@@ -870,7 +863,8 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	association_mode.short_preamble = info->use_short_preamble;
 	association_mode.basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates));
 	association_mode.greenfield = wfx_ht_greenfield(&wvif->ht_info);
-	association_mode.mpdu_start_spacing = wfx_ht_ampdu_density(&wvif->ht_info);
+	if (sta && sta->ht_cap.ht_supported)
+		association_mode.mpdu_start_spacing = sta->ht_cap.ampdu_density;
 
 	wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
 	cancel_work_sync(&wvif->unjoin_work);
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 12/65] staging: wfx: retrieve greenfield mode from sta->ht_cap and bss_conf
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (10 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 11/65] staging: wfx: retrieve ampdu_density from sta->ht_cap Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 13/65] staging: wfx: drop struct wfx_ht_info Jérôme Pouiller
                   ` (53 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wvif->ht_info contains useless copies of sta->ht_cap and
bss_conf->ht_operation_mode. Prefer to retrieve information from the
original structs instead of rely on wvif->ht_info.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index f13a5b41735c..fcd9fe66e417 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -817,14 +817,6 @@ static int wfx_is_ht(const struct wfx_ht_info *ht_info)
 	return ht_info->channel_type != NL80211_CHAN_NO_HT;
 }
 
-static int wfx_ht_greenfield(const struct wfx_ht_info *ht_info)
-{
-	return wfx_is_ht(ht_info) &&
-		(ht_info->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
-		!(ht_info->operation_mode &
-		  IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
-}
-
 static void wfx_join_finalize(struct wfx_vif *wvif,
 			      struct ieee80211_bss_conf *info)
 {
@@ -849,9 +841,8 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	}
 	rcu_read_unlock();
 
-	/* Non Greenfield stations present */
-	if (wvif->ht_info.operation_mode &
-	    IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
+	if (sta &&
+	    info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
 		hif_dual_cts_protection(wvif, true);
 	else
 		hif_dual_cts_protection(wvif, false);
@@ -862,7 +853,10 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	association_mode.spacing = 1;
 	association_mode.short_preamble = info->use_short_preamble;
 	association_mode.basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates));
-	association_mode.greenfield = wfx_ht_greenfield(&wvif->ht_info);
+	if (sta && sta->ht_cap.ht_supported &&
+	    !(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
+		association_mode.greenfield =
+			!!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);
 	if (sta && sta->ht_cap.ht_supported)
 		association_mode.mpdu_start_spacing = sta->ht_cap.ampdu_density;
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 13/65] staging: wfx: drop struct wfx_ht_info
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (11 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 12/65] staging: wfx: retrieve greenfield mode from sta->ht_cap and bss_conf Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 14/65] staging: wfx: drop wdev->output_power Jérôme Pouiller
                   ` (52 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

This struct is no more used.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 18 +++---------------
 drivers/staging/wfx/sta.h |  6 ------
 drivers/staging/wfx/wfx.h |  1 -
 3 files changed, 3 insertions(+), 22 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index fcd9fe66e417..dd2d0422c9ca 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -517,7 +517,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
 	wfx_update_filtering(wvif);
 	memset(&wvif->bss_params, 0, sizeof(wvif->bss_params));
 	wvif->setbssparams_done = false;
-	memset(&wvif->ht_info, 0, sizeof(wvif->ht_info));
 
 done:
 	mutex_unlock(&wvif->wdev->conf_mutex);
@@ -812,11 +811,6 @@ static int wfx_upload_beacon(struct wfx_vif *wvif)
 	return 0;
 }
 
-static int wfx_is_ht(const struct wfx_ht_info *ht_info)
-{
-	return ht_info->channel_type != NL80211_CHAN_NO_HT;
-}
-
 static void wfx_join_finalize(struct wfx_vif *wvif,
 			      struct ieee80211_bss_conf *info)
 {
@@ -830,17 +824,12 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	rcu_read_lock();
 	if (info->bssid && !info->ibss_joined)
 		sta = ieee80211_find_sta(wvif->vif, info->bssid);
-	if (sta) {
-		wvif->ht_info.ht_cap = sta->ht_cap;
+	rcu_read_unlock();
+	if (sta)
 		wvif->bss_params.operational_rate_set =
 			wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]);
-		wvif->ht_info.operation_mode = info->ht_operation_mode;
-	} else {
-		memset(&wvif->ht_info, 0, sizeof(wvif->ht_info));
+	else
 		wvif->bss_params.operational_rate_set = -1;
-	}
-	rcu_read_unlock();
-
 	if (sta &&
 	    info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
 		hif_dual_cts_protection(wvif, true);
@@ -1224,7 +1213,6 @@ int wfx_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 	WARN(wvif->channel, "channel overwrite");
 	wvif->channel = ch;
-	wvif->ht_info.channel_type = cfg80211_get_chandef_type(&conf->def);
 
 	return 0;
 }
diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h
index b5d8d6494157..e0b54332e98a 100644
--- a/drivers/staging/wfx/sta.h
+++ b/drivers/staging/wfx/sta.h
@@ -23,12 +23,6 @@ enum wfx_state {
 	WFX_STATE_AP,
 };
 
-struct wfx_ht_info {
-	struct ieee80211_sta_ht_cap ht_cap;
-	enum nl80211_channel_type channel_type;
-	u16 operation_mode;
-};
-
 struct wfx_hif_event {
 	struct list_head link;
 	struct hif_ind_event evt;
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 0a3df382af03..ba6e0e923f4b 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -113,7 +113,6 @@ struct wfx_vif {
 	u32			erp_info;
 	int			cqm_rssi_thold;
 	bool			setbssparams_done;
-	struct wfx_ht_info	ht_info;
 	unsigned long		uapsd_mask;
 	struct ieee80211_tx_queue_params edca_params[IEEE80211_NUM_ACS];
 	struct hif_req_set_bss_params bss_params;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 14/65] staging: wfx: drop wdev->output_power
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (12 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 13/65] staging: wfx: drop struct wfx_ht_info Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 15/65] staging: wfx: simplify wfx_config() Jérôme Pouiller
                   ` (51 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

mac80211 and the device are both able to control tx power per vif. But,
the current code retrieve tx power from wfx_config(). So, it does not
allow to setup the tx power independently for each vif. Driver just has
to rely on bss_conf->txpower to get the correct information.

In add, it is no more necessary to protect access to wdev->output_power
with scan_lock.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/scan.c |  4 ++--
 drivers/staging/wfx/sta.c  | 16 ++--------------
 drivers/staging/wfx/wfx.h  |  2 --
 3 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c
index 8e0ac89fd28f..5cc9df5eb6a1 100644
--- a/drivers/staging/wfx/scan.c
+++ b/drivers/staging/wfx/scan.c
@@ -60,8 +60,8 @@ static int send_scan_req(struct wfx_vif *wvif,
 	if (timeout < 0)
 		return timeout;
 	ret = wait_for_completion_timeout(&wvif->scan_complete, timeout);
-	if (req->channels[start_idx]->max_power != wvif->wdev->output_power)
-		hif_set_output_power(wvif, wvif->wdev->output_power);
+	if (req->channels[start_idx]->max_power != wvif->vif->bss_conf.txpower)
+		hif_set_output_power(wvif, wvif->vif->bss_conf.txpower);
 	wfx_tx_unlock(wvif->wdev);
 	if (!ret) {
 		dev_notice(wvif->wdev->dev, "scan timeout\n");
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index dd2d0422c9ca..a0f19d33e972 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -503,7 +503,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
 	hif_keep_alive_period(wvif, 0);
 	hif_reset(wvif, false);
 	wfx_tx_policy_init(wvif);
-	hif_set_output_power(wvif, wvif->wdev->output_power);
 	wvif->dtim_period = 0;
 	hif_set_macaddr(wvif, wvif->vif->addr);
 	wfx_free_event_queue(wvif);
@@ -990,11 +989,8 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 					    info->cqm_rssi_hyst);
 	}
 
-	if (changed & BSS_CHANGED_TXPOWER &&
-	    info->txpower != wdev->output_power) {
-		wdev->output_power = info->txpower;
-		hif_set_output_power(wvif, wdev->output_power);
-	}
+	if (changed & BSS_CHANGED_TXPOWER)
+		hif_set_output_power(wvif, info->txpower);
 	mutex_unlock(&wdev->conf_mutex);
 
 	if (do_join)
@@ -1232,7 +1228,6 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed)
 {
 	int ret = 0;
 	struct wfx_dev *wdev = hw->priv;
-	struct ieee80211_conf *conf = &hw->conf;
 	struct wfx_vif *wvif;
 
 	// FIXME: Interface id should not been hardcoded
@@ -1242,13 +1237,7 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed)
 		return 0;
 	}
 
-	mutex_lock(&wvif->scan_lock);
 	mutex_lock(&wdev->conf_mutex);
-	if (changed & IEEE80211_CONF_CHANGE_POWER) {
-		wdev->output_power = conf->power_level;
-		hif_set_output_power(wvif, wdev->output_power);
-	}
-
 	if (changed & IEEE80211_CONF_CHANGE_PS) {
 		wvif = NULL;
 		while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
@@ -1257,7 +1246,6 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed)
 	}
 
 	mutex_unlock(&wdev->conf_mutex);
-	mutex_unlock(&wvif->scan_lock);
 	return ret;
 }
 
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index ba6e0e923f4b..155dbe5704c9 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -59,8 +59,6 @@ struct wfx_dev {
 
 	struct hif_rx_stats	rx_stats;
 	struct mutex		rx_stats_lock;
-
-	int			output_power;
 };
 
 struct wfx_vif {
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 15/65] staging: wfx: simplify wfx_config()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (13 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 14/65] staging: wfx: drop wdev->output_power Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 16/65] staging: wfx: rename wfx_upload_beacon() Jérôme Pouiller
                   ` (50 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Now that wfx_config() only handles IEEE80211_CONF_CHANGE_PS, it can be
simplified.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index a0f19d33e972..451d0108a1b0 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -1230,22 +1230,13 @@ int wfx_config(struct ieee80211_hw *hw, u32 changed)
 	struct wfx_dev *wdev = hw->priv;
 	struct wfx_vif *wvif;
 
-	// FIXME: Interface id should not been hardcoded
-	wvif = wdev_to_wvif(wdev, 0);
-	if (!wvif) {
-		WARN(1, "interface 0 does not exist anymore");
-		return 0;
-	}
-
-	mutex_lock(&wdev->conf_mutex);
 	if (changed & IEEE80211_CONF_CHANGE_PS) {
+		mutex_lock(&wdev->conf_mutex);
 		wvif = NULL;
 		while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
 			ret = wfx_update_pm(wvif);
-		wvif = wdev_to_wvif(wdev, 0);
+		mutex_unlock(&wdev->conf_mutex);
 	}
-
-	mutex_unlock(&wdev->conf_mutex);
 	return ret;
 }
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 16/65] staging: wfx: rename wfx_upload_beacon()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (14 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 15/65] staging: wfx: simplify wfx_config() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 17/65] staging: wfx: simplify wfx_upload_ap_templates() Jérôme Pouiller
                   ` (49 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

In fact, wfx_upload_beacon() uploads beacon and probe response. So,
rename it in wfx_upload_ap_templates().

The call to wfx_fwd_probe_req() has nothing to do with template
uploading, so relocate it.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 451d0108a1b0..fdde7ab92302 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -780,7 +780,7 @@ static int wfx_update_beaconing(struct wfx_vif *wvif)
 	return 0;
 }
 
-static int wfx_upload_beacon(struct wfx_vif *wvif)
+static int wfx_upload_ap_templates(struct wfx_vif *wvif)
 {
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
@@ -805,7 +805,6 @@ static int wfx_upload_beacon(struct wfx_vif *wvif)
 
 	hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBRES,
 			       API_RATE_INDEX_B_1MBPS);
-	wfx_fwd_probe_req(wvif, false);
 	dev_kfree_skb(skb);
 	return 0;
 }
@@ -900,7 +899,8 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 	    changed & BSS_CHANGED_IBSS) {
 		wvif->beacon_int = info->beacon_int;
 		wfx_update_beaconing(wvif);
-		wfx_upload_beacon(wvif);
+		wfx_upload_ap_templates(wvif);
+		wfx_fwd_probe_req(wvif, false);
 	}
 
 	if (changed & BSS_CHANGED_BEACON_ENABLED &&
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 17/65] staging: wfx: simplify wfx_upload_ap_templates()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (15 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 16/65] staging: wfx: rename wfx_upload_beacon() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 18/65] staging: wfx: simplify wfx_update_beaconing() Jérôme Pouiller
                   ` (48 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

This function built probe response from data retrieved in beacon. Yet,
this job can be done with ieee80211_proberesp_get(). So, we can simplify
that code (and fix bugs like inclusion of TIM in probe responses).

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index fdde7ab92302..1181203489f0 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -783,7 +783,6 @@ static int wfx_update_beaconing(struct wfx_vif *wvif)
 static int wfx_upload_ap_templates(struct wfx_vif *wvif)
 {
 	struct sk_buff *skb;
-	struct ieee80211_mgmt *mgmt;
 
 	if (wvif->vif->type == NL80211_IFTYPE_STATION ||
 	    wvif->vif->type == NL80211_IFTYPE_MONITOR ||
@@ -795,14 +794,11 @@ static int wfx_upload_ap_templates(struct wfx_vif *wvif)
 		return -ENOMEM;
 	hif_set_template_frame(wvif, skb, HIF_TMPLT_BCN,
 			       API_RATE_INDEX_B_1MBPS);
+	dev_kfree_skb(skb);
 
-	/* TODO: Distill probe resp; remove TIM and any other beacon-specific
-	 * IEs
-	 */
-	mgmt = (void *)skb->data;
-	mgmt->frame_control =
-		cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
-
+	skb = ieee80211_proberesp_get(wvif->wdev->hw, wvif->vif);
+	if (!skb)
+		return -ENOMEM;
 	hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBRES,
 			       API_RATE_INDEX_B_1MBPS);
 	dev_kfree_skb(skb);
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 18/65] staging: wfx: simplify wfx_update_beaconing()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (16 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 17/65] staging: wfx: simplify wfx_upload_ap_templates() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 19/65] staging: wfx: fix __wfx_flush() when drop == false Jérôme Pouiller
                   ` (47 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Remove most of indentation of wfx_update_beaconing() by reworking the
error handling.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 28 +++++++++++-----------------
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 1181203489f0..0c73691ab736 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -760,23 +760,17 @@ static int wfx_start_ap(struct wfx_vif *wvif)
 
 static int wfx_update_beaconing(struct wfx_vif *wvif)
 {
-	struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
-
-	if (wvif->vif->type == NL80211_IFTYPE_AP) {
-		/* TODO: check if changed channel, band */
-		if (wvif->state != WFX_STATE_AP ||
-		    wvif->beacon_int != conf->beacon_int) {
-			wfx_tx_lock_flush(wvif->wdev);
-			if (wvif->state != WFX_STATE_PASSIVE) {
-				hif_reset(wvif, false);
-				wfx_tx_policy_init(wvif);
-			}
-			wvif->state = WFX_STATE_PASSIVE;
-			wfx_start_ap(wvif);
-			wfx_tx_unlock(wvif->wdev);
-		} else {
-		}
-	}
+	if (wvif->vif->type != NL80211_IFTYPE_AP)
+		return 0;
+	if (wvif->state == WFX_STATE_AP &&
+	    wvif->beacon_int == wvif->vif->bss_conf.beacon_int)
+		return 0;
+	wfx_tx_lock_flush(wvif->wdev);
+	hif_reset(wvif, false);
+	wfx_tx_policy_init(wvif);
+	wvif->state = WFX_STATE_PASSIVE;
+	wfx_start_ap(wvif);
+	wfx_tx_unlock(wvif->wdev);
 	return 0;
 }
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 19/65] staging: wfx: fix __wfx_flush() when drop == false
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (17 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 18/65] staging: wfx: simplify wfx_update_beaconing() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 20/65] staging: wfx: simplify wfx_flush() Jérôme Pouiller
                   ` (46 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wfx_tx_queues_clear() only clear not yet sent requests. So, it always
necessary to wait for tx_queue_stats.wait_link_id_empty whatever the
value of "drop" argument.

In add, it is not necessary to return with tx queue locked since all
calls to __wfx_flush() unlock the tx queue just after the call to
__wfx_tx_flush().

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/queue.c |  2 --
 drivers/staging/wfx/sta.c   | 42 ++++++++++---------------------------
 2 files changed, 11 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c
index abfbad7c9f75..92bb9a794f30 100644
--- a/drivers/staging/wfx/queue.c
+++ b/drivers/staging/wfx/queue.c
@@ -31,8 +31,6 @@ void wfx_tx_flush(struct wfx_dev *wdev)
 {
 	int ret;
 
-	WARN(!atomic_read(&wdev->tx_lock), "tx_lock is not locked");
-
 	// Do not wait for any reply if chip is frozen
 	if (wdev->chip_frozen)
 		return;
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 0c73691ab736..3d665eef8ba7 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -343,42 +343,25 @@ int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 	return 0;
 }
 
-/* If successful, LOCKS the TX queue! */
 static int __wfx_flush(struct wfx_dev *wdev, bool drop)
 {
-	int ret;
-
 	for (;;) {
-		if (drop) {
+		if (drop)
 			wfx_tx_queues_clear(wdev);
-		} else {
-			ret = wait_event_timeout(
-				wdev->tx_queue_stats.wait_link_id_empty,
-				wfx_tx_queues_is_empty(wdev),
-				2 * HZ);
-		}
-
-		if (!drop && ret <= 0) {
-			ret = -ETIMEDOUT;
-			break;
-		}
-		ret = 0;
-
-		wfx_tx_lock_flush(wdev);
-		if (!wfx_tx_queues_is_empty(wdev)) {
-			/* Highly unlikely: WSM requeued frames. */
-			wfx_tx_unlock(wdev);
-			continue;
-		}
-		break;
+		if (wait_event_timeout(wdev->tx_queue_stats.wait_link_id_empty,
+				       wfx_tx_queues_is_empty(wdev),
+				       2 * HZ) <= 0)
+			return -ETIMEDOUT;
+		wfx_tx_flush(wdev);
+		if (wfx_tx_queues_is_empty(wdev))
+			return 0;
+		dev_warn(wdev->dev, "frames queued while flushing tx queues");
 	}
-	return ret;
 }
 
 void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		  u32 queues, bool drop)
 {
-	struct wfx_dev *wdev = hw->priv;
 	struct wfx_vif *wvif;
 
 	if (vif) {
@@ -389,10 +372,8 @@ void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		    !wvif->enable_beacon)
 			drop = true;
 	}
-
 	// FIXME: only flush requested vif
-	if (!__wfx_flush(wdev, drop))
-		wfx_tx_unlock(wdev);
+	__wfx_flush(hw->priv, drop);
 }
 
 /* WSM callbacks */
@@ -1046,8 +1027,7 @@ static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
 	skb = ieee80211_beacon_get_tim(wvif->wdev->hw, wvif->vif,
 				       &tim_offset, &tim_length);
 	if (!skb) {
-		if (!__wfx_flush(wvif->wdev, true))
-			wfx_tx_unlock(wvif->wdev);
+		__wfx_flush(wvif->wdev, true);
 		return -ENOENT;
 	}
 	tim_ptr = skb->data + tim_offset;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 20/65] staging: wfx: simplify wfx_flush()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (18 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 19/65] staging: wfx: fix __wfx_flush() when drop == false Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 21/65] staging: wfx: simplify update of DTIM period Jérôme Pouiller
                   ` (45 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Current code of wfx_flush() force to drop packets in some contexts.
However, there is no obvious reasons to do that. It looks like a
workaround for a bug with the old implementation of __wfx_flush().

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 3d665eef8ba7..ae01f7be0ddb 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -362,17 +362,7 @@ static int __wfx_flush(struct wfx_dev *wdev, bool drop)
 void wfx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		  u32 queues, bool drop)
 {
-	struct wfx_vif *wvif;
-
-	if (vif) {
-		wvif = (struct wfx_vif *) vif->drv_priv;
-		if (wvif->vif->type == NL80211_IFTYPE_MONITOR)
-			drop = true;
-		if (wvif->vif->type == NL80211_IFTYPE_AP &&
-		    !wvif->enable_beacon)
-			drop = true;
-	}
-	// FIXME: only flush requested vif
+	// FIXME: only flush requested vif and queues
 	__wfx_flush(hw->priv, drop);
 }
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 21/65] staging: wfx: simplify update of DTIM period
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (19 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 20/65] staging: wfx: simplify wfx_flush() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 22/65] staging: wfx: drop wvif->dtim_period Jérôme Pouiller
                   ` (44 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Current code parse the TIM and retrieve the DTIM period. It is far
easier to rely on bss_info_changed() for this job.

It is no more necessary to run task asynchronously. So
set_beacon_wakeup_period_work is now useless.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_rx.c | 14 --------------
 drivers/staging/wfx/sta.c     | 19 ++++++-------------
 drivers/staging/wfx/wfx.h     |  2 --
 3 files changed, 6 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/wfx/data_rx.c b/drivers/staging/wfx/data_rx.c
index d460c0ffca1f..0ab71c911f84 100644
--- a/drivers/staging/wfx/data_rx.c
+++ b/drivers/staging/wfx/data_rx.c
@@ -173,20 +173,6 @@ void wfx_rx_cb(struct wfx_vif *wvif,
 	    !arg->status && wvif->vif &&
 	    ether_addr_equal(ieee80211_get_SA(frame),
 			     wvif->vif->bss_conf.bssid)) {
-		const u8 *tim_ie;
-		u8 *ies = mgmt->u.beacon.variable;
-		size_t ies_len = skb->len - (ies - skb->data);
-
-		tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len);
-		if (tim_ie) {
-			struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *)&tim_ie[2];
-
-			if (wvif->dtim_period != tim->dtim_period) {
-				wvif->dtim_period = tim->dtim_period;
-				schedule_work(&wvif->set_beacon_wakeup_period_work);
-			}
-		}
-
 		/* Disable beacon filter once we're associated... */
 		if (wvif->disable_beacon_filter &&
 		    (wvif->vif->bss_conf.assoc ||
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index ae01f7be0ddb..1af99b7930f4 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -446,15 +446,6 @@ static void wfx_bss_params_work(struct work_struct *work)
 	mutex_unlock(&wvif->wdev->conf_mutex);
 }
 
-static void wfx_set_beacon_wakeup_period_work(struct work_struct *work)
-{
-	struct wfx_vif *wvif = container_of(work, struct wfx_vif,
-					    set_beacon_wakeup_period_work);
-
-	hif_set_beacon_wakeup_period(wvif, wvif->dtim_period,
-				     wvif->dtim_period);
-}
-
 static void wfx_do_unjoin(struct wfx_vif *wvif)
 {
 	mutex_lock(&wvif->wdev->conf_mutex);
@@ -466,7 +457,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
 		goto done;
 
 	cancel_work_sync(&wvif->update_filtering_work);
-	cancel_work_sync(&wvif->set_beacon_wakeup_period_work);
 	wvif->state = WFX_STATE_PASSIVE;
 
 	/* Unjoin is a reset. */
@@ -823,7 +813,8 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 		hif_keep_alive_period(wvif, 30 /* sec */);
 		hif_set_bss_params(wvif, &wvif->bss_params);
 		wvif->setbssparams_done = true;
-		wfx_set_beacon_wakeup_period_work(&wvif->set_beacon_wakeup_period_work);
+		hif_set_beacon_wakeup_period(wvif, info->dtim_period,
+					     info->dtim_period);
 		wfx_update_pm(wvif);
 	}
 }
@@ -872,6 +863,10 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 		}
 	}
 
+	if (changed & BSS_CHANGED_BEACON_INFO)
+		hif_set_beacon_wakeup_period(wvif, info->dtim_period,
+					     info->dtim_period);
+
 	/* assoc/disassoc, or maybe AID changed */
 	if (changed & BSS_CHANGED_ASSOC) {
 		wfx_tx_lock_flush(wdev);
@@ -1260,8 +1255,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 
 	init_completion(&wvif->set_pm_mode_complete);
 	complete(&wvif->set_pm_mode_complete);
-	INIT_WORK(&wvif->set_beacon_wakeup_period_work,
-		  wfx_set_beacon_wakeup_period_work);
 	INIT_WORK(&wvif->update_filtering_work, wfx_update_filtering_work);
 	INIT_WORK(&wvif->bss_params_work, wfx_bss_params_work);
 	INIT_WORK(&wvif->set_cts_work, wfx_set_cts_work);
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 155dbe5704c9..d201cceec1ab 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -101,8 +101,6 @@ struct wfx_vif {
 	int			dtim_period;
 	int			beacon_int;
 	bool			enable_beacon;
-	struct work_struct	set_beacon_wakeup_period_work;
-
 	bool			filter_bssid;
 	bool			fwd_probe_req;
 	bool			disable_beacon_filter;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 22/65] staging: wfx: drop wvif->dtim_period
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (20 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 21/65] staging: wfx: simplify update of DTIM period Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 23/65] staging: wfx: drop wvif->enable_beacon Jérôme Pouiller
                   ` (43 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

It is not necessary to keep a copy of dtim_period in wfx_vif. Prefer to
just rely on bss_conf->dtim_period.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 20 ++++----------------
 drivers/staging/wfx/wfx.h |  1 -
 2 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 1af99b7930f4..376451433e9e 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -464,7 +464,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
 	hif_keep_alive_period(wvif, 0);
 	hif_reset(wvif, false);
 	wfx_tx_policy_init(wvif);
-	wvif->dtim_period = 0;
 	hif_set_macaddr(wvif, wvif->vif->addr);
 	wfx_free_event_queue(wvif);
 	cancel_work_sync(&wvif->event_handler_work);
@@ -557,10 +556,6 @@ static void wfx_do_join(struct wfx_vif *wvif)
 		wvif->beacon_int = 1;
 
 	join.beacon_interval = wvif->beacon_int;
-
-	// DTIM period will be set on first Beacon
-	wvif->dtim_period = 0;
-
 	join.channel_number = wvif->channel->hw_value;
 	memcpy(join.bssid, bssid, sizeof(join.bssid));
 
@@ -701,8 +696,6 @@ static int wfx_start_ap(struct wfx_vif *wvif)
 	int ret;
 
 	wvif->beacon_int = wvif->vif->bss_conf.beacon_int;
-	wvif->dtim_period = wvif->vif->bss_conf.dtim_period;
-
 	memset(&wvif->link_id_db, 0, sizeof(wvif->link_id_db));
 
 	wvif->wdev->tx_burst_idx = -1;
@@ -766,10 +759,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	struct ieee80211_sta *sta = NULL;
 	struct hif_mib_set_association_mode association_mode = { };
 
-	if (info->dtim_period)
-		wvif->dtim_period = info->dtim_period;
 	wvif->beacon_int = info->beacon_int;
-
 	rcu_read_lock();
 	if (info->bssid && !info->ibss_joined)
 		sta = ieee80211_find_sta(wvif->vif, info->bssid);
@@ -804,9 +794,6 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	wvif->bss_params.beacon_lost_count = 20;
 	wvif->bss_params.aid = info->aid;
 
-	if (wvif->dtim_period < 1)
-		wvif->dtim_period = 1;
-
 	hif_set_association_mode(wvif, &association_mode);
 
 	if (!info->ibss_joined) {
@@ -1055,9 +1042,10 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
 
 static void wfx_mcast_start_work(struct work_struct *work)
 {
-	struct wfx_vif *wvif = container_of(work, struct wfx_vif,
-					    mcast_start_work);
-	long tmo = wvif->dtim_period * TU_TO_JIFFIES(wvif->beacon_int + 20);
+	struct wfx_vif *wvif =
+		container_of(work, struct wfx_vif, mcast_start_work);
+	struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
+	long tmo = conf->dtim_period * TU_TO_JIFFIES(wvif->beacon_int + 20);
 
 	cancel_work_sync(&wvif->mcast_stop_work);
 	if (!wvif->aid0_bit_set) {
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index d201cceec1ab..bd4b55e07c73 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -98,7 +98,6 @@ struct wfx_vif {
 	spinlock_t		ps_state_lock;
 	struct work_struct	set_tim_work;
 
-	int			dtim_period;
 	int			beacon_int;
 	bool			enable_beacon;
 	bool			filter_bssid;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 23/65] staging: wfx: drop wvif->enable_beacon
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (21 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 22/65] staging: wfx: drop wvif->dtim_period Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 24/65] staging: wfx: drop wvif->cqm_rssi_thold Jérôme Pouiller
                   ` (42 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

It seems that current code try to save calls to hif_beacon_transmit() by
keeping a copy of the previous value of bss_conf->enable_beacon.
However, hif_beacon_transmit() does not cost so much and mac80211
already take care to not send useless events.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 9 ++-------
 drivers/staging/wfx/wfx.h | 1 -
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 376451433e9e..dede6323bb17 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -843,12 +843,8 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 	}
 
 	if (changed & BSS_CHANGED_BEACON_ENABLED &&
-	    wvif->state != WFX_STATE_IBSS) {
-		if (wvif->enable_beacon != info->enable_beacon) {
-			hif_beacon_transmit(wvif, info->enable_beacon);
-			wvif->enable_beacon = info->enable_beacon;
-		}
-	}
+	    wvif->state != WFX_STATE_IBSS)
+		hif_beacon_transmit(wvif, info->enable_beacon);
 
 	if (changed & BSS_CHANGED_BEACON_INFO)
 		hif_set_beacon_wakeup_period(wvif, info->dtim_period,
@@ -1299,7 +1295,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
 		}
 		memset(wvif->link_id_db, 0, sizeof(wvif->link_id_db));
 		wvif->sta_asleep_mask = 0;
-		wvif->enable_beacon = false;
 		wvif->mcast_tx = false;
 		wvif->aid0_bit_set = false;
 		wvif->mcast_buffered = false;
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index bd4b55e07c73..84cb3a83e5d9 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -99,7 +99,6 @@ struct wfx_vif {
 	struct work_struct	set_tim_work;
 
 	int			beacon_int;
-	bool			enable_beacon;
 	bool			filter_bssid;
 	bool			fwd_probe_req;
 	bool			disable_beacon_filter;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 24/65] staging: wfx: drop wvif->cqm_rssi_thold
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (22 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 23/65] staging: wfx: drop wvif->enable_beacon Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 25/65] staging: wfx: drop wvif->setbssparams_done Jérôme Pouiller
                   ` (41 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Current code keeps a copy of bss_conf->cqm_rssi_thold in wfx_vif. There
is no sane reason for that.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 6 ++----
 drivers/staging/wfx/wfx.h | 1 -
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index dede6323bb17..021daa9f7a33 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -377,7 +377,7 @@ static void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi)
 	int cqm_evt;
 
 	rcpi_rssi = raw_rcpi_rssi / 2 - 110;
-	if (rcpi_rssi <= wvif->cqm_rssi_thold)
+	if (rcpi_rssi <= wvif->vif->bss_conf.cqm_rssi_thold)
 		cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
 	else
 		cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
@@ -922,11 +922,9 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 	if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_ERP_SLOT)
 		hif_slot_time(wvif, info->use_short_slot ? 9 : 20);
 
-	if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_CQM) {
-		wvif->cqm_rssi_thold = info->cqm_rssi_thold;
+	if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_CQM)
 		hif_set_rcpi_rssi_threshold(wvif, info->cqm_rssi_thold,
 					    info->cqm_rssi_hyst);
-	}
 
 	if (changed & BSS_CHANGED_TXPOWER)
 		hif_set_output_power(wvif, info->txpower);
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 84cb3a83e5d9..1b487d96eca2 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -105,7 +105,6 @@ struct wfx_vif {
 	struct work_struct	update_filtering_work;
 
 	u32			erp_info;
-	int			cqm_rssi_thold;
 	bool			setbssparams_done;
 	unsigned long		uapsd_mask;
 	struct ieee80211_tx_queue_params edca_params[IEEE80211_NUM_ACS];
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 25/65] staging: wfx: drop wvif->setbssparams_done
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (23 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 24/65] staging: wfx: drop wvif->cqm_rssi_thold Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 26/65] staging: wfx: drop wfx_set_cts_work() Jérôme Pouiller
                   ` (40 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

setbssparams_done was here to ensure that the firmware does not enable
powersave before to get the first beacon. However, mac80211 already
ensures it gets a beacon before to associate to the BSS. And even, if
it won't, the firmware wake up at least on every DTIM, which is
sufficient to finalize the association.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 8 +++-----
 drivers/staging/wfx/wfx.h | 1 -
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 021daa9f7a33..7abe272ddc0d 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -326,8 +326,7 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	hif_set_edca_queue_params(wvif, queue, params);
 	if (wvif->vif->type == NL80211_IFTYPE_STATION) {
 		hif_set_uapsd_info(wvif, wvif->uapsd_mask);
-		if (wvif->setbssparams_done && wvif->state == WFX_STATE_STA)
-			ret = wfx_update_pm(wvif);
+		wfx_update_pm(wvif);
 	}
 	mutex_unlock(&wdev->conf_mutex);
 	return ret;
@@ -475,7 +474,6 @@ static void wfx_do_unjoin(struct wfx_vif *wvif)
 	wvif->disable_beacon_filter = false;
 	wfx_update_filtering(wvif);
 	memset(&wvif->bss_params, 0, sizeof(wvif->bss_params));
-	wvif->setbssparams_done = false;
 
 done:
 	mutex_unlock(&wvif->wdev->conf_mutex);
@@ -799,7 +797,6 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	if (!info->ibss_joined) {
 		hif_keep_alive_period(wvif, 30 /* sec */);
 		hif_set_bss_params(wvif, &wvif->bss_params);
-		wvif->setbssparams_done = true;
 		hif_set_beacon_wakeup_period(wvif, info->dtim_period,
 					     info->dtim_period);
 		wfx_update_pm(wvif);
@@ -1224,7 +1221,8 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	INIT_WORK(&wvif->mcast_stop_work, wfx_mcast_stop_work);
 	timer_setup(&wvif->mcast_timeout, wfx_mcast_timeout, 0);
 
-	wvif->setbssparams_done = false;
+	memset(&wvif->bss_params, 0, sizeof(wvif->bss_params));
+
 	mutex_init(&wvif->bss_loss_lock);
 	INIT_DELAYED_WORK(&wvif->bss_loss_work, wfx_bss_loss_work);
 
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 1b487d96eca2..5e1a763eb4b5 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -105,7 +105,6 @@ struct wfx_vif {
 	struct work_struct	update_filtering_work;
 
 	u32			erp_info;
-	bool			setbssparams_done;
 	unsigned long		uapsd_mask;
 	struct ieee80211_tx_queue_params edca_params[IEEE80211_NUM_ACS];
 	struct hif_req_set_bss_params bss_params;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 26/65] staging: wfx: drop wfx_set_cts_work()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (24 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 25/65] staging: wfx: drop wvif->setbssparams_done Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 27/65] staging: wfx: SSID should be provided to hif_start() even if hidden Jérôme Pouiller
                   ` (39 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wfx_bss_info_changed() is not called from atomic contexts. So, it is not
necessary to raise an asynchronous work to change ERP. Thus
wfx_set_cts_work() become useless.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 40 +++++++++------------------------------
 drivers/staging/wfx/wfx.h |  2 --
 2 files changed, 9 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 7abe272ddc0d..e02ebc39ed41 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -671,24 +671,6 @@ int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	return 0;
 }
 
-static void wfx_set_cts_work(struct work_struct *work)
-{
-	struct wfx_vif *wvif = container_of(work, struct wfx_vif, set_cts_work);
-	u8 erp_ie[3] = { WLAN_EID_ERP_INFO, 1, 0 };
-	struct hif_ie_flags target_frame = {
-		.beacon = 1,
-	};
-
-	mutex_lock(&wvif->wdev->conf_mutex);
-	erp_ie[2] = wvif->erp_info;
-	mutex_unlock(&wvif->wdev->conf_mutex);
-
-	hif_erp_use_protection(wvif, erp_ie[2] & WLAN_ERP_USE_PROTECTION);
-
-	if (wvif->vif->type != NL80211_IFTYPE_STATION)
-		hif_update_ie(wvif, &target_frame, erp_ie, sizeof(erp_ie));
-}
-
 static int wfx_start_ap(struct wfx_vif *wvif)
 {
 	int ret;
@@ -896,24 +878,21 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 		}
 	}
 
-	/* ERP Protection */
 	if (changed & BSS_CHANGED_ASSOC ||
 	    changed & BSS_CHANGED_ERP_CTS_PROT ||
 	    changed & BSS_CHANGED_ERP_PREAMBLE) {
-		u32 prev_erp_info = wvif->erp_info;
+		struct hif_ie_flags target_frame = {
+			.beacon = 1,
+		};
+		u8 erp_ie[3] = { WLAN_EID_ERP_INFO, 1, 0 };
 
+		hif_erp_use_protection(wvif, info->use_cts_prot);
 		if (info->use_cts_prot)
-			wvif->erp_info |= WLAN_ERP_USE_PROTECTION;
-		else if (!(prev_erp_info & WLAN_ERP_NON_ERP_PRESENT))
-			wvif->erp_info &= ~WLAN_ERP_USE_PROTECTION;
-
+			erp_ie[2] |= WLAN_ERP_USE_PROTECTION;
 		if (info->use_short_preamble)
-			wvif->erp_info |= WLAN_ERP_BARKER_PREAMBLE;
-		else
-			wvif->erp_info &= ~WLAN_ERP_BARKER_PREAMBLE;
-
-		if (prev_erp_info != wvif->erp_info)
-			schedule_work(&wvif->set_cts_work);
+			erp_ie[2] |= WLAN_ERP_BARKER_PREAMBLE;
+		if (wvif->vif->type != NL80211_IFTYPE_STATION)
+			hif_update_ie(wvif, &target_frame, erp_ie, sizeof(erp_ie));
 	}
 
 	if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_ERP_SLOT)
@@ -1237,7 +1216,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	complete(&wvif->set_pm_mode_complete);
 	INIT_WORK(&wvif->update_filtering_work, wfx_update_filtering_work);
 	INIT_WORK(&wvif->bss_params_work, wfx_bss_params_work);
-	INIT_WORK(&wvif->set_cts_work, wfx_set_cts_work);
 	INIT_WORK(&wvif->unjoin_work, wfx_unjoin_work);
 	INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work);
 
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 5e1a763eb4b5..f56a91ea082d 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -104,12 +104,10 @@ struct wfx_vif {
 	bool			disable_beacon_filter;
 	struct work_struct	update_filtering_work;
 
-	u32			erp_info;
 	unsigned long		uapsd_mask;
 	struct ieee80211_tx_queue_params edca_params[IEEE80211_NUM_ACS];
 	struct hif_req_set_bss_params bss_params;
 	struct work_struct	bss_params_work;
-	struct work_struct	set_cts_work;
 
 	int			join_complete_status;
 	struct work_struct	unjoin_work;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 27/65] staging: wfx: SSID should be provided to hif_start() even if hidden
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (25 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 26/65] staging: wfx: drop wfx_set_cts_work() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 28/65] staging: wfx: simplify hif_update_ie() Jérôme Pouiller
                   ` (38 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

SSID is hidden in beacon but firmware has to know to which probe
requests it has to answer.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c
index 2d541601e224..8df6e43fe742 100644
--- a/drivers/staging/wfx/hif_tx.c
+++ b/drivers/staging/wfx/hif_tx.c
@@ -422,10 +422,8 @@ int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
 	body->beacon_interval = cpu_to_le32(conf->beacon_int);
 	body->basic_rate_set =
 		cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates));
-	if (!conf->hidden_ssid) {
-		body->ssid_length = conf->ssid_len;
-		memcpy(body->ssid, conf->ssid, conf->ssid_len);
-	}
+	body->ssid_length = conf->ssid_len;
+	memcpy(body->ssid, conf->ssid, conf->ssid_len);
 	wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START, sizeof(*body));
 	ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
 	kfree(hif);
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 28/65] staging: wfx: simplify hif_update_ie()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (26 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 27/65] staging: wfx: SSID should be provided to hif_start() even if hidden Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 29/65] staging: wfx: simplify hif_join() Jérôme Pouiller
                   ` (37 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

hif_update_ie() is only called to change the beacon template. So,
specialize this function and simplify the way to call it.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx.c |  5 ++---
 drivers/staging/wfx/hif_tx.h |  3 +--
 drivers/staging/wfx/sta.c    | 10 ++--------
 3 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c
index 8df6e43fe742..32eeba2fca47 100644
--- a/drivers/staging/wfx/hif_tx.c
+++ b/drivers/staging/wfx/hif_tx.c
@@ -461,15 +461,14 @@ int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id)
 	return ret;
 }
 
-int hif_update_ie(struct wfx_vif *wvif, const struct hif_ie_flags *target_frame,
-		  const u8 *ies, size_t ies_len)
+int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len)
 {
 	int ret;
 	struct hif_msg *hif;
 	int buf_len = sizeof(struct hif_req_update_ie) + ies_len;
 	struct hif_req_update_ie *body = wfx_alloc_hif(buf_len, &hif);
 
-	memcpy(&body->ie_flags, target_frame, sizeof(struct hif_ie_flags));
+	body->ie_flags.beacon = 1;
 	body->num_ies = cpu_to_le16(1);
 	memcpy(body->ie, ies, ies_len);
 	wfx_fill_header(hif, wvif->id, HIF_REQ_ID_UPDATE_IE, buf_len);
diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h
index fbaed991b112..924b889cad0a 100644
--- a/drivers/staging/wfx/hif_tx.h
+++ b/drivers/staging/wfx/hif_tx.h
@@ -57,8 +57,7 @@ int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
 	      const struct ieee80211_channel *channel);
 int hif_beacon_transmit(struct wfx_vif *wvif, bool enable);
 int hif_map_link(struct wfx_vif *wvif, u8 *mac_addr, int flags, int sta_id);
-int hif_update_ie(struct wfx_vif *wvif, const struct hif_ie_flags *target_frame,
-		  const u8 *ies, size_t ies_len);
+int hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len);
 int hif_sl_set_mac_key(struct wfx_dev *wdev, const u8 *slk_key,
 		       int destination);
 int hif_sl_config(struct wfx_dev *wdev, const unsigned long *bitmap);
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index e02ebc39ed41..395a282346b1 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -881,9 +881,6 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 	if (changed & BSS_CHANGED_ASSOC ||
 	    changed & BSS_CHANGED_ERP_CTS_PROT ||
 	    changed & BSS_CHANGED_ERP_PREAMBLE) {
-		struct hif_ie_flags target_frame = {
-			.beacon = 1,
-		};
 		u8 erp_ie[3] = { WLAN_EID_ERP_INFO, 1, 0 };
 
 		hif_erp_use_protection(wvif, info->use_cts_prot);
@@ -892,7 +889,7 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 		if (info->use_short_preamble)
 			erp_ie[2] |= WLAN_ERP_BARKER_PREAMBLE;
 		if (wvif->vif->type != NL80211_IFTYPE_STATION)
-			hif_update_ie(wvif, &target_frame, erp_ie, sizeof(erp_ie));
+			hif_update_ie_beacon(wvif, erp_ie, sizeof(erp_ie));
 	}
 
 	if (changed & BSS_CHANGED_ASSOC || changed & BSS_CHANGED_ERP_SLOT)
@@ -960,9 +957,6 @@ void wfx_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
 {
 	struct sk_buff *skb;
-	struct hif_ie_flags target_frame = {
-		.beacon = 1,
-	};
 	u16 tim_offset, tim_length;
 	u8 *tim_ptr;
 
@@ -987,7 +981,7 @@ static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
 			tim_ptr[4] &= ~1;
 	}
 
-	hif_update_ie(wvif, &target_frame, tim_ptr, tim_length);
+	hif_update_ie_beacon(wvif, tim_ptr, tim_length);
 	dev_kfree_skb(skb);
 
 	return 0;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 29/65] staging: wfx: simplify hif_join()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (27 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 28/65] staging: wfx: simplify hif_update_ie() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 30/65] staging: wfx: simplify hif_set_association_mode() Jérôme Pouiller
                   ` (36 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The structure hif_req_join come from hardware API. It is not intended
to be manipulated in upper layers of the driver.

In add, current code for hif_join() is too dumb. It should pack data
with hardware representation instead of leaving all work to the caller.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx.c | 25 ++++++++++++++------
 drivers/staging/wfx/hif_tx.h |  3 ++-
 drivers/staging/wfx/sta.c    | 45 ++++++++----------------------------
 3 files changed, 30 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c
index 32eeba2fca47..2428363371fa 100644
--- a/drivers/staging/wfx/hif_tx.c
+++ b/drivers/staging/wfx/hif_tx.c
@@ -288,18 +288,29 @@ int hif_stop_scan(struct wfx_vif *wvif)
 	return ret;
 }
 
-int hif_join(struct wfx_vif *wvif, const struct hif_req_join *arg)
+int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
+	     const struct ieee80211_channel *channel, const u8 *ssidie)
 {
 	int ret;
 	struct hif_msg *hif;
 	struct hif_req_join *body = wfx_alloc_hif(sizeof(*body), &hif);
 
-	memcpy(body, arg, sizeof(struct hif_req_join));
-	cpu_to_le16s(&body->channel_number);
-	cpu_to_le16s(&body->atim_window);
-	cpu_to_le32s(&body->ssid_length);
-	cpu_to_le32s(&body->beacon_interval);
-	cpu_to_le32s(&body->basic_rate_set);
+	WARN_ON(!conf->basic_rates);
+	body->infrastructure_bss_mode = !conf->ibss_joined;
+	body->short_preamble = conf->use_short_preamble;
+	if (channel && channel->flags & IEEE80211_CHAN_NO_IR)
+		body->probe_for_join = 0;
+	else
+		body->probe_for_join = 1;
+	body->channel_number = cpu_to_le16(channel->hw_value);
+	body->beacon_interval = cpu_to_le32(conf->beacon_int);
+	body->basic_rate_set =
+		cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates));
+	memcpy(body->bssid, conf->bssid, sizeof(body->bssid));
+	if (!conf->ibss_joined && ssidie) {
+		body->ssid_length = cpu_to_le32(ssidie[1]);
+		memcpy(body->ssid, &ssidie[2], ssidie[1]);
+	}
 	wfx_fill_header(hif, wvif->id, HIF_REQ_ID_JOIN, sizeof(*body));
 	ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
 	kfree(hif);
diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h
index 924b889cad0a..20977e461718 100644
--- a/drivers/staging/wfx/hif_tx.h
+++ b/drivers/staging/wfx/hif_tx.h
@@ -45,7 +45,8 @@ int hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id,
 int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req80211,
 	     int chan_start, int chan_num);
 int hif_stop_scan(struct wfx_vif *wvif);
-int hif_join(struct wfx_vif *wvif, const struct hif_req_join *arg);
+int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf,
+	     const struct ieee80211_channel *channel, const u8 *ssidie);
 int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout);
 int hif_set_bss_params(struct wfx_vif *wvif,
 		       const struct hif_req_set_bss_params *arg);
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 395a282346b1..30c62e3b3716 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -512,32 +512,19 @@ static void wfx_set_mfp(struct wfx_vif *wvif,
 
 static void wfx_do_join(struct wfx_vif *wvif)
 {
-	const u8 *bssid;
+	int ret;
+	const u8 *ssidie;
 	struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
 	struct cfg80211_bss *bss = NULL;
-	struct hif_req_join join = {
-		.infrastructure_bss_mode = !conf->ibss_joined,
-		.short_preamble = conf->use_short_preamble,
-		.probe_for_join = 1,
-		.atim_window = 0,
-		.basic_rate_set = wfx_rate_mask_to_hw(wvif->wdev,
-						      conf->basic_rates),
-	};
 
 	wfx_tx_lock_flush(wvif->wdev);
 
-	if (wvif->channel->flags & IEEE80211_CHAN_NO_IR)
-		join.probe_for_join = 0;
-
 	if (wvif->state)
 		wfx_do_unjoin(wvif);
 
-	bssid = wvif->vif->bss_conf.bssid;
-
 	bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel,
-			       bssid, NULL, 0,
+			       conf->bssid, NULL, 0,
 			       IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY);
-
 	if (!bss && !conf->ibss_joined) {
 		wfx_tx_unlock(wvif->wdev);
 		return;
@@ -545,29 +532,15 @@ static void wfx_do_join(struct wfx_vif *wvif)
 
 	mutex_lock(&wvif->wdev->conf_mutex);
 
-	/* Sanity check basic rates */
-	if (!join.basic_rate_set)
-		join.basic_rate_set = 7;
-
 	/* Sanity check beacon interval */
 	if (!wvif->beacon_int)
 		wvif->beacon_int = 1;
 
-	join.beacon_interval = wvif->beacon_int;
-	join.channel_number = wvif->channel->hw_value;
-	memcpy(join.bssid, bssid, sizeof(join.bssid));
-
-	if (!conf->ibss_joined) {
-		const u8 *ssidie;
-
-		rcu_read_lock();
+	rcu_read_lock();
+	if (!conf->ibss_joined)
 		ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
-		if (ssidie) {
-			join.ssid_length = ssidie[1];
-			memcpy(join.ssid, &ssidie[2], join.ssid_length);
-		}
-		rcu_read_unlock();
-	}
+	else
+		ssidie = NULL;
 
 	wfx_tx_flush(wvif->wdev);
 
@@ -578,7 +551,9 @@ static void wfx_do_join(struct wfx_vif *wvif)
 
 	/* Perform actual join */
 	wvif->wdev->tx_burst_idx = -1;
-	if (hif_join(wvif, &join)) {
+	ret = hif_join(wvif, conf, wvif->channel, ssidie);
+	rcu_read_unlock();
+	if (ret) {
 		ieee80211_connection_loss(wvif->vif);
 		wvif->join_complete_status = -1;
 		/* Tx lock still held, unjoin will clear it. */
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 30/65] staging: wfx: simplify hif_set_association_mode()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (28 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 29/65] staging: wfx: simplify hif_join() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 31/65] staging: wfx: simplify hif_set_uc_mc_bc_condition() Jérôme Pouiller
                   ` (35 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The structure hif_mib_set_association_mode come from hardware API. It is
not intended to be manipulated in upper layers of the driver.

In add, current code for hif_set_association_mode() is too dumb. It
should pack data with hardware representation instead of leaving all
work to the caller.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx_mib.h | 22 ++++++++++++++++++++--
 drivers/staging/wfx/sta.c        | 16 +---------------
 2 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index 5b39200bd697..eec6f4157e60 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -191,10 +191,28 @@ static inline int hif_set_block_ack_policy(struct wfx_vif *wvif,
 }
 
 static inline int hif_set_association_mode(struct wfx_vif *wvif,
-					   struct hif_mib_set_association_mode *arg)
+					   struct ieee80211_bss_conf *info,
+					   struct ieee80211_sta_ht_cap *ht_cap)
 {
+	int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates);
+	struct hif_mib_set_association_mode val = {
+		.preambtype_use = 1,
+		.mode = 1,
+		.rateset = 1,
+		.spacing = 1,
+		.short_preamble = info->use_short_preamble,
+		.basic_rate_set = cpu_to_le32(basic_rates)
+	};
+
+	// FIXME: it is strange to not retrieve all information from bss_info
+	if (ht_cap && ht_cap->ht_supported) {
+		val.mpdu_start_spacing = ht_cap->ampdu_density;
+		if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
+			val.greenfield = !!(ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD);
+	}
+
 	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_SET_ASSOCIATION_MODE, arg, sizeof(*arg));
+			     HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val));
 }
 
 static inline int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif,
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 30c62e3b3716..9030681858bb 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -712,7 +712,6 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 			      struct ieee80211_bss_conf *info)
 {
 	struct ieee80211_sta *sta = NULL;
-	struct hif_mib_set_association_mode association_mode = { };
 
 	wvif->beacon_int = info->beacon_int;
 	rcu_read_lock();
@@ -730,26 +729,13 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	else
 		hif_dual_cts_protection(wvif, false);
 
-	association_mode.preambtype_use = 1;
-	association_mode.mode = 1;
-	association_mode.rateset = 1;
-	association_mode.spacing = 1;
-	association_mode.short_preamble = info->use_short_preamble;
-	association_mode.basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates));
-	if (sta && sta->ht_cap.ht_supported &&
-	    !(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT))
-		association_mode.greenfield =
-			!!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);
-	if (sta && sta->ht_cap.ht_supported)
-		association_mode.mpdu_start_spacing = sta->ht_cap.ampdu_density;
-
 	wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
 	cancel_work_sync(&wvif->unjoin_work);
 
 	wvif->bss_params.beacon_lost_count = 20;
 	wvif->bss_params.aid = info->aid;
 
-	hif_set_association_mode(wvif, &association_mode);
+	hif_set_association_mode(wvif, info, sta ? &sta->ht_cap : NULL);
 
 	if (!info->ibss_joined) {
 		hif_keep_alive_period(wvif, 30 /* sec */);
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 31/65] staging: wfx: simplify hif_set_uc_mc_bc_condition()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (29 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 30/65] staging: wfx: simplify hif_set_association_mode() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 32/65] staging: wfx: simplify hif_mib_uc_mc_bc_data_frame_condition Jérôme Pouiller
                   ` (34 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The structure hif_mib_uc_mc_bc_data_frame_condition come from hardware
API. It is not intended to be manipulated in upper layers of the driver.

In add, current code for hif_set_uc_mc_bc_condition() is too dumb. It
should pack data with hardware representation instead of leaving all
work to the caller.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx_mib.h | 14 +++++++++++---
 drivers/staging/wfx/sta.c        |  6 +-----
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index eec6f4157e60..4d171e6cfc9a 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -246,12 +246,20 @@ static inline int hif_set_mac_addr_condition(struct wfx_vif *wvif,
 			     arg, sizeof(*arg));
 }
 
-static inline int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif,
-					     struct hif_mib_uc_mc_bc_data_frame_condition *arg)
+// FIXME: use a bitfield instead of 3 boolean values
+static inline int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif, int idx,
+					     bool unic, bool multic, bool broadc)
 {
+	struct hif_mib_uc_mc_bc_data_frame_condition val = {
+		.condition_idx = idx,
+		.param.bits.type_unicast = unic,
+		.param.bits.type_multicast = multic,
+		.param.bits.type_broadcast = broadc,
+	};
+
 	return hif_write_mib(wvif->wdev, wvif->id,
 			     HIF_MIB_ID_UC_MC_BC_DATAFRAME_CONDITION,
-			     arg, sizeof(*arg));
+			     &val, sizeof(val));
 }
 
 static inline int hif_set_config_data_filter(struct wfx_vif *wvif,
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 9030681858bb..79285927c7bf 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -120,7 +120,6 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 	struct hif_mib_config_data_filter config = { };
 	struct hif_mib_set_data_filtering filter_data = { };
 	struct hif_mib_mac_addr_data_frame_condition filter_addr_val = { };
-	struct hif_mib_uc_mc_bc_data_frame_condition filter_addr_type = { };
 
 	// Temporary workaround for filters
 	return hif_set_data_filtering(wvif, &filter_data);
@@ -144,10 +143,7 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 	}
 
 	// Accept unicast and broadcast
-	filter_addr_type.condition_idx = 0;
-	filter_addr_type.param.bits.type_unicast = 1;
-	filter_addr_type.param.bits.type_broadcast = 1;
-	ret = hif_set_uc_mc_bc_condition(wvif, &filter_addr_type);
+	ret = hif_set_uc_mc_bc_condition(wvif, 0, true, false, true);
 	if (ret)
 		return ret;
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 32/65] staging: wfx: simplify hif_mib_uc_mc_bc_data_frame_condition
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (30 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 31/65] staging: wfx: simplify hif_set_uc_mc_bc_condition() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 33/65] staging: wfx: simplify hif_mib_set_data_filtering Jérôme Pouiller
                   ` (33 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The current API defines bitfields. It is not very convenient. Prefer to
use bitmasks.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_api_mib.h | 14 ++++----------
 drivers/staging/wfx/hif_tx_mib.h  |  9 +++------
 drivers/staging/wfx/sta.c         |  4 ++--
 3 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h
index 1603b3074bf7..e0ef0337e01c 100644
--- a/drivers/staging/wfx/hif_api_mib.h
+++ b/drivers/staging/wfx/hif_api_mib.h
@@ -181,19 +181,13 @@ struct hif_mib_ipv6_addr_data_frame_condition {
 	u8    i_pv6_address[HIF_API_IPV6_ADDRESS_SIZE];
 } __packed;
 
-union hif_addr_type {
-	u8 value;
-	struct {
-		u8    type_unicast:1;
-		u8    type_multicast:1;
-		u8    type_broadcast:1;
-		u8    reserved:5;
-	} bits;
-};
+#define HIF_FILTER_UNICAST   0x1
+#define HIF_FILTER_MULTICAST 0x2
+#define HIF_FILTER_BROADCAST 0x4
 
 struct hif_mib_uc_mc_bc_data_frame_condition {
 	u8    condition_idx;
-	union hif_addr_type param;
+	u8    allowed_frames;
 	u8    reserved[2];
 } __packed;
 
diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index 4d171e6cfc9a..6e8b050cbc25 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -246,15 +246,12 @@ static inline int hif_set_mac_addr_condition(struct wfx_vif *wvif,
 			     arg, sizeof(*arg));
 }
 
-// FIXME: use a bitfield instead of 3 boolean values
-static inline int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif, int idx,
-					     bool unic, bool multic, bool broadc)
+static inline int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif,
+					     int idx, u8 allowed_frames)
 {
 	struct hif_mib_uc_mc_bc_data_frame_condition val = {
 		.condition_idx = idx,
-		.param.bits.type_unicast = unic,
-		.param.bits.type_multicast = multic,
-		.param.bits.type_broadcast = broadc,
+		.allowed_frames = allowed_frames,
 	};
 
 	return hif_write_mib(wvif->wdev, wvif->id,
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 79285927c7bf..1c1b5a6c2474 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -142,8 +142,8 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 		config.mac_cond |= 1 << i;
 	}
 
-	// Accept unicast and broadcast
-	ret = hif_set_uc_mc_bc_condition(wvif, 0, true, false, true);
+	ret = hif_set_uc_mc_bc_condition(wvif, 0, HIF_FILTER_UNICAST |
+						  HIF_FILTER_BROADCAST);
 	if (ret)
 		return ret;
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 33/65] staging: wfx: simplify hif_mib_set_data_filtering
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (31 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 32/65] staging: wfx: simplify hif_mib_uc_mc_bc_data_frame_condition Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 34/65] staging: wfx: simplify hif_set_data_filtering() Jérôme Pouiller
                   ` (32 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The field "default_filter" was not obvious.

In add, explicitly declare that fields default_filter and enable are
booleans.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_api_mib.h | 8 +++++---
 drivers/staging/wfx/sta.c         | 3 +--
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/wfx/hif_api_mib.h b/drivers/staging/wfx/hif_api_mib.h
index e0ef0337e01c..0c67cd4c1593 100644
--- a/drivers/staging/wfx/hif_api_mib.h
+++ b/drivers/staging/wfx/hif_api_mib.h
@@ -206,9 +206,11 @@ struct hif_mib_config_data_filter {
 } __packed;
 
 struct hif_mib_set_data_filtering {
-	u8    default_filter;
-	u8    enable;
-	u8    reserved[2];
+	u8    invert_matching:1;
+	u8    reserved1:7;
+	u8    enable:1;
+	u8    reserved2:7;
+	u8    reserved3[2];
 } __packed;
 
 enum hif_arp_ns_frame_treatment {
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 1c1b5a6c2474..27248ea62aea 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -154,9 +154,8 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 	if (ret)
 		return ret;
 
-	// discard all data frames except match filter
 	filter_data.enable = 1;
-	filter_data.default_filter = 1; // discard all
+	filter_data.invert_matching = 1; // discard all but matching frames
 	ret = hif_set_data_filtering(wvif, &filter_data);
 
 	return ret;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 34/65] staging: wfx: simplify hif_set_data_filtering()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (32 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 33/65] staging: wfx: simplify hif_mib_set_data_filtering Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 35/65] staging: wfx: simplify hif_set_mac_addr_condition() Jérôme Pouiller
                   ` (31 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The structure hif_mib_set_data_filtering come from hardware API. It is
not intended to be manipulated in upper layers of the driver.

In add, current code for hif_set_data_filtering() is too dumb. It should
pack data with hardware representation instead of leaving all work to
the caller.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx_mib.h |  9 +++++++--
 drivers/staging/wfx/sta.c        | 13 ++++---------
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index 6e8b050cbc25..ee22c7169fab 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -267,10 +267,15 @@ static inline int hif_set_config_data_filter(struct wfx_vif *wvif,
 }
 
 static inline int hif_set_data_filtering(struct wfx_vif *wvif,
-					 struct hif_mib_set_data_filtering *arg)
+					 bool enable, bool invert)
 {
+	struct hif_mib_set_data_filtering val = {
+		.enable = enable,
+		.invert_matching = invert,
+	};
+
 	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_SET_DATA_FILTERING, arg, sizeof(*arg));
+			     HIF_MIB_ID_SET_DATA_FILTERING, &val, sizeof(val));
 }
 
 static inline int hif_keep_alive_period(struct wfx_vif *wvif, int period)
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 27248ea62aea..588094486a7a 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -118,16 +118,13 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 {
 	int i, ret;
 	struct hif_mib_config_data_filter config = { };
-	struct hif_mib_set_data_filtering filter_data = { };
 	struct hif_mib_mac_addr_data_frame_condition filter_addr_val = { };
 
 	// Temporary workaround for filters
-	return hif_set_data_filtering(wvif, &filter_data);
+	return hif_set_data_filtering(wvif, false, true);
 
-	if (!fp->enable) {
-		filter_data.enable = 0;
-		return hif_set_data_filtering(wvif, &filter_data);
-	}
+	if (!fp->enable)
+		return hif_set_data_filtering(wvif, false, true);
 
 	// A1 Address match on list
 	for (i = 0; i < fp->num_addresses; i++) {
@@ -154,9 +151,7 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 	if (ret)
 		return ret;
 
-	filter_data.enable = 1;
-	filter_data.invert_matching = 1; // discard all but matching frames
-	ret = hif_set_data_filtering(wvif, &filter_data);
+	ret = hif_set_data_filtering(wvif, true, true);
 
 	return ret;
 }
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 35/65] staging: wfx: simplify hif_set_mac_addr_condition()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (33 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 34/65] staging: wfx: simplify hif_set_data_filtering() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 36/65] staging: wfx: simplify hif_set_config_data_filter() Jérôme Pouiller
                   ` (30 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The structure hif_mib_mac_addr_data_frame_condition come from hardware
API. It is not intended to be manipulated in upper layers of the driver.

In add, current code for hif_set_mac_addr_condition() is too dumb. It
should pack data with hardware representation instead of leaving all
work to the caller.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx_mib.h | 10 ++++++++--
 drivers/staging/wfx/sta.c        |  9 +--------
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index ee22c7169fab..90474b1c5ec3 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -239,11 +239,17 @@ static inline int hif_set_tx_rate_retry_policy(struct wfx_vif *wvif,
 }
 
 static inline int hif_set_mac_addr_condition(struct wfx_vif *wvif,
-					     struct hif_mib_mac_addr_data_frame_condition *arg)
+					     int idx, const u8 *mac_addr)
 {
+	struct hif_mib_mac_addr_data_frame_condition val = {
+		.condition_idx = idx,
+		.address_type = HIF_MAC_ADDR_A1,
+	};
+
+	ether_addr_copy(val.mac_address, mac_addr);
 	return hif_write_mib(wvif->wdev, wvif->id,
 			     HIF_MIB_ID_MAC_ADDR_DATAFRAME_CONDITION,
-			     arg, sizeof(*arg));
+			     &val, sizeof(val));
 }
 
 static inline int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif,
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 588094486a7a..b74e0ce41069 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -118,7 +118,6 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 {
 	int i, ret;
 	struct hif_mib_config_data_filter config = { };
-	struct hif_mib_mac_addr_data_frame_condition filter_addr_val = { };
 
 	// Temporary workaround for filters
 	return hif_set_data_filtering(wvif, false, true);
@@ -126,14 +125,8 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 	if (!fp->enable)
 		return hif_set_data_filtering(wvif, false, true);
 
-	// A1 Address match on list
 	for (i = 0; i < fp->num_addresses; i++) {
-		filter_addr_val.condition_idx = i;
-		filter_addr_val.address_type = HIF_MAC_ADDR_A1;
-		ether_addr_copy(filter_addr_val.mac_address,
-				fp->address_list[i]);
-		ret = hif_set_mac_addr_condition(wvif,
-						 &filter_addr_val);
+		ret = hif_set_mac_addr_condition(wvif, i, fp->address_list[i]);
 		if (ret)
 			return ret;
 		config.mac_cond |= 1 << i;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 36/65] staging: wfx: simplify hif_set_config_data_filter()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (34 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 35/65] staging: wfx: simplify hif_set_mac_addr_condition() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 37/65] staging: wfx: simplify wfx_set_mcast_filter() Jérôme Pouiller
                   ` (29 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The structure hif_mib_config_data_filter come from hardware
API. It is not intended to be manipulated in upper layers of the driver.

In add, current code for hif_set_config_data_filter() is too dumb. It
should pack data with hardware representation instead of leaving all
work to the caller.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx_mib.h | 14 +++++++++++---
 drivers/staging/wfx/sta.c        |  8 ++------
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index 90474b1c5ec3..ccea3f15a34d 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -265,11 +265,19 @@ static inline int hif_set_uc_mc_bc_condition(struct wfx_vif *wvif,
 			     &val, sizeof(val));
 }
 
-static inline int hif_set_config_data_filter(struct wfx_vif *wvif,
-					     struct hif_mib_config_data_filter *arg)
+static inline int hif_set_config_data_filter(struct wfx_vif *wvif, bool enable,
+					     int idx, int mac_filters,
+					     int frames_types_filters)
 {
+	struct hif_mib_config_data_filter val = {
+		.enable = enable,
+		.filter_idx = idx,
+		.mac_cond = mac_filters,
+		.uc_mc_bc_cond = frames_types_filters,
+	};
+
 	return hif_write_mib(wvif->wdev, wvif->id,
-			     HIF_MIB_ID_CONFIG_DATA_FILTER, arg, sizeof(*arg));
+			     HIF_MIB_ID_CONFIG_DATA_FILTER, &val, sizeof(val));
 }
 
 static inline int hif_set_data_filtering(struct wfx_vif *wvif,
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index b74e0ce41069..e71b99aa1f63 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -117,7 +117,6 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 				    struct wfx_grp_addr_table *fp)
 {
 	int i, ret;
-	struct hif_mib_config_data_filter config = { };
 
 	// Temporary workaround for filters
 	return hif_set_data_filtering(wvif, false, true);
@@ -129,7 +128,6 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 		ret = hif_set_mac_addr_condition(wvif, i, fp->address_list[i]);
 		if (ret)
 			return ret;
-		config.mac_cond |= 1 << i;
 	}
 
 	ret = hif_set_uc_mc_bc_condition(wvif, 0, HIF_FILTER_UNICAST |
@@ -137,10 +135,8 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 	if (ret)
 		return ret;
 
-	config.uc_mc_bc_cond = 1;
-	config.filter_idx = 0; // TODO #define MULTICAST_FILTERING 0
-	config.enable = 1;
-	ret = hif_set_config_data_filter(wvif, &config);
+	ret = hif_set_config_data_filter(wvif, true, 0, BIT(1),
+					 BIT(fp->num_addresses) - 1);
 	if (ret)
 		return ret;
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 37/65] staging: wfx: simplify wfx_set_mcast_filter()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (35 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 36/65] staging: wfx: simplify hif_set_config_data_filter() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:12 ` [PATCH 38/65] staging: wfx: simplify wfx_update_filtering() Jérôme Pouiller
                   ` (28 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

HIF functions return only serious errors (OOM or device freeze). The
current handling of errors in wfx_set_mcast_filter() does not bring
anything. Finally it may disturb the developer more than it helps.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index e71b99aa1f63..a934f66f3a4c 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -116,7 +116,7 @@ int wfx_fwd_probe_req(struct wfx_vif *wvif, bool enable)
 static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 				    struct wfx_grp_addr_table *fp)
 {
-	int i, ret;
+	int i;
 
 	// Temporary workaround for filters
 	return hif_set_data_filtering(wvif, false, true);
@@ -124,25 +124,15 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 	if (!fp->enable)
 		return hif_set_data_filtering(wvif, false, true);
 
-	for (i = 0; i < fp->num_addresses; i++) {
-		ret = hif_set_mac_addr_condition(wvif, i, fp->address_list[i]);
-		if (ret)
-			return ret;
-	}
-
-	ret = hif_set_uc_mc_bc_condition(wvif, 0, HIF_FILTER_UNICAST |
-						  HIF_FILTER_BROADCAST);
-	if (ret)
-		return ret;
-
-	ret = hif_set_config_data_filter(wvif, true, 0, BIT(1),
-					 BIT(fp->num_addresses) - 1);
-	if (ret)
-		return ret;
-
-	ret = hif_set_data_filtering(wvif, true, true);
-
-	return ret;
+	for (i = 0; i < fp->num_addresses; i++)
+		hif_set_mac_addr_condition(wvif, i, fp->address_list[i]);
+	hif_set_uc_mc_bc_condition(wvif, 0,
+				   HIF_FILTER_UNICAST | HIF_FILTER_BROADCAST);
+	hif_set_config_data_filter(wvif, true, 0, BIT(1),
+				   BIT(fp->num_addresses) - 1);
+	hif_set_data_filtering(wvif, true, true);
+
+	return 0;
 }
 
 void wfx_update_filtering(struct wfx_vif *wvif)
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 38/65] staging: wfx: simplify wfx_update_filtering()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (36 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 37/65] staging: wfx: simplify wfx_set_mcast_filter() Jérôme Pouiller
@ 2020-01-15 12:12 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 39/65] staging: wfx: simplify wfx_scan_complete() Jérôme Pouiller
                   ` (27 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:12 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wfx_update_filtering() has no reason to instantiate a struct
hif_mib_bcn_filter_enable. Drop it and simplify the code.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 31 +++++++++++++------------------
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index a934f66f3a4c..0c3150a94c7c 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -138,10 +138,9 @@ static int wfx_set_mcast_filter(struct wfx_vif *wvif,
 void wfx_update_filtering(struct wfx_vif *wvif)
 {
 	int ret;
-	bool is_sta = wvif->vif && NL80211_IFTYPE_STATION == wvif->vif->type;
-	bool filter_bssid = wvif->filter_bssid;
-	bool fwd_probe_req = wvif->fwd_probe_req;
-	struct hif_mib_bcn_filter_enable bf_ctrl;
+	int bf_enable;
+	int bf_count;
+	int n_filter_ies;
 	struct hif_ie_table_entry filter_ies[] = {
 		{
 			.ie_id        = WLAN_EID_VENDOR_SPECIFIC,
@@ -161,33 +160,29 @@ void wfx_update_filtering(struct wfx_vif *wvif)
 			.has_appeared = 1,
 		}
 	};
-	int n_filter_ies;
 
 	if (wvif->state == WFX_STATE_PASSIVE)
 		return;
 
 	if (wvif->disable_beacon_filter) {
-		bf_ctrl.enable = 0;
-		bf_ctrl.bcn_count = 1;
+		bf_enable = 0;
+		bf_count = 1;
 		n_filter_ies = 0;
-	} else if (!is_sta) {
-		bf_ctrl.enable = HIF_BEACON_FILTER_ENABLE |
-				 HIF_BEACON_FILTER_AUTO_ERP;
-		bf_ctrl.bcn_count = 0;
+	} else if (wvif->vif->type != NL80211_IFTYPE_STATION) {
+		bf_enable = HIF_BEACON_FILTER_ENABLE | HIF_BEACON_FILTER_AUTO_ERP;
+		bf_count = 0;
 		n_filter_ies = 2;
 	} else {
-		bf_ctrl.enable = HIF_BEACON_FILTER_ENABLE;
-		bf_ctrl.bcn_count = 0;
+		bf_enable = HIF_BEACON_FILTER_ENABLE;
+		bf_count = 0;
 		n_filter_ies = 3;
 	}
 
-	ret = hif_set_rx_filter(wvif, filter_bssid, fwd_probe_req);
+	ret = hif_set_rx_filter(wvif, wvif->filter_bssid, wvif->fwd_probe_req);
 	if (!ret)
-		ret = hif_set_beacon_filter_table(wvif, n_filter_ies,
-						  filter_ies);
+		ret = hif_set_beacon_filter_table(wvif, n_filter_ies, filter_ies);
 	if (!ret)
-		ret = hif_beacon_filter_control(wvif, bf_ctrl.enable,
-						bf_ctrl.bcn_count);
+		ret = hif_beacon_filter_control(wvif, bf_enable, bf_count);
 	if (!ret)
 		ret = wfx_set_mcast_filter(wvif, &wvif->mcast_filter);
 	if (ret)
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 39/65] staging: wfx: simplify wfx_scan_complete()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (37 preceding siblings ...)
  2020-01-15 12:12 ` [PATCH 38/65] staging: wfx: simplify wfx_update_filtering() Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 40/65] staging: wfx: update power-save per interface Jérôme Pouiller
                   ` (26 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wfx_scan_complete() do nothing with argument hif_ind_scan_cmpl. In add,
hif_ind_scan_cmpl come from hardware API and is not expected to be used
with upper layers of the driver.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_rx.c | 3 +--
 drivers/staging/wfx/scan.c   | 3 +--
 drivers/staging/wfx/scan.h   | 5 +----
 3 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c
index 408967a4c457..f04afc6db9a5 100644
--- a/drivers/staging/wfx/hif_rx.c
+++ b/drivers/staging/wfx/hif_rx.c
@@ -203,10 +203,9 @@ static int hif_scan_complete_indication(struct wfx_dev *wdev,
 					const void *buf)
 {
 	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
-	const struct hif_ind_scan_cmpl *body = buf;
 
 	WARN_ON(!wvif);
-	wfx_scan_complete(wvif, body);
+	wfx_scan_complete(wvif);
 
 	return 0;
 }
diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c
index 5cc9df5eb6a1..6e1e50048651 100644
--- a/drivers/staging/wfx/scan.c
+++ b/drivers/staging/wfx/scan.c
@@ -127,8 +127,7 @@ void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	hif_stop_scan(wvif);
 }
 
-void wfx_scan_complete(struct wfx_vif *wvif,
-		       const struct hif_ind_scan_cmpl *arg)
+void wfx_scan_complete(struct wfx_vif *wvif)
 {
 	complete(&wvif->scan_complete);
 }
diff --git a/drivers/staging/wfx/scan.h b/drivers/staging/wfx/scan.h
index bba9f15a9ff5..2eb786c9572c 100644
--- a/drivers/staging/wfx/scan.h
+++ b/drivers/staging/wfx/scan.h
@@ -10,8 +10,6 @@
 
 #include <net/mac80211.h>
 
-#include "hif_api_cmd.h"
-
 struct wfx_dev;
 struct wfx_vif;
 
@@ -19,7 +17,6 @@ void wfx_hw_scan_work(struct work_struct *work);
 int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		struct ieee80211_scan_request *req);
 void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
-void wfx_scan_complete(struct wfx_vif *wvif,
-		       const struct hif_ind_scan_cmpl *ind);
+void wfx_scan_complete(struct wfx_vif *wvif);
 
 #endif /* WFX_SCAN_H */
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 40/65] staging: wfx: update power-save per interface
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (38 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 39/65] staging: wfx: simplify wfx_scan_complete() Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 41/65] staging: wfx: with multiple vifs, force PS only if channels differs Jérôme Pouiller
                   ` (25 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

mac80211 and the device are both able to control power-save per vif.
But, the current code retrieve power-save from wfx_config(). So, it does
not allow to setup power-save independently for each vif. Driver just
has to rely on wfx_bss_info_changed() instead of wfx_config().

wfx_config() has nothing to do anymore, but we keep it since it is
mandatory for mac80211.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/main.c |  2 +-
 drivers/staging/wfx/sta.c  | 17 +++++------------
 2 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c
index 1904890c03fe..84adad64fc30 100644
--- a/drivers/staging/wfx/main.c
+++ b/drivers/staging/wfx/main.c
@@ -131,7 +131,7 @@ static const struct ieee80211_ops wfx_ops = {
 	.stop			= wfx_stop,
 	.add_interface		= wfx_add_interface,
 	.remove_interface	= wfx_remove_interface,
-	.config			= wfx_config,
+	.config                 = wfx_config,
 	.tx			= wfx_tx,
 	.conf_tx		= wfx_conf_tx,
 	.hw_scan		= wfx_hw_scan,
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 0c3150a94c7c..94683a1440c8 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -826,6 +826,10 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 
 	if (changed & BSS_CHANGED_TXPOWER)
 		hif_set_output_power(wvif, info->txpower);
+
+	if (changed & BSS_CHANGED_PS)
+		wfx_update_pm(wvif);
+
 	mutex_unlock(&wdev->conf_mutex);
 
 	if (do_join)
@@ -1058,18 +1062,7 @@ void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw,
 
 int wfx_config(struct ieee80211_hw *hw, u32 changed)
 {
-	int ret = 0;
-	struct wfx_dev *wdev = hw->priv;
-	struct wfx_vif *wvif;
-
-	if (changed & IEEE80211_CONF_CHANGE_PS) {
-		mutex_lock(&wdev->conf_mutex);
-		wvif = NULL;
-		while ((wvif = wvif_iterate(wdev, wvif)) != NULL)
-			ret = wfx_update_pm(wvif);
-		mutex_unlock(&wdev->conf_mutex);
-	}
-	return ret;
+	return 0;
 }
 
 int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 41/65] staging: wfx: with multiple vifs, force PS only if channels differs
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (39 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 40/65] staging: wfx: update power-save per interface Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 42/65] staging: wfx: do not update uapsd if not necessary Jérôme Pouiller
                   ` (24 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

When multiple vif are in use (the only supported configuration is one
station and one AP), the driver force power save flag on station.
This behavior allows the station to leave the station channel and make
its business on AP channel.

However, this has a big impact on station performances (especially since
only legacy PS is supported).

When both vifs use the same channel, it is not necessary to keep this
restriction. This greatly improve station performances.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 94683a1440c8..bf285389c303 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -251,6 +251,7 @@ static int wfx_update_pm(struct wfx_vif *wvif)
 	struct ieee80211_conf *conf = &wvif->wdev->hw->conf;
 	bool ps = conf->flags & IEEE80211_CONF_PS;
 	int ps_timeout = conf->dynamic_ps_timeout;
+	struct ieee80211_channel *chan0 = NULL, *chan1 = NULL;
 
 	WARN_ON(conf->dynamic_ps_timeout < 0);
 	if (wvif->state != WFX_STATE_STA || !wvif->bss_params.aid)
@@ -260,10 +261,15 @@ static int wfx_update_pm(struct wfx_vif *wvif)
 	if (wvif->uapsd_mask)
 		ps_timeout = 0;
 
-	// Kernel disable PowerSave when multiple vifs are in use. In contrary,
-	// it is absolutly necessary to enable PowerSave for WF200
-	// FIXME: only if channel vif0 != channel vif1
-	if (wvif_count(wvif->wdev) > 1) {
+	// Kernel disable powersave when an AP is in use. In contrary, it is
+	// absolutely necessary to enable legacy powersave for WF200 if channels
+	// are differents.
+	if (wdev_to_wvif(wvif->wdev, 0))
+		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) {
 		ps = true;
 		ps_timeout = 0;
 	}
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 42/65] staging: wfx: do not update uapsd if not necessary
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (40 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 41/65] staging: wfx: with multiple vifs, force PS only if channels differs Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 43/65] staging: wfx: fix case where RTS threshold is 0 Jérôme Pouiller
                   ` (23 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wfx_conf_tx() is called for each queue. On every call, the function
updates UAPSD mask and PM mode for all queues. It is a pity since the
UAPSD configuration very rarely changes and it makes exchanges between
the host and the chip more difficult to track.

This patch avoid to update UAPSD and Power Mode in most usual cases.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index bf285389c303..6a43decd5ae6 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -286,6 +286,7 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 {
 	struct wfx_dev *wdev = hw->priv;
 	struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
+	int old_uapsd = wvif->uapsd_mask;
 	int ret = 0;
 
 	WARN_ON(queue >= hw->queues);
@@ -294,7 +295,8 @@ int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	assign_bit(queue, &wvif->uapsd_mask, params->uapsd);
 	memcpy(&wvif->edca_params[queue], params, sizeof(*params));
 	hif_set_edca_queue_params(wvif, queue, params);
-	if (wvif->vif->type == NL80211_IFTYPE_STATION) {
+	if (wvif->vif->type == NL80211_IFTYPE_STATION &&
+	    old_uapsd != wvif->uapsd_mask) {
 		hif_set_uapsd_info(wvif, wvif->uapsd_mask);
 		wfx_update_pm(wvif);
 	}
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 43/65] staging: wfx: fix case where RTS threshold is 0
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (41 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 42/65] staging: wfx: do not update uapsd if not necessary Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 44/65] staging: wfx: fix possible overflow on jiffies comparaison Jérôme Pouiller
                   ` (22 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

If RTS threshold is 0, it currently disables RTS. It should mean
"enabled for every frames".

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_tx_mib.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/wfx/hif_tx_mib.h b/drivers/staging/wfx/hif_tx_mib.h
index ccea3f15a34d..bf3769c2a9b6 100644
--- a/drivers/staging/wfx/hif_tx_mib.h
+++ b/drivers/staging/wfx/hif_tx_mib.h
@@ -391,7 +391,7 @@ static inline int hif_wep_default_key_id(struct wfx_vif *wvif, int val)
 static inline int hif_rts_threshold(struct wfx_vif *wvif, int val)
 {
 	struct hif_mib_dot11_rts_threshold arg = {
-		.threshold = cpu_to_le32(val > 0 ? val : 0xFFFF),
+		.threshold = cpu_to_le32(val >= 0 ? val : 0xFFFF),
 	};
 
 	return hif_write_mib(wvif->wdev, wvif->id,
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 44/65] staging: wfx: fix possible overflow on jiffies comparaison
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (42 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 43/65] staging: wfx: fix case where RTS threshold is 0 Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 45/65] staging: wfx: remove handling of "early_data" Jérôme Pouiller
                   ` (21 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

It is recommended to use function time_*() to compare jiffies.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_tx.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index 60459299a3a9..704ebfe1cd05 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -270,8 +270,7 @@ void wfx_tx_policy_init(struct wfx_vif *wvif)
 static int wfx_alloc_link_id(struct wfx_vif *wvif, const u8 *mac)
 {
 	int i, ret = 0;
-	unsigned long max_inactivity = 0;
-	unsigned long now = jiffies;
+	unsigned long oldest;
 
 	spin_lock_bh(&wvif->ps_state_lock);
 	for (i = 0; i < WFX_MAX_STA_IN_AP_MODE; ++i) {
@@ -280,13 +279,10 @@ static int wfx_alloc_link_id(struct wfx_vif *wvif, const u8 *mac)
 			break;
 		} else if (wvif->link_id_db[i].status != WFX_LINK_HARD &&
 			   !wvif->wdev->tx_queue_stats.link_map_cache[i + 1]) {
-			unsigned long inactivity =
-				now - wvif->link_id_db[i].timestamp;
-
-			if (inactivity < max_inactivity)
-				continue;
-			max_inactivity = inactivity;
-			ret = i + 1;
+			if (!ret || time_after(oldest, wvif->link_id_db[i].timestamp)) {
+				oldest = wvif->link_id_db[i].timestamp;
+				ret = i + 1;
+			}
 		}
 	}
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 45/65] staging: wfx: remove handling of "early_data"
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (43 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 44/65] staging: wfx: fix possible overflow on jiffies comparaison Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 46/65] staging: wfx: relocate "buffered" information to sta_priv Jérôme Pouiller
                   ` (20 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

It seems that purpose of "early_data" was to prevent sending data to
mac80211 before station was completely associated. It is a useless
precaution.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_rx.c | 17 +----------------
 drivers/staging/wfx/data_tx.c |  3 ---
 drivers/staging/wfx/data_tx.h |  1 -
 drivers/staging/wfx/sta.c     |  3 ---
 4 files changed, 1 insertion(+), 23 deletions(-)

diff --git a/drivers/staging/wfx/data_rx.c b/drivers/staging/wfx/data_rx.c
index 0ab71c911f84..e26bc665b2b3 100644
--- a/drivers/staging/wfx/data_rx.c
+++ b/drivers/staging/wfx/data_rx.c
@@ -108,7 +108,6 @@ void wfx_rx_cb(struct wfx_vif *wvif,
 	struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
 	struct wfx_link_entry *entry = NULL;
-	bool early_data = false;
 
 	memset(hdr, 0, sizeof(*hdr));
 
@@ -121,9 +120,6 @@ void wfx_rx_cb(struct wfx_vif *wvif,
 	if (link_id && link_id <= WFX_MAX_STA_IN_AP_MODE) {
 		entry = &wvif->link_id_db[link_id - 1];
 		entry->timestamp = jiffies;
-		if (entry->status == WFX_LINK_SOFT &&
-		    ieee80211_is_data(frame->frame_control))
-			early_data = true;
 	}
 
 	if (arg->status == HIF_STATUS_MICFAILURE)
@@ -181,18 +177,7 @@ void wfx_rx_cb(struct wfx_vif *wvif,
 			schedule_work(&wvif->update_filtering_work);
 		}
 	}
-
-	if (early_data) {
-		spin_lock_bh(&wvif->ps_state_lock);
-		/* Double-check status with lock held */
-		if (entry->status == WFX_LINK_SOFT)
-			skb_queue_tail(&entry->rx_queue, skb);
-		else
-			ieee80211_rx_irqsafe(wvif->wdev->hw, skb);
-		spin_unlock_bh(&wvif->ps_state_lock);
-	} else {
-		ieee80211_rx_irqsafe(wvif->wdev->hw, skb);
-	}
+	ieee80211_rx_irqsafe(wvif->wdev->hw, skb);
 
 	return;
 
diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index 704ebfe1cd05..e669fc4485e6 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -292,7 +292,6 @@ static int wfx_alloc_link_id(struct wfx_vif *wvif, const u8 *mac)
 		entry->status = WFX_LINK_RESERVE;
 		ether_addr_copy(entry->mac, mac);
 		memset(&entry->buffered, 0, WFX_MAX_TID);
-		skb_queue_head_init(&entry->rx_queue);
 		wfx_tx_lock(wvif->wdev);
 
 		if (!schedule_work(&wvif->link_id_work))
@@ -400,8 +399,6 @@ void wfx_link_id_gc_work(struct work_struct *work)
 				next_gc = min_t(unsigned long, next_gc, ttl);
 			}
 		}
-		if (need_reset)
-			skb_queue_purge(&wvif->link_id_db[i].rx_queue);
 	}
 	spin_unlock_bh(&wvif->ps_state_lock);
 	if (next_gc != -1)
diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h
index 078d0cfc521a..54738c2e3eac 100644
--- a/drivers/staging/wfx/data_tx.h
+++ b/drivers/staging/wfx/data_tx.h
@@ -34,7 +34,6 @@ struct wfx_link_entry {
 	u8			mac[ETH_ALEN];
 	u8			old_mac[ETH_ALEN];
 	u8			buffered[WFX_MAX_TID];
-	struct sk_buff_head	rx_queue;
 };
 
 struct tx_policy {
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 6a43decd5ae6..4a44d72f0db1 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -571,7 +571,6 @@ int wfx_sta_add(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;
 	struct wfx_link_entry *entry;
-	struct sk_buff *skb;
 
 	if (wvif->vif->type != NL80211_IFTYPE_AP)
 		return 0;
@@ -589,8 +588,6 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 					IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
 		wvif->sta_asleep_mask |= BIT(sta_priv->link_id);
 	entry->status = WFX_LINK_HARD;
-	while ((skb = skb_dequeue(&entry->rx_queue)))
-		ieee80211_rx_irqsafe(wdev->hw, skb);
 	spin_unlock_bh(&wvif->ps_state_lock);
 	return 0;
 }
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 46/65] staging: wfx: relocate "buffered" information to sta_priv
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (44 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 45/65] staging: wfx: remove handling of "early_data" Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 47/65] staging: wfx: fix bss_loss Jérôme Pouiller
                   ` (19 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

It simplify the code if field buffered is hosted in the struct sta_priv
instead of in the struct wfx_link_entry. More globally, struct
wfx_link_entry has no real reasons to exist and should be dropped soon.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_tx.c | 50 ++++++++++++++++-------------------
 drivers/staging/wfx/data_tx.h |  4 ---
 drivers/staging/wfx/sta.c     |  1 +
 drivers/staging/wfx/sta.h     |  6 +++++
 4 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index e669fc4485e6..9313c8f5d4d8 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -291,7 +291,6 @@ static int wfx_alloc_link_id(struct wfx_vif *wvif, const u8 *mac)
 
 		entry->status = WFX_LINK_RESERVE;
 		ether_addr_copy(entry->mac, mac);
-		memset(&entry->buffered, 0, WFX_MAX_TID);
 		wfx_tx_lock(wvif->wdev);
 
 		if (!schedule_work(&wvif->link_id_work))
@@ -434,6 +433,7 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
 			     struct ieee80211_sta *sta)
 {
 	u32 mask = ~BIT(tx_priv->raw_link_id);
+	struct wfx_sta_priv *sta_priv;
 
 	spin_lock_bh(&wvif->ps_state_lock);
 	if (ieee80211_is_auth(hdr->frame_control)) {
@@ -448,15 +448,17 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
 			schedule_work(&wvif->mcast_start_work);
 	}
 
-	if (tx_priv->raw_link_id) {
+	if (tx_priv->raw_link_id)
 		wvif->link_id_db[tx_priv->raw_link_id - 1].timestamp = jiffies;
-		if (tx_priv->tid < WFX_MAX_TID)
-			wvif->link_id_db[tx_priv->raw_link_id - 1].buffered[tx_priv->tid]++;
-	}
 	spin_unlock_bh(&wvif->ps_state_lock);
 
-	if (sta)
+	if (sta && tx_priv->tid < WFX_MAX_TID) {
+		sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
+		spin_lock_bh(&sta_priv->lock);
+		sta_priv->buffered[tx_priv->tid]++;
 		ieee80211_sta_set_buffered(sta, tx_priv->tid, true);
+		spin_unlock_bh(&sta_priv->lock);
+	}
 }
 
 static u8 wfx_tx_get_raw_link_id(struct wfx_vif *wvif,
@@ -789,31 +791,25 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg)
 	wfx_pending_remove(wvif->wdev, skb);
 }
 
-static void wfx_notify_buffered_tx(struct wfx_vif *wvif, struct sk_buff *skb,
-				   struct hif_req_tx *req)
+static void wfx_notify_buffered_tx(struct wfx_vif *wvif, struct sk_buff *skb)
 {
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_sta *sta;
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct wfx_sta_priv *sta_priv;
 	int tid = wfx_tx_get_tid(hdr);
-	int raw_link_id = req->queue_id.peer_sta_id;
-	u8 *buffered;
 
-	if (raw_link_id && tid < WFX_MAX_TID) {
-		buffered = wvif->link_id_db[raw_link_id - 1].buffered;
-
-		spin_lock_bh(&wvif->ps_state_lock);
-		WARN(!buffered[tid], "inconsistent notification");
-		buffered[tid]--;
-		spin_unlock_bh(&wvif->ps_state_lock);
-
-		if (!buffered[tid]) {
-			rcu_read_lock();
-			sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
-			if (sta)
-				ieee80211_sta_set_buffered(sta, tid, false);
-			rcu_read_unlock();
-		}
+	rcu_read_lock(); // protect sta
+	sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
+	if (sta && tid < WFX_MAX_TID) {
+		sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
+		spin_lock_bh(&sta_priv->lock);
+		WARN(!sta_priv->buffered[tid], "inconsistent notification");
+		sta_priv->buffered[tid]--;
+		if (!sta_priv->buffered[tid])
+			ieee80211_sta_set_buffered(sta, tid, false);
+		spin_unlock_bh(&sta_priv->lock);
 	}
+	rcu_read_unlock();
 }
 
 void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb)
@@ -827,7 +823,7 @@ void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb)
 
 	WARN_ON(!wvif);
 	skb_pull(skb, offset);
-	wfx_notify_buffered_tx(wvif, skb, req);
+	wfx_notify_buffered_tx(wvif, skb);
 	wfx_tx_policy_put(wvif, req->tx_flags.retry_policy_index);
 	ieee80211_tx_status_irqsafe(wdev->hw, skb);
 }
diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h
index 54738c2e3eac..d02a7b325b27 100644
--- a/drivers/staging/wfx/data_tx.h
+++ b/drivers/staging/wfx/data_tx.h
@@ -14,9 +14,6 @@
 #include "hif_api_cmd.h"
 #include "hif_api_mib.h"
 
-// FIXME: use IEEE80211_NUM_TIDS
-#define WFX_MAX_TID               8
-
 struct wfx_tx_priv;
 struct wfx_dev;
 struct wfx_vif;
@@ -33,7 +30,6 @@ struct wfx_link_entry {
 	enum wfx_link_status	status;
 	u8			mac[ETH_ALEN];
 	u8			old_mac[ETH_ALEN];
-	u8			buffered[WFX_MAX_TID];
 };
 
 struct tx_policy {
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 4a44d72f0db1..aebce96dcd4a 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -572,6 +572,7 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
 	struct wfx_link_entry *entry;
 
+	spin_lock_init(&sta_priv->lock);
 	if (wvif->vif->type != NL80211_IFTYPE_AP)
 		return 0;
 
diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h
index e0b54332e98a..47d94d6b8590 100644
--- a/drivers/staging/wfx/sta.h
+++ b/drivers/staging/wfx/sta.h
@@ -12,6 +12,9 @@
 
 #include "hif_api_cmd.h"
 
+// FIXME: use IEEE80211_NUM_TIDS
+#define WFX_MAX_TID               8
+
 struct wfx_dev;
 struct wfx_vif;
 
@@ -37,6 +40,9 @@ struct wfx_grp_addr_table {
 struct wfx_sta_priv {
 	int link_id;
 	int vif_id;
+	u8 buffered[WFX_MAX_TID];
+	// Ensure atomicity of "buffered" and calls to ieee80211_sta_set_buffered()
+	spinlock_t lock;
 };
 
 // mac80211 interface
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 47/65] staging: wfx: fix bss_loss
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (45 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 46/65] staging: wfx: relocate "buffered" information to sta_priv Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 48/65] staging: wfx: fix RCU usage Jérôme Pouiller
                   ` (18 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wfx_tx_confirm_cb()  retrieves the station associated with a frame using
the MAC address from the 802.11 header. In the other side wfx_tx()
retrieves the station using sta field from the ieee80211_tx_control
argument.

In wfx_cqm_bssloss_sm(), wfx_tx() was called directly without valid sta
field, but with a valid MAC address in 802.11 header. So there the
processing of this packet was unbalanced and may produce weird bugs.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index aebce96dcd4a..80a2a9e8256f 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -88,19 +88,25 @@ void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad)
 	// FIXME: call ieee80211_beacon_loss/ieee80211_connection_loss instead
 	if (tx) {
 		struct sk_buff *skb;
+		struct ieee80211_hdr *hdr
+		struct ieee80211_tx_control control = { };
 
 		wvif->bss_loss_state++;
 
 		skb = ieee80211_nullfunc_get(wvif->wdev->hw, wvif->vif, false);
 		if (!skb)
 			goto end;
+		hdr = (struct ieee80211_hdr *)skb->data;
 		memset(IEEE80211_SKB_CB(skb), 0,
 		       sizeof(*IEEE80211_SKB_CB(skb)));
 		IEEE80211_SKB_CB(skb)->control.vif = wvif->vif;
 		IEEE80211_SKB_CB(skb)->driver_rates[0].idx = 0;
 		IEEE80211_SKB_CB(skb)->driver_rates[0].count = 1;
 		IEEE80211_SKB_CB(skb)->driver_rates[1].idx = -1;
-		wfx_tx(wvif->wdev->hw, NULL, skb);
+		rcu_read_lock(); // protect control.sta
+		control.sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
+		wfx_tx(wvif->wdev->hw, &control, skb);
+		rcu_read_unlock();
 	}
 end:
 	mutex_unlock(&wvif->bss_loss_lock);
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 48/65] staging: wfx: fix RCU usage
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (46 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 47/65] staging: wfx: fix bss_loss Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 49/65] staging: wfx: simplify wfx_set_tim_impl() Jérôme Pouiller
                   ` (17 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Indeed, sta was used after call to rcu_unlock()

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 80a2a9e8256f..d50b583af187 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -690,10 +690,9 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	struct ieee80211_sta *sta = NULL;
 
 	wvif->beacon_int = info->beacon_int;
-	rcu_read_lock();
+	rcu_read_lock(); // protect sta
 	if (info->bssid && !info->ibss_joined)
 		sta = ieee80211_find_sta(wvif->vif, info->bssid);
-	rcu_read_unlock();
 	if (sta)
 		wvif->bss_params.operational_rate_set =
 			wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]);
@@ -712,6 +711,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif,
 	wvif->bss_params.aid = info->aid;
 
 	hif_set_association_mode(wvif, info, sta ? &sta->ht_cap : NULL);
+	rcu_read_unlock();
 
 	if (!info->ibss_joined) {
 		hif_keep_alive_period(wvif, 30 /* sec */);
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 49/65] staging: wfx: simplify wfx_set_tim_impl()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (47 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 48/65] staging: wfx: fix RCU usage Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 50/65] staging: wfx: simplify the link-id allocation Jérôme Pouiller
                   ` (16 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Argument provided to wfx_set_tim_impl() is always wvif->aid0_bit_set and
there is no reason to provide another argument.

Also rename wfx_set_tim_impl() into wfx_update_tim() to reflect the new
behavior.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 18 +++++++++---------
 drivers/staging/wfx/wfx.h |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index d50b583af187..47271b7eeaab 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -895,7 +895,7 @@ void wfx_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	wfx_ps_notify(wvif, notify_cmd, sta_priv->link_id);
 }
 
-static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
+static int wfx_update_tim(struct wfx_vif *wvif)
 {
 	struct sk_buff *skb;
 	u16 tim_offset, tim_length;
@@ -916,7 +916,7 @@ static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
 		tim_ptr[2] = 0;
 
 		/* Set/reset aid0 bit */
-		if (aid0_bit_set)
+		if (wvif->aid0_bit_set)
 			tim_ptr[4] |= 1;
 		else
 			tim_ptr[4] &= ~1;
@@ -928,11 +928,11 @@ static int wfx_set_tim_impl(struct wfx_vif *wvif, bool aid0_bit_set)
 	return 0;
 }
 
-static void wfx_set_tim_work(struct work_struct *work)
+static void wfx_update_tim_work(struct work_struct *work)
 {
-	struct wfx_vif *wvif = container_of(work, struct wfx_vif, set_tim_work);
+	struct wfx_vif *wvif = container_of(work, struct wfx_vif, update_tim_work);
 
-	wfx_set_tim_impl(wvif, wvif->aid0_bit_set);
+	wfx_update_tim(wvif);
 }
 
 int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
@@ -941,7 +941,7 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
 	struct wfx_sta_priv *sta_dev = (struct wfx_sta_priv *) &sta->drv_priv;
 	struct wfx_vif *wvif = wdev_to_wvif(wdev, sta_dev->vif_id);
 
-	schedule_work(&wvif->set_tim_work);
+	schedule_work(&wvif->update_tim_work);
 	return 0;
 }
 
@@ -955,8 +955,8 @@ static void wfx_mcast_start_work(struct work_struct *work)
 	cancel_work_sync(&wvif->mcast_stop_work);
 	if (!wvif->aid0_bit_set) {
 		wfx_tx_lock_flush(wvif->wdev);
-		wfx_set_tim_impl(wvif, true);
 		wvif->aid0_bit_set = true;
+		wfx_update_tim(wvif);
 		mod_timer(&wvif->mcast_timeout, jiffies + tmo);
 		wfx_tx_unlock(wvif->wdev);
 	}
@@ -971,7 +971,7 @@ static void wfx_mcast_stop_work(struct work_struct *work)
 		del_timer_sync(&wvif->mcast_timeout);
 		wfx_tx_lock_flush(wvif->wdev);
 		wvif->aid0_bit_set = false;
-		wfx_set_tim_impl(wvif, false);
+		wfx_update_tim(wvif);
 		wfx_tx_unlock(wvif->wdev);
 	}
 }
@@ -1118,7 +1118,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	INIT_DELAYED_WORK(&wvif->link_id_gc_work, wfx_link_id_gc_work);
 
 	spin_lock_init(&wvif->ps_state_lock);
-	INIT_WORK(&wvif->set_tim_work, wfx_set_tim_work);
+	INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work);
 
 	INIT_WORK(&wvif->mcast_start_work, wfx_mcast_start_work);
 	INIT_WORK(&wvif->mcast_stop_work, wfx_mcast_stop_work);
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index f56a91ea082d..cb359150e2ad 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -96,7 +96,7 @@ struct wfx_vif {
 	u32			sta_asleep_mask;
 	u32			pspoll_mask;
 	spinlock_t		ps_state_lock;
-	struct work_struct	set_tim_work;
+	struct work_struct	update_tim_work;
 
 	int			beacon_int;
 	bool			filter_bssid;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 50/65] staging: wfx: simplify the link-id allocation
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (48 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 49/65] staging: wfx: simplify wfx_set_tim_impl() Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 51/65] staging: wfx: check that no tx is pending before release sta Jérôme Pouiller
                   ` (15 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The "link-id" is a slot number provided to the chip. A link-id is
allocated to every station associated with the chip (mainly when the
chip is in AP mode). It is more or less the same thing than the
association ID, but it is limited to 14 values.

Firmware uses the link-id to track the power save status of the
stations.

The current code try to associate a link-id as soon as data are
exchanged with station. It is far easier to rely on sta_add() and
sta_remove().

Until now the value WFX_LINK_ID_NO_ASSOC, was only used when no more
link-id was available. Now, we also use this value for
not-yet-associated stations (that was its primary behavior).

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_rx.c |   7 --
 drivers/staging/wfx/data_tx.c | 164 +---------------------------------
 drivers/staging/wfx/data_tx.h |  19 ----
 drivers/staging/wfx/queue.c   |   7 +-
 drivers/staging/wfx/queue.h   |   7 +-
 drivers/staging/wfx/sta.c     |  58 ++++--------
 drivers/staging/wfx/wfx.h     |   3 -
 7 files changed, 24 insertions(+), 241 deletions(-)

diff --git a/drivers/staging/wfx/data_rx.c b/drivers/staging/wfx/data_rx.c
index e26bc665b2b3..699e2d60fa89 100644
--- a/drivers/staging/wfx/data_rx.c
+++ b/drivers/staging/wfx/data_rx.c
@@ -103,11 +103,9 @@ static int wfx_drop_encrypt_data(struct wfx_dev *wdev,
 void wfx_rx_cb(struct wfx_vif *wvif,
 	       const struct hif_ind_rx *arg, struct sk_buff *skb)
 {
-	int link_id = arg->rx_flags.peer_sta_id;
 	struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb);
 	struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-	struct wfx_link_entry *entry = NULL;
 
 	memset(hdr, 0, sizeof(*hdr));
 
@@ -117,11 +115,6 @@ void wfx_rx_cb(struct wfx_vif *wvif,
 	     ieee80211_is_beacon(frame->frame_control)))
 		goto drop;
 
-	if (link_id && link_id <= WFX_MAX_STA_IN_AP_MODE) {
-		entry = &wvif->link_id_db[link_id - 1];
-		entry->timestamp = jiffies;
-	}
-
 	if (arg->status == HIF_STATUS_MICFAILURE)
 		hdr->flag |= RX_FLAG_MMIC_ERROR;
 	else if (arg->status)
diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index 9313c8f5d4d8..8c9f986ec672 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -17,7 +17,6 @@
 #include "hif_tx_mib.h"
 
 #define WFX_INVALID_RATE_ID    15
-#define WFX_LINK_ID_NO_ASSOC   15
 #define WFX_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ))
 
 static int wfx_get_hw_rate(struct wfx_dev *wdev,
@@ -265,156 +264,6 @@ void wfx_tx_policy_init(struct wfx_vif *wvif)
 		list_add(&cache->cache[i].link, &cache->free);
 }
 
-/* Link ID related functions */
-
-static int wfx_alloc_link_id(struct wfx_vif *wvif, const u8 *mac)
-{
-	int i, ret = 0;
-	unsigned long oldest;
-
-	spin_lock_bh(&wvif->ps_state_lock);
-	for (i = 0; i < WFX_MAX_STA_IN_AP_MODE; ++i) {
-		if (!wvif->link_id_db[i].status) {
-			ret = i + 1;
-			break;
-		} else if (wvif->link_id_db[i].status != WFX_LINK_HARD &&
-			   !wvif->wdev->tx_queue_stats.link_map_cache[i + 1]) {
-			if (!ret || time_after(oldest, wvif->link_id_db[i].timestamp)) {
-				oldest = wvif->link_id_db[i].timestamp;
-				ret = i + 1;
-			}
-		}
-	}
-
-	if (ret) {
-		struct wfx_link_entry *entry = &wvif->link_id_db[ret - 1];
-
-		entry->status = WFX_LINK_RESERVE;
-		ether_addr_copy(entry->mac, mac);
-		wfx_tx_lock(wvif->wdev);
-
-		if (!schedule_work(&wvif->link_id_work))
-			wfx_tx_unlock(wvif->wdev);
-	} else {
-		dev_info(wvif->wdev->dev, "no more link-id available\n");
-	}
-	spin_unlock_bh(&wvif->ps_state_lock);
-	return ret;
-}
-
-int wfx_find_link_id(struct wfx_vif *wvif, const u8 *mac)
-{
-	int i, ret = 0;
-
-	spin_lock_bh(&wvif->ps_state_lock);
-	for (i = 0; i < WFX_MAX_STA_IN_AP_MODE; ++i) {
-		if (ether_addr_equal(mac, wvif->link_id_db[i].mac) &&
-		    wvif->link_id_db[i].status) {
-			wvif->link_id_db[i].timestamp = jiffies;
-			ret = i + 1;
-			break;
-		}
-	}
-	spin_unlock_bh(&wvif->ps_state_lock);
-	return ret;
-}
-
-static int wfx_map_link(struct wfx_vif *wvif,
-			struct wfx_link_entry *link_entry, int sta_id)
-{
-	int ret;
-
-	ret = hif_map_link(wvif, link_entry->mac, 0, sta_id);
-
-	if (ret == 0)
-		/* Save the MAC address currently associated with the peer
-		 * for future unmap request
-		 */
-		ether_addr_copy(link_entry->old_mac, link_entry->mac);
-
-	return ret;
-}
-
-int wfx_unmap_link(struct wfx_vif *wvif, int sta_id)
-{
-	u8 *mac_addr = NULL;
-
-	if (sta_id)
-		mac_addr = wvif->link_id_db[sta_id - 1].old_mac;
-
-	return hif_map_link(wvif, mac_addr, 1, sta_id);
-}
-
-void wfx_link_id_gc_work(struct work_struct *work)
-{
-	struct wfx_vif *wvif =
-		container_of(work, struct wfx_vif, link_id_gc_work.work);
-	unsigned long now = jiffies;
-	unsigned long next_gc = -1;
-	long ttl;
-	u32 mask;
-	int i;
-
-	if (wvif->state != WFX_STATE_AP)
-		return;
-
-	wfx_tx_lock_flush(wvif->wdev);
-	spin_lock_bh(&wvif->ps_state_lock);
-	for (i = 0; i < WFX_MAX_STA_IN_AP_MODE; ++i) {
-		bool need_reset = false;
-
-		mask = BIT(i + 1);
-		if (wvif->link_id_db[i].status == WFX_LINK_RESERVE ||
-		    (wvif->link_id_db[i].status == WFX_LINK_HARD &&
-		     !(wvif->link_id_map & mask))) {
-			if (wvif->link_id_map & mask) {
-				wvif->sta_asleep_mask &= ~mask;
-				wvif->pspoll_mask &= ~mask;
-				need_reset = true;
-			}
-			wvif->link_id_map |= mask;
-			if (wvif->link_id_db[i].status != WFX_LINK_HARD)
-				wvif->link_id_db[i].status = WFX_LINK_SOFT;
-
-			spin_unlock_bh(&wvif->ps_state_lock);
-			if (need_reset)
-				wfx_unmap_link(wvif, i + 1);
-			wfx_map_link(wvif, &wvif->link_id_db[i], i + 1);
-			next_gc = min(next_gc, WFX_LINK_ID_GC_TIMEOUT);
-			spin_lock_bh(&wvif->ps_state_lock);
-		} else if (wvif->link_id_db[i].status == WFX_LINK_SOFT) {
-			ttl = wvif->link_id_db[i].timestamp - now +
-					WFX_LINK_ID_GC_TIMEOUT;
-			if (ttl <= 0) {
-				need_reset = true;
-				wvif->link_id_db[i].status = WFX_LINK_OFF;
-				wvif->link_id_map &= ~mask;
-				wvif->sta_asleep_mask &= ~mask;
-				wvif->pspoll_mask &= ~mask;
-				spin_unlock_bh(&wvif->ps_state_lock);
-				wfx_unmap_link(wvif, i + 1);
-				spin_lock_bh(&wvif->ps_state_lock);
-			} else {
-				next_gc = min_t(unsigned long, next_gc, ttl);
-			}
-		}
-	}
-	spin_unlock_bh(&wvif->ps_state_lock);
-	if (next_gc != -1)
-		schedule_delayed_work(&wvif->link_id_gc_work, next_gc);
-	wfx_tx_unlock(wvif->wdev);
-}
-
-void wfx_link_id_work(struct work_struct *work)
-{
-	struct wfx_vif *wvif =
-		container_of(work, struct wfx_vif, link_id_work);
-
-	wfx_tx_flush(wvif->wdev);
-	wfx_link_id_gc_work(&wvif->link_id_gc_work.work);
-	wfx_tx_unlock(wvif->wdev);
-}
-
 /* Tx implementation */
 
 static bool ieee80211_is_action_back(struct ieee80211_hdr *hdr)
@@ -447,9 +296,6 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
 		if (wvif->sta_asleep_mask)
 			schedule_work(&wvif->mcast_start_work);
 	}
-
-	if (tx_priv->raw_link_id)
-		wvif->link_id_db[tx_priv->raw_link_id - 1].timestamp = jiffies;
 	spin_unlock_bh(&wvif->ps_state_lock);
 
 	if (sta && tx_priv->tid < WFX_MAX_TID) {
@@ -468,7 +314,6 @@ static u8 wfx_tx_get_raw_link_id(struct wfx_vif *wvif,
 	struct wfx_sta_priv *sta_priv =
 		sta ? (struct wfx_sta_priv *) &sta->drv_priv : NULL;
 	const u8 *da = ieee80211_get_DA(hdr);
-	int ret;
 
 	if (sta_priv && sta_priv->link_id)
 		return sta_priv->link_id;
@@ -476,14 +321,7 @@ static u8 wfx_tx_get_raw_link_id(struct wfx_vif *wvif,
 		return 0;
 	if (is_multicast_ether_addr(da))
 		return 0;
-	ret = wfx_find_link_id(wvif, da);
-	if (!ret)
-		ret = wfx_alloc_link_id(wvif, da);
-	if (!ret) {
-		dev_err(wvif->wdev->dev, "no more link-id available\n");
-		return WFX_LINK_ID_NO_ASSOC;
-	}
-	return ret;
+	return WFX_LINK_ID_NO_ASSOC;
 }
 
 static void wfx_tx_fixup_rates(struct ieee80211_tx_rate *rates)
diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h
index d02a7b325b27..83720b343484 100644
--- a/drivers/staging/wfx/data_tx.h
+++ b/drivers/staging/wfx/data_tx.h
@@ -18,20 +18,6 @@ struct wfx_tx_priv;
 struct wfx_dev;
 struct wfx_vif;
 
-enum wfx_link_status {
-	WFX_LINK_OFF,
-	WFX_LINK_RESERVE,
-	WFX_LINK_SOFT,
-	WFX_LINK_HARD,
-};
-
-struct wfx_link_entry {
-	unsigned long		timestamp;
-	enum wfx_link_status	status;
-	u8			mac[ETH_ALEN];
-	u8			old_mac[ETH_ALEN];
-};
-
 struct tx_policy {
 	struct list_head link;
 	int usage_count;
@@ -63,11 +49,6 @@ void wfx_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
 void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg);
 void wfx_skb_dtor(struct wfx_dev *wdev, struct sk_buff *skb);
 
-int wfx_unmap_link(struct wfx_vif *wvif, int link_id);
-void wfx_link_id_work(struct work_struct *work);
-void wfx_link_id_gc_work(struct work_struct *work);
-int wfx_find_link_id(struct wfx_vif *wvif, const u8 *mac);
-
 static inline struct wfx_tx_priv *wfx_skb_tx_priv(struct sk_buff *skb)
 {
 	struct ieee80211_tx_info *tx_info;
diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c
index 92bb9a794f30..3d40388739e3 100644
--- a/drivers/staging/wfx/queue.c
+++ b/drivers/staging/wfx/queue.c
@@ -378,13 +378,8 @@ static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb,
 			action = do_drop;
 		break;
 	case NL80211_IFTYPE_AP:
-		if (!wvif->state) {
+		if (!wvif->state)
 			action = do_drop;
-		} else if (!(BIT(tx_priv->raw_link_id) &
-			     (BIT(0) | wvif->link_id_map))) {
-			dev_warn(wvif->wdev->dev, "a frame with expired link-id is dropped\n");
-			action = do_drop;
-		}
 		break;
 	case NL80211_IFTYPE_ADHOC:
 		if (wvif->state != WFX_STATE_IBSS)
diff --git a/drivers/staging/wfx/queue.h b/drivers/staging/wfx/queue.h
index 21566e48b2c2..813c2d09e034 100644
--- a/drivers/staging/wfx/queue.h
+++ b/drivers/staging/wfx/queue.h
@@ -13,9 +13,10 @@
 #include "hif_api_cmd.h"
 
 #define WFX_MAX_STA_IN_AP_MODE    14
-#define WFX_LINK_ID_AFTER_DTIM    (WFX_MAX_STA_IN_AP_MODE + 1)
-#define WFX_LINK_ID_UAPSD         (WFX_MAX_STA_IN_AP_MODE + 2)
-#define WFX_LINK_ID_MAX           (WFX_MAX_STA_IN_AP_MODE + 3)
+#define WFX_LINK_ID_NO_ASSOC      15
+#define WFX_LINK_ID_AFTER_DTIM    (WFX_LINK_ID_NO_ASSOC + 1)
+#define WFX_LINK_ID_UAPSD         (WFX_LINK_ID_NO_ASSOC + 2)
+#define WFX_LINK_ID_MAX           (WFX_LINK_ID_NO_ASSOC + 3)
 
 struct wfx_dev;
 struct wfx_vif;
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 47271b7eeaab..84853aa90f4b 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -573,28 +573,26 @@ static void wfx_unjoin_work(struct work_struct *work)
 int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		struct ieee80211_sta *sta)
 {
-	struct wfx_dev *wdev = hw->priv;
 	struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
 	struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
-	struct wfx_link_entry *entry;
 
 	spin_lock_init(&sta_priv->lock);
-	if (wvif->vif->type != NL80211_IFTYPE_AP)
-		return 0;
-
 	sta_priv->vif_id = wvif->id;
-	sta_priv->link_id = wfx_find_link_id(wvif, sta->addr);
-	if (!sta_priv->link_id) {
-		dev_warn(wdev->dev, "mo more link-id available\n");
-		return -ENOENT;
-	}
 
-	entry = &wvif->link_id_db[sta_priv->link_id - 1];
+	// FIXME: in station mode, the current API interprets new link-id as a
+	// tdls peer.
+	if (vif->type == NL80211_IFTYPE_STATION)
+		return 0;
+	sta_priv->link_id = ffz(wvif->link_id_map);
+	wvif->link_id_map |= BIT(sta_priv->link_id);
+	WARN_ON(!sta_priv->link_id);
+	WARN_ON(sta_priv->link_id >= WFX_MAX_STA_IN_AP_MODE);
+	hif_map_link(wvif, sta->addr, 0, sta_priv->link_id);
+
 	spin_lock_bh(&wvif->ps_state_lock);
 	if ((sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) ==
 					IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
 		wvif->sta_asleep_mask |= BIT(sta_priv->link_id);
-	entry->status = WFX_LINK_HARD;
 	spin_unlock_bh(&wvif->ps_state_lock);
 	return 0;
 }
@@ -602,23 +600,15 @@ int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		   struct ieee80211_sta *sta)
 {
-	struct wfx_dev *wdev = hw->priv;
 	struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
 	struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
-	struct wfx_link_entry *entry;
 
-	if (wvif->vif->type != NL80211_IFTYPE_AP || !sta_priv->link_id)
+	// FIXME: see note in wfx_sta_add()
+	if (vif->type == NL80211_IFTYPE_STATION)
 		return 0;
-
-	entry = &wvif->link_id_db[sta_priv->link_id - 1];
-	spin_lock_bh(&wvif->ps_state_lock);
-	entry->status = WFX_LINK_RESERVE;
-	entry->timestamp = jiffies;
-	wfx_tx_lock(wdev);
-	if (!schedule_work(&wvif->link_id_work))
-		wfx_tx_unlock(wdev);
-	spin_unlock_bh(&wvif->ps_state_lock);
-	flush_work(&wvif->link_id_work);
+	// FIXME add a mutex?
+	hif_map_link(wvif, sta->addr, 1, sta_priv->link_id);
+	wvif->link_id_map &= ~BIT(sta_priv->link_id);
 	return 0;
 }
 
@@ -627,8 +617,6 @@ static int wfx_start_ap(struct wfx_vif *wvif)
 	int ret;
 
 	wvif->beacon_int = wvif->vif->bss_conf.beacon_int;
-	memset(&wvif->link_id_db, 0, sizeof(wvif->link_id_db));
-
 	wvif->wdev->tx_burst_idx = -1;
 	ret = hif_start(wvif, &wvif->vif->bss_conf, wvif->channel);
 	if (ret)
@@ -861,7 +849,7 @@ static void wfx_ps_notify(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd,
 		dev_warn(wvif->wdev->dev, "unsupported notify command\n");
 		bit = 0;
 	} else {
-		bit = wvif->link_id_map;
+		bit = wvif->link_id_map & ~1;
 	}
 	prev = wvif->sta_asleep_mask & bit;
 
@@ -1114,9 +1102,7 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	wvif->vif = vif;
 	wvif->wdev = wdev;
 
-	INIT_WORK(&wvif->link_id_work, wfx_link_id_work);
-	INIT_DELAYED_WORK(&wvif->link_id_gc_work, wfx_link_id_gc_work);
-
+	wvif->link_id_map = 1; // link-id 0 is reserved for multicast
 	spin_lock_init(&wvif->ps_state_lock);
 	INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work);
 
@@ -1171,11 +1157,11 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
 {
 	struct wfx_dev *wdev = hw->priv;
 	struct wfx_vif *wvif = (struct wfx_vif *) vif->drv_priv;
-	int i;
 
 	wait_for_completion_timeout(&wvif->set_pm_mode_complete, msecs_to_jiffies(300));
 
 	mutex_lock(&wdev->conf_mutex);
+	WARN(wvif->link_id_map != 1, "corrupted state");
 	switch (wvif->state) {
 	case WFX_STATE_PRE_STA:
 	case WFX_STATE_STA:
@@ -1185,13 +1171,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
 			wfx_tx_unlock(wdev);
 		break;
 	case WFX_STATE_AP:
-		for (i = 0; wvif->link_id_map; ++i) {
-			if (wvif->link_id_map & BIT(i)) {
-				wfx_unmap_link(wvif, i);
-				wvif->link_id_map &= ~BIT(i);
-			}
-		}
-		memset(wvif->link_id_db, 0, sizeof(wvif->link_id_db));
 		wvif->sta_asleep_mask = 0;
 		wvif->mcast_tx = false;
 		wvif->aid0_bit_set = false;
@@ -1213,7 +1192,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
 
 	wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
 	cancel_work_sync(&wvif->unjoin_work);
-	cancel_delayed_work_sync(&wvif->link_id_gc_work);
 	del_timer_sync(&wvif->mcast_timeout);
 	wfx_free_event_queue(wvif);
 
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index cb359150e2ad..365aacc073fb 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -74,9 +74,6 @@ struct wfx_vif {
 	struct delayed_work	bss_loss_work;
 
 	u32			link_id_map;
-	struct wfx_link_entry	link_id_db[WFX_MAX_STA_IN_AP_MODE];
-	struct delayed_work	link_id_gc_work;
-	struct work_struct	link_id_work;
 
 	bool			aid0_bit_set;
 	bool			mcast_tx;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 51/65] staging: wfx: check that no tx is pending before release sta
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (49 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 50/65] staging: wfx: simplify the link-id allocation Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 52/65] staging: wfx: replace wfx_tx_get_tid() with ieee80211_get_tid() Jérôme Pouiller
                   ` (14 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Just for sanity.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 84853aa90f4b..eebbd3292b1b 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -602,7 +602,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;
+	int i;
 
+	for (i = 0; i < WFX_MAX_TID; i++)
+		WARN(sta_priv->buffered[i], "release station while Tx is in progress");
 	// FIXME: see note in wfx_sta_add()
 	if (vif->type == NL80211_IFTYPE_STATION)
 		return 0;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 52/65] staging: wfx: replace wfx_tx_get_tid() with ieee80211_get_tid()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (50 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 51/65] staging: wfx: check that no tx is pending before release sta Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 53/65] staging: wfx: pspoll_mask make no sense Jérôme Pouiller
                   ` (13 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wfx_tx_get_tid() was used as a wrapper around ieee80211_get_tid(). It
did sometime return WFX_MAX_TID to ask to upper layers to not include
the frame in "buffered" counter. The objective of this behavior is not
clear, but tests has shown that wfx_tx_get_tid() can be replaced by
ieee80211_get_tid() without any regressions.

BTW, it is not necessary to save the tid in tx_rpiv since it can be
retrieved from the 802.11 header.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_tx.c | 23 ++++++-----------------
 drivers/staging/wfx/data_tx.h |  1 -
 drivers/staging/wfx/sta.c     |  2 +-
 drivers/staging/wfx/sta.h     |  5 +----
 4 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index 8c9f986ec672..7da1afd6e9b5 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -283,6 +283,7 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
 {
 	u32 mask = ~BIT(tx_priv->raw_link_id);
 	struct wfx_sta_priv *sta_priv;
+	int tid = ieee80211_get_tid(hdr);
 
 	spin_lock_bh(&wvif->ps_state_lock);
 	if (ieee80211_is_auth(hdr->frame_control)) {
@@ -298,11 +299,11 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
 	}
 	spin_unlock_bh(&wvif->ps_state_lock);
 
-	if (sta && tx_priv->tid < WFX_MAX_TID) {
+	if (sta) {
 		sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
 		spin_lock_bh(&sta_priv->lock);
-		sta_priv->buffered[tx_priv->tid]++;
-		ieee80211_sta_set_buffered(sta, tx_priv->tid, true);
+		sta_priv->buffered[tid]++;
+		ieee80211_sta_set_buffered(sta, tid, true);
 		spin_unlock_bh(&sta_priv->lock);
 	}
 }
@@ -418,17 +419,6 @@ static struct hif_ht_tx_parameters wfx_tx_get_tx_parms(struct wfx_dev *wdev, str
 	return ret;
 }
 
-static u8 wfx_tx_get_tid(struct ieee80211_hdr *hdr)
-{
-	// FIXME: ieee80211_get_tid(hdr) should be sufficient for all cases.
-	if (!ieee80211_is_data(hdr->frame_control))
-		return WFX_MAX_TID;
-	if (ieee80211_is_data_qos(hdr->frame_control))
-		return ieee80211_get_tid(hdr);
-	else
-		return 0;
-}
-
 static int wfx_tx_get_icv_len(struct ieee80211_key_conf *hw_key)
 {
 	int mic_space;
@@ -460,7 +450,6 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
 	memset(tx_info->rate_driver_data, 0, sizeof(struct wfx_tx_priv));
 	// Fill tx_priv
 	tx_priv = (struct wfx_tx_priv *)tx_info->rate_driver_data;
-	tx_priv->tid = wfx_tx_get_tid(hdr);
 	tx_priv->raw_link_id = wfx_tx_get_raw_link_id(wvif, sta, hdr);
 	tx_priv->link_id = tx_priv->raw_link_id;
 	if (ieee80211_has_protected(hdr->frame_control))
@@ -634,11 +623,11 @@ static void wfx_notify_buffered_tx(struct wfx_vif *wvif, struct sk_buff *skb)
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_sta *sta;
 	struct wfx_sta_priv *sta_priv;
-	int tid = wfx_tx_get_tid(hdr);
+	int tid = ieee80211_get_tid(hdr);
 
 	rcu_read_lock(); // protect sta
 	sta = ieee80211_find_sta(wvif->vif, hdr->addr1);
-	if (sta && tid < WFX_MAX_TID) {
+	if (sta) {
 		sta_priv = (struct wfx_sta_priv *)&sta->drv_priv;
 		spin_lock_bh(&sta_priv->lock);
 		WARN(!sta_priv->buffered[tid], "inconsistent notification");
diff --git a/drivers/staging/wfx/data_tx.h b/drivers/staging/wfx/data_tx.h
index 83720b343484..04b2147101b6 100644
--- a/drivers/staging/wfx/data_tx.h
+++ b/drivers/staging/wfx/data_tx.h
@@ -38,7 +38,6 @@ struct wfx_tx_priv {
 	struct ieee80211_key_conf *hw_key;
 	u8 link_id;
 	u8 raw_link_id;
-	u8 tid;
 } __packed;
 
 void wfx_tx_policy_init(struct wfx_vif *wvif);
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index eebbd3292b1b..61d64beb6143 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -604,7 +604,7 @@ int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *) &sta->drv_priv;
 	int i;
 
-	for (i = 0; i < WFX_MAX_TID; i++)
+	for (i = 0; i < ARRAY_SIZE(sta_priv->buffered); i++)
 		WARN(sta_priv->buffered[i], "release station while Tx is in progress");
 	// FIXME: see note in wfx_sta_add()
 	if (vif->type == NL80211_IFTYPE_STATION)
diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h
index 47d94d6b8590..e832405d604e 100644
--- a/drivers/staging/wfx/sta.h
+++ b/drivers/staging/wfx/sta.h
@@ -12,9 +12,6 @@
 
 #include "hif_api_cmd.h"
 
-// FIXME: use IEEE80211_NUM_TIDS
-#define WFX_MAX_TID               8
-
 struct wfx_dev;
 struct wfx_vif;
 
@@ -40,7 +37,7 @@ struct wfx_grp_addr_table {
 struct wfx_sta_priv {
 	int link_id;
 	int vif_id;
-	u8 buffered[WFX_MAX_TID];
+	u8 buffered[IEEE80211_NUM_TIDS];
 	// Ensure atomicity of "buffered" and calls to ieee80211_sta_set_buffered()
 	spinlock_t lock;
 };
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 53/65] staging: wfx: pspoll_mask make no sense
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (51 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 52/65] staging: wfx: replace wfx_tx_get_tid() with ieee80211_get_tid() Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 54/65] staging: wfx: sta and dtim Jérôme Pouiller
                   ` (12 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

pspoll_mask is here to send data buffered in driver. But since station
is marked buffered, TIM for this station is 1 and mac80211 will call
sta_notify when a ps-poll is received. So pspoll_mask is useless and
sta_alseep_mask is sufficient.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_rx.c | 39 -----------------------------------
 drivers/staging/wfx/data_tx.c |  4 +---
 drivers/staging/wfx/queue.c   |  8 ++-----
 drivers/staging/wfx/sta.c     |  2 --
 drivers/staging/wfx/wfx.h     |  1 -
 5 files changed, 3 insertions(+), 51 deletions(-)

diff --git a/drivers/staging/wfx/data_rx.c b/drivers/staging/wfx/data_rx.c
index 699e2d60fa89..5d198457c6ce 100644
--- a/drivers/staging/wfx/data_rx.c
+++ b/drivers/staging/wfx/data_rx.c
@@ -13,41 +13,6 @@
 #include "bh.h"
 #include "sta.h"
 
-static int wfx_handle_pspoll(struct wfx_vif *wvif, struct sk_buff *skb)
-{
-	struct ieee80211_sta *sta;
-	struct ieee80211_pspoll *pspoll = (struct ieee80211_pspoll *)skb->data;
-	int link_id = 0;
-	u32 pspoll_mask = 0;
-	int i;
-
-	if (wvif->state != WFX_STATE_AP)
-		return 1;
-	if (!ether_addr_equal(wvif->vif->addr, pspoll->bssid))
-		return 1;
-
-	rcu_read_lock();
-	sta = ieee80211_find_sta(wvif->vif, pspoll->ta);
-	if (sta)
-		link_id = ((struct wfx_sta_priv *)&sta->drv_priv)->link_id;
-	rcu_read_unlock();
-	if (link_id)
-		pspoll_mask = BIT(link_id);
-	else
-		return 1;
-
-	wvif->pspoll_mask |= pspoll_mask;
-	/* Do not report pspols if data for given link id is queued already. */
-	for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
-		if (wfx_tx_queue_get_num_queued(&wvif->wdev->tx_queue[i],
-						pspoll_mask)) {
-			wfx_bh_request_tx(wvif->wdev);
-			return 1;
-		}
-	}
-	return 0;
-}
-
 static int wfx_drop_encrypt_data(struct wfx_dev *wdev,
 				 const struct hif_ind_rx *arg,
 				 struct sk_buff *skb)
@@ -125,10 +90,6 @@ void wfx_rx_cb(struct wfx_vif *wvif,
 		goto drop;
 	}
 
-	if (ieee80211_is_pspoll(frame->frame_control))
-		if (wfx_handle_pspoll(wvif, skb))
-			goto drop;
-
 	hdr->band = NL80211_BAND_2GHZ;
 	hdr->freq = ieee80211_channel_to_frequency(arg->channel_number,
 						   hdr->band);
diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index 7da1afd6e9b5..7914c06578aa 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -286,10 +286,8 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
 	int tid = ieee80211_get_tid(hdr);
 
 	spin_lock_bh(&wvif->ps_state_lock);
-	if (ieee80211_is_auth(hdr->frame_control)) {
+	if (ieee80211_is_auth(hdr->frame_control))
 		wvif->sta_asleep_mask &= mask;
-		wvif->pspoll_mask &= mask;
-	}
 
 	if (tx_priv->link_id == WFX_LINK_ID_AFTER_DTIM &&
 	    !wvif->mcast_buffered) {
diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c
index 3d40388739e3..42d64534c92c 100644
--- a/drivers/staging/wfx/queue.c
+++ b/drivers/staging/wfx/queue.c
@@ -493,12 +493,10 @@ static int wfx_tx_queue_mask_get(struct wfx_vif *wvif,
 	/* Search for unicast traffic */
 	tx_allowed_mask = ~wvif->sta_asleep_mask;
 	tx_allowed_mask |= BIT(WFX_LINK_ID_UAPSD);
-	if (wvif->sta_asleep_mask) {
-		tx_allowed_mask |= wvif->pspoll_mask;
+	if (wvif->sta_asleep_mask)
 		tx_allowed_mask &= ~BIT(WFX_LINK_ID_AFTER_DTIM);
-	} else {
+	else
 		tx_allowed_mask |= BIT(WFX_LINK_ID_AFTER_DTIM);
-	}
 	idx = wfx_get_prio_queue(wvif, tx_allowed_mask, &total);
 	if (idx < 0)
 		return -ENOENT;
@@ -585,8 +583,6 @@ struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev)
 		if (hif_handle_tx_data(wvif, skb, queue))
 			continue;  /* Handled by WSM */
 
-		wvif->pspoll_mask &= ~BIT(tx_priv->raw_link_id);
-
 		/* allow bursting if txop is set */
 		if (wvif->edca_params[queue_num].txop)
 			burst = (int)wfx_tx_queue_get_num_queued(queue, tx_allowed_mask) + 1;
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 61d64beb6143..6697c736a054 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -867,7 +867,6 @@ static void wfx_ps_notify(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd,
 	case STA_NOTIFY_AWAKE:
 		if (prev) {
 			wvif->sta_asleep_mask &= ~bit;
-			wvif->pspoll_mask &= ~bit;
 			if (link_id && !wvif->sta_asleep_mask)
 				schedule_work(&wvif->mcast_stop_work);
 			wfx_bh_request_tx(wvif->wdev);
@@ -1178,7 +1177,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
 		wvif->mcast_tx = false;
 		wvif->aid0_bit_set = false;
 		wvif->mcast_buffered = false;
-		wvif->pspoll_mask = 0;
 		/* reset.link_id = 0; */
 		hif_reset(wvif, false);
 		break;
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 365aacc073fb..8491f050478d 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -91,7 +91,6 @@ struct wfx_vif {
 	struct work_struct	tx_policy_upload_work;
 
 	u32			sta_asleep_mask;
-	u32			pspoll_mask;
 	spinlock_t		ps_state_lock;
 	struct work_struct	update_tim_work;
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 54/65] staging: wfx: sta and dtim
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (52 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 53/65] staging: wfx: pspoll_mask make no sense Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 55/65] staging: wfx: firmware never return PS status for stations Jérôme Pouiller
                   ` (11 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wfx_ps_notify() is called for any changes in the TIM. However,
association ID 0 is a very special case that should be handled
independently.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 6697c736a054..d4c11b07497f 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -839,21 +839,13 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 		wfx_do_join(wvif);
 }
 
-static void wfx_ps_notify(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd,
-			  int link_id)
+static void wfx_ps_notify_sta(struct wfx_vif *wvif,
+			      enum sta_notify_cmd notify_cmd, int link_id)
 {
 	u32 bit, prev;
 
 	spin_lock_bh(&wvif->ps_state_lock);
-	/* Zero link id means "for all link IDs" */
-	if (link_id) {
-		bit = BIT(link_id);
-	} else if (notify_cmd != STA_NOTIFY_AWAKE) {
-		dev_warn(wvif->wdev->dev, "unsupported notify command\n");
-		bit = 0;
-	} else {
-		bit = wvif->link_id_map & ~1;
-	}
+	bit = BIT(link_id);
 	prev = wvif->sta_asleep_mask & bit;
 
 	switch (notify_cmd) {
@@ -867,7 +859,7 @@ static void wfx_ps_notify(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd,
 	case STA_NOTIFY_AWAKE:
 		if (prev) {
 			wvif->sta_asleep_mask &= ~bit;
-			if (link_id && !wvif->sta_asleep_mask)
+			if (!wvif->sta_asleep_mask)
 				schedule_work(&wvif->mcast_stop_work);
 			wfx_bh_request_tx(wvif->wdev);
 		}
@@ -882,7 +874,7 @@ void wfx_sta_notify(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;
 
-	wfx_ps_notify(wvif, notify_cmd, sta_priv->link_id);
+	wfx_ps_notify_sta(wvif, notify_cmd, sta_priv->link_id);
 }
 
 static int wfx_update_tim(struct wfx_vif *wvif)
@@ -993,6 +985,14 @@ int wfx_ampdu_action(struct ieee80211_hw *hw,
 	return -ENOTSUPP;
 }
 
+static void wfx_dtim_notify(struct wfx_vif *wvif)
+{
+	spin_lock_bh(&wvif->ps_state_lock);
+	wvif->sta_asleep_mask = 0;
+	wfx_bh_request_tx(wvif->wdev);
+	spin_unlock_bh(&wvif->ps_state_lock);
+}
+
 void wfx_suspend_resume(struct wfx_vif *wvif,
 			const struct hif_ind_suspend_resume_tx *arg)
 {
@@ -1013,12 +1013,9 @@ void wfx_suspend_resume(struct wfx_vif *wvif,
 		if (cancel_tmo)
 			del_timer_sync(&wvif->mcast_timeout);
 	} else if (arg->suspend_resume_flags.resume) {
-		// FIXME: should change each station status independently
-		wfx_ps_notify(wvif, STA_NOTIFY_AWAKE, 0);
-		wfx_bh_request_tx(wvif->wdev);
+		wfx_dtim_notify(wvif);
 	} else {
-		// FIXME: should change each station status independently
-		wfx_ps_notify(wvif, STA_NOTIFY_SLEEP, 0);
+		dev_warn(wvif->wdev->dev, "unsupported suspend/resume notification\n");
 	}
 }
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 55/65] staging: wfx: firmware never return PS status for stations
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (53 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 54/65] staging: wfx: sta and dtim Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 56/65] staging: wfx: simplify wfx_suspend_resume_mc() Jérôme Pouiller
                   ` (10 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

At the beginning, firmware could send suspend_resume indication to
notify that a station wake up or sleep down. However, mac80211 already
handles power save status of stations and this behavior has been removed
from the firmware. So now, when suspend_resume indication is received,
it is always to notify that a DTIM is about to be sent.

So, it is possible to simply wfx_suspend_resume().

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 43 ++++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 26 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index d4c11b07497f..ce83a57397c8 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -985,38 +985,29 @@ int wfx_ampdu_action(struct ieee80211_hw *hw,
 	return -ENOTSUPP;
 }
 
-static void wfx_dtim_notify(struct wfx_vif *wvif)
-{
-	spin_lock_bh(&wvif->ps_state_lock);
-	wvif->sta_asleep_mask = 0;
-	wfx_bh_request_tx(wvif->wdev);
-	spin_unlock_bh(&wvif->ps_state_lock);
-}
-
 void wfx_suspend_resume(struct wfx_vif *wvif,
 			const struct hif_ind_suspend_resume_tx *arg)
 {
-	if (arg->suspend_resume_flags.bc_mc_only) {
-		bool cancel_tmo = false;
+	bool cancel_tmo = false;
 
-		spin_lock_bh(&wvif->ps_state_lock);
-		if (!arg->suspend_resume_flags.resume)
-			wvif->mcast_tx = false;
-		else
-			wvif->mcast_tx = wvif->aid0_bit_set &&
-					 wvif->mcast_buffered;
-		if (wvif->mcast_tx) {
-			cancel_tmo = true;
-			wfx_bh_request_tx(wvif->wdev);
-		}
-		spin_unlock_bh(&wvif->ps_state_lock);
-		if (cancel_tmo)
-			del_timer_sync(&wvif->mcast_timeout);
-	} else if (arg->suspend_resume_flags.resume) {
-		wfx_dtim_notify(wvif);
-	} else {
+	if (!arg->suspend_resume_flags.bc_mc_only) {
 		dev_warn(wvif->wdev->dev, "unsupported suspend/resume notification\n");
+		return;
 	}
+
+	spin_lock_bh(&wvif->ps_state_lock);
+	if (!arg->suspend_resume_flags.resume)
+		wvif->mcast_tx = false;
+	else
+		wvif->mcast_tx = wvif->aid0_bit_set &&
+				 wvif->mcast_buffered;
+	if (wvif->mcast_tx) {
+		cancel_tmo = true;
+		wfx_bh_request_tx(wvif->wdev);
+	}
+	spin_unlock_bh(&wvif->ps_state_lock);
+	if (cancel_tmo)
+		del_timer_sync(&wvif->mcast_timeout);
 }
 
 int wfx_add_chanctx(struct ieee80211_hw *hw,
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 56/65] staging: wfx: simplify wfx_suspend_resume_mc()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (54 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 55/65] staging: wfx: firmware never return PS status for stations Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 57/65] staging: wfx: simplify handling of IEEE80211_TX_CTL_SEND_AFTER_DTIM Jérôme Pouiller
                   ` (9 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Indeed, it is not necessary to pass whole hif_ind_suspend_resume_tx to
wfx_suspend_resume_mc().

In add, the structure hif_ind_suspend_resume_tx come from hardware API.
It is not intended to be manipulated in upper layers of the driver.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_tx.c |  7 +------
 drivers/staging/wfx/hif_rx.c  |  6 +++++-
 drivers/staging/wfx/sta.c     | 10 ++--------
 drivers/staging/wfx/sta.h     |  3 +--
 4 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index 7914c06578aa..8710383f66e5 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -600,13 +600,8 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg)
 			tx_info->flags |= IEEE80211_TX_STAT_ACK;
 	} else if (arg->status == HIF_REQUEUE) {
 		/* "REQUEUE" means "implicit suspend" */
-		struct hif_ind_suspend_resume_tx suspend = {
-			.suspend_resume_flags.resume = 0,
-			.suspend_resume_flags.bc_mc_only = 1,
-		};
-
 		WARN(!arg->tx_result_flags.requeue, "incoherent status and result_flags");
-		wfx_suspend_resume(wvif, &suspend);
+		wfx_suspend_resume_mc(wvif, STA_NOTIFY_SLEEP);
 		tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
 	} else {
 		if (wvif->bss_loss_state &&
diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c
index f04afc6db9a5..f798cd6973b6 100644
--- a/drivers/staging/wfx/hif_rx.c
+++ b/drivers/staging/wfx/hif_rx.c
@@ -230,7 +230,11 @@ static int hif_suspend_resume_indication(struct wfx_dev *wdev,
 	const struct hif_ind_suspend_resume_tx *body = buf;
 
 	WARN_ON(!wvif);
-	wfx_suspend_resume(wvif, body);
+	WARN(!body->suspend_resume_flags.bc_mc_only, "unsupported suspend/resume notification");
+	if (body->suspend_resume_flags.resume)
+		wfx_suspend_resume_mc(wvif, STA_NOTIFY_AWAKE);
+	else
+		wfx_suspend_resume_mc(wvif, STA_NOTIFY_SLEEP);
 
 	return 0;
 }
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index ce83a57397c8..d647dff46673 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -985,18 +985,12 @@ int wfx_ampdu_action(struct ieee80211_hw *hw,
 	return -ENOTSUPP;
 }
 
-void wfx_suspend_resume(struct wfx_vif *wvif,
-			const struct hif_ind_suspend_resume_tx *arg)
+void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd)
 {
 	bool cancel_tmo = false;
 
-	if (!arg->suspend_resume_flags.bc_mc_only) {
-		dev_warn(wvif->wdev->dev, "unsupported suspend/resume notification\n");
-		return;
-	}
-
 	spin_lock_bh(&wvif->ps_state_lock);
-	if (!arg->suspend_resume_flags.resume)
+	if (notify_cmd == STA_NOTIFY_SLEEP)
 		wvif->mcast_tx = false;
 	else
 		wvif->mcast_tx = wvif->aid0_bit_set &&
diff --git a/drivers/staging/wfx/sta.h b/drivers/staging/wfx/sta.h
index e832405d604e..cf99a8a74a81 100644
--- a/drivers/staging/wfx/sta.h
+++ b/drivers/staging/wfx/sta.h
@@ -82,8 +82,7 @@ void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw,
 			      struct ieee80211_chanctx_conf *conf);
 
 // WSM Callbacks
-void wfx_suspend_resume(struct wfx_vif *wvif,
-			const struct hif_ind_suspend_resume_tx *arg);
+void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd cmd);
 
 // Other Helpers
 void wfx_cqm_bssloss_sm(struct wfx_vif *wvif, int init, int good, int bad);
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 57/65] staging: wfx: simplify handling of IEEE80211_TX_CTL_SEND_AFTER_DTIM
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (55 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 56/65] staging: wfx: simplify wfx_suspend_resume_mc() Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 58/65] staging: wfx: simplify wfx_ps_notify_sta() Jérôme Pouiller
                   ` (8 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

When mac80211 ask for a frame to be sent after a DTIM, driver should:
  1. Update TIM with multicast bit set (using update_ie). This function
     can be called whenever.
  2. Keep buffered all frames marked "after dtim"
  3. When it receive a suspend_resume indication (see
     wfx_suspend_resume_mc()), send all the buffered frames. This
     indication is sent by the firmware 4ms before the dtim.
  4. If one of the frames returns status "REQUEUE", it means that the
     DTIM period was ended before to be able to send the frame.
  5. When all the buffered frames were sent or if DTIM period was ended,
     driver should update the TIM with multicast bit reset.

All the mess with the asynchronous works can be dropped.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_tx.c     | 17 +++---
 drivers/staging/wfx/hif_api_cmd.h |  3 +-
 drivers/staging/wfx/queue.c       | 98 +++++++++++++++----------------
 drivers/staging/wfx/queue.h       |  1 +
 drivers/staging/wfx/sta.c         | 78 ++----------------------
 drivers/staging/wfx/wfx.h         |  7 +--
 6 files changed, 66 insertions(+), 138 deletions(-)

diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index 8710383f66e5..c32994553633 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -288,13 +288,6 @@ static void wfx_tx_manage_pm(struct wfx_vif *wvif, struct ieee80211_hdr *hdr,
 	spin_lock_bh(&wvif->ps_state_lock);
 	if (ieee80211_is_auth(hdr->frame_control))
 		wvif->sta_asleep_mask &= mask;
-
-	if (tx_priv->link_id == WFX_LINK_ID_AFTER_DTIM &&
-	    !wvif->mcast_buffered) {
-		wvif->mcast_buffered = true;
-		if (wvif->sta_asleep_mask)
-			schedule_work(&wvif->mcast_start_work);
-	}
 	spin_unlock_bh(&wvif->ps_state_lock);
 
 	if (sta) {
@@ -479,6 +472,8 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
 	req->packet_id = queue_id << 16 |
 			 IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
 	req->data_flags.fc_offset = offset;
+	if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
+		req->data_flags.after_dtim = 1;
 	req->queue_id.peer_sta_id = tx_priv->raw_link_id;
 	// Queue index are inverted between firmware and Linux
 	req->queue_id.queue_id = 3 - queue_id;
@@ -488,6 +483,8 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
 	// Auxiliary operations
 	wfx_tx_manage_pm(wvif, hdr, tx_priv, sta);
 	wfx_tx_queue_put(wvif->wdev, &wvif->wdev->tx_queue[queue_id], skb);
+	if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
+		schedule_work(&wvif->update_tim_work);
 	wfx_bh_request_tx(wvif->wdev);
 	return 0;
 }
@@ -599,9 +596,11 @@ void wfx_tx_confirm_cb(struct wfx_vif *wvif, const struct hif_cnf_tx *arg)
 		else
 			tx_info->flags |= IEEE80211_TX_STAT_ACK;
 	} else if (arg->status == HIF_REQUEUE) {
-		/* "REQUEUE" means "implicit suspend" */
 		WARN(!arg->tx_result_flags.requeue, "incoherent status and result_flags");
-		wfx_suspend_resume_mc(wvif, STA_NOTIFY_SLEEP);
+		if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
+			wvif->after_dtim_tx_allowed = false; // DTIM period elapsed
+			schedule_work(&wvif->update_tim_work);
+		}
 		tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
 	} else {
 		if (wvif->bss_loss_state &&
diff --git a/drivers/staging/wfx/hif_api_cmd.h b/drivers/staging/wfx/hif_api_cmd.h
index fc078d54bfbf..5554d6eddbf3 100644
--- a/drivers/staging/wfx/hif_api_cmd.h
+++ b/drivers/staging/wfx/hif_api_cmd.h
@@ -253,7 +253,8 @@ struct hif_queue {
 struct hif_data_flags {
 	u8    more:1;
 	u8    fc_offset:3;
-	u8    reserved:4;
+	u8    after_dtim:1;
+	u8    reserved:3;
 } __packed;
 
 struct hif_tx_flags {
diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c
index 42d64534c92c..ec11a63a2ff9 100644
--- a/drivers/staging/wfx/queue.c
+++ b/drivers/staging/wfx/queue.c
@@ -235,7 +235,6 @@ static struct sk_buff *wfx_tx_queue_get(struct wfx_dev *wdev,
 			break;
 		}
 	}
-	WARN_ON(!skb);
 	if (skb) {
 		tx_priv = wfx_skb_tx_priv(skb);
 		tx_priv->xmit_timestamp = ktime_get();
@@ -473,23 +472,12 @@ static int wfx_get_prio_queue(struct wfx_vif *wvif,
 
 static int wfx_tx_queue_mask_get(struct wfx_vif *wvif,
 				     struct wfx_queue **queue_p,
-				     u32 *tx_allowed_mask_p,
-				     bool *more)
+				     u32 *tx_allowed_mask_p)
 {
 	int idx;
 	u32 tx_allowed_mask;
 	int total = 0;
 
-	/* Search for a queue with multicast frames buffered */
-	if (wvif->mcast_tx) {
-		tx_allowed_mask = BIT(WFX_LINK_ID_AFTER_DTIM);
-		idx = wfx_get_prio_queue(wvif, tx_allowed_mask, &total);
-		if (idx >= 0) {
-			*more = total > 1;
-			goto found;
-		}
-	}
-
 	/* Search for unicast traffic */
 	tx_allowed_mask = ~wvif->sta_asleep_mask;
 	tx_allowed_mask |= BIT(WFX_LINK_ID_UAPSD);
@@ -501,64 +489,83 @@ static int wfx_tx_queue_mask_get(struct wfx_vif *wvif,
 	if (idx < 0)
 		return -ENOENT;
 
-found:
 	*queue_p = &wvif->wdev->tx_queue[idx];
 	*tx_allowed_mask_p = tx_allowed_mask;
 	return 0;
 }
 
+struct hif_msg *wfx_tx_queues_get_after_dtim(struct wfx_vif *wvif)
+{
+	struct wfx_dev *wdev = wvif->wdev;
+	struct ieee80211_tx_info *tx_info;
+	struct hif_msg *hif;
+	struct sk_buff *skb;
+	int i;
+
+	for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
+		skb_queue_walk(&wdev->tx_queue[i].queue, skb) {
+			tx_info = IEEE80211_SKB_CB(skb);
+			hif = (struct hif_msg *)skb->data;
+			if ((tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) &&
+			    (hif->interface == wvif->id))
+				return (struct hif_msg *)skb->data;
+		}
+	}
+	return NULL;
+}
+
 struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev)
 {
 	struct sk_buff *skb;
 	struct hif_msg *hif = NULL;
-	struct hif_req_tx *req = NULL;
 	struct wfx_queue *queue = NULL;
 	struct wfx_queue *vif_queue = NULL;
 	u32 tx_allowed_mask = 0;
 	u32 vif_tx_allowed_mask = 0;
 	const struct wfx_tx_priv *tx_priv = NULL;
 	struct wfx_vif *wvif;
-	/* More is used only for broadcasts. */
-	bool more = false;
-	bool vif_more = false;
 	int not_found;
 	int burst;
+	int i;
+
+	if (atomic_read(&wdev->tx_lock))
+		return NULL;
+
+	wvif = NULL;
+	while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
+		if (wvif->after_dtim_tx_allowed) {
+			for (i = 0; i < IEEE80211_NUM_ACS; ++i) {
+				skb = wfx_tx_queue_get(wvif->wdev,
+						       &wdev->tx_queue[i],
+						       BIT(WFX_LINK_ID_AFTER_DTIM));
+				if (skb) {
+					hif = (struct hif_msg *)skb->data;
+					// Cannot happen since only one vif can
+					// be AP at time
+					WARN_ON(wvif->id != hif->interface);
+					return hif;
+				}
+			}
+			// No more multicast to sent
+			wvif->after_dtim_tx_allowed = false;
+			schedule_work(&wvif->update_tim_work);
+		}
+	}
 
 	for (;;) {
 		int ret = -ENOENT;
 		int queue_num;
-		struct ieee80211_hdr *hdr;
-
-		if (atomic_read(&wdev->tx_lock))
-			return NULL;
 
 		wvif = NULL;
 		while ((wvif = wvif_iterate(wdev, wvif)) != NULL) {
 			spin_lock_bh(&wvif->ps_state_lock);
 
 			not_found = wfx_tx_queue_mask_get(wvif, &vif_queue,
-							  &vif_tx_allowed_mask,
-							  &vif_more);
-
-			if (wvif->mcast_buffered && (not_found || !vif_more) &&
-					(wvif->mcast_tx ||
-					 !wvif->sta_asleep_mask)) {
-				wvif->mcast_buffered = false;
-				if (wvif->mcast_tx) {
-					wvif->mcast_tx = false;
-					schedule_work(&wvif->mcast_stop_work);
-				}
-			}
+							  &vif_tx_allowed_mask);
 
 			spin_unlock_bh(&wvif->ps_state_lock);
 
-			if (vif_more) {
-				more = true;
-				tx_allowed_mask = vif_tx_allowed_mask;
-				queue = vif_queue;
-				ret = 0;
-				break;
-			} else if (!not_found) {
+			if (!not_found) {
 				if (queue && queue != vif_queue)
 					dev_info(wdev->dev, "vifs disagree about queue priority\n");
 				tx_allowed_mask |= vif_tx_allowed_mask;
@@ -595,15 +602,6 @@ struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev)
 		else
 			wdev->tx_burst_idx = -1;
 
-		/* more buffered multicast/broadcast frames
-		 *  ==> set MoreData flag in IEEE 802.11 header
-		 *  to inform PS STAs
-		 */
-		if (more) {
-			req = (struct hif_req_tx *) hif->body;
-			hdr = (struct ieee80211_hdr *) (req->frame + req->data_flags.fc_offset);
-			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
-		}
 		return hif;
 	}
 }
diff --git a/drivers/staging/wfx/queue.h b/drivers/staging/wfx/queue.h
index 813c2d09e034..096ae86135cc 100644
--- a/drivers/staging/wfx/queue.h
+++ b/drivers/staging/wfx/queue.h
@@ -47,6 +47,7 @@ void wfx_tx_queues_clear(struct wfx_dev *wdev);
 bool wfx_tx_queues_is_empty(struct wfx_dev *wdev);
 void wfx_tx_queues_wait_empty_vif(struct wfx_vif *wvif);
 struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev);
+struct hif_msg *wfx_tx_queues_get_after_dtim(struct wfx_vif *wvif);
 
 void wfx_tx_queue_put(struct wfx_dev *wdev, struct wfx_queue *queue,
 		      struct sk_buff *skb);
diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index d647dff46673..01eee06a1ef4 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -851,16 +851,12 @@ static void wfx_ps_notify_sta(struct wfx_vif *wvif,
 	switch (notify_cmd) {
 	case STA_NOTIFY_SLEEP:
 		if (!prev) {
-			if (wvif->mcast_buffered && !wvif->sta_asleep_mask)
-				schedule_work(&wvif->mcast_start_work);
 			wvif->sta_asleep_mask |= bit;
 		}
 		break;
 	case STA_NOTIFY_AWAKE:
 		if (prev) {
 			wvif->sta_asleep_mask &= ~bit;
-			if (!wvif->sta_asleep_mask)
-				schedule_work(&wvif->mcast_stop_work);
 			wfx_bh_request_tx(wvif->wdev);
 		}
 		break;
@@ -898,7 +894,7 @@ static int wfx_update_tim(struct wfx_vif *wvif)
 		tim_ptr[2] = 0;
 
 		/* Set/reset aid0 bit */
-		if (wvif->aid0_bit_set)
+		if (wfx_tx_queues_get_after_dtim(wvif))
 			tim_ptr[4] |= 1;
 		else
 			tim_ptr[4] &= ~1;
@@ -927,47 +923,12 @@ int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
 	return 0;
 }
 
-static void wfx_mcast_start_work(struct work_struct *work)
+void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd)
 {
-	struct wfx_vif *wvif =
-		container_of(work, struct wfx_vif, mcast_start_work);
-	struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf;
-	long tmo = conf->dtim_period * TU_TO_JIFFIES(wvif->beacon_int + 20);
-
-	cancel_work_sync(&wvif->mcast_stop_work);
-	if (!wvif->aid0_bit_set) {
-		wfx_tx_lock_flush(wvif->wdev);
-		wvif->aid0_bit_set = true;
-		wfx_update_tim(wvif);
-		mod_timer(&wvif->mcast_timeout, jiffies + tmo);
-		wfx_tx_unlock(wvif->wdev);
-	}
-}
-
-static void wfx_mcast_stop_work(struct work_struct *work)
-{
-	struct wfx_vif *wvif = container_of(work, struct wfx_vif,
-					    mcast_stop_work);
-
-	if (wvif->aid0_bit_set) {
-		del_timer_sync(&wvif->mcast_timeout);
-		wfx_tx_lock_flush(wvif->wdev);
-		wvif->aid0_bit_set = false;
-		wfx_update_tim(wvif);
-		wfx_tx_unlock(wvif->wdev);
-	}
-}
-
-static void wfx_mcast_timeout(struct timer_list *t)
-{
-	struct wfx_vif *wvif = from_timer(wvif, t, mcast_timeout);
-
-	dev_warn(wvif->wdev->dev, "multicast delivery timeout\n");
-	spin_lock_bh(&wvif->ps_state_lock);
-	wvif->mcast_tx = wvif->aid0_bit_set && wvif->mcast_buffered;
-	if (wvif->mcast_tx)
-		wfx_bh_request_tx(wvif->wdev);
-	spin_unlock_bh(&wvif->ps_state_lock);
+	WARN(!wfx_tx_queues_get_after_dtim(wvif), "incorrect sequence");
+	WARN(wvif->after_dtim_tx_allowed, "incorrect sequence");
+	wvif->after_dtim_tx_allowed = true;
+	wfx_bh_request_tx(wvif->wdev);
 }
 
 int wfx_ampdu_action(struct ieee80211_hw *hw,
@@ -985,25 +946,6 @@ int wfx_ampdu_action(struct ieee80211_hw *hw,
 	return -ENOTSUPP;
 }
 
-void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd)
-{
-	bool cancel_tmo = false;
-
-	spin_lock_bh(&wvif->ps_state_lock);
-	if (notify_cmd == STA_NOTIFY_SLEEP)
-		wvif->mcast_tx = false;
-	else
-		wvif->mcast_tx = wvif->aid0_bit_set &&
-				 wvif->mcast_buffered;
-	if (wvif->mcast_tx) {
-		cancel_tmo = true;
-		wfx_bh_request_tx(wvif->wdev);
-	}
-	spin_unlock_bh(&wvif->ps_state_lock);
-	if (cancel_tmo)
-		del_timer_sync(&wvif->mcast_timeout);
-}
-
 int wfx_add_chanctx(struct ieee80211_hw *hw,
 		    struct ieee80211_chanctx_conf *conf)
 {
@@ -1090,10 +1032,6 @@ int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	spin_lock_init(&wvif->ps_state_lock);
 	INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work);
 
-	INIT_WORK(&wvif->mcast_start_work, wfx_mcast_start_work);
-	INIT_WORK(&wvif->mcast_stop_work, wfx_mcast_stop_work);
-	timer_setup(&wvif->mcast_timeout, wfx_mcast_timeout, 0);
-
 	memset(&wvif->bss_params, 0, sizeof(wvif->bss_params));
 
 	mutex_init(&wvif->bss_loss_lock);
@@ -1156,9 +1094,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
 		break;
 	case WFX_STATE_AP:
 		wvif->sta_asleep_mask = 0;
-		wvif->mcast_tx = false;
-		wvif->aid0_bit_set = false;
-		wvif->mcast_buffered = false;
 		/* reset.link_id = 0; */
 		hif_reset(wvif, false);
 		break;
@@ -1175,7 +1110,6 @@ void wfx_remove_interface(struct ieee80211_hw *hw,
 
 	wfx_cqm_bssloss_sm(wvif, 0, 0, 0);
 	cancel_work_sync(&wvif->unjoin_work);
-	del_timer_sync(&wvif->mcast_timeout);
 	wfx_free_event_queue(wvif);
 
 	wdev->vif[wvif->id] = NULL;
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 8491f050478d..5d61946e33e0 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -75,13 +75,8 @@ struct wfx_vif {
 
 	u32			link_id_map;
 
-	bool			aid0_bit_set;
-	bool			mcast_tx;
-	bool			mcast_buffered;
+	bool			after_dtim_tx_allowed;
 	struct wfx_grp_addr_table mcast_filter;
-	struct timer_list	mcast_timeout;
-	struct work_struct	mcast_start_work;
-	struct work_struct	mcast_stop_work;
 
 	s8			wep_default_key_id;
 	struct sk_buff		*wep_pending_skb;
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 58/65] staging: wfx: simplify wfx_ps_notify_sta()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (56 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 57/65] staging: wfx: simplify handling of IEEE80211_TX_CTL_SEND_AFTER_DTIM Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 59/65] staging: wfx: ensure that packet_id is unique Jérôme Pouiller
                   ` (7 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wfx_ps_notify_sta() is too complex compared to the task it do.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/sta.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c
index 01eee06a1ef4..726884091706 100644
--- a/drivers/staging/wfx/sta.c
+++ b/drivers/staging/wfx/sta.c
@@ -842,26 +842,14 @@ void wfx_bss_info_changed(struct ieee80211_hw *hw,
 static void wfx_ps_notify_sta(struct wfx_vif *wvif,
 			      enum sta_notify_cmd notify_cmd, int link_id)
 {
-	u32 bit, prev;
-
 	spin_lock_bh(&wvif->ps_state_lock);
-	bit = BIT(link_id);
-	prev = wvif->sta_asleep_mask & bit;
-
-	switch (notify_cmd) {
-	case STA_NOTIFY_SLEEP:
-		if (!prev) {
-			wvif->sta_asleep_mask |= bit;
-		}
-		break;
-	case STA_NOTIFY_AWAKE:
-		if (prev) {
-			wvif->sta_asleep_mask &= ~bit;
-			wfx_bh_request_tx(wvif->wdev);
-		}
-		break;
-	}
+	if (notify_cmd == STA_NOTIFY_SLEEP)
+		wvif->sta_asleep_mask |= BIT(link_id);
+	else // notify_cmd == STA_NOTIFY_AWAKE
+		wvif->sta_asleep_mask &= ~BIT(link_id);
 	spin_unlock_bh(&wvif->ps_state_lock);
+	if (notify_cmd == STA_NOTIFY_AWAKE)
+		wfx_bh_request_tx(wvif->wdev);
 }
 
 void wfx_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 59/65] staging: wfx: ensure that packet_id is unique
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (57 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 58/65] staging: wfx: simplify wfx_ps_notify_sta() Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 60/65] staging: wfx: remove unused do_probe Jérôme Pouiller
                   ` (6 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

In current code, packet_id is derivated from mac802.11 packet sequence
number, but this number is only unique for a station. It is not
sufficient.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/data_tx.c | 8 ++++++--
 drivers/staging/wfx/wfx.h     | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/wfx/data_tx.c b/drivers/staging/wfx/data_tx.c
index c32994553633..20f4740734f2 100644
--- a/drivers/staging/wfx/data_tx.c
+++ b/drivers/staging/wfx/data_tx.c
@@ -469,8 +469,12 @@ static int wfx_tx_inner(struct wfx_vif *wvif, struct ieee80211_sta *sta,
 
 	// Fill tx request
 	req = (struct hif_req_tx *)hif_msg->body;
-	req->packet_id = queue_id << 16 |
-			 IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl));
+	// packet_id just need to be unique on device. 32bits are more than
+	// necessary for that task, so we tae advantage of it to add some extra
+	// data for debug.
+	req->packet_id = queue_id << 28 |
+			 IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)) << 16 |
+			 (atomic_add_return(1, &wvif->wdev->packet_id) & 0xFFFF);
 	req->data_flags.fc_offset = offset;
 	if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)
 		req->data_flags.after_dtim = 1;
diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h
index 5d61946e33e0..8b85bb1abb9c 100644
--- a/drivers/staging/wfx/wfx.h
+++ b/drivers/staging/wfx/wfx.h
@@ -54,6 +54,7 @@ struct wfx_dev {
 	int			tx_burst_idx;
 	atomic_t		tx_lock;
 
+	atomic_t		packet_id;
 	u32			key_map;
 	struct hif_req_add_key	keys[MAX_KEY_ENTRIES];
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 60/65] staging: wfx: remove unused do_probe
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (58 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 59/65] staging: wfx: ensure that packet_id is unique Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 61/65] staging: wfx: remove check for interface state Jérôme Pouiller
                   ` (5 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The identifier do_probe is unused since "staging: wfx: remove workaround
to send probe requests"

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/queue.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c
index ec11a63a2ff9..c87d64fbb88f 100644
--- a/drivers/staging/wfx/queue.c
+++ b/drivers/staging/wfx/queue.c
@@ -365,7 +365,6 @@ static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb,
 	struct ieee80211_hdr *frame = (struct ieee80211_hdr *) (req->frame + req->data_flags.fc_offset);
 
 	enum {
-		do_probe,
 		do_drop,
 		do_wep,
 		do_tx,
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 61/65] staging: wfx: remove check for interface state
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (59 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 60/65] staging: wfx: remove unused do_probe Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 62/65] staging: wfx: simplify hif_handle_tx_data() Jérôme Pouiller
                   ` (4 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Obviously, the value of wvif->state as no reason to be wrong. At least,
if it the case, dropping the frame is probably not the bast thing to do.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/queue.c | 50 +++++++++----------------------------
 1 file changed, 12 insertions(+), 38 deletions(-)

diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c
index c87d64fbb88f..e0c609c35a7b 100644
--- a/drivers/staging/wfx/queue.c
+++ b/drivers/staging/wfx/queue.c
@@ -365,52 +365,26 @@ static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb,
 	struct ieee80211_hdr *frame = (struct ieee80211_hdr *) (req->frame + req->data_flags.fc_offset);
 
 	enum {
-		do_drop,
 		do_wep,
 		do_tx,
 	} action = do_tx;
 
-	switch (wvif->vif->type) {
-	case NL80211_IFTYPE_STATION:
-		if (wvif->state < WFX_STATE_PRE_STA)
-			action = do_drop;
-		break;
-	case NL80211_IFTYPE_AP:
-		if (!wvif->state)
-			action = do_drop;
-		break;
-	case NL80211_IFTYPE_ADHOC:
-		if (wvif->state != WFX_STATE_IBSS)
-			action = do_drop;
-		break;
-	case NL80211_IFTYPE_MONITOR:
-	default:
-		action = do_drop;
-		break;
-	}
-
-	if (action == do_tx) {
-		if (ieee80211_is_nullfunc(frame->frame_control)) {
-			mutex_lock(&wvif->bss_loss_lock);
-			if (wvif->bss_loss_state) {
-				wvif->bss_loss_confirm_id = req->packet_id;
-				req->queue_id.queue_id = HIF_QUEUE_ID_VOICE;
-			}
-			mutex_unlock(&wvif->bss_loss_lock);
-		} else if (ieee80211_has_protected(frame->frame_control) &&
-			   tx_priv->hw_key &&
-			   tx_priv->hw_key->keyidx != wvif->wep_default_key_id &&
-			   (tx_priv->hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
-			    tx_priv->hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
-			action = do_wep;
+	if (ieee80211_is_nullfunc(frame->frame_control)) {
+		mutex_lock(&wvif->bss_loss_lock);
+		if (wvif->bss_loss_state) {
+			wvif->bss_loss_confirm_id = req->packet_id;
+			req->queue_id.queue_id = HIF_QUEUE_ID_VOICE;
 		}
+		mutex_unlock(&wvif->bss_loss_lock);
+	} else if (ieee80211_has_protected(frame->frame_control) &&
+		   tx_priv->hw_key &&
+		   tx_priv->hw_key->keyidx != wvif->wep_default_key_id &&
+		   (tx_priv->hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+		    tx_priv->hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
+		action = do_wep;
 	}
 
 	switch (action) {
-	case do_drop:
-		wfx_pending_remove(wvif->wdev, skb);
-		handled = true;
-		break;
 	case do_wep:
 		wfx_tx_lock(wvif->wdev);
 		WARN_ON(wvif->wep_pending_skb);
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 62/65] staging: wfx: simplify hif_handle_tx_data()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (60 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 61/65] staging: wfx: remove check for interface state Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 63/65] staging: wfx: simplify wfx_tx_queue_get_num_queued() Jérôme Pouiller
                   ` (3 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Since enum action has now only two cases, it can be dropped. Then
hif_handle_tx_data() can be simplified.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/queue.c | 40 ++++++++++++++-----------------------
 1 file changed, 15 insertions(+), 25 deletions(-)

diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c
index e0c609c35a7b..024497eb19ac 100644
--- a/drivers/staging/wfx/queue.c
+++ b/drivers/staging/wfx/queue.c
@@ -359,16 +359,13 @@ bool wfx_tx_queues_is_empty(struct wfx_dev *wdev)
 static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb,
 			       struct wfx_queue *queue)
 {
-	bool handled = false;
-	struct wfx_tx_priv *tx_priv = wfx_skb_tx_priv(skb);
 	struct hif_req_tx *req = wfx_skb_txreq(skb);
-	struct ieee80211_hdr *frame = (struct ieee80211_hdr *) (req->frame + req->data_flags.fc_offset);
-
-	enum {
-		do_wep,
-		do_tx,
-	} action = do_tx;
+	struct ieee80211_key_conf *hw_key = wfx_skb_tx_priv(skb)->hw_key;
+	struct ieee80211_hdr *frame =
+		(struct ieee80211_hdr *)(req->frame + req->data_flags.fc_offset);
 
+	// FIXME: mac80211 is smart enough to handle BSS loss. Driver should not
+	// try to do anything about that.
 	if (ieee80211_is_nullfunc(frame->frame_control)) {
 		mutex_lock(&wvif->bss_loss_lock);
 		if (wvif->bss_loss_state) {
@@ -376,31 +373,24 @@ static bool hif_handle_tx_data(struct wfx_vif *wvif, struct sk_buff *skb,
 			req->queue_id.queue_id = HIF_QUEUE_ID_VOICE;
 		}
 		mutex_unlock(&wvif->bss_loss_lock);
-	} else if (ieee80211_has_protected(frame->frame_control) &&
-		   tx_priv->hw_key &&
-		   tx_priv->hw_key->keyidx != wvif->wep_default_key_id &&
-		   (tx_priv->hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
-		    tx_priv->hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
-		action = do_wep;
 	}
 
-	switch (action) {
-	case do_wep:
+	// FIXME: identify the exact scenario matched by this condition. Does it
+	// happen yet?
+	if (ieee80211_has_protected(frame->frame_control) &&
+	    hw_key && hw_key->keyidx != wvif->wep_default_key_id &&
+	    (hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
+	     hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
 		wfx_tx_lock(wvif->wdev);
 		WARN_ON(wvif->wep_pending_skb);
-		wvif->wep_default_key_id = tx_priv->hw_key->keyidx;
+		wvif->wep_default_key_id = hw_key->keyidx;
 		wvif->wep_pending_skb = skb;
 		if (!schedule_work(&wvif->wep_key_work))
 			wfx_tx_unlock(wvif->wdev);
-		handled = true;
-		break;
-	case do_tx:
-		break;
-	default:
-		/* Do nothing */
-		break;
+		return true;
+	} else {
+		return false;
 	}
-	return handled;
 }
 
 static int wfx_get_prio_queue(struct wfx_vif *wvif,
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 63/65] staging: wfx: simplify wfx_tx_queue_get_num_queued()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (61 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 62/65] staging: wfx: simplify hif_handle_tx_data() Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 64/65] staging: wfx: simplify hif_multi_tx_confirm() Jérôme Pouiller
                   ` (2 subsequent siblings)
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

wfx_tx_queue_get_num_queued() can take advantage of BIT() instead of
maintaining one variable for a counter and another for a mask.

In add, wfx_tx_queue_get_num_queued() has no real reason to return a
size_t instead of an int.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/queue.c | 14 +++++---------
 drivers/staging/wfx/queue.h |  2 +-
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/wfx/queue.c b/drivers/staging/wfx/queue.c
index 024497eb19ac..0bcc61feee1d 100644
--- a/drivers/staging/wfx/queue.c
+++ b/drivers/staging/wfx/queue.c
@@ -175,11 +175,9 @@ void wfx_tx_queues_deinit(struct wfx_dev *wdev)
 	wfx_tx_queues_clear(wdev);
 }
 
-size_t wfx_tx_queue_get_num_queued(struct wfx_queue *queue,
-				   u32 link_id_map)
+int wfx_tx_queue_get_num_queued(struct wfx_queue *queue, u32 link_id_map)
 {
-	size_t ret;
-	int i, bit;
+	int ret, i;
 
 	if (!link_id_map)
 		return 0;
@@ -189,11 +187,9 @@ size_t wfx_tx_queue_get_num_queued(struct wfx_queue *queue,
 		ret = skb_queue_len(&queue->queue);
 	} else {
 		ret = 0;
-		for (i = 0, bit = 1; i < ARRAY_SIZE(queue->link_map_cache);
-		     ++i, bit <<= 1) {
-			if (link_id_map & bit)
+		for (i = 0; i < ARRAY_SIZE(queue->link_map_cache); i++)
+			if (link_id_map & BIT(i))
 				ret += queue->link_map_cache[i];
-		}
 	}
 	spin_unlock_bh(&queue->queue.lock);
 	return ret;
@@ -555,7 +551,7 @@ struct hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev)
 
 		/* allow bursting if txop is set */
 		if (wvif->edca_params[queue_num].txop)
-			burst = (int)wfx_tx_queue_get_num_queued(queue, tx_allowed_mask) + 1;
+			burst = wfx_tx_queue_get_num_queued(queue, tx_allowed_mask) + 1;
 		else
 			burst = 1;
 
diff --git a/drivers/staging/wfx/queue.h b/drivers/staging/wfx/queue.h
index 096ae86135cc..90bb060d1204 100644
--- a/drivers/staging/wfx/queue.h
+++ b/drivers/staging/wfx/queue.h
@@ -51,7 +51,7 @@ struct hif_msg *wfx_tx_queues_get_after_dtim(struct wfx_vif *wvif);
 
 void wfx_tx_queue_put(struct wfx_dev *wdev, struct wfx_queue *queue,
 		      struct sk_buff *skb);
-size_t wfx_tx_queue_get_num_queued(struct wfx_queue *queue, u32 link_id_map);
+int wfx_tx_queue_get_num_queued(struct wfx_queue *queue, u32 link_id_map);
 
 struct sk_buff *wfx_pending_get(struct wfx_dev *wdev, u32 packet_id);
 int wfx_pending_remove(struct wfx_dev *wdev, struct sk_buff *skb);
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 64/65] staging: wfx: simplify hif_multi_tx_confirm()
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (62 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 63/65] staging: wfx: simplify wfx_tx_queue_get_num_queued() Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 12:13 ` [PATCH 65/65] staging: wfx: update TODO Jérôme Pouiller
  2020-01-15 13:40 ` [PATCH 00/65] Simplify and improve the wfx driver Greg Kroah-Hartman
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Usage of the "buf_loc" variable does not simplify the function.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_rx.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c
index f798cd6973b6..33c22c5d629d 100644
--- a/drivers/staging/wfx/hif_rx.c
+++ b/drivers/staging/wfx/hif_rx.c
@@ -77,21 +77,16 @@ static int hif_multi_tx_confirm(struct wfx_dev *wdev,
 				const struct hif_msg *hif, const void *buf)
 {
 	const struct hif_cnf_multi_transmit *body = buf;
-	const struct hif_cnf_tx *buf_loc =
-		(const struct hif_cnf_tx *)&body->tx_conf_payload;
 	struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface);
-	int count = body->num_tx_confs;
 	int i;
 
-	WARN(count <= 0, "corrupted message");
+	WARN(body->num_tx_confs <= 0, "corrupted message");
 	WARN_ON(!wvif);
 	if (!wvif)
 		return -EFAULT;
 
-	for (i = 0; i < count; ++i) {
-		wfx_tx_confirm_cb(wvif, buf_loc);
-		buf_loc++;
-	}
+	for (i = 0; i < body->num_tx_confs; i++)
+		wfx_tx_confirm_cb(wvif, &body->tx_conf_payload[i]);
 	return 0;
 }
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH 65/65] staging: wfx: update TODO
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (63 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 64/65] staging: wfx: simplify hif_multi_tx_confirm() Jérôme Pouiller
@ 2020-01-15 12:13 ` Jérôme Pouiller
  2020-01-15 13:40 ` [PATCH 00/65] Simplify and improve the wfx driver Greg Kroah-Hartman
  65 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 12:13 UTC (permalink / raw)
  To: devel, linux-wireless
  Cc: netdev, linux-kernel, Greg Kroah-Hartman, Kalle Valo,
	David S . Miller, Jérôme Pouiller

From: Jérôme Pouiller <jerome.pouiller@silabs.com>

Some work has been done :)

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/TODO | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/staging/wfx/TODO b/drivers/staging/wfx/TODO
index 6b1cdd24afc9..efcb7c6a5aa7 100644
--- a/drivers/staging/wfx/TODO
+++ b/drivers/staging/wfx/TODO
@@ -1,18 +1,8 @@
 This is a list of things that need to be done to get this driver out of the
 staging directory.
 
-  - Allocation of "link ids" is too complex. Allocation/release of link ids from
-    sta_add()/sta_remove() should be sufficient.
-
-  - The path for packets with IEEE80211_TX_CTL_SEND_AFTER_DTIM flags should be
-    cleaned up. Currently, the process involve multiple work structs and a
-    timer. It could be simplifed. In add, the requeue mechanism triggers more
-    frequently than it should.
-
   - All structures defined in hif_api_*.h are intended to sent/received to/from
-    hardware. All their members whould be declared __le32 or __le16. These
-    structs should only been used in files named hif_* (and maybe in data_*.c).
-    The upper layers (sta.c, scan.c etc...) should manage mac80211 structures.
+    hardware. All their members whould be declared __le32 or __le16.
     See:
        https://lore.kernel.org/lkml/20191111202852.GX26530@ZenIV.linux.org.uk
 
-- 
2.25.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* Re: [PATCH 00/65] Simplify and improve the wfx driver
  2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
                   ` (64 preceding siblings ...)
  2020-01-15 12:13 ` [PATCH 65/65] staging: wfx: update TODO Jérôme Pouiller
@ 2020-01-15 13:40 ` Greg Kroah-Hartman
  2020-01-15 13:50   ` Jérôme Pouiller
  65 siblings, 1 reply; 68+ messages in thread
From: Greg Kroah-Hartman @ 2020-01-15 13:40 UTC (permalink / raw)
  To: Jérôme Pouiller
  Cc: devel, linux-wireless, netdev, linux-kernel, David S . Miller,
	Kalle Valo

On Wed, Jan 15, 2020 at 12:12:07PM +0000, Jérôme Pouiller wrote:
> From: Jérôme Pouiller <jerome.pouiller@silabs.com>
> 
> Hello all,
> 
> This pull request is finally bigger than I expected, sorry.

After applying this series, I get this build error:

drivers/staging/wfx/sta.c: In function ‘wfx_cqm_bssloss_sm’:
drivers/staging/wfx/sta.c:91:28: error: expected ‘;’ before ‘struct’
   91 |   struct ieee80211_hdr *hdr
      |                            ^
      |                            ;
   92 |   struct ieee80211_tx_control control = { };
      |   ~~~~~~
drivers/staging/wfx/sta.c:99:3: error: ‘hdr’ undeclared (first use in this function); did you mean ‘idr’?
   99 |   hdr = (struct ieee80211_hdr *)skb->data;
      |   ^~~
      |   idr

Did you even test-build this?

I could try to bisect and track down the offending commit, but that's
too much work :)

I'll wait for a v2 of this series, please fix up and resend.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH 00/65] Simplify and improve the wfx driver
  2020-01-15 13:40 ` [PATCH 00/65] Simplify and improve the wfx driver Greg Kroah-Hartman
@ 2020-01-15 13:50   ` Jérôme Pouiller
  0 siblings, 0 replies; 68+ messages in thread
From: Jérôme Pouiller @ 2020-01-15 13:50 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: devel, linux-wireless, netdev, linux-kernel, David S . Miller,
	Kalle Valo

On Wednesday 15 January 2020 14:40:10 CET Greg Kroah-Hartman wrote:
> On Wed, Jan 15, 2020 at 12:12:07PM +0000, Jérôme Pouiller wrote:
> > From: Jérôme Pouiller <jerome.pouiller@silabs.com>
> >
> > Hello all,
> >
> > This pull request is finally bigger than I expected, sorry.
> 
> After applying this series, I get this build error:
> 
> drivers/staging/wfx/sta.c: In function ‘wfx_cqm_bssloss_sm’:
> drivers/staging/wfx/sta.c:91:28: error: expected ‘;’ before ‘struct’
>    91 |   struct ieee80211_hdr *hdr
>       |                            ^
>       |                            ;
>    92 |   struct ieee80211_tx_control control = { };
>       |   ~~~~~~
> drivers/staging/wfx/sta.c:99:3: error: ‘hdr’ undeclared (first use in this function); did you mean ‘idr’?
>    99 |   hdr = (struct ieee80211_hdr *)skb->data;
>       |   ^~~
>       |   idr
> 
> Did you even test-build this?

Arf, I have not tried to built after having fixed warnings from
checkpatch. Shame on me.


-- 
Jérôme Pouiller


^ permalink raw reply	[flat|nested] 68+ messages in thread

end of thread, other threads:[~2020-01-15 13:50 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-15 12:12 [PATCH 00/65] Simplify and improve the wfx driver Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 01/65] staging: wfx: revert unexpected change in debugfs output Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 02/65] staging: wfx: make hif_scan() usage clearer Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 03/65] staging: wfx: add missing PROBE_RESP_OFFLOAD feature Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 04/65] staging: wfx: send rate policies one by one Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 05/65] staging: wfx: simplify hif_set_tx_rate_retry_policy() usage Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 06/65] staging: wfx: simplify hif_set_output_power() usage Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 07/65] staging: wfx: simplify hif_set_rcpi_rssi_threshold() usage Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 08/65] staging: wfx: simplify hif_set_arp_ipv4_filter() usage Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 09/65] staging: wfx: simplify hif_start() usage Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 10/65] staging: wfx: use specialized structs for HIF arguments Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 11/65] staging: wfx: retrieve ampdu_density from sta->ht_cap Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 12/65] staging: wfx: retrieve greenfield mode from sta->ht_cap and bss_conf Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 13/65] staging: wfx: drop struct wfx_ht_info Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 14/65] staging: wfx: drop wdev->output_power Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 15/65] staging: wfx: simplify wfx_config() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 16/65] staging: wfx: rename wfx_upload_beacon() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 17/65] staging: wfx: simplify wfx_upload_ap_templates() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 18/65] staging: wfx: simplify wfx_update_beaconing() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 19/65] staging: wfx: fix __wfx_flush() when drop == false Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 20/65] staging: wfx: simplify wfx_flush() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 21/65] staging: wfx: simplify update of DTIM period Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 22/65] staging: wfx: drop wvif->dtim_period Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 23/65] staging: wfx: drop wvif->enable_beacon Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 24/65] staging: wfx: drop wvif->cqm_rssi_thold Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 25/65] staging: wfx: drop wvif->setbssparams_done Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 26/65] staging: wfx: drop wfx_set_cts_work() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 27/65] staging: wfx: SSID should be provided to hif_start() even if hidden Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 28/65] staging: wfx: simplify hif_update_ie() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 29/65] staging: wfx: simplify hif_join() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 30/65] staging: wfx: simplify hif_set_association_mode() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 31/65] staging: wfx: simplify hif_set_uc_mc_bc_condition() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 32/65] staging: wfx: simplify hif_mib_uc_mc_bc_data_frame_condition Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 33/65] staging: wfx: simplify hif_mib_set_data_filtering Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 34/65] staging: wfx: simplify hif_set_data_filtering() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 35/65] staging: wfx: simplify hif_set_mac_addr_condition() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 36/65] staging: wfx: simplify hif_set_config_data_filter() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 37/65] staging: wfx: simplify wfx_set_mcast_filter() Jérôme Pouiller
2020-01-15 12:12 ` [PATCH 38/65] staging: wfx: simplify wfx_update_filtering() Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 39/65] staging: wfx: simplify wfx_scan_complete() Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 40/65] staging: wfx: update power-save per interface Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 41/65] staging: wfx: with multiple vifs, force PS only if channels differs Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 42/65] staging: wfx: do not update uapsd if not necessary Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 43/65] staging: wfx: fix case where RTS threshold is 0 Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 44/65] staging: wfx: fix possible overflow on jiffies comparaison Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 45/65] staging: wfx: remove handling of "early_data" Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 46/65] staging: wfx: relocate "buffered" information to sta_priv Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 47/65] staging: wfx: fix bss_loss Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 48/65] staging: wfx: fix RCU usage Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 49/65] staging: wfx: simplify wfx_set_tim_impl() Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 50/65] staging: wfx: simplify the link-id allocation Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 51/65] staging: wfx: check that no tx is pending before release sta Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 52/65] staging: wfx: replace wfx_tx_get_tid() with ieee80211_get_tid() Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 53/65] staging: wfx: pspoll_mask make no sense Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 54/65] staging: wfx: sta and dtim Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 55/65] staging: wfx: firmware never return PS status for stations Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 56/65] staging: wfx: simplify wfx_suspend_resume_mc() Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 57/65] staging: wfx: simplify handling of IEEE80211_TX_CTL_SEND_AFTER_DTIM Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 58/65] staging: wfx: simplify wfx_ps_notify_sta() Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 59/65] staging: wfx: ensure that packet_id is unique Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 60/65] staging: wfx: remove unused do_probe Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 61/65] staging: wfx: remove check for interface state Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 62/65] staging: wfx: simplify hif_handle_tx_data() Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 63/65] staging: wfx: simplify wfx_tx_queue_get_num_queued() Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 64/65] staging: wfx: simplify hif_multi_tx_confirm() Jérôme Pouiller
2020-01-15 12:13 ` [PATCH 65/65] staging: wfx: update TODO Jérôme Pouiller
2020-01-15 13:40 ` [PATCH 00/65] Simplify and improve the wfx driver Greg Kroah-Hartman
2020-01-15 13:50   ` Jérôme Pouiller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).