diff options
author | Chun-Yeow Yeoh <yeohchunyeow@cozybit.com> | 2013-10-14 22:08:28 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-10-28 10:05:29 -0400 |
commit | c6da674aff9425dc41255bcb7f7586a656843f2d (patch) | |
tree | b711d3f6149e66ee579efc544c3391e4b0a48e7c /net/mac80211/ibss.c | |
parent | 8f2535b92d685c68db4bc699dd78462a646f6ef9 (diff) |
{nl,cfg,mac}80211: enable the triggering of CSA frame in mesh
Allow the triggering of CSA frame using mesh interface. The
rules are more or less same with IBSS, such as not allowed to
change between the band and channel width has to be same from
the previous mode. Also, move the ieee80211_send_action_csa
to a common space so that it can be re-used by mesh interface.
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r-- | net/mac80211/ibss.c | 54 |
1 files changed, 0 insertions, 54 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index a0ae02760139..531be040b9ae 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -464,60 +464,6 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
464 | tsf, false); | 464 | tsf, false); |
465 | } | 465 | } |
466 | 466 | ||
467 | static int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, | ||
468 | struct cfg80211_csa_settings *csa_settings) | ||
469 | { | ||
470 | struct sk_buff *skb; | ||
471 | struct ieee80211_mgmt *mgmt; | ||
472 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | ||
473 | struct ieee80211_local *local = sdata->local; | ||
474 | int freq; | ||
475 | int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) + | ||
476 | sizeof(mgmt->u.action.u.chan_switch); | ||
477 | u8 *pos; | ||
478 | |||
479 | skb = dev_alloc_skb(local->tx_headroom + hdr_len + | ||
480 | 5 + /* channel switch announcement element */ | ||
481 | 3); /* secondary channel offset element */ | ||
482 | if (!skb) | ||
483 | return -1; | ||
484 | |||
485 | skb_reserve(skb, local->tx_headroom); | ||
486 | mgmt = (struct ieee80211_mgmt *)skb_put(skb, hdr_len); | ||
487 | memset(mgmt, 0, hdr_len); | ||
488 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
489 | IEEE80211_STYPE_ACTION); | ||
490 | |||
491 | eth_broadcast_addr(mgmt->da); | ||
492 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | ||
493 | memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); | ||
494 | mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; | ||
495 | mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH; | ||
496 | pos = skb_put(skb, 5); | ||
497 | *pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */ | ||
498 | *pos++ = 3; /* IE length */ | ||
499 | *pos++ = csa_settings->block_tx ? 1 : 0; /* CSA mode */ | ||
500 | freq = csa_settings->chandef.chan->center_freq; | ||
501 | *pos++ = ieee80211_frequency_to_channel(freq); /* channel */ | ||
502 | *pos++ = csa_settings->count; /* count */ | ||
503 | |||
504 | if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) { | ||
505 | enum nl80211_channel_type ch_type; | ||
506 | |||
507 | skb_put(skb, 3); | ||
508 | *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */ | ||
509 | *pos++ = 1; /* IE length */ | ||
510 | ch_type = cfg80211_get_chandef_type(&csa_settings->chandef); | ||
511 | if (ch_type == NL80211_CHAN_HT40PLUS) | ||
512 | *pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
513 | else | ||
514 | *pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
515 | } | ||
516 | |||
517 | ieee80211_tx_skb(sdata, skb); | ||
518 | return 0; | ||
519 | } | ||
520 | |||
521 | int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, | 467 | int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata, |
522 | struct cfg80211_csa_settings *csa_settings) | 468 | struct cfg80211_csa_settings *csa_settings) |
523 | { | 469 | { |