Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH v2 05/11] wlcore: cleanup scan debug prints
From: Eliad Peller @ 2013-09-17 15:41 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1379432490-22157-1-git-send-email-eliad@wizery.com>

From: Victor Goldenshtein <victorg@ti.com>

Remove scan debug dumps which are rarely used.
Make scan debug prints more clear and short.

Signed-off-by: Victor Goldenshtein <victorg@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
v1->v2: fix some formatting issues

 drivers/net/wireless/ti/wlcore/cmd.c  |  6 +++---
 drivers/net/wireless/ti/wlcore/scan.c | 27 +++++++++++++--------------
 2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index c9e0607..e3ae425 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1126,6 +1126,8 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 	u16 template_id_2_4 = wl->scan_templ_id_2_4;
 	u16 template_id_5 = wl->scan_templ_id_5;
 
+	wl1271_debug(DEBUG_SCAN, "build probe request band %d", band);
+
 	skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
 				     ie_len);
 	if (!skb) {
@@ -1135,8 +1137,6 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 	if (ie_len)
 		memcpy(skb_put(skb, ie_len), ie, ie_len);
 
-	wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
-
 	if (sched_scan &&
 	    (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) {
 		template_id_2_4 = wl->sched_scan_templ_id_2_4;
@@ -1172,7 +1172,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
 	if (!skb)
 		goto out;
 
-	wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len);
+	wl1271_debug(DEBUG_SCAN, "set ap probe request template");
 
 	rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[wlvif->band]);
 	if (wlvif->band == IEEE80211_BAND_2GHZ)
diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
index f407101..13e743d 100644
--- a/drivers/net/wireless/ti/wlcore/scan.c
+++ b/drivers/net/wireless/ti/wlcore/scan.c
@@ -174,17 +174,7 @@ wlcore_scan_get_channels(struct wl1271 *wl,
 		    /* if radar is set, we ignore the passive flag */
 		    (radar ||
 		     !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) {
-			wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
-				     req_channels[i]->band,
-				     req_channels[i]->center_freq);
-			wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
-				     req_channels[i]->hw_value,
-				     req_channels[i]->flags);
-			wl1271_debug(DEBUG_SCAN, "max_power %d",
-				     req_channels[i]->max_power);
-			wl1271_debug(DEBUG_SCAN, "min_dwell_time %d max dwell time %d",
-				     min_dwell_time_active,
-				     max_dwell_time_active);
+
 
 			if (flags & IEEE80211_CHAN_RADAR) {
 				channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
@@ -222,6 +212,17 @@ wlcore_scan_get_channels(struct wl1271 *wl,
 					     *n_pactive_ch);
 			}
 
+			wl1271_debug(DEBUG_SCAN, "freq %d, ch. %d, flags 0x%x, power %d, min/max_dwell %d/%d%s%s",
+				     req_channels[i]->center_freq,
+				     req_channels[i]->hw_value,
+				     req_channels[i]->flags,
+				     req_channels[i]->max_power,
+				     min_dwell_time_active,
+				     max_dwell_time_active,
+				     flags & IEEE80211_CHAN_RADAR ?
+					", DFS" : "",
+				     flags & IEEE80211_CHAN_PASSIVE_SCAN ?
+					", PASSIVE" : "");
 			j++;
 		}
 	}
@@ -364,7 +365,7 @@ wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl,
 	struct cfg80211_ssid *ssids = req->ssids;
 	int ret = 0, type, i, j, n_match_ssids = 0;
 
-	wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list");
+	wl1271_debug((DEBUG_CMD | DEBUG_SCAN), "cmd sched scan ssid list");
 
 	/* count the match sets that contain SSIDs */
 	for (i = 0; i < req->n_match_sets; i++)
@@ -442,8 +443,6 @@ wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl,
 		}
 	}
 
-	wl1271_dump(DEBUG_SCAN, "SSID_LIST: ", cmd, sizeof(*cmd));
-
 	ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd,
 			      sizeof(*cmd), 0);
 	if (ret < 0) {
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH v2 04/11] wlcore: re-enable idle handling
From: Eliad Peller @ 2013-09-17 15:41 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1379432490-22157-1-git-send-email-eliad@wizery.com>

From: Arik Nemtsov <arik@wizery.com>

We need some stuff done on idle change, most notably we have to stop
sched-scanning. Take care of this by reintroducing idle handling.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/main.c     | 22 ++++++++++++++++++++++
 drivers/net/wireless/ti/wlcore/wlcore_i.h |  1 +
 2 files changed, 23 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 611e81d..d952593 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -2927,6 +2927,25 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
 	wlvif->rate_set = wlvif->basic_rate_set;
 }
 
+static void wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+				   bool idle)
+{
+	bool cur_idle = !test_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+
+	if (idle == cur_idle)
+		return;
+
+	if (idle) {
+		clear_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+	} else {
+		/* The current firmware only supports sched_scan in idle */
+		if (wl->sched_vif == wlvif)
+			wl->ops->sched_scan_stop(wl, wlvif);
+
+		set_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+	}
+}
+
 static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 			     struct ieee80211_conf *conf, u32 changed)
 {
@@ -4179,6 +4198,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
 		do_join = true;
 	}
 
+	if (changed & BSS_CHANGED_IDLE && !is_ibss)
+		wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle);
+
 	if (changed & BSS_CHANGED_CQM) {
 		bool enable = false;
 		if (bss_conf->cqm_rssi_thold)
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 3f4f08b..2a50e08 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -255,6 +255,7 @@ enum wl12xx_vif_flags {
 	WLVIF_FLAG_CS_PROGRESS,
 	WLVIF_FLAG_AP_PROBE_RESP_SET,
 	WLVIF_FLAG_IN_USE,
+	WLVIF_FLAG_ACTIVE,
 };
 
 struct wl12xx_vif;
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH v2 03/11] wlcore: disable elp sleep while in plt mode
From: Eliad Peller @ 2013-09-17 15:41 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1379432490-22157-1-git-send-email-eliad@wizery.com>

From: Yair Shapira <yair.shapira@ti.com>

We now disable elp sleep during plt mode to allow normal operation of
plt tools such as calibrator.

Having elp_sleep enabled during plt mode is actually not required and
in fact it disrupt plt operations such as rx statistics etc.

Signed-off-by: Yair Shapira <yair.shapira@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/ps.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 98066d4..26bfc36 100644
--- a/drivers/net/wireless/ti/wlcore/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -83,6 +83,10 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
 	struct wl12xx_vif *wlvif;
 	u32 timeout;
 
+	/* We do not enter elp sleep in PLT mode */
+	if (wl->plt)
+		return;
+
 	if (wl->sleep_auth != WL1271_PSM_ELP)
 		return;
 
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH v2 02/11] wlcore: add new plt power-mode: CHIP_AWAKE
From: Eliad Peller @ 2013-09-17 15:41 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1379432490-22157-1-git-send-email-eliad@wizery.com>

From: Yair Shapira <yair.shapira@ti.com>

Under this mode the chip is powered on including sdio
but no FW is downloaded and run, interrupts are not enabled, etc...

This mode is intended to allow RTTT to bridge sdio as a transport
to the chip.

Driver only provides sdio access using the dev_mem debugfs file.

