36
36
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
37
37
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
38
38
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
39
+ * Copyright(c) 2018 Intel Corporation
39
40
* All rights reserved.
40
41
*
41
42
* Redistribution and use in source and binary forms, with or without
@@ -914,7 +915,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
914
915
enum ieee80211_ampdu_mlme_action action = params -> action ;
915
916
u16 tid = params -> tid ;
916
917
u16 * ssn = & params -> ssn ;
917
- u8 buf_size = params -> buf_size ;
918
+ u16 buf_size = params -> buf_size ;
918
919
bool amsdu = params -> amsdu ;
919
920
u16 timeout = params -> timeout ;
920
921
@@ -1897,6 +1898,194 @@ void iwl_mvm_mu_mimo_grp_notif(struct iwl_mvm *mvm,
1897
1898
iwl_mvm_mu_mimo_iface_iterator , notif );
1898
1899
}
1899
1900
1901
+ static u8 iwl_mvm_he_get_ppe_val (u8 * ppe , u8 ppe_pos_bit )
1902
+ {
1903
+ u8 byte_num = ppe_pos_bit / 8 ;
1904
+ u8 bit_num = ppe_pos_bit % 8 ;
1905
+ u8 residue_bits ;
1906
+ u8 res ;
1907
+
1908
+ if (bit_num <= 5 )
1909
+ return (ppe [byte_num ] >> bit_num ) &
1910
+ (BIT (IEEE80211_PPE_THRES_INFO_PPET_SIZE ) - 1 );
1911
+
1912
+ /*
1913
+ * If bit_num > 5, we have to combine bits with next byte.
1914
+ * Calculate how many bits we need to take from current byte (called
1915
+ * here "residue_bits"), and add them to bits from next byte.
1916
+ */
1917
+
1918
+ residue_bits = 8 - bit_num ;
1919
+
1920
+ res = (ppe [byte_num + 1 ] &
1921
+ (BIT (IEEE80211_PPE_THRES_INFO_PPET_SIZE - residue_bits ) - 1 )) <<
1922
+ residue_bits ;
1923
+ res += (ppe [byte_num ] >> bit_num ) & (BIT (residue_bits ) - 1 );
1924
+
1925
+ return res ;
1926
+ }
1927
+
1928
+ static void iwl_mvm_cfg_he_sta (struct iwl_mvm * mvm ,
1929
+ struct ieee80211_vif * vif , u8 sta_id )
1930
+ {
1931
+ struct iwl_mvm_vif * mvmvif = iwl_mvm_vif_from_mac80211 (vif );
1932
+ struct iwl_he_sta_context_cmd sta_ctxt_cmd = {
1933
+ .sta_id = sta_id ,
1934
+ .tid_limit = IWL_MAX_TID_COUNT ,
1935
+ .bss_color = vif -> bss_conf .bss_color ,
1936
+ .htc_trig_based_pkt_ext = vif -> bss_conf .htc_trig_based_pkt_ext ,
1937
+ .frame_time_rts_th =
1938
+ cpu_to_le16 (vif -> bss_conf .frame_time_rts_th ),
1939
+ };
1940
+ struct ieee80211_sta * sta ;
1941
+ u32 flags ;
1942
+ int i ;
1943
+
1944
+ rcu_read_lock ();
1945
+
1946
+ sta = rcu_dereference (mvm -> fw_id_to_mac_id [sta_ctxt_cmd .sta_id ]);
1947
+ if (IS_ERR (sta )) {
1948
+ rcu_read_unlock ();
1949
+ WARN (1 , "Can't find STA to configure HE\n" );
1950
+ return ;
1951
+ }
1952
+
1953
+ if (!sta -> he_cap .has_he ) {
1954
+ rcu_read_unlock ();
1955
+ return ;
1956
+ }
1957
+
1958
+ flags = 0 ;
1959
+
1960
+ /* HTC flags */
1961
+ if (sta -> he_cap .he_cap_elem .mac_cap_info [0 ] &
1962
+ IEEE80211_HE_MAC_CAP0_HTC_HE )
1963
+ sta_ctxt_cmd .htc_flags |= cpu_to_le32 (IWL_HE_HTC_SUPPORT );
1964
+ if ((sta -> he_cap .he_cap_elem .mac_cap_info [1 ] &
1965
+ IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION ) ||
1966
+ (sta -> he_cap .he_cap_elem .mac_cap_info [2 ] &
1967
+ IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION )) {
1968
+ u8 link_adap =
1969
+ ((sta -> he_cap .he_cap_elem .mac_cap_info [2 ] &
1970
+ IEEE80211_HE_MAC_CAP2_LINK_ADAPTATION ) << 1 ) +
1971
+ (sta -> he_cap .he_cap_elem .mac_cap_info [1 ] &
1972
+ IEEE80211_HE_MAC_CAP1_LINK_ADAPTATION );
1973
+
1974
+ if (link_adap == 2 )
1975
+ sta_ctxt_cmd .htc_flags |=
1976
+ cpu_to_le32 (IWL_HE_HTC_LINK_ADAP_UNSOLICITED );
1977
+ else if (link_adap == 3 )
1978
+ sta_ctxt_cmd .htc_flags |=
1979
+ cpu_to_le32 (IWL_HE_HTC_LINK_ADAP_BOTH );
1980
+ }
1981
+ if (sta -> he_cap .he_cap_elem .mac_cap_info [2 ] &
1982
+ IEEE80211_HE_MAC_CAP2_UL_MU_RESP_SCHED )
1983
+ sta_ctxt_cmd .htc_flags |=
1984
+ cpu_to_le32 (IWL_HE_HTC_UL_MU_RESP_SCHED );
1985
+ if (sta -> he_cap .he_cap_elem .mac_cap_info [2 ] & IEEE80211_HE_MAC_CAP2_BSR )
1986
+ sta_ctxt_cmd .htc_flags |= cpu_to_le32 (IWL_HE_HTC_BSR_SUPP );
1987
+ if (sta -> he_cap .he_cap_elem .mac_cap_info [3 ] &
1988
+ IEEE80211_HE_MAC_CAP3_OMI_CONTROL )
1989
+ sta_ctxt_cmd .htc_flags |= cpu_to_le32 (IWL_HE_HTC_OMI_SUPP );
1990
+ if (sta -> he_cap .he_cap_elem .mac_cap_info [4 ] & IEEE80211_HE_MAC_CAP4_BQR )
1991
+ sta_ctxt_cmd .htc_flags |= cpu_to_le32 (IWL_HE_HTC_BQR_SUPP );
1992
+
1993
+ /* If PPE Thresholds exist, parse them into a FW-familiar format */
1994
+ if (sta -> he_cap .he_cap_elem .phy_cap_info [6 ] &
1995
+ IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT ) {
1996
+ u8 nss = (sta -> he_cap .ppe_thres [0 ] &
1997
+ IEEE80211_PPE_THRES_NSS_MASK ) + 1 ;
1998
+ u8 ru_index_bitmap =
1999
+ (sta -> he_cap .ppe_thres [0 ] &
2000
+ IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK ) >>
2001
+ IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS ;
2002
+ u8 * ppe = & sta -> he_cap .ppe_thres [0 ];
2003
+ u8 ppe_pos_bit = 7 ; /* Starting after PPE header */
2004
+
2005
+ /*
2006
+ * FW currently supports only nss == MAX_HE_SUPP_NSS
2007
+ *
2008
+ * If nss > MAX: we can ignore values we don't support
2009
+ * If nss < MAX: we can set zeros in other streams
2010
+ */
2011
+ if (nss > MAX_HE_SUPP_NSS ) {
2012
+ IWL_INFO (mvm , "Got NSS = %d - trimming to %d\n" , nss ,
2013
+ MAX_HE_SUPP_NSS );
2014
+ nss = MAX_HE_SUPP_NSS ;
2015
+ }
2016
+
2017
+ for (i = 0 ; i < nss ; i ++ ) {
2018
+ u8 ru_index_tmp = ru_index_bitmap << 1 ;
2019
+ u8 bw ;
2020
+
2021
+ for (bw = 0 ; bw < MAX_HE_CHANNEL_BW_INDX ; bw ++ ) {
2022
+ ru_index_tmp >>= 1 ;
2023
+ if (!(ru_index_tmp & 1 ))
2024
+ continue ;
2025
+
2026
+ sta_ctxt_cmd .pkt_ext .pkt_ext_qam_th [i ][bw ][1 ] =
2027
+ iwl_mvm_he_get_ppe_val (ppe ,
2028
+ ppe_pos_bit );
2029
+ ppe_pos_bit +=
2030
+ IEEE80211_PPE_THRES_INFO_PPET_SIZE ;
2031
+ sta_ctxt_cmd .pkt_ext .pkt_ext_qam_th [i ][bw ][0 ] =
2032
+ iwl_mvm_he_get_ppe_val (ppe ,
2033
+ ppe_pos_bit );
2034
+ ppe_pos_bit +=
2035
+ IEEE80211_PPE_THRES_INFO_PPET_SIZE ;
2036
+ }
2037
+ }
2038
+
2039
+ flags |= STA_CTXT_HE_PACKET_EXT ;
2040
+ }
2041
+ rcu_read_unlock ();
2042
+
2043
+ /* Mark MU EDCA as enabled, unless none detected on some AC */
2044
+ flags |= STA_CTXT_HE_MU_EDCA_CW ;
2045
+ for (i = 0 ; i < AC_NUM ; i ++ ) {
2046
+ struct ieee80211_he_mu_edca_param_ac_rec * mu_edca =
2047
+ & mvmvif -> queue_params [i ].mu_edca_param_rec ;
2048
+
2049
+ if (!mvmvif -> queue_params [i ].mu_edca ) {
2050
+ flags &= ~STA_CTXT_HE_MU_EDCA_CW ;
2051
+ break ;
2052
+ }
2053
+
2054
+ sta_ctxt_cmd .trig_based_txf [i ].cwmin =
2055
+ cpu_to_le16 (mu_edca -> ecw_min_max & 0xf );
2056
+ sta_ctxt_cmd .trig_based_txf [i ].cwmax =
2057
+ cpu_to_le16 ((mu_edca -> ecw_min_max & 0xf0 ) >> 4 );
2058
+ sta_ctxt_cmd .trig_based_txf [i ].aifsn =
2059
+ cpu_to_le16 (mu_edca -> aifsn );
2060
+ sta_ctxt_cmd .trig_based_txf [i ].mu_time =
2061
+ cpu_to_le16 (mu_edca -> mu_edca_timer );
2062
+ }
2063
+
2064
+ if (vif -> bss_conf .multi_sta_back_32bit )
2065
+ flags |= STA_CTXT_HE_32BIT_BA_BITMAP ;
2066
+
2067
+ if (vif -> bss_conf .ack_enabled )
2068
+ flags |= STA_CTXT_HE_ACK_ENABLED ;
2069
+
2070
+ if (vif -> bss_conf .uora_exists ) {
2071
+ flags |= STA_CTXT_HE_TRIG_RND_ALLOC ;
2072
+
2073
+ sta_ctxt_cmd .rand_alloc_ecwmin =
2074
+ vif -> bss_conf .uora_ocw_range & 0x7 ;
2075
+ sta_ctxt_cmd .rand_alloc_ecwmax =
2076
+ (vif -> bss_conf .uora_ocw_range >> 3 ) & 0x7 ;
2077
+ }
2078
+
2079
+ /* TODO: support Multi BSSID IE */
2080
+
2081
+ sta_ctxt_cmd .flags = cpu_to_le32 (flags );
2082
+
2083
+ if (iwl_mvm_send_cmd_pdu (mvm , iwl_cmd_id (STA_HE_CTXT_CMD ,
2084
+ DATA_PATH_GROUP , 0 ),
2085
+ 0 , sizeof (sta_ctxt_cmd ), & sta_ctxt_cmd ))
2086
+ IWL_ERR (mvm , "Failed to config FW to work HE!\n" );
2087
+ }
2088
+
1900
2089
static void iwl_mvm_bss_info_changed_station (struct iwl_mvm * mvm ,
1901
2090
struct ieee80211_vif * vif ,
1902
2091
struct ieee80211_bss_conf * bss_conf ,
@@ -1910,8 +2099,12 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1910
2099
* beacon interval, which was not known when the station interface was
1911
2100
* added.
1912
2101
*/
1913
- if (changes & BSS_CHANGED_ASSOC && bss_conf -> assoc )
2102
+ if (changes & BSS_CHANGED_ASSOC && bss_conf -> assoc ) {
2103
+ if (vif -> bss_conf .he_support )
2104
+ iwl_mvm_cfg_he_sta (mvm , vif , mvmvif -> ap_sta_id );
2105
+
1914
2106
iwl_mvm_mac_ctxt_recalc_tsf_id (mvm , vif );
2107
+ }
1915
2108
1916
2109
/*
1917
2110
* If we're not associated yet, take the (new) BSSID before associating
0 commit comments