aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJanusz.Dziedzic@tieto.com <Janusz.Dziedzic@tieto.com>2015-03-09 02:58:15 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-03-17 06:06:53 -0400
commit8a4988d13734f9340ba8b34467d8ea09347b55d5 (patch)
tree85c2604e2884ebae03033b5ca63cf192906ce5ef
parentd66c258278fde25b0454ba0f9ec24874237d6ac5 (diff)
mac80211: IBSS: refactor ieee80211_rx_bss_info
Put station specific code in ieee80211_update_sta_info function. Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/ibss.c184
1 files changed, 99 insertions, 85 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index ee93d7d9aa4b..dec24d436e73 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -965,110 +965,124 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
965 mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0, 0); 965 mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0, 0);
966} 966}
967 967
968static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 968static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
969 struct ieee80211_mgmt *mgmt, size_t len, 969 struct ieee80211_mgmt *mgmt, size_t len,
970 struct ieee80211_rx_status *rx_status, 970 struct ieee80211_rx_status *rx_status,
971 struct ieee802_11_elems *elems) 971 struct ieee802_11_elems *elems,
972 struct ieee80211_channel *channel)
972{ 973{
973 struct ieee80211_local *local = sdata->local;
974 struct cfg80211_bss *cbss;
975 struct ieee80211_bss *bss;
976 struct sta_info *sta; 974 struct sta_info *sta;
977 struct ieee80211_channel *channel;
978 u64 beacon_timestamp, rx_timestamp;
979 u32 supp_rates = 0;
980 enum ieee80211_band band = rx_status->band; 975 enum ieee80211_band band = rx_status->band;
981 enum nl80211_bss_scan_width scan_width; 976 enum nl80211_bss_scan_width scan_width;
977 struct ieee80211_local *local = sdata->local;
982 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; 978 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
983 bool rates_updated = false; 979 bool rates_updated = false;
980 u32 supp_rates = 0;
984 981
985 channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq); 982 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
986 if (!channel)
987 return; 983 return;
988 984
989 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && 985 if (!ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid))
990 ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid)) { 986 return;
991 987
992 rcu_read_lock(); 988 rcu_read_lock();
993 sta = sta_info_get(sdata, mgmt->sa); 989 sta = sta_info_get(sdata, mgmt->sa);
994 990
995 if (elems->supp_rates) { 991 if (elems->supp_rates) {
996 supp_rates = ieee80211_sta_get_rates(sdata, elems, 992 supp_rates = ieee80211_sta_get_rates(sdata, elems,
997 band, NULL); 993 band, NULL);
998 if (sta) { 994 if (sta) {
999 u32 prev_rates; 995 u32 prev_rates;
1000 996
1001 prev_rates = sta->sta.supp_rates[band]; 997 prev_rates = sta->sta.supp_rates[band];
1002 /* make sure mandatory rates are always added */ 998 /* make sure mandatory rates are always added */
1003 scan_width = NL80211_BSS_CHAN_WIDTH_20; 999 scan_width = NL80211_BSS_CHAN_WIDTH_20;
1004 if (rx_status->flag & RX_FLAG_5MHZ) 1000 if (rx_status->flag & RX_FLAG_5MHZ)
1005 scan_width = NL80211_BSS_CHAN_WIDTH_5; 1001 scan_width = NL80211_BSS_CHAN_WIDTH_5;
1006 if (rx_status->flag & RX_FLAG_10MHZ) 1002 if (rx_status->flag & RX_FLAG_10MHZ)
1007 scan_width = NL80211_BSS_CHAN_WIDTH_10; 1003 scan_width = NL80211_BSS_CHAN_WIDTH_10;
1008 1004
1009 sta->sta.supp_rates[band] = supp_rates | 1005 sta->sta.supp_rates[band] = supp_rates |
1010 ieee80211_mandatory_rates(sband, 1006 ieee80211_mandatory_rates(sband, scan_width);
1011 scan_width); 1007 if (sta->sta.supp_rates[band] != prev_rates) {
1012 if (sta->sta.supp_rates[band] != prev_rates) { 1008 ibss_dbg(sdata,
1013 ibss_dbg(sdata, 1009 "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n",
1014 "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", 1010 sta->sta.addr, prev_rates,
1015 sta->sta.addr, prev_rates, 1011 sta->sta.supp_rates[band]);
1016 sta->sta.supp_rates[band]); 1012 rates_updated = true;
1017 rates_updated = true;
1018 }
1019 } else {
1020 rcu_read_unlock();
1021 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
1022 mgmt->sa, supp_rates);
1023 } 1013 }
1014 } else {
1015 rcu_read_unlock();
1016 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
1017 mgmt->sa, supp_rates);
1024 } 1018 }
1019 }
1025 1020
1026 if (sta && elems->wmm_info) 1021 if (sta && elems->wmm_info)
1027 sta->sta.wme = true; 1022 sta->sta.wme = true;
1028
1029 if (sta && elems->ht_operation && elems->ht_cap_elem &&
1030 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
1031 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 &&
1032 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) {
1033 /* we both use HT */
1034 struct ieee80211_ht_cap htcap_ie;
1035 struct cfg80211_chan_def chandef;
1036
1037 ieee80211_ht_oper_to_chandef(channel,
1038 elems->ht_operation,
1039 &chandef);
1040
1041 memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie));
1042
1043 /*
1044 * fall back to HT20 if we don't use or use
1045 * the other extension channel
1046 */
1047 if (chandef.center_freq1 !=
1048 sdata->u.ibss.chandef.center_freq1)
1049 htcap_ie.cap_info &=
1050 cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40);
1051
1052 rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(
1053 sdata, sband, &htcap_ie, sta);
1054 }
1055 1023
1056 if (sta && rates_updated) { 1024 if (sta && elems->ht_operation && elems->ht_cap_elem &&
1057 u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED; 1025 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
1058 u8 rx_nss = sta->sta.rx_nss; 1026 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 &&
1027 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) {
1028 /* we both use HT */
1029 struct ieee80211_ht_cap htcap_ie;
1030 struct cfg80211_chan_def chandef;
1059 1031
1060 /* Force rx_nss recalculation */ 1032 ieee80211_ht_oper_to_chandef(channel,
1061 sta->sta.rx_nss = 0; 1033 elems->ht_operation,
1062 rate_control_rate_init(sta); 1034 &chandef);
1063 if (sta->sta.rx_nss != rx_nss)
1064 changed |= IEEE80211_RC_NSS_CHANGED;
1065 1035
1066 drv_sta_rc_update(local, sdata, &sta->sta, changed); 1036 memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie));
1067 }
1068 1037
1069 rcu_read_unlock(); 1038 /*
1039 * fall back to HT20 if we don't use or use
1040 * the other extension channel
1041 */
1042 if (chandef.center_freq1 != sdata->u.ibss.chandef.center_freq1)
1043 htcap_ie.cap_info &=
1044 cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40);
1045
1046 rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
1047 &htcap_ie,
1048 sta);
1070 } 1049 }
1071 1050
1051 if (sta && rates_updated) {
1052 u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED;
1053 u8 rx_nss = sta->sta.rx_nss;
1054
1055 /* Force rx_nss recalculation */
1056 sta->sta.rx_nss = 0;
1057 rate_control_rate_init(sta);
1058 if (sta->sta.rx_nss != rx_nss)
1059 changed |= IEEE80211_RC_NSS_CHANGED;
1060
1061 drv_sta_rc_update(local, sdata, &sta->sta, changed);
1062 }
1063
1064 rcu_read_unlock();
1065}
1066
1067static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1068 struct ieee80211_mgmt *mgmt, size_t len,
1069 struct ieee80211_rx_status *rx_status,
1070 struct ieee802_11_elems *elems)
1071{
1072 struct ieee80211_local *local = sdata->local;
1073 struct cfg80211_bss *cbss;
1074 struct ieee80211_bss *bss;
1075 struct ieee80211_channel *channel;
1076 u64 beacon_timestamp, rx_timestamp;
1077 u32 supp_rates = 0;
1078 enum ieee80211_band band = rx_status->band;
1079
1080 channel = ieee80211_get_channel(local->hw.wiphy, rx_status->freq);
1081 if (!channel)
1082 return;
1083
1084 ieee80211_update_sta_info(sdata, mgmt, len, rx_status, elems, channel);
1085
1072 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, 1086 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
1073 channel); 1087 channel);
1074 if (!bss) 1088 if (!bss)