mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Conflicts: net/wireless/reg.c
This commit is contained in:
commit
353c78152c
38 changed files with 1302 additions and 453 deletions
|
@ -300,9 +300,6 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
|
|||
if (!sdata->dev)
|
||||
continue;
|
||||
|
||||
if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
|
||||
continue;
|
||||
|
||||
if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE &&
|
||||
local->queue_stop_reasons[sdata->vif.cab_queue] != 0)
|
||||
continue;
|
||||
|
@ -743,6 +740,7 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
|||
case WLAN_EID_TIMEOUT_INTERVAL:
|
||||
case WLAN_EID_SECONDARY_CHANNEL_OFFSET:
|
||||
case WLAN_EID_WIDE_BW_CHANNEL_SWITCH:
|
||||
case WLAN_EID_CHAN_SWITCH_PARAM:
|
||||
/*
|
||||
* not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible
|
||||
* that if the content gets bigger it might be needed more than once
|
||||
|
@ -908,6 +906,14 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
|||
}
|
||||
elems->sec_chan_offs = (void *)pos;
|
||||
break;
|
||||
case WLAN_EID_CHAN_SWITCH_PARAM:
|
||||
if (elen !=
|
||||
sizeof(*elems->mesh_chansw_params_ie)) {
|
||||
elem_parse_failed = true;
|
||||
break;
|
||||
}
|
||||
elems->mesh_chansw_params_ie = (void *)pos;
|
||||
break;
|
||||
case WLAN_EID_WIDE_BW_CHANNEL_SWITCH:
|
||||
if (!action ||
|
||||
elen != sizeof(*elems->wide_bw_chansw_ie)) {
|
||||
|
@ -2354,3 +2360,115 @@ u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if smps_mode_new is strictly more restrictive than
|
||||
* smps_mode_old.
|
||||
*/
|
||||
bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old,
|
||||
enum ieee80211_smps_mode smps_mode_new)
|
||||
{
|
||||
if (WARN_ON_ONCE(smps_mode_old == IEEE80211_SMPS_AUTOMATIC ||
|
||||
smps_mode_new == IEEE80211_SMPS_AUTOMATIC))
|
||||
return false;
|
||||
|
||||
switch (smps_mode_old) {
|
||||
case IEEE80211_SMPS_STATIC:
|
||||
return false;
|
||||
case IEEE80211_SMPS_DYNAMIC:
|
||||
return smps_mode_new == IEEE80211_SMPS_STATIC;
|
||||
case IEEE80211_SMPS_OFF:
|
||||
return smps_mode_new != IEEE80211_SMPS_OFF;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_csa_settings *csa_settings)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
int freq;
|
||||
int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) +
|
||||
sizeof(mgmt->u.action.u.chan_switch);
|
||||
u8 *pos;
|
||||
|
||||
if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
|
||||
sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = dev_alloc_skb(local->tx_headroom + hdr_len +
|
||||
5 + /* channel switch announcement element */
|
||||
3 + /* secondary channel offset element */
|
||||
8); /* mesh channel switch parameters element */
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
skb_reserve(skb, local->tx_headroom);
|
||||
mgmt = (struct ieee80211_mgmt *)skb_put(skb, hdr_len);
|
||||
memset(mgmt, 0, hdr_len);
|
||||
mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||
IEEE80211_STYPE_ACTION);
|
||||
|
||||
eth_broadcast_addr(mgmt->da);
|
||||
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
|
||||
if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
|
||||
} else {
|
||||
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
||||
memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
|
||||
}
|
||||
mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
|
||||
mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
|
||||
pos = skb_put(skb, 5);
|
||||
*pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */
|
||||
*pos++ = 3; /* IE length */
|
||||
*pos++ = csa_settings->block_tx ? 1 : 0; /* CSA mode */
|
||||
freq = csa_settings->chandef.chan->center_freq;
|
||||
*pos++ = ieee80211_frequency_to_channel(freq); /* channel */
|
||||
*pos++ = csa_settings->count; /* count */
|
||||
|
||||
if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) {
|
||||
enum nl80211_channel_type ch_type;
|
||||
|
||||
skb_put(skb, 3);
|
||||
*pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */
|
||||
*pos++ = 1; /* IE length */
|
||||
ch_type = cfg80211_get_chandef_type(&csa_settings->chandef);
|
||||
if (ch_type == NL80211_CHAN_HT40PLUS)
|
||||
*pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
|
||||
else
|
||||
*pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
|
||||
}
|
||||
|
||||
if (ieee80211_vif_is_mesh(&sdata->vif)) {
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
__le16 pre_value;
|
||||
|
||||
skb_put(skb, 8);
|
||||
*pos++ = WLAN_EID_CHAN_SWITCH_PARAM; /* EID */
|
||||
*pos++ = 6; /* IE length */
|
||||
*pos++ = sdata->u.mesh.mshcfg.dot11MeshTTL; /* Mesh TTL */
|
||||
*pos = 0x00; /* Mesh Flag: Tx Restrict, Initiator, Reason */
|
||||
*pos |= WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
|
||||
*pos++ |= csa_settings->block_tx ?
|
||||
WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
|
||||
put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */
|
||||
pos += 2;
|
||||
if (!ifmsh->pre_value)
|
||||
ifmsh->pre_value = 1;
|
||||
else
|
||||
ifmsh->pre_value++;
|
||||
pre_value = cpu_to_le16(ifmsh->pre_value);
|
||||
memcpy(pos, &pre_value, 2); /* Precedence Value */
|
||||
pos += 2;
|
||||
ifmsh->chsw_init = true;
|
||||
}
|
||||
|
||||
ieee80211_tx_skb(sdata, skb);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue