2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-24 13:13:57 +08:00

mwifiex: support for channel report for radar detection

This patch adds support for channel report enabling.
Channel report event happens if radar is detected on specified channel
after driver has issued radar detect command within CAC time.
Driver in turn sends RADAR_DETECTED event to cfg80211 to tell radar was
detected within CAC time.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Qingshui Gao <gaoqs@marvell.com>
Signed-off-by: Cathy Luo <cluo@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Avinash Patil 2015-01-28 15:54:22 +05:30 committed by Kalle Valo
parent 85afb18621
commit 0a694d6865
5 changed files with 85 additions and 0 deletions

View File

@ -165,3 +165,54 @@ void mwifiex_abort_cac(struct mwifiex_private *priv)
NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
}
}
/* This function handles channel report event from FW during CAC period.
* If radar is detected during CAC, driver indicates the same to cfg80211
* and also cancels ongoing delayed work.
*/
int mwifiex_11h_handle_chanrpt_ready(struct mwifiex_private *priv,
struct sk_buff *skb)
{
struct host_cmd_ds_chan_rpt_event *rpt_event;
struct mwifiex_ie_types_chan_rpt_data *rpt;
u8 *evt_buf;
u16 event_len, tlv_len;
rpt_event = (void *)(skb->data + sizeof(u32));
event_len = skb->len - (sizeof(struct host_cmd_ds_chan_rpt_event)+
sizeof(u32));
if (le32_to_cpu(rpt_event->result) != HostCmd_RESULT_OK) {
dev_err(priv->adapter->dev, "Error in channel report event\n");
return -1;
}
evt_buf = (void *)&rpt_event->tlvbuf;
while (event_len >= sizeof(struct mwifiex_ie_types_header)) {
rpt = (void *)&rpt_event->tlvbuf;
tlv_len = le16_to_cpu(rpt->header.len);
switch (le16_to_cpu(rpt->header.type)) {
case TLV_TYPE_CHANRPT_11H_BASIC:
if (rpt->map.radar) {
dev_notice(priv->adapter->dev,
"RADAR Detected on channel %d!\n",
priv->dfs_chandef.chan->hw_value);
cancel_delayed_work_sync(&priv->dfs_cac_work);
cfg80211_cac_event(priv->netdev,
&priv->dfs_chandef,
NL80211_RADAR_DETECTED,
GFP_KERNEL);
}
break;
default:
break;
}
evt_buf += (tlv_len + sizeof(rpt->header));
event_len -= (tlv_len + sizeof(rpt->header));
}
return 0;
}

View File

@ -158,6 +158,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84)
#define TLV_TYPE_BSS_SCAN_RSP (PROPRIETARY_TLV_BASE_ID + 86)
#define TLV_TYPE_BSS_SCAN_INFO (PROPRIETARY_TLV_BASE_ID + 87)
#define TLV_TYPE_CHANRPT_11H_BASIC (PROPRIETARY_TLV_BASE_ID + 91)
#define TLV_TYPE_UAP_RETRY_LIMIT (PROPRIETARY_TLV_BASE_ID + 93)
#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94)
#define TLV_TYPE_UAP_MGMT_FRAME (PROPRIETARY_TLV_BASE_ID + 104)
@ -494,6 +495,7 @@ enum P2P_MODES {
#define EVENT_HOSTWAKE_STAIE 0x0000004d
#define EVENT_CHANNEL_SWITCH_ANN 0x00000050
#define EVENT_TDLS_GENERIC_EVENT 0x00000052
#define EVENT_CHANNEL_REPORT_RDY 0x00000054
#define EVENT_EXT_SCAN_REPORT 0x00000058
#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f
#define EVENT_TX_STATUS_REPORT 0x00000074
@ -1228,6 +1230,13 @@ struct host_cmd_ds_chan_rpt_req {
__le32 msec_dwell_time;
} __packed;
struct host_cmd_ds_chan_rpt_event {
__le32 result;
__le64 start_tsf;
__le32 duration;
u8 tlvbuf[0];
} __packed;
struct mwifiex_fixed_bcn_param {
__le64 timestamp;
__le16 beacon_period;
@ -1804,6 +1813,20 @@ struct mwifiex_ie_types_rssi_threshold {
u8 evt_freq;
} __packed;
struct meas_rpt_map {
u8 rssi:3;
u8 unmeasured:1;
u8 radar:1;
u8 unidentified_sig:1;
u8 ofdm_preamble:1;
u8 bss:1;
} __packed;
struct mwifiex_ie_types_chan_rpt_data {
struct mwifiex_ie_types_header header;
struct meas_rpt_map map;
} __packed;
struct host_cmd_ds_802_11_subsc_evt {
__le16 action;
__le16 events;

View File

@ -1384,6 +1384,8 @@ void mwifiex_clean_auto_tdls(struct mwifiex_private *priv);
int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv,
struct host_cmd_ds_command *cmd,
void *data_buf);
int mwifiex_11h_handle_chanrpt_ready(struct mwifiex_private *priv,
struct sk_buff *skb);
void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
void *event_body);

View File

@ -516,6 +516,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
mwifiex_parse_tx_status_event(priv, adapter->event_body);
break;
case EVENT_CHANNEL_REPORT_RDY:
dev_dbg(adapter->dev, "event: Channel Report\n");
ret = mwifiex_11h_handle_chanrpt_ready(priv,
adapter->event_skb);
break;
default:
dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
eventcause);

View File

@ -215,7 +215,11 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
adapter->ps_state = PS_STATE_AWAKE;
adapter->pm_wakeup_card_req = false;
adapter->pm_wakeup_fw_try = false;
break;
case EVENT_CHANNEL_REPORT_RDY:
dev_dbg(adapter->dev, "event: Channel Report\n");
mwifiex_11h_handle_chanrpt_ready(priv, adapter->event_skb);
break;
default:
dev_dbg(adapter->dev, "event: unknown event id: %#x\n",