| .. | .. |
|---|
| 241 | 241 | */ |
|---|
| 242 | 242 | REG_RULE(2484-10, 2484+10, 20, 6, 20, 0), |
|---|
| 243 | 243 | /* IEEE 802.11a, channel 36..64 */ |
|---|
| 244 | | - REG_RULE(5150-10, 5350+10, 40, 6, 20, 0), |
|---|
| 244 | + REG_RULE(5150-10, 5350+10, 80, 6, 20, 0), |
|---|
| 245 | 245 | /* IEEE 802.11a, channel 100..165 */ |
|---|
| 246 | | - REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), |
|---|
| 246 | + REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), |
|---|
| 247 | 247 | #ifdef WL_6G_BAND |
|---|
| 248 | 248 | REG_RULE(6025-80, 6985+80, 160, 6, 20, 0), |
|---|
| 249 | 249 | REG_RULE(5935-10, 7115+10, 20, 6, 20, 0), |
|---|
| .. | .. |
|---|
| 1089 | 1089 | }; |
|---|
| 1090 | 1090 | #endif /* CFG80211_6G_SUPPORT */ |
|---|
| 1091 | 1091 | |
|---|
| 1092 | +#ifdef WL_CAP_HE |
|---|
| 1093 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) || defined(CONFIG_6GHZ_BKPORT) |
|---|
| 1094 | +static struct ieee80211_sband_iftype_data __wl_he_cap = { |
|---|
| 1095 | + .types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP), |
|---|
| 1096 | + .he_cap = { |
|---|
| 1097 | + .has_he = true, |
|---|
| 1098 | + .he_cap_elem = { |
|---|
| 1099 | + .mac_cap_info[0] = (IEEE80211_HE_MAC_CAP0_HTC_HE | |
|---|
| 1100 | + IEEE80211_HE_MAC_CAP0_TWT_REQ), |
|---|
| 1101 | + .mac_cap_info[1] = IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US, |
|---|
| 1102 | + .mac_cap_info[2] = IEEE80211_HE_MAC_CAP2_BSR, |
|---|
| 1103 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)) |
|---|
| 1104 | + .mac_cap_info[5] = IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX, |
|---|
| 1105 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) */ |
|---|
| 1106 | + |
|---|
| 1107 | + .phy_cap_info[0] = |
|---|
| 1108 | + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | |
|---|
| 1109 | + IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G, |
|---|
| 1110 | + .phy_cap_info[1] = |
|---|
| 1111 | + IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A | |
|---|
| 1112 | + IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD, |
|---|
| 1113 | + .phy_cap_info[2] = |
|---|
| 1114 | + IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US, |
|---|
| 1115 | + .phy_cap_info[3] = |
|---|
| 1116 | + IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER, |
|---|
| 1117 | + .phy_cap_info[4] = |
|---|
| 1118 | + IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | |
|---|
| 1119 | + IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK | |
|---|
| 1120 | + IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4, |
|---|
| 1121 | + .phy_cap_info[5] = |
|---|
| 1122 | + IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2, |
|---|
| 1123 | + .phy_cap_info[6] = |
|---|
| 1124 | + IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU | |
|---|
| 1125 | + IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU | |
|---|
| 1126 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)) |
|---|
| 1127 | + IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB | |
|---|
| 1128 | + IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB | |
|---|
| 1129 | +#else |
|---|
| 1130 | + IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB | |
|---|
| 1131 | + IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB | |
|---|
| 1132 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) */ |
|---|
| 1133 | + IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB | |
|---|
| 1134 | + IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, |
|---|
| 1135 | + .phy_cap_info[7] = |
|---|
| 1136 | + IEEE80211_HE_PHY_CAP7_MAX_NC_1, |
|---|
| 1137 | + .phy_cap_info[8] = |
|---|
| 1138 | + IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU | |
|---|
| 1139 | + IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU, |
|---|
| 1140 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) |
|---|
| 1141 | + .phy_cap_info[9] = |
|---|
| 1142 | + IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU | |
|---|
| 1143 | + IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU, |
|---|
| 1144 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) */ |
|---|
| 1145 | + }, |
|---|
| 1146 | + .he_mcs_nss_supp = { |
|---|
| 1147 | + .rx_mcs_80 = cpu_to_le16(0xfffa), |
|---|
| 1148 | + .tx_mcs_80 = cpu_to_le16(0xfffa), |
|---|
| 1149 | + .rx_mcs_160 = cpu_to_le16((0xfffa)), |
|---|
| 1150 | + .tx_mcs_160 = cpu_to_le16((0xfffa)), |
|---|
| 1151 | + } |
|---|
| 1152 | + }, |
|---|
| 1153 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)) |
|---|
| 1154 | + .he_6ghz_capa = {.capa = cpu_to_le16(0x3038)}, |
|---|
| 1155 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0) */ |
|---|
| 1156 | +}; |
|---|
| 1157 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) */ |
|---|
| 1158 | +#endif /* WL_CAP_HE */ |
|---|
| 1159 | + |
|---|
| 1092 | 1160 | static struct ieee80211_supported_band __wl_band_2ghz = { |
|---|
| 1093 | 1161 | .band = IEEE80211_BAND_2GHZ, |
|---|
| 1094 | 1162 | .channels = __wl_2ghz_channels, |
|---|
| 1095 | 1163 | .n_channels = ARRAY_SIZE(__wl_2ghz_channels), |
|---|
| 1096 | 1164 | .bitrates = wl_g_rates, |
|---|
| 1097 | | - .n_bitrates = wl_g_rates_size |
|---|
| 1165 | + .n_bitrates = wl_g_rates_size, |
|---|
| 1166 | +#ifdef WL_CAP_HE |
|---|
| 1167 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) || defined(CONFIG_6GHZ_BKPORT) |
|---|
| 1168 | + .iftype_data = &__wl_he_cap, |
|---|
| 1169 | + .n_iftype_data = 1 |
|---|
| 1170 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) */ |
|---|
| 1171 | +#endif /* WL_CAP_HE */ |
|---|
| 1098 | 1172 | }; |
|---|
| 1099 | 1173 | |
|---|
| 1100 | 1174 | static struct ieee80211_supported_band __wl_band_5ghz_a = { |
|---|
| .. | .. |
|---|
| 1102 | 1176 | .channels = __wl_5ghz_a_channels, |
|---|
| 1103 | 1177 | .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels), |
|---|
| 1104 | 1178 | .bitrates = wl_a_rates, |
|---|
| 1105 | | - .n_bitrates = wl_a_rates_size |
|---|
| 1179 | + .n_bitrates = wl_a_rates_size, |
|---|
| 1180 | +#ifdef WL_CAP_HE |
|---|
| 1181 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) || defined(CONFIG_6GHZ_BKPORT) |
|---|
| 1182 | + .iftype_data = &__wl_he_cap, |
|---|
| 1183 | + .n_iftype_data = 1 |
|---|
| 1184 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) */ |
|---|
| 1185 | +#endif /* WL_CAP_HE */ |
|---|
| 1106 | 1186 | }; |
|---|
| 1107 | 1187 | |
|---|
| 1108 | 1188 | #ifdef CFG80211_6G_SUPPORT |
|---|
| .. | .. |
|---|
| 1111 | 1191 | .channels = __wl_6ghz_channels, |
|---|
| 1112 | 1192 | .n_channels = ARRAY_SIZE(__wl_6ghz_channels), |
|---|
| 1113 | 1193 | .bitrates = wl_a_rates, |
|---|
| 1114 | | - .n_bitrates = wl_a_rates_size |
|---|
| 1194 | + .n_bitrates = wl_a_rates_size, |
|---|
| 1195 | +#ifdef WL_CAP_HE |
|---|
| 1196 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) || defined(CONFIG_6GHZ_BKPORT) |
|---|
| 1197 | + .iftype_data = &__wl_he_cap, |
|---|
| 1198 | + .n_iftype_data = 1 |
|---|
| 1199 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) */ |
|---|
| 1200 | +#endif /* WL_CAP_HE */ |
|---|
| 1115 | 1201 | }; |
|---|
| 1116 | 1202 | #endif /* CFG80211_6G_SUPPORT */ |
|---|
| 1117 | 1203 | |
|---|
| .. | .. |
|---|
| 6556 | 6642 | } |
|---|
| 6557 | 6643 | if (conn_in_progress || connected || |
|---|
| 6558 | 6644 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) || defined(CFG80211_BKPORT_MLO) |
|---|
| 6559 | | - wdev->u.client.ssid_len |
|---|
| 6645 | + wdev->u.client.ssid_len) |
|---|
| 6560 | 6646 | #else |
|---|
| 6561 | | - wdev->ssid_len |
|---|
| 6562 | | -#endif |
|---|
| 6563 | | - ) { |
|---|
| 6647 | + wdev->ssid_len) |
|---|
| 6648 | +#endif /* CFG80211_BKPORT_MLO */ |
|---|
| 6649 | + { |
|---|
| 6564 | 6650 | #ifdef WL_EXT_IAPSTA |
|---|
| 6565 | 6651 | wl_ext_in4way_sync(dev, 0, WL_EXT_STATUS_PRE_DISCONNECTING, NULL); |
|---|
| 6566 | 6652 | #endif |
|---|
| .. | .. |
|---|
| 6607 | 6693 | * disassoc indicates state mismatch with upper layer. Check for state |
|---|
| 6608 | 6694 | * and issue disconnect indication if required. |
|---|
| 6609 | 6695 | */ |
|---|
| 6610 | | - |
|---|
| 6611 | 6696 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) || defined(CFG80211_BKPORT_MLO) |
|---|
| 6612 | | - // terence 20220911: fix me |
|---|
| 6613 | | - if (wdev->links[0].client.current_bss || wdev->u.client.ssid_len) |
|---|
| 6697 | + if (wdev->connected || wdev->u.client.ssid_len) |
|---|
| 6614 | 6698 | #else |
|---|
| 6615 | 6699 | if (wdev->current_bss || wdev->ssid_len) |
|---|
| 6616 | | -#endif |
|---|
| 6700 | +#endif /* CFG80211_BKPORT_MLO */ |
|---|
| 6617 | 6701 | { |
|---|
| 6618 | 6702 | WL_INFORM_MEM(("report disconnect event\n")); |
|---|
| 6619 | 6703 | CFG80211_DISCONNECTED(dev, 0, NULL, 0, false, GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 10183 | 10267 | chan = &band->channels[idx]; |
|---|
| 10184 | 10268 | /* Setting current channel to the requested channel */ |
|---|
| 10185 | 10269 | if ((err = wl_cfg80211_set_channel(wiphy, ndev, chan, |
|---|
| 10186 | | - NL80211_CHAN_HT20) < 0)) { |
|---|
| 10270 | + NL80211_CHAN_WIDTH_20) < 0)) { |
|---|
| 10187 | 10271 | /* |
|---|
| 10188 | 10272 | * FIXME: |
|---|
| 10189 | 10273 | * |
|---|
| .. | .. |
|---|
| 13033 | 13117 | ndev = cfgdev_to_wlc_ndev(cfgdev, cfg); |
|---|
| 13034 | 13118 | if (ndev) { |
|---|
| 13035 | 13119 | wdev = ndev->ieee80211_ptr; |
|---|
| 13120 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) || defined(CFG80211_BKPORT_MLO) |
|---|
| 13121 | + wdev->u.client.ssid_len = |
|---|
| 13122 | + min(ssid->SSID_len, (uint32)DOT11_MAX_SSID_LEN); |
|---|
| 13123 | + memcpy(wdev->u.client.ssid, ssid->SSID, wdev->u.client.ssid_len); |
|---|
| 13124 | +#else |
|---|
| 13036 | 13125 | wdev->ssid_len = min(ssid->SSID_len, (uint32)DOT11_MAX_SSID_LEN); |
|---|
| 13037 | 13126 | memcpy(wdev->ssid, ssid->SSID, wdev->ssid_len); |
|---|
| 13127 | +#endif /* CFG80211_BKPORT_MLO */ |
|---|
| 13038 | 13128 | WL_ERR(("SSID is %s\n", ssid->SSID)); |
|---|
| 13039 | 13129 | wl_update_prof(cfg, ndev, NULL, ssid, WL_PROF_SSID); |
|---|
| 13040 | 13130 | } else { |
|---|
| .. | .. |
|---|
| 13732 | 13822 | (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)) || \ |
|---|
| 13733 | 13823 | defined(WL_FILS_ROAM_OFFLD) || defined(CFG80211_ROAM_API_GE_4_12) |
|---|
| 13734 | 13824 | memset(&roam_info, 0, sizeof(struct cfg80211_roam_info)); |
|---|
| 13735 | | -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) || defined(CFG80211_BKPORT_MLO) |
|---|
| 13825 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(CFG80211_BKPORT_MLO) |
|---|
| 13736 | 13826 | roam_info.links[0].channel = notify_channel; |
|---|
| 13737 | 13827 | roam_info.links[0].bssid = curbssid; |
|---|
| 13738 | 13828 | #else |
|---|
| 13739 | 13829 | roam_info.channel = notify_channel; |
|---|
| 13740 | 13830 | roam_info.bssid = curbssid; |
|---|
| 13741 | | -#endif |
|---|
| 13831 | +#endif /* CFG80211_BKPORT_MLO */ |
|---|
| 13742 | 13832 | roam_info.req_ie = conn_info->req_ie; |
|---|
| 13743 | 13833 | roam_info.req_ie_len = conn_info->req_ie_len; |
|---|
| 13744 | 13834 | roam_info.resp_ie = conn_info->resp_ie; |
|---|
| .. | .. |
|---|
| 13935 | 14025 | |
|---|
| 13936 | 14026 | resp_params = (struct cfg80211_connect_resp_params *)params; |
|---|
| 13937 | 14027 | resp_params->status = status; |
|---|
| 13938 | | -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) || defined(CFG80211_BKPORT_MLO) |
|---|
| 14028 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(CFG80211_BKPORT_MLO) |
|---|
| 13939 | 14029 | resp_params->links[0].bssid = curbssid; |
|---|
| 13940 | 14030 | resp_params->links[0].bss = CFG80211_GET_BSS(wiphy, NULL, curbssid, |
|---|
| 13941 | 14031 | ssid->SSID, ssid->SSID_len); |
|---|
| .. | .. |
|---|
| 13944 | 14034 | resp_params->bss = CFG80211_GET_BSS(wiphy, NULL, curbssid, |
|---|
| 13945 | 14035 | ssid->SSID, ssid->SSID_len); |
|---|
| 13946 | 14036 | #endif |
|---|
| 13947 | | -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) || defined(CFG80211_BKPORT_MLO) |
|---|
| 14037 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) || defined(CFG80211_BKPORT_MLO) |
|---|
| 13948 | 14038 | if (!resp_params->links[0].bss) |
|---|
| 13949 | 14039 | #else |
|---|
| 13950 | 14040 | if (!resp_params->bss) |
|---|
| 13951 | | -#endif |
|---|
| 14041 | +#endif /* CFG80211_BKPORT_MLO */ |
|---|
| 13952 | 14042 | { |
|---|
| 13953 | 14043 | WL_ERR(("null bss\n")); |
|---|
| 13954 | 14044 | return BCME_ERROR; |
|---|
| .. | .. |
|---|
| 14063 | 14153 | if (!ndev->ieee80211_ptr->u.client.ssid_len) |
|---|
| 14064 | 14154 | #else |
|---|
| 14065 | 14155 | if (!ndev->ieee80211_ptr->ssid_len) |
|---|
| 14066 | | -#endif |
|---|
| 14156 | +#endif /* CFG80211_BKPORT_MLO */ |
|---|
| 14067 | 14157 | { |
|---|
| 14068 | 14158 | /* In certain cases, the delayed cfg80211 work from |
|---|
| 14069 | 14159 | * disconnect context will induce race conditions in |
|---|
| .. | .. |
|---|
| 16730 | 16820 | return err; |
|---|
| 16731 | 16821 | } |
|---|
| 16732 | 16822 | |
|---|
| 16733 | | -static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, s32 bw_cap) |
|---|
| 16823 | +static int wl_construct_reginfo(struct bcm_cfg80211 *cfg, s32 bw_cap_2g, |
|---|
| 16824 | + s32 bw_cap_5g, s32 bw_cap_6g) |
|---|
| 16734 | 16825 | { |
|---|
| 16735 | 16826 | struct net_device *dev = bcmcfg_to_prmry_ndev(cfg); |
|---|
| 16736 | 16827 | struct ieee80211_channel *band_chan_arr = NULL; |
|---|
| .. | .. |
|---|
| 16798 | 16889 | (channel <= CH_MAX_2G_CHANNEL)) { |
|---|
| 16799 | 16890 | band_chan_arr = __wl_2ghz_channels; |
|---|
| 16800 | 16891 | array_size = ARRAYSIZE(__wl_2ghz_channels); |
|---|
| 16801 | | - ht40_allowed = (bw_cap == WLC_N_BW_40ALL)? true : false; |
|---|
| 16802 | 16892 | } |
|---|
| 16803 | 16893 | #ifdef CFG80211_6G_SUPPORT |
|---|
| 16804 | 16894 | else if (CHSPEC_IS6G(chspec) && (channel >= CH_MIN_6G_CHANNEL) && |
|---|
| 16805 | 16895 | (channel <= CH_MAX_6G_CHANNEL)) { |
|---|
| 16806 | 16896 | band_chan_arr = __wl_6ghz_channels; |
|---|
| 16807 | 16897 | array_size = ARRAYSIZE(__wl_6ghz_channels); |
|---|
| 16808 | | - ht40_allowed = (bw_cap == WLC_N_BW_20ALL)? false : true; |
|---|
| 16898 | + ht40_allowed = WL_BW_CAP_40MHZ(bw_cap_6g); |
|---|
| 16809 | 16899 | } |
|---|
| 16810 | 16900 | #endif /* CFG80211_6G_SUPPORT */ |
|---|
| 16811 | 16901 | else if ( |
|---|
| .. | .. |
|---|
| 16819 | 16909 | (CHSPEC_IS5G(chspec) && channel >= CH_MIN_5G_CHANNEL)) { |
|---|
| 16820 | 16910 | band_chan_arr = __wl_5ghz_a_channels; |
|---|
| 16821 | 16911 | array_size = ARRAYSIZE(__wl_5ghz_a_channels); |
|---|
| 16822 | | - ht40_allowed = (bw_cap == WLC_N_BW_20ALL)? false : true; |
|---|
| 16912 | + ht40_allowed = WL_BW_CAP_40MHZ(bw_cap_5g); |
|---|
| 16823 | 16913 | } else { |
|---|
| 16824 | 16914 | WL_ERR(("Invalid channel Sepc. 0x%x.\n", chspec)); |
|---|
| 16825 | 16915 | continue; |
|---|
| .. | .. |
|---|
| 16827 | 16917 | if (!ht40_allowed && CHSPEC_IS40(chspec)) |
|---|
| 16828 | 16918 | continue; |
|---|
| 16829 | 16919 | for (j = 0; j < array_size; j++) { |
|---|
| 16830 | | - if (band_chan_arr[j].hw_value == chspec) { |
|---|
| 16920 | + if (band_chan_arr[j].hw_value == wf_chspec_primary20_chspec(chspec)) { |
|---|
| 16831 | 16921 | break; |
|---|
| 16832 | 16922 | } |
|---|
| 16833 | 16923 | } |
|---|
| .. | .. |
|---|
| 16842 | 16932 | band_chan_arr[index].center_freq = |
|---|
| 16843 | 16933 | wl_channel_to_frequency(channel, CHSPEC_BAND(chspec)); |
|---|
| 16844 | 16934 | #endif |
|---|
| 16845 | | - band_chan_arr[index].hw_value = chspec; |
|---|
| 16935 | + band_chan_arr[index].hw_value = wf_chspec_primary20_chspec(chspec); |
|---|
| 16846 | 16936 | band_chan_arr[index].beacon_found = false; |
|---|
| 16847 | 16937 | band_chan_arr[index].flags &= ~IEEE80211_CHAN_DISABLED; |
|---|
| 16848 | 16938 | |
|---|
| .. | .. |
|---|
| 16850 | 16940 | /* assuming the order is HT20, HT40 Upper, |
|---|
| 16851 | 16941 | * HT40 lower from chanspecs |
|---|
| 16852 | 16942 | */ |
|---|
| 16853 | | - u32 ht40_flag = band_chan_arr[index].flags & IEEE80211_CHAN_NO_HT40; |
|---|
| 16943 | + u32 ht40_flag = |
|---|
| 16944 | + band_chan_arr[index].flags & IEEE80211_CHAN_NO_HT40; |
|---|
| 16854 | 16945 | if (CHSPEC_SB_UPPER(chspec)) { |
|---|
| 16855 | 16946 | if (ht40_flag == IEEE80211_CHAN_NO_HT40) |
|---|
| 16856 | 16947 | band_chan_arr[index].flags &= |
|---|
| 16857 | 16948 | ~IEEE80211_CHAN_NO_HT40; |
|---|
| 16858 | | - band_chan_arr[index].flags |= IEEE80211_CHAN_NO_HT40PLUS; |
|---|
| 16949 | + band_chan_arr[index].flags |= |
|---|
| 16950 | + IEEE80211_CHAN_NO_HT40PLUS; |
|---|
| 16859 | 16951 | } else { |
|---|
| 16860 | 16952 | /* It should be one of |
|---|
| 16861 | 16953 | * IEEE80211_CHAN_NO_HT40 or IEEE80211_CHAN_NO_HT40PLUS |
|---|
| .. | .. |
|---|
| 16880 | 16972 | } |
|---|
| 16881 | 16973 | |
|---|
| 16882 | 16974 | } |
|---|
| 16975 | + |
|---|
| 16976 | + WL_CHANNEL_COPY_FLAG(__wl_2ghz_channels); |
|---|
| 16977 | + WL_CHANNEL_COPY_FLAG(__wl_5ghz_a_channels); |
|---|
| 16978 | +#ifdef CFG80211_6G_SUPPORT |
|---|
| 16979 | + WL_CHANNEL_COPY_FLAG(__wl_6ghz_channels); |
|---|
| 16980 | +#endif /* CFG80211_6G_SUPPORT */ |
|---|
| 16883 | 16981 | |
|---|
| 16884 | 16982 | __wl_band_2ghz.n_channels = ARRAYSIZE(__wl_2ghz_channels); |
|---|
| 16885 | 16983 | __wl_band_5ghz_a.n_channels = ARRAYSIZE(__wl_5ghz_a_channels); |
|---|
| .. | .. |
|---|
| 16919 | 17017 | s32 err = 0; |
|---|
| 16920 | 17018 | s32 index = 0; |
|---|
| 16921 | 17019 | s32 nmode = 0; |
|---|
| 16922 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) || defined(CUSTOMER_HW5) |
|---|
| 16923 | 17020 | u32 j = 0; |
|---|
| 17021 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) |
|---|
| 16924 | 17022 | s32 vhtmode = 0; |
|---|
| 16925 | 17023 | s32 txstreams = 0; |
|---|
| 16926 | 17024 | s32 rxstreams = 0; |
|---|
| .. | .. |
|---|
| 16929 | 17027 | s32 stbc_tx = 0; |
|---|
| 16930 | 17028 | s32 txbf_bfe_cap = 0; |
|---|
| 16931 | 17029 | s32 txbf_bfr_cap = 0; |
|---|
| 16932 | | -#endif /* KERNEL >= 3.6 || CUSTOMER_HW5 */ |
|---|
| 16933 | | - s32 bw_cap = 0; |
|---|
| 17030 | +#endif |
|---|
| 17031 | + s32 txchain = 0; |
|---|
| 17032 | + s32 rxchain = 0; |
|---|
| 17033 | + s32 bw_cap_2g = 0, bw_cap_5g = 0, bw_cap_6g = 0; |
|---|
| 16934 | 17034 | s32 cur_band = -1; |
|---|
| 16935 | 17035 | struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS] = {NULL, }; |
|---|
| 16936 | 17036 | |
|---|
| 17037 | + WL_INFORM(("%s: Enter\n", __FUNCTION__)); |
|---|
| 16937 | 17038 | bzero(bandlist, sizeof(bandlist)); |
|---|
| 16938 | 17039 | err = wldev_ioctl_get(dev, WLC_GET_BANDLIST, bandlist, |
|---|
| 16939 | 17040 | sizeof(bandlist)); |
|---|
| .. | .. |
|---|
| 16953 | 17054 | WL_ERR(("error reading nmode (%d)\n", err)); |
|---|
| 16954 | 17055 | } |
|---|
| 16955 | 17056 | |
|---|
| 16956 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) || defined(CUSTOMER_HW5) |
|---|
| 17057 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) |
|---|
| 16957 | 17058 | err = wldev_iovar_getint(dev, "vhtmode", &vhtmode); |
|---|
| 16958 | 17059 | if (unlikely(err)) { |
|---|
| 16959 | 17060 | WL_ERR(("error reading vhtmode (%d)\n", err)); |
|---|
| .. | .. |
|---|
| 16995 | 17096 | WL_ERR(("error reading txbf_bfr_cap (%d)\n", err)); |
|---|
| 16996 | 17097 | } |
|---|
| 16997 | 17098 | } |
|---|
| 16998 | | -#endif /* KERNEL >= 3.6 || CUSTOMER_HW5 */ |
|---|
| 17099 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) */ |
|---|
| 17100 | + |
|---|
| 17101 | + err = wldev_iovar_getint(dev, "txchain", &txchain); |
|---|
| 17102 | + if (unlikely(err)) { |
|---|
| 17103 | + WL_ERR(("error reading txchain (%d)\n", err)); |
|---|
| 17104 | + } else if (txchain == 0x03) { |
|---|
| 17105 | + txchain = 2; |
|---|
| 17106 | + } else { |
|---|
| 17107 | + txchain = 1; |
|---|
| 17108 | + } |
|---|
| 17109 | + err = wldev_iovar_getint(dev, "rxchain", &rxchain); |
|---|
| 17110 | + if (unlikely(err)) { |
|---|
| 17111 | + WL_ERR(("error reading rxchain (%d)\n", err)); |
|---|
| 17112 | + } else if (rxchain == 0x03) { |
|---|
| 17113 | + rxchain = 2; |
|---|
| 17114 | + } else { |
|---|
| 17115 | + rxchain = 1; |
|---|
| 17116 | + } |
|---|
| 16999 | 17117 | |
|---|
| 17000 | 17118 | /* For nmode and vhtmode check bw cap */ |
|---|
| 17001 | 17119 | if (nmode || |
|---|
| 17002 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) || defined(CUSTOMER_HW5) |
|---|
| 17120 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) |
|---|
| 17003 | 17121 | vhtmode || |
|---|
| 17004 | | -#endif /* KERNEL >= 3.6 || CUSTOMER_HW5 */ |
|---|
| 17122 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) */ |
|---|
| 17005 | 17123 | 0) { |
|---|
| 17006 | | - err = wldev_iovar_getint(dev, "mimo_bw_cap", &bw_cap); |
|---|
| 17124 | + uint32 value; |
|---|
| 17125 | + |
|---|
| 17126 | + value = WLC_BAND_2G; |
|---|
| 17127 | + err = wldev_iovar_getint(dev, "bw_cap", &value); |
|---|
| 17007 | 17128 | if (unlikely(err)) { |
|---|
| 17008 | | - WL_ERR(("error get mimo_bw_cap (%d)\n", err)); |
|---|
| 17129 | + WL_ERR(("error get bw_cap 2g (%d)\n", err)); |
|---|
| 17009 | 17130 | } |
|---|
| 17131 | + bw_cap_2g = dtoh32(value); |
|---|
| 17132 | + value = WLC_BAND_5G; |
|---|
| 17133 | + err = wldev_iovar_getint(dev, "bw_cap", &value); |
|---|
| 17134 | + if (unlikely(err)) { |
|---|
| 17135 | + WL_ERR(("error get bw_cap 5g (%d)\n", err)); |
|---|
| 17136 | + } |
|---|
| 17137 | + bw_cap_5g = dtoh32(value); |
|---|
| 17138 | + value = WLC_BAND_6G; |
|---|
| 17139 | + err = wldev_iovar_getint(dev, "bw_cap", &value); |
|---|
| 17140 | + if (unlikely(err)) { |
|---|
| 17141 | + WL_ERR(("error get bw_cap 6g (%d)\n", err)); |
|---|
| 17142 | + } |
|---|
| 17143 | + bw_cap_6g = dtoh32(value); |
|---|
| 17010 | 17144 | } |
|---|
| 17011 | 17145 | |
|---|
| 17012 | 17146 | #ifdef WL_6G_BAND |
|---|
| 17013 | 17147 | wl_is_6g_supported(cfg, bandlist, bandlist[0]); |
|---|
| 17014 | 17148 | #endif /* WL_6G_BAND */ |
|---|
| 17015 | 17149 | |
|---|
| 17016 | | - err = wl_construct_reginfo(cfg, bw_cap); |
|---|
| 17150 | + err = wl_construct_reginfo(cfg, bw_cap_2g, bw_cap_5g, bw_cap_6g); |
|---|
| 17017 | 17151 | if (err) { |
|---|
| 17018 | 17152 | WL_ERR(("wl_construct_reginfo() fails err=%d\n", err)); |
|---|
| 17019 | 17153 | if (err != BCME_UNSUPPORTED) |
|---|
| .. | .. |
|---|
| 17023 | 17157 | wiphy = bcmcfg_to_wiphy(cfg); |
|---|
| 17024 | 17158 | nband = bandlist[0]; |
|---|
| 17025 | 17159 | |
|---|
| 17160 | + wiphy->available_antennas_tx = txchain; |
|---|
| 17161 | + wiphy->available_antennas_rx = rxchain; |
|---|
| 17162 | + |
|---|
| 17026 | 17163 | for (i = 1; i <= nband && i < ARRAYSIZE(bandlist); i++) { |
|---|
| 17027 | 17164 | index = -1; |
|---|
| 17028 | 17165 | |
|---|
| .. | .. |
|---|
| 17030 | 17167 | bands[IEEE80211_BAND_2GHZ] = |
|---|
| 17031 | 17168 | &__wl_band_2ghz; |
|---|
| 17032 | 17169 | index = IEEE80211_BAND_2GHZ; |
|---|
| 17033 | | - if (bw_cap == WLC_N_BW_40ALL) |
|---|
| 17034 | | - bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; |
|---|
| 17170 | + (void)memset_s(bands[index]->ht_cap.mcs.rx_mask, IEEE80211_HT_MCS_MASK_LEN, |
|---|
| 17171 | + 0, IEEE80211_HT_MCS_MASK_LEN); |
|---|
| 17172 | + if (nmode && (WL_BW_CAP_40MHZ(bw_cap_2g))) { |
|---|
| 17173 | + bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | |
|---|
| 17174 | + IEEE80211_HT_CAP_SGI_40; |
|---|
| 17175 | + bands[index]->ht_cap.mcs.rx_mask[4] = 0x01; |
|---|
| 17176 | + bands[index]->ht_cap.mcs.rx_highest = |
|---|
| 17177 | + cpu_to_le16(150 * rxchain); /* Mbps */ |
|---|
| 17178 | + } else { |
|---|
| 17179 | + bands[index]->ht_cap.mcs.rx_highest = |
|---|
| 17180 | + cpu_to_le16(72 * rxchain); /* Mbps */ |
|---|
| 17181 | + } |
|---|
| 17035 | 17182 | } else { |
|---|
| 17036 | 17183 | if (bandlist[i] == WLC_BAND_6G) { |
|---|
| 17037 | 17184 | #ifdef CFG80211_6G_SUPPORT |
|---|
| .. | .. |
|---|
| 17062 | 17209 | continue; |
|---|
| 17063 | 17210 | } |
|---|
| 17064 | 17211 | |
|---|
| 17065 | | - if (nmode && (bw_cap == WLC_N_BW_40ALL || bw_cap == WLC_N_BW_20IN2G_40IN5G)) |
|---|
| 17066 | | - bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; |
|---|
| 17212 | + (void)memset_s(bands[index]->ht_cap.mcs.rx_mask, IEEE80211_HT_MCS_MASK_LEN, |
|---|
| 17213 | + 0, IEEE80211_HT_MCS_MASK_LEN); |
|---|
| 17214 | + if (nmode && (WL_BW_CAP_40MHZ(bw_cap_5g))) { |
|---|
| 17215 | + bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | |
|---|
| 17216 | + IEEE80211_HT_CAP_SGI_40; |
|---|
| 17217 | + bands[index]->ht_cap.mcs.rx_mask[4] = 0x01; |
|---|
| 17218 | + bands[index]->ht_cap.mcs.rx_highest = cpu_to_le16(150 * rxchain); |
|---|
| 17219 | + } else { |
|---|
| 17220 | + bands[index]->ht_cap.mcs.rx_highest = cpu_to_le16(72 * rxchain); |
|---|
| 17221 | + } |
|---|
| 17067 | 17222 | |
|---|
| 17068 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) || defined(CUSTOMER_HW5) |
|---|
| 17223 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) |
|---|
| 17069 | 17224 | /* VHT capabilities. */ |
|---|
| 17070 | 17225 | if (vhtmode) { |
|---|
| 17071 | 17226 | /* Supported */ |
|---|
| 17072 | 17227 | bands[index]->vht_cap.vht_supported = TRUE; |
|---|
| 17228 | + bands[index]->vht_cap.vht_mcs.tx_highest = |
|---|
| 17229 | + cpu_to_le16(433 * txstreams); /* Mbps */ |
|---|
| 17230 | + bands[index]->vht_cap.vht_mcs.rx_highest = |
|---|
| 17231 | + cpu_to_le16(433 * txstreams); /* Mbps */ |
|---|
| 17073 | 17232 | |
|---|
| 17074 | 17233 | for (j = 1; j <= VHT_CAP_MCS_MAP_NSS_MAX; j++) { |
|---|
| 17075 | 17234 | /* TX stream rates. */ |
|---|
| .. | .. |
|---|
| 17092 | 17251 | } |
|---|
| 17093 | 17252 | |
|---|
| 17094 | 17253 | /* Capabilities */ |
|---|
| 17254 | + bands[index]->vht_cap.cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
|---|
| 17255 | + | IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; |
|---|
| 17095 | 17256 | /* 80 MHz is mandatory */ |
|---|
| 17096 | 17257 | bands[index]->vht_cap.cap |= |
|---|
| 17097 | 17258 | IEEE80211_VHT_CAP_SHORT_GI_80; |
|---|
| 17098 | 17259 | |
|---|
| 17099 | | - if (WL_BW_CAP_160MHZ(bw_cap)) { |
|---|
| 17260 | + if (WL_BW_CAP_160MHZ(bw_cap_5g)) { |
|---|
| 17100 | 17261 | bands[index]->vht_cap.cap |= |
|---|
| 17101 | 17262 | IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; |
|---|
| 17102 | 17263 | bands[index]->vht_cap.cap |= |
|---|
| .. | .. |
|---|
| 17148 | 17309 | bands[index]->vht_cap.vht_mcs.rx_mcs_map, |
|---|
| 17149 | 17310 | bands[index]->vht_cap.vht_mcs.tx_mcs_map)); |
|---|
| 17150 | 17311 | } |
|---|
| 17151 | | -#endif /* KERNEL >= 3.6 || CUSTOMER_HW5 */ |
|---|
| 17312 | +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0) */ |
|---|
| 17152 | 17313 | } |
|---|
| 17153 | 17314 | |
|---|
| 17154 | 17315 | if ((index >= 0) && nmode) { |
|---|
| .. | .. |
|---|
| 17158 | 17319 | bands[index]->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; |
|---|
| 17159 | 17320 | bands[index]->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; |
|---|
| 17160 | 17321 | /* An HT shall support all EQM rates for one spatial stream */ |
|---|
| 17161 | | - bands[index]->ht_cap.mcs.rx_mask[0] = 0xff; |
|---|
| 17322 | + for (j = 0; j < rxchain; j++) { |
|---|
| 17323 | + bands[index]->ht_cap.mcs.rx_mask[j] = 0xff; |
|---|
| 17324 | + } |
|---|
| 17325 | + bands[index]->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; |
|---|
| 17162 | 17326 | } |
|---|
| 17163 | 17327 | |
|---|
| 17164 | 17328 | } |
|---|
| .. | .. |
|---|
| 17623 | 17787 | struct wireless_dev *wdev = ndev->ieee80211_ptr; |
|---|
| 17624 | 17788 | struct cfg80211_bss *bss = CFG80211_GET_BSS(wiphy, NULL, latest_bssid, |
|---|
| 17625 | 17789 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) || defined(CFG80211_BKPORT_MLO) |
|---|
| 17626 | | - wdev->u.client.ssid, wdev->u.client.ssid_len |
|---|
| 17790 | + wdev->u.client.ssid, wdev->u.client.ssid_len); |
|---|
| 17627 | 17791 | #else |
|---|
| 17628 | | - wdev->ssid, wdev->ssid_len |
|---|
| 17629 | | -#endif |
|---|
| 17630 | | - ); |
|---|
| 17792 | + wdev->ssid, wdev->ssid_len); |
|---|
| 17793 | +#endif /* CFG80211_BKPORT_MLO */ |
|---|
| 17631 | 17794 | |
|---|
| 17632 | 17795 | BCM_REFERENCE(bss); |
|---|
| 17633 | 17796 | |
|---|
| .. | .. |
|---|
| 19536 | 19699 | while (ie) { |
|---|
| 19537 | 19700 | if (count >= MAX_VNDR_IE_NUMBER) |
|---|
| 19538 | 19701 | break; |
|---|
| 19539 | | - if (ie->id == DOT11_MNG_VS_ID || (ie->id == DOT11_MNG_ID_EXT_ID)) { |
|---|
| 19702 | +#ifdef HOSTAPD_EID_EXTENSION_SUPPORT |
|---|
| 19703 | + if (ie->id == DOT11_MNG_VS_ID || (ie->id == DOT11_MNG_ID_EXT_ID)) |
|---|
| 19704 | +#else |
|---|
| 19705 | + if (ie->id == DOT11_MNG_VS_ID) |
|---|
| 19706 | +#endif |
|---|
| 19707 | + { |
|---|
| 19540 | 19708 | vndrie = (const vndr_ie_t *) ie; |
|---|
| 19541 | 19709 | if (ie->id == DOT11_MNG_ID_EXT_ID) { |
|---|
| 19542 | 19710 | /* len should be bigger than sizeof ID extn field at least */ |
|---|
| .. | .. |
|---|
| 19876 | 20044 | return 0; |
|---|
| 19877 | 20045 | } |
|---|
| 19878 | 20046 | |
|---|
| 20047 | +#ifdef GET_FW_IE_DATA |
|---|
| 20048 | +static void |
|---|
| 20049 | +wl_dump_ie_buf(vndr_ie_buf_t *ie_getbuf) |
|---|
| 20050 | +{ |
|---|
| 20051 | + uchar *iebuf; |
|---|
| 20052 | + uchar *data; |
|---|
| 20053 | + int tot_ie, pktflag, iecount, datalen; |
|---|
| 20054 | + vndr_ie_info_t *ie_info; |
|---|
| 20055 | + vndr_ie_t *ie; |
|---|
| 20056 | + |
|---|
| 20057 | + memcpy(&tot_ie, (void *)&ie_getbuf->iecount, sizeof(int)); |
|---|
| 20058 | + tot_ie = dtoh32(tot_ie); |
|---|
| 20059 | + iebuf = (uchar *)&ie_getbuf->vndr_ie_list[0]; |
|---|
| 20060 | + |
|---|
| 20061 | + printf("-----------------\n"); |
|---|
| 20062 | + printf("Total IEs %d\n", tot_ie); |
|---|
| 20063 | + for (iecount = 0; iecount < tot_ie; iecount++) { |
|---|
| 20064 | + ie_info = (vndr_ie_info_t *) iebuf; |
|---|
| 20065 | + memcpy(&pktflag, (void *)&ie_info->pktflag, sizeof(uint32)); |
|---|
| 20066 | + pktflag = dtoh32(pktflag); |
|---|
| 20067 | + iebuf += sizeof(uint32); |
|---|
| 20068 | + ie = &ie_info->vndr_ie_data; |
|---|
| 20069 | + data = &ie->data[0]; |
|---|
| 20070 | + datalen = ie->len - VNDR_IE_MIN_LEN; |
|---|
| 20071 | + printf("index=%d, pktflag=0x%x\n", iecount, pktflag); |
|---|
| 20072 | + prhex("IE", (u8 *)ie, ie->len+VNDR_IE_HDR_LEN); |
|---|
| 20073 | + |
|---|
| 20074 | + iebuf += ie->len + VNDR_IE_HDR_LEN; |
|---|
| 20075 | + } |
|---|
| 20076 | + printf("-----------------\n"); |
|---|
| 20077 | + printf("\n"); |
|---|
| 20078 | +} |
|---|
| 20079 | +#endif /* GET_FW_IE_DATA */ |
|---|
| 20080 | + |
|---|
| 19879 | 20081 | static void |
|---|
| 19880 | 20082 | wl_print_fw_ie_data(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bssidx) |
|---|
| 19881 | 20083 | { |
|---|
| .. | .. |
|---|
| 19887 | 20089 | bssidx, &cfg->ioctl_buf_sync); |
|---|
| 19888 | 20090 | if (ret == BCME_OK) { |
|---|
| 19889 | 20091 | ies = (vndr_ie_buf_t *)cfg->ioctl_buf; |
|---|
| 19890 | | - WL_INFORM_MEM(("FW IE count:%d\n", ies->iecount)); |
|---|
| 19891 | 20092 | #ifdef GET_FW_IE_DATA |
|---|
| 19892 | | - if (wl_dbg_level & WL_DBG_DBG) { |
|---|
| 19893 | | - int i = 0; |
|---|
| 19894 | | - /* If debug enabled, print each IE */ |
|---|
| 19895 | | - for (i = 0; i < ies->iecount; i++) { |
|---|
| 19896 | | - vndr_ie_info_t *info = &ies->vndr_ie_list[i]; |
|---|
| 19897 | | - WL_DBG_MEM(("pktflag:0x%x\n", info->pktflag)); |
|---|
| 19898 | | - prhex("IE:", (u8 *)&info->vndr_ie_data, |
|---|
| 19899 | | - info->vndr_ie_data.len + TLV_HDR_LEN); |
|---|
| 19900 | | - } |
|---|
| 19901 | | - } |
|---|
| 20093 | + wl_dump_ie_buf((vndr_ie_buf_t *)cfg->ioctl_buf); |
|---|
| 20094 | +#else |
|---|
| 20095 | + WL_MSG(ndev->name, "FW IE count:%d\n", ies->iecount); |
|---|
| 19902 | 20096 | #endif /* GET_FW_IE_DATA */ |
|---|
| 19903 | 20097 | } else { |
|---|
| 19904 | 20098 | WL_ERR(("IE retrieval failed! ret:%d\n", ret)); |
|---|
| .. | .. |
|---|
| 19922 | 20116 | u32 parsed_ie_buf_len = 0; |
|---|
| 19923 | 20117 | struct parsed_vndr_ies old_vndr_ies; |
|---|
| 19924 | 20118 | struct parsed_vndr_ies new_vndr_ies; |
|---|
| 20119 | + int del_add_cnt = 0; |
|---|
| 19925 | 20120 | s32 i; |
|---|
| 19926 | 20121 | u8 *ptr; |
|---|
| 19927 | 20122 | s32 remained_buf_len; |
|---|
| .. | .. |
|---|
| 20065 | 20260 | |
|---|
| 20066 | 20261 | curr_ie_buf += del_add_ie_buf_len; |
|---|
| 20067 | 20262 | total_ie_buf_len += del_add_ie_buf_len; |
|---|
| 20263 | + del_add_cnt++; |
|---|
| 20068 | 20264 | } |
|---|
| 20069 | 20265 | } |
|---|
| 20070 | 20266 | |
|---|
| .. | .. |
|---|
| 20114 | 20310 | *mgmt_ie_len += vndrie_info->ie_len; |
|---|
| 20115 | 20311 | curr_ie_buf += del_add_ie_buf_len; |
|---|
| 20116 | 20312 | total_ie_buf_len += del_add_ie_buf_len; |
|---|
| 20313 | + del_add_cnt++; |
|---|
| 20117 | 20314 | } |
|---|
| 20118 | 20315 | } |
|---|
| 20119 | 20316 | |
|---|
| 20120 | 20317 | if (total_ie_buf_len && cfg->ioctl_buf != NULL) { |
|---|
| 20121 | | - ret = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", g_mgmt_ie_buf, |
|---|
| 20318 | +#ifdef VNDR_IE_WAR |
|---|
| 20319 | + curr_ie_buf = g_mgmt_ie_buf; |
|---|
| 20320 | + for (i=0; i<del_add_cnt; i++) { |
|---|
| 20321 | + vndr_ie_setbuf_t *vndr_ie_setbuf = (vndr_ie_setbuf_t *)curr_ie_buf; |
|---|
| 20322 | + u32 curr_ie_buf_len; |
|---|
| 20323 | + curr_ie_buf_len = |
|---|
| 20324 | + (u8*)&vndr_ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.oui[0] - |
|---|
| 20325 | + (u8*)vndr_ie_setbuf; |
|---|
| 20326 | + curr_ie_buf_len += vndr_ie_setbuf->vndr_ie_buffer.vndr_ie_list[0].vndr_ie_data.len; |
|---|
| 20327 | + ret = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", curr_ie_buf, |
|---|
| 20328 | + curr_ie_buf_len, cfg->ioctl_buf, WLC_IOCTL_MAXLEN, |
|---|
| 20329 | + bssidx, &cfg->ioctl_buf_sync); |
|---|
| 20330 | + if (ret) |
|---|
| 20331 | + break; |
|---|
| 20332 | + curr_ie_buf += curr_ie_buf_len; |
|---|
| 20333 | + } |
|---|
| 20334 | +#else |
|---|
| 20335 | + ret = wldev_iovar_setbuf_bsscfg(ndev, "vndr_ie", g_mgmt_ie_buf, |
|---|
| 20122 | 20336 | total_ie_buf_len, cfg->ioctl_buf, WLC_IOCTL_MAXLEN, |
|---|
| 20123 | 20337 | bssidx, &cfg->ioctl_buf_sync); |
|---|
| 20338 | +#endif |
|---|
| 20124 | 20339 | if (ret) { |
|---|
| 20125 | 20340 | WL_ERR(("vndr_ie set error :%d\n", ret)); |
|---|
| 20126 | 20341 | if (ret == BCME_NOTFOUND) { |
|---|