mwifiex: add cfg80211 start_radar_detection handler
authorAvinash Patil <patila@marvell.com>
Wed, 28 Jan 2015 10:24:21 +0000 (15:54 +0530)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 29 Jan 2015 08:22:04 +0000 (10:22 +0200)
This patch adds support for cfg80211 start_radar_detection handler.
Upon reception of start_radar_detection, driver prepares radar detect
command to FW.

Delayed work is queued for CAC time which sends radar detection finished
event to cfg80211.

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>
drivers/net/wireless/mwifiex/11h.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/decl.h
drivers/net/wireless/mwifiex/fw.h
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sta_cmd.c
drivers/net/wireless/mwifiex/sta_cmdresp.c
drivers/net/wireless/mwifiex/uap_cmd.c

index f23b647..8832c83 100644 (file)
@@ -99,3 +99,69 @@ void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
                bss_desc->cap_info_bitmap &= ~WLAN_CAPABILITY_SPECTRUM_MGMT;
        }
 }
+
+/* This is DFS CAC work queue function.
+ * This delayed work emits CAC finished event for cfg80211 if
+ * CAC was started earlier.
+ */
+void mwifiex_dfs_cac_work_queue(struct work_struct *work)
+{
+       struct cfg80211_chan_def chandef;
+       struct delayed_work *delayed_work =
+                       container_of(work, struct delayed_work, work);
+       struct mwifiex_private *priv =
+                       container_of(delayed_work, struct mwifiex_private,
+                                    dfs_cac_work);
+
+       if (WARN_ON(!priv))
+               return;
+
+       chandef = priv->dfs_chandef;
+       if (priv->wdev.cac_started) {
+               dev_dbg(priv->adapter->dev,
+                       "CAC timer finished; No radar detected\n");
+               cfg80211_cac_event(priv->netdev, &chandef,
+                                  NL80211_RADAR_CAC_FINISHED,
+                                  GFP_KERNEL);
+       }
+}
+
+/* This function prepares channel report request command to FW for
+ * starting radar detection.
+ */
+int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv,
+                                         struct host_cmd_ds_command *cmd,
+                                         void *data_buf)
+{
+       struct host_cmd_ds_chan_rpt_req *cr_req = &cmd->params.chan_rpt_req;
+       struct mwifiex_radar_params *radar_params = (void *)data_buf;
+
+       cmd->command = cpu_to_le16(HostCmd_CMD_CHAN_REPORT_REQUEST);
+       cmd->size = cpu_to_le16(S_DS_GEN);
+       le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_chan_rpt_req));
+
+       cr_req->chan_desc.start_freq = cpu_to_le16(MWIFIEX_A_BAND_START_FREQ);
+       cr_req->chan_desc.chan_num = radar_params->chandef->chan->hw_value;
+       cr_req->chan_desc.chan_width = radar_params->chandef->width;
+       cr_req->msec_dwell_time = cpu_to_le32(radar_params->cac_time_ms);
+
+       dev_dbg(priv->adapter->dev,
+               "11h: issuing DFS Radar check for channel=%d\n",
+               radar_params->chandef->chan->hw_value);
+
+       return 0;
+}
+
+/* This function is to abort ongoing CAC upon stopping AP operations
+ * or during unload.
+ */
+void mwifiex_abort_cac(struct mwifiex_private *priv)
+{
+       if (priv->wdev.cac_started) {
+               dev_dbg(priv->adapter->dev,
+                       "Aborting delayed work for CAC.\n");
+               cancel_delayed_work_sync(&priv->dfs_cac_work);
+               cfg80211_cac_event(priv->netdev, &priv->dfs_chandef,
+                                  NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
+       }
+}
Simple merge
Simple merge
Simple merge
Simple merge