Some fixes done to the code that ensures that PLT mode and normal
driver power mode (ifconfig/add_interface) are mutually excluded.

Signed-off-by: Yair Shapira <yair.shapira@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/main.c     | 16 ++++++++++++----
 drivers/net/wireless/ti/wlcore/testmode.c | 13 +++++++++++--
 drivers/net/wireless/ti/wlcore/wlcore_i.h |  1 +
 3 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index b64b465..611e81d 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1062,7 +1062,8 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode)
 	static const char* const PLT_MODE[] = {
 		"PLT_OFF",
 		"PLT_ON",
-		"PLT_FEM_DETECT"
+		"PLT_FEM_DETECT",
+		"PLT_CHIP_AWAKE"
 	};
 
 	int ret;
@@ -1088,9 +1089,11 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode)
 		if (ret < 0)
 			goto power_off;
 
-		ret = wl->ops->plt_init(wl);
-		if (ret < 0)
-			goto power_off;
+		if (plt_mode != PLT_CHIP_AWAKE) {
+			ret = wl->ops->plt_init(wl);
+			if (ret < 0)
+				goto power_off;
+		}
 
 		wl->state = WLCORE_STATE_ON;
 		wl1271_notice("firmware booted in PLT mode %s (%s)",
@@ -2419,6 +2422,11 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
 	int ret = 0;
 	u8 role_type;
 
+	if (wl->plt) {
+		wl1271_error("Adding Interface not allowed while in PLT mode");
+		return -EBUSY;
+	}
+
 	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
 			     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
 
diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c
index 527590f..a3b7d95 100644
--- a/drivers/net/wireless/ti/wlcore/testmode.c
+++ b/drivers/net/wireless/ti/wlcore/testmode.c
@@ -297,7 +297,8 @@ static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
 		ret = wl1271_plt_stop(wl);
 		break;
 	case PLT_ON:
-		ret = wl1271_plt_start(wl, PLT_ON);
+	case PLT_CHIP_AWAKE:
+		ret = wl1271_plt_start(wl, val);
 		break;
 	case PLT_FEM_DETECT:
 		ret = wl1271_tm_detect_fem(wl, tb);
@@ -361,6 +362,7 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 {
 	struct wl1271 *wl = hw->priv;
 	struct nlattr *tb[WL1271_TM_ATTR_MAX + 1];
+	u32 nla_cmd;
 	int err;
 
 	err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy);
@@ -370,7 +372,14 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 	if (!tb[WL1271_TM_ATTR_CMD_ID])
 		return -EINVAL;
 
-	switch (nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID])) {
+	nla_cmd = nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID]);
+
+	/* Only SET_PLT_MODE is allowed in case of mode PLT_CHIP_AWAKE */
+	if (wl->plt_mode == PLT_CHIP_AWAKE &&
+	    nla_cmd != WL1271_TM_CMD_SET_PLT_MODE)
+		return -EOPNOTSUPP;
+
+	switch (nla_cmd) {
 	case WL1271_TM_CMD_TEST:
 		return wl1271_tm_cmd_test(wl, tb);
 	case WL1271_TM_CMD_INTERROGATE:
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 14fd111..3f4f08b 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -307,6 +307,7 @@ enum plt_mode {
 	PLT_OFF = 0,
 	PLT_ON = 1,
 	PLT_FEM_DETECT = 2,
+	PLT_CHIP_AWAKE = 3
 };
 
 struct wl12xx_rx_filter_field {
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH v2 01/11] wlcore: ROC on AP channel before auth reply
From: Eliad Peller @ 2013-09-17 15:41 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless

From: Arik Nemtsov <arik@wizery.com>

Start a ROC on the AP channel beforing sending the authentication reply
to a connecting STA. This ROC is held up to 1 second via a timer. If the
station is authorized and added by mac80211, the ROC is extended until
the station is fully authorized.
We make sure not to ROC twice when several stations are connecting in
parallel and to only release the ROC when both the pending-reply timer
and the STA-state callbacks do not require it.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/ti/wlcore/main.c     | 101 +++++++++++++++++++++++++-----
 drivers/net/wireless/ti/wlcore/tx.c       |  25 ++++++--
 drivers/net/wireless/ti/wlcore/tx.h       |   3 +
 drivers/net/wireless/ti/wlcore/wlcore.h   |   2 +
 drivers/net/wireless/ti/wlcore/wlcore_i.h |   9 +++
 5 files changed, 120 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 38995f9..b64b465 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -2008,6 +2008,47 @@ out:
 	mutex_unlock(&wl->mutex);
 }
 
+static void wlcore_pending_auth_complete_work(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct wl1271 *wl;
+	struct wl12xx_vif *wlvif;
+	unsigned long time_spare;
+	int ret;
+
+	dwork = container_of(work, struct delayed_work, work);
+	wlvif = container_of(dwork, struct wl12xx_vif,
+			     pending_auth_complete_work);
+	wl = wlvif->wl;
+
+	mutex_lock(&wl->mutex);
+
+	if (unlikely(wl->state != WLCORE_STATE_ON))
+		goto out;
+
+	/*
+	 * Make sure a second really passed since the last auth reply. Maybe
+	 * a second auth reply arrived while we were stuck on the mutex.
+	 * Check for a little less than the timeout to protect from scheduler
+	 * irregularities.
+	 */
+	time_spare = jiffies +
+			msecs_to_jiffies(WLCORE_PEND_AUTH_ROC_TIMEOUT - 50);
+	if (!time_after(time_spare, wlvif->pending_auth_reply_time))
+		goto out;
+
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	/* cancel the ROC if active */
+	wlcore_update_inconn_sta(wl, wlvif, NULL, false);
+
+	wl1271_ps_elp_sleep(wl);
+out:
+	mutex_unlock(&wl->mutex);
+}
+
 static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx)
 {
 	u8 policy = find_first_zero_bit(wl->rate_policies_map,
@@ -2159,6 +2200,8 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
 			  wlcore_channel_switch_work);
 	INIT_DELAYED_WORK(&wlvif->connection_loss_work,
 			  wlcore_connection_loss_work);
+	INIT_DELAYED_WORK(&wlvif->pending_auth_complete_work,
+			  wlcore_pending_auth_complete_work);
 	INIT_LIST_HEAD(&wlvif->list);
 
 	setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer,
@@ -2590,6 +2633,7 @@ unlock:
 	cancel_work_sync(&wlvif->rx_streaming_disable_work);
 	cancel_delayed_work_sync(&wlvif->connection_loss_work);
 	cancel_delayed_work_sync(&wlvif->channel_switch_work);
+	cancel_delayed_work_sync(&wlvif->pending_auth_complete_work);
 
 	mutex_lock(&wl->mutex);
 }
