aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/cfg80211.c
diff options
context:
space:
mode:
authorStone Piao <piaoyun@marvell.com>2012-09-25 23:23:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-09-28 13:54:04 -0400
commit7feb4c48313d58b445a91a598d99c025029ce00b (patch)
treeb77c5922101df50081442a96335a0730a235ca45 /drivers/net/wireless/mwifiex/cfg80211.c
parent2dbaf751b1dec3a603130a475f94cc4d3f404362 (diff)
mwifiex: implement remain_on_channel and cancel_remain_on_channel
Add a new command to implement remain_on_channel and cancel_remain_on_channel. Signed-off-by: Stone Piao <piaoyun@marvell.com> Signed-off-by: Kiran Divekar <dkiran@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex/cfg80211.c')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c82
1 files changed, 79 insertions, 3 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index f86043df8d4d..261d7c548a5e 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -77,8 +77,7 @@ static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
77 * NL80211_CHAN_HT40MINUS -> IEEE80211_HT_PARAM_CHA_SEC_BELOW 77 * NL80211_CHAN_HT40MINUS -> IEEE80211_HT_PARAM_CHA_SEC_BELOW
78 * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE 78 * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE
79 */ 79 */
80static u8 80u8 mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
81mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type)
82{ 81{
83 switch (chan_type) { 82 switch (chan_type) {
84 case NL80211_CHAN_NO_HT: 83 case NL80211_CHAN_NO_HT:
@@ -248,6 +247,79 @@ mwifiex_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
248} 247}
249 248
250/* 249/*
250 * CFG802.11 operation handler to remain on channel.
251 */
252static int
253mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy,
254 struct wireless_dev *wdev,
255 struct ieee80211_channel *chan,
256 enum nl80211_channel_type channel_type,
257 unsigned int duration, u64 *cookie)
258{
259 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
260 int ret;
261
262 if (!chan || !cookie) {
263 wiphy_err(wiphy, "Invalid parameter for ROC\n");
264 return -EINVAL;
265 }
266
267 if (priv->roc_cfg.cookie) {
268 wiphy_dbg(wiphy, "info: ongoing ROC, cookie = 0x%llu\n",
269 priv->roc_cfg.cookie);
270 return -EBUSY;
271 }
272
273 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan,
274 &channel_type, duration);
275
276 if (!ret) {
277 *cookie = random32() | 1;
278 priv->roc_cfg.cookie = *cookie;
279 priv->roc_cfg.chan = *chan;
280 priv->roc_cfg.chan_type = channel_type;
281
282 cfg80211_ready_on_channel(wdev, *cookie, chan, channel_type,
283 duration, GFP_ATOMIC);
284
285 wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie);
286 }
287
288 return ret;
289}
290
291/*
292 * CFG802.11 operation handler to cancel remain on channel.
293 */
294static int
295mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
296 struct wireless_dev *wdev, u64 cookie)
297{
298 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
299 int ret;
300
301 if (cookie != priv->roc_cfg.cookie)
302 return -ENOENT;
303
304 ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE,
305 &priv->roc_cfg.chan,
306 &priv->roc_cfg.chan_type, 0);
307
308 if (!ret) {
309 cfg80211_remain_on_channel_expired(wdev, cookie,
310 &priv->roc_cfg.chan,
311 priv->roc_cfg.chan_type,
312 GFP_ATOMIC);
313
314 memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg));
315
316 wiphy_dbg(wiphy, "info: cancel ROC, cookie = 0x%llx\n", cookie);
317 }
318
319 return ret;
320}
321
322/*
251 * CFG802.11 operation handler to set Tx power. 323 * CFG802.11 operation handler to set Tx power.
252 */ 324 */
253static int 325static int
@@ -1950,6 +2022,8 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
1950 .del_key = mwifiex_cfg80211_del_key, 2022 .del_key = mwifiex_cfg80211_del_key,
1951 .mgmt_tx = mwifiex_cfg80211_mgmt_tx, 2023 .mgmt_tx = mwifiex_cfg80211_mgmt_tx,
1952 .mgmt_frame_register = mwifiex_cfg80211_mgmt_frame_register, 2024 .mgmt_frame_register = mwifiex_cfg80211_mgmt_frame_register,
2025 .remain_on_channel = mwifiex_cfg80211_remain_on_channel,
2026 .cancel_remain_on_channel = mwifiex_cfg80211_cancel_remain_on_channel,
1953 .set_default_key = mwifiex_cfg80211_set_default_key, 2027 .set_default_key = mwifiex_cfg80211_set_default_key,
1954 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, 2028 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
1955 .set_tx_power = mwifiex_cfg80211_set_tx_power, 2029 .set_tx_power = mwifiex_cfg80211_set_tx_power,
@@ -1987,6 +2061,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
1987 wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH; 2061 wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
1988 wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN; 2062 wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
1989 wiphy->mgmt_stypes = mwifiex_mgmt_stypes; 2063 wiphy->mgmt_stypes = mwifiex_mgmt_stypes;
2064 wiphy->max_remain_on_channel_duration = 5000;
1990 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 2065 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1991 BIT(NL80211_IFTYPE_ADHOC) | 2066 BIT(NL80211_IFTYPE_ADHOC) |
1992 BIT(NL80211_IFTYPE_AP); 2067 BIT(NL80211_IFTYPE_AP);
@@ -2008,7 +2083,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2008 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 2083 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2009 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | 2084 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
2010 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | 2085 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
2011 WIPHY_FLAG_CUSTOM_REGULATORY; 2086 WIPHY_FLAG_CUSTOM_REGULATORY |
2087 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2012 2088
2013 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom); 2089 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
2014 2090