summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/11h.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/11h.c')
-rw-r--r--drivers/net/wireless/mwifiex/11h.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
index 8832c83816ee..e44cac72712e 100644
--- a/drivers/net/wireless/mwifiex/11h.c
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -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;
+}