Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mac80211-next-for-john-2014-11-04' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg <johannes@sipsolutions.net> says:

"This relatively large batch of changes is comprised of the
following:
* large mac80211-hwsim changes from Ben, Jukka and a bit myself
* OCB/WAVE/11p support from Rostislav on behalf of the Czech Technical
University in Prague and Volkswagen Group Research
* minstrel VHT work from Karl
* more CSA work from Luca
* WMM admission control support in mac80211 (myself)
* various smaller fixes, spelling corrections, and minor API additions"

Conflicts:
drivers/net/wireless/ath/wil6210/cfg80211.c

Signed-off-by: John W. Linville <linville@tuxdriver.com>

+2758 -453
+1 -1
drivers/net/wireless/ath/ath10k/core.h
··· 338 338 * stopped in ath10k_core_restart() work holding conf_mutex. The state 339 339 * RESTARTED means that the device is up and mac80211 has started hw 340 340 * reconfiguration. Once mac80211 is done with the reconfiguration we 341 - * set the state to STATE_ON in restart_complete(). */ 341 + * set the state to STATE_ON in reconfig_complete(). */ 342 342 ATH10K_STATE_RESTARTING, 343 343 ATH10K_STATE_RESTARTED, 344 344
+6 -2
drivers/net/wireless/ath/ath10k/mac.c
··· 3994 3994 } 3995 3995 #endif 3996 3996 3997 - static void ath10k_restart_complete(struct ieee80211_hw *hw) 3997 + static void ath10k_reconfig_complete(struct ieee80211_hw *hw, 3998 + enum ieee80211_reconfig_type reconfig_type) 3998 3999 { 3999 4000 struct ath10k *ar = hw->priv; 4001 + 4002 + if (reconfig_type != IEEE80211_RECONFIG_TYPE_RESTART) 4003 + return; 4000 4004 4001 4005 mutex_lock(&ar->conf_mutex); 4002 4006 ··· 4519 4515 .tx_last_beacon = ath10k_tx_last_beacon, 4520 4516 .set_antenna = ath10k_set_antenna, 4521 4517 .get_antenna = ath10k_get_antenna, 4522 - .restart_complete = ath10k_restart_complete, 4518 + .reconfig_complete = ath10k_reconfig_complete, 4523 4519 .get_survey = ath10k_get_survey, 4524 4520 .set_bitrate_mask = ath10k_set_bitrate_mask, 4525 4521 .sta_rc_update = ath10k_sta_rc_update,
+2 -2
drivers/net/wireless/ath/ath6kl/cfg80211.c
··· 2976 2976 static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 2977 2977 2978 2978 static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev, 2979 - const u8 *mac) 2979 + struct station_del_parameters *params) 2980 2980 { 2981 2981 struct ath6kl *ar = ath6kl_priv(dev); 2982 2982 struct ath6kl_vif *vif = netdev_priv(dev); 2983 - const u8 *addr = mac ? mac : bcast_addr; 2983 + const u8 *addr = params->mac ? params->mac : bcast_addr; 2984 2984 2985 2985 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH, 2986 2986 addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
+3 -2
drivers/net/wireless/ath/wil6210/cfg80211.c
··· 792 792 } 793 793 794 794 static int wil_cfg80211_del_station(struct wiphy *wiphy, 795 - struct net_device *dev, const u8 *mac) 795 + struct net_device *dev, 796 + struct station_del_parameters *params) 796 797 { 797 798 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 798 799 799 800 mutex_lock(&wil->mutex); 800 - wil6210_disconnect(wil, mac, false); 801 + wil6210_disconnect(wil, params->mac, false); 801 802 mutex_unlock(&wil->mutex); 802 803 803 804 return 0;
+4 -4
drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
··· 4045 4045 4046 4046 static int 4047 4047 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev, 4048 - const u8 *mac) 4048 + struct station_del_parameters *params) 4049 4049 { 4050 4050 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 4051 4051 struct brcmf_scb_val_le scbval; 4052 4052 struct brcmf_if *ifp = netdev_priv(ndev); 4053 4053 s32 err; 4054 4054 4055 - if (!mac) 4055 + if (!params->mac) 4056 4056 return -EFAULT; 4057 4057 4058 - brcmf_dbg(TRACE, "Enter %pM\n", mac); 4058 + brcmf_dbg(TRACE, "Enter %pM\n", params->mac); 4059 4059 4060 4060 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) 4061 4061 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; 4062 4062 if (!check_vif_up(ifp->vif)) 4063 4063 return -EIO; 4064 4064 4065 - memcpy(&scbval.ea, mac, ETH_ALEN); 4065 + memcpy(&scbval.ea, params->mac, ETH_ALEN); 4066 4066 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING); 4067 4067 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, 4068 4068 &scbval, sizeof(scbval));
+1 -1
drivers/net/wireless/iwlegacy/4965-mac.c
··· 6063 6063 } 6064 6064 6065 6065 void 6066 - il4965_mac_channel_switch(struct ieee80211_hw *hw, 6066 + il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 6067 6067 struct ieee80211_channel_switch *ch_switch) 6068 6068 { 6069 6069 struct il_priv *il = hw->priv;
+3 -2
drivers/net/wireless/iwlegacy/4965.h
··· 187 187 u8 buf_size); 188 188 int il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 189 189 struct ieee80211_sta *sta); 190 - void il4965_mac_channel_switch(struct ieee80211_hw *hw, 191 - struct ieee80211_channel_switch *ch_switch); 190 + void 191 + il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 192 + struct ieee80211_channel_switch *ch_switch); 192 193 193 194 void il4965_led_enable(struct il_priv *il); 194 195
+1
drivers/net/wireless/iwlwifi/dvm/mac80211.c
··· 941 941 } 942 942 943 943 static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, 944 + struct ieee80211_vif *vif, 944 945 struct ieee80211_channel_switch *ch_switch) 945 946 { 946 947 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
+17 -3
drivers/net/wireless/iwlwifi/mvm/mac80211.c
··· 895 895 return ret; 896 896 } 897 897 898 - static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw) 898 + static void iwl_mvm_restart_complete(struct iwl_mvm *mvm) 899 899 { 900 - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 901 900 int ret; 902 901 903 902 mutex_lock(&mvm->mutex); ··· 912 913 iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); 913 914 914 915 mutex_unlock(&mvm->mutex); 916 + } 917 + 918 + static void 919 + iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw, 920 + enum ieee80211_reconfig_type reconfig_type) 921 + { 922 + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 923 + 924 + switch (reconfig_type) { 925 + case IEEE80211_RECONFIG_TYPE_RESTART: 926 + iwl_mvm_restart_complete(mvm); 927 + break; 928 + case IEEE80211_RECONFIG_TYPE_SUSPEND: 929 + break; 930 + } 915 931 } 916 932 917 933 void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) ··· 3072 3058 .tx = iwl_mvm_mac_tx, 3073 3059 .ampdu_action = iwl_mvm_mac_ampdu_action, 3074 3060 .start = iwl_mvm_mac_start, 3075 - .restart_complete = iwl_mvm_mac_restart_complete, 3061 + .reconfig_complete = iwl_mvm_mac_reconfig_complete, 3076 3062 .stop = iwl_mvm_mac_stop, 3077 3063 .add_interface = iwl_mvm_mac_add_interface, 3078 3064 .remove_interface = iwl_mvm_mac_remove_interface,
+382 -80
drivers/net/wireless/mac80211_hwsim.c
··· 412 412 struct mac_address addresses[2]; 413 413 int channels, idx; 414 414 bool use_chanctx; 415 + bool destroy_on_close; 416 + struct work_struct destroy_work; 417 + u32 portid; 415 418 416 419 struct ieee80211_channel *tmp_chan; 417 420 struct delayed_work roc_done; ··· 439 436 /* 440 437 * Only radios in the same group can communicate together (the 441 438 * channel has to match too). Each bit represents a group. A 442 - * radio can be in more then one group. 439 + * radio can be in more than one group. 443 440 */ 444 441 u64 group; 445 442 ··· 450 447 s64 bcn_delta; 451 448 /* absolute beacon transmission time. Used to cover up "tx" delay. */ 452 449 u64 abs_bcn_ts; 450 + 451 + /* Stats */ 452 + u64 tx_pkts; 453 + u64 rx_pkts; 454 + u64 tx_bytes; 455 + u64 rx_bytes; 456 + u64 tx_dropped; 457 + u64 tx_failed; 453 458 }; 454 459 455 460 ··· 487 476 .maxattr = HWSIM_ATTR_MAX, 488 477 }; 489 478 479 + enum hwsim_multicast_groups { 480 + HWSIM_MCGRP_CONFIG, 481 + }; 482 + 483 + static const struct genl_multicast_group hwsim_mcgrps[] = { 484 + [HWSIM_MCGRP_CONFIG] = { .name = "config", }, 485 + }; 486 + 490 487 /* MAC80211_HWSIM netlink policy */ 491 488 492 489 static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { ··· 515 496 [HWSIM_ATTR_REG_CUSTOM_REG] = { .type = NLA_U32 }, 516 497 [HWSIM_ATTR_REG_STRICT_REG] = { .type = NLA_FLAG }, 517 498 [HWSIM_ATTR_SUPPORT_P2P_DEVICE] = { .type = NLA_FLAG }, 499 + [HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE] = { .type = NLA_FLAG }, 500 + [HWSIM_ATTR_RADIO_NAME] = { .type = NLA_STRING }, 501 + [HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG }, 502 + [HWSIM_ATTR_FREQ] = { .type = NLA_U32 }, 518 503 }; 519 504 520 505 static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, ··· 884 861 /* If the queue contains MAX_QUEUE skb's drop some */ 885 862 if (skb_queue_len(&data->pending) >= MAX_QUEUE) { 886 863 /* Droping until WARN_QUEUE level */ 887 - while (skb_queue_len(&data->pending) >= WARN_QUEUE) 888 - skb_dequeue(&data->pending); 864 + while (skb_queue_len(&data->pending) >= WARN_QUEUE) { 865 + ieee80211_free_txskb(hw, skb_dequeue(&data->pending)); 866 + data->tx_dropped++; 867 + } 889 868 } 890 869 891 870 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC); ··· 921 896 if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags)) 922 897 goto nla_put_failure; 923 898 899 + if (nla_put_u32(skb, HWSIM_ATTR_FREQ, data->channel->center_freq)) 900 + goto nla_put_failure; 901 + 924 902 /* We get the tx control (rate and retries) info*/ 925 903 926 904 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { ··· 945 917 946 918 /* Enqueue the packet */ 947 919 skb_queue_tail(&data->pending, my_skb); 920 + data->tx_pkts++; 921 + data->tx_bytes += my_skb->len; 948 922 return; 949 923 950 924 nla_put_failure: 951 925 printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); 926 + ieee80211_free_txskb(hw, my_skb); 927 + data->tx_failed++; 952 928 } 953 929 954 930 static bool hwsim_chans_compat(struct ieee80211_channel *c1, ··· 1098 1066 rx_status.mactime = now + data2->tsf_offset; 1099 1067 1100 1068 memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); 1069 + data2->rx_pkts++; 1070 + data2->rx_bytes += nskb->len; 1101 1071 ieee80211_rx_irqsafe(data2->hw, nskb); 1102 1072 } 1103 1073 spin_unlock(&hwsim_radio_lock); ··· 1167 1133 return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); 1168 1134 1169 1135 /* NO wmediumd detected, perfect medium simulation */ 1136 + data->tx_pkts++; 1137 + data->tx_bytes += skb->len; 1170 1138 ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel); 1171 1139 1172 1140 if (ack && skb->len >= 16) { ··· 1952 1916 hwsim_check_chanctx_magic(ctx); 1953 1917 } 1954 1918 1919 + static const char mac80211_hwsim_gstrings_stats[][ETH_GSTRING_LEN] = { 1920 + "tx_pkts_nic", 1921 + "tx_bytes_nic", 1922 + "rx_pkts_nic", 1923 + "rx_bytes_nic", 1924 + "d_tx_dropped", 1925 + "d_tx_failed", 1926 + "d_ps_mode", 1927 + "d_group", 1928 + "d_tx_power", 1929 + }; 1930 + 1931 + #define MAC80211_HWSIM_SSTATS_LEN ARRAY_SIZE(mac80211_hwsim_gstrings_stats) 1932 + 1933 + static void mac80211_hwsim_get_et_strings(struct ieee80211_hw *hw, 1934 + struct ieee80211_vif *vif, 1935 + u32 sset, u8 *data) 1936 + { 1937 + if (sset == ETH_SS_STATS) 1938 + memcpy(data, *mac80211_hwsim_gstrings_stats, 1939 + sizeof(mac80211_hwsim_gstrings_stats)); 1940 + } 1941 + 1942 + static int mac80211_hwsim_get_et_sset_count(struct ieee80211_hw *hw, 1943 + struct ieee80211_vif *vif, int sset) 1944 + { 1945 + if (sset == ETH_SS_STATS) 1946 + return MAC80211_HWSIM_SSTATS_LEN; 1947 + return 0; 1948 + } 1949 + 1950 + static void mac80211_hwsim_get_et_stats(struct ieee80211_hw *hw, 1951 + struct ieee80211_vif *vif, 1952 + struct ethtool_stats *stats, u64 *data) 1953 + { 1954 + struct mac80211_hwsim_data *ar = hw->priv; 1955 + int i = 0; 1956 + 1957 + data[i++] = ar->tx_pkts; 1958 + data[i++] = ar->tx_bytes; 1959 + data[i++] = ar->rx_pkts; 1960 + data[i++] = ar->rx_bytes; 1961 + data[i++] = ar->tx_dropped; 1962 + data[i++] = ar->tx_failed; 1963 + data[i++] = ar->ps; 1964 + data[i++] = ar->group; 1965 + data[i++] = ar->power_level; 1966 + 1967 + WARN_ON(i != MAC80211_HWSIM_SSTATS_LEN); 1968 + } 1969 + 1955 1970 static const struct ieee80211_ops mac80211_hwsim_ops = { 1956 1971 .tx = mac80211_hwsim_tx, 1957 1972 .start = mac80211_hwsim_start, ··· 2026 1939 .flush = mac80211_hwsim_flush, 2027 1940 .get_tsf = mac80211_hwsim_get_tsf, 2028 1941 .set_tsf = mac80211_hwsim_set_tsf, 1942 + .get_et_sset_count = mac80211_hwsim_get_et_sset_count, 1943 + .get_et_stats = mac80211_hwsim_get_et_stats, 1944 + .get_et_strings = mac80211_hwsim_get_et_strings, 2029 1945 }; 2030 1946 2031 1947 static struct ieee80211_ops mac80211_hwsim_mchan_ops; 2032 1948 2033 - static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, 2034 - const struct ieee80211_regdomain *regd, 2035 - bool reg_strict, bool p2p_device, 2036 - bool use_chanctx) 1949 + struct hwsim_new_radio_params { 1950 + unsigned int channels; 1951 + const char *reg_alpha2; 1952 + const struct ieee80211_regdomain *regd; 1953 + bool reg_strict; 1954 + bool p2p_device; 1955 + bool use_chanctx; 1956 + bool destroy_on_close; 1957 + const char *hwname; 1958 + bool no_vif; 1959 + }; 1960 + 1961 + static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb, 1962 + struct genl_info *info) 1963 + { 1964 + if (info) 1965 + genl_notify(&hwsim_genl_family, mcast_skb, 1966 + genl_info_net(info), info->snd_portid, 1967 + HWSIM_MCGRP_CONFIG, info->nlhdr, GFP_KERNEL); 1968 + else 1969 + genlmsg_multicast(&hwsim_genl_family, mcast_skb, 0, 1970 + HWSIM_MCGRP_CONFIG, GFP_KERNEL); 1971 + } 1972 + 1973 + static struct sk_buff *build_radio_msg(int cmd, int id, 1974 + struct hwsim_new_radio_params *param) 1975 + { 1976 + struct sk_buff *skb; 1977 + void *data; 1978 + int ret; 1979 + 1980 + skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 1981 + if (!skb) 1982 + return NULL; 1983 + 1984 + data = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, cmd); 1985 + if (!data) 1986 + goto error; 1987 + 1988 + ret = nla_put_u32(skb, HWSIM_ATTR_RADIO_ID, id); 1989 + if (ret < 0) 1990 + goto error; 1991 + 1992 + if (param->channels) { 1993 + ret = nla_put_u32(skb, HWSIM_ATTR_CHANNELS, param->channels); 1994 + if (ret < 0) 1995 + goto error; 1996 + } 1997 + 1998 + if (param->reg_alpha2) { 1999 + ret = nla_put(skb, HWSIM_ATTR_REG_HINT_ALPHA2, 2, 2000 + param->reg_alpha2); 2001 + if (ret < 0) 2002 + goto error; 2003 + } 2004 + 2005 + if (param->regd) { 2006 + int i; 2007 + 2008 + for (i = 0; hwsim_world_regdom_custom[i] != param->regd && 2009 + i < ARRAY_SIZE(hwsim_world_regdom_custom); i++) 2010 + ; 2011 + 2012 + if (i < ARRAY_SIZE(hwsim_world_regdom_custom)) { 2013 + ret = nla_put_u32(skb, HWSIM_ATTR_REG_CUSTOM_REG, i); 2014 + if (ret < 0) 2015 + goto error; 2016 + } 2017 + } 2018 + 2019 + if (param->reg_strict) { 2020 + ret = nla_put_flag(skb, HWSIM_ATTR_REG_STRICT_REG); 2021 + if (ret < 0) 2022 + goto error; 2023 + } 2024 + 2025 + if (param->p2p_device) { 2026 + ret = nla_put_flag(skb, HWSIM_ATTR_SUPPORT_P2P_DEVICE); 2027 + if (ret < 0) 2028 + goto error; 2029 + } 2030 + 2031 + if (param->use_chanctx) { 2032 + ret = nla_put_flag(skb, HWSIM_ATTR_USE_CHANCTX); 2033 + if (ret < 0) 2034 + goto error; 2035 + } 2036 + 2037 + if (param->hwname) { 2038 + ret = nla_put(skb, HWSIM_ATTR_RADIO_NAME, 2039 + strlen(param->hwname), param->hwname); 2040 + if (ret < 0) 2041 + goto error; 2042 + } 2043 + 2044 + genlmsg_end(skb, data); 2045 + 2046 + return skb; 2047 + 2048 + error: 2049 + nlmsg_free(skb); 2050 + return NULL; 2051 + } 2052 + 2053 + static void hswim_mcast_new_radio(int id, struct genl_info *info, 2054 + struct hwsim_new_radio_params *param) 2055 + { 2056 + struct sk_buff *mcast_skb; 2057 + 2058 + mcast_skb = build_radio_msg(HWSIM_CMD_NEW_RADIO, id, param); 2059 + if (!mcast_skb) 2060 + return; 2061 + 2062 + hwsim_mcast_config_msg(mcast_skb, info); 2063 + } 2064 + 2065 + static int mac80211_hwsim_new_radio(struct genl_info *info, 2066 + struct hwsim_new_radio_params *param) 2037 2067 { 2038 2068 int err; 2039 2069 u8 addr[ETH_ALEN]; ··· 2160 1956 const struct ieee80211_ops *ops = &mac80211_hwsim_ops; 2161 1957 int idx; 2162 1958 2163 - if (WARN_ON(channels > 1 && !use_chanctx)) 1959 + if (WARN_ON(param->channels > 1 && !param->use_chanctx)) 2164 1960 return -EINVAL; 2165 1961 2166 1962 spin_lock_bh(&hwsim_radio_lock); 2167 1963 idx = hwsim_radio_idx++; 2168 1964 spin_unlock_bh(&hwsim_radio_lock); 2169 1965 2170 - if (use_chanctx) 1966 + if (param->use_chanctx) 2171 1967 ops = &mac80211_hwsim_mchan_ops; 2172 - hw = ieee80211_alloc_hw(sizeof(*data), ops); 1968 + hw = ieee80211_alloc_hw_nm(sizeof(*data), ops, param->hwname); 2173 1969 if (!hw) { 2174 1970 printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw failed\n"); 2175 1971 err = -ENOMEM; ··· 2207 2003 hw->wiphy->n_addresses = 2; 2208 2004 hw->wiphy->addresses = data->addresses; 2209 2005 2210 - data->channels = channels; 2211 - data->use_chanctx = use_chanctx; 2006 + data->channels = param->channels; 2007 + data->use_chanctx = param->use_chanctx; 2212 2008 data->idx = idx; 2009 + data->destroy_on_close = param->destroy_on_close; 2010 + if (info) 2011 + data->portid = info->snd_portid; 2213 2012 2214 2013 if (data->use_chanctx) { 2215 2014 hw->wiphy->max_scan_ssids = 255; ··· 2221 2014 /* For channels > 1 DFS is not allowed */ 2222 2015 hw->wiphy->n_iface_combinations = 1; 2223 2016 hw->wiphy->iface_combinations = &data->if_combination; 2224 - if (p2p_device) 2017 + if (param->p2p_device) 2225 2018 data->if_combination = hwsim_if_comb_p2p_dev[0]; 2226 2019 else 2227 2020 data->if_combination = hwsim_if_comb[0]; 2228 2021 data->if_combination.num_different_channels = data->channels; 2229 - } else if (p2p_device) { 2022 + } else if (param->p2p_device) { 2230 2023 hw->wiphy->iface_combinations = hwsim_if_comb_p2p_dev; 2231 2024 hw->wiphy->n_iface_combinations = 2232 2025 ARRAY_SIZE(hwsim_if_comb_p2p_dev); ··· 2247 2040 BIT(NL80211_IFTYPE_ADHOC) | 2248 2041 BIT(NL80211_IFTYPE_MESH_POINT); 2249 2042 2250 - if (p2p_device) 2043 + if (param->p2p_device) 2251 2044 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_DEVICE); 2252 2045 2253 2046 hw->flags = IEEE80211_HW_MFP_CAPABLE | ··· 2302 2095 sband->ht_cap.ht_supported = true; 2303 2096 sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 2304 2097 IEEE80211_HT_CAP_GRN_FLD | 2098 + IEEE80211_HT_CAP_SGI_20 | 2305 2099 IEEE80211_HT_CAP_SGI_40 | 2306 2100 IEEE80211_HT_CAP_DSSSCCK40; 2307 2101 sband->ht_cap.ampdu_factor = 0x3; ··· 2350 2142 hw->max_rates = 4; 2351 2143 hw->max_rate_tries = 11; 2352 2144 2353 - if (reg_strict) 2145 + if (param->reg_strict) 2354 2146 hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG; 2355 - if (regd) { 2147 + if (param->regd) { 2356 2148 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 2357 - wiphy_apply_custom_regulatory(hw->wiphy, regd); 2149 + wiphy_apply_custom_regulatory(hw->wiphy, param->regd); 2358 2150 /* give the regulatory workqueue a chance to run */ 2359 2151 schedule_timeout_interruptible(1); 2360 2152 } 2153 + 2154 + if (param->no_vif) 2155 + hw->flags |= IEEE80211_HW_NO_AUTO_VIF; 2361 2156 2362 2157 err = ieee80211_register_hw(hw); 2363 2158 if (err < 0) { ··· 2371 2160 2372 2161 wiphy_debug(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr); 2373 2162 2374 - if (reg_alpha2) 2375 - regulatory_hint(hw->wiphy, reg_alpha2); 2163 + if (param->reg_alpha2) 2164 + regulatory_hint(hw->wiphy, param->reg_alpha2); 2376 2165 2377 2166 data->debugfs = debugfs_create_dir("hwsim", hw->wiphy->debugfsdir); 2378 2167 debugfs_create_file("ps", 0666, data->debugfs, data, &hwsim_fops_ps); ··· 2391 2180 list_add_tail(&data->list, &hwsim_radios); 2392 2181 spin_unlock_bh(&hwsim_radio_lock); 2393 2182 2183 + if (idx > 0) 2184 + hswim_mcast_new_radio(idx, info, param); 2185 + 2394 2186 return idx; 2395 2187 2396 2188 failed_hw: ··· 2404 2190 return err; 2405 2191 } 2406 2192 2407 - static void mac80211_hwsim_destroy_radio(struct mac80211_hwsim_data *data) 2193 + static void hwsim_mcast_del_radio(int id, const char *hwname, 2194 + struct genl_info *info) 2408 2195 { 2196 + struct sk_buff *skb; 2197 + void *data; 2198 + int ret; 2199 + 2200 + skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 2201 + if (!skb) 2202 + return; 2203 + 2204 + data = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, 2205 + HWSIM_CMD_DEL_RADIO); 2206 + if (!data) 2207 + goto error; 2208 + 2209 + ret = nla_put_u32(skb, HWSIM_ATTR_RADIO_ID, id); 2210 + if (ret < 0) 2211 + goto error; 2212 + 2213 + if (hwname) { 2214 + ret = nla_put(skb, HWSIM_ATTR_RADIO_NAME, strlen(hwname), 2215 + hwname); 2216 + if (ret < 0) 2217 + goto error; 2218 + } 2219 + 2220 + genlmsg_end(skb, data); 2221 + 2222 + hwsim_mcast_config_msg(skb, info); 2223 + 2224 + return; 2225 + 2226 + error: 2227 + nlmsg_free(skb); 2228 + } 2229 + 2230 + static void mac80211_hwsim_del_radio(struct mac80211_hwsim_data *data, 2231 + const char *hwname, 2232 + struct genl_info *info) 2233 + { 2234 + hwsim_mcast_del_radio(data->idx, hwname, info); 2409 2235 debugfs_remove_recursive(data->debugfs); 2410 2236 ieee80211_unregister_hw(data->hw); 2411 2237 device_release_driver(data->dev); ··· 2463 2209 list))) { 2464 2210 list_del(&data->list); 2465 2211 spin_unlock_bh(&hwsim_radio_lock); 2466 - mac80211_hwsim_destroy_radio(data); 2212 + mac80211_hwsim_del_radio(data, NULL, NULL); 2467 2213 spin_lock_bh(&hwsim_radio_lock); 2468 2214 } 2469 2215 spin_unlock_bh(&hwsim_radio_lock); ··· 2591 2337 static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, 2592 2338 struct genl_info *info) 2593 2339 { 2594 - 2595 2340 struct mac80211_hwsim_data *data2; 2596 2341 struct ieee80211_rx_status rx_status; 2597 2342 const u8 *dst; ··· 2633 2380 2634 2381 /* A frame is received from user space */ 2635 2382 memset(&rx_status, 0, sizeof(rx_status)); 2383 + /* TODO: Check ATTR_FREQ if it exists, and maybe throw away off-channel 2384 + * packets? 2385 + */ 2636 2386 rx_status.freq = data2->channel->center_freq; 2637 2387 rx_status.band = data2->channel->band; 2638 2388 rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); 2639 2389 rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); 2640 2390 2641 2391 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); 2392 + data2->rx_pkts++; 2393 + data2->rx_bytes += skb->len; 2642 2394 ieee80211_rx_irqsafe(data2->hw, skb); 2643 2395 2644 2396 return 0; 2645 2397 err: 2646 2398 printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); 2647 - goto out; 2648 2399 out: 2649 2400 dev_kfree_skb(skb); 2650 2401 return -EINVAL; ··· 2684 2427 return 0; 2685 2428 } 2686 2429 2687 - static int hwsim_create_radio_nl(struct sk_buff *msg, struct genl_info *info) 2430 + static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) 2688 2431 { 2689 - unsigned int chans = channels; 2690 - const char *alpha2 = NULL; 2691 - const struct ieee80211_regdomain *regd = NULL; 2692 - bool reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; 2693 - bool p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; 2694 - bool use_chanctx; 2432 + struct hwsim_new_radio_params param = { 0 }; 2433 + 2434 + param.reg_strict = info->attrs[HWSIM_ATTR_REG_STRICT_REG]; 2435 + param.p2p_device = info->attrs[HWSIM_ATTR_SUPPORT_P2P_DEVICE]; 2436 + param.channels = channels; 2437 + param.destroy_on_close = 2438 + info->attrs[HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE]; 2695 2439 2696 2440 if (info->attrs[HWSIM_ATTR_CHANNELS]) 2697 - chans = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); 2441 + param.channels = nla_get_u32(info->attrs[HWSIM_ATTR_CHANNELS]); 2442 + 2443 + if (info->attrs[HWSIM_ATTR_NO_VIF]) 2444 + param.no_vif = true; 2445 + 2446 + if (info->attrs[HWSIM_ATTR_RADIO_NAME]) 2447 + param.hwname = nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); 2698 2448 2699 2449 if (info->attrs[HWSIM_ATTR_USE_CHANCTX]) 2700 - use_chanctx = true; 2450 + param.use_chanctx = true; 2701 2451 else 2702 - use_chanctx = (chans > 1); 2452 + param.use_chanctx = (param.channels > 1); 2703 2453 2704 2454 if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]) 2705 - alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]); 2455 + param.reg_alpha2 = 2456 + nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]); 2706 2457 2707 2458 if (info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]) { 2708 2459 u32 idx = nla_get_u32(info->attrs[HWSIM_ATTR_REG_CUSTOM_REG]); 2709 2460 2710 2461 if (idx >= ARRAY_SIZE(hwsim_world_regdom_custom)) 2711 2462 return -EINVAL; 2712 - regd = hwsim_world_regdom_custom[idx]; 2463 + param.regd = hwsim_world_regdom_custom[idx]; 2713 2464 } 2714 2465 2715 - return mac80211_hwsim_create_radio(chans, alpha2, regd, reg_strict, 2716 - p2p_device, use_chanctx); 2466 + return mac80211_hwsim_new_radio(info, &param); 2717 2467 } 2718 2468 2719 - static int hwsim_destroy_radio_nl(struct sk_buff *msg, struct genl_info *info) 2469 + static int hwsim_del_radio_nl(struct sk_buff *msg, struct genl_info *info) 2720 2470 { 2721 2471 struct mac80211_hwsim_data *data; 2722 - int idx; 2472 + s64 idx = -1; 2473 + const char *hwname = NULL; 2723 2474 2724 - if (!info->attrs[HWSIM_ATTR_RADIO_ID]) 2475 + if (info->attrs[HWSIM_ATTR_RADIO_ID]) 2476 + idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]); 2477 + else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) 2478 + hwname = (void *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]); 2479 + else 2725 2480 return -EINVAL; 2726 - idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]); 2727 2481 2728 2482 spin_lock_bh(&hwsim_radio_lock); 2729 2483 list_for_each_entry(data, &hwsim_radios, list) { 2730 - if (data->idx != idx) 2731 - continue; 2484 + if (idx >= 0) { 2485 + if (data->idx != idx) 2486 + continue; 2487 + } else { 2488 + if (hwname && 2489 + strcmp(hwname, wiphy_name(data->hw->wiphy))) 2490 + continue; 2491 + } 2492 + 2732 2493 list_del(&data->list); 2733 2494 spin_unlock_bh(&hwsim_radio_lock); 2734 - mac80211_hwsim_destroy_radio(data); 2495 + mac80211_hwsim_del_radio(data, hwname, info); 2735 2496 return 0; 2736 2497 } 2737 2498 spin_unlock_bh(&hwsim_radio_lock); ··· 2776 2501 .doit = hwsim_tx_info_frame_received_nl, 2777 2502 }, 2778 2503 { 2779 - .cmd = HWSIM_CMD_CREATE_RADIO, 2504 + .cmd = HWSIM_CMD_NEW_RADIO, 2780 2505 .policy = hwsim_genl_policy, 2781 - .doit = hwsim_create_radio_nl, 2506 + .doit = hwsim_new_radio_nl, 2782 2507 .flags = GENL_ADMIN_PERM, 2783 2508 }, 2784 2509 { 2785 - .cmd = HWSIM_CMD_DESTROY_RADIO, 2510 + .cmd = HWSIM_CMD_DEL_RADIO, 2786 2511 .policy = hwsim_genl_policy, 2787 - .doit = hwsim_destroy_radio_nl, 2512 + .doit = hwsim_del_radio_nl, 2788 2513 .flags = GENL_ADMIN_PERM, 2789 2514 }, 2790 2515 }; 2516 + 2517 + static void destroy_radio(struct work_struct *work) 2518 + { 2519 + struct mac80211_hwsim_data *data = 2520 + container_of(work, struct mac80211_hwsim_data, destroy_work); 2521 + 2522 + mac80211_hwsim_del_radio(data, NULL, NULL); 2523 + } 2524 + 2525 + static void remove_user_radios(u32 portid) 2526 + { 2527 + struct mac80211_hwsim_data *entry, *tmp; 2528 + 2529 + spin_lock_bh(&hwsim_radio_lock); 2530 + list_for_each_entry_safe(entry, tmp, &hwsim_radios, list) { 2531 + if (entry->destroy_on_close && entry->portid == portid) { 2532 + list_del(&entry->list); 2533 + INIT_WORK(&entry->destroy_work, destroy_radio); 2534 + schedule_work(&entry->destroy_work); 2535 + } 2536 + } 2537 + spin_unlock_bh(&hwsim_radio_lock); 2538 + } 2791 2539 2792 2540 static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, 2793 2541 unsigned long state, ··· 2820 2522 2821 2523 if (state != NETLINK_URELEASE) 2822 2524 return NOTIFY_DONE; 2525 + 2526 + remove_user_radios(notify->portid); 2823 2527 2824 2528 if (notify->portid == wmediumd_portid) { 2825 2529 printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink" ··· 2842 2542 2843 2543 printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); 2844 2544 2845 - rc = genl_register_family_with_ops(&hwsim_genl_family, hwsim_ops); 2545 + rc = genl_register_family_with_ops_groups(&hwsim_genl_family, 2546 + hwsim_ops, 2547 + hwsim_mcgrps); 2846 2548 if (rc) 2847 2549 goto failure; 2848 2550 ··· 2905 2603 goto out_unregister_driver; 2906 2604 } 2907 2605 2606 + err = hwsim_init_netlink(); 2607 + if (err < 0) 2608 + goto out_unregister_driver; 2609 + 2908 2610 for (i = 0; i < radios; i++) { 2909 - const char *reg_alpha2 = NULL; 2910 - const struct ieee80211_regdomain *regd = NULL; 2911 - bool reg_strict = false; 2611 + struct hwsim_new_radio_params param = { 0 }; 2612 + 2613 + param.channels = channels; 2912 2614 2913 2615 switch (regtest) { 2914 2616 case HWSIM_REGTEST_DIFF_COUNTRY: 2915 2617 if (i < ARRAY_SIZE(hwsim_alpha2s)) 2916 - reg_alpha2 = hwsim_alpha2s[i]; 2618 + param.reg_alpha2 = hwsim_alpha2s[i]; 2917 2619 break; 2918 2620 case HWSIM_REGTEST_DRIVER_REG_FOLLOW: 2919 2621 if (!i) 2920 - reg_alpha2 = hwsim_alpha2s[0]; 2622 + param.reg_alpha2 = hwsim_alpha2s[0]; 2921 2623 break; 2922 2624 case HWSIM_REGTEST_STRICT_ALL: 2923 - reg_strict = true; 2625 + param.reg_strict = true; 2924 2626 case HWSIM_REGTEST_DRIVER_REG_ALL: 2925 - reg_alpha2 = hwsim_alpha2s[0]; 2627 + param.reg_alpha2 = hwsim_alpha2s[0]; 2926 2628 break; 2927 2629 case HWSIM_REGTEST_WORLD_ROAM: 2928 2630 if (i == 0) 2929 - regd = &hwsim_world_regdom_custom_01; 2631 + param.regd = &hwsim_world_regdom_custom_01; 2930 2632 break; 2931 2633 case HWSIM_REGTEST_CUSTOM_WORLD: 2932 - regd = &hwsim_world_regdom_custom_01; 2634 + param.regd = &hwsim_world_regdom_custom_01; 2933 2635 break; 2934 2636 case HWSIM_REGTEST_CUSTOM_WORLD_2: 2935 2637 if (i == 0) 2936 - regd = &hwsim_world_regdom_custom_01; 2638 + param.regd = &hwsim_world_regdom_custom_01; 2937 2639 else if (i == 1) 2938 - regd = &hwsim_world_regdom_custom_02; 2640 + param.regd = &hwsim_world_regdom_custom_02; 2939 2641 break; 2940 2642 case HWSIM_REGTEST_STRICT_FOLLOW: 2941 2643 if (i == 0) { 2942 - reg_strict = true; 2943 - reg_alpha2 = hwsim_alpha2s[0]; 2644 + param.reg_strict = true; 2645 + param.reg_alpha2 = hwsim_alpha2s[0]; 2944 2646 } 2945 2647 break; 2946 2648 case HWSIM_REGTEST_STRICT_AND_DRIVER_REG: 2947 2649 if (i == 0) { 2948 - reg_strict = true; 2949 - reg_alpha2 = hwsim_alpha2s[0]; 2650 + param.reg_strict = true; 2651 + param.reg_alpha2 = hwsim_alpha2s[0]; 2950 2652 } else if (i == 1) { 2951 - reg_alpha2 = hwsim_alpha2s[1]; 2653 + param.reg_alpha2 = hwsim_alpha2s[1]; 2952 2654 } 2953 2655 break; 2954 2656 case HWSIM_REGTEST_ALL: 2955 2657 switch (i) { 2956 2658 case 0: 2957 - regd = &hwsim_world_regdom_custom_01; 2659 + param.regd = &hwsim_world_regdom_custom_01; 2958 2660 break; 2959 2661 case 1: 2960 - regd = &hwsim_world_regdom_custom_02; 2662 + param.regd = &hwsim_world_regdom_custom_02; 2961 2663 break; 2962 2664 case 2: 2963 - reg_alpha2 = hwsim_alpha2s[0]; 2665 + param.reg_alpha2 = hwsim_alpha2s[0]; 2964 2666 break; 2965 2667 case 3: 2966 - reg_alpha2 = hwsim_alpha2s[1]; 2668 + param.reg_alpha2 = hwsim_alpha2s[1]; 2967 2669 break; 2968 2670 case 4: 2969 - reg_strict = true; 2970 - reg_alpha2 = hwsim_alpha2s[2]; 2671 + param.reg_strict = true; 2672 + param.reg_alpha2 = hwsim_alpha2s[2]; 2971 2673 break; 2972 2674 } 2973 2675 break; ··· 2979 2673 break; 2980 2674 } 2981 2675 2982 - err = mac80211_hwsim_create_radio(channels, reg_alpha2, 2983 - regd, reg_strict, 2984 - support_p2p_device, 2985 - channels > 1); 2676 + param.p2p_device = support_p2p_device; 2677 + param.use_chanctx = channels > 1; 2678 + 2679 + err = mac80211_hwsim_new_radio(NULL, &param); 2986 2680 if (err < 0) 2987 2681 goto out_free_radios; 2988 2682 } ··· 3007 2701 goto out_free_mon; 3008 2702 } 3009 2703 rtnl_unlock(); 3010 - 3011 - err = hwsim_init_netlink(); 3012 - if (err < 0) 3013 - goto out_free_mon; 3014 2704 3015 2705 return 0; 3016 2706
+19 -6
drivers/net/wireless/mac80211_hwsim.h
··· 60 60 * space, uses: 61 61 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_ADDR_RECEIVER, 62 62 * %HWSIM_ATTR_FRAME, %HWSIM_ATTR_FLAGS, %HWSIM_ATTR_RX_RATE, 63 - * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE 63 + * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE, %HWSIM_ATTR_FREQ (optional) 64 64 * @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to 65 65 * kernel, uses: 66 66 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS, 67 67 * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE 68 - * @HWSIM_CMD_CREATE_RADIO: create a new radio with the given parameters, 69 - * returns the radio ID (>= 0) or negative on errors 70 - * @HWSIM_CMD_DESTROY_RADIO: destroy a radio 68 + * @HWSIM_CMD_NEW_RADIO: create a new radio with the given parameters, 69 + * returns the radio ID (>= 0) or negative on errors, if successful 70 + * then multicast the result 71 + * @HWSIM_CMD_DEL_RADIO: destroy a radio, reply is multicasted 71 72 * @__HWSIM_CMD_MAX: enum limit 72 73 */ 73 74 enum { ··· 76 75 HWSIM_CMD_REGISTER, 77 76 HWSIM_CMD_FRAME, 78 77 HWSIM_CMD_TX_INFO_FRAME, 79 - HWSIM_CMD_CREATE_RADIO, 80 - HWSIM_CMD_DESTROY_RADIO, 78 + HWSIM_CMD_NEW_RADIO, 79 + HWSIM_CMD_DEL_RADIO, 81 80 __HWSIM_CMD_MAX, 82 81 }; 83 82 #define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1) 83 + 84 + #define HWSIM_CMD_CREATE_RADIO HWSIM_CMD_NEW_RADIO 85 + #define HWSIM_CMD_DESTROY_RADIO HWSIM_CMD_DEL_RADIO 84 86 85 87 /** 86 88 * enum hwsim_attrs - hwsim netlink attributes ··· 115 111 * @HWSIM_ATTR_USE_CHANCTX: used with the %HWSIM_CMD_CREATE_RADIO 116 112 * command to force use of channel contexts even when only a 117 113 * single channel is supported 114 + * @HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE: used with the %HWSIM_CMD_CREATE_RADIO 115 + * command to force radio removal when process that created the radio dies 116 + * @HWSIM_ATTR_RADIO_NAME: Name of radio, e.g. phy666 117 + * @HWSIM_ATTR_NO_VIF: Do not create vif (wlanX) when creating radio. 118 + * @HWSIM_ATTR_FREQ: Frequency at which packet is transmitted or received. 118 119 * @__HWSIM_ATTR_MAX: enum limit 119 120 */ 120 121 ··· 141 132 HWSIM_ATTR_REG_STRICT_REG, 142 133 HWSIM_ATTR_SUPPORT_P2P_DEVICE, 143 134 HWSIM_ATTR_USE_CHANCTX, 135 + HWSIM_ATTR_DESTROY_RADIO_ON_CLOSE, 136 + HWSIM_ATTR_RADIO_NAME, 137 + HWSIM_ATTR_NO_VIF, 138 + HWSIM_ATTR_FREQ, 144 139 __HWSIM_ATTR_MAX, 145 140 }; 146 141 #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
+5 -4
drivers/net/wireless/mwifiex/cfg80211.c
··· 1285 1285 */ 1286 1286 static int 1287 1287 mwifiex_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev, 1288 - const u8 *mac) 1288 + struct station_del_parameters *params) 1289 1289 { 1290 1290 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1291 1291 struct mwifiex_sta_node *sta_node; ··· 1294 1294 if (list_empty(&priv->sta_list) || !priv->bss_started) 1295 1295 return 0; 1296 1296 1297 - if (!mac || is_broadcast_ether_addr(mac)) { 1297 + if (!params->mac || is_broadcast_ether_addr(params->mac)) { 1298 1298 wiphy_dbg(wiphy, "%s: NULL/broadcast mac address\n", __func__); 1299 1299 list_for_each_entry(sta_node, &priv->sta_list, list) { 1300 1300 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH, ··· 1304 1304 mwifiex_uap_del_sta_data(priv, sta_node); 1305 1305 } 1306 1306 } else { 1307 - wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, mac); 1307 + wiphy_dbg(wiphy, "%s: mac address %pM\n", __func__, 1308 + params->mac); 1308 1309 spin_lock_irqsave(&priv->sta_list_spinlock, flags); 1309 - sta_node = mwifiex_get_sta_entry(priv, mac); 1310 + sta_node = mwifiex_get_sta_entry(priv, params->mac); 1310 1311 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); 1311 1312 if (sta_node) { 1312 1313 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_STA_DEAUTH,
+8 -15
drivers/net/wireless/ti/wlcore/main.c
··· 5177 5177 } 5178 5178 5179 5179 static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, 5180 + struct ieee80211_vif *vif, 5180 5181 struct ieee80211_channel_switch *ch_switch) 5181 5182 { 5182 5183 struct wl1271 *wl = hw->priv; 5183 - struct wl12xx_vif *wlvif; 5184 + struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 5184 5185 int ret; 5185 5186 5186 5187 wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); ··· 5191 5190 mutex_lock(&wl->mutex); 5192 5191 5193 5192 if (unlikely(wl->state == WLCORE_STATE_OFF)) { 5194 - wl12xx_for_each_wlvif_sta(wl, wlvif) { 5195 - struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 5196 - 5197 - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 5198 - continue; 5199 - 5193 + if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 5200 5194 ieee80211_chswitch_done(vif, false); 5201 - } 5202 5195 goto out; 5203 5196 } else if (unlikely(wl->state != WLCORE_STATE_ON)) { 5204 5197 goto out; ··· 5203 5208 goto out; 5204 5209 5205 5210 /* TODO: change mac80211 to pass vif as param */ 5206 - wl12xx_for_each_wlvif_sta(wl, wlvif) { 5207 - unsigned long delay_usec; 5208 5211 5209 - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 5210 - continue; 5212 + if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { 5213 + unsigned long delay_usec; 5211 5214 5212 5215 ret = wl->ops->channel_switch(wl, wlvif, ch_switch); 5213 5216 if (ret) ··· 5215 5222 5216 5223 /* indicate failure 5 seconds after channel switch time */ 5217 5224 delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) * 5218 - ch_switch->count; 5225 + ch_switch->count; 5219 5226 ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work, 5220 - usecs_to_jiffies(delay_usec) + 5221 - msecs_to_jiffies(5000)); 5227 + usecs_to_jiffies(delay_usec) + 5228 + msecs_to_jiffies(5000)); 5222 5229 } 5223 5230 5224 5231 out_sleep:
+3 -1
drivers/staging/rtl8723au/os_dep/ioctl_cfg80211.c
··· 2856 2856 } 2857 2857 2858 2858 static int cfg80211_rtw_del_station(struct wiphy *wiphy, 2859 - struct net_device *ndev, const u8 *mac) 2859 + struct net_device *ndev, 2860 + struct station_del_parameters *params) 2860 2861 { 2862 + const u8 *mac = params->mac; 2861 2863 int ret = 0; 2862 2864 struct list_head *phead, *plist, *ptmp; 2863 2865 u8 updated = 0;
+21 -1
include/linux/ieee80211.h
··· 1274 1274 #define IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT 2 1275 1275 1276 1276 /* 1277 - * Maximum length of AMPDU that the STA can receive. 1277 + * Maximum length of AMPDU that the STA can receive in high-throughput (HT). 1278 1278 * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) 1279 1279 */ 1280 1280 enum ieee80211_max_ampdu_length_exp { ··· 1282 1282 IEEE80211_HT_MAX_AMPDU_16K = 1, 1283 1283 IEEE80211_HT_MAX_AMPDU_32K = 2, 1284 1284 IEEE80211_HT_MAX_AMPDU_64K = 3 1285 + }; 1286 + 1287 + /* 1288 + * Maximum length of AMPDU that the STA can receive in VHT. 1289 + * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) 1290 + */ 1291 + enum ieee80211_vht_max_ampdu_length_exp { 1292 + IEEE80211_VHT_MAX_AMPDU_8K = 0, 1293 + IEEE80211_VHT_MAX_AMPDU_16K = 1, 1294 + IEEE80211_VHT_MAX_AMPDU_32K = 2, 1295 + IEEE80211_VHT_MAX_AMPDU_64K = 3, 1296 + IEEE80211_VHT_MAX_AMPDU_128K = 4, 1297 + IEEE80211_VHT_MAX_AMPDU_256K = 5, 1298 + IEEE80211_VHT_MAX_AMPDU_512K = 6, 1299 + IEEE80211_VHT_MAX_AMPDU_1024K = 7 1285 1300 }; 1286 1301 1287 1302 #define IEEE80211_HT_MAX_AMPDU_FACTOR 13 ··· 2012 1997 WLAN_TDLS_PEER_TRAFFIC_RESPONSE = 9, 2013 1998 WLAN_TDLS_DISCOVERY_REQUEST = 10, 2014 1999 }; 2000 + 2001 + /* Extended Channel Switching capability to be set in the 1st byte of 2002 + * the @WLAN_EID_EXT_CAPABILITY information element 2003 + */ 2004 + #define WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING BIT(2) 2015 2005 2016 2006 /* Interworking capabilities are set in 7th bit of 4th byte of the 2017 2007 * @WLAN_EID_EXT_CAPABILITY information element
+73 -11
include/net/cfg80211.h
··· 319 319 /** 320 320 * struct vif_params - describes virtual interface parameters 321 321 * @use_4addr: use 4-address frames 322 - * @macaddr: address to use for this virtual interface. This will only 323 - * be used for non-netdevice interfaces. If this parameter is set 324 - * to zero address the driver may determine the address as needed. 322 + * @macaddr: address to use for this virtual interface. 323 + * If this parameter is set to zero address the driver may 324 + * determine the address as needed. 325 + * This feature is only fully supported by drivers that enable the 326 + * %NL80211_FEATURE_MAC_ON_CREATE flag. Others may support creating 327 + ** only p2p devices with specified MAC. 325 328 */ 326 329 struct vif_params { 327 330 int use_4addr; ··· 799 796 u8 supported_oper_classes_len; 800 797 u8 opmode_notif; 801 798 bool opmode_notif_used; 799 + }; 800 + 801 + /** 802 + * struct station_del_parameters - station deletion parameters 803 + * 804 + * Used to delete a station entry (or all stations). 805 + * 806 + * @mac: MAC address of the station to remove or NULL to remove all stations 807 + * @subtype: Management frame subtype to use for indicating removal 808 + * (10 = Disassociation, 12 = Deauthentication) 809 + * @reason_code: Reason code for the Disassociation/Deauthentication frame 810 + */ 811 + struct station_del_parameters { 812 + const u8 *mac; 813 + u8 subtype; 814 + u16 reason_code; 802 815 }; 803 816 804 817 /** ··· 1356 1337 u16 beacon_interval; 1357 1338 int mcast_rate[IEEE80211_NUM_BANDS]; 1358 1339 u32 basic_rates; 1340 + }; 1341 + 1342 + /** 1343 + * struct ocb_setup - 802.11p OCB mode setup configuration 1344 + * @chandef: defines the channel to use 1345 + * 1346 + * These parameters are fixed when connecting to the network 1347 + */ 1348 + struct ocb_setup { 1349 + struct cfg80211_chan_def chandef; 1359 1350 }; 1360 1351 1361 1352 /** ··· 2161 2132 * @stop_ap: Stop being an AP, including stopping beaconing. 2162 2133 * 2163 2134 * @add_station: Add a new station. 2164 - * @del_station: Remove a station; @mac may be NULL to remove all stations. 2135 + * @del_station: Remove a station 2165 2136 * @change_station: Modify a given station. Note that flags changes are not much 2166 2137 * validated in cfg80211, in particular the auth/assoc/authorized flags 2167 2138 * might come to the driver in invalid combinations -- make sure to check ··· 2175 2146 * @change_mpath: change a given mesh path 2176 2147 * @get_mpath: get a mesh path for the given parameters 2177 2148 * @dump_mpath: dump mesh path callback -- resume dump at index @idx 2149 + * @get_mpp: get a mesh proxy path for the given parameters 2150 + * @dump_mpp: dump mesh proxy path callback -- resume dump at index @idx 2178 2151 * @join_mesh: join the mesh network with the specified parameters 2179 2152 * (invoked with the wireless_dev mutex held) 2180 2153 * @leave_mesh: leave the current mesh network ··· 2362 2331 * with the peer followed by immediate teardown when the addition is later 2363 2332 * rejected) 2364 2333 * @del_tx_ts: remove an existing TX TS 2334 + * 2335 + * @join_ocb: join the OCB network with the specified parameters 2336 + * (invoked with the wireless_dev mutex held) 2337 + * @leave_ocb: leave the current OCB network 2338 + * (invoked with the wireless_dev mutex held) 2365 2339 */ 2366 2340 struct cfg80211_ops { 2367 2341 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); ··· 2412 2376 const u8 *mac, 2413 2377 struct station_parameters *params); 2414 2378 int (*del_station)(struct wiphy *wiphy, struct net_device *dev, 2415 - const u8 *mac); 2379 + struct station_del_parameters *params); 2416 2380 int (*change_station)(struct wiphy *wiphy, struct net_device *dev, 2417 2381 const u8 *mac, 2418 2382 struct station_parameters *params); ··· 2432 2396 int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, 2433 2397 int idx, u8 *dst, u8 *next_hop, 2434 2398 struct mpath_info *pinfo); 2399 + int (*get_mpp)(struct wiphy *wiphy, struct net_device *dev, 2400 + u8 *dst, u8 *mpp, struct mpath_info *pinfo); 2401 + int (*dump_mpp)(struct wiphy *wiphy, struct net_device *dev, 2402 + int idx, u8 *dst, u8 *mpp, 2403 + struct mpath_info *pinfo); 2435 2404 int (*get_mesh_config)(struct wiphy *wiphy, 2436 2405 struct net_device *dev, 2437 2406 struct mesh_config *conf); ··· 2447 2406 const struct mesh_config *conf, 2448 2407 const struct mesh_setup *setup); 2449 2408 int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev); 2409 + 2410 + int (*join_ocb)(struct wiphy *wiphy, struct net_device *dev, 2411 + struct ocb_setup *setup); 2412 + int (*leave_ocb)(struct wiphy *wiphy, struct net_device *dev); 2450 2413 2451 2414 int (*change_bss)(struct wiphy *wiphy, struct net_device *dev, 2452 2415 struct bss_parameters *params); ··· 2668 2623 * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels. 2669 2624 * @WIPHY_FLAG_HAS_CHANNEL_SWITCH: Device supports channel switch in 2670 2625 * beaconing mode (AP, IBSS, Mesh, ...). 2671 - * @WIPHY_FLAG_SUPPORTS_WMM_ADMISSION: the device supports setting up WMM 2672 - * TSPEC sessions (TID aka TSID 0-7) with the NL80211_CMD_ADD_TX_TS 2673 - * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it 2674 - * needs to be able to handle Block-Ack agreements and other things. 2675 2626 */ 2676 2627 enum wiphy_flags { 2677 - WIPHY_FLAG_SUPPORTS_WMM_ADMISSION = BIT(0), 2628 + /* use hole at 0 */ 2678 2629 /* use hole at 1 */ 2679 2630 /* use hole at 2 */ 2680 2631 WIPHY_FLAG_NETNS_OK = BIT(3), ··· 3207 3166 } 3208 3167 3209 3168 /** 3169 + * wiphy_new_nm - create a new wiphy for use with cfg80211 3170 + * 3171 + * @ops: The configuration operations for this device 3172 + * @sizeof_priv: The size of the private area to allocate 3173 + * @requested_name: Request a particular name. 3174 + * NULL is valid value, and means use the default phy%d naming. 3175 + * 3176 + * Create a new wiphy and associate the given operations with it. 3177 + * @sizeof_priv bytes are allocated for private use. 3178 + * 3179 + * Return: A pointer to the new wiphy. This pointer must be 3180 + * assigned to each netdev's ieee80211_ptr for proper operation. 3181 + */ 3182 + struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, 3183 + const char *requested_name); 3184 + 3185 + /** 3210 3186 * wiphy_new - create a new wiphy for use with cfg80211 3211 3187 * 3212 3188 * @ops: The configuration operations for this device ··· 3235 3177 * Return: A pointer to the new wiphy. This pointer must be 3236 3178 * assigned to each netdev's ieee80211_ptr for proper operation. 3237 3179 */ 3238 - struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv); 3180 + static inline struct wiphy *wiphy_new(const struct cfg80211_ops *ops, 3181 + int sizeof_priv) 3182 + { 3183 + return wiphy_new_nm(ops, sizeof_priv, NULL); 3184 + } 3239 3185 3240 3186 /** 3241 3187 * wiphy_register - register a wiphy with cfg80211
+128 -10
include/net/mac80211.h
··· 263 263 * @BSS_CHANGED_BANDWIDTH: The bandwidth used by this interface changed, 264 264 * note that this is only called when it changes after the channel 265 265 * context had been assigned. 266 + * @BSS_CHANGED_OCB: OCB join status changed 266 267 */ 267 268 enum ieee80211_bss_change { 268 269 BSS_CHANGED_ASSOC = 1<<0, ··· 288 287 BSS_CHANGED_P2P_PS = 1<<19, 289 288 BSS_CHANGED_BEACON_INFO = 1<<20, 290 289 BSS_CHANGED_BANDWIDTH = 1<<21, 290 + BSS_CHANGED_OCB = 1<<22, 291 291 292 292 /* when adding here, make sure to change ieee80211_reconfig */ 293 293 }; ··· 741 739 u8 ampdu_ack_len; 742 740 u8 ampdu_len; 743 741 u8 antenna; 744 - void *status_driver_data[21 / sizeof(void *)]; 742 + u16 tx_time; 743 + void *status_driver_data[19 / sizeof(void *)]; 745 744 } status; 746 745 struct { 747 746 struct ieee80211_tx_rate driver_rates[ ··· 1120 1117 * Function (TSF) timer when the frame containing the channel switch 1121 1118 * announcement was received. This is simply the rx.mactime parameter 1122 1119 * the driver passed into mac80211. 1120 + * @device_timestamp: arbitrary timestamp for the device, this is the 1121 + * rx.device_timestamp parameter the driver passed to mac80211. 1123 1122 * @block_tx: Indicates whether transmission must be blocked before the 1124 1123 * scheduled channel switch, as indicated by the AP. 1125 1124 * @chandef: the new channel to switch to ··· 1129 1124 */ 1130 1125 struct ieee80211_channel_switch { 1131 1126 u64 timestamp; 1127 + u32 device_timestamp; 1132 1128 bool block_tx; 1133 1129 struct cfg80211_chan_def chandef; 1134 1130 u8 count; ··· 1429 1423 * @smps_mode: current SMPS mode (off, static or dynamic) 1430 1424 * @rates: rate control selection table 1431 1425 * @tdls: indicates whether the STA is a TDLS peer 1426 + * @tdls_initiator: indicates the STA is an initiator of the TDLS link. Only 1427 + * valid if the STA is a TDLS peer in the first place. 1432 1428 */ 1433 1429 struct ieee80211_sta { 1434 1430 u32 supp_rates[IEEE80211_NUM_BANDS]; ··· 1446 1438 enum ieee80211_smps_mode smps_mode; 1447 1439 struct ieee80211_sta_rates __rcu *rates; 1448 1440 bool tdls; 1441 + bool tdls_initiator; 1449 1442 1450 1443 /* must be last */ 1451 1444 u8 drv_priv[0] __aligned(sizeof(void *)); ··· 1585 1576 * a virtual monitor interface when monitor interfaces are the only 1586 1577 * active interfaces. 1587 1578 * 1579 + * @IEEE80211_HW_NO_AUTO_VIF: The driver would like for no wlanX to 1580 + * be created. It is expected user-space will create vifs as 1581 + * desired (and thus have them named as desired). 1582 + * 1588 1583 * @IEEE80211_HW_QUEUE_CONTROL: The driver wants to control per-interface 1589 1584 * queue mapping in order to use different queues (not just one per AC) 1590 1585 * for different virtual interfaces. See the doc section on HW queue ··· 1635 1622 IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12, 1636 1623 IEEE80211_HW_MFP_CAPABLE = 1<<13, 1637 1624 IEEE80211_HW_WANT_MONITOR_VIF = 1<<14, 1638 - /* free slots */ 1625 + IEEE80211_HW_NO_AUTO_VIF = 1<<15, 1626 + /* free slot */ 1639 1627 IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, 1640 1628 IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, 1641 1629 IEEE80211_HW_CONNECTION_MONITOR = 1<<19, ··· 2389 2375 }; 2390 2376 2391 2377 /** 2378 + * enum ieee80211_reconfig_complete_type - reconfig type 2379 + * 2380 + * This enum is used by the reconfig_complete() callback to indicate what 2381 + * reconfiguration type was completed. 2382 + * 2383 + * @IEEE80211_RECONFIG_TYPE_RESTART: hw restart type 2384 + * (also due to resume() callback returning 1) 2385 + * @IEEE80211_RECONFIG_TYPE_SUSPEND: suspend type (regardless 2386 + * of wowlan configuration) 2387 + */ 2388 + enum ieee80211_reconfig_type { 2389 + IEEE80211_RECONFIG_TYPE_RESTART, 2390 + IEEE80211_RECONFIG_TYPE_SUSPEND, 2391 + }; 2392 + 2393 + /** 2392 2394 * struct ieee80211_ops - callbacks from mac80211 to the driver 2393 2395 * 2394 2396 * This structure contains various callbacks that the driver may ··· 2839 2809 * disabled/enabled via @bss_info_changed. 2840 2810 * @stop_ap: Stop operation on the AP interface. 2841 2811 * 2842 - * @restart_complete: Called after a call to ieee80211_restart_hw(), when the 2843 - * reconfiguration has completed. This can help the driver implement the 2844 - * reconfiguration step. Also called when reconfiguring because the 2845 - * driver's resume function returned 1, as this is just like an "inline" 2846 - * hardware restart. This callback may sleep. 2812 + * @reconfig_complete: Called after a call to ieee80211_restart_hw() and 2813 + * during resume, when the reconfiguration has completed. 2814 + * This can help the driver implement the reconfiguration step (and 2815 + * indicate mac80211 is ready to receive frames). 2816 + * This callback may sleep. 2847 2817 * 2848 2818 * @ipv6_addr_change: IPv6 address assignment on the given interface changed. 2849 2819 * Currently, this is only called for managed or P2P client interfaces. ··· 2859 2829 * transmitted and then call ieee80211_csa_finish(). 2860 2830 * If the CSA count starts as zero or 1, this function will not be called, 2861 2831 * since there won't be any time to beacon before the switch anyway. 2832 + * @pre_channel_switch: This is an optional callback that is called 2833 + * before a channel switch procedure is started (ie. when a STA 2834 + * gets a CSA or an userspace initiated channel-switch), allowing 2835 + * the driver to prepare for the channel switch. 2836 + * @post_channel_switch: This is an optional callback that is called 2837 + * after a channel switch procedure is completed, allowing the 2838 + * driver to go back to a normal configuration. 2862 2839 * 2863 2840 * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all 2864 2841 * information in bss_conf is set up and the beacon can be retrieved. A ··· 2875 2838 * @get_expected_throughput: extract the expected throughput towards the 2876 2839 * specified station. The returned value is expressed in Kbps. It returns 0 2877 2840 * if the RC algorithm does not have proper data to provide. 2841 + * 2842 + * @get_txpower: get current maximum tx power (in dBm) based on configuration 2843 + * and hardware limits. 2878 2844 */ 2879 2845 struct ieee80211_ops { 2880 2846 void (*tx)(struct ieee80211_hw *hw, ··· 2999 2959 void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 3000 2960 u32 queues, bool drop); 3001 2961 void (*channel_switch)(struct ieee80211_hw *hw, 2962 + struct ieee80211_vif *vif, 3002 2963 struct ieee80211_channel_switch *ch_switch); 3003 2964 int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); 3004 2965 int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); ··· 3066 3025 int n_vifs, 3067 3026 enum ieee80211_chanctx_switch_mode mode); 3068 3027 3069 - void (*restart_complete)(struct ieee80211_hw *hw); 3028 + void (*reconfig_complete)(struct ieee80211_hw *hw, 3029 + enum ieee80211_reconfig_type reconfig_type); 3070 3030 3071 3031 #if IS_ENABLED(CONFIG_IPV6) 3072 3032 void (*ipv6_addr_change)(struct ieee80211_hw *hw, ··· 3077 3035 void (*channel_switch_beacon)(struct ieee80211_hw *hw, 3078 3036 struct ieee80211_vif *vif, 3079 3037 struct cfg80211_chan_def *chandef); 3038 + int (*pre_channel_switch)(struct ieee80211_hw *hw, 3039 + struct ieee80211_vif *vif, 3040 + struct ieee80211_channel_switch *ch_switch); 3041 + 3042 + int (*post_channel_switch)(struct ieee80211_hw *hw, 3043 + struct ieee80211_vif *vif); 3080 3044 3081 3045 int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 3082 3046 void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 3083 3047 u32 (*get_expected_throughput)(struct ieee80211_sta *sta); 3048 + int (*get_txpower)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 3049 + int *dbm); 3084 3050 }; 3085 3051 3086 3052 /** 3087 - * ieee80211_alloc_hw - Allocate a new hardware device 3053 + * ieee80211_alloc_hw_nm - Allocate a new hardware device 3054 + * 3055 + * This must be called once for each hardware device. The returned pointer 3056 + * must be used to refer to this device when calling other functions. 3057 + * mac80211 allocates a private data area for the driver pointed to by 3058 + * @priv in &struct ieee80211_hw, the size of this area is given as 3059 + * @priv_data_len. 3060 + * 3061 + * @priv_data_len: length of private data 3062 + * @ops: callbacks for this device 3063 + * @requested_name: Requested name for this device. 3064 + * NULL is valid value, and means use the default naming (phy%d) 3065 + * 3066 + * Return: A pointer to the new hardware device, or %NULL on error. 3067 + */ 3068 + struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, 3069 + const struct ieee80211_ops *ops, 3070 + const char *requested_name); 3071 + 3072 + /** 3073 + * ieee80211_alloc_hw - Allocate a new hardware device 3088 3074 * 3089 3075 * This must be called once for each hardware device. The returned pointer 3090 3076 * must be used to refer to this device when calling other functions. ··· 3125 3055 * 3126 3056 * Return: A pointer to the new hardware device, or %NULL on error. 3127 3057 */ 3058 + static inline 3128 3059 struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 3129 - const struct ieee80211_ops *ops); 3060 + const struct ieee80211_ops *ops) 3061 + { 3062 + return ieee80211_alloc_hw_nm(priv_data_len, ops, NULL); 3063 + } 3130 3064 3131 3065 /** 3132 3066 * ieee80211_register_hw - Register hardware device ··· 4246 4172 void *data); 4247 4173 4248 4174 /** 4175 + * ieee80211_iterate_stations_atomic - iterate stations 4176 + * 4177 + * This function iterates over all stations associated with a given 4178 + * hardware that are currently uploaded to the driver and calls the callback 4179 + * function for them. 4180 + * This function requires the iterator callback function to be atomic, 4181 + * 4182 + * @hw: the hardware struct of which the interfaces should be iterated over 4183 + * @iterator: the iterator function to call, cannot sleep 4184 + * @data: first argument of the iterator function 4185 + */ 4186 + void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, 4187 + void (*iterator)(void *data, 4188 + struct ieee80211_sta *sta), 4189 + void *data); 4190 + /** 4249 4191 * ieee80211_queue_work - add work onto the mac80211 workqueue 4250 4192 * 4251 4193 * Drivers and mac80211 use this to add work onto the mac80211 workqueue. ··· 4978 4888 void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer, 4979 4889 enum nl80211_tdls_operation oper, 4980 4890 u16 reason_code, gfp_t gfp); 4891 + 4892 + /** 4893 + * ieee80211_ie_split - split an IE buffer according to ordering 4894 + * 4895 + * @ies: the IE buffer 4896 + * @ielen: the length of the IE buffer 4897 + * @ids: an array with element IDs that are allowed before 4898 + * the split 4899 + * @n_ids: the size of the element ID array 4900 + * @offset: offset where to start splitting in the buffer 4901 + * 4902 + * This function splits an IE buffer by updating the @offset 4903 + * variable to point to the location where the buffer should be 4904 + * split. 4905 + * 4906 + * It assumes that the given IE buffer is well-formed, this 4907 + * has to be guaranteed by the caller! 4908 + * 4909 + * It also assumes that the IEs in the buffer are ordered 4910 + * correctly, if not the result of using this function will not 4911 + * be ordered correctly either, i.e. it does no reordering. 4912 + * 4913 + * The function returns the offset where the next part of the 4914 + * buffer starts, which may be @ielen if the entire (remainder) 4915 + * of the buffer should be used. 4916 + */ 4917 + size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 4918 + const u8 *ids, int n_ids, size_t offset); 4981 4919 #endif /* MAC80211_H */
+31 -1
include/uapi/linux/nl80211.h
··· 227 227 * the interface identified by %NL80211_ATTR_IFINDEX. 228 228 * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC 229 229 * or, if no MAC address given, all stations, on the interface identified 230 - * by %NL80211_ATTR_IFINDEX. 230 + * by %NL80211_ATTR_IFINDEX. %NL80211_ATTR_MGMT_SUBTYPE and 231 + * %NL80211_ATTR_REASON_CODE can optionally be used to specify which type 232 + * of disconnection indication should be sent to the station 233 + * (Deauthentication or Disassociation frame and reason code for that 234 + * frame). 231 235 * 232 236 * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to 233 237 * destination %NL80211_ATTR_MAC on the interface identified by ··· 742 738 * before removing a station entry entirely, or before disassociating 743 739 * or similar, cleanup will happen in the driver/device in this case. 744 740 * 741 + * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to 742 + * destination %NL80211_ATTR_MAC on the interface identified by 743 + * %NL80211_ATTR_IFINDEX. 744 + * 745 + * @NL80211_CMD_JOIN_OCB: Join the OCB network. The center frequency and 746 + * bandwidth of a channel must be given. 747 + * @NL80211_CMD_LEAVE_OCB: Leave the OCB network -- no special arguments, the 748 + * network is determined by the network interface. 749 + * 745 750 * @NL80211_CMD_MAX: highest used command number 746 751 * @__NL80211_CMD_AFTER_LAST: internal use 747 752 */ ··· 924 911 925 912 NL80211_CMD_ADD_TX_TS, 926 913 NL80211_CMD_DEL_TX_TS, 914 + 915 + NL80211_CMD_GET_MPP, 916 + 917 + NL80211_CMD_JOIN_OCB, 918 + NL80211_CMD_LEAVE_OCB, 927 919 928 920 /* add new commands above here */ 929 921 ··· 2082 2064 * and therefore can't be created in the normal ways, use the 2083 2065 * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE 2084 2066 * commands to create and destroy one 2067 + * @NL80211_IF_TYPE_OCB: Outside Context of a BSS 2068 + * This mode corresponds to the MIB variable dot11OCBActivated=true 2085 2069 * @NL80211_IFTYPE_MAX: highest interface type number currently defined 2086 2070 * @NUM_NL80211_IFTYPES: number of defined interface types 2087 2071 * ··· 2103 2083 NL80211_IFTYPE_P2P_CLIENT, 2104 2084 NL80211_IFTYPE_P2P_GO, 2105 2085 NL80211_IFTYPE_P2P_DEVICE, 2086 + NL80211_IFTYPE_OCB, 2106 2087 2107 2088 /* keep last */ 2108 2089 NUM_NL80211_IFTYPES, ··· 4063 4042 * multiplexing powersave, ie. can turn off all but one chain 4064 4043 * and then wake the rest up as required after, for example, 4065 4044 * rts/cts handshake. 4045 + * @NL80211_FEATURE_SUPPORTS_WMM_ADMISSION: the device supports setting up WMM 4046 + * TSPEC sessions (TID aka TSID 0-7) with the %NL80211_CMD_ADD_TX_TS 4047 + * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it 4048 + * needs to be able to handle Block-Ack agreements and other things. 4049 + * @NL80211_FEATURE_MAC_ON_CREATE: Device supports configuring 4050 + * the vif's MAC address upon creation. 4051 + * See 'macaddr' field in the vif_params (cfg80211.h). 4066 4052 */ 4067 4053 enum nl80211_feature_flags { 4068 4054 NL80211_FEATURE_SK_TX_STATUS = 1 << 0, ··· 4098 4070 NL80211_FEATURE_ACKTO_ESTIMATION = 1 << 23, 4099 4071 NL80211_FEATURE_STATIC_SMPS = 1 << 24, 4100 4072 NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25, 4073 + NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 1 << 26, 4074 + NL80211_FEATURE_MAC_ON_CREATE = 1 << 27, 4101 4075 }; 4102 4076 4103 4077 /**
+18
net/mac80211/Kconfig
··· 33 33 ---help--- 34 34 This option enables the 'minstrel_ht' TX rate control algorithm 35 35 36 + config MAC80211_RC_MINSTREL_VHT 37 + bool "Minstrel 802.11ac support" if EXPERT 38 + depends on MAC80211_RC_MINSTREL_HT 39 + default n 40 + ---help--- 41 + This option enables VHT in the 'minstrel_ht' TX rate control algorithm 42 + 36 43 choice 37 44 prompt "Default rate control algorithm" 38 45 depends on MAC80211_HAS_RC ··· 173 166 174 167 It should not be selected on production systems as some 175 168 of the messages are remotely triggerable. 169 + 170 + Do not select this option. 171 + 172 + config MAC80211_OCB_DEBUG 173 + bool "Verbose OCB debugging" 174 + depends on MAC80211_DEBUG_MENU 175 + ---help--- 176 + Selecting this option causes mac80211 to print out 177 + very verbose OCB debugging messages. It should not 178 + be selected on production systems as those messages 179 + are remotely triggerable. 176 180 177 181 Do not select this option. 178 182
+2 -1
net/mac80211/Makefile
··· 27 27 event.o \ 28 28 chan.o \ 29 29 trace.o mlme.o \ 30 - tdls.o 30 + tdls.o \ 31 + ocb.o 31 32 32 33 mac80211-$(CONFIG_MAC80211_LEDS) += led.o 33 34 mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
-5
net/mac80211/agg-tx.c
··· 149 149 rcu_assign_pointer(sta->ampdu_mlme.tid_tx[tid], tid_tx); 150 150 } 151 151 152 - static inline int ieee80211_ac_from_tid(int tid) 153 - { 154 - return ieee802_1d_to_ac[tid & 7]; 155 - } 156 - 157 152 /* 158 153 * When multiple aggregation sessions on multiple stations 159 154 * are being created/destroyed simultaneously, we need to
+168 -12
net/mac80211/cfg.c
··· 20 20 #include "cfg.h" 21 21 #include "rate.h" 22 22 #include "mesh.h" 23 + #include "wme.h" 23 24 24 25 static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, 25 26 const char *name, ··· 191 190 * receive the key. When wpa_supplicant has roamed 192 191 * using FT, it attempts to set the key before 193 192 * association has completed, this rejects that attempt 194 - * so it will set the key again after assocation. 193 + * so it will set the key again after association. 195 194 * 196 195 * TODO: accept the key if we have a station entry and 197 196 * add it to the device after the station. ··· 230 229 case NUM_NL80211_IFTYPES: 231 230 case NL80211_IFTYPE_P2P_CLIENT: 232 231 case NL80211_IFTYPE_P2P_GO: 232 + case NL80211_IFTYPE_OCB: 233 233 /* shouldn't happen */ 234 234 WARN_ON_ONCE(1); 235 235 break; ··· 1227 1225 } 1228 1226 1229 1227 static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, 1230 - const u8 *mac) 1228 + struct station_del_parameters *params) 1231 1229 { 1232 1230 struct ieee80211_sub_if_data *sdata; 1233 1231 1234 1232 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1235 1233 1236 - if (mac) 1237 - return sta_info_destroy_addr_bss(sdata, mac); 1234 + if (params->mac) 1235 + return sta_info_destroy_addr_bss(sdata, params->mac); 1238 1236 1239 1237 sta_info_flush(sdata); 1240 1238 return 0; ··· 1514 1512 } 1515 1513 memcpy(dst, mpath->dst, ETH_ALEN); 1516 1514 mpath_set_pinfo(mpath, next_hop, pinfo); 1515 + rcu_read_unlock(); 1516 + return 0; 1517 + } 1518 + 1519 + static void mpp_set_pinfo(struct mesh_path *mpath, u8 *mpp, 1520 + struct mpath_info *pinfo) 1521 + { 1522 + memset(pinfo, 0, sizeof(*pinfo)); 1523 + memcpy(mpp, mpath->mpp, ETH_ALEN); 1524 + 1525 + pinfo->generation = mpp_paths_generation; 1526 + } 1527 + 1528 + static int ieee80211_get_mpp(struct wiphy *wiphy, struct net_device *dev, 1529 + u8 *dst, u8 *mpp, struct mpath_info *pinfo) 1530 + 1531 + { 1532 + struct ieee80211_sub_if_data *sdata; 1533 + struct mesh_path *mpath; 1534 + 1535 + sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1536 + 1537 + rcu_read_lock(); 1538 + mpath = mpp_path_lookup(sdata, dst); 1539 + if (!mpath) { 1540 + rcu_read_unlock(); 1541 + return -ENOENT; 1542 + } 1543 + memcpy(dst, mpath->dst, ETH_ALEN); 1544 + mpp_set_pinfo(mpath, mpp, pinfo); 1545 + rcu_read_unlock(); 1546 + return 0; 1547 + } 1548 + 1549 + static int ieee80211_dump_mpp(struct wiphy *wiphy, struct net_device *dev, 1550 + int idx, u8 *dst, u8 *mpp, 1551 + struct mpath_info *pinfo) 1552 + { 1553 + struct ieee80211_sub_if_data *sdata; 1554 + struct mesh_path *mpath; 1555 + 1556 + sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1557 + 1558 + rcu_read_lock(); 1559 + mpath = mpp_path_lookup_by_idx(sdata, idx); 1560 + if (!mpath) { 1561 + rcu_read_unlock(); 1562 + return -ENOENT; 1563 + } 1564 + memcpy(dst, mpath->dst, ETH_ALEN); 1565 + mpp_set_pinfo(mpath, mpp, pinfo); 1517 1566 rcu_read_unlock(); 1518 1567 return 0; 1519 1568 } ··· 2019 1966 return ieee80211_ibss_leave(IEEE80211_DEV_TO_SUB_IF(dev)); 2020 1967 } 2021 1968 1969 + static int ieee80211_join_ocb(struct wiphy *wiphy, struct net_device *dev, 1970 + struct ocb_setup *setup) 1971 + { 1972 + return ieee80211_ocb_join(IEEE80211_DEV_TO_SUB_IF(dev), setup); 1973 + } 1974 + 1975 + static int ieee80211_leave_ocb(struct wiphy *wiphy, struct net_device *dev) 1976 + { 1977 + return ieee80211_ocb_leave(IEEE80211_DEV_TO_SUB_IF(dev)); 1978 + } 1979 + 2022 1980 static int ieee80211_set_mcast_rate(struct wiphy *wiphy, struct net_device *dev, 2023 1981 int rate[IEEE80211_NUM_BANDS]) 2024 1982 { ··· 2144 2080 { 2145 2081 struct ieee80211_local *local = wiphy_priv(wiphy); 2146 2082 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 2083 + 2084 + if (local->ops->get_txpower) 2085 + return drv_get_txpower(local, sdata, dbm); 2147 2086 2148 2087 if (!local->use_chanctx) 2149 2088 *dbm = local->hw.conf.power_level; ··· 2917 2850 if (sdata->reserved_ready) 2918 2851 return 0; 2919 2852 2920 - err = ieee80211_vif_use_reserved_context(sdata); 2921 - if (err) 2922 - return err; 2923 - 2924 - return 0; 2853 + return ieee80211_vif_use_reserved_context(sdata); 2925 2854 } 2926 2855 2927 2856 if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef, ··· 2931 2868 return err; 2932 2869 2933 2870 ieee80211_bss_info_change_notify(sdata, changed); 2934 - cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); 2935 2871 2936 2872 if (sdata->csa_block_tx) { 2937 2873 ieee80211_wake_vif_queues(local, sdata, 2938 2874 IEEE80211_QUEUE_STOP_REASON_CSA); 2939 2875 sdata->csa_block_tx = false; 2940 2876 } 2877 + 2878 + err = drv_post_channel_switch(sdata); 2879 + if (err) 2880 + return err; 2881 + 2882 + cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); 2941 2883 2942 2884 return 0; 2943 2885 } ··· 3121 3053 { 3122 3054 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3123 3055 struct ieee80211_local *local = sdata->local; 3056 + struct ieee80211_channel_switch ch_switch; 3124 3057 struct ieee80211_chanctx_conf *conf; 3125 3058 struct ieee80211_chanctx *chanctx; 3126 - int err, changed = 0; 3059 + u32 changed = 0; 3060 + int err; 3127 3061 3128 3062 sdata_assert_lock(sdata); 3129 3063 lockdep_assert_held(&local->mtx); ··· 3158 3088 goto out; 3159 3089 } 3160 3090 3091 + err = drv_pre_channel_switch(sdata, &ch_switch); 3092 + if (err) 3093 + goto out; 3094 + 3161 3095 err = ieee80211_vif_reserve_chanctx(sdata, &params->chandef, 3162 3096 chanctx->mode, 3163 3097 params->radar_required); ··· 3174 3100 ieee80211_vif_unreserve_chanctx(sdata); 3175 3101 goto out; 3176 3102 } 3103 + 3104 + ch_switch.timestamp = 0; 3105 + ch_switch.device_timestamp = 0; 3106 + ch_switch.block_tx = params->block_tx; 3107 + ch_switch.chandef = params->chandef; 3108 + ch_switch.count = params->count; 3177 3109 3178 3110 err = ieee80211_set_csa_beacon(sdata, params, &changed); 3179 3111 if (err) { ··· 3538 3458 rcu_read_lock(); 3539 3459 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 3540 3460 if (chanctx_conf) { 3541 - *chandef = chanctx_conf->def; 3461 + *chandef = sdata->vif.bss_conf.chandef; 3542 3462 ret = 0; 3543 3463 } else if (local->open_count > 0 && 3544 3464 local->open_count == local->monitors && ··· 3601 3521 return ret; 3602 3522 } 3603 3523 3524 + static int ieee80211_add_tx_ts(struct wiphy *wiphy, struct net_device *dev, 3525 + u8 tsid, const u8 *peer, u8 up, 3526 + u16 admitted_time) 3527 + { 3528 + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3529 + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3530 + int ac = ieee802_1d_to_ac[up]; 3531 + 3532 + if (sdata->vif.type != NL80211_IFTYPE_STATION) 3533 + return -EOPNOTSUPP; 3534 + 3535 + if (!(sdata->wmm_acm & BIT(up))) 3536 + return -EINVAL; 3537 + 3538 + if (ifmgd->tx_tspec[ac].admitted_time) 3539 + return -EBUSY; 3540 + 3541 + if (admitted_time) { 3542 + ifmgd->tx_tspec[ac].admitted_time = 32 * admitted_time; 3543 + ifmgd->tx_tspec[ac].tsid = tsid; 3544 + ifmgd->tx_tspec[ac].up = up; 3545 + } 3546 + 3547 + return 0; 3548 + } 3549 + 3550 + static int ieee80211_del_tx_ts(struct wiphy *wiphy, struct net_device *dev, 3551 + u8 tsid, const u8 *peer) 3552 + { 3553 + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3554 + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3555 + struct ieee80211_local *local = wiphy_priv(wiphy); 3556 + int ac; 3557 + 3558 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 3559 + struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; 3560 + 3561 + /* skip unused entries */ 3562 + if (!tx_tspec->admitted_time) 3563 + continue; 3564 + 3565 + if (tx_tspec->tsid != tsid) 3566 + continue; 3567 + 3568 + /* due to this new packets will be reassigned to non-ACM ACs */ 3569 + tx_tspec->up = -1; 3570 + 3571 + /* Make sure that all packets have been sent to avoid to 3572 + * restore the QoS params on packets that are still on the 3573 + * queues. 3574 + */ 3575 + synchronize_net(); 3576 + ieee80211_flush_queues(local, sdata); 3577 + 3578 + /* restore the normal QoS parameters 3579 + * (unconditionally to avoid races) 3580 + */ 3581 + tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE; 3582 + tx_tspec->downgraded = false; 3583 + ieee80211_sta_handle_tspec_ac_params(sdata); 3584 + 3585 + /* finally clear all the data */ 3586 + memset(tx_tspec, 0, sizeof(*tx_tspec)); 3587 + 3588 + return 0; 3589 + } 3590 + 3591 + return -ENOENT; 3592 + } 3593 + 3604 3594 const struct cfg80211_ops mac80211_config_ops = { 3605 3595 .add_virtual_intf = ieee80211_add_iface, 3606 3596 .del_virtual_intf = ieee80211_del_iface, ··· 3697 3547 .change_mpath = ieee80211_change_mpath, 3698 3548 .get_mpath = ieee80211_get_mpath, 3699 3549 .dump_mpath = ieee80211_dump_mpath, 3550 + .get_mpp = ieee80211_get_mpp, 3551 + .dump_mpp = ieee80211_dump_mpp, 3700 3552 .update_mesh_config = ieee80211_update_mesh_config, 3701 3553 .get_mesh_config = ieee80211_get_mesh_config, 3702 3554 .join_mesh = ieee80211_join_mesh, 3703 3555 .leave_mesh = ieee80211_leave_mesh, 3704 3556 #endif 3557 + .join_ocb = ieee80211_join_ocb, 3558 + .leave_ocb = ieee80211_leave_ocb, 3705 3559 .change_bss = ieee80211_change_bss, 3706 3560 .set_txq_params = ieee80211_set_txq_params, 3707 3561 .set_monitor_channel = ieee80211_set_monitor_channel, ··· 3751 3597 .channel_switch = ieee80211_channel_switch, 3752 3598 .set_qos_map = ieee80211_set_qos_map, 3753 3599 .set_ap_chanwidth = ieee80211_set_ap_chanwidth, 3600 + .add_tx_ts = ieee80211_add_tx_ts, 3601 + .del_tx_ts = ieee80211_del_tx_ts, 3754 3602 };
+4 -1
net/mac80211/chan.c
··· 270 270 case NL80211_IFTYPE_ADHOC: 271 271 case NL80211_IFTYPE_WDS: 272 272 case NL80211_IFTYPE_MESH_POINT: 273 + case NL80211_IFTYPE_OCB: 273 274 width = vif->bss_conf.chandef.width; 274 275 break; 275 276 case NL80211_IFTYPE_UNSPECIFIED: ··· 675 674 case NL80211_IFTYPE_ADHOC: 676 675 case NL80211_IFTYPE_WDS: 677 676 case NL80211_IFTYPE_MESH_POINT: 677 + case NL80211_IFTYPE_OCB: 678 678 break; 679 679 default: 680 680 WARN_ON_ONCE(1); ··· 911 909 case NL80211_IFTYPE_ADHOC: 912 910 case NL80211_IFTYPE_AP: 913 911 case NL80211_IFTYPE_MESH_POINT: 912 + case NL80211_IFTYPE_OCB: 914 913 ieee80211_queue_work(&sdata->local->hw, 915 914 &sdata->csa_finalize_work); 916 915 break; ··· 1637 1634 } 1638 1635 break; 1639 1636 case IEEE80211_CHANCTX_WILL_BE_REPLACED: 1640 - /* TODO: Perhaps the bandwith change could be treated as a 1637 + /* TODO: Perhaps the bandwidth change could be treated as a 1641 1638 * reservation itself? */ 1642 1639 ret = -EBUSY; 1643 1640 goto out;
+10
net/mac80211/debug.h
··· 2 2 #define __MAC80211_DEBUG_H 3 3 #include <net/cfg80211.h> 4 4 5 + #ifdef CONFIG_MAC80211_OCB_DEBUG 6 + #define MAC80211_OCB_DEBUG 1 7 + #else 8 + #define MAC80211_OCB_DEBUG 0 9 + #endif 10 + 5 11 #ifdef CONFIG_MAC80211_IBSS_DEBUG 6 12 #define MAC80211_IBSS_DEBUG 1 7 13 #else ··· 135 129 136 130 #define ht_dbg_ratelimited(sdata, fmt, ...) \ 137 131 _sdata_dbg(MAC80211_HT_DEBUG && net_ratelimit(), \ 132 + sdata, fmt, ##__VA_ARGS__) 133 + 134 + #define ocb_dbg(sdata, fmt, ...) \ 135 + _sdata_dbg(MAC80211_OCB_DEBUG, \ 138 136 sdata, fmt, ##__VA_ARGS__) 139 137 140 138 #define ibss_dbg(sdata, fmt, ...) \
+4 -8
net/mac80211/debugfs_key.c
··· 300 300 301 301 lockdep_assert_held(&sdata->local->key_mtx); 302 302 303 - if (sdata->debugfs.default_unicast_key) { 304 - debugfs_remove(sdata->debugfs.default_unicast_key); 305 - sdata->debugfs.default_unicast_key = NULL; 306 - } 303 + debugfs_remove(sdata->debugfs.default_unicast_key); 304 + sdata->debugfs.default_unicast_key = NULL; 307 305 308 306 if (sdata->default_unicast_key) { 309 307 key = key_mtx_dereference(sdata->local, ··· 312 314 sdata->vif.debugfs_dir, buf); 313 315 } 314 316 315 - if (sdata->debugfs.default_multicast_key) { 316 - debugfs_remove(sdata->debugfs.default_multicast_key); 317 - sdata->debugfs.default_multicast_key = NULL; 318 - } 317 + debugfs_remove(sdata->debugfs.default_multicast_key); 318 + sdata->debugfs.default_multicast_key = NULL; 319 319 320 320 if (sdata->default_multicast_key) { 321 321 key = key_mtx_dereference(sdata->local,
+66 -8
net/mac80211/driver-ops.h
··· 214 214 BSS_CHANGED_BEACON_ENABLED) && 215 215 sdata->vif.type != NL80211_IFTYPE_AP && 216 216 sdata->vif.type != NL80211_IFTYPE_ADHOC && 217 - sdata->vif.type != NL80211_IFTYPE_MESH_POINT)) 217 + sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 218 + sdata->vif.type != NL80211_IFTYPE_OCB)) 218 219 return; 219 220 220 221 if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || ··· 632 631 if (!check_sdata_in_driver(sdata)) 633 632 return -EIO; 634 633 634 + if (WARN_ONCE(params->cw_min == 0 || 635 + params->cw_min > params->cw_max, 636 + "%s: invalid CW_min/CW_max: %d/%d\n", 637 + sdata->name, params->cw_min, params->cw_max)) 638 + return -EINVAL; 639 + 635 640 trace_drv_conf_tx(local, sdata, ac, params); 636 641 if (local->ops->conf_tx) 637 642 ret = local->ops->conf_tx(&local->hw, &sdata->vif, ··· 771 764 } 772 765 773 766 static inline void drv_channel_switch(struct ieee80211_local *local, 774 - struct ieee80211_channel_switch *ch_switch) 767 + struct ieee80211_sub_if_data *sdata, 768 + struct ieee80211_channel_switch *ch_switch) 775 769 { 776 770 might_sleep(); 777 771 778 - trace_drv_channel_switch(local, ch_switch); 779 - local->ops->channel_switch(&local->hw, ch_switch); 772 + trace_drv_channel_switch(local, sdata, ch_switch); 773 + local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch); 780 774 trace_drv_return_void(local); 781 775 } 782 776 ··· 1152 1144 trace_drv_return_void(local); 1153 1145 } 1154 1146 1155 - static inline void drv_restart_complete(struct ieee80211_local *local) 1147 + static inline void 1148 + drv_reconfig_complete(struct ieee80211_local *local, 1149 + enum ieee80211_reconfig_type reconfig_type) 1156 1150 { 1157 1151 might_sleep(); 1158 1152 1159 - trace_drv_restart_complete(local); 1160 - if (local->ops->restart_complete) 1161 - local->ops->restart_complete(&local->hw); 1153 + trace_drv_reconfig_complete(local, reconfig_type); 1154 + if (local->ops->reconfig_complete) 1155 + local->ops->reconfig_complete(&local->hw, reconfig_type); 1162 1156 trace_drv_return_void(local); 1163 1157 } 1164 1158 ··· 1206 1196 } 1207 1197 } 1208 1198 1199 + static inline int 1200 + drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata, 1201 + struct ieee80211_channel_switch *ch_switch) 1202 + { 1203 + struct ieee80211_local *local = sdata->local; 1204 + int ret = 0; 1205 + 1206 + if (!check_sdata_in_driver(sdata)) 1207 + return -EIO; 1208 + 1209 + trace_drv_pre_channel_switch(local, sdata, ch_switch); 1210 + if (local->ops->pre_channel_switch) 1211 + ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif, 1212 + ch_switch); 1213 + trace_drv_return_int(local, ret); 1214 + return ret; 1215 + } 1216 + 1217 + static inline int 1218 + drv_post_channel_switch(struct ieee80211_sub_if_data *sdata) 1219 + { 1220 + struct ieee80211_local *local = sdata->local; 1221 + int ret = 0; 1222 + 1223 + if (!check_sdata_in_driver(sdata)) 1224 + return -EIO; 1225 + 1226 + trace_drv_post_channel_switch(local, sdata); 1227 + if (local->ops->post_channel_switch) 1228 + ret = local->ops->post_channel_switch(&local->hw, &sdata->vif); 1229 + trace_drv_return_int(local, ret); 1230 + return ret; 1231 + } 1232 + 1209 1233 static inline int drv_join_ibss(struct ieee80211_local *local, 1210 1234 struct ieee80211_sub_if_data *sdata) 1211 1235 { ··· 1278 1234 if (local->ops->get_expected_throughput) 1279 1235 ret = local->ops->get_expected_throughput(sta); 1280 1236 trace_drv_return_u32(local, ret); 1237 + 1238 + return ret; 1239 + } 1240 + 1241 + static inline int drv_get_txpower(struct ieee80211_local *local, 1242 + struct ieee80211_sub_if_data *sdata, int *dbm) 1243 + { 1244 + int ret; 1245 + 1246 + if (!local->ops->get_txpower) 1247 + return -EOPNOTSUPP; 1248 + 1249 + ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm); 1250 + trace_drv_get_txpower(local, sdata, *dbm, ret); 1281 1251 1282 1252 return ret; 1283 1253 }
+76 -4
net/mac80211/ieee80211_i.h
··· 131 131 * 132 132 * These are bss flags that are attached to a bss in the 133 133 * @valid_data field of &struct ieee80211_bss. They show which parts 134 - * of the data structure were recieved as a result of an un-corrupted 134 + * of the data structure were received as a result of an un-corrupted 135 135 * beacon/probe response. 136 136 */ 137 137 enum ieee80211_bss_valid_data_flags { ··· 399 399 u8 ie[]; 400 400 }; 401 401 402 + struct ieee80211_sta_tx_tspec { 403 + /* timestamp of the first packet in the time slice */ 404 + unsigned long time_slice_start; 405 + 406 + u32 admitted_time; /* in usecs, unlike over the air */ 407 + u8 tsid; 408 + s8 up; /* signed to be able to invalidate with -1 during teardown */ 409 + 410 + /* consumed TX time in microseconds in the time slice */ 411 + u32 consumed_tx_time; 412 + enum { 413 + TX_TSPEC_ACTION_NONE = 0, 414 + TX_TSPEC_ACTION_DOWNGRADE, 415 + TX_TSPEC_ACTION_STOP_DOWNGRADE, 416 + } action; 417 + bool downgraded; 418 + }; 419 + 402 420 struct ieee80211_if_managed { 403 421 struct timer_list timer; 404 422 struct timer_list conn_mon_timer; ··· 451 433 struct work_struct request_smps_work; 452 434 453 435 unsigned int flags; 436 + 437 + bool csa_waiting_bcn; 454 438 455 439 bool beacon_crc_valid; 456 440 u32 beacon_crc; ··· 527 507 528 508 u8 tdls_peer[ETH_ALEN] __aligned(2); 529 509 struct delayed_work tdls_peer_del_work; 510 + 511 + /* WMM-AC TSPEC support */ 512 + struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS]; 513 + /* Use a separate work struct so that we can do something here 514 + * while the sdata->work is flushing the queues, for example. 515 + * otherwise, in scenarios where we hardly get any traffic out 516 + * on the BE queue, but there's a lot of VO traffic, we might 517 + * get stuck in a downgraded situation and flush takes forever. 518 + */ 519 + struct delayed_work tx_tspec_wk; 530 520 }; 531 521 532 522 struct ieee80211_if_ibss { ··· 574 544 IEEE80211_IBSS_MLME_SEARCH, 575 545 IEEE80211_IBSS_MLME_JOINED, 576 546 } state; 547 + }; 548 + 549 + /** 550 + * struct ieee80211_if_ocb - OCB mode state 551 + * 552 + * @housekeeping_timer: timer for periodic invocation of a housekeeping task 553 + * @wrkq_flags: OCB deferred task action 554 + * @incomplete_lock: delayed STA insertion lock 555 + * @incomplete_stations: list of STAs waiting for delayed insertion 556 + * @joined: indication if the interface is connected to an OCB network 557 + */ 558 + struct ieee80211_if_ocb { 559 + struct timer_list housekeeping_timer; 560 + unsigned long wrkq_flags; 561 + 562 + spinlock_t incomplete_lock; 563 + struct list_head incomplete_stations; 564 + 565 + bool joined; 577 566 }; 578 567 579 568 /** ··· 888 839 struct ieee80211_if_managed mgd; 889 840 struct ieee80211_if_ibss ibss; 890 841 struct ieee80211_if_mesh mesh; 842 + struct ieee80211_if_ocb ocb; 891 843 u32 mntr_flags; 892 844 } u; 893 845 ··· 1357 1307 /* virtual monitor interface */ 1358 1308 struct ieee80211_sub_if_data __rcu *monitor_sdata; 1359 1309 struct cfg80211_chan_def monitor_chandef; 1310 + 1311 + /* extended capabilities provided by mac80211 */ 1312 + u8 ext_capa[8]; 1360 1313 }; 1361 1314 1362 1315 static inline struct ieee80211_sub_if_data * ··· 1507 1454 __le16 fc, bool acked); 1508 1455 void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata); 1509 1456 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); 1457 + void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata); 1510 1458 1511 1459 /* IBSS code */ 1512 1460 void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); ··· 1524 1470 struct cfg80211_csa_settings *csa_settings); 1525 1471 int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata); 1526 1472 void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata); 1473 + 1474 + /* OCB code */ 1475 + void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata); 1476 + void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata, 1477 + const u8 *bssid, const u8 *addr, u32 supp_rates); 1478 + void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata); 1479 + int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata, 1480 + struct ocb_setup *setup); 1481 + int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata); 1527 1482 1528 1483 /* mesh code */ 1529 1484 void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata); ··· 1821 1758 return true; 1822 1759 } 1823 1760 1761 + extern const int ieee802_1d_to_ac[8]; 1762 + 1763 + static inline int ieee80211_ac_from_tid(int tid) 1764 + { 1765 + return ieee802_1d_to_ac[tid & 7]; 1766 + } 1767 + 1824 1768 void ieee80211_dynamic_ps_enable_work(struct work_struct *work); 1825 1769 void ieee80211_dynamic_ps_disable_work(struct work_struct *work); 1826 1770 void ieee80211_dynamic_ps_timer(unsigned long data); ··· 1837 1767 void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1838 1768 struct ieee80211_hdr *hdr); 1839 1769 void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, 1840 - struct ieee80211_hdr *hdr, bool ack); 1770 + struct ieee80211_hdr *hdr, bool ack, u16 tx_time); 1841 1771 1842 1772 void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1843 1773 unsigned long queues, ··· 1903 1833 void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); 1904 1834 void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata); 1905 1835 1906 - size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 1907 - const u8 *ids, int n_ids, size_t offset); 1836 + size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, 1837 + const u8 *ids, int n_ids, 1838 + const u8 *after_ric, int n_after_ric, 1839 + size_t offset); 1908 1840 size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); 1909 1841 u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, 1910 1842 u16 cap);
+29 -1
net/mac80211/iface.c
··· 259 259 list_for_each_entry(nsdata, &local->interfaces, list) { 260 260 if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { 261 261 /* 262 + * Only OCB and monitor mode may coexist 263 + */ 264 + if ((sdata->vif.type == NL80211_IFTYPE_OCB && 265 + nsdata->vif.type != NL80211_IFTYPE_MONITOR) || 266 + (sdata->vif.type != NL80211_IFTYPE_MONITOR && 267 + nsdata->vif.type == NL80211_IFTYPE_OCB)) 268 + return -EBUSY; 269 + 270 + /* 262 271 * Allow only a single IBSS interface to be up at any 263 272 * time. This is restricted because beacon distribution 264 273 * cannot work properly if both are in the same IBSS. ··· 530 521 case NL80211_IFTYPE_MONITOR: 531 522 case NL80211_IFTYPE_ADHOC: 532 523 case NL80211_IFTYPE_P2P_DEVICE: 524 + case NL80211_IFTYPE_OCB: 533 525 /* no special treatment */ 534 526 break; 535 527 case NL80211_IFTYPE_UNSPECIFIED: ··· 641 631 case NL80211_IFTYPE_ADHOC: 642 632 case NL80211_IFTYPE_AP: 643 633 case NL80211_IFTYPE_MESH_POINT: 634 + case NL80211_IFTYPE_OCB: 644 635 netif_carrier_off(dev); 645 636 break; 646 637 case NL80211_IFTYPE_WDS: ··· 853 842 sdata_lock(sdata); 854 843 mutex_lock(&local->mtx); 855 844 sdata->vif.csa_active = false; 845 + if (sdata->vif.type == NL80211_IFTYPE_STATION) 846 + sdata->u.mgd.csa_waiting_bcn = false; 856 847 if (sdata->csa_block_tx) { 857 848 ieee80211_wake_vif_queues(local, sdata, 858 849 IEEE80211_QUEUE_STOP_REASON_CSA); ··· 1292 1279 break; 1293 1280 ieee80211_mesh_work(sdata); 1294 1281 break; 1282 + case NL80211_IFTYPE_OCB: 1283 + ieee80211_ocb_work(sdata); 1284 + break; 1295 1285 default: 1296 1286 break; 1297 1287 } ··· 1314 1298 static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, 1315 1299 enum nl80211_iftype type) 1316 1300 { 1301 + static const u8 bssid_wildcard[ETH_ALEN] = {0xff, 0xff, 0xff, 1302 + 0xff, 0xff, 0xff}; 1303 + 1317 1304 /* clear type-dependent union */ 1318 1305 memset(&sdata->u, 0, sizeof(sdata->u)); 1319 1306 ··· 1368 1349 sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; 1369 1350 ieee80211_sta_setup_sdata(sdata); 1370 1351 break; 1352 + case NL80211_IFTYPE_OCB: 1353 + sdata->vif.bss_conf.bssid = bssid_wildcard; 1354 + ieee80211_ocb_setup_sdata(sdata); 1355 + break; 1371 1356 case NL80211_IFTYPE_ADHOC: 1372 1357 sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; 1373 1358 ieee80211_ibss_setup_sdata(sdata); ··· 1419 1396 case NL80211_IFTYPE_AP: 1420 1397 case NL80211_IFTYPE_STATION: 1421 1398 case NL80211_IFTYPE_ADHOC: 1399 + case NL80211_IFTYPE_OCB: 1422 1400 /* 1423 1401 * Could maybe also all others here? 1424 1402 * Just not sure how that interacts ··· 1435 1411 case NL80211_IFTYPE_AP: 1436 1412 case NL80211_IFTYPE_STATION: 1437 1413 case NL80211_IFTYPE_ADHOC: 1414 + case NL80211_IFTYPE_OCB: 1438 1415 /* 1439 1416 * Could probably support everything 1440 1417 * but WDS here (WDS do_open can fail ··· 1694 1669 } 1695 1670 1696 1671 ieee80211_assign_perm_addr(local, ndev->perm_addr, type); 1697 - memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); 1672 + if (params && is_valid_ether_addr(params->macaddr)) 1673 + memcpy(ndev->dev_addr, params->macaddr, ETH_ALEN); 1674 + else 1675 + memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); 1698 1676 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); 1699 1677 1700 1678 /* don't use IEEE80211_DEV_TO_SUB_IF -- it checks too much */
+10 -1
net/mac80211/key.c
··· 94 94 95 95 might_sleep(); 96 96 97 - if (key->flags & KEY_FLAG_TAINTED) 97 + if (key->flags & KEY_FLAG_TAINTED) { 98 + /* If we get here, it's during resume and the key is 99 + * tainted so shouldn't be used/programmed any more. 100 + * However, its flags may still indicate that it was 101 + * programmed into the device (since we're in resume) 102 + * so clear that flag now to avoid trying to remove 103 + * it again later. 104 + */ 105 + key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; 98 106 return -EINVAL; 107 + } 99 108 100 109 if (!key->local->ops->set_key) 101 110 goto out_unsupported;
+22 -16
net/mac80211/main.c
··· 478 478 }, 479 479 }; 480 480 481 - static const u8 extended_capabilities[] = { 482 - 0, 0, 0, 0, 0, 0, 0, 483 - WLAN_EXT_CAPA8_OPMODE_NOTIF, 484 - }; 485 - 486 - struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, 487 - const struct ieee80211_ops *ops) 481 + struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, 482 + const struct ieee80211_ops *ops, 483 + const char *requested_name) 488 484 { 489 485 struct ieee80211_local *local; 490 486 int priv_size, i; ··· 520 524 */ 521 525 priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len; 522 526 523 - wiphy = wiphy_new(&mac80211_config_ops, priv_size); 527 + wiphy = wiphy_new_nm(&mac80211_config_ops, priv_size, requested_name); 524 528 525 529 if (!wiphy) 526 530 return NULL; ··· 535 539 WIPHY_FLAG_REPORTS_OBSS | 536 540 WIPHY_FLAG_OFFCHAN_TX; 537 541 538 - wiphy->extended_capabilities = extended_capabilities; 539 - wiphy->extended_capabilities_mask = extended_capabilities; 540 - wiphy->extended_capabilities_len = ARRAY_SIZE(extended_capabilities); 541 - 542 542 if (ops->remain_on_channel) 543 543 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 544 544 ··· 542 550 NL80211_FEATURE_SAE | 543 551 NL80211_FEATURE_HT_IBSS | 544 552 NL80211_FEATURE_VIF_TXPOWER | 553 + NL80211_FEATURE_MAC_ON_CREATE | 545 554 NL80211_FEATURE_USERSPACE_MPM; 546 555 547 556 if (!ops->hw_scan) ··· 583 590 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; 584 591 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; 585 592 wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask; 593 + 594 + local->ext_capa[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF; 595 + 596 + wiphy->extended_capabilities = local->ext_capa; 597 + wiphy->extended_capabilities_mask = local->ext_capa; 598 + wiphy->extended_capabilities_len = 599 + ARRAY_SIZE(local->ext_capa); 586 600 587 601 INIT_LIST_HEAD(&local->interfaces); 588 602 ··· 651 651 652 652 return &local->hw; 653 653 } 654 - EXPORT_SYMBOL(ieee80211_alloc_hw); 654 + EXPORT_SYMBOL(ieee80211_alloc_hw_nm); 655 655 656 656 static int ieee80211_init_cipher_suites(struct ieee80211_local *local) 657 657 { ··· 787 787 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_WDS)) 788 788 return -EINVAL; 789 789 790 - /* DFS currently not supported with channel context drivers */ 790 + /* DFS is not supported with multi-channel combinations yet */ 791 791 for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) { 792 792 const struct ieee80211_iface_combination *comb; 793 793 794 794 comb = &local->hw.wiphy->iface_combinations[i]; 795 795 796 - if (comb->radar_detect_widths) 796 + if (comb->radar_detect_widths && 797 + comb->num_different_channels > 1) 797 798 return -EINVAL; 798 799 } 799 800 } ··· 959 958 if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) 960 959 local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; 961 960 961 + /* mac80211 supports eCSA, if the driver supports STA CSA at all */ 962 + if (local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA) 963 + local->ext_capa[0] |= WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING; 964 + 962 965 local->hw.wiphy->max_num_csa_counters = IEEE80211_MAX_CSA_COUNTERS_NUM; 963 966 964 967 result = wiphy_register(local->hw.wiphy); ··· 1024 1019 } 1025 1020 1026 1021 /* add one default STA interface if supported */ 1027 - if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { 1022 + if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) && 1023 + !(hw->flags & IEEE80211_HW_NO_AUTO_VIF)) { 1028 1024 result = ieee80211_if_add(local, "wlan%d", NULL, 1029 1025 NL80211_IFTYPE_STATION, NULL); 1030 1026 if (result)
+3
net/mac80211/mesh.h
··· 270 270 const u8 *dst, const u8 *mpp); 271 271 struct mesh_path * 272 272 mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); 273 + struct mesh_path * 274 + mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); 273 275 void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); 274 276 void mesh_path_expire(struct ieee80211_sub_if_data *sdata); 275 277 void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, ··· 319 317 320 318 bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); 321 319 extern int mesh_paths_generation; 320 + extern int mpp_paths_generation; 322 321 323 322 #ifdef CONFIG_MAC80211_MESH 324 323 static inline
+31
net/mac80211/mesh_pathtbl.c
··· 44 44 static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */ 45 45 46 46 int mesh_paths_generation; 47 + int mpp_paths_generation; 47 48 48 49 /* This lock will have the grow table function as writer and add / delete nodes 49 50 * as readers. RCU provides sufficient protection only when reading the table ··· 411 410 } 412 411 413 412 /** 413 + * mpp_path_lookup_by_idx - look up a path in the proxy path table by its index 414 + * @idx: index 415 + * @sdata: local subif, or NULL for all entries 416 + * 417 + * Returns: pointer to the proxy path structure, or NULL if not found. 418 + * 419 + * Locking: must be called within a read rcu section. 420 + */ 421 + struct mesh_path * 422 + mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx) 423 + { 424 + struct mesh_table *tbl = rcu_dereference(mpp_paths); 425 + struct mpath_node *node; 426 + int i; 427 + int j = 0; 428 + 429 + for_each_mesh_entry(tbl, node, i) { 430 + if (sdata && node->mpath->sdata != sdata) 431 + continue; 432 + if (j++ == idx) 433 + return node->mpath; 434 + } 435 + 436 + return NULL; 437 + } 438 + 439 + /** 414 440 * mesh_path_add_gate - add the given mpath to a mesh gate to our path table 415 441 * @mpath: gate path to add to table 416 442 */ ··· 719 691 720 692 spin_unlock(&tbl->hashwlock[hash_idx]); 721 693 read_unlock_bh(&pathtbl_resize_lock); 694 + 695 + mpp_paths_generation++; 696 + 722 697 if (grow) { 723 698 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); 724 699 ieee80211_queue_work(&local->hw, &sdata->work);
+236 -47
net/mac80211/mlme.c
··· 775 775 WLAN_EID_QOS_CAPA, 776 776 WLAN_EID_RRM_ENABLED_CAPABILITIES, 777 777 WLAN_EID_MOBILITY_DOMAIN, 778 + WLAN_EID_FAST_BSS_TRANSITION, /* reassoc only */ 779 + WLAN_EID_RIC_DATA, /* reassoc only */ 778 780 WLAN_EID_SUPPORTED_REGULATORY_CLASSES, 779 781 }; 780 - noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len, 781 - before_ht, ARRAY_SIZE(before_ht), 782 - offset); 782 + static const u8 after_ric[] = { 783 + WLAN_EID_SUPPORTED_REGULATORY_CLASSES, 784 + WLAN_EID_HT_CAPABILITY, 785 + WLAN_EID_BSS_COEX_2040, 786 + WLAN_EID_EXT_CAPABILITY, 787 + WLAN_EID_QOS_TRAFFIC_CAPA, 788 + WLAN_EID_TIM_BCAST_REQ, 789 + WLAN_EID_INTERWORKING, 790 + /* 60GHz doesn't happen right now */ 791 + WLAN_EID_VHT_CAPABILITY, 792 + WLAN_EID_OPMODE_NOTIF, 793 + }; 794 + 795 + noffset = ieee80211_ie_split_ric(assoc_data->ie, 796 + assoc_data->ie_len, 797 + before_ht, 798 + ARRAY_SIZE(before_ht), 799 + after_ric, 800 + ARRAY_SIZE(after_ric), 801 + offset); 783 802 pos = skb_put(skb, noffset - offset); 784 803 memcpy(pos, assoc_data->ie + offset, noffset - offset); 785 804 offset = noffset; ··· 832 813 WLAN_EID_TIM_BCAST_REQ, 833 814 WLAN_EID_INTERWORKING, 834 815 }; 816 + 817 + /* RIC already taken above, so no need to handle here anymore */ 835 818 noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len, 836 819 before_vht, ARRAY_SIZE(before_vht), 837 820 offset); ··· 1022 1001 /* XXX: shouldn't really modify cfg80211-owned data! */ 1023 1002 ifmgd->associated->channel = sdata->csa_chandef.chan; 1024 1003 1025 - sdata->vif.csa_active = false; 1026 - 1027 - /* XXX: wait for a beacon first? */ 1028 - if (sdata->csa_block_tx) { 1029 - ieee80211_wake_vif_queues(local, sdata, 1030 - IEEE80211_QUEUE_STOP_REASON_CSA); 1031 - sdata->csa_block_tx = false; 1032 - } 1004 + ifmgd->csa_waiting_bcn = true; 1033 1005 1034 1006 ieee80211_sta_reset_beacon_monitor(sdata); 1035 1007 ieee80211_sta_reset_conn_monitor(sdata); ··· 1031 1017 mutex_unlock(&local->chanctx_mtx); 1032 1018 mutex_unlock(&local->mtx); 1033 1019 sdata_unlock(sdata); 1020 + } 1021 + 1022 + static void ieee80211_chswitch_post_beacon(struct ieee80211_sub_if_data *sdata) 1023 + { 1024 + struct ieee80211_local *local = sdata->local; 1025 + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1026 + int ret; 1027 + 1028 + sdata_assert_lock(sdata); 1029 + 1030 + WARN_ON(!sdata->vif.csa_active); 1031 + 1032 + if (sdata->csa_block_tx) { 1033 + ieee80211_wake_vif_queues(local, sdata, 1034 + IEEE80211_QUEUE_STOP_REASON_CSA); 1035 + sdata->csa_block_tx = false; 1036 + } 1037 + 1038 + sdata->vif.csa_active = false; 1039 + ifmgd->csa_waiting_bcn = false; 1040 + 1041 + ret = drv_post_channel_switch(sdata); 1042 + if (ret) { 1043 + sdata_info(sdata, 1044 + "driver post channel switch failed, disconnecting\n"); 1045 + ieee80211_queue_work(&local->hw, 1046 + &ifmgd->csa_connection_drop_work); 1047 + return; 1048 + } 1034 1049 } 1035 1050 1036 1051 void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) ··· 1089 1046 1090 1047 static void 1091 1048 ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, 1092 - u64 timestamp, struct ieee802_11_elems *elems, 1049 + u64 timestamp, u32 device_timestamp, 1050 + struct ieee802_11_elems *elems, 1093 1051 bool beacon) 1094 1052 { 1095 1053 struct ieee80211_local *local = sdata->local; ··· 1100 1056 struct ieee80211_chanctx *chanctx; 1101 1057 enum ieee80211_band current_band; 1102 1058 struct ieee80211_csa_ie csa_ie; 1059 + struct ieee80211_channel_switch ch_switch; 1103 1060 int res; 1104 1061 1105 1062 sdata_assert_lock(sdata); ··· 1155 1110 1156 1111 chanctx = container_of(conf, struct ieee80211_chanctx, conf); 1157 1112 1158 - if (local->use_chanctx) { 1159 - u32 num_chanctx = 0; 1160 - list_for_each_entry(chanctx, &local->chanctx_list, list) 1161 - num_chanctx++; 1113 + if (local->use_chanctx && 1114 + !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { 1115 + sdata_info(sdata, 1116 + "driver doesn't support chan-switch with channel contexts\n"); 1117 + ieee80211_queue_work(&local->hw, 1118 + &ifmgd->csa_connection_drop_work); 1119 + mutex_unlock(&local->chanctx_mtx); 1120 + mutex_unlock(&local->mtx); 1121 + return; 1122 + } 1162 1123 1163 - if (num_chanctx > 1 || 1164 - !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { 1165 - sdata_info(sdata, 1166 - "not handling chan-switch with channel contexts\n"); 1167 - ieee80211_queue_work(&local->hw, 1168 - &ifmgd->csa_connection_drop_work); 1169 - mutex_unlock(&local->chanctx_mtx); 1170 - mutex_unlock(&local->mtx); 1171 - return; 1172 - } 1124 + ch_switch.timestamp = timestamp; 1125 + ch_switch.device_timestamp = device_timestamp; 1126 + ch_switch.block_tx = csa_ie.mode; 1127 + ch_switch.chandef = csa_ie.chandef; 1128 + ch_switch.count = csa_ie.count; 1129 + 1130 + if (drv_pre_channel_switch(sdata, &ch_switch)) { 1131 + sdata_info(sdata, 1132 + "preparing for channel switch failed, disconnecting\n"); 1133 + ieee80211_queue_work(&local->hw, 1134 + &ifmgd->csa_connection_drop_work); 1135 + mutex_unlock(&local->chanctx_mtx); 1136 + mutex_unlock(&local->mtx); 1137 + return; 1173 1138 } 1174 1139 1175 1140 res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef, ··· 1207 1152 1208 1153 if (local->ops->channel_switch) { 1209 1154 /* use driver's channel switch callback */ 1210 - struct ieee80211_channel_switch ch_switch = { 1211 - .timestamp = timestamp, 1212 - .block_tx = csa_ie.mode, 1213 - .chandef = csa_ie.chandef, 1214 - .count = csa_ie.count, 1215 - }; 1216 - 1217 - drv_channel_switch(local, &ch_switch); 1155 + drv_channel_switch(local, sdata, &ch_switch); 1218 1156 return; 1219 1157 } 1220 1158 ··· 1627 1579 mutex_unlock(&sdata->local->mtx); 1628 1580 } 1629 1581 1582 + static bool 1583 + __ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata) 1584 + { 1585 + struct ieee80211_local *local = sdata->local; 1586 + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1587 + bool ret; 1588 + int ac; 1589 + 1590 + if (local->hw.queues < IEEE80211_NUM_ACS) 1591 + return false; 1592 + 1593 + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 1594 + struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; 1595 + int non_acm_ac; 1596 + unsigned long now = jiffies; 1597 + 1598 + if (tx_tspec->action == TX_TSPEC_ACTION_NONE && 1599 + tx_tspec->admitted_time && 1600 + time_after(now, tx_tspec->time_slice_start + HZ)) { 1601 + tx_tspec->consumed_tx_time = 0; 1602 + tx_tspec->time_slice_start = now; 1603 + 1604 + if (tx_tspec->downgraded) 1605 + tx_tspec->action = 1606 + TX_TSPEC_ACTION_STOP_DOWNGRADE; 1607 + } 1608 + 1609 + switch (tx_tspec->action) { 1610 + case TX_TSPEC_ACTION_STOP_DOWNGRADE: 1611 + /* take the original parameters */ 1612 + if (drv_conf_tx(local, sdata, ac, &sdata->tx_conf[ac])) 1613 + sdata_err(sdata, 1614 + "failed to set TX queue parameters for queue %d\n", 1615 + ac); 1616 + tx_tspec->action = TX_TSPEC_ACTION_NONE; 1617 + tx_tspec->downgraded = false; 1618 + ret = true; 1619 + break; 1620 + case TX_TSPEC_ACTION_DOWNGRADE: 1621 + if (time_after(now, tx_tspec->time_slice_start + HZ)) { 1622 + tx_tspec->action = TX_TSPEC_ACTION_NONE; 1623 + ret = true; 1624 + break; 1625 + } 1626 + /* downgrade next lower non-ACM AC */ 1627 + for (non_acm_ac = ac + 1; 1628 + non_acm_ac < IEEE80211_NUM_ACS; 1629 + non_acm_ac++) 1630 + if (!(sdata->wmm_acm & BIT(7 - 2 * non_acm_ac))) 1631 + break; 1632 + /* The loop will result in using BK even if it requires 1633 + * admission control, such configuration makes no sense 1634 + * and we have to transmit somehow - the AC selection 1635 + * does the same thing. 1636 + */ 1637 + if (drv_conf_tx(local, sdata, ac, 1638 + &sdata->tx_conf[non_acm_ac])) 1639 + sdata_err(sdata, 1640 + "failed to set TX queue parameters for queue %d\n", 1641 + ac); 1642 + tx_tspec->action = TX_TSPEC_ACTION_NONE; 1643 + ret = true; 1644 + schedule_delayed_work(&ifmgd->tx_tspec_wk, 1645 + tx_tspec->time_slice_start + HZ - now + 1); 1646 + break; 1647 + case TX_TSPEC_ACTION_NONE: 1648 + /* nothing now */ 1649 + break; 1650 + } 1651 + } 1652 + 1653 + return ret; 1654 + } 1655 + 1656 + void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata) 1657 + { 1658 + if (__ieee80211_sta_handle_tspec_ac_params(sdata)) 1659 + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); 1660 + } 1661 + 1662 + static void ieee80211_sta_handle_tspec_ac_params_wk(struct work_struct *work) 1663 + { 1664 + struct ieee80211_sub_if_data *sdata; 1665 + 1666 + sdata = container_of(work, struct ieee80211_sub_if_data, 1667 + u.mgd.tx_tspec_wk.work); 1668 + ieee80211_sta_handle_tspec_ac_params(sdata); 1669 + } 1670 + 1630 1671 /* MLME */ 1631 1672 static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, 1632 1673 struct ieee80211_sub_if_data *sdata, ··· 1800 1663 params.uapsd = uapsd; 1801 1664 1802 1665 mlme_dbg(sdata, 1803 - "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d\n", 1666 + "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d, downgraded=%d\n", 1804 1667 queue, aci, acm, 1805 1668 params.aifs, params.cw_min, params.cw_max, 1806 - params.txop, params.uapsd); 1669 + params.txop, params.uapsd, 1670 + ifmgd->tx_tspec[queue].downgraded); 1807 1671 sdata->tx_conf[queue] = params; 1808 - if (drv_conf_tx(local, sdata, queue, &params)) 1672 + if (!ifmgd->tx_tspec[queue].downgraded && 1673 + drv_conf_tx(local, sdata, queue, &params)) 1809 1674 sdata_err(sdata, 1810 1675 "failed to set TX queue parameters for queue %d\n", 1811 1676 queue); ··· 2062 1923 ieee80211_vif_release_channel(sdata); 2063 1924 2064 1925 sdata->vif.csa_active = false; 1926 + ifmgd->csa_waiting_bcn = false; 2065 1927 if (sdata->csa_block_tx) { 2066 1928 ieee80211_wake_vif_queues(local, sdata, 2067 1929 IEEE80211_QUEUE_STOP_REASON_CSA); 2068 1930 sdata->csa_block_tx = false; 2069 1931 } 2070 1932 mutex_unlock(&local->mtx); 1933 + 1934 + /* existing TX TSPEC sessions no longer exist */ 1935 + memset(ifmgd->tx_tspec, 0, sizeof(ifmgd->tx_tspec)); 1936 + cancel_delayed_work_sync(&ifmgd->tx_tspec_wk); 2071 1937 2072 1938 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 2073 1939 } ··· 2126 1982 mutex_unlock(&local->mtx); 2127 1983 } 2128 1984 2129 - void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, 2130 - struct ieee80211_hdr *hdr, bool ack) 1985 + static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata, 1986 + struct ieee80211_hdr *hdr, 1987 + u16 tx_time) 2131 1988 { 1989 + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1990 + u16 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 1991 + int ac = ieee80211_ac_from_tid(tid); 1992 + struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac]; 1993 + unsigned long now = jiffies; 1994 + 1995 + if (likely(!tx_tspec->admitted_time)) 1996 + return; 1997 + 1998 + if (time_after(now, tx_tspec->time_slice_start + HZ)) { 1999 + tx_tspec->consumed_tx_time = 0; 2000 + tx_tspec->time_slice_start = now; 2001 + 2002 + if (tx_tspec->downgraded) { 2003 + tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE; 2004 + schedule_delayed_work(&ifmgd->tx_tspec_wk, 0); 2005 + } 2006 + } 2007 + 2008 + if (tx_tspec->downgraded) 2009 + return; 2010 + 2011 + tx_tspec->consumed_tx_time += tx_time; 2012 + 2013 + if (tx_tspec->consumed_tx_time >= tx_tspec->admitted_time) { 2014 + tx_tspec->downgraded = true; 2015 + tx_tspec->action = TX_TSPEC_ACTION_DOWNGRADE; 2016 + schedule_delayed_work(&ifmgd->tx_tspec_wk, 0); 2017 + } 2018 + } 2019 + 2020 + void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata, 2021 + struct ieee80211_hdr *hdr, bool ack, u16 tx_time) 2022 + { 2023 + ieee80211_sta_tx_wmm_ac_notify(sdata, hdr, tx_time); 2024 + 2132 2025 if (!ieee80211_is_data(hdr->frame_control)) 2133 2026 return; 2134 2027 ··· 2228 2047 2229 2048 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); 2230 2049 run_again(sdata, ifmgd->probe_timeout); 2231 - if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) 2232 - ieee80211_flush_queues(sdata->local, sdata); 2233 2050 } 2234 2051 2235 2052 static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, ··· 2350 2171 true, frame_buf); 2351 2172 mutex_lock(&local->mtx); 2352 2173 sdata->vif.csa_active = false; 2174 + ifmgd->csa_waiting_bcn = false; 2353 2175 if (sdata->csa_block_tx) { 2354 2176 ieee80211_wake_vif_queues(local, sdata, 2355 2177 IEEE80211_QUEUE_STOP_REASON_CSA); ··· 3375 3195 } 3376 3196 } 3377 3197 3198 + if (ifmgd->csa_waiting_bcn) 3199 + ieee80211_chswitch_post_beacon(sdata); 3200 + 3378 3201 if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) 3379 3202 return; 3380 3203 ifmgd->beacon_crc = ncrc; ··· 3386 3203 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); 3387 3204 3388 3205 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, 3206 + rx_status->device_timestamp, 3389 3207 &elems, true); 3390 3208 3391 3209 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && ··· 3518 3334 break; 3519 3335 3520 3336 ieee80211_sta_process_chanswitch(sdata, 3521 - rx_status->mactime, 3522 - &elems, false); 3337 + rx_status->mactime, 3338 + rx_status->device_timestamp, 3339 + &elems, false); 3523 3340 } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { 3524 3341 ies_len = skb->len - 3525 3342 offsetof(struct ieee80211_mgmt, ··· 3541 3356 &mgmt->u.action.u.ext_chan_switch.data; 3542 3357 3543 3358 ieee80211_sta_process_chanswitch(sdata, 3544 - rx_status->mactime, 3545 - &elems, false); 3359 + rx_status->mactime, 3360 + rx_status->device_timestamp, 3361 + &elems, false); 3546 3362 } 3547 3363 break; 3548 3364 } ··· 3850 3664 struct ieee80211_sub_if_data *sdata = 3851 3665 (struct ieee80211_sub_if_data *) data; 3852 3666 struct ieee80211_local *local = sdata->local; 3667 + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3853 3668 3854 3669 if (local->quiescing) 3855 3670 return; 3856 3671 3857 - if (sdata->vif.csa_active) 3672 + if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) 3858 3673 return; 3859 3674 3860 3675 sdata->u.mgd.connection_loss = false; ··· 3873 3686 if (local->quiescing) 3874 3687 return; 3875 3688 3876 - if (sdata->vif.csa_active) 3689 + if (sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) 3877 3690 return; 3878 3691 3879 3692 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work); ··· 3985 3798 (unsigned long) sdata); 3986 3799 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, 3987 3800 (unsigned long) sdata); 3801 + INIT_DELAYED_WORK(&ifmgd->tx_tspec_wk, 3802 + ieee80211_sta_handle_tspec_ac_params_wk); 3988 3803 3989 3804 ifmgd->flags = 0; 3990 3805 ifmgd->powersave = sdata->wdev.ps;
+250
net/mac80211/ocb.c
··· 1 + /* 2 + * OCB mode implementation 3 + * 4 + * Copyright: (c) 2014 Czech Technical University in Prague 5 + * (c) 2014 Volkswagen Group Research 6 + * Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz> 7 + * Funded by: Volkswagen Group Research 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2 as 11 + * published by the Free Software Foundation. 12 + */ 13 + 14 + #include <linux/delay.h> 15 + #include <linux/if_ether.h> 16 + #include <linux/skbuff.h> 17 + #include <linux/if_arp.h> 18 + #include <linux/etherdevice.h> 19 + #include <linux/rtnetlink.h> 20 + #include <net/mac80211.h> 21 + #include <asm/unaligned.h> 22 + 23 + #include "ieee80211_i.h" 24 + #include "driver-ops.h" 25 + #include "rate.h" 26 + 27 + #define IEEE80211_OCB_HOUSEKEEPING_INTERVAL (60 * HZ) 28 + #define IEEE80211_OCB_PEER_INACTIVITY_LIMIT (240 * HZ) 29 + #define IEEE80211_OCB_MAX_STA_ENTRIES 128 30 + 31 + /** 32 + * enum ocb_deferred_task_flags - mac80211 OCB deferred tasks 33 + * @OCB_WORK_HOUSEKEEPING: run the periodic OCB housekeeping tasks 34 + * 35 + * These flags are used in @wrkq_flags field of &struct ieee80211_if_ocb 36 + */ 37 + enum ocb_deferred_task_flags { 38 + OCB_WORK_HOUSEKEEPING, 39 + }; 40 + 41 + void ieee80211_ocb_rx_no_sta(struct ieee80211_sub_if_data *sdata, 42 + const u8 *bssid, const u8 *addr, 43 + u32 supp_rates) 44 + { 45 + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; 46 + struct ieee80211_local *local = sdata->local; 47 + struct ieee80211_chanctx_conf *chanctx_conf; 48 + struct ieee80211_supported_band *sband; 49 + enum nl80211_bss_scan_width scan_width; 50 + struct sta_info *sta; 51 + int band; 52 + 53 + /* XXX: Consider removing the least recently used entry and 54 + * allow new one to be added. 55 + */ 56 + if (local->num_sta >= IEEE80211_OCB_MAX_STA_ENTRIES) { 57 + net_info_ratelimited("%s: No room for a new OCB STA entry %pM\n", 58 + sdata->name, addr); 59 + return; 60 + } 61 + 62 + ocb_dbg(sdata, "Adding new OCB station %pM\n", addr); 63 + 64 + rcu_read_lock(); 65 + chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 66 + if (WARN_ON_ONCE(!chanctx_conf)) { 67 + rcu_read_unlock(); 68 + return; 69 + } 70 + band = chanctx_conf->def.chan->band; 71 + scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def); 72 + rcu_read_unlock(); 73 + 74 + sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); 75 + if (!sta) 76 + return; 77 + 78 + sta->last_rx = jiffies; 79 + 80 + /* Add only mandatory rates for now */ 81 + sband = local->hw.wiphy->bands[band]; 82 + sta->sta.supp_rates[band] = 83 + ieee80211_mandatory_rates(sband, scan_width); 84 + 85 + spin_lock(&ifocb->incomplete_lock); 86 + list_add(&sta->list, &ifocb->incomplete_stations); 87 + spin_unlock(&ifocb->incomplete_lock); 88 + ieee80211_queue_work(&local->hw, &sdata->work); 89 + } 90 + 91 + static struct sta_info *ieee80211_ocb_finish_sta(struct sta_info *sta) 92 + __acquires(RCU) 93 + { 94 + struct ieee80211_sub_if_data *sdata = sta->sdata; 95 + u8 addr[ETH_ALEN]; 96 + 97 + memcpy(addr, sta->sta.addr, ETH_ALEN); 98 + 99 + ocb_dbg(sdata, "Adding new IBSS station %pM (dev=%s)\n", 100 + addr, sdata->name); 101 + 102 + sta_info_move_state(sta, IEEE80211_STA_AUTH); 103 + sta_info_move_state(sta, IEEE80211_STA_ASSOC); 104 + sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); 105 + 106 + rate_control_rate_init(sta); 107 + 108 + /* If it fails, maybe we raced another insertion? */ 109 + if (sta_info_insert_rcu(sta)) 110 + return sta_info_get(sdata, addr); 111 + return sta; 112 + } 113 + 114 + static void ieee80211_ocb_housekeeping(struct ieee80211_sub_if_data *sdata) 115 + { 116 + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; 117 + 118 + ocb_dbg(sdata, "Running ocb housekeeping\n"); 119 + 120 + ieee80211_sta_expire(sdata, IEEE80211_OCB_PEER_INACTIVITY_LIMIT); 121 + 122 + mod_timer(&ifocb->housekeeping_timer, 123 + round_jiffies(jiffies + IEEE80211_OCB_HOUSEKEEPING_INTERVAL)); 124 + } 125 + 126 + void ieee80211_ocb_work(struct ieee80211_sub_if_data *sdata) 127 + { 128 + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; 129 + struct sta_info *sta; 130 + 131 + if (ifocb->joined != true) 132 + return; 133 + 134 + sdata_lock(sdata); 135 + 136 + spin_lock_bh(&ifocb->incomplete_lock); 137 + while (!list_empty(&ifocb->incomplete_stations)) { 138 + sta = list_first_entry(&ifocb->incomplete_stations, 139 + struct sta_info, list); 140 + list_del(&sta->list); 141 + spin_unlock_bh(&ifocb->incomplete_lock); 142 + 143 + ieee80211_ocb_finish_sta(sta); 144 + rcu_read_unlock(); 145 + spin_lock_bh(&ifocb->incomplete_lock); 146 + } 147 + spin_unlock_bh(&ifocb->incomplete_lock); 148 + 149 + if (test_and_clear_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags)) 150 + ieee80211_ocb_housekeeping(sdata); 151 + 152 + sdata_unlock(sdata); 153 + } 154 + 155 + static void ieee80211_ocb_housekeeping_timer(unsigned long data) 156 + { 157 + struct ieee80211_sub_if_data *sdata = (void *)data; 158 + struct ieee80211_local *local = sdata->local; 159 + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; 160 + 161 + set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags); 162 + 163 + ieee80211_queue_work(&local->hw, &sdata->work); 164 + } 165 + 166 + void ieee80211_ocb_setup_sdata(struct ieee80211_sub_if_data *sdata) 167 + { 168 + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; 169 + 170 + setup_timer(&ifocb->housekeeping_timer, 171 + ieee80211_ocb_housekeeping_timer, 172 + (unsigned long)sdata); 173 + INIT_LIST_HEAD(&ifocb->incomplete_stations); 174 + spin_lock_init(&ifocb->incomplete_lock); 175 + } 176 + 177 + int ieee80211_ocb_join(struct ieee80211_sub_if_data *sdata, 178 + struct ocb_setup *setup) 179 + { 180 + struct ieee80211_local *local = sdata->local; 181 + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; 182 + u32 changed = BSS_CHANGED_OCB; 183 + int err; 184 + 185 + if (ifocb->joined == true) 186 + return -EINVAL; 187 + 188 + sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; 189 + sdata->smps_mode = IEEE80211_SMPS_OFF; 190 + sdata->needed_rx_chains = sdata->local->rx_chains; 191 + 192 + mutex_lock(&sdata->local->mtx); 193 + err = ieee80211_vif_use_channel(sdata, &setup->chandef, 194 + IEEE80211_CHANCTX_SHARED); 195 + mutex_unlock(&sdata->local->mtx); 196 + if (err) 197 + return err; 198 + 199 + ieee80211_bss_info_change_notify(sdata, changed); 200 + 201 + ifocb->joined = true; 202 + 203 + set_bit(OCB_WORK_HOUSEKEEPING, &ifocb->wrkq_flags); 204 + ieee80211_queue_work(&local->hw, &sdata->work); 205 + 206 + netif_carrier_on(sdata->dev); 207 + return 0; 208 + } 209 + 210 + int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata) 211 + { 212 + struct ieee80211_if_ocb *ifocb = &sdata->u.ocb; 213 + struct ieee80211_local *local = sdata->local; 214 + struct sta_info *sta; 215 + 216 + ifocb->joined = false; 217 + sta_info_flush(sdata); 218 + 219 + spin_lock_bh(&ifocb->incomplete_lock); 220 + while (!list_empty(&ifocb->incomplete_stations)) { 221 + sta = list_first_entry(&ifocb->incomplete_stations, 222 + struct sta_info, list); 223 + list_del(&sta->list); 224 + spin_unlock_bh(&ifocb->incomplete_lock); 225 + 226 + sta_info_free(local, sta); 227 + spin_lock_bh(&ifocb->incomplete_lock); 228 + } 229 + spin_unlock_bh(&ifocb->incomplete_lock); 230 + 231 + netif_carrier_off(sdata->dev); 232 + clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); 233 + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_OCB); 234 + 235 + mutex_lock(&sdata->local->mtx); 236 + ieee80211_vif_release_channel(sdata); 237 + mutex_unlock(&sdata->local->mtx); 238 + 239 + skb_queue_purge(&sdata->skb_queue); 240 + 241 + del_timer_sync(&sdata->u.ocb.housekeeping_timer); 242 + /* If the timer fired while we waited for it, it will have 243 + * requeued the work. Now the work will be running again 244 + * but will not rearm the timer again because it checks 245 + * whether we are connected to the network or not -- at this 246 + * point we shouldn't be anymore. 247 + */ 248 + 249 + return 0; 250 + }
+1 -1
net/mac80211/rate.c
··· 448 448 */ 449 449 if (!(rates[0].flags & IEEE80211_TX_RC_MCS)) { 450 450 u32 basic_rates = vif->bss_conf.basic_rates; 451 - s8 baserate = basic_rates ? ffs(basic_rates - 1) : 0; 451 + s8 baserate = basic_rates ? ffs(basic_rates) - 1 : 0; 452 452 453 453 rate = &sband->bitrates[rates[0].idx]; 454 454
+1 -1
net/mac80211/rc80211_minstrel.c
··· 191 191 * (1) if any success probabilitiy >= 95%, out of those rates 192 192 * choose the maximum throughput rate as max_prob_rate 193 193 * (2) if all success probabilities < 95%, the rate with 194 - * highest success probability is choosen as max_prob_rate */ 194 + * highest success probability is chosen as max_prob_rate */ 195 195 if (mrs->probability >= MINSTREL_FRAC(95, 100)) { 196 196 if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp) 197 197 tmp_prob_rate = i;
+7 -5
net/mac80211/rc80211_minstrel_debugfs.c
··· 62 62 unsigned int i, tp, prob, eprob; 63 63 char *p; 64 64 65 - ms = kmalloc(sizeof(*ms) + 4096, GFP_KERNEL); 65 + ms = kmalloc(2048, GFP_KERNEL); 66 66 if (!ms) 67 67 return -ENOMEM; 68 68 69 69 file->private_data = ms; 70 70 p = ms->buf; 71 - p += sprintf(p, "rate throughput ewma prob this prob " 72 - "this succ/attempt success attempts\n"); 71 + p += sprintf(p, "rate tpt eprob *prob" 72 + " *ok(*cum) ok( cum)\n"); 73 73 for (i = 0; i < mi->n_rates; i++) { 74 74 struct minstrel_rate *mr = &mi->r[i]; 75 75 struct minstrel_rate_stats *mrs = &mi->r[i].stats; ··· 86 86 prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); 87 87 eprob = MINSTREL_TRUNC(mrs->probability * 1000); 88 88 89 - p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u " 90 - " %3u(%3u) %8llu %8llu\n", 89 + p += sprintf(p, " %4u.%1u %3u.%1u %3u.%1u" 90 + " %4u(%4u) %9llu(%9llu)\n", 91 91 tp / 10, tp % 10, 92 92 eprob / 10, eprob % 10, 93 93 prob / 10, prob % 10, ··· 101 101 mi->total_packets - mi->sample_packets, 102 102 mi->sample_packets); 103 103 ms->len = p - ms->buf; 104 + 105 + WARN_ON(ms->len + sizeof(*ms) > 2048); 104 106 105 107 return 0; 106 108 }
+253 -60
net/mac80211/rc80211_minstrel_ht.c
··· 10 10 #include <linux/skbuff.h> 11 11 #include <linux/debugfs.h> 12 12 #include <linux/random.h> 13 + #include <linux/moduleparam.h> 13 14 #include <linux/ieee80211.h> 14 15 #include <net/mac80211.h> 15 16 #include "rate.h" ··· 35 34 /* Transmit duration for the raw data part of an average sized packet */ 36 35 #define MCS_DURATION(streams, sgi, bps) MCS_SYMBOL_TIME(sgi, MCS_NSYMS((streams) * (bps))) 37 36 37 + #define BW_20 0 38 + #define BW_40 1 39 + #define BW_80 2 40 + 38 41 /* 39 42 * Define group sort order: HT40 -> SGI -> #streams 40 43 */ 41 44 #define GROUP_IDX(_streams, _sgi, _ht40) \ 45 + MINSTREL_HT_GROUP_0 + \ 42 46 MINSTREL_MAX_STREAMS * 2 * _ht40 + \ 43 - MINSTREL_MAX_STREAMS * _sgi + \ 47 + MINSTREL_MAX_STREAMS * _sgi + \ 44 48 _streams - 1 45 49 46 50 /* MCS rate information for an MCS group */ ··· 53 47 [GROUP_IDX(_streams, _sgi, _ht40)] = { \ 54 48 .streams = _streams, \ 55 49 .flags = \ 50 + IEEE80211_TX_RC_MCS | \ 56 51 (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ 57 52 (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ 58 53 .duration = { \ ··· 65 58 MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208), \ 66 59 MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234), \ 67 60 MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) \ 61 + } \ 62 + } 63 + 64 + #define VHT_GROUP_IDX(_streams, _sgi, _bw) \ 65 + (MINSTREL_VHT_GROUP_0 + \ 66 + MINSTREL_MAX_STREAMS * 2 * (_bw) + \ 67 + MINSTREL_MAX_STREAMS * (_sgi) + \ 68 + (_streams) - 1) 69 + 70 + #define BW2VBPS(_bw, r3, r2, r1) \ 71 + (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1) 72 + 73 + #define VHT_GROUP(_streams, _sgi, _bw) \ 74 + [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \ 75 + .streams = _streams, \ 76 + .flags = \ 77 + IEEE80211_TX_RC_VHT_MCS | \ 78 + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ 79 + (_bw == BW_80 ? IEEE80211_TX_RC_80_MHZ_WIDTH : \ 80 + _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ 81 + .duration = { \ 82 + MCS_DURATION(_streams, _sgi, \ 83 + BW2VBPS(_bw, 117, 54, 26)), \ 84 + MCS_DURATION(_streams, _sgi, \ 85 + BW2VBPS(_bw, 234, 108, 52)), \ 86 + MCS_DURATION(_streams, _sgi, \ 87 + BW2VBPS(_bw, 351, 162, 78)), \ 88 + MCS_DURATION(_streams, _sgi, \ 89 + BW2VBPS(_bw, 468, 216, 104)), \ 90 + MCS_DURATION(_streams, _sgi, \ 91 + BW2VBPS(_bw, 702, 324, 156)), \ 92 + MCS_DURATION(_streams, _sgi, \ 93 + BW2VBPS(_bw, 936, 432, 208)), \ 94 + MCS_DURATION(_streams, _sgi, \ 95 + BW2VBPS(_bw, 1053, 486, 234)), \ 96 + MCS_DURATION(_streams, _sgi, \ 97 + BW2VBPS(_bw, 1170, 540, 260)), \ 98 + MCS_DURATION(_streams, _sgi, \ 99 + BW2VBPS(_bw, 1404, 648, 312)), \ 100 + MCS_DURATION(_streams, _sgi, \ 101 + BW2VBPS(_bw, 1560, 720, 346)) \ 68 102 } \ 69 103 } 70 104 ··· 124 76 CCK_ACK_DURATION(55, _short), \ 125 77 CCK_ACK_DURATION(110, _short) 126 78 127 - #define CCK_GROUP \ 128 - [MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS] = { \ 129 - .streams = 0, \ 130 - .duration = { \ 131 - CCK_DURATION_LIST(false), \ 132 - CCK_DURATION_LIST(true) \ 133 - } \ 79 + #define CCK_GROUP \ 80 + [MINSTREL_CCK_GROUP] = { \ 81 + .streams = 0, \ 82 + .flags = 0, \ 83 + .duration = { \ 84 + CCK_DURATION_LIST(false), \ 85 + CCK_DURATION_LIST(true) \ 86 + } \ 134 87 } 88 + 89 + #ifdef CONFIG_MAC80211_RC_MINSTREL_VHT 90 + static bool minstrel_vht_only = true; 91 + module_param(minstrel_vht_only, bool, 0644); 92 + MODULE_PARM_DESC(minstrel_vht_only, 93 + "Use only VHT rates when VHT is supported by sta."); 94 + #endif 135 95 136 96 /* 137 97 * To enable sufficiently targeted rate sampling, MCS rates are divided into ··· 147 91 * use. 148 92 * 149 93 * Sortorder has to be fixed for GROUP_IDX macro to be applicable: 150 - * HT40 -> SGI -> #streams 94 + * BW -> SGI -> #streams 151 95 */ 152 96 const struct mcs_group minstrel_mcs_groups[] = { 153 - MCS_GROUP(1, 0, 0), 154 - MCS_GROUP(2, 0, 0), 97 + MCS_GROUP(1, 0, BW_20), 98 + MCS_GROUP(2, 0, BW_20), 155 99 #if MINSTREL_MAX_STREAMS >= 3 156 - MCS_GROUP(3, 0, 0), 100 + MCS_GROUP(3, 0, BW_20), 157 101 #endif 158 102 159 - MCS_GROUP(1, 1, 0), 160 - MCS_GROUP(2, 1, 0), 103 + MCS_GROUP(1, 1, BW_20), 104 + MCS_GROUP(2, 1, BW_20), 161 105 #if MINSTREL_MAX_STREAMS >= 3 162 - MCS_GROUP(3, 1, 0), 106 + MCS_GROUP(3, 1, BW_20), 163 107 #endif 164 108 165 - MCS_GROUP(1, 0, 1), 166 - MCS_GROUP(2, 0, 1), 109 + MCS_GROUP(1, 0, BW_40), 110 + MCS_GROUP(2, 0, BW_40), 167 111 #if MINSTREL_MAX_STREAMS >= 3 168 - MCS_GROUP(3, 0, 1), 112 + MCS_GROUP(3, 0, BW_40), 169 113 #endif 170 114 171 - MCS_GROUP(1, 1, 1), 172 - MCS_GROUP(2, 1, 1), 115 + MCS_GROUP(1, 1, BW_40), 116 + MCS_GROUP(2, 1, BW_40), 173 117 #if MINSTREL_MAX_STREAMS >= 3 174 - MCS_GROUP(3, 1, 1), 118 + MCS_GROUP(3, 1, BW_40), 175 119 #endif 176 120 177 - /* must be last */ 178 - CCK_GROUP 121 + CCK_GROUP, 122 + 123 + #ifdef CONFIG_MAC80211_RC_MINSTREL_VHT 124 + VHT_GROUP(1, 0, BW_20), 125 + VHT_GROUP(2, 0, BW_20), 126 + #if MINSTREL_MAX_STREAMS >= 3 127 + VHT_GROUP(3, 0, BW_20), 128 + #endif 129 + 130 + VHT_GROUP(1, 1, BW_20), 131 + VHT_GROUP(2, 1, BW_20), 132 + #if MINSTREL_MAX_STREAMS >= 3 133 + VHT_GROUP(3, 1, BW_20), 134 + #endif 135 + 136 + VHT_GROUP(1, 0, BW_40), 137 + VHT_GROUP(2, 0, BW_40), 138 + #if MINSTREL_MAX_STREAMS >= 3 139 + VHT_GROUP(3, 0, BW_40), 140 + #endif 141 + 142 + VHT_GROUP(1, 1, BW_40), 143 + VHT_GROUP(2, 1, BW_40), 144 + #if MINSTREL_MAX_STREAMS >= 3 145 + VHT_GROUP(3, 1, BW_40), 146 + #endif 147 + 148 + VHT_GROUP(1, 0, BW_80), 149 + VHT_GROUP(2, 0, BW_80), 150 + #if MINSTREL_MAX_STREAMS >= 3 151 + VHT_GROUP(3, 0, BW_80), 152 + #endif 153 + 154 + VHT_GROUP(1, 1, BW_80), 155 + VHT_GROUP(2, 1, BW_80), 156 + #if MINSTREL_MAX_STREAMS >= 3 157 + VHT_GROUP(3, 1, BW_80), 158 + #endif 159 + #endif 179 160 }; 180 - 181 - #define MINSTREL_CCK_GROUP (ARRAY_SIZE(minstrel_mcs_groups) - 1) 182 161 183 162 static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; 184 163 ··· 221 130 minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); 222 131 223 132 /* 133 + * Some VHT MCSes are invalid (when Ndbps / Nes is not an integer) 134 + * e.g for MCS9@20MHzx1Nss: Ndbps=8x52*(5/6) Nes=1 135 + * 136 + * Returns the valid mcs map for struct minstrel_mcs_group_data.supported 137 + */ 138 + static u16 139 + minstrel_get_valid_vht_rates(int bw, int nss, __le16 mcs_map) 140 + { 141 + u16 mask = 0; 142 + 143 + if (bw == BW_20) { 144 + if (nss != 3 && nss != 6) 145 + mask = BIT(9); 146 + } else if (bw == BW_80) { 147 + if (nss == 3 || nss == 7) 148 + mask = BIT(6); 149 + else if (nss == 6) 150 + mask = BIT(9); 151 + } else { 152 + WARN_ON(bw != BW_40); 153 + } 154 + 155 + switch ((le16_to_cpu(mcs_map) >> (2 * (nss - 1))) & 3) { 156 + case IEEE80211_VHT_MCS_SUPPORT_0_7: 157 + mask |= 0x300; 158 + break; 159 + case IEEE80211_VHT_MCS_SUPPORT_0_8: 160 + mask |= 0x200; 161 + break; 162 + case IEEE80211_VHT_MCS_SUPPORT_0_9: 163 + break; 164 + default: 165 + mask = 0x3ff; 166 + } 167 + 168 + return 0x3ff & ~mask; 169 + } 170 + 171 + /* 224 172 * Look up an MCS group index based on mac80211 rate information 225 173 */ 226 174 static int 227 175 minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) 228 176 { 229 - return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1, 177 + return GROUP_IDX((rate->idx / 8) + 1, 230 178 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), 231 179 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); 180 + } 181 + 182 + static int 183 + minstrel_vht_get_group_idx(struct ieee80211_tx_rate *rate) 184 + { 185 + return VHT_GROUP_IDX(ieee80211_rate_get_vht_nss(rate), 186 + !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), 187 + !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + 188 + 2*!!(rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)); 232 189 } 233 190 234 191 static struct minstrel_rate_stats * ··· 288 149 if (rate->flags & IEEE80211_TX_RC_MCS) { 289 150 group = minstrel_ht_get_group_idx(rate); 290 151 idx = rate->idx % 8; 152 + } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) { 153 + group = minstrel_vht_get_group_idx(rate); 154 + idx = ieee80211_rate_get_vht_mcs(rate); 291 155 } else { 292 156 group = MINSTREL_CCK_GROUP; 293 157 ··· 382 240 * MCS groups, CCK rates do not provide aggregation and are therefore at last. 383 241 */ 384 242 static void 385 - minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index, 386 - u8 *tp_list) 243 + minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u16 index, 244 + u16 *tp_list) 387 245 { 388 246 int cur_group, cur_idx, cur_thr, cur_prob; 389 247 int tmp_group, tmp_idx, tmp_thr, tmp_prob; ··· 420 278 * Find and set the topmost probability rate per sta and per group 421 279 */ 422 280 static void 423 - minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u8 index) 281 + minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 index) 424 282 { 425 283 struct minstrel_mcs_group_data *mg; 426 284 struct minstrel_rate_stats *mr; ··· 463 321 */ 464 322 static void 465 323 minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi, 466 - u8 tmp_mcs_tp_rate[MAX_THR_RATES], 467 - u8 tmp_cck_tp_rate[MAX_THR_RATES]) 324 + u16 tmp_mcs_tp_rate[MAX_THR_RATES], 325 + u16 tmp_cck_tp_rate[MAX_THR_RATES]) 468 326 { 469 327 unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp; 470 328 int i; ··· 528 386 struct minstrel_mcs_group_data *mg; 529 387 struct minstrel_rate_stats *mr; 530 388 int group, i, j; 531 - u8 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; 532 - u8 tmp_cck_tp_rate[MAX_THR_RATES], index; 389 + u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; 390 + u16 tmp_cck_tp_rate[MAX_THR_RATES], index; 533 391 534 392 if (mi->ampdu_packets > 0) { 535 393 mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, ··· 627 485 if (!rate->count) 628 486 return false; 629 487 630 - if (rate->flags & IEEE80211_TX_RC_MCS) 488 + if (rate->flags & IEEE80211_TX_RC_MCS || 489 + rate->flags & IEEE80211_TX_RC_VHT_MCS) 631 490 return true; 632 491 633 492 return rate->idx == mp->cck_rates[0] || ··· 660 517 } 661 518 662 519 static void 663 - minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u8 *idx, bool primary) 520 + minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary) 664 521 { 665 522 int group, orig_group; 666 523 ··· 857 714 const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; 858 715 struct minstrel_rate_stats *mr; 859 716 u8 idx; 860 - u16 flags; 717 + u16 flags = group->flags; 861 718 862 719 mr = minstrel_get_ratestats(mi, index); 863 720 if (!mr->retry_updated) ··· 873 730 ratetbl->rate[offset].count_rts = mr->retry_count_rtscts; 874 731 } 875 732 876 - if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { 733 + if (index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) 877 734 idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; 878 - flags = 0; 879 - } else { 735 + else if (flags & IEEE80211_TX_RC_VHT_MCS) 736 + idx = ((group->streams - 1) << 4) | 737 + ((index % MCS_GROUP_RATES) & 0xF); 738 + else 880 739 idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8; 881 - flags = IEEE80211_TX_RC_MCS | group->flags; 882 - } 883 740 884 741 if (offset > 0) { 885 742 ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; ··· 1059 916 if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { 1060 917 int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); 1061 918 rate->idx = mp->cck_rates[idx]; 1062 - rate->flags = 0; 1063 - return; 919 + } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { 920 + ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, 921 + sample_group->streams); 922 + } else { 923 + rate->idx = sample_idx % MCS_GROUP_RATES + 924 + (sample_group->streams - 1) * 8; 1064 925 } 1065 926 1066 - rate->idx = sample_idx % MCS_GROUP_RATES + 1067 - (sample_group->streams - 1) * 8; 1068 - rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags; 927 + rate->flags = sample_group->flags; 1069 928 } 1070 929 1071 930 static void ··· 1107 962 struct minstrel_ht_sta *mi = &msp->ht; 1108 963 struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; 1109 964 u16 sta_cap = sta->ht_cap.cap; 965 + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; 966 + int use_vht; 1110 967 int n_supported = 0; 1111 968 int ack_dur; 1112 969 int stbc; ··· 1118 971 if (!sta->ht_cap.ht_supported) 1119 972 goto use_legacy; 1120 973 1121 - BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != 1122 - MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1); 974 + BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); 975 + 976 + #ifdef CONFIG_MAC80211_RC_MINSTREL_VHT 977 + if (vht_cap->vht_supported) 978 + use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0); 979 + else 980 + #endif 981 + use_vht = 0; 1123 982 1124 983 msp->is_ht = true; 1125 984 memset(mi, 0, sizeof(*mi)); ··· 1150 997 } 1151 998 mi->sample_tries = 4; 1152 999 1153 - stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> 1154 - IEEE80211_HT_CAP_RX_STBC_SHIFT; 1155 - mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; 1000 + /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */ 1001 + if (!use_vht) { 1002 + stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> 1003 + IEEE80211_HT_CAP_RX_STBC_SHIFT; 1004 + mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; 1156 1005 1157 - if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) 1158 - mi->tx_flags |= IEEE80211_TX_CTL_LDPC; 1006 + if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) 1007 + mi->tx_flags |= IEEE80211_TX_CTL_LDPC; 1008 + } 1159 1009 1160 1010 for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { 1011 + u32 gflags = minstrel_mcs_groups[i].flags; 1012 + int bw, nss; 1013 + 1161 1014 mi->groups[i].supported = 0; 1162 1015 if (i == MINSTREL_CCK_GROUP) { 1163 1016 minstrel_ht_update_cck(mp, mi, sband, sta); 1164 1017 continue; 1165 1018 } 1166 1019 1167 - if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_SHORT_GI) { 1168 - if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { 1020 + if (gflags & IEEE80211_TX_RC_SHORT_GI) { 1021 + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { 1169 1022 if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) 1170 1023 continue; 1171 1024 } else { ··· 1180 1021 } 1181 1022 } 1182 1023 1183 - if (minstrel_mcs_groups[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH && 1024 + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH && 1184 1025 sta->bandwidth < IEEE80211_STA_RX_BW_40) 1185 1026 continue; 1186 1027 1028 + nss = minstrel_mcs_groups[i].streams; 1029 + 1187 1030 /* Mark MCS > 7 as unsupported if STA is in static SMPS mode */ 1188 - if (sta->smps_mode == IEEE80211_SMPS_STATIC && 1189 - minstrel_mcs_groups[i].streams > 1) 1031 + if (sta->smps_mode == IEEE80211_SMPS_STATIC && nss > 1) 1190 1032 continue; 1191 1033 1192 - mi->groups[i].supported = 1193 - mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; 1034 + /* HT rate */ 1035 + if (gflags & IEEE80211_TX_RC_MCS) { 1036 + #ifdef CONFIG_MAC80211_RC_MINSTREL_VHT 1037 + if (use_vht && minstrel_vht_only) 1038 + continue; 1039 + #endif 1040 + mi->groups[i].supported = mcs->rx_mask[nss - 1]; 1041 + if (mi->groups[i].supported) 1042 + n_supported++; 1043 + continue; 1044 + } 1045 + 1046 + /* VHT rate */ 1047 + if (!vht_cap->vht_supported || 1048 + WARN_ON(!(gflags & IEEE80211_TX_RC_VHT_MCS)) || 1049 + WARN_ON(gflags & IEEE80211_TX_RC_160_MHZ_WIDTH)) 1050 + continue; 1051 + 1052 + if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) { 1053 + if (sta->bandwidth < IEEE80211_STA_RX_BW_80 || 1054 + ((gflags & IEEE80211_TX_RC_SHORT_GI) && 1055 + !(vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80))) { 1056 + continue; 1057 + } 1058 + } 1059 + 1060 + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) 1061 + bw = BW_40; 1062 + else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) 1063 + bw = BW_80; 1064 + else 1065 + bw = BW_20; 1066 + 1067 + mi->groups[i].supported = minstrel_get_valid_vht_rates(bw, nss, 1068 + vht_cap->vht_mcs.tx_mcs_map); 1194 1069 1195 1070 if (mi->groups[i].supported) 1196 1071 n_supported++;
+31 -9
net/mac80211/rc80211_minstrel_ht.h
··· 13 13 * The number of streams can be changed to 2 to reduce code 14 14 * size and memory footprint. 15 15 */ 16 - #define MINSTREL_MAX_STREAMS 3 17 - #define MINSTREL_STREAM_GROUPS 4 16 + #define MINSTREL_MAX_STREAMS 3 17 + #define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */ 18 + #ifdef CONFIG_MAC80211_RC_MINSTREL_VHT 19 + #define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */ 20 + #else 21 + #define MINSTREL_VHT_STREAM_GROUPS 0 22 + #endif 18 23 19 - #define MCS_GROUP_RATES 8 24 + #define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ 25 + MINSTREL_HT_STREAM_GROUPS) 26 + #define MINSTREL_VHT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ 27 + MINSTREL_VHT_STREAM_GROUPS) 28 + #define MINSTREL_CCK_GROUPS_NB 1 29 + #define MINSTREL_GROUPS_NB (MINSTREL_HT_GROUPS_NB + \ 30 + MINSTREL_VHT_GROUPS_NB + \ 31 + MINSTREL_CCK_GROUPS_NB) 32 + 33 + #define MINSTREL_HT_GROUP_0 0 34 + #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) 35 + #define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1) 36 + 37 + #ifdef CONFIG_MAC80211_RC_MINSTREL_VHT 38 + #define MCS_GROUP_RATES 10 39 + #else 40 + #define MCS_GROUP_RATES 8 41 + #endif 20 42 21 43 struct mcs_group { 22 44 u32 flags; ··· 53 31 u8 column; 54 32 55 33 /* bitfield of supported MCS rates of this group */ 56 - u8 supported; 34 + u16 supported; 57 35 58 36 /* sorted rate set within a MCS group*/ 59 - u8 max_group_tp_rate[MAX_THR_RATES]; 60 - u8 max_group_prob_rate; 37 + u16 max_group_tp_rate[MAX_THR_RATES]; 38 + u16 max_group_prob_rate; 61 39 62 40 /* MCS rate statistics */ 63 41 struct minstrel_rate_stats rates[MCS_GROUP_RATES]; ··· 74 52 unsigned int avg_ampdu_len; 75 53 76 54 /* overall sorted rate set */ 77 - u8 max_tp_rate[MAX_THR_RATES]; 78 - u8 max_prob_rate; 55 + u16 max_tp_rate[MAX_THR_RATES]; 56 + u16 max_prob_rate; 79 57 80 58 /* time of last status update */ 81 59 unsigned long stats_update; ··· 102 80 u8 cck_supported_short; 103 81 104 82 /* MCS rate group info and statistics */ 105 - struct minstrel_mcs_group_data groups[MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS + 1]; 83 + struct minstrel_mcs_group_data groups[MINSTREL_GROUPS_NB]; 106 84 }; 107 85 108 86 struct minstrel_ht_sta_priv {
+30 -18
net/mac80211/rc80211_minstrel_ht_debugfs.c
··· 18 18 static char * 19 19 minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) 20 20 { 21 - unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; 22 21 const struct mcs_group *mg; 23 22 unsigned int j, tp, prob, eprob; 24 23 char htmode = '2'; 25 24 char gimode = 'L'; 25 + u32 gflags; 26 26 27 27 if (!mi->groups[i].supported) 28 28 return p; 29 29 30 30 mg = &minstrel_mcs_groups[i]; 31 - if (mg->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) 31 + gflags = mg->flags; 32 + 33 + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) 32 34 htmode = '4'; 33 - if (mg->flags & IEEE80211_TX_RC_SHORT_GI) 35 + else if (gflags & IEEE80211_TX_RC_80_MHZ_WIDTH) 36 + htmode = '8'; 37 + if (gflags & IEEE80211_TX_RC_SHORT_GI) 34 38 gimode = 'S'; 35 39 36 40 for (j = 0; j < MCS_GROUP_RATES; j++) { ··· 45 41 if (!(mi->groups[i].supported & BIT(j))) 46 42 continue; 47 43 48 - if (i == max_mcs) 49 - p += sprintf(p, "CCK/%cP ", j < 4 ? 'L' : 'S'); 44 + if (gflags & IEEE80211_TX_RC_MCS) 45 + p += sprintf(p, " HT%c0/%cGI ", htmode, gimode); 46 + else if (gflags & IEEE80211_TX_RC_VHT_MCS) 47 + p += sprintf(p, "VHT%c0/%cGI ", htmode, gimode); 50 48 else 51 - p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); 49 + p += sprintf(p, " CCK/%cP ", j < 4 ? 'L' : 'S'); 52 50 53 51 *(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' '; 54 52 *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' '; ··· 58 52 *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' '; 59 53 *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; 60 54 61 - if (i == max_mcs) { 62 - int r = bitrates[j % 4]; 63 - p += sprintf(p, " %2u.%1uM", r / 10, r % 10); 55 + if (gflags & IEEE80211_TX_RC_MCS) { 56 + p += sprintf(p, " MCS%-2u ", (mg->streams - 1) * 8 + j); 57 + } else if (gflags & IEEE80211_TX_RC_VHT_MCS) { 58 + p += sprintf(p, " MCS%-1u/%1u", j, mg->streams); 64 59 } else { 65 - p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j); 60 + int r = bitrates[j % 4]; 61 + 62 + p += sprintf(p, " %2u.%1uM ", r / 10, r % 10); 66 63 } 67 64 68 65 tp = mr->cur_tp / 10; 69 66 prob = MINSTREL_TRUNC(mr->cur_prob * 1000); 70 67 eprob = MINSTREL_TRUNC(mr->probability * 1000); 71 68 72 - p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u " 73 - "%3u %3u(%3u) %8llu %8llu\n", 69 + p += sprintf(p, " %4u.%1u %3u.%1u %3u.%1u " 70 + "%3u %4u(%4u) %9llu(%9llu)\n", 74 71 tp / 10, tp % 10, 75 72 eprob / 10, eprob % 10, 76 73 prob / 10, prob % 10, ··· 94 85 struct minstrel_ht_sta *mi = &msp->ht; 95 86 struct minstrel_debugfs_info *ms; 96 87 unsigned int i; 97 - unsigned int max_mcs = MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS; 98 88 char *p; 99 89 int ret; 100 90 ··· 104 96 return ret; 105 97 } 106 98 107 - ms = kmalloc(sizeof(*ms) + 8192, GFP_KERNEL); 99 + ms = kmalloc(32768, GFP_KERNEL); 108 100 if (!ms) 109 101 return -ENOMEM; 110 102 111 103 file->private_data = ms; 112 104 p = ms->buf; 113 - p += sprintf(p, "type rate throughput ewma prob " 114 - "this prob retry this succ/attempt success attempts\n"); 105 + p += sprintf(p, " type rate tpt eprob *prob " 106 + "ret *ok(*cum) ok( cum)\n"); 115 107 116 - p = minstrel_ht_stats_dump(mi, max_mcs, p); 117 - for (i = 0; i < max_mcs; i++) 108 + p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p); 109 + for (i = 0; i < MINSTREL_CCK_GROUP; i++) 110 + p = minstrel_ht_stats_dump(mi, i, p); 111 + for (i++; i < ARRAY_SIZE(mi->groups); i++) 118 112 p = minstrel_ht_stats_dump(mi, i, p); 119 113 120 114 p += sprintf(p, "\nTotal packet count:: ideal %d " ··· 127 117 MINSTREL_TRUNC(mi->avg_ampdu_len), 128 118 MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); 129 119 ms->len = p - ms->buf; 120 + 121 + WARN_ON(ms->len + sizeof(*ms) > 32768); 130 122 131 123 return nonseekable_open(inode, file); 132 124 }
+35
net/mac80211/rx.c
··· 1032 1032 ieee80211_is_pspoll(hdr->frame_control)) && 1033 1033 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && 1034 1034 rx->sdata->vif.type != NL80211_IFTYPE_WDS && 1035 + rx->sdata->vif.type != NL80211_IFTYPE_OCB && 1035 1036 (!rx->sta || !test_sta_flag(rx->sta, WLAN_STA_ASSOC)))) { 1036 1037 /* 1037 1038 * accept port control frames from the AP even when it's not ··· 1273 1272 sta->last_rx_rate_vht_nss = status->vht_nss; 1274 1273 } 1275 1274 } 1275 + } else if (rx->sdata->vif.type == NL80211_IFTYPE_OCB) { 1276 + u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, 1277 + NL80211_IFTYPE_OCB); 1278 + /* OCB uses wild-card BSSID */ 1279 + if (is_broadcast_ether_addr(bssid)) 1280 + sta->last_rx = jiffies; 1276 1281 } else if (!is_multicast_ether_addr(hdr->addr1)) { 1277 1282 /* 1278 1283 * Mesh beacons will update last_rx when if they are found to ··· 2827 2820 2828 2821 if (!ieee80211_vif_is_mesh(&sdata->vif) && 2829 2822 sdata->vif.type != NL80211_IFTYPE_ADHOC && 2823 + sdata->vif.type != NL80211_IFTYPE_OCB && 2830 2824 sdata->vif.type != NL80211_IFTYPE_STATION) 2831 2825 return RX_DROP_MONITOR; 2832 2826 ··· 3136 3128 rate_idx = status->rate_idx; 3137 3129 ieee80211_ibss_rx_no_sta(sdata, bssid, hdr->addr2, 3138 3130 BIT(rate_idx)); 3131 + } 3132 + break; 3133 + case NL80211_IFTYPE_OCB: 3134 + if (!bssid) 3135 + return false; 3136 + if (ieee80211_is_beacon(hdr->frame_control)) { 3137 + return false; 3138 + } else if (!is_broadcast_ether_addr(bssid)) { 3139 + ocb_dbg(sdata, "BSSID mismatch in OCB mode!\n"); 3140 + return false; 3141 + } else if (!multicast && 3142 + !ether_addr_equal(sdata->dev->dev_addr, 3143 + hdr->addr1)) { 3144 + /* if we are in promisc mode we also accept 3145 + * packets not destined for us 3146 + */ 3147 + if (!(sdata->dev->flags & IFF_PROMISC)) 3148 + return false; 3149 + rx->flags &= ~IEEE80211_RX_RA_MATCH; 3150 + } else if (!rx->sta) { 3151 + int rate_idx; 3152 + if (status->flag & RX_FLAG_HT) 3153 + rate_idx = 0; /* TODO: HT rates */ 3154 + else 3155 + rate_idx = status->rate_idx; 3156 + ieee80211_ocb_rx_no_sta(sdata, bssid, hdr->addr2, 3157 + BIT(rate_idx)); 3139 3158 } 3140 3159 break; 3141 3160 case NL80211_IFTYPE_MESH_POINT:
+2 -2
net/mac80211/sta_info.c
··· 501 501 /* make the station visible */ 502 502 sta_info_hash_add(local, sta); 503 503 504 - list_add_rcu(&sta->list, &local->sta_list); 504 + list_add_tail_rcu(&sta->list, &local->sta_list); 505 505 506 506 /* notify driver */ 507 507 err = sta_info_insert_drv_state(local, sdata, sta); ··· 1531 1531 break; 1532 1532 case 0: 1533 1533 /* XXX: what is a good value? */ 1534 - n_frames = 8; 1534 + n_frames = 128; 1535 1535 break; 1536 1536 } 1537 1537
+1
net/mac80211/sta_info.h
··· 336 336 * @known_smps_mode: the smps_mode the client thinks we are in. Relevant for 337 337 * AP only. 338 338 * @cipher_scheme: optional cipher scheme for this station 339 + * @last_tdls_pkt_time: holds the time in jiffies of last TDLS pkt ACKed 339 340 */ 340 341 struct sta_info { 341 342 /* General information, mostly static */
+2 -1
net/mac80211/status.c
··· 704 704 705 705 if ((sta->sdata->vif.type == NL80211_IFTYPE_STATION) && 706 706 (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) 707 - ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, acked); 707 + ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, 708 + acked, info->status.tx_time); 708 709 709 710 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { 710 711 if (info->flags & IEEE80211_TX_STAT_ACK) {
+6 -2
net/mac80211/tdls.c
··· 562 562 /* infer the initiator if we can, to support old userspace */ 563 563 switch (action_code) { 564 564 case WLAN_TDLS_SETUP_REQUEST: 565 - if (sta) 565 + if (sta) { 566 566 set_sta_flag(sta, WLAN_STA_TDLS_INITIATOR); 567 + sta->sta.tdls_initiator = false; 568 + } 567 569 /* fall-through */ 568 570 case WLAN_TDLS_SETUP_CONFIRM: 569 571 case WLAN_TDLS_DISCOVERY_REQUEST: ··· 577 575 * Make the last packet sent take effect for the initiator 578 576 * value. 579 577 */ 580 - if (sta) 578 + if (sta) { 581 579 clear_sta_flag(sta, WLAN_STA_TDLS_INITIATOR); 580 + sta->sta.tdls_initiator = true; 581 + } 582 582 /* fall-through */ 583 583 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 584 584 initiator = false;
+94 -6
net/mac80211/trace.h
··· 987 987 988 988 TRACE_EVENT(drv_channel_switch, 989 989 TP_PROTO(struct ieee80211_local *local, 990 + struct ieee80211_sub_if_data *sdata, 990 991 struct ieee80211_channel_switch *ch_switch), 991 992 992 - TP_ARGS(local, ch_switch), 993 + TP_ARGS(local, sdata, ch_switch), 993 994 994 995 TP_STRUCT__entry( 995 996 LOCAL_ENTRY 997 + VIF_ENTRY 996 998 CHANDEF_ENTRY 997 999 __field(u64, timestamp) 1000 + __field(u32, device_timestamp) 998 1001 __field(bool, block_tx) 999 1002 __field(u8, count) 1000 1003 ), 1001 1004 1002 1005 TP_fast_assign( 1003 1006 LOCAL_ASSIGN; 1007 + VIF_ASSIGN; 1004 1008 CHANDEF_ASSIGN(&ch_switch->chandef) 1005 1009 __entry->timestamp = ch_switch->timestamp; 1010 + __entry->device_timestamp = ch_switch->device_timestamp; 1006 1011 __entry->block_tx = ch_switch->block_tx; 1007 1012 __entry->count = ch_switch->count; 1008 1013 ), 1009 1014 1010 1015 TP_printk( 1011 - LOCAL_PR_FMT " new " CHANDEF_PR_FMT " count:%d", 1012 - LOCAL_PR_ARG, CHANDEF_PR_ARG, __entry->count 1016 + LOCAL_PR_FMT VIF_PR_FMT " new " CHANDEF_PR_FMT " count:%d", 1017 + LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count 1013 1018 ) 1014 1019 ); 1015 1020 ··· 1562 1557 TP_ARGS(local, sdata) 1563 1558 ); 1564 1559 1565 - DEFINE_EVENT(local_only_evt, drv_restart_complete, 1566 - TP_PROTO(struct ieee80211_local *local), 1567 - TP_ARGS(local) 1560 + TRACE_EVENT(drv_reconfig_complete, 1561 + TP_PROTO(struct ieee80211_local *local, 1562 + enum ieee80211_reconfig_type reconfig_type), 1563 + TP_ARGS(local, reconfig_type), 1564 + 1565 + TP_STRUCT__entry( 1566 + LOCAL_ENTRY 1567 + __field(u8, reconfig_type) 1568 + ), 1569 + 1570 + TP_fast_assign( 1571 + LOCAL_ASSIGN; 1572 + __entry->reconfig_type = reconfig_type; 1573 + ), 1574 + 1575 + TP_printk( 1576 + LOCAL_PR_FMT " reconfig_type:%d", 1577 + LOCAL_PR_ARG, __entry->reconfig_type 1578 + ) 1579 + 1568 1580 ); 1569 1581 1570 1582 #if IS_ENABLED(CONFIG_IPV6) ··· 2125 2103 TP_printk( 2126 2104 LOCAL_PR_FMT VIF_PR_FMT " channel switch to " CHANDEF_PR_FMT, 2127 2105 LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG 2106 + ) 2107 + ); 2108 + 2109 + TRACE_EVENT(drv_pre_channel_switch, 2110 + TP_PROTO(struct ieee80211_local *local, 2111 + struct ieee80211_sub_if_data *sdata, 2112 + struct ieee80211_channel_switch *ch_switch), 2113 + 2114 + TP_ARGS(local, sdata, ch_switch), 2115 + 2116 + TP_STRUCT__entry( 2117 + LOCAL_ENTRY 2118 + VIF_ENTRY 2119 + CHANDEF_ENTRY 2120 + __field(u64, timestamp) 2121 + __field(bool, block_tx) 2122 + __field(u8, count) 2123 + ), 2124 + 2125 + TP_fast_assign( 2126 + LOCAL_ASSIGN; 2127 + VIF_ASSIGN; 2128 + CHANDEF_ASSIGN(&ch_switch->chandef) 2129 + __entry->timestamp = ch_switch->timestamp; 2130 + __entry->block_tx = ch_switch->block_tx; 2131 + __entry->count = ch_switch->count; 2132 + ), 2133 + 2134 + TP_printk( 2135 + LOCAL_PR_FMT VIF_PR_FMT " prepare channel switch to " 2136 + CHANDEF_PR_FMT " count:%d block_tx:%d timestamp:%llu", 2137 + LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count, 2138 + __entry->block_tx, __entry->timestamp 2139 + ) 2140 + ); 2141 + 2142 + DEFINE_EVENT(local_sdata_evt, drv_post_channel_switch, 2143 + TP_PROTO(struct ieee80211_local *local, 2144 + struct ieee80211_sub_if_data *sdata), 2145 + TP_ARGS(local, sdata) 2146 + ); 2147 + 2148 + TRACE_EVENT(drv_get_txpower, 2149 + TP_PROTO(struct ieee80211_local *local, 2150 + struct ieee80211_sub_if_data *sdata, 2151 + int dbm, int ret), 2152 + 2153 + TP_ARGS(local, sdata, dbm, ret), 2154 + 2155 + TP_STRUCT__entry( 2156 + LOCAL_ENTRY 2157 + VIF_ENTRY 2158 + __field(int, dbm) 2159 + __field(int, ret) 2160 + ), 2161 + 2162 + TP_fast_assign( 2163 + LOCAL_ASSIGN; 2164 + VIF_ASSIGN; 2165 + __entry->dbm = dbm; 2166 + __entry->ret = ret; 2167 + ), 2168 + 2169 + TP_printk( 2170 + LOCAL_PR_FMT VIF_PR_FMT " dbm:%d ret:%d", 2171 + LOCAL_PR_ARG, VIF_PR_ARG, __entry->dbm, __entry->ret 2128 2172 ) 2129 2173 ); 2130 2174
+15
net/mac80211/tx.c
··· 296 296 */ 297 297 return TX_DROP; 298 298 299 + if (tx->sdata->vif.type == NL80211_IFTYPE_OCB) 300 + return TX_CONTINUE; 301 + 299 302 if (tx->sdata->vif.type == NL80211_IFTYPE_WDS) 300 303 return TX_CONTINUE; 301 304 ··· 2016 2013 goto fail_rcu; 2017 2014 band = chanctx_conf->def.chan->band; 2018 2015 break; 2016 + case NL80211_IFTYPE_OCB: 2017 + /* DA SA BSSID */ 2018 + memcpy(hdr.addr1, skb->data, ETH_ALEN); 2019 + memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); 2020 + eth_broadcast_addr(hdr.addr3); 2021 + hdrlen = 24; 2022 + chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2023 + if (!chanctx_conf) 2024 + goto fail_rcu; 2025 + band = chanctx_conf->def.chan->band; 2026 + break; 2019 2027 case NL80211_IFTYPE_ADHOC: 2020 2028 /* DA SA BSSID */ 2021 2029 memcpy(hdr.addr1, skb->data, ETH_ALEN); ··· 2071 2057 * EAPOL frames from the local station. 2072 2058 */ 2073 2059 if (unlikely(!ieee80211_vif_is_mesh(&sdata->vif) && 2060 + (sdata->vif.type != NL80211_IFTYPE_OCB) && 2074 2061 !multicast && !authorized && 2075 2062 (cpu_to_be16(ethertype) != sdata->control_port_protocol || 2076 2063 !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) {
+95 -37
net/mac80211/util.c
··· 693 693 } 694 694 EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_rtnl); 695 695 696 + static void __iterate_stations(struct ieee80211_local *local, 697 + void (*iterator)(void *data, 698 + struct ieee80211_sta *sta), 699 + void *data) 700 + { 701 + struct sta_info *sta; 702 + 703 + list_for_each_entry_rcu(sta, &local->sta_list, list) { 704 + if (!sta->uploaded) 705 + continue; 706 + 707 + iterator(data, &sta->sta); 708 + } 709 + } 710 + 711 + void ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw, 712 + void (*iterator)(void *data, 713 + struct ieee80211_sta *sta), 714 + void *data) 715 + { 716 + struct ieee80211_local *local = hw_to_local(hw); 717 + 718 + rcu_read_lock(); 719 + __iterate_stations(local, iterator, data); 720 + rcu_read_unlock(); 721 + } 722 + EXPORT_SYMBOL_GPL(ieee80211_iterate_stations_atomic); 723 + 696 724 struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev) 697 725 { 698 726 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); ··· 1101 1073 struct ieee80211_chanctx_conf *chanctx_conf; 1102 1074 int ac; 1103 1075 bool use_11b, enable_qos; 1076 + bool is_ocb; /* Use another EDCA parameters if dot11OCBActivated=true */ 1104 1077 int aCWmin, aCWmax; 1105 1078 1106 1079 if (!local->ops->conf_tx) ··· 1126 1097 */ 1127 1098 enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION); 1128 1099 1100 + is_ocb = (sdata->vif.type == NL80211_IFTYPE_OCB); 1101 + 1129 1102 /* Set defaults according to 802.11-2007 Table 7-37 */ 1130 1103 aCWmax = 1023; 1131 1104 if (use_11b) ··· 1149 1118 qparam.cw_max = aCWmax; 1150 1119 qparam.cw_min = aCWmin; 1151 1120 qparam.txop = 0; 1152 - qparam.aifs = 7; 1121 + if (is_ocb) 1122 + qparam.aifs = 9; 1123 + else 1124 + qparam.aifs = 7; 1153 1125 break; 1154 1126 /* never happens but let's not leave undefined */ 1155 1127 default: ··· 1160 1126 qparam.cw_max = aCWmax; 1161 1127 qparam.cw_min = aCWmin; 1162 1128 qparam.txop = 0; 1163 - qparam.aifs = 3; 1129 + if (is_ocb) 1130 + qparam.aifs = 6; 1131 + else 1132 + qparam.aifs = 3; 1164 1133 break; 1165 1134 case IEEE80211_AC_VI: 1166 1135 qparam.cw_max = aCWmin; 1167 1136 qparam.cw_min = (aCWmin + 1) / 2 - 1; 1168 - if (use_11b) 1137 + if (is_ocb) 1138 + qparam.txop = 0; 1139 + else if (use_11b) 1169 1140 qparam.txop = 6016/32; 1170 1141 else 1171 1142 qparam.txop = 3008/32; 1172 - qparam.aifs = 2; 1143 + 1144 + if (is_ocb) 1145 + qparam.aifs = 3; 1146 + else 1147 + qparam.aifs = 2; 1173 1148 break; 1174 1149 case IEEE80211_AC_VO: 1175 1150 qparam.cw_max = (aCWmin + 1) / 2 - 1; 1176 1151 qparam.cw_min = (aCWmin + 1) / 4 - 1; 1177 - if (use_11b) 1152 + if (is_ocb) 1153 + qparam.txop = 0; 1154 + else if (use_11b) 1178 1155 qparam.txop = 3264/32; 1179 1156 else 1180 1157 qparam.txop = 1504/32; ··· 1858 1813 ieee80211_bss_info_change_notify(sdata, changed); 1859 1814 sdata_unlock(sdata); 1860 1815 break; 1816 + case NL80211_IFTYPE_OCB: 1817 + changed |= BSS_CHANGED_OCB; 1818 + ieee80211_bss_info_change_notify(sdata, changed); 1819 + break; 1861 1820 case NL80211_IFTYPE_ADHOC: 1862 1821 changed |= BSS_CHANGED_IBSS; 1863 1822 /* fall through */ ··· 1998 1949 * We may want to change that later, however. 1999 1950 */ 2000 1951 if (!local->suspended || reconfig_due_to_wowlan) 2001 - drv_restart_complete(local); 1952 + drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_RESTART); 2002 1953 2003 1954 if (!local->suspended) 2004 1955 return 0; ··· 2008 1959 local->suspended = false; 2009 1960 mb(); 2010 1961 local->resuming = false; 1962 + 1963 + if (!reconfig_due_to_wowlan) 1964 + drv_reconfig_complete(local, IEEE80211_RECONFIG_TYPE_SUSPEND); 2011 1965 2012 1966 list_for_each_entry(sdata, &local->interfaces, list) { 2013 1967 if (!ieee80211_sdata_running(sdata)) ··· 2104 2052 return false; 2105 2053 } 2106 2054 2107 - /** 2108 - * ieee80211_ie_split - split an IE buffer according to ordering 2109 - * 2110 - * @ies: the IE buffer 2111 - * @ielen: the length of the IE buffer 2112 - * @ids: an array with element IDs that are allowed before 2113 - * the split 2114 - * @n_ids: the size of the element ID array 2115 - * @offset: offset where to start splitting in the buffer 2116 - * 2117 - * This function splits an IE buffer by updating the @offset 2118 - * variable to point to the location where the buffer should be 2119 - * split. 2120 - * 2121 - * It assumes that the given IE buffer is well-formed, this 2122 - * has to be guaranteed by the caller! 2123 - * 2124 - * It also assumes that the IEs in the buffer are ordered 2125 - * correctly, if not the result of using this function will not 2126 - * be ordered correctly either, i.e. it does no reordering. 2127 - * 2128 - * The function returns the offset where the next part of the 2129 - * buffer starts, which may be @ielen if the entire (remainder) 2130 - * of the buffer should be used. 2131 - */ 2132 - size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 2133 - const u8 *ids, int n_ids, size_t offset) 2055 + size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, 2056 + const u8 *ids, int n_ids, 2057 + const u8 *after_ric, int n_after_ric, 2058 + size_t offset) 2134 2059 { 2135 2060 size_t pos = offset; 2136 2061 2137 - while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) 2138 - pos += 2 + ies[pos + 1]; 2062 + while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) { 2063 + if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) { 2064 + pos += 2 + ies[pos + 1]; 2065 + 2066 + while (pos < ielen && 2067 + !ieee80211_id_in_list(after_ric, n_after_ric, 2068 + ies[pos])) 2069 + pos += 2 + ies[pos + 1]; 2070 + } else { 2071 + pos += 2 + ies[pos + 1]; 2072 + } 2073 + } 2139 2074 2140 2075 return pos; 2141 2076 } 2077 + 2078 + size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 2079 + const u8 *ids, int n_ids, size_t offset) 2080 + { 2081 + return ieee80211_ie_split_ric(ies, ielen, ids, n_ids, NULL, 0, offset); 2082 + } 2083 + EXPORT_SYMBOL(ieee80211_ie_split); 2142 2084 2143 2085 size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset) 2144 2086 { ··· 2572 2526 struct ieee80211_local *local = 2573 2527 container_of(work, struct ieee80211_local, radar_detected_work); 2574 2528 struct cfg80211_chan_def chandef = local->hw.conf.chandef; 2529 + struct ieee80211_chanctx *ctx; 2530 + int num_chanctx = 0; 2531 + 2532 + mutex_lock(&local->chanctx_mtx); 2533 + list_for_each_entry(ctx, &local->chanctx_list, list) { 2534 + if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) 2535 + continue; 2536 + 2537 + num_chanctx++; 2538 + chandef = ctx->conf.def; 2539 + } 2540 + mutex_unlock(&local->chanctx_mtx); 2575 2541 2576 2542 ieee80211_dfs_cac_cancel(local); 2577 2543 2578 - if (local->use_chanctx) 2579 - /* currently not handled */ 2544 + if (num_chanctx > 1) 2545 + /* XXX: multi-channel is not supported yet */ 2580 2546 WARN_ON(1); 2581 2547 else 2582 2548 cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
-2
net/mac80211/wep.c
··· 111 111 (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) 112 112 return newhdr + hdrlen; 113 113 114 - skb_set_network_header(skb, skb_network_offset(skb) + 115 - IEEE80211_WEP_IV_LEN); 116 114 ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); 117 115 return newhdr + hdrlen; 118 116 }
+24 -9
net/mac80211/wme.c
··· 54 54 } 55 55 56 56 static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, 57 - struct sk_buff *skb) 57 + struct sta_info *sta, struct sk_buff *skb) 58 58 { 59 + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 60 + 59 61 /* in case we are a client verify acm is not set for this ac */ 60 - while (unlikely(sdata->wmm_acm & BIT(skb->priority))) { 62 + while (sdata->wmm_acm & BIT(skb->priority)) { 63 + int ac = ieee802_1d_to_ac[skb->priority]; 64 + 65 + if (ifmgd->tx_tspec[ac].admitted_time && 66 + skb->priority == ifmgd->tx_tspec[ac].up) 67 + return ac; 68 + 61 69 if (wme_downgrade_ac(skb)) { 62 70 /* 63 71 * This should not really happen. The AP has marked all ··· 104 96 p = ieee80211_get_qos_ctl(hdr); 105 97 skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; 106 98 107 - return ieee80211_downgrade_queue(sdata, skb); 99 + return ieee80211_downgrade_queue(sdata, NULL, skb); 108 100 } 109 101 110 102 /* Indicate which queue to use. */ ··· 116 108 const u8 *ra = NULL; 117 109 bool qos = false; 118 110 struct mac80211_qos_map *qos_map; 111 + u16 ret; 119 112 120 113 if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { 121 114 skb->priority = 0; /* required for correct WPA/11i MIC */ ··· 148 139 case NL80211_IFTYPE_ADHOC: 149 140 ra = skb->data; 150 141 break; 142 + case NL80211_IFTYPE_OCB: 143 + /* all stations are required to support WME */ 144 + qos = true; 145 + break; 151 146 default: 152 147 break; 153 148 } ··· 161 148 if (sta) 162 149 qos = sta->sta.wme; 163 150 } 164 - rcu_read_unlock(); 165 151 166 152 if (!qos) { 167 153 skb->priority = 0; /* required for correct WPA/11i MIC */ 168 - return IEEE80211_AC_BE; 154 + ret = IEEE80211_AC_BE; 155 + goto out; 169 156 } 170 157 171 158 if (skb->protocol == sdata->control_port_protocol) { 172 159 skb->priority = 7; 173 - return ieee80211_downgrade_queue(sdata, skb); 160 + goto downgrade; 174 161 } 175 162 176 163 /* use the data classifier to determine what 802.1d tag the 177 164 * data frame has */ 178 - rcu_read_lock(); 179 165 qos_map = rcu_dereference(sdata->qos_map); 180 166 skb->priority = cfg80211_classify8021d(skb, qos_map ? 181 167 &qos_map->qos_map : NULL); 182 - rcu_read_unlock(); 183 168 184 - return ieee80211_downgrade_queue(sdata, skb); 169 + downgrade: 170 + ret = ieee80211_downgrade_queue(sdata, sta, skb); 171 + out: 172 + rcu_read_unlock(); 173 + return ret; 185 174 } 186 175 187 176 /**
-2
net/mac80211/wme.h
··· 13 13 #include <linux/netdevice.h> 14 14 #include "ieee80211_i.h" 15 15 16 - extern const int ieee802_1d_to_ac[8]; 17 - 18 16 u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, 19 17 struct sk_buff *skb, 20 18 struct ieee80211_hdr *hdr);
-5
net/mac80211/wpa.c
··· 209 209 210 210 pos = skb_push(skb, IEEE80211_TKIP_IV_LEN); 211 211 memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen); 212 - skb_set_network_header(skb, skb_network_offset(skb) + 213 - IEEE80211_TKIP_IV_LEN); 214 212 pos += hdrlen; 215 213 216 214 /* the HW only needs room for the IV, but not the actual IV */ ··· 432 434 433 435 pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN); 434 436 memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen); 435 - skb_set_network_header(skb, skb_network_offset(skb) + 436 - IEEE80211_CCMP_HDR_LEN); 437 437 438 438 /* the HW only needs room for the IV, but not the actual IV */ 439 439 if (info->control.hw_key && ··· 571 575 572 576 pos = skb_push(skb, cs->hdr_len); 573 577 memmove(pos, pos + cs->hdr_len, hdrlen); 574 - skb_set_network_header(skb, skb_network_offset(skb) + cs->hdr_len); 575 578 576 579 return TX_CONTINUE; 577 580 }
+1 -1
net/wireless/Makefile
··· 10 10 obj-$(CONFIG_WEXT_PRIV) += wext-priv.o 11 11 12 12 cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o 13 - cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o 13 + cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o 14 14 cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o 15 15 cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o 16 16 cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o
+9 -1
net/wireless/chan.c
··· 115 115 EXPORT_SYMBOL(cfg80211_chandef_valid); 116 116 117 117 static void chandef_primary_freqs(const struct cfg80211_chan_def *c, 118 - int *pri40, int *pri80) 118 + u32 *pri40, u32 *pri80) 119 119 { 120 120 int tmp; 121 121 ··· 366 366 367 367 break; 368 368 case NL80211_IFTYPE_STATION: 369 + case NL80211_IFTYPE_OCB: 369 370 case NL80211_IFTYPE_P2P_CLIENT: 370 371 case NL80211_IFTYPE_MONITOR: 371 372 case NL80211_IFTYPE_AP_VLAN: ··· 893 892 *radar_detect |= BIT(wdev->chandef.width); 894 893 } 895 894 return; 895 + case NL80211_IFTYPE_OCB: 896 + if (wdev->chandef.chan) { 897 + *chan = wdev->chandef.chan; 898 + *chanmode = CHAN_MODE_SHARED; 899 + return; 900 + } 901 + break; 896 902 case NL80211_IFTYPE_MONITOR: 897 903 case NL80211_IFTYPE_AP_VLAN: 898 904 case NL80211_IFTYPE_WDS:
+66 -13
net/wireless/core.c
··· 86 86 return &rdev->wiphy; 87 87 } 88 88 89 - int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, 90 - char *newname) 89 + static int cfg80211_dev_check_name(struct cfg80211_registered_device *rdev, 90 + const char *newname) 91 91 { 92 92 struct cfg80211_registered_device *rdev2; 93 - int wiphy_idx, taken = -1, result, digits; 93 + int wiphy_idx, taken = -1, digits; 94 94 95 95 ASSERT_RTNL(); 96 96 ··· 109 109 return -EINVAL; 110 110 } 111 111 112 - 113 - /* Ignore nop renames */ 114 - if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) 115 - return 0; 116 - 117 112 /* Ensure another device does not already have this name. */ 118 113 list_for_each_entry(rdev2, &cfg80211_rdev_list, list) 119 - if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) 114 + if (strcmp(newname, wiphy_name(&rdev2->wiphy)) == 0) 120 115 return -EINVAL; 116 + 117 + return 0; 118 + } 119 + 120 + int cfg80211_dev_rename(struct cfg80211_registered_device *rdev, 121 + char *newname) 122 + { 123 + int result; 124 + 125 + ASSERT_RTNL(); 126 + 127 + /* Ignore nop renames */ 128 + if (strcmp(newname, wiphy_name(&rdev->wiphy)) == 0) 129 + return 0; 130 + 131 + result = cfg80211_dev_check_name(rdev, newname); 132 + if (result < 0) 133 + return result; 121 134 122 135 result = device_rename(&rdev->wiphy.dev, newname); 123 136 if (result) ··· 322 309 323 310 /* exported functions */ 324 311 325 - struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) 312 + struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, 313 + const char *requested_name) 326 314 { 327 315 static atomic_t wiphy_counter = ATOMIC_INIT(0); 328 316 ··· 360 346 rdev->wiphy_idx--; 361 347 362 348 /* give it a proper name */ 363 - dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 349 + if (requested_name && requested_name[0]) { 350 + int rv; 351 + 352 + rtnl_lock(); 353 + rv = cfg80211_dev_check_name(rdev, requested_name); 354 + 355 + if (rv < 0) { 356 + rtnl_unlock(); 357 + goto use_default_name; 358 + } 359 + 360 + rv = dev_set_name(&rdev->wiphy.dev, "%s", requested_name); 361 + rtnl_unlock(); 362 + if (rv) 363 + goto use_default_name; 364 + } else { 365 + use_default_name: 366 + /* NOTE: This is *probably* safe w/out holding rtnl because of 367 + * the restrictions on phy names. Probably this call could 368 + * fail if some other part of the kernel (re)named a device 369 + * phyX. But, might should add some locking and check return 370 + * value, and use a different name if this one exists? 371 + */ 372 + dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 373 + } 364 374 365 375 INIT_LIST_HEAD(&rdev->wdev_list); 366 376 INIT_LIST_HEAD(&rdev->beacon_registrations); ··· 444 406 445 407 return &rdev->wiphy; 446 408 } 447 - EXPORT_SYMBOL(wiphy_new); 409 + EXPORT_SYMBOL(wiphy_new_nm); 448 410 449 411 static int wiphy_verify_combinations(struct wiphy *wiphy) 450 412 { ··· 869 831 case NL80211_IFTYPE_P2P_GO: 870 832 __cfg80211_stop_ap(rdev, dev, true); 871 833 break; 872 - default: 834 + case NL80211_IFTYPE_OCB: 835 + __cfg80211_leave_ocb(rdev, dev); 836 + break; 837 + case NL80211_IFTYPE_WDS: 838 + /* must be handled by mac80211/driver, has no APIs */ 839 + break; 840 + case NL80211_IFTYPE_P2P_DEVICE: 841 + /* cannot happen, has no netdev */ 842 + break; 843 + case NL80211_IFTYPE_AP_VLAN: 844 + case NL80211_IFTYPE_MONITOR: 845 + /* nothing to do */ 846 + break; 847 + case NL80211_IFTYPE_UNSPECIFIED: 848 + case NUM_NL80211_IFTYPES: 849 + /* invalid */ 873 850 break; 874 851 } 875 852 }
+12
net/wireless/core.h
··· 290 290 struct wireless_dev *wdev, 291 291 struct cfg80211_chan_def *chandef); 292 292 293 + /* OCB */ 294 + int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev, 295 + struct net_device *dev, 296 + struct ocb_setup *setup); 297 + int cfg80211_join_ocb(struct cfg80211_registered_device *rdev, 298 + struct net_device *dev, 299 + struct ocb_setup *setup); 300 + int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, 301 + struct net_device *dev); 302 + int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, 303 + struct net_device *dev); 304 + 293 305 /* AP */ 294 306 int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, 295 307 struct net_device *dev, bool notify);
+188 -18
net/wireless/nl80211.c
··· 884 884 if (!wdev->current_bss) 885 885 return -ENOLINK; 886 886 break; 887 - default: 887 + case NL80211_IFTYPE_UNSPECIFIED: 888 + case NL80211_IFTYPE_OCB: 889 + case NL80211_IFTYPE_MONITOR: 890 + case NL80211_IFTYPE_P2P_DEVICE: 891 + case NL80211_IFTYPE_WDS: 892 + case NUM_NL80211_IFTYPES: 888 893 return -EINVAL; 889 894 } 890 895 ··· 1519 1514 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) 1520 1515 CMD(channel_switch, CHANNEL_SWITCH); 1521 1516 CMD(set_qos_map, SET_QOS_MAP); 1522 - if (rdev->wiphy.flags & 1523 - WIPHY_FLAG_SUPPORTS_WMM_ADMISSION) 1517 + if (rdev->wiphy.features & 1518 + NL80211_FEATURE_SUPPORTS_WMM_ADMISSION) 1524 1519 CMD(add_tx_ts, ADD_TX_TS); 1525 1520 } 1526 1521 /* add into the if now */ ··· 2610 2605 !(rdev->wiphy.interface_modes & (1 << type))) 2611 2606 return -EOPNOTSUPP; 2612 2607 2613 - if (type == NL80211_IFTYPE_P2P_DEVICE && info->attrs[NL80211_ATTR_MAC]) { 2608 + if ((type == NL80211_IFTYPE_P2P_DEVICE || 2609 + rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) && 2610 + info->attrs[NL80211_ATTR_MAC]) { 2614 2611 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC], 2615 2612 ETH_ALEN); 2616 2613 if (!is_valid_ether_addr(params.macaddr)) ··· 4405 4398 { 4406 4399 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4407 4400 struct net_device *dev = info->user_ptr[1]; 4408 - u8 *mac_addr = NULL; 4401 + struct station_del_parameters params; 4402 + 4403 + memset(&params, 0, sizeof(params)); 4409 4404 4410 4405 if (info->attrs[NL80211_ATTR_MAC]) 4411 - mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 4406 + params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]); 4412 4407 4413 4408 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 4414 4409 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && ··· 4421 4412 if (!rdev->ops->del_station) 4422 4413 return -EOPNOTSUPP; 4423 4414 4424 - return rdev_del_station(rdev, dev, mac_addr); 4415 + if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) { 4416 + params.subtype = 4417 + nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]); 4418 + if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 && 4419 + params.subtype != IEEE80211_STYPE_DEAUTH >> 4) 4420 + return -EINVAL; 4421 + } else { 4422 + /* Default to Deauthentication frame */ 4423 + params.subtype = IEEE80211_STYPE_DEAUTH >> 4; 4424 + } 4425 + 4426 + if (info->attrs[NL80211_ATTR_REASON_CODE]) { 4427 + params.reason_code = 4428 + nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); 4429 + if (params.reason_code == 0) 4430 + return -EINVAL; /* 0 is reserved */ 4431 + } else { 4432 + /* Default to reason code 2 */ 4433 + params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID; 4434 + } 4435 + 4436 + return rdev_del_station(rdev, dev, &params); 4425 4437 } 4426 4438 4427 4439 static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, ··· 4652 4622 return -EOPNOTSUPP; 4653 4623 4654 4624 return rdev_del_mpath(rdev, dev, dst); 4625 + } 4626 + 4627 + static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info) 4628 + { 4629 + struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4630 + int err; 4631 + struct net_device *dev = info->user_ptr[1]; 4632 + struct mpath_info pinfo; 4633 + struct sk_buff *msg; 4634 + u8 *dst = NULL; 4635 + u8 mpp[ETH_ALEN]; 4636 + 4637 + memset(&pinfo, 0, sizeof(pinfo)); 4638 + 4639 + if (!info->attrs[NL80211_ATTR_MAC]) 4640 + return -EINVAL; 4641 + 4642 + dst = nla_data(info->attrs[NL80211_ATTR_MAC]); 4643 + 4644 + if (!rdev->ops->get_mpp) 4645 + return -EOPNOTSUPP; 4646 + 4647 + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) 4648 + return -EOPNOTSUPP; 4649 + 4650 + err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo); 4651 + if (err) 4652 + return err; 4653 + 4654 + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4655 + if (!msg) 4656 + return -ENOMEM; 4657 + 4658 + if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, 4659 + dev, dst, mpp, &pinfo) < 0) { 4660 + nlmsg_free(msg); 4661 + return -ENOBUFS; 4662 + } 4663 + 4664 + return genlmsg_reply(msg, info); 4665 + } 4666 + 4667 + static int nl80211_dump_mpp(struct sk_buff *skb, 4668 + struct netlink_callback *cb) 4669 + { 4670 + struct mpath_info pinfo; 4671 + struct cfg80211_registered_device *rdev; 4672 + struct wireless_dev *wdev; 4673 + u8 dst[ETH_ALEN]; 4674 + u8 mpp[ETH_ALEN]; 4675 + int path_idx = cb->args[2]; 4676 + int err; 4677 + 4678 + err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev); 4679 + if (err) 4680 + return err; 4681 + 4682 + if (!rdev->ops->dump_mpp) { 4683 + err = -EOPNOTSUPP; 4684 + goto out_err; 4685 + } 4686 + 4687 + if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) { 4688 + err = -EOPNOTSUPP; 4689 + goto out_err; 4690 + } 4691 + 4692 + while (1) { 4693 + err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst, 4694 + mpp, &pinfo); 4695 + if (err == -ENOENT) 4696 + break; 4697 + if (err) 4698 + goto out_err; 4699 + 4700 + if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, 4701 + cb->nlh->nlmsg_seq, NLM_F_MULTI, 4702 + wdev->netdev, dst, mpp, 4703 + &pinfo) < 0) 4704 + goto out; 4705 + 4706 + path_idx++; 4707 + } 4708 + 4709 + out: 4710 + cb->args[2] = path_idx; 4711 + err = skb->len; 4712 + out_err: 4713 + nl80211_finish_wdev_dump(rdev); 4714 + return err; 4655 4715 } 4656 4716 4657 4717 static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) ··· 6043 5923 * function is called under RTNL lock, so this should not be a problem. 6044 5924 */ 6045 5925 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1]; 6046 - u8 radar_detect_width = 0; 6047 5926 int err; 6048 5927 bool need_new_beacon = false; 6049 5928 int len, i; 5929 + u32 cs_count; 6050 5930 6051 5931 if (!rdev->ops->channel_switch || 6052 5932 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)) ··· 6083 5963 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES]) 6084 5964 return -EINVAL; 6085 5965 6086 - params.count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]); 5966 + /* Even though the attribute is u32, the specification says 5967 + * u8, so let's make sure we don't overflow. 5968 + */ 5969 + cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]); 5970 + if (cs_count > 255) 5971 + return -EINVAL; 5972 + 5973 + params.count = cs_count; 6087 5974 6088 5975 if (!need_new_beacon) 6089 5976 goto skip_beacons; ··· 6178 6051 if (err < 0) 6179 6052 return err; 6180 6053 6181 - if (err > 0) { 6182 - radar_detect_width = BIT(params.chandef.width); 6054 + if (err > 0) 6183 6055 params.radar_required = true; 6184 - } 6185 6056 6186 6057 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) 6187 6058 params.block_tx = true; ··· 8276 8151 return -EINVAL; 8277 8152 } 8278 8153 8154 + static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info) 8155 + { 8156 + struct cfg80211_registered_device *rdev = info->user_ptr[0]; 8157 + struct net_device *dev = info->user_ptr[1]; 8158 + struct ocb_setup setup = {}; 8159 + int err; 8160 + 8161 + err = nl80211_parse_chandef(rdev, info, &setup.chandef); 8162 + if (err) 8163 + return err; 8164 + 8165 + return cfg80211_join_ocb(rdev, dev, &setup); 8166 + } 8167 + 8168 + static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info) 8169 + { 8170 + struct cfg80211_registered_device *rdev = info->user_ptr[0]; 8171 + struct net_device *dev = info->user_ptr[1]; 8172 + 8173 + return cfg80211_leave_ocb(rdev, dev); 8174 + } 8175 + 8279 8176 static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) 8280 8177 { 8281 8178 struct cfg80211_registered_device *rdev = info->user_ptr[0]; ··· 9583 9436 u16 admitted_time = 0; 9584 9437 int err; 9585 9438 9586 - if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) 9439 + if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)) 9587 9440 return -EOPNOTSUPP; 9588 9441 9589 9442 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] || ··· 9599 9452 return -EINVAL; 9600 9453 9601 9454 /* WMM uses TIDs 0-7 even for TSPEC */ 9602 - if (tsid < IEEE80211_FIRST_TSPEC_TSID) { 9603 - if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) 9604 - return -EINVAL; 9605 - } else { 9455 + if (tsid >= IEEE80211_FIRST_TSPEC_TSID) { 9606 9456 /* TODO: handle 802.11 TSPEC/admission control 9607 - * need more attributes for that (e.g. BA session requirement) 9457 + * need more attributes for that (e.g. BA session requirement); 9458 + * change the WMM adminssion test above to allow both then 9608 9459 */ 9609 9460 return -EINVAL; 9610 9461 } ··· 9919 9774 NL80211_FLAG_NEED_RTNL, 9920 9775 }, 9921 9776 { 9777 + .cmd = NL80211_CMD_GET_MPP, 9778 + .doit = nl80211_get_mpp, 9779 + .dumpit = nl80211_dump_mpp, 9780 + .policy = nl80211_policy, 9781 + .flags = GENL_ADMIN_PERM, 9782 + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 9783 + NL80211_FLAG_NEED_RTNL, 9784 + }, 9785 + { 9922 9786 .cmd = NL80211_CMD_SET_MPATH, 9923 9787 .doit = nl80211_set_mpath, 9924 9788 .policy = nl80211_policy, ··· 10236 10082 { 10237 10083 .cmd = NL80211_CMD_LEAVE_MESH, 10238 10084 .doit = nl80211_leave_mesh, 10085 + .policy = nl80211_policy, 10086 + .flags = GENL_ADMIN_PERM, 10087 + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 10088 + NL80211_FLAG_NEED_RTNL, 10089 + }, 10090 + { 10091 + .cmd = NL80211_CMD_JOIN_OCB, 10092 + .doit = nl80211_join_ocb, 10093 + .policy = nl80211_policy, 10094 + .flags = GENL_ADMIN_PERM, 10095 + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 10096 + NL80211_FLAG_NEED_RTNL, 10097 + }, 10098 + { 10099 + .cmd = NL80211_CMD_LEAVE_OCB, 10100 + .doit = nl80211_leave_ocb, 10239 10101 .policy = nl80211_policy, 10240 10102 .flags = GENL_ADMIN_PERM, 10241 10103 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+88
net/wireless/ocb.c
··· 1 + /* 2 + * OCB mode implementation 3 + * 4 + * Copyright: (c) 2014 Czech Technical University in Prague 5 + * (c) 2014 Volkswagen Group Research 6 + * Author: Rostislav Lisovy <rostislav.lisovy@fel.cvut.cz> 7 + * Funded by: Volkswagen Group Research 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License version 2 as 11 + * published by the Free Software Foundation. 12 + */ 13 + 14 + #include <linux/ieee80211.h> 15 + #include <net/cfg80211.h> 16 + #include "nl80211.h" 17 + #include "core.h" 18 + #include "rdev-ops.h" 19 + 20 + int __cfg80211_join_ocb(struct cfg80211_registered_device *rdev, 21 + struct net_device *dev, 22 + struct ocb_setup *setup) 23 + { 24 + struct wireless_dev *wdev = dev->ieee80211_ptr; 25 + int err; 26 + 27 + ASSERT_WDEV_LOCK(wdev); 28 + 29 + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB) 30 + return -EOPNOTSUPP; 31 + 32 + if (WARN_ON(!setup->chandef.chan)) 33 + return -EINVAL; 34 + 35 + err = rdev_join_ocb(rdev, dev, setup); 36 + if (!err) 37 + wdev->chandef = setup->chandef; 38 + 39 + return err; 40 + } 41 + 42 + int cfg80211_join_ocb(struct cfg80211_registered_device *rdev, 43 + struct net_device *dev, 44 + struct ocb_setup *setup) 45 + { 46 + struct wireless_dev *wdev = dev->ieee80211_ptr; 47 + int err; 48 + 49 + wdev_lock(wdev); 50 + err = __cfg80211_join_ocb(rdev, dev, setup); 51 + wdev_unlock(wdev); 52 + 53 + return err; 54 + } 55 + 56 + int __cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, 57 + struct net_device *dev) 58 + { 59 + struct wireless_dev *wdev = dev->ieee80211_ptr; 60 + int err; 61 + 62 + ASSERT_WDEV_LOCK(wdev); 63 + 64 + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB) 65 + return -EOPNOTSUPP; 66 + 67 + if (!rdev->ops->leave_ocb) 68 + return -EOPNOTSUPP; 69 + 70 + err = rdev_leave_ocb(rdev, dev); 71 + if (!err) 72 + memset(&wdev->chandef, 0, sizeof(wdev->chandef)); 73 + 74 + return err; 75 + } 76 + 77 + int cfg80211_leave_ocb(struct cfg80211_registered_device *rdev, 78 + struct net_device *dev) 79 + { 80 + struct wireless_dev *wdev = dev->ieee80211_ptr; 81 + int err; 82 + 83 + wdev_lock(wdev); 84 + err = __cfg80211_leave_ocb(rdev, dev); 85 + wdev_unlock(wdev); 86 + 87 + return err; 88 + }
+51 -4
net/wireless/rdev-ops.h
··· 178 178 } 179 179 180 180 static inline int rdev_del_station(struct cfg80211_registered_device *rdev, 181 - struct net_device *dev, u8 *mac) 181 + struct net_device *dev, 182 + struct station_del_parameters *params) 182 183 { 183 184 int ret; 184 - trace_rdev_del_station(&rdev->wiphy, dev, mac); 185 - ret = rdev->ops->del_station(&rdev->wiphy, dev, mac); 185 + trace_rdev_del_station(&rdev->wiphy, dev, params); 186 + ret = rdev->ops->del_station(&rdev->wiphy, dev, params); 186 187 trace_rdev_return_int(&rdev->wiphy, ret); 187 188 return ret; 188 189 } ··· 264 263 265 264 } 266 265 266 + static inline int rdev_get_mpp(struct cfg80211_registered_device *rdev, 267 + struct net_device *dev, u8 *dst, u8 *mpp, 268 + struct mpath_info *pinfo) 269 + { 270 + int ret; 271 + 272 + trace_rdev_get_mpp(&rdev->wiphy, dev, dst, mpp); 273 + ret = rdev->ops->get_mpp(&rdev->wiphy, dev, dst, mpp, pinfo); 274 + trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); 275 + return ret; 276 + } 277 + 267 278 static inline int rdev_dump_mpath(struct cfg80211_registered_device *rdev, 268 279 struct net_device *dev, int idx, u8 *dst, 269 280 u8 *next_hop, struct mpath_info *pinfo) ··· 284 271 int ret; 285 272 trace_rdev_dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop); 286 273 ret = rdev->ops->dump_mpath(&rdev->wiphy, dev, idx, dst, next_hop, 287 - pinfo); 274 + pinfo); 275 + trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); 276 + return ret; 277 + } 278 + 279 + static inline int rdev_dump_mpp(struct cfg80211_registered_device *rdev, 280 + struct net_device *dev, int idx, u8 *dst, 281 + u8 *mpp, struct mpath_info *pinfo) 282 + 283 + { 284 + int ret; 285 + 286 + trace_rdev_dump_mpp(&rdev->wiphy, dev, idx, dst, mpp); 287 + ret = rdev->ops->dump_mpp(&rdev->wiphy, dev, idx, dst, mpp, pinfo); 288 288 trace_rdev_return_int_mpath_info(&rdev->wiphy, ret, pinfo); 289 289 return ret; 290 290 } ··· 344 318 int ret; 345 319 trace_rdev_leave_mesh(&rdev->wiphy, dev); 346 320 ret = rdev->ops->leave_mesh(&rdev->wiphy, dev); 321 + trace_rdev_return_int(&rdev->wiphy, ret); 322 + return ret; 323 + } 324 + 325 + static inline int rdev_join_ocb(struct cfg80211_registered_device *rdev, 326 + struct net_device *dev, 327 + struct ocb_setup *setup) 328 + { 329 + int ret; 330 + trace_rdev_join_ocb(&rdev->wiphy, dev, setup); 331 + ret = rdev->ops->join_ocb(&rdev->wiphy, dev, setup); 332 + trace_rdev_return_int(&rdev->wiphy, ret); 333 + return ret; 334 + } 335 + 336 + static inline int rdev_leave_ocb(struct cfg80211_registered_device *rdev, 337 + struct net_device *dev) 338 + { 339 + int ret; 340 + trace_rdev_leave_ocb(&rdev->wiphy, dev); 341 + ret = rdev->ops->leave_ocb(&rdev->wiphy, dev); 347 342 trace_rdev_return_int(&rdev->wiphy, ret); 348 343 return ret; 349 344 }
+11 -2
net/wireless/sme.c
··· 80 80 if (!request) 81 81 return -ENOMEM; 82 82 83 - if (wdev->conn->params.channel) 83 + if (wdev->conn->params.channel) { 84 + enum ieee80211_band band = wdev->conn->params.channel->band; 85 + struct ieee80211_supported_band *sband = 86 + wdev->wiphy->bands[band]; 87 + 88 + if (!sband) { 89 + kfree(request); 90 + return -EINVAL; 91 + } 84 92 request->channels[0] = wdev->conn->params.channel; 85 - else { 93 + request->rates[band] = (1 << sband->n_bitrates) - 1; 94 + } else { 86 95 int i = 0, j; 87 96 enum ieee80211_band band; 88 97 struct ieee80211_supported_band *bands;
+94 -3
net/wireless/trace.h
··· 600 600 TP_ARGS(wiphy, netdev) 601 601 ); 602 602 603 + DEFINE_EVENT(wiphy_netdev_evt, rdev_leave_ocb, 604 + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), 605 + TP_ARGS(wiphy, netdev) 606 + ); 607 + 603 608 DEFINE_EVENT(wiphy_netdev_evt, rdev_flush_pmksa, 604 609 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), 605 610 TP_ARGS(wiphy, netdev) ··· 685 680 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac)) 686 681 ); 687 682 688 - DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_del_station, 689 - TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, const u8 *mac), 690 - TP_ARGS(wiphy, netdev, mac) 683 + DECLARE_EVENT_CLASS(station_del, 684 + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, 685 + struct station_del_parameters *params), 686 + TP_ARGS(wiphy, netdev, params), 687 + TP_STRUCT__entry( 688 + WIPHY_ENTRY 689 + NETDEV_ENTRY 690 + MAC_ENTRY(sta_mac) 691 + __field(u8, subtype) 692 + __field(u16, reason_code) 693 + ), 694 + TP_fast_assign( 695 + WIPHY_ASSIGN; 696 + NETDEV_ASSIGN; 697 + MAC_ASSIGN(sta_mac, params->mac); 698 + __entry->subtype = params->subtype; 699 + __entry->reason_code = params->reason_code; 700 + ), 701 + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", station mac: " MAC_PR_FMT 702 + ", subtype: %u, reason_code: %u", 703 + WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(sta_mac), 704 + __entry->subtype, __entry->reason_code) 705 + ); 706 + 707 + DEFINE_EVENT(station_del, rdev_del_station, 708 + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, 709 + struct station_del_parameters *params), 710 + TP_ARGS(wiphy, netdev, params) 691 711 ); 692 712 693 713 DEFINE_EVENT(wiphy_netdev_mac_evt, rdev_get_station, ··· 829 799 MAC_PR_FMT ", next hop: " MAC_PR_FMT, 830 800 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), 831 801 MAC_PR_ARG(next_hop)) 802 + ); 803 + 804 + TRACE_EVENT(rdev_get_mpp, 805 + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, 806 + u8 *dst, u8 *mpp), 807 + TP_ARGS(wiphy, netdev, dst, mpp), 808 + TP_STRUCT__entry( 809 + WIPHY_ENTRY 810 + NETDEV_ENTRY 811 + MAC_ENTRY(dst) 812 + MAC_ENTRY(mpp) 813 + ), 814 + TP_fast_assign( 815 + WIPHY_ASSIGN; 816 + NETDEV_ASSIGN; 817 + MAC_ASSIGN(dst, dst); 818 + MAC_ASSIGN(mpp, mpp); 819 + ), 820 + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", destination: " MAC_PR_FMT 821 + ", mpp: " MAC_PR_FMT, WIPHY_PR_ARG, NETDEV_PR_ARG, 822 + MAC_PR_ARG(dst), MAC_PR_ARG(mpp)) 823 + ); 824 + 825 + TRACE_EVENT(rdev_dump_mpp, 826 + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int idx, 827 + u8 *dst, u8 *mpp), 828 + TP_ARGS(wiphy, netdev, idx, mpp, dst), 829 + TP_STRUCT__entry( 830 + WIPHY_ENTRY 831 + NETDEV_ENTRY 832 + MAC_ENTRY(dst) 833 + MAC_ENTRY(mpp) 834 + __field(int, idx) 835 + ), 836 + TP_fast_assign( 837 + WIPHY_ASSIGN; 838 + NETDEV_ASSIGN; 839 + MAC_ASSIGN(dst, dst); 840 + MAC_ASSIGN(mpp, mpp); 841 + __entry->idx = idx; 842 + ), 843 + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", index: %d, destination: " 844 + MAC_PR_FMT ", mpp: " MAC_PR_FMT, 845 + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->idx, MAC_PR_ARG(dst), 846 + MAC_PR_ARG(mpp)) 832 847 ); 833 848 834 849 TRACE_EVENT(rdev_return_int_mpath_info, ··· 1319 1244 ), 1320 1245 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT ", ssid: %s", 1321 1246 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(bssid), __entry->ssid) 1247 + ); 1248 + 1249 + TRACE_EVENT(rdev_join_ocb, 1250 + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, 1251 + const struct ocb_setup *setup), 1252 + TP_ARGS(wiphy, netdev, setup), 1253 + TP_STRUCT__entry( 1254 + WIPHY_ENTRY 1255 + NETDEV_ENTRY 1256 + ), 1257 + TP_fast_assign( 1258 + WIPHY_ASSIGN; 1259 + NETDEV_ASSIGN; 1260 + ), 1261 + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT, 1262 + WIPHY_PR_ARG, NETDEV_PR_ARG) 1322 1263 ); 1323 1264 1324 1265 TRACE_EVENT(rdev_set_wiphy_params,
+4 -1
net/wireless/util.c
··· 442 442 break; 443 443 case cpu_to_le16(0): 444 444 if (iftype != NL80211_IFTYPE_ADHOC && 445 - iftype != NL80211_IFTYPE_STATION) 445 + iftype != NL80211_IFTYPE_STATION && 446 + iftype != NL80211_IFTYPE_OCB) 446 447 return -1; 447 448 break; 448 449 } ··· 520 519 memcpy(hdr.addr3, skb->data, ETH_ALEN); 521 520 hdrlen = 24; 522 521 break; 522 + case NL80211_IFTYPE_OCB: 523 523 case NL80211_IFTYPE_ADHOC: 524 524 /* DA SA BSSID */ 525 525 memcpy(hdr.addr1, skb->data, ETH_ALEN); ··· 939 937 if (dev->ieee80211_ptr->use_4addr) 940 938 break; 941 939 /* fall through */ 940 + case NL80211_IFTYPE_OCB: 942 941 case NL80211_IFTYPE_P2P_CLIENT: 943 942 case NL80211_IFTYPE_ADHOC: 944 943 dev->priv_flags |= IFF_DONT_BRIDGE;