@@ -3969,6 +4013,13 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
 			}
 		} else {
 			if (test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
+				/*
+				 * AP might be in ROC in case we have just
+				 * sent auth reply. handle it.
+				 */
+				if (test_bit(wlvif->role_id, wl->roc_map))
+					wl12xx_croc(wl, wlvif->role_id);
+
 				ret = wl12xx_cmd_role_stop_ap(wl, wlvif);
 				if (ret < 0)
 					goto out;
@@ -4656,29 +4707,49 @@ static void wlcore_roc_if_possible(struct wl1271 *wl,
 	wl12xx_roc(wl, wlvif, wlvif->role_id, wlvif->band, wlvif->channel);
 }
 
-static void wlcore_update_inconn_sta(struct wl1271 *wl,
-				     struct wl12xx_vif *wlvif,
-				     struct wl1271_station *wl_sta,
-				     bool in_connection)
+/*
+ * when wl_sta is NULL, we treat this call as if coming from a
+ * pending auth reply.
+ * wl->mutex must be taken and the FW must be awake when the call
+ * takes place.
+ */
+void wlcore_update_inconn_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+			      struct wl1271_station *wl_sta, bool in_conn)
 {
-	if (in_connection) {
-		if (WARN_ON(wl_sta->in_connection))
+	if (in_conn) {
+		if (WARN_ON(wl_sta && wl_sta->in_connection))
 			return;
-		wl_sta->in_connection = true;
-		if (!wlvif->inconn_count++)
+
+		if (!wlvif->ap_pending_auth_reply &&
+		    !wlvif->inconn_count)
 			wlcore_roc_if_possible(wl, wlvif);
+
+		if (wl_sta) {
+			wl_sta->in_connection = true;
+			wlvif->inconn_count++;
+		} else {
+			wlvif->ap_pending_auth_reply = true;
+		}
 	} else {
-		if (!wl_sta->in_connection)
+		if (wl_sta && !wl_sta->in_connection)
+			return;
+
+		if (WARN_ON(!wl_sta && !wlvif->ap_pending_auth_reply))
 			return;
 
-		wl_sta->in_connection = false;
-		wlvif->inconn_count--;
-		if (WARN_ON(wlvif->inconn_count < 0))
+		if (WARN_ON(wl_sta && !wlvif->inconn_count))
 			return;
 
-		if (!wlvif->inconn_count)
-			if (test_bit(wlvif->role_id, wl->roc_map))
-				wl12xx_croc(wl, wlvif->role_id);
+		if (wl_sta) {
+			wl_sta->in_connection = false;
+			wlvif->inconn_count--;
+		} else {
+			wlvif->ap_pending_auth_reply = false;
+		}
+
+		if (!wlvif->inconn_count && !wlvif->ap_pending_auth_reply &&
+		    test_bit(wlvif->role_id, wl->roc_map))
+			wl12xx_croc(wl, wlvif->role_id);
 	}
 }
 
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 7e93fe6..03249da 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -86,19 +86,34 @@ void wl1271_free_tx_id(struct wl1271 *wl, int id)
 EXPORT_SYMBOL(wl1271_free_tx_id);
 
 static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
+						 struct wl12xx_vif *wlvif,
 						 struct sk_buff *skb)
 {
 	struct ieee80211_hdr *hdr;
 
+	hdr = (struct ieee80211_hdr *)(skb->data +
+				       sizeof(struct wl1271_tx_hw_descr));
+	if (!ieee80211_is_auth(hdr->frame_control))
+		return;
+
 	/*
 	 * add the station to the known list before transmitting the
 	 * authentication response. this way it won't get de-authed by FW
 	 * when transmitting too soon.
 	 */
-	hdr = (struct ieee80211_hdr *)(skb->data +
-				       sizeof(struct wl1271_tx_hw_descr));
-	if (ieee80211_is_auth(hdr->frame_control))
-		wl1271_acx_set_inconnection_sta(wl, hdr->addr1);
+	wl1271_acx_set_inconnection_sta(wl, hdr->addr1);
+
+	/*
+	 * ROC for 1 second on the AP channel for completing the connection.
+	 * Note the ROC will be continued by the update_sta_state callbacks
+	 * once the station reaches the associated state.
+	 */
+	wlcore_update_inconn_sta(wl, wlvif, NULL, true);
+	wlvif->pending_auth_reply_time = jiffies;
+	cancel_delayed_work(&wlvif->pending_auth_complete_work);
+	ieee80211_queue_delayed_work(wl->hw,
+				&wlvif->pending_auth_complete_work,
+				msecs_to_jiffies(WLCORE_PEND_AUTH_ROC_TIMEOUT));
 }
 
 static void wl1271_tx_regulate_link(struct wl1271 *wl,
@@ -404,7 +419,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 	wl1271_tx_fill_hdr(wl, wlvif, skb, extra, info, hlid);
 
 	if (!is_dummy && wlvif && wlvif->bss_type == BSS_TYPE_AP_BSS) {
-		wl1271_tx_ap_update_inconnection_sta(wl, skb);
+		wl1271_tx_ap_update_inconnection_sta(wl, wlvif, skb);
 		wl1271_tx_regulate_link(wl, wlvif, hlid);
 	}
 
diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h
index 55aa4ac..35489c3 100644
--- a/drivers/net/wireless/ti/wlcore/tx.h
+++ b/drivers/net/wireless/ti/wlcore/tx.h
@@ -56,6 +56,9 @@
 /* Used for management frames and dummy packets */
 #define WL1271_TID_MGMT 7
 
+/* stop a ROC for pending authentication reply after this time (ms) */
+#define WLCORE_PEND_AUTH_ROC_TIMEOUT     1000
+
 struct wl127x_tx_mem {
 	/*
 	 * Number of extra memory blocks to allocate for this packet
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 0034979..54ce5d5 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -481,6 +481,8 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
 		   struct ieee80211_sta *sta,
 		   struct ieee80211_key_conf *key_conf);
 void wlcore_regdomain_config(struct wl1271 *wl);
+void wlcore_update_inconn_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+			      struct wl1271_station *wl_sta, bool in_conn);
 
 static inline void
 wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band,
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index e5e1464..14fd111 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -456,6 +456,15 @@ struct wl12xx_vif {
 	 */
 	int hw_queue_base;
 
+	/* do we have a pending auth reply? (and ROC) */
+	bool ap_pending_auth_reply;
+
+	/* time when we sent the pending auth reply */
+	unsigned long pending_auth_reply_time;
+
+	/* work for canceling ROC after pending auth reply */
+	struct delayed_work pending_auth_complete_work;
+
 	/*
 	 * This struct must be last!
 	 * data that has to be saved acrossed reconfigs (e.g. recovery)
-- 
1.8.3.rc1.35.g9b79519


^ permalink raw reply related

* [PATCH v2] cfg80211: don't start p2p device while in RFKILL
From: Emmanuel Grumbach @ 2013-09-17 12:30 UTC (permalink / raw)
  To: linux-wireless; +Cc: Emmanuel Grumbach

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
v2: Check the rfkill before adding the interface
---
 net/wireless/nl80211.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 316503f..a344f23 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8659,6 +8659,9 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
 	if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
 		return -EOPNOTSUPP;
 
+	if (rfkill_blocked(rdev->rfkill))
+		return -ERFKILL;
+
 	if (wdev->p2p_started)
 		return 0;
 
-- 
1.7.10.4


^ permalink raw reply related

* RE: [PATCH] cfg80211: don't start p2p device while in RFKILL
From: Grumbach, Emmanuel @ 2013-09-17 12:25 UTC (permalink / raw)
  To: linux-wireless@vger.kernel.org
In-Reply-To: <1379420619-6123-1-git-send-email-emmanuel.grumbach@intel.com>

> -----Original Message-----
> From: Grumbach, Emmanuel
> Sent: Tuesday, September 17, 2013 3:24 PM
> To: linux-wireless@vger.kernel.org
> Cc: Grumbach, Emmanuel
> Subject: [PATCH] cfg80211: don't start p2p device while in RFKILL
> 
> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
> ---
>  net/wireless/nl80211.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index
> 316503f..6bb03b5 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -8666,6 +8666,9 @@ static int nl80211_start_p2p_device(struct sk_buff
> *skb, struct genl_info *info)
>  	if (err)
>  		return err;
> 
> +	if (rfkill_blocked(rdev->rfkill))
> +		return -ERFKILL;
> +
>  	err = rdev_start_p2p_device(rdev, wdev);
>  	if (err)
>  		return err;

This is bad... obviously I need to test that before I add the interface... v2 on the way

^ permalink raw reply

* [PATCH] cfg80211: don't start p2p device while in RFKILL
From: Emmanuel Grumbach @ 2013-09-17 12:23 UTC (permalink / raw)
  To: linux-wireless; +Cc: Emmanuel Grumbach

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 net/wireless/nl80211.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 316503f..6bb03b5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8666,6 +8666,9 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
 	if (err)
 		return err;
 
+	if (rfkill_blocked(rdev->rfkill))
+		return -ERFKILL;
+
 	err = rdev_start_p2p_device(rdev, wdev);
 	if (err)
 		return err;
-- 
1.7.10.4


^ permalink raw reply related

* Re: [RFC] mac80211: correctly close cancelled scans
From: Eliad Peller @ 2013-09-17 11:30 UTC (permalink / raw)
  To: Grumbach, Emmanuel; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <0BA3FCBA62E2DC44AF3030971E174FB301DB0B1C@HASMSX103.ger.corp.intel.com>

On Tue, Sep 17, 2013 at 2:28 PM, Grumbach, Emmanuel
<emmanuel.grumbach@intel.com> wrote:
>> On Tue, Sep 17, 2013 at 8:48 AM, Emmanuel Grumbach
>> <emmanuel.grumbach@intel.com> wrote:
>> > __ieee80211_scan_completed is called from a worker. This means that
>> > the following flow is possible.
>> >
>> >  * driver calls ieee80211_scan_completed
>> >  * mac80211 cancels the scan (that is already complete)
>> >  * __ieee80211_scan_complete runs
>> >
>> > When scan_work will finally run, it will see that the scan hasn't been
>> > aborted and might even trigger another scan on another band. This
>> > leads to a situation where cfg80211's scan is not done and no further
>> > scan can be issued.
>> >
>> > Fix this by setting a new flag when a HW scan is being cancelled so
>> > that no other scan will be triggered.
>> >
>> > Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
>> > ---
>> [...]
>>
>> >         if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
>> > -               if (local->ops->cancel_hw_scan)
>> > +               /*
>> > +                * Make sure that __ieee80211_scan_completed doesn't trigger a
>> > +                * scan on another band.
>> > +                */
>> > +               set_bit(SCAN_HW_CANCELLED, &local->scanning);
>> > +               if (local->ops->cancel_hw_scan) {
>> >                         drv_cancel_hw_scan(local,
>> >                                 rcu_dereference_protected(local->scan_sdata,
>> >
>> > lockdep_is_held(&local->mtx)));
>> > +               }
>> >                 goto out;
>> >         }
>>
>> you don't seem to clear this flag anywhere...
>>
>
> Yeah - just like SCAN_HW_SCANNING isn't cleared anywhere... but... in __ieee80211_scan_completed:
>
>         local->scanning = 0;
>         local->scan_chandef.chan = NULL;
>
> yes I know. Don't ask.

oh, right, i overlooked it :)

Eliad.

^ permalink raw reply

* RE: [RFC] mac80211: correctly close cancelled scans
From: Grumbach, Emmanuel @ 2013-09-17 11:28 UTC (permalink / raw)
  To: Eliad Peller; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <CAB3XZEc-h=mS-etjvm_zeJ2czsLj9yseq+jpsXOR=smy5+7Rdg@mail.gmail.com>

> On Tue, Sep 17, 2013 at 8:48 AM, Emmanuel Grumbach
> <emmanuel.grumbach@intel.com> wrote:
> > __ieee80211_scan_completed is called from a worker. This means that
> > the following flow is possible.
> >
> >  * driver calls ieee80211_scan_completed
> >  * mac80211 cancels the scan (that is already complete)
> >  * __ieee80211_scan_complete runs
> >
> > When scan_work will finally run, it will see that the scan hasn't been
> > aborted and might even trigger another scan on another band. This
> > leads to a situation where cfg80211's scan is not done and no further
> > scan can be issued.
> >
> > Fix this by setting a new flag when a HW scan is being cancelled so
> > that no other scan will be triggered.
> >
> > Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
> > ---
> [...]
> 
> >         if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
> > -               if (local->ops->cancel_hw_scan)
> > +               /*
> > +                * Make sure that __ieee80211_scan_completed doesn't trigger a
> > +                * scan on another band.
> > +                */
> > +               set_bit(SCAN_HW_CANCELLED, &local->scanning);
> > +               if (local->ops->cancel_hw_scan) {
> >                         drv_cancel_hw_scan(local,
> >                                 rcu_dereference_protected(local->scan_sdata,
> >
> > lockdep_is_held(&local->mtx)));
> > +               }
> >                 goto out;
> >         }
> 
> you don't seem to clear this flag anywhere...
> 

