Commit 2c2b4bbc authored by Naftali Goldstein's avatar Naftali Goldstein Committed by Luca Coelho

iwlwifi: mvm: update rs-fw API

Update rs-fw API to match changes in FW.  Specifically, the
TLC_MNG_NOTIF_REQ_CMD command and TLC_MNG_AMSDU_ENABLE_NOTIF
notification are removed, the A-MSDU related info is received from FW
via the TLC_MNG_UPDATE_NOTIF, and the TLC_MNG_CONFIG_CMD uses version
2 of its data structure.

Additionally, constify some arguments in a couple of functions.
Signed-off-by: default avatarNaftali Goldstein <naftali.goldstein@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 4883145a
...@@ -87,16 +87,6 @@ enum iwl_data_path_subcmd_ids { ...@@ -87,16 +87,6 @@ enum iwl_data_path_subcmd_ids {
*/ */
TLC_MNG_CONFIG_CMD = 0xF, TLC_MNG_CONFIG_CMD = 0xF,
/**
* @TLC_MNG_NOTIF_REQ_CMD: &struct iwl_tlc_notif_req_config_cmd
*/
TLC_MNG_NOTIF_REQ_CMD = 0x10,
/**
* @TLC_MNG_AMSDU_ENABLE_NOTIF: &struct iwl_tlc_amsdu_notif
*/
TLC_MNG_AMSDU_ENABLE_NOTIF = 0xF6,
/** /**
* @TLC_MNG_UPDATE_NOTIF: &struct iwl_tlc_update_notif * @TLC_MNG_UPDATE_NOTIF: &struct iwl_tlc_update_notif
*/ */
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* *
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2017 Intel Deutschland GmbH * Copyright(c) 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as * it under the terms of version 2 of the GNU General Public License as
...@@ -28,6 +29,7 @@ ...@@ -28,6 +29,7 @@
* *
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2017 Intel Deutschland GmbH * Copyright(c) 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -64,62 +66,38 @@ ...@@ -64,62 +66,38 @@
/** /**
* enum iwl_tlc_mng_cfg_flags_enum - options for TLC config flags * enum iwl_tlc_mng_cfg_flags_enum - options for TLC config flags
* @IWL_TLC_MNG_CFG_FLAGS_CCK_MSK: CCK support
* @IWL_TLC_MNG_CFG_FLAGS_DD_MSK: enable DD
* @IWL_TLC_MNG_CFG_FLAGS_STBC_MSK: enable STBC * @IWL_TLC_MNG_CFG_FLAGS_STBC_MSK: enable STBC
* @IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK: enable LDPC * @IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK: enable LDPC
* @IWL_TLC_MNG_CFG_FLAGS_BF_MSK: enable BFER
* @IWL_TLC_MNG_CFG_FLAGS_DCM_MSK: enable DCM
*/ */
enum iwl_tlc_mng_cfg_flags { enum iwl_tlc_mng_cfg_flags {
IWL_TLC_MNG_CFG_FLAGS_CCK_MSK = BIT(0), IWL_TLC_MNG_CFG_FLAGS_STBC_MSK = BIT(0),
IWL_TLC_MNG_CFG_FLAGS_DD_MSK = BIT(1), IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK = BIT(1),
IWL_TLC_MNG_CFG_FLAGS_STBC_MSK = BIT(2),
IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK = BIT(3),
IWL_TLC_MNG_CFG_FLAGS_BF_MSK = BIT(4),
IWL_TLC_MNG_CFG_FLAGS_DCM_MSK = BIT(5),
}; };
/** /**
* enum iwl_tlc_mng_cfg_cw - channel width options * enum iwl_tlc_mng_cfg_cw - channel width options
* @IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ: 20MHZ channel * @IWL_TLC_MNG_CH_WIDTH_20MHZ: 20MHZ channel
* @IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ: 40MHZ channel * @IWL_TLC_MNG_CH_WIDTH_40MHZ: 40MHZ channel
* @IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ: 80MHZ channel * @IWL_TLC_MNG_CH_WIDTH_80MHZ: 80MHZ channel
* @IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ: 160MHZ channel * @IWL_TLC_MNG_CH_WIDTH_160MHZ: 160MHZ channel
* @IWL_TLC_MNG_MAX_CH_WIDTH_LAST: maximum value * @IWL_TLC_MNG_CH_WIDTH_LAST: maximum value
*/ */
enum iwl_tlc_mng_cfg_cw { enum iwl_tlc_mng_cfg_cw {
IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ, IWL_TLC_MNG_CH_WIDTH_20MHZ,
IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ, IWL_TLC_MNG_CH_WIDTH_40MHZ,
IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ, IWL_TLC_MNG_CH_WIDTH_80MHZ,
IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ, IWL_TLC_MNG_CH_WIDTH_160MHZ,
IWL_TLC_MNG_MAX_CH_WIDTH_LAST = IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ, IWL_TLC_MNG_CH_WIDTH_LAST = IWL_TLC_MNG_CH_WIDTH_160MHZ,
}; };
/** /**
* enum iwl_tlc_mng_cfg_chains - possible chains * enum iwl_tlc_mng_cfg_chains - possible chains
* @IWL_TLC_MNG_CHAIN_A_MSK: chain A * @IWL_TLC_MNG_CHAIN_A_MSK: chain A
* @IWL_TLC_MNG_CHAIN_B_MSK: chain B * @IWL_TLC_MNG_CHAIN_B_MSK: chain B
* @IWL_TLC_MNG_CHAIN_C_MSK: chain C
*/ */
enum iwl_tlc_mng_cfg_chains { enum iwl_tlc_mng_cfg_chains {
IWL_TLC_MNG_CHAIN_A_MSK = BIT(0), IWL_TLC_MNG_CHAIN_A_MSK = BIT(0),
IWL_TLC_MNG_CHAIN_B_MSK = BIT(1), IWL_TLC_MNG_CHAIN_B_MSK = BIT(1),
IWL_TLC_MNG_CHAIN_C_MSK = BIT(2),
};
/**
* enum iwl_tlc_mng_cfg_gi - guard interval options
* @IWL_TLC_MNG_SGI_20MHZ_MSK: enable short GI for 20MHZ
* @IWL_TLC_MNG_SGI_40MHZ_MSK: enable short GI for 40MHZ
* @IWL_TLC_MNG_SGI_80MHZ_MSK: enable short GI for 80MHZ
* @IWL_TLC_MNG_SGI_160MHZ_MSK: enable short GI for 160MHZ
*/
enum iwl_tlc_mng_cfg_gi {
IWL_TLC_MNG_SGI_20MHZ_MSK = BIT(0),
IWL_TLC_MNG_SGI_40MHZ_MSK = BIT(1),
IWL_TLC_MNG_SGI_80MHZ_MSK = BIT(2),
IWL_TLC_MNG_SGI_160MHZ_MSK = BIT(3),
}; };
/** /**
...@@ -145,25 +123,7 @@ enum iwl_tlc_mng_cfg_mode { ...@@ -145,25 +123,7 @@ enum iwl_tlc_mng_cfg_mode {
}; };
/** /**
* enum iwl_tlc_mng_vht_he_types - VHT HE types * enum iwl_tlc_mng_ht_rates - HT/VHT/HE rates
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU: VHT HT single user
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT: VHT HT single user extended
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU: VHT HT multiple users
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED: trigger based
* @IWL_TLC_MNG_VALID_VHT_HE_TYPES_NUM: a count of possible types
*/
enum iwl_tlc_mng_vht_he_types {
IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU = 0,
IWL_TLC_MNG_VALID_VHT_HE_TYPES_SU_EXT,
IWL_TLC_MNG_VALID_VHT_HE_TYPES_MU,
IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED,
IWL_TLC_MNG_VALID_VHT_HE_TYPES_NUM =
IWL_TLC_MNG_VALID_VHT_HE_TYPES_TRIG_BASED,
};
/**
* enum iwl_tlc_mng_ht_rates - HT/VHT rates
* @IWL_TLC_MNG_HT_RATE_MCS0: index of MCS0 * @IWL_TLC_MNG_HT_RATE_MCS0: index of MCS0
* @IWL_TLC_MNG_HT_RATE_MCS1: index of MCS1 * @IWL_TLC_MNG_HT_RATE_MCS1: index of MCS1
* @IWL_TLC_MNG_HT_RATE_MCS2: index of MCS2 * @IWL_TLC_MNG_HT_RATE_MCS2: index of MCS2
...@@ -174,6 +134,8 @@ enum iwl_tlc_mng_vht_he_types { ...@@ -174,6 +134,8 @@ enum iwl_tlc_mng_vht_he_types {
* @IWL_TLC_MNG_HT_RATE_MCS7: index of MCS7 * @IWL_TLC_MNG_HT_RATE_MCS7: index of MCS7
* @IWL_TLC_MNG_HT_RATE_MCS8: index of MCS8 * @IWL_TLC_MNG_HT_RATE_MCS8: index of MCS8
* @IWL_TLC_MNG_HT_RATE_MCS9: index of MCS9 * @IWL_TLC_MNG_HT_RATE_MCS9: index of MCS9
* @IWL_TLC_MNG_HT_RATE_MCS10: index of MCS10
* @IWL_TLC_MNG_HT_RATE_MCS11: index of MCS11
* @IWL_TLC_MNG_HT_RATE_MAX: maximal rate for HT/VHT * @IWL_TLC_MNG_HT_RATE_MAX: maximal rate for HT/VHT
*/ */
enum iwl_tlc_mng_ht_rates { enum iwl_tlc_mng_ht_rates {
...@@ -187,95 +149,73 @@ enum iwl_tlc_mng_ht_rates { ...@@ -187,95 +149,73 @@ enum iwl_tlc_mng_ht_rates {
IWL_TLC_MNG_HT_RATE_MCS7, IWL_TLC_MNG_HT_RATE_MCS7,
IWL_TLC_MNG_HT_RATE_MCS8, IWL_TLC_MNG_HT_RATE_MCS8,
IWL_TLC_MNG_HT_RATE_MCS9, IWL_TLC_MNG_HT_RATE_MCS9,
IWL_TLC_MNG_HT_RATE_MAX = IWL_TLC_MNG_HT_RATE_MCS9, IWL_TLC_MNG_HT_RATE_MCS10,
IWL_TLC_MNG_HT_RATE_MCS11,
IWL_TLC_MNG_HT_RATE_MAX = IWL_TLC_MNG_HT_RATE_MCS11,
}; };
/* Maximum supported tx antennas number */ /* Maximum supported tx antennas number */
#define MAX_RS_ANT_NUM 3 #define MAX_NSS 2
/** /**
* struct tlc_config_cmd - TLC configuration * struct tlc_config_cmd - TLC configuration
* @sta_id: station id * @sta_id: station id
* @reserved1: reserved * @reserved1: reserved
* @max_supp_ch_width: channel width * @max_ch_width: max supported channel width from @enum iwl_tlc_mng_cfg_cw
* @flags: bitmask of &enum iwl_tlc_mng_cfg_flags
* @chains: bitmask of &enum iwl_tlc_mng_cfg_chains
* @max_supp_ss: valid values are 0-3, 0 - spatial streams are not supported
* @valid_vht_he_types: bitmap of &enum iwl_tlc_mng_vht_he_types
* @non_ht_supp_rates: bitmap of supported legacy rates
* @ht_supp_rates: bitmap of supported HT/VHT rates, valid bits are 0-9
* @mode: &enum iwl_tlc_mng_cfg_mode * @mode: &enum iwl_tlc_mng_cfg_mode
* @chains: bitmask of &enum iwl_tlc_mng_cfg_chains
* @amsdu: TX amsdu is supported * @amsdu: TX amsdu is supported
* @he_supp_rates: bitmap of supported HE rates * @flags: bitmask of &enum iwl_tlc_mng_cfg_flags
* @non_ht_rates: bitmap of supported legacy rates
* @ht_rates: bitmap of &enum iwl_tlc_mng_ht_rates, per <nss, channel-width>
* pair (0 - 80mhz width and below, 1 - 160mhz).
* @max_mpdu_len: max MPDU length, in bytes
* @sgi_ch_width_supp: bitmap of SGI support per channel width * @sgi_ch_width_supp: bitmap of SGI support per channel width
* @he_gi_support: 11ax HE guard interval * use BIT(@enum iwl_tlc_mng_cfg_cw)
* @max_ampdu_cnt: max AMPDU size (frames count) * @reserved2: reserved
*/ */
struct iwl_tlc_config_cmd { struct iwl_tlc_config_cmd {
u8 sta_id; u8 sta_id;
u8 reserved1[3]; u8 reserved1[3];
u8 max_supp_ch_width; u8 max_ch_width;
u8 chains;
u8 max_supp_ss;
u8 valid_vht_he_types;
__le16 flags;
__le16 non_ht_supp_rates;
__le16 ht_supp_rates[MAX_RS_ANT_NUM];
u8 mode; u8 mode;
u8 chains;
u8 amsdu; u8 amsdu;
__le16 he_supp_rates; __le16 flags;
__le16 non_ht_rates;
__le16 ht_rates[MAX_NSS][2];
__le16 max_mpdu_len;
u8 sgi_ch_width_supp; u8 sgi_ch_width_supp;
u8 he_gi_support; u8 reserved2[1];
__le32 max_ampdu_cnt; } __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_2 */
} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_1 */
/**
* struct iwl_tlc_amsdu_notif - TLC AMSDU configuration
* @sta_id: station id
* @reserved: reserved
* @amsdu_size: Max AMSDU size, in bytes
* @amsdu_enabled: bitmap for per-TID AMSDU enablement
*/
struct iwl_tlc_amsdu_notif {
u8 sta_id;
u8 reserved[3];
__le16 amsdu_size;
__le16 amsdu_enabled;
} __packed; /* TLC_MNG_AMSDU_ENABLE_NTFY_API_S_VER_1 */
#define IWL_TLC_NOTIF_INIT_RATE_POS 0
#define IWL_TLC_NOTIF_INIT_RATE_MSK BIT(IWL_TLC_NOTIF_INIT_RATE_POS)
#define IWL_TLC_NOTIF_REQ_INTERVAL (500)
/** /**
* struct iwl_tlc_notif_req_config_cmd - request notif on specific changes * enum iwl_tlc_update_flags - updated fields
* @sta_id: relevant station * @IWL_TLC_NOTIF_FLAG_RATE: last initial rate update
* @reserved1: reserved * @IWL_TLC_NOTIF_FLAG_AMSDU: umsdu parameters update
* @flags: bitmap of requested notifications %IWL_TLC_NOTIF_INIT_\*
* @interval: minimum time between notifications from TLC to the driver (msec)
* @reserved2: reserved
*/ */
struct iwl_tlc_notif_req_config_cmd { enum iwl_tlc_update_flags {
u8 sta_id; IWL_TLC_NOTIF_FLAG_RATE = BIT(0),
u8 reserved1; IWL_TLC_NOTIF_FLAG_AMSDU = BIT(1),
__le16 flags; };
__le16 interval;
__le16 reserved2;
} __packed; /* TLC_MNG_NOTIF_REQ_CMD_API_S_VER_1 */
/** /**
* struct iwl_tlc_update_notif - TLC notification from FW * struct iwl_tlc_update_notif - TLC notification from FW
* @sta_id: station id * @sta_id: station id
* @reserved: reserved * @reserved: reserved
* @flags: bitmap of notifications reported * @flags: bitmap of notifications reported
* @values: field per flag in struct iwl_tlc_notif_req_config_cmd * @rate: current initial rate
* @amsdu_size: Max AMSDU size, in bytes
* @amsdu_enabled: bitmap for per-TID AMSDU enablement
*/ */
struct iwl_tlc_update_notif { struct iwl_tlc_update_notif {
u8 sta_id; u8 sta_id;
u8 reserved; u8 reserved[3];
__le16 flags; __le32 flags;
__le32 values[16]; __le32 rate;
} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_1 */ __le32 amsdu_size;
__le32 amsdu_enabled;
} __packed; /* TLC_MNG_UPDATE_NTFY_API_S_VER_2 */
/** /**
* enum iwl_tlc_debug_flags - debug options * enum iwl_tlc_debug_flags - debug options
......
...@@ -151,6 +151,8 @@ enum iwl_nvm_type { ...@@ -151,6 +151,8 @@ enum iwl_nvm_type {
#define ANT_AC (ANT_A | ANT_C) #define ANT_AC (ANT_A | ANT_C)
#define ANT_BC (ANT_B | ANT_C) #define ANT_BC (ANT_B | ANT_C)
#define ANT_ABC (ANT_A | ANT_B | ANT_C) #define ANT_ABC (ANT_A | ANT_B | ANT_C)
#define MAX_ANT_NUM 3
static inline u8 num_of_ant(u8 mask) static inline u8 num_of_ant(u8 mask)
{ {
......
...@@ -312,8 +312,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { ...@@ -312,8 +312,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
iwl_mvm_mu_mimo_grp_notif, RX_HANDLER_SYNC), iwl_mvm_mu_mimo_grp_notif, RX_HANDLER_SYNC),
RX_HANDLER_GRP(DATA_PATH_GROUP, STA_PM_NOTIF, RX_HANDLER_GRP(DATA_PATH_GROUP, STA_PM_NOTIF,
iwl_mvm_sta_pm_notif, RX_HANDLER_SYNC), iwl_mvm_sta_pm_notif, RX_HANDLER_SYNC),
RX_HANDLER_GRP(DATA_PATH_GROUP, TLC_MNG_AMSDU_ENABLE_NOTIF,
iwl_mvm_tlc_amsdu_notif, RX_HANDLER_SYNC),
}; };
#undef RX_HANDLER #undef RX_HANDLER
#undef RX_HANDLER_GRP #undef RX_HANDLER_GRP
...@@ -450,7 +448,6 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = { ...@@ -450,7 +448,6 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
HCMD_NAME(DQA_ENABLE_CMD), HCMD_NAME(DQA_ENABLE_CMD),
HCMD_NAME(UPDATE_MU_GROUPS_CMD), HCMD_NAME(UPDATE_MU_GROUPS_CMD),
HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD), HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
HCMD_NAME(TLC_MNG_AMSDU_ENABLE_NOTIF),
HCMD_NAME(STA_PM_NOTIF), HCMD_NAME(STA_PM_NOTIF),
HCMD_NAME(MU_GROUP_MGMT_NOTIF), HCMD_NAME(MU_GROUP_MGMT_NOTIF),
HCMD_NAME(RX_QUEUES_NOTIFICATION), HCMD_NAME(RX_QUEUES_NOTIFICATION),
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* GPL LICENSE SUMMARY * GPL LICENSE SUMMARY
* *
* Copyright(c) 2017 Intel Deutschland GmbH * Copyright(c) 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as * it under the terms of version 2 of the GNU General Public License as
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
* BSD LICENSE * BSD LICENSE
* *
* Copyright(c) 2017 Intel Deutschland GmbH * Copyright(c) 2017 Intel Deutschland GmbH
* Copyright(c) 2018 Intel Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
...@@ -65,14 +67,14 @@ static u8 rs_fw_bw_from_sta_bw(struct ieee80211_sta *sta) ...@@ -65,14 +67,14 @@ static u8 rs_fw_bw_from_sta_bw(struct ieee80211_sta *sta)
{ {
switch (sta->bandwidth) { switch (sta->bandwidth) {
case IEEE80211_STA_RX_BW_160: case IEEE80211_STA_RX_BW_160:
return IWL_TLC_MNG_MAX_CH_WIDTH_160MHZ; return IWL_TLC_MNG_CH_WIDTH_160MHZ;
case IEEE80211_STA_RX_BW_80: case IEEE80211_STA_RX_BW_80:
return IWL_TLC_MNG_MAX_CH_WIDTH_80MHZ; return IWL_TLC_MNG_CH_WIDTH_80MHZ;
case IEEE80211_STA_RX_BW_40: case IEEE80211_STA_RX_BW_40:
return IWL_TLC_MNG_MAX_CH_WIDTH_40MHZ; return IWL_TLC_MNG_CH_WIDTH_40MHZ;
case IEEE80211_STA_RX_BW_20: case IEEE80211_STA_RX_BW_20:
default: default:
return IWL_TLC_MNG_MAX_CH_WIDTH_20MHZ; return IWL_TLC_MNG_CH_WIDTH_20MHZ;
} }
} }
...@@ -85,7 +87,9 @@ static u8 rs_fw_set_active_chains(u8 chains) ...@@ -85,7 +87,9 @@ static u8 rs_fw_set_active_chains(u8 chains)
if (chains & ANT_B) if (chains & ANT_B)
fw_chains |= IWL_TLC_MNG_CHAIN_B_MSK; fw_chains |= IWL_TLC_MNG_CHAIN_B_MSK;
if (chains & ANT_C) if (chains & ANT_C)
fw_chains |= IWL_TLC_MNG_CHAIN_C_MSK; WARN(false,
"tlc offload doesn't support antenna C. chains: 0x%x\n",
chains);
return fw_chains; return fw_chains;
} }
...@@ -97,13 +101,13 @@ static u8 rs_fw_sgi_cw_support(struct ieee80211_sta *sta) ...@@ -97,13 +101,13 @@ static u8 rs_fw_sgi_cw_support(struct ieee80211_sta *sta)
u8 supp = 0; u8 supp = 0;
if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20) if (ht_cap->cap & IEEE80211_HT_CAP_SGI_20)
supp |= IWL_TLC_MNG_SGI_20MHZ_MSK; supp |= BIT(IWL_TLC_MNG_CH_WIDTH_20MHZ);
if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40) if (ht_cap->cap & IEEE80211_HT_CAP_SGI_40)
supp |= IWL_TLC_MNG_SGI_40MHZ_MSK; supp |= BIT(IWL_TLC_MNG_CH_WIDTH_40MHZ);
if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80) if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_80)
supp |= IWL_TLC_MNG_SGI_80MHZ_MSK; supp |= BIT(IWL_TLC_MNG_CH_WIDTH_80MHZ);
if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_160) if (vht_cap->cap & IEEE80211_VHT_CAP_SHORT_GI_160)
supp |= IWL_TLC_MNG_SGI_160MHZ_MSK; supp |= BIT(IWL_TLC_MNG_CH_WIDTH_160MHZ);
return supp; return supp;
} }
...@@ -114,9 +118,7 @@ static u16 rs_fw_set_config_flags(struct iwl_mvm *mvm, ...@@ -114,9 +118,7 @@ static u16 rs_fw_set_config_flags(struct iwl_mvm *mvm,
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
bool vht_ena = vht_cap && vht_cap->vht_supported; bool vht_ena = vht_cap && vht_cap->vht_supported;
u16 flags = IWL_TLC_MNG_CFG_FLAGS_CCK_MSK | u16 flags = 0;
IWL_TLC_MNG_CFG_FLAGS_DCM_MSK |
IWL_TLC_MNG_CFG_FLAGS_DD_MSK;
if (mvm->cfg->ht_params->stbc && if (mvm->cfg->ht_params->stbc &&
(num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) && (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
...@@ -129,16 +131,11 @@ static u16 rs_fw_set_config_flags(struct iwl_mvm *mvm, ...@@ -129,16 +131,11 @@ static u16 rs_fw_set_config_flags(struct iwl_mvm *mvm,
(vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))))
flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK;
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_BEAMFORMER) &&
(num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
(vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE))
flags |= IWL_TLC_MNG_CFG_FLAGS_BF_MSK;
return flags; return flags;
} }
static static
int rs_fw_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap, int rs_fw_vht_highest_rx_mcs_index(const struct ieee80211_sta_vht_cap *vht_cap,
int nss) int nss)
{ {
u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) & u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) &
...@@ -160,15 +157,16 @@ int rs_fw_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap, ...@@ -160,15 +157,16 @@ int rs_fw_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,
return 0; return 0;
} }
static void rs_fw_vht_set_enabled_rates(struct ieee80211_sta *sta, static void
struct ieee80211_sta_vht_cap *vht_cap, rs_fw_vht_set_enabled_rates(const struct ieee80211_sta *sta,
const struct ieee80211_sta_vht_cap *vht_cap,
struct iwl_tlc_config_cmd *cmd) struct iwl_tlc_config_cmd *cmd)
{ {
u16 supp; u16 supp;
int i, highest_mcs; int i, highest_mcs;
for (i = 0; i < sta->rx_nss; i++) { for (i = 0; i < sta->rx_nss; i++) {
if (i == MAX_RS_ANT_NUM) if (i == MAX_NSS)
break; break;
highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1); highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1);
...@@ -179,7 +177,9 @@ static void rs_fw_vht_set_enabled_rates(struct ieee80211_sta *sta, ...@@ -179,7 +177,9 @@ static void rs_fw_vht_set_enabled_rates(struct ieee80211_sta *sta,
if (sta->bandwidth == IEEE80211_STA_RX_BW_20) if (sta->bandwidth == IEEE80211_STA_RX_BW_20)
supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9); supp &= ~BIT(IWL_TLC_MNG_HT_RATE_MCS9);
cmd->ht_supp_rates[i] = cpu_to_le16(supp); cmd->ht_rates[i][0] = cpu_to_le16(supp);
if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
cmd->ht_rates[i][1] = cmd->ht_rates[i][0];
} }
} }
...@@ -190,8 +190,8 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta, ...@@ -190,8 +190,8 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
int i; int i;
unsigned long tmp; unsigned long tmp;
unsigned long supp; /* must be unsigned long for for_each_set_bit */ unsigned long supp; /* must be unsigned long for for_each_set_bit */
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
/* non HT rates */ /* non HT rates */
supp = 0; supp = 0;
...@@ -199,99 +199,71 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta, ...@@ -199,99 +199,71 @@ static void rs_fw_set_supp_rates(struct ieee80211_sta *sta,
for_each_set_bit(i, &tmp, BITS_PER_LONG) for_each_set_bit(i, &tmp, BITS_PER_LONG)
supp |= BIT(sband->bitrates[i].hw_value); supp |= BIT(sband->bitrates[i].hw_value);
cmd->non_ht_supp_rates = cpu_to_le16(supp); cmd->non_ht_rates = cpu_to_le16(supp);
cmd->mode = IWL_TLC_MNG_MODE_NON_HT; cmd->mode = IWL_TLC_MNG_MODE_NON_HT;
/* HT/VHT rates */
if (vht_cap && vht_cap->vht_supported) { if (vht_cap && vht_cap->vht_supported) {
cmd->mode = IWL_TLC_MNG_MODE_VHT; cmd->mode = IWL_TLC_MNG_MODE_VHT;
rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd); rs_fw_vht_set_enabled_rates(sta, vht_cap, cmd);
} else if (ht_cap && ht_cap->ht_supported) { } else if (ht_cap && ht_cap->ht_supported) {
cmd->mode = IWL_TLC_MNG_MODE_HT; cmd->mode = IWL_TLC_MNG_MODE_HT;
cmd->ht_supp_rates[0] = cpu_to_le16(ht_cap->mcs.rx_mask[0]); cmd->ht_rates[0][0] = cpu_to_le16(ht_cap->mcs.rx_mask[0]);
cmd->ht_supp_rates[1] = cpu_to_le16(ht_cap->mcs.rx_mask[1]); cmd->ht_rates[1][0] = cpu_to_le16(ht_cap->mcs.rx_mask[1]);
} }
} }
static void rs_fw_tlc_mng_notif_req_config(struct iwl_mvm *mvm, u8 sta_id) void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
{ struct iwl_rx_cmd_buffer *rxb)
u32 cmd_id = iwl_cmd_id(TLC_MNG_NOTIF_REQ_CMD, DATA_PATH_GROUP, 0);
struct iwl_tlc_notif_req_config_cmd cfg_cmd = {
.sta_id = sta_id,
.flags = cpu_to_le16(IWL_TLC_NOTIF_INIT_RATE_MSK),
.interval = cpu_to_le16(IWL_TLC_NOTIF_REQ_INTERVAL),
};
int ret;
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd);
if (ret)
IWL_ERR(mvm, "Failed to send TLC notif request (%d)\n", ret);
}
void iwl_mvm_tlc_amsdu_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
{ {
struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_tlc_amsdu_notif *notif; struct iwl_tlc_update_notif *notif;
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
struct iwl_mvm_sta *mvmsta; struct iwl_mvm_sta *mvmsta;
u16 size; struct iwl_lq_sta_rs_fw *lq_sta;
u32 flags;
notif = (void *)pkt->data;
if (WARN_ON(notif->sta_id >= ARRAY_SIZE(mvm->fw_id_to_mac_id)))
return;
rcu_read_lock(); rcu_read_lock();
notif = (void *)pkt->data;
sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]); sta = rcu_dereference(mvm->fw_id_to_mac_id[notif->sta_id]);
if (IS_ERR_OR_NULL(sta)) { if (IS_ERR_OR_NULL(sta)) {
rcu_read_unlock();
IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n", IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n",
notif->sta_id); notif->sta_id);
return; goto out;
} }
mvmsta = iwl_mvm_sta_from_mac80211(sta); mvmsta = iwl_mvm_sta_from_mac80211(sta);
size = min(le16_to_cpu(notif->amsdu_size), sta->max_amsdu_len);
mvmsta->amsdu_enabled = le16_to_cpu(notif->amsdu_enabled);
mvmsta->max_amsdu_len = size;
IWL_DEBUG_RATE(mvm,
"AMSDU notification. AMSDU size: %d, AMSDU selected size: %d, AMSDU TID bitmap 0x%X\n",
le16_to_cpu(notif->amsdu_size), size,
mvmsta->amsdu_enabled);
rcu_read_unlock();
};
void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_tlc_update_notif *notif;
struct iwl_mvm_sta *mvmsta;
struct iwl_lq_sta_rs_fw *lq_sta;
rcu_read_lock();
notif = (void *)pkt->data;
mvmsta = iwl_mvm_sta_from_staid_rcu(mvm, notif->sta_id);
if (!mvmsta) { if (!mvmsta) {
IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n", IWL_ERR(mvm, "Invalid sta id (%d) in FW TLC notification\n",
notif->sta_id); notif->sta_id);
goto out; goto out;
} }
flags = le32_to_cpu(notif->flags);
lq_sta = &mvmsta->lq_sta.rs_fw; lq_sta = &mvmsta->lq_sta.rs_fw;
if (le16_to_cpu(notif->flags) & IWL_TLC_NOTIF_INIT_RATE_MSK) { if (flags & IWL_TLC_NOTIF_FLAG_RATE) {
lq_sta->last_rate_n_flags = lq_sta->last_rate_n_flags = le32_to_cpu(notif->rate);
le32_to_cpu(notif->values[IWL_TLC_NOTIF_INIT_RATE_POS]);
IWL_DEBUG_RATE(mvm, "new rate_n_flags: 0x%X\n", IWL_DEBUG_RATE(mvm, "new rate_n_flags: 0x%X\n",
lq_sta->last_rate_n_flags); lq_sta->last_rate_n_flags);
} }
if (flags & IWL_TLC_NOTIF_FLAG_AMSDU) {
u16 size = le32_to_cpu(notif->amsdu_size);
if (WARN_ON(sta->max_amsdu_len < size))
goto out;
mvmsta->amsdu_enabled = le32_to_cpu(notif->amsdu_enabled);
mvmsta->max_amsdu_len = size;
IWL_DEBUG_RATE(mvm,
"AMSDU update. AMSDU size: %d, AMSDU selected size: %d, AMSDU TID bitmap 0x%X\n",
le32_to_cpu(notif->amsdu_size), size,
mvmsta->amsdu_enabled);
}
out: out:
rcu_read_unlock(); rcu_read_unlock();
} }
...@@ -306,11 +278,10 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -306,11 +278,10 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
struct iwl_tlc_config_cmd cfg_cmd = { struct iwl_tlc_config_cmd cfg_cmd = {
.sta_id = mvmsta->sta_id, .sta_id = mvmsta->sta_id,
.max_supp_ch_width = rs_fw_bw_from_sta_bw(sta), .max_ch_width = rs_fw_bw_from_sta_bw(sta),
.flags = cpu_to_le16(rs_fw_set_config_flags(mvm, sta)), .flags = cpu_to_le16(rs_fw_set_config_flags(mvm, sta)),
.chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)), .chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)),
.max_supp_ss = sta->rx_nss, .max_mpdu_len = cpu_to_le16(sta->max_amsdu_len),
.max_ampdu_cnt = cpu_to_le32(mvmsta->max_agg_bufsize),
.sgi_ch_width_supp = rs_fw_sgi_cw_support(sta), .sgi_ch_width_supp = rs_fw_sgi_cw_support(sta),
.amsdu = iwl_mvm_is_csum_supported(mvm), .amsdu = iwl_mvm_is_csum_supported(mvm),
}; };
...@@ -327,8 +298,6 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -327,8 +298,6 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd); ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd);
if (ret) if (ret)
IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret); IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret);
rs_fw_tlc_mng_notif_req_config(mvm, cfg_cmd.sta_id);
} }
int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
......
...@@ -456,6 +456,4 @@ int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, ...@@ -456,6 +456,4 @@ int rs_fw_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
bool enable); bool enable);
void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm, void iwl_mvm_tlc_update_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb); struct iwl_rx_cmd_buffer *rxb);
void iwl_mvm_tlc_amsdu_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb);
#endif /* __rs__ */ #endif /* __rs__ */
...@@ -278,8 +278,8 @@ u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx) ...@@ -278,8 +278,8 @@ u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx)
u8 ind = last_idx; u8 ind = last_idx;
int i; int i;
for (i = 0; i < MAX_RS_ANT_NUM; i++) { for (i = 0; i < MAX_ANT_NUM; i++) {
ind = (ind + 1) % MAX_RS_ANT_NUM; ind = (ind + 1) % MAX_ANT_NUM;
if (valid & BIT(ind)) if (valid & BIT(ind))
return ind; return ind;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment