diff options
author | Janusz.Dziedzic@tieto.com <Janusz.Dziedzic@tieto.com> | 2015-03-09 02:58:15 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2015-03-17 06:06:53 -0400 |
commit | 8a4988d13734f9340ba8b34467d8ea09347b55d5 (patch) | |
tree | 85c2604e2884ebae03033b5ca63cf192906ce5ef | |
parent | d66c258278fde25b0454ba0f9ec24874237d6ac5 (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.c | 184 |
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 | ||
968 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 968 | static 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 | |||
1067 | static 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) |