Yeah - just like SCAN_HW_SCANNING isn't cleared anywhere... but... in __ieee80211_scan_completed:

	local->scanning = 0;
	local->scan_chandef.chan = NULL;

yes I know. Don't ask.

^ permalink raw reply

* Re: [RFC] mac80211: correctly close cancelled scans
From: Eliad Peller @ 2013-09-17 11:22 UTC (permalink / raw)
  To: Emmanuel Grumbach; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1379396919-11983-1-git-send-email-emmanuel.grumbach@intel.com>

On Tue, Sep 17, 2013 at 8:48 AM, Emmanuel Grumbach
<emmanuel.grumbach@intel.com> wrote:
> __ieee80211_scan_completed is called from a worker. This
> means that the following flow is possible.
>
>  * driver calls ieee80211_scan_completed
>  * mac80211 cancels the scan (that is already complete)
>  * __ieee80211_scan_complete runs
>
> When scan_work will finally run, it will see that the scan
> hasn't been aborted and might even trigger another scan on
> another band. This leads to a situation where cfg80211's
> scan is not done and no further scan can be issued.
>
> Fix this by setting a new flag when a HW scan is being
> cancelled so that no other scan will be triggered.
>
> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
> ---
[...]

>         if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
> -               if (local->ops->cancel_hw_scan)
> +               /*
> +                * Make sure that __ieee80211_scan_completed doesn't trigger a
> +                * scan on another band.
> +                */
> +               set_bit(SCAN_HW_CANCELLED, &local->scanning);
> +               if (local->ops->cancel_hw_scan) {
>                         drv_cancel_hw_scan(local,
>                                 rcu_dereference_protected(local->scan_sdata,
>                                                 lockdep_is_held(&local->mtx)));
> +               }
>                 goto out;
>         }

you don't seem to clear this flag anywhere...

Eliad.

^ permalink raw reply

* [PATCH 3.12] ath9k: don't use BAW tracking on PS responses for non-AMPDU packets
From: Felix Fietkau @ 2013-09-17 10:05 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

When .release_buffered_frames was implemented, only A-MPDU packets were
buffered internally. Now that this has changed, the BUF_AMPDU flag needs
to be checked before calling ath_tx_addto_baw

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/xmit.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 5849960..9b3736e 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1556,8 +1556,10 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
 			__skb_unlink(bf->bf_mpdu, tid_q);
 			list_add_tail(&bf->list, &bf_q);
 			ath_set_rates(tid->an->vif, tid->an->sta, bf);
-			ath_tx_addto_baw(sc, tid, bf);
-			bf->bf_state.bf_type &= ~BUF_AGGR;
+			if (bf_isampdu(bf)) {
+				ath_tx_addto_baw(sc, tid, bf);
+				bf->bf_state.bf_type &= ~BUF_AGGR;
+			}
 			if (bf_tail)
 				bf_tail->bf_next = bf;
 
-- 
1.8.0.2


^ permalink raw reply related

* [PATCH 3.12] mac80211: drop spoofed packets in ad-hoc mode
From: Felix Fietkau @ 2013-09-17  9:15 UTC (permalink / raw)
  To: linux-wireless; +Cc: johannes, thomas

If an Ad-Hoc node receives packets with the Cell ID or its own MAC
address as source address, it hits a WARN_ON in sta_info_insert_check()
With many packets, this can massively spam the logs. One way that this
can easily happen is through having Cisco APs in the area with rouge AP
detection and countermeasures enabled.
Such Cisco APs will regularly send fake beacons, disassoc and deauth
packets that trigger these warnings.

To fix this issue, drop such spoofed packets early in the rx path.

Cc: stable@vger.kernel.org
Reported-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 net/mac80211/rx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 54395d7..674eac1 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3056,6 +3056,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
 	case NL80211_IFTYPE_ADHOC:
 		if (!bssid)
 			return 0;
+		if (ether_addr_equal(sdata->vif.addr, hdr->addr2) ||
+		    ether_addr_equal(sdata->u.ibss.bssid, hdr->addr2))
+			return 0;
 		if (ieee80211_is_beacon(hdr->frame_control)) {
 			return 1;
 		} else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) {
-- 
1.8.0.2


^ permalink raw reply related

* RE: [PATCH 8/8 V2] rtlwifi: Remove variable 'noise' from rtl_stats struct
From: David Laight @ 2013-09-17  8:48 UTC (permalink / raw)
  To: Larry Finger, linville; +Cc: linux-wireless, netdev
In-Reply-To: <1379357722-17687-9-git-send-email-Larry.Finger@lwfinger.net>

> diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
> index cc03e7c..284ee8d 100644
> --- a/drivers/net/wireless/rtlwifi/wifi.h
> +++ b/drivers/net/wireless/rtlwifi/wifi.h
> @@ -1535,7 +1535,6 @@ struct rtl_stats {
>  	u32 mac_time[2];
>  	s8 rssi;
>  	u8 signal;
> -	u8 noise;
>  	u8 rate;		/* hw desc rate */
>  	u8 received_channel;
>  	u8 control;
> --

Is 'struct rtl_stats' exposed to userspace?
(or even to loadable drivers)
If so you probably ought to replace 'noise' with an explicit
pad in order to avoid changing the offsets of the other fields.

	David




^ permalink raw reply

* RT3573 wpa_supplicant: "nl80211: Delete station $my_ap" after "SME: Send 20/40 BSS Coexistence to $my_ap"
From: Peter Stuge @ 2013-09-17  8:43 UTC (permalink / raw)
  To: linux-wireless, users, hostap

Xose Vazquez Perez wrote:
> 0x0846, 0x9012 NETGEAR WNDA4100 N900 Wireless Dual Band USB Adapter

I'm testing the WNDA4100 with torvalds/linux.git and as of a day or
two ago and wpa_supplicant-2.0.

I haven't measured throughput. Latency is really bad for interactive
connections, but at least the packets are flowing on all bands. Yay!

Ping to the access point is around 3 ms with the odd 20+ ms when the
kernel goes off to do something else.


Here's my problem:

After wpa_supplicant -Dnl80211 -ddd sees scan results and says
"SME: Send 20/40 BSS Coexistence to $my_ap" and that frame is acked,
wpa_supplicant seems to receive a "link up" event which causes it to
delete the existing association for no good reason. It blacklists my
ap so I need to reconnect manually with iw dev wlan1 connect -w $ssid.

(Oh, and iw dev wlan1 connect -w consistently says "Unspecified failure"
even though the connection is established fine by wpa_supplicant. Other
problem though.)

My AP is hidden, so it isn't included in the scan results. But
wpa_supplicant is connected to it fine when the scan results arrive.

wpa_supplicant does *not* disconnect if I manually initiate a scan
when there is no other link activity, this only happens for
"Scan requested (ret=0) - scan timeout 30 seconds" scans.

--8<-- wpa_supplicant -ddd log snippet with MAC address replaced with $my_ap.
wlan1: New scan results available
SME: Send 20/40 BSS Coexistence to $my_ap
nl80211: Send Action frame (ifindex=6, freq=2417 MHz wait=0 ms no_cck=0)
nl80211: CMD_FRAME freq=2417 wait=0 no_cck=0 no_ack=0 offchanok=1
nl80211: Frame TX command accepted; cookie 0xffff880039f70700
wlan1: Checking for other virtual interfaces sharing same radio (phy1) in event_scan_results
nl80211: Event message available
nl80211: MLME event 60
nl80211: MLME event frame - hexdump(len=34): d0 00 da 00 $my_ap 84 1b 5e 7e e1 bc $my_ap d0 72 04 00 48 01 00 49 03 00 06 05
nl80211: Frame TX status event
nl80211: Action TX status: cookie=0ffff880039f70700 (match) (ack=1)
wlan1: Event TX_STATUS (18) received
wlan1: EVENT_TX_STATUS dst=$my_ap type=0 stype=13
RTM_NEWLINK: operstate=1 ifi_flags=0x1003 ([UP])
RTM_NEWLINK, IFLA_IFNAME: Interface 'wlan1' added
nl80211: if_removed already cleared - ignore event
nl80211: Event message available
nl80211: Delete station $my_ap
nl80211: Event message available
nl80211: MLME event 39
nl80211: MLME event frame - hexdump(len=26): c0 00 00 00 $my_ap 84 1b 5e 7e e1 bc $my_ap 00 00 04 00
nl80211: Deauthenticate event
wlan1: Event DEAUTH (12) received
wlan1: Deauthentication notification
wlan1:  * reason 4 (locally generated)
wlan1:  * address $my_ap
Deauthentication frame IE(s) - hexdump(len=0): [NULL]
wlan1: CTRL-EVENT-DISCONNECTED bssid=$my_ap reason=4 locally_generated=1
wlan1: Auto connect enabled: try to reconnect (wps=0 wpa_state=9)
wlan1: Setting scan request: 0 sec 100000 usec
Added BSSID $my_ap into blacklist
wlan1: Blacklist count 1 --> request scan in 100 ms
wlan1: Setting scan request: 0 sec 100000 usec
wlan1: Disconnect event - remove keys
wpa_driver_nl80211_set_key: ifindex=6 alg=0 addr=(nil) key_idx=0 set_tx=0 seq_len=0 key_len=0
wpa_driver_nl80211_set_key: ifindex=6 alg=0 addr=(nil) key_idx=1 set_tx=0 seq_len=0 key_len=0
wpa_driver_nl80211_set_key: ifindex=6 alg=0 addr=(nil) key_idx=2 set_tx=0 seq_len=0 key_len=0
wpa_driver_nl80211_set_key: ifindex=6 alg=0 addr=(nil) key_idx=3 set_tx=0 seq_len=0 key_len=0
wpa_driver_nl80211_set_key: ifindex=6 alg=0 addr=0x112f828 key_idx=0 set_tx=0 seq_len=0 key_len=0
   addr=$my_ap
wlan1: State: COMPLETED -> DISCONNECTED
-->8--


What's the problem? wpa_supplicant or rt2800usb or mac80211 or all of
the above?


Thanks

//Peter

^ permalink raw reply

* [PATCH] cfg80211: parse dfs region for internal regdb option
From: Janusz Dziedzic @ 2013-09-17  6:25 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, rodrigue, Janusz Dziedzic

Add support for parsing and setting the dfs region (ETSI, FCC, JP)
when the internal regulatory database is used. Before this
the DFS region was being ignored even if present on the used
db.txt

Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
---
 net/wireless/genregdb.awk |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk
index 9392f8c..42ed274 100644
--- a/net/wireless/genregdb.awk
+++ b/net/wireless/genregdb.awk
@@ -46,6 +46,12 @@ BEGIN {
 	sub(/:/, "", country)
 	printf "static const struct ieee80211_regdomain regdom_%s = {\n", country
 	printf "\t.alpha2 = \"%s\",\n", country
+	if ($NF ~ /DFS-ETSI/)
+		printf "\t.dfs_region = NL80211_DFS_ETSI,\n"
+	else if ($NF ~ /DFS-FCC/)
+		printf "\t.dfs_region = NL80211_DFS_FCC,\n"
+	else if ($NF ~ /DFS-JP/)
+		printf "\t.dfs_region = NL80211_DFS_JP,\n"
 	printf "\t.reg_rules = {\n"
 	active = 1
 	regdb = regdb "\t&regdom_" country ",\n"
-- 
1.7.9.5


^ permalink raw reply related

* [RFC] mac80211: correctly close cancelled scans
From: Emmanuel Grumbach @ 2013-09-17  5:48 UTC (permalink / raw)
  To: linux-wireless; +Cc: Emmanuel Grumbach

__ieee80211_scan_completed is called from a worker. This
means that the following flow is possible.

 * driver calls ieee80211_scan_completed
 * mac80211 cancels the scan (that is already complete)
 * __ieee80211_scan_complete runs

When scan_work will finally run, it will see that the scan
hasn't been aborted and might even trigger another scan on
another band. This leads to a situation where cfg80211's
scan is not done and no further scan can be issued.

Fix this by setting a new flag when a HW scan is being
cancelled so that no other scan will be triggered.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
 net/mac80211/ieee80211_i.h |    3 +++
 net/mac80211/scan.c        |   22 +++++++++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d604e16..a523e5a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -893,6 +893,8 @@ struct tpt_led_trigger {
  *	that the scan completed.
  * @SCAN_ABORTED: Set for our scan work function when the driver reported
  *	a scan complete for an aborted scan.
+ * @SCAN_HW_CANCELLED: Set for our scan work function when the scan is being
+ *	cancelled.
  */
 enum {
 	SCAN_SW_SCANNING,
@@ -900,6 +902,7 @@ enum {
 	SCAN_ONCHANNEL_SCANNING,
 	SCAN_COMPLETED,
 	SCAN_ABORTED,
+	SCAN_HW_CANCELLED,
 };
 
 /**
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 08afe74..67f81a4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -238,6 +238,9 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
 	enum ieee80211_band band;
 	int i, ielen, n_chans;
 
+	if (test_bit(SCAN_HW_CANCELLED, &local->scanning))
+		return false;
+
 	do {
 		if (local->hw_scan_band == IEEE80211_NUM_BANDS)
 			return false;
@@ -940,11 +943,28 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
 	if (!local->scan_req)
 		goto out;
 
+	/*
+	 * We have a scan running and the driver already reported completion,
+	 * but the worker hasn't run yet or is stuck on the mutex - mark it as
+	 * cancelled.
+	 */
+	if (test_bit(SCAN_HW_SCANNING, &local->scanning) &&
+	    test_bit(SCAN_COMPLETED, &local->scanning)) {
+		set_bit(SCAN_HW_CANCELLED, &local->scanning);
+		goto out;
+	}
+
 	if (test_bit(SCAN_HW_SCANNING, &local->scanning)) {
-		if (local->ops->cancel_hw_scan)
+		/*
+		 * Make sure that __ieee80211_scan_completed doesn't trigger a
+		 * scan on another band.
+		 */
+		set_bit(SCAN_HW_CANCELLED, &local->scanning);
+		if (local->ops->cancel_hw_scan) {
 			drv_cancel_hw_scan(local,
 				rcu_dereference_protected(local->scan_sdata,
 						lockdep_is_held(&local->mtx)));
+		}
 		goto out;
 	}
 
-- 
1.7.10.4


^ permalink raw reply related

* Re: [RFC 3/4] ath10k: cleanup RX decap handling
From: Michal Kazior @ 2013-09-17  5:19 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath10k, linux-wireless
In-Reply-To: <8738p4laid.fsf@qca.qualcomm.com>

On 16 September 2013 23:30, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> Michal Kazior <michal.kazior@tieto.com> writes:
>
>> Native Wifi frames are always decapped as non-QoS
>> data frames meaning mac80211 couldn't set sk_buff
>> priority properly. The patch fixes this by using
>> the original 802.11 header.
>>
>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>
> The patch title doesn't seem to match with the content. Unless I'm
> mistaken it looks like you are adding native wifi frame format support
> and doing some cleanup at the same time. They should be in separate
> patches.

You're right. I'll split it up.

Nwifi was supported, however QoS Data frames were reported as Data
frames though.


>> @@ -652,6 +652,19 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
>>                       skb_trim(skb, skb->len - FCS_LEN);
>>                       break;
>>               case RX_MSDU_DECAP_NATIVE_WIFI:
>> +                     hdr = (struct ieee80211_hdr *)skb->data;
>> +                     hdr_len = ieee80211_hdrlen(hdr->frame_control);
>> +                     memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN);
>> +                     skb_pull(skb, hdr_len);
>> +
>> +                     hdr = (struct ieee80211_hdr *)hdr_buf;
>> +                     hdr_len = ieee80211_hdrlen(hdr->frame_control);
>> +                     memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
>> +
>> +                     hdr = (struct ieee80211_hdr *)skb->data;
>> +                     qos = ieee80211_get_qos_ctl(hdr);
>> +                     qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
>> +                     memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN);
>>                       break;
>
> It would be good to have small comments what each part is doing("remove
> the native wifi header", "copy the real 802.11 header", "copy correct
> destination address" etc), makes it a lot faster to skim the code. Also
> document why IEEE80211_QOS_CTL_A_MSDU_PRESENT needs to be cleared.

Okay.


>>       case RX_MSDU_DECAP_RAW:
>> -             /* remove trailing FCS */
>> -             skb_trim(skb, skb->len - 4);
>> +             skb_trim(skb, skb->len - FCS_LEN);
>>               break;
>
> Please keep the comment still

Why? The point of the comment was to explain the literal "4". Using
define makes the comment redundant.


>
>>       case RX_MSDU_DECAP_NATIVE_WIFI:
>> -             /* nothing to do here */
>> +             hdr = (struct ieee80211_hdr *)skb->data;
>> +             hdr_len = ieee80211_hdrlen(hdr->frame_control);
>> +             memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN);
>> +             skb_pull(skb, hdr_len);
>> +
>> +             hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status;
>> +             hdr_len = ieee80211_hdrlen(hdr->frame_control);
>> +             memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
>> +
>> +             hdr = (struct ieee80211_hdr *)skb->data;
>> +             memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN);
>>               break;
>
> Again add small comments describing how we are modifying the headers.

Okay.


>>       case RX_MSDU_DECAP_ETHERNET2_DIX:
>> -             /* macaddr[6] + macaddr[6] + ethertype[2] */
>> -             skb_pull(skb, 6 + 6 + 2);
>> +             rfc1042 = hdr;
>> +             rfc1042 += roundup(hdr_len, 4);
>> +             rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4);
>> +
>> +             skb_pull(skb, sizeof(struct ethhdr));
>> +             memcpy(skb_push(skb, sizeof(struct rfc1042_hdr)),
>> +                    rfc1042, sizeof(struct rfc1042_hdr));
>> +             memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
>>               break;
>
> Ditto.

Comment was supposed to explain where those numbers come from. Using
structures explains it now.


>>       case RX_MSDU_DECAP_8023_SNAP_LLC:
>> -             /* macaddr[6] + macaddr[6] + len[2] */
>> -             /* we don't need this for non-A-MSDU */
>> -             skb_pull(skb, 6 + 6 + 2);
>> +             skb_pull(skb, sizeof(struct amsdu_subframe_hdr));
>> +             memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
>>               break;
>
> And here.

Ditto.


Michał.

^ permalink raw reply

* Re: [PATCH 1/1] mwifiex: queue main work from main process when bailing on races
From: Daniel Mack @ 2013-09-16 23:00 UTC (permalink / raw)
  To: Bing Zhao
  Cc: linux-wireless@vger.kernel.org, s.neumann@raumfeld.com,
	afenkart@gmail.com, linville@tuxdriver.com,
	johannes.berg@intel.com, stable@vger.kernel.org
In-Reply-To: <477F20668A386D41ADCC57781B1F70430F44C5849E@SC-VEXCH1.marvell.com>

Hi Bing,

On 16.09.2013 23:14, Bing Zhao wrote:
>> diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
>> index ff4ed96..0700bc2 100644
>> --- a/drivers/net/wireless/mwifiex/main.c
>> +++ b/drivers/net/wireless/mwifiex/main.c
>> @@ -235,6 +235,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
>>  	/* Check if already processing */
>>  	if (adapter->mwifiex_processing) {
>>  		spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
>> +		queue_work(adapter->workqueue, &adapter->main_work);
> 
> This is specific to SDIO interface,

Is it really? By checking adapter->mwifiex_processing, the driver seems
to expect mwifiex_main_process() to be called from multiple execution
paths, and in that case, we will always loose one execution cycle in
case we bail early. I actually wonder why this didn't hit us earlier,
but I might miss a detail.

OTOH, the worst thing that can happen if the function is executed too
often is that it exits early and does nothing.

> +               if (adapter->iface_type == MWIFIEX_SDIO)
> +                       queue_work(adapter->workqueue, &adapter->main_work);

I can of course add this, but I don't fully understand why the driver
takes care of concurrently running executing paths and then just bails
silently in case a race is detected.


Best regards,
Daniel


^ permalink raw reply

* Re: [PATCH 2/8 V2] rtlwifi: rtl8192de: Fix smatch warnings in rtl8192de/hw.c
From: Kalle Valo @ 2013-09-16 21:44 UTC (permalink / raw)
  To: Larry Finger; +Cc: linville, linux-wireless, netdev
In-Reply-To: <1379357722-17687-3-git-send-email-Larry.Finger@lwfinger.net>

Larry Finger <Larry.Finger@lwfinger.net> writes:

> Smatch lists the following:
>   CHECK   drivers/net/wireless/rtlwifi/rtl8192de/hw.c
> drivers/net/wireless/rtlwifi/rtl8192de/hw.c:1200 rtl92de_set_qos() info: ignoring unreachable code.
> drivers/net/wireless/rtlwifi/rtl8192de/hw.c:1200 rtl92de_set_qos() info: ignoring unreachable code.
>
> Dead code is commented out. It has not been deleted in case I find a need for
> it later.

We should not have any commented out code. It's better to remove it and
if it's ever needed it can be found from the git history.

-- 
Kalle Valo

^ permalink raw reply

* RE: [PATCH v4] Bluetooth: btmrvl: add calibration data download support
From: Bing Zhao @ 2013-09-16 21:17 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: linux-bluetooth@vger.kernel.org, Gustavo Padovan, Johan Hedberg,
	linux-wireless@vger.kernel.org, Mike Frysinger, Hyuckjoo Lee,
	Amitkumar Karwar
In-Reply-To: <525C3DAD-2AD3-468F-8309-630EEE54A3CE@holtmann.org>

Hi Marcel,

Thanks for your comment.

> > +	bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
> > +	skb_put(skb, sizeof(*cmd));
> > +	skb->dev = (void *)priv->btmrvl_dev.hcidev;
> > +	skb_queue_head(&priv->adapter->tx_queue, skb);
> > +	priv->btmrvl_dev.sendcmdflag = true;
> > +	priv->adapter->cmd_complete = false;
> 
> since the Bluetooth HCI core got ->setup() support with proper synchronous HCI request handling
> available for every single driver (see the Intel support in btusb.c), why not start using that with
> this driver as well.

We will convert btmrvl driver to use ->setup() callback.

Thanks,
Bing


^ permalink raw reply

* Re: [RFC 3/4] ath10k: cleanup RX decap handling
From: Kalle Valo @ 2013-09-16 21:30 UTC (permalink / raw)
  To: Michal Kazior; +Cc: ath10k, linux-wireless
In-Reply-To: <1379335757-15180-4-git-send-email-michal.kazior@tieto.com>

Michal Kazior <michal.kazior@tieto.com> writes:

> Native Wifi frames are always decapped as non-QoS
> data frames meaning mac80211 couldn't set sk_buff
> priority properly. The patch fixes this by using
> the original 802.11 header.
>
> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>

The patch title doesn't seem to match with the content. Unless I'm
mistaken it looks like you are adding native wifi frame format support
and doing some cleanup at the same time. They should be in separate
patches.

> @@ -652,6 +652,19 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
>  			skb_trim(skb, skb->len - FCS_LEN);
>  			break;
>  		case RX_MSDU_DECAP_NATIVE_WIFI:
> +			hdr = (struct ieee80211_hdr *)skb->data;
> +			hdr_len = ieee80211_hdrlen(hdr->frame_control);
> +			memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN);
> +			skb_pull(skb, hdr_len);
> +
> +			hdr = (struct ieee80211_hdr *)hdr_buf;
> +			hdr_len = ieee80211_hdrlen(hdr->frame_control);
> +			memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
> +
> +			hdr = (struct ieee80211_hdr *)skb->data;
> +			qos = ieee80211_get_qos_ctl(hdr);
> +			qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
> +			memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN);
>  			break;

