* [PATCH 0/4] mac80211: inform the low level driver about events in mac80211
@ 2015-03-16 21:23 Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 1/4] mac80211: convert rssi_callback() to event_callback() Emmanuel Grumbach
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Emmanuel Grumbach @ 2015-03-16 21:23 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
This can be useful to know what is happening in mac80211
from the low level driver without guessing from mac80211's
callbacks.
This can be used for error detection (too many deauths)
and trigger recovery / debug flows based on that
information.
Another possibility is to change parameters that are not
controlled by mac80211 based on this. For example, after
a few association failures, a device may change its BT
Coexist scheme or modify the time sharing between its
vifs.
I use these patches in iwlwifi for debug only (currently).
This allows me to collect firmware debug data upon
authentication failure / deauth Rx etc...
Emmanuel Grumbach (4):
mac80211: convert rssi_callback() to event_callback()
mac80211: notify the driver about authentication status
mac80211: notify the driver about association status
mac80211: notify the driver about deauth
drivers/net/wireless/iwlwifi/dvm/mac80211.c | 15 ++--
drivers/net/wireless/iwlwifi/mvm/coex.c | 2 +-
drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 2 +-
drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 +-
include/net/mac80211.h | 90 ++++++++++++++++++++---
net/mac80211/driver-ops.h | 12 ++--
net/mac80211/mlme.c | 99 ++++++++++++++++++++------
net/mac80211/trace.h | 14 ++--
8 files changed, 185 insertions(+), 53 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] mac80211: convert rssi_callback() to event_callback()
2015-03-16 21:23 [PATCH 0/4] mac80211: inform the low level driver about events in mac80211 Emmanuel Grumbach
@ 2015-03-16 21:23 ` Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 2/4] mac80211: notify the driver about authentication status Emmanuel Grumbach
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Emmanuel Grumbach @ 2015-03-16 21:23 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
We will be able to add more events, such as MLME events and
others. The low level driver may be interested in knowing
about these events to dump firmware data upon failures, or
to change parameters in case connection attempts fail etc...
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
drivers/net/wireless/iwlwifi/dvm/mac80211.c | 15 ++++----
drivers/net/wireless/iwlwifi/mvm/coex.c | 2 +-
drivers/net/wireless/iwlwifi/mvm/coex_legacy.c | 2 +-
drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 +--
include/net/mac80211.h | 48 ++++++++++++++++++++------
net/mac80211/driver-ops.h | 12 +++----
net/mac80211/mlme.c | 9 +++--
net/mac80211/trace.h | 14 ++++----
8 files changed, 71 insertions(+), 35 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 47e64e8..5707ba5 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1129,20 +1129,23 @@ done:
IWL_DEBUG_MAC80211(priv, "leave\n");
}
-static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_rssi_event rssi_event)
+static void iwlagn_mac_event_callback(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ const struct ieee80211_event *event)
{
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+ if (event->type != RSSI_EVENT)
+ return;
+
IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex);
if (priv->lib->bt_params &&
priv->lib->bt_params->advanced_bt_coexist) {
- if (rssi_event == RSSI_EVENT_LOW)
+ if (event->u.rssi.data == RSSI_EVENT_LOW)
priv->bt_enable_pspoll = true;
- else if (rssi_event == RSSI_EVENT_HIGH)
+ else if (event->u.rssi.data == RSSI_EVENT_HIGH)
priv->bt_enable_pspoll = false;
iwlagn_send_advance_bt_config(priv);
@@ -1613,7 +1616,7 @@ const struct ieee80211_ops iwlagn_hw_ops = {
.channel_switch = iwlagn_mac_channel_switch,
.flush = iwlagn_mac_flush,
.tx_last_beacon = iwlagn_mac_tx_last_beacon,
- .rssi_callback = iwlagn_mac_rssi_callback,
+ .event_callback = iwlagn_mac_event_callback,
.set_tim = iwlagn_mac_set_tim,
};
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 1ec4d55..ba0a596 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -1023,7 +1023,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
}
void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
- enum ieee80211_rssi_event rssi_event)
+ enum ieee80211_rssi_event_data rssi_event)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_bt_iterator_data data = {
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
index d530ef3..92c3072 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
@@ -1068,7 +1068,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
}
void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
- enum ieee80211_rssi_event rssi_event)
+ enum ieee80211_rssi_event_data rssi_event)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_bt_iterator_data data = {
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 6c69d05..646ef92 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -1225,7 +1225,7 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd);
void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
- enum ieee80211_rssi_event rssi_event);
+ enum ieee80211_rssi_event_data);
void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm);
u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
struct ieee80211_sta *sta);
@@ -1246,7 +1246,7 @@ int iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd);
void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
- enum ieee80211_rssi_event rssi_event);
+ enum ieee80211_rssi_event_data);
u16 iwl_mvm_coex_agg_time_limit_old(struct iwl_mvm *mvm,
struct ieee80211_sta *sta);
bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm,
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 157c0f1..7a966f3e 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -301,17 +301,44 @@ enum ieee80211_bss_change {
#define IEEE80211_BSS_ARP_ADDR_LIST_LEN 4
/**
- * enum ieee80211_rssi_event - RSSI threshold event
- * An indicator for when RSSI goes below/above a certain threshold.
- * @RSSI_EVENT_HIGH: AP's rssi crossed the high threshold set by the driver.
- * @RSSI_EVENT_LOW: AP's rssi crossed the low threshold set by the driver.
+ * enum ieee80211_event_type - event to be notified to the low level driver
+ * @RSSI_EVENT: AP's rssi crossed the a threshold set by the driver.
*/
-enum ieee80211_rssi_event {
+enum ieee80211_event_type {
+ RSSI_EVENT,
+};
+
+/**
+ * enum ieee80211_rssi_event_data - relevant when event type is %RSSI_EVENT
+ * @RSSI_EVENT_HIGH: AP's rssi went below the threshold set by the driver.
+ * @RSSI_EVENT_LOW: AP's rssi went above the threshold set by the driver.
+ */
+enum ieee80211_rssi_event_data {
RSSI_EVENT_HIGH,
RSSI_EVENT_LOW,
};
/**
+ * enum ieee80211_rssi_event - data attached to an %RSSI_EVENT
+ * @data: See &enum ieee80211_rssi_event_data
+ */
+struct ieee80211_rssi_event {
+ enum ieee80211_rssi_event_data data;
+};
+
+/**
+ * struct ieee80211_event - event to be sent to the driver
+ * @type The event itself. See &enum ieee80211_event_type.
+ * @rssi: relevant if &type is %RSSI_EVENT
+ */
+struct ieee80211_event {
+ enum ieee80211_event_type type;
+ union {
+ struct ieee80211_rssi_event rssi;
+ } u;
+};
+
+/**
* struct ieee80211_bss_conf - holds the BSS's changing parameters
*
* This structure keeps information about a BSS (and an association
@@ -2862,8 +2889,9 @@ enum ieee80211_reconfig_type {
* @set_bitrate_mask: Set a mask of rates to be used for rate control selection
* when transmitting a frame. Currently only legacy rates are handled.
* The callback can sleep.
- * @rssi_callback: Notify driver when the average RSSI goes above/below
- * thresholds that were registered previously. The callback can sleep.
+ * @event_callback: Notify driver about any event in mac80211. See
+ * &enum ieee80211_event_type for the different types.
+ * The callback can sleep.
*
* @release_buffered_frames: Release buffered frames according to the given
* parameters. In the case where the driver buffers some frames for
@@ -3159,9 +3187,9 @@ struct ieee80211_ops {
bool (*tx_frames_pending)(struct ieee80211_hw *hw);
int (*set_bitrate_mask)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask);
- void (*rssi_callback)(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_rssi_event rssi_event);
+ void (*event_callback)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ const struct ieee80211_event *event);
void (*allow_buffered_frames)(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index fdeda17..0a39d3d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -941,13 +941,13 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,
trace_drv_return_void(local);
}
-static inline void drv_rssi_callback(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata,
- const enum ieee80211_rssi_event event)
+static inline void drv_event_callback(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ const struct ieee80211_event *event)
{
- trace_drv_rssi_callback(local, sdata, event);
- if (local->ops->rssi_callback)
- local->ops->rssi_callback(&local->hw, &sdata->vif, event);
+ trace_drv_event_callback(local, sdata, event);
+ if (local->ops->event_callback)
+ local->ops->event_callback(&local->hw, &sdata->vif, event);
trace_drv_return_void(local);
}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 1999bc0..a8c8fe4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3291,6 +3291,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
int sig = ifmgd->ave_beacon_signal;
int last_sig = ifmgd->last_ave_beacon_signal;
+ struct ieee80211_event event = {
+ .type = RSSI_EVENT,
+ };
/*
* if signal crosses either of the boundaries, invoke callback
@@ -3299,12 +3302,14 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
if (sig > ifmgd->rssi_max_thold &&
(last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) {
ifmgd->last_ave_beacon_signal = sig;
- drv_rssi_callback(local, sdata, RSSI_EVENT_HIGH);
+ event.u.rssi.data = RSSI_EVENT_HIGH;
+ drv_event_callback(local, sdata, &event);
} else if (sig < ifmgd->rssi_min_thold &&
(last_sig >= ifmgd->rssi_max_thold ||
last_sig == 0)) {
ifmgd->last_ave_beacon_signal = sig;
- drv_rssi_callback(local, sdata, RSSI_EVENT_LOW);
+ event.u.rssi.data = RSSI_EVENT_LOW;
+ drv_event_callback(local, sdata, &event);
}
}
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 263a956..e9e462b 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1256,28 +1256,28 @@ TRACE_EVENT(drv_set_rekey_data,
LOCAL_PR_ARG, VIF_PR_ARG)
);
-TRACE_EVENT(drv_rssi_callback,
+TRACE_EVENT(drv_event_callback,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
- enum ieee80211_rssi_event rssi_event),
+ const struct ieee80211_event *_event),
- TP_ARGS(local, sdata, rssi_event),
+ TP_ARGS(local, sdata, _event),
TP_STRUCT__entry(
LOCAL_ENTRY
VIF_ENTRY
- __field(u32, rssi_event)
+ __field(u32, type)
),
TP_fast_assign(
LOCAL_ASSIGN;
VIF_ASSIGN;
- __entry->rssi_event = rssi_event;
+ __entry->type = _event->type;
),
TP_printk(
- LOCAL_PR_FMT VIF_PR_FMT " rssi_event:%d",
- LOCAL_PR_ARG, VIF_PR_ARG, __entry->rssi_event
+ LOCAL_PR_FMT VIF_PR_FMT " event:%d",
+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->type
)
);
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] mac80211: notify the driver about authentication status
2015-03-16 21:23 [PATCH 0/4] mac80211: inform the low level driver about events in mac80211 Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 1/4] mac80211: convert rssi_callback() to event_callback() Emmanuel Grumbach
@ 2015-03-16 21:23 ` Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 3/4] mac80211: notify the driver about association status Emmanuel Grumbach
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Emmanuel Grumbach @ 2015-03-16 21:23 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
This can allow the driver to take action based on the
success / failure of the authentication.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
include/net/mac80211.h | 36 ++++++++++++++++++++++++++++++++++++
net/mac80211/mlme.c | 15 +++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7a966f3e..6cddf77 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -303,9 +303,11 @@ enum ieee80211_bss_change {
/**
* enum ieee80211_event_type - event to be notified to the low level driver
* @RSSI_EVENT: AP's rssi crossed the a threshold set by the driver.
+ * @MLME_EVENT: event related to MLME
*/
enum ieee80211_event_type {
RSSI_EVENT,
+ MLME_EVENT,
};
/**
@@ -327,14 +329,48 @@ struct ieee80211_rssi_event {
};
/**
+ * enum ieee80211_mlme_event_data - relevant when event type is %MLME_EVENT
+ * @AUTH_EVENT: the MLME operation is authentication
+ */
+enum ieee80211_mlme_event_data {
+ AUTH_EVENT,
+};
+
+/**
+ * enum ieee80211_mlme_event_status - relevant when event type is %MLME_EVENT
+ * @MLME_SUCCESS: the MLME operation completed successfully.
+ * @MLME_DENIED: the MLME operation was denied by the peer.
+ * @MLME_TIMEOUT: the MLME operation timed out.
+ */
+enum ieee80211_mlme_event_status {
+ MLME_SUCCESS,
+ MLME_DENIED,
+ MLME_TIMEOUT,
+};
+
+/**
+ * enum ieee80211_mlme_event - data attached to an %MLME_EVENT
+ * @data: See &enum ieee80211_mlme_event_data
+ * @status: See &enum ieee80211_mlme_event_status
+ * @reason: the reason code if applicable
+ */
+struct ieee80211_mlme_event {
+ enum ieee80211_mlme_event_data data;
+ enum ieee80211_mlme_event_status status;
+ u16 reason;
+};
+
+/**
* struct ieee80211_event - event to be sent to the driver
* @type The event itself. See &enum ieee80211_event_type.
* @rssi: relevant if &type is %RSSI_EVENT
+ * @mlme: relevant if &type is %AUTH_EVENT
*/
struct ieee80211_event {
enum ieee80211_event_type type;
union {
struct ieee80211_rssi_event rssi;
+ struct ieee80211_mlme_event mlme;
} u;
};
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a8c8fe4..7865998 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2495,6 +2495,10 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
u8 bssid[ETH_ALEN];
u16 auth_alg, auth_transaction, status_code;
struct sta_info *sta;
+ struct ieee80211_event event = {
+ .type = MLME_EVENT,
+ .u.mlme.data = AUTH_EVENT,
+ };
sdata_assert_lock(sdata);
@@ -2527,6 +2531,9 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
mgmt->sa, status_code);
ieee80211_destroy_auth_data(sdata, false);
cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
+ event.u.mlme.status = MLME_DENIED;
+ event.u.mlme.reason = status_code;
+ drv_event_callback(sdata->local, sdata, &event);
return;
}
@@ -2549,6 +2556,8 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
return;
}
+ event.u.mlme.status = MLME_SUCCESS;
+ drv_event_callback(sdata->local, sdata, &event);
sdata_info(sdata, "authenticated\n");
ifmgd->auth_data->done = true;
ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
@@ -3805,12 +3814,18 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
ieee80211_destroy_auth_data(sdata, false);
} else if (ieee80211_probe_auth(sdata)) {
u8 bssid[ETH_ALEN];
+ struct ieee80211_event event = {
+ .type = MLME_EVENT,
+ .u.mlme.data = AUTH_EVENT,
+ .u.mlme.status = MLME_TIMEOUT,
+ };
memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
ieee80211_destroy_auth_data(sdata, false);
cfg80211_auth_timeout(sdata->dev, bssid);
+ drv_event_callback(sdata->local, sdata, &event);
}
} else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started)
run_again(sdata, ifmgd->auth_data->timeout);
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] mac80211: notify the driver about association status
2015-03-16 21:23 [PATCH 0/4] mac80211: inform the low level driver about events in mac80211 Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 1/4] mac80211: convert rssi_callback() to event_callback() Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 2/4] mac80211: notify the driver about authentication status Emmanuel Grumbach
@ 2015-03-16 21:23 ` Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 4/4] mac80211: notify the driver about deauth Emmanuel Grumbach
2015-03-30 8:17 ` [PATCH 0/4] mac80211: inform the low level driver about events in mac80211 Johannes Berg
4 siblings, 0 replies; 6+ messages in thread
From: Emmanuel Grumbach @ 2015-03-16 21:23 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
This can allow the driver to take action based on the
success / failure of the association.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
include/net/mac80211.h | 2 ++
net/mac80211/mlme.c | 15 +++++++++++++++
2 files changed, 17 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 6cddf77..dcddc4a 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -331,9 +331,11 @@ struct ieee80211_rssi_event {
/**
* enum ieee80211_mlme_event_data - relevant when event type is %MLME_EVENT
* @AUTH_EVENT: the MLME operation is authentication
+ * @ASSOC_EVENT: the MLME operation is association
*/
enum ieee80211_mlme_event_data {
AUTH_EVENT,
+ ASSOC_EVENT,
};
/**
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 7865998..b6817c4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3041,6 +3041,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
u8 *pos;
bool reassoc;
struct cfg80211_bss *bss;
+ struct ieee80211_event event = {
+ .type = MLME_EVENT,
+ .u.mlme.data = ASSOC_EVENT,
+ };
sdata_assert_lock(sdata);
@@ -3092,6 +3096,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
sdata_info(sdata, "%pM denied association (code=%d)\n",
mgmt->sa, status_code);
ieee80211_destroy_assoc_data(sdata, false);
+ event.u.mlme.status = MLME_DENIED;
+ event.u.mlme.reason = status_code;
+ drv_event_callback(sdata->local, sdata, &event);
} else {
if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
/* oops -- internal error -- send timeout for now */
@@ -3099,6 +3106,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
cfg80211_assoc_timeout(sdata->dev, bss);
return;
}
+ event.u.mlme.status = MLME_SUCCESS;
+ drv_event_callback(sdata->local, sdata, &event);
sdata_info(sdata, "associated\n");
/*
@@ -3835,9 +3844,15 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) ||
ieee80211_do_assoc(sdata)) {
struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
+ struct ieee80211_event event = {
+ .type = MLME_EVENT,
+ .u.mlme.data = ASSOC_EVENT,
+ .u.mlme.status = MLME_TIMEOUT,
+ };
ieee80211_destroy_assoc_data(sdata, false);
cfg80211_assoc_timeout(sdata->dev, bss);
+ drv_event_callback(sdata->local, sdata, &event);
}
} else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
run_again(sdata, ifmgd->assoc_data->timeout);
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] mac80211: notify the driver about deauth
2015-03-16 21:23 [PATCH 0/4] mac80211: inform the low level driver about events in mac80211 Emmanuel Grumbach
` (2 preceding siblings ...)
2015-03-16 21:23 ` [PATCH 3/4] mac80211: notify the driver about association status Emmanuel Grumbach
@ 2015-03-16 21:23 ` Emmanuel Grumbach
2015-03-30 8:17 ` [PATCH 0/4] mac80211: inform the low level driver about events in mac80211 Johannes Berg
4 siblings, 0 replies; 6+ messages in thread
From: Emmanuel Grumbach @ 2015-03-16 21:23 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach
This can allow the driver to take action based on the reason
of the deauth.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
---
include/net/mac80211.h | 4 ++++
net/mac80211/mlme.c | 60 +++++++++++++++++++++++++++++++++++---------------
2 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dcddc4a..94c8c62 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -332,10 +332,14 @@ struct ieee80211_rssi_event {
* enum ieee80211_mlme_event_data - relevant when event type is %MLME_EVENT
* @AUTH_EVENT: the MLME operation is authentication
* @ASSOC_EVENT: the MLME operation is association
+ * @DEAUTH_RX_EVENT: deauth received..
+ * @DEAUTH_TX_EVENT: deauth sent.
*/
enum ieee80211_mlme_event_data {
AUTH_EVENT,
ASSOC_EVENT,
+ DEAUTH_RX_EVENT,
+ DEAUTH_TX_EVENT,
};
/**
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b6817c4..22b1259 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2345,6 +2345,24 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
}
EXPORT_SYMBOL(ieee80211_ap_probereq_get);
+static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata,
+ const u8 *buf, size_t len, bool tx,
+ u16 reason)
+{
+ struct ieee80211_event event = {
+ .type = MLME_EVENT,
+ .u.mlme.data = tx ? DEAUTH_TX_EVENT : DEAUTH_RX_EVENT,
+ .u.mlme.reason = reason,
+ };
+
+ if (tx)
+ cfg80211_tx_mlme_mgmt(sdata->dev, buf, len);
+ else
+ cfg80211_rx_mlme_mgmt(sdata->dev, buf, len);
+
+ drv_event_callback(sdata->local, sdata, &event);
+}
+
static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
@@ -2370,8 +2388,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
}
mutex_unlock(&local->mtx);
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
- IEEE80211_DEAUTH_FRAME_LEN);
+ ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
+
sdata_unlock(sdata);
}
@@ -2676,7 +2695,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
- cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
+ ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code);
}
@@ -2702,7 +2721,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
- cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
+ ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code);
}
static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
@@ -3509,8 +3528,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
WLAN_REASON_DEAUTH_LEAVING,
true, deauth_buf);
- cfg80211_tx_mlme_mgmt(sdata->dev, deauth_buf,
- sizeof(deauth_buf));
+ ieee80211_report_disconnect(sdata, deauth_buf,
+ sizeof(deauth_buf), true,
+ WLAN_REASON_DEAUTH_LEAVING);
return;
}
@@ -3628,8 +3648,8 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
tx, frame_buf);
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
- IEEE80211_DEAUTH_FRAME_LEN);
+ ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
+ reason);
}
static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
@@ -4507,8 +4527,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
WLAN_REASON_UNSPECIFIED,
false, frame_buf);
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
- sizeof(frame_buf));
+ ieee80211_report_disconnect(sdata, frame_buf,
+ sizeof(frame_buf), true,
+ WLAN_REASON_UNSPECIFIED);
}
sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
@@ -4608,8 +4629,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
WLAN_REASON_UNSPECIFIED,
false, frame_buf);
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
- sizeof(frame_buf));
+ ieee80211_report_disconnect(sdata, frame_buf,
+ sizeof(frame_buf), true,
+ WLAN_REASON_UNSPECIFIED);
}
if (ifmgd->auth_data && !ifmgd->auth_data->done) {
@@ -4899,8 +4921,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
req->reason_code, tx,
frame_buf);
ieee80211_destroy_auth_data(sdata, false);
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
- IEEE80211_DEAUTH_FRAME_LEN);
+ ieee80211_report_disconnect(sdata, frame_buf,
+ sizeof(frame_buf), true,
+ req->reason_code);
return 0;
}
@@ -4914,8 +4937,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
req->reason_code, tx, frame_buf);
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
- IEEE80211_DEAUTH_FRAME_LEN);
+ ieee80211_report_disconnect(sdata, frame_buf,
+ sizeof(frame_buf), true,
+ req->reason_code);
return 0;
}
@@ -4947,8 +4971,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
req->reason_code, !req->local_state_change,
frame_buf);
- cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
- IEEE80211_DEAUTH_FRAME_LEN);
+ ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
+ req->reason_code);
return 0;
}
--
1.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/4] mac80211: inform the low level driver about events in mac80211
2015-03-16 21:23 [PATCH 0/4] mac80211: inform the low level driver about events in mac80211 Emmanuel Grumbach
` (3 preceding siblings ...)
2015-03-16 21:23 ` [PATCH 4/4] mac80211: notify the driver about deauth Emmanuel Grumbach
@ 2015-03-30 8:17 ` Johannes Berg
4 siblings, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2015-03-30 8:17 UTC (permalink / raw)
To: Emmanuel Grumbach; +Cc: linux-wireless
On Mon, 2015-03-16 at 23:23 +0200, Emmanuel Grumbach wrote:
> This can be useful to know what is happening in mac80211
> from the low level driver without guessing from mac80211's
> callbacks.
> This can be used for error detection (too many deauths)
> and trigger recovery / debug flows based on that
> information.
> Another possibility is to change parameters that are not
> controlled by mac80211 based on this. For example, after
> a few association failures, a device may change its BT
> Coexist scheme or modify the time sharing between its
> vifs.
>
> I use these patches in iwlwifi for debug only (currently).
> This allows me to collect firmware debug data upon
> authentication failure / deauth Rx etc...
Applied all four.
johannes
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-03-30 8:17 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-16 21:23 [PATCH 0/4] mac80211: inform the low level driver about events in mac80211 Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 1/4] mac80211: convert rssi_callback() to event_callback() Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 2/4] mac80211: notify the driver about authentication status Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 3/4] mac80211: notify the driver about association status Emmanuel Grumbach
2015-03-16 21:23 ` [PATCH 4/4] mac80211: notify the driver about deauth Emmanuel Grumbach
2015-03-30 8:17 ` [PATCH 0/4] mac80211: inform the low level driver about events in mac80211 Johannes Berg
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).