It would be good to have small comments what each part is doing("remove
the native wifi header", "copy the real 802.11 header", "copy correct
destination address" etc), makes it a lot faster to skim the code. Also
document why IEEE80211_QOS_CTL_A_MSDU_PRESENT needs to be cleared.

>  	case RX_MSDU_DECAP_RAW:
> -		/* remove trailing FCS */
> -		skb_trim(skb, skb->len - 4);
> +		skb_trim(skb, skb->len - FCS_LEN);
>  		break;

Please keep the comment still

>  	case RX_MSDU_DECAP_NATIVE_WIFI:
> -		/* nothing to do here */
> +		hdr = (struct ieee80211_hdr *)skb->data;
> +		hdr_len = ieee80211_hdrlen(hdr->frame_control);
> +		memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN);
> +		skb_pull(skb, hdr_len);
> +
> +		hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status;
> +		hdr_len = ieee80211_hdrlen(hdr->frame_control);
> +		memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
> +
> +		hdr = (struct ieee80211_hdr *)skb->data;
> +		memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN);
>  		break;

Again add small comments describing how we are modifying the headers.

>  	case RX_MSDU_DECAP_ETHERNET2_DIX:
> -		/* macaddr[6] + macaddr[6] + ethertype[2] */
> -		skb_pull(skb, 6 + 6 + 2);
> +		rfc1042 = hdr;
> +		rfc1042 += roundup(hdr_len, 4);
> +		rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4);
> +
> +		skb_pull(skb, sizeof(struct ethhdr));
> +		memcpy(skb_push(skb, sizeof(struct rfc1042_hdr)),
> +		       rfc1042, sizeof(struct rfc1042_hdr));
> +		memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
>  		break;

Ditto.

>  	case RX_MSDU_DECAP_8023_SNAP_LLC:
> -		/* macaddr[6] + macaddr[6] + len[2] */
> -		/* we don't need this for non-A-MSDU */
> -		skb_pull(skb, 6 + 6 + 2);
> +		skb_pull(skb, sizeof(struct amsdu_subframe_hdr));
> +		memcpy(skb_push(skb, hdr_len), hdr, hdr_len);
>  		break;

And here.

-- 
Kalle Valo

^ permalink raw reply

* RE: [PATCH] mwifiex: Remove casting the return value which is a void pointer
From: Bing Zhao @ 2013-09-16 21:26 UTC (permalink / raw)
  To: Jingoo Han, 'John W. Linville'
  Cc: linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
	'David Miller'
In-Reply-To: <004d01cead1d$3058dcf0$910a96d0$%han@samsung.com>

Hi Jingoo,

Thanks for the patch.

> Casting the return value which is a void pointer is redundant.
> The conversion from void pointer to any other pointer type is
> guaranteed by the C programming language.
> 
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>

Acked-by: Bing Zhao <bzhao@marvell.com>

Thanks,
Bing

> ---
>  drivers/net/wireless/mwifiex/pcie.c |    6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)


^ permalink raw reply

* RE: [PATCH 1/1] mwifiex: queue main work from main process when bailing on races
From: Bing Zhao @ 2013-09-16 21:14 UTC (permalink / raw)
  To: Daniel Mack, linux-wireless@vger.kernel.org
  Cc: s.neumann@raumfeld.com, afenkart@gmail.com,
	linville@tuxdriver.com, johannes.berg@intel.com,
	stable@vger.kernel.org
In-Reply-To: <1379331546-30617-2-git-send-email-zonque@gmail.com>

Hi Daniel,

Thanks for the patch.

> Queue main_work in case mwifiex_main_process() bails due to an already
> processed transaction. This is particularly necessary because
> mwifiex_main_process() is called from both the SDIO interrupt handler
> and the workqueue. In case an interrupt occurs while the main process
> is currently executed from the workqueue, the interrupt is lost,
> resulting in a command timeout and consequently a card reset.
> 
> I'm marking this for stable kernel in version 3.7+, because on our
> platform, the issue appears since 601216e12c ("mwifiex: process RX
> packets in SDIO IRQ thread directly") went in.
> 
> Signed-off-by: Daniel Mack <zonque@gmail.com>
> Reported-by: Sven Neumann <s.neumann@raumfeld.com>
> Reported-by: Andreas Fenkart <andreas.fenkart@streamunlimited.com>
> Cc: Bing Zhao <bzhao@marvell.com>
> Cc: <stable@vger.kernel.org> [v3.7+]
> ---
>  drivers/net/wireless/mwifiex/main.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
> index ff4ed96..0700bc2 100644
> --- a/drivers/net/wireless/mwifiex/main.c
> +++ b/drivers/net/wireless/mwifiex/main.c
> @@ -235,6 +235,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
>  	/* Check if already processing */
>  	if (adapter->mwifiex_processing) {
>  		spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
> +		queue_work(adapter->workqueue, &adapter->main_work);

This is specific to SDIO interface, so we'd add a check here.

+               if (adapter->iface_type == MWIFIEX_SDIO)
+                       queue_work(adapter->workqueue, &adapter->main_work);

Thanks,
Bing

>  		goto exit_main_proc;
>  	} else {
>  		adapter->mwifiex_processing = true;
> --
> 1.8.3.1


^ permalink raw reply

* Re: guidance on struct alignment for rtl8192cu driver
From: Larry Finger @ 2013-09-16 19:40 UTC (permalink / raw)
  To: Emmanuel Grumbach
  Cc: Seth Forshee, Jason Andrews, linux-wireless@vger.kernel.org
In-Reply-To: <CANUX_P3iBywud0SxXtnwUWby0DNm-UoB-CP=X+tdsS7MbmVg=Q@mail.gmail.com>

On 09/16/2013 02:29 PM, Emmanuel Grumbach wrote:
>>>> Index: wireless-testing-save/drivers/net/wireless/rtlwifi/wifi.h
>>>> ===================================================================
>>>> --- wireless-testing-save.orig/drivers/net/wireless/rtlwifi/wifi.h
>>>> +++ wireless-testing-save/drivers/net/wireless/rtlwifi/wifi.h
>>>> @@ -2057,7 +2057,7 @@ struct rtl_priv {
>>>>            that it points to the data allocated
>>>>            beyond  this structure like:
>>>>            rtl_pci_priv or rtl_usb_priv */
>>>> -       u8 priv[0];
>>>> +       u8 __aligned(4) priv[0];
>>>>    };
>>>
>>>
>>> __attribute__((aligned)) might be a safer bet, as this will align it to
>>> the largest alignment that could possibly be needed.
>
> Or copy the code from mac80211.h:
>
> u8 drv_priv[0] __aligned(sizeof(void *));
>
> I did the same in iwlwifi.
> Note the new way to add the __aligned thing. Joe will tell you that is
> better than __attribute__ blablabla

Thanks. I had noticed that checkpatch.pl complains about the __attribute 
construction.

Larry



^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox