Commit 444474dd authored by John W. Linville's avatar John W. Linville
parents a72e25f7 246dd992
...@@ -83,6 +83,8 @@ ...@@ -83,6 +83,8 @@
#define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */ #define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */
#define IWL3160_NVM_VERSION 0x709 #define IWL3160_NVM_VERSION 0x709
#define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */ #define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */
#define IWL7265_NVM_VERSION 0x0a1d
#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
#define IWL7260_FW_PRE "iwlwifi-7260-" #define IWL7260_FW_PRE "iwlwifi-7260-"
#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode" #define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode"
...@@ -90,6 +92,9 @@ ...@@ -90,6 +92,9 @@
#define IWL3160_FW_PRE "iwlwifi-3160-" #define IWL3160_FW_PRE "iwlwifi-3160-"
#define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode" #define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode"
#define IWL7265_FW_PRE "iwlwifi-7265-"
#define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"
static const struct iwl_base_params iwl7000_base_params = { static const struct iwl_base_params iwl7000_base_params = {
.eeprom_size = OTP_LOW_IMAGE_SIZE, .eeprom_size = OTP_LOW_IMAGE_SIZE,
.num_of_queues = IWLAGN_NUM_QUEUES, .num_of_queues = IWLAGN_NUM_QUEUES,
...@@ -182,5 +187,14 @@ const struct iwl_cfg iwl3160_n_cfg = { ...@@ -182,5 +187,14 @@ const struct iwl_cfg iwl3160_n_cfg = {
.nvm_calib_ver = IWL3160_TX_POWER_VERSION, .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
}; };
const struct iwl_cfg iwl7265_2ac_cfg = {
.name = "Intel(R) Dual Band Wireless AC 7265",
.fw_name_pre = IWL7265_FW_PRE,
IWL_DEVICE_7000,
.ht_params = &iwl7000_ht_params,
.nvm_ver = IWL7265_NVM_VERSION,
.nvm_calib_ver = IWL7265_TX_POWER_VERSION,
};
MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
...@@ -292,6 +292,7 @@ extern const struct iwl_cfg iwl7260_n_cfg; ...@@ -292,6 +292,7 @@ extern const struct iwl_cfg iwl7260_n_cfg;
extern const struct iwl_cfg iwl3160_2ac_cfg; extern const struct iwl_cfg iwl3160_2ac_cfg;
extern const struct iwl_cfg iwl3160_2n_cfg; extern const struct iwl_cfg iwl3160_2n_cfg;
extern const struct iwl_cfg iwl3160_n_cfg; extern const struct iwl_cfg iwl3160_n_cfg;
extern const struct iwl_cfg iwl7265_2ac_cfg;
#endif /* CONFIG_IWLMVM */ #endif /* CONFIG_IWLMVM */
#endif /* __IWL_CONFIG_H__ */ #endif /* __IWL_CONFIG_H__ */
...@@ -394,6 +394,38 @@ ...@@ -394,6 +394,38 @@
#define CSR_DRAM_INT_TBL_ENABLE (1 << 31) #define CSR_DRAM_INT_TBL_ENABLE (1 << 31)
#define CSR_DRAM_INIT_TBL_WRAP_CHECK (1 << 27) #define CSR_DRAM_INIT_TBL_WRAP_CHECK (1 << 27)
/* SECURE boot registers */
#define CSR_SECURE_BOOT_CONFIG_ADDR (0x100)
enum secure_boot_config_reg {
CSR_SECURE_BOOT_CONFIG_INSPECTOR_BURNED_IN_OTP = 0x00000001,
CSR_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ = 0x00000002,
};
#define CSR_SECURE_BOOT_CPU1_STATUS_ADDR (0x100)
#define CSR_SECURE_BOOT_CPU2_STATUS_ADDR (0x100)
enum secure_boot_status_reg {
CSR_SECURE_BOOT_CPU_STATUS_VERF_STATUS = 0x00000003,
CSR_SECURE_BOOT_CPU_STATUS_VERF_COMPLETED = 0x00000002,
CSR_SECURE_BOOT_CPU_STATUS_VERF_SUCCESS = 0x00000004,
CSR_SECURE_BOOT_CPU_STATUS_VERF_FAIL = 0x00000008,
CSR_SECURE_BOOT_CPU_STATUS_SIGN_VERF_FAIL = 0x00000010,
};
#define CSR_UCODE_LOAD_STATUS_ADDR (0x100)
enum secure_load_status_reg {
CSR_CPU_STATUS_LOADING_STARTED = 0x00000001,
CSR_CPU_STATUS_LOADING_COMPLETED = 0x00000002,
CSR_CPU_STATUS_NUM_OF_LAST_COMPLETED = 0x000000F8,
CSR_CPU_STATUS_NUM_OF_LAST_LOADED_BLOCK = 0x0000FF00,
};
#define CSR_SECURE_INSPECTOR_CODE_ADDR (0x100)
#define CSR_SECURE_INSPECTOR_DATA_ADDR (0x100)
#define CSR_SECURE_TIME_OUT (100)
#define FH_TCSR_0_REG0 (0x1D00)
/* /*
* HBUS (Host-side Bus) * HBUS (Host-side Bus)
* *
......
...@@ -483,6 +483,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, ...@@ -483,6 +483,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
const u8 *tlv_data; const u8 *tlv_data;
char buildstr[25]; char buildstr[25];
u32 build; u32 build;
int num_of_cpus;
if (len < sizeof(*ucode)) { if (len < sizeof(*ucode)) {
IWL_ERR(drv, "uCode has invalid length: %zd\n", len); IWL_ERR(drv, "uCode has invalid length: %zd\n", len);
...@@ -692,6 +693,42 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, ...@@ -692,6 +693,42 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
goto invalid_tlv_len; goto invalid_tlv_len;
drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data); drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data);
break; break;
case IWL_UCODE_TLV_SECURE_SEC_RT:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
tlv_len);
drv->fw.mvm_fw = true;
drv->fw.img[IWL_UCODE_REGULAR].is_secure = true;
break;
case IWL_UCODE_TLV_SECURE_SEC_INIT:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT,
tlv_len);
drv->fw.mvm_fw = true;
drv->fw.img[IWL_UCODE_INIT].is_secure = true;
break;
case IWL_UCODE_TLV_SECURE_SEC_WOWLAN:
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN,
tlv_len);
drv->fw.mvm_fw = true;
drv->fw.img[IWL_UCODE_WOWLAN].is_secure = true;
break;
case IWL_UCODE_TLV_NUM_OF_CPU:
if (tlv_len != sizeof(u32))
goto invalid_tlv_len;
num_of_cpus =
le32_to_cpup((__le32 *)tlv_data);
if (num_of_cpus == 2) {
drv->fw.img[IWL_UCODE_REGULAR].is_dual_cpus =
true;
drv->fw.img[IWL_UCODE_INIT].is_dual_cpus =
true;
drv->fw.img[IWL_UCODE_WOWLAN].is_dual_cpus =
true;
} else if ((num_of_cpus > 2) || (num_of_cpus < 1)) {
IWL_ERR(drv, "Driver support upto 2 CPUs\n");
return -EINVAL;
}
break;
default: default:
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
break; break;
......
...@@ -121,6 +121,10 @@ enum iwl_ucode_tlv_type { ...@@ -121,6 +121,10 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_SEC_WOWLAN = 21, IWL_UCODE_TLV_SEC_WOWLAN = 21,
IWL_UCODE_TLV_DEF_CALIB = 22, IWL_UCODE_TLV_DEF_CALIB = 22,
IWL_UCODE_TLV_PHY_SKU = 23, IWL_UCODE_TLV_PHY_SKU = 23,
IWL_UCODE_TLV_SECURE_SEC_RT = 24,
IWL_UCODE_TLV_SECURE_SEC_INIT = 25,
IWL_UCODE_TLV_SECURE_SEC_WOWLAN = 26,
IWL_UCODE_TLV_NUM_OF_CPU = 27,
}; };
struct iwl_ucode_tlv { struct iwl_ucode_tlv {
......
...@@ -75,11 +75,23 @@ ...@@ -75,11 +75,23 @@
* @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
* @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
* @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD * @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD
* @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan
* offload profile config command.
* @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api * @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api
* @IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2: using the new time event API. * @IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2: using the new time event API.
* @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
* (rather than two) IPv6 addresses * (rather than two) IPv6 addresses
* @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API * @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API
* @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
* from the probe request template.
* @IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API: modified D3 API to allow keeping
* connection when going back to D0
* @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version)
* @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
* @IWL_UCODE_TLV_FLAGS_SCHED_SCAN: this uCode image supports scheduled scan.
* @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API
* @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command
* containing CAM (Continuous Active Mode) indication.
*/ */
enum iwl_ucode_tlv_flag { enum iwl_ucode_tlv_flag {
IWL_UCODE_TLV_FLAGS_PAN = BIT(0), IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
...@@ -87,11 +99,20 @@ enum iwl_ucode_tlv_flag { ...@@ -87,11 +99,20 @@ enum iwl_ucode_tlv_flag {
IWL_UCODE_TLV_FLAGS_MFP = BIT(2), IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
IWL_UCODE_TLV_FLAGS_P2P = BIT(3), IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
IWL_UCODE_TLV_FLAGS_NEWBT_COEX = BIT(5),
IWL_UCODE_TLV_FLAGS_UAPSD = BIT(6), IWL_UCODE_TLV_FLAGS_UAPSD = BIT(6),
IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7),
IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8), IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8),
IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9), IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9),
IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10), IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10),
IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11), IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11),
IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12),
IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API = BIT(14),
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL = BIT(15),
IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE = BIT(16),
IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17),
IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19),
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20),
}; };
/* The default calibrate table size if not specified by firmware file */ /* The default calibrate table size if not specified by firmware file */
...@@ -133,7 +154,8 @@ enum iwl_ucode_sec { ...@@ -133,7 +154,8 @@ enum iwl_ucode_sec {
* For 16.0 uCode and above, there is no differentiation between sections, * For 16.0 uCode and above, there is no differentiation between sections,
* just an offset to the HW address. * just an offset to the HW address.
*/ */
#define IWL_UCODE_SECTION_MAX 4 #define IWL_UCODE_SECTION_MAX 6
#define IWL_UCODE_FIRST_SECTION_OF_SECOND_CPU (IWL_UCODE_SECTION_MAX/2)
struct iwl_ucode_capabilities { struct iwl_ucode_capabilities {
u32 max_probe_length; u32 max_probe_length;
...@@ -150,6 +172,8 @@ struct fw_desc { ...@@ -150,6 +172,8 @@ struct fw_desc {
struct fw_img { struct fw_img {
struct fw_desc sec[IWL_UCODE_SECTION_MAX]; struct fw_desc sec[IWL_UCODE_SECTION_MAX];
bool is_secure;
bool is_dual_cpus;
}; };
/* uCode version contains 4 values: Major/Minor/API/Serial */ /* uCode version contains 4 values: Major/Minor/API/Serial */
......
...@@ -97,6 +97,8 @@ ...@@ -97,6 +97,8 @@
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
#define APMG_RTC_INT_STT_RFKILL (0x10000000)
/* Device system time */ /* Device system time */
#define DEVICE_SYSTEM_TIME_REG 0xA0206C #define DEVICE_SYSTEM_TIME_REG 0xA0206C
......
This diff is collapsed.
...@@ -70,7 +70,9 @@ ...@@ -70,7 +70,9 @@
#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC) #define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC) #define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
#define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20 #define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20
#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 20 #define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8
#define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30
#define IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS 20
#define IWL_MVM_PS_HEAVY_TX_THLD_PERCENT 50 #define IWL_MVM_PS_HEAVY_TX_THLD_PERCENT 50
#define IWL_MVM_PS_HEAVY_RX_THLD_PERCENT 50 #define IWL_MVM_PS_HEAVY_RX_THLD_PERCENT 50
#define IWL_MVM_PS_SNOOZE_INTERVAL 25 #define IWL_MVM_PS_SNOOZE_INTERVAL 25
......
This diff is collapsed.
...@@ -246,58 +246,56 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, ...@@ -246,58 +246,56 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos); return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
} }
static ssize_t iwl_dbgfs_power_down_allow_write(struct file *file, static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,
const char __user *user_buf, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct iwl_mvm *mvm = file->private_data; struct iwl_mvm *mvm = file->private_data;
char buf[8] = {}; char buf[64];
int allow; int bufsz = sizeof(buf);
int pos = 0;
if (!mvm->ucode_loaded)
return -EIO;
if (copy_from_user(buf, user_buf, sizeof(buf)))
return -EFAULT;
if (sscanf(buf, "%d", &allow) != 1)
return -EINVAL;
IWL_DEBUG_POWER(mvm, "%s device power down\n",
allow ? "allow" : "prevent");
/* pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d0=%d\n",
* TODO: Send REPLY_DEBUG_CMD (0xf0) when FW support it mvm->disable_power_off);
*/ pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d3=%d\n",
mvm->disable_power_off_d3);
return count; return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
} }
static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file,
const char __user *user_buf, const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct iwl_mvm *mvm = file->private_data; struct iwl_mvm *mvm = file->private_data;
char buf[8] = {}; char buf[64] = {};
int allow; int ret;
int val;
if (!mvm->ucode_loaded)
return -EIO;
if (copy_from_user(buf, user_buf, sizeof(buf))) count = min_t(size_t, count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, count))
return -EFAULT; return -EFAULT;
if (sscanf(buf, "%d", &allow) != 1) if (!strncmp("disable_power_off_d0=", buf, 21)) {
if (sscanf(buf + 21, "%d", &val) != 1)
return -EINVAL; return -EINVAL;
mvm->disable_power_off = val;
} else if (!strncmp("disable_power_off_d3=", buf, 21)) {
if (sscanf(buf + 21, "%d", &val) != 1)
return -EINVAL;
mvm->disable_power_off_d3 = val;
} else {
return -EINVAL;
}
IWL_DEBUG_POWER(mvm, "%s device power down in d3\n", mutex_lock(&mvm->mutex);
allow ? "allow" : "prevent"); ret = iwl_mvm_power_update_device_mode(mvm);
mutex_unlock(&mvm->mutex);
/*
* TODO: When WoWLAN FW alive notification happens, driver will send
* REPLY_DEBUG_CMD setting power_down_allow flag according to
* mvm->prevent_power_down_d3
*/
mvm->prevent_power_down_d3 = !allow;
return count; return ret ?: count;
} }
static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm, static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
...@@ -371,7 +369,8 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file, ...@@ -371,7 +369,8 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
int val; int val;
int ret; int ret;
if (copy_from_user(buf, user_buf, sizeof(buf))) count = min_t(size_t, count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, count))
return -EFAULT; return -EFAULT;
if (!strncmp("keep_alive=", buf, 11)) { if (!strncmp("keep_alive=", buf, 11)) {
...@@ -394,7 +393,9 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file, ...@@ -394,7 +393,9 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
if (sscanf(buf + 16, "%d", &val) != 1) if (sscanf(buf + 16, "%d", &val) != 1)
return -EINVAL; return -EINVAL;
param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT; param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT;
} else if (!strncmp("disable_power_off=", buf, 18)) { } else if (!strncmp("disable_power_off=", buf, 18) &&
!(mvm->fw->ucode_capa.flags &
IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) {
if (sscanf(buf + 18, "%d", &val) != 1) if (sscanf(buf + 18, "%d", &val) != 1)
return -EINVAL; return -EINVAL;
param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF; param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
...@@ -590,6 +591,12 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, ...@@ -590,6 +591,12 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
notif->bt_agg_traffic_load); notif->bt_agg_traffic_load);
pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n", pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n",
notif->bt_ci_compliance); notif->bt_ci_compliance);
pos += scnprintf(buf+pos, bufsz-pos, "primary_ch_lut = %d\n",
le32_to_cpu(notif->primary_ch_lut));
pos += scnprintf(buf+pos, bufsz-pos, "secondary_ch_lut = %d\n",
le32_to_cpu(notif->secondary_ch_lut));
pos += scnprintf(buf+pos, bufsz-pos, "bt_activity_grading = %d\n",
le32_to_cpu(notif->bt_activity_grading));
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
...@@ -600,6 +607,38 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, ...@@ -600,6 +607,38 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
} }
#undef BT_MBOX_PRINT #undef BT_MBOX_PRINT
static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_mvm *mvm = file->private_data;
struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd;
char buf[256];
int bufsz = sizeof(buf);
int pos = 0;
mutex_lock(&mvm->mutex);
pos += scnprintf(buf+pos, bufsz-pos, "Channel inhibition CMD\n");
pos += scnprintf(buf+pos, bufsz-pos,
"\tPrimary Channel Bitmap 0x%016llx Fat: %d\n",
le64_to_cpu(cmd->bt_primary_ci),
!!cmd->co_run_bw_primary);
pos += scnprintf(buf+pos, bufsz-pos,
"\tSecondary Channel Bitmap 0x%016llx Fat: %d\n",
le64_to_cpu(cmd->bt_secondary_ci),
!!cmd->co_run_bw_secondary);
pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n");
pos += scnprintf(buf+pos, bufsz-pos, "\tACK Kill Mask 0x%08x\n",
iwl_bt_ack_kill_msk[mvm->bt_kill_msk]);
pos += scnprintf(buf+pos, bufsz-pos, "\tCTS Kill Mask 0x%08x\n",
iwl_bt_cts_kill_msk[mvm->bt_kill_msk]);
mutex_unlock(&mvm->mutex);
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
#define PRINT_STATS_LE32(_str, _val) \ #define PRINT_STATS_LE32(_str, _val) \
pos += scnprintf(buf + pos, bufsz - pos, \ pos += scnprintf(buf + pos, bufsz - pos, \
fmt_table, _str, \ fmt_table, _str, \
...@@ -615,9 +654,11 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, ...@@ -615,9 +654,11 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
int pos = 0; int pos = 0;
char *buf; char *buf;
int ret; int ret;
int bufsz = sizeof(struct mvm_statistics_rx_phy) * 20 + /* 43 is the size of each data line, 33 is the size of each header */
sizeof(struct mvm_statistics_rx_non_phy) * 10 + size_t bufsz =
sizeof(struct mvm_statistics_rx_ht_phy) * 10 + 200; ((sizeof(struct mvm_statistics_rx) / sizeof(__le32)) * 43) +
(4 * 33) + 1;
struct mvm_statistics_rx_phy *ofdm; struct mvm_statistics_rx_phy *ofdm;
struct mvm_statistics_rx_phy *cck; struct mvm_statistics_rx_phy *cck;
struct mvm_statistics_rx_non_phy *general; struct mvm_statistics_rx_non_phy *general;
...@@ -712,6 +753,7 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, ...@@ -712,6 +753,7 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
PRINT_STATS_LE32("beacon_energy_b", general->beacon_energy_b); PRINT_STATS_LE32("beacon_energy_b", general->beacon_energy_b);
PRINT_STATS_LE32("beacon_energy_c", general->beacon_energy_c); PRINT_STATS_LE32("beacon_energy_c", general->beacon_energy_c);
PRINT_STATS_LE32("num_bt_kills", general->num_bt_kills); PRINT_STATS_LE32("num_bt_kills", general->num_bt_kills);
PRINT_STATS_LE32("mac_id", general->mac_id);
PRINT_STATS_LE32("directed_data_mpdu", general->directed_data_mpdu); PRINT_STATS_LE32("directed_data_mpdu", general->directed_data_mpdu);
pos += scnprintf(buf + pos, bufsz - pos, fmt_header, pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
...@@ -757,6 +799,59 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, ...@@ -757,6 +799,59 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,
return count; return count;
} }
static ssize_t
iwl_dbgfs_scan_ant_rxchain_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_mvm *mvm = file->private_data;
int pos = 0;
char buf[32];
const size_t bufsz = sizeof(buf);
/* print which antennas were set for the scan command by the user */
pos += scnprintf(buf + pos, bufsz - pos, "Antennas for scan: ");
if (mvm->scan_rx_ant & ANT_A)
pos += scnprintf(buf + pos, bufsz - pos, "A");
if (mvm->scan_rx_ant & ANT_B)
pos += scnprintf(buf + pos, bufsz - pos, "B");
if (mvm->scan_rx_ant & ANT_C)
pos += scnprintf(buf + pos, bufsz - pos, "C");
pos += scnprintf(buf + pos, bufsz - pos, " (%hhx)\n", mvm->scan_rx_ant);
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
static ssize_t
iwl_dbgfs_scan_ant_rxchain_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_mvm *mvm = file->private_data;
char buf[8];
int buf_size;
u8 scan_rx_ant;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
/* get the argument from the user and check if it is valid */
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%hhx", &scan_rx_ant) != 1)
return -EINVAL;
if (scan_rx_ant > ANT_ABC)
return -EINVAL;
if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw))
return -EINVAL;
/* change the rx antennas for scan command */
mvm->scan_rx_ant = scan_rx_ant;
return count;
}
static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif, static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif,
enum iwl_dbgfs_bf_mask param, int value) enum iwl_dbgfs_bf_mask param, int value)
{ {
...@@ -968,7 +1063,8 @@ static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, ...@@ -968,7 +1063,8 @@ static ssize_t iwl_dbgfs_d3_sram_write(struct file *file,
char buf[8] = {}; char buf[8] = {};
int store; int store;
if (copy_from_user(buf, user_buf, sizeof(buf))) count = min_t(size_t, count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, count))
return -EFAULT; return -EFAULT;
if (sscanf(buf, "%d", &store) != 1) if (sscanf(buf, "%d", &store) != 1)
...@@ -1063,10 +1159,12 @@ MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); ...@@ -1063,10 +1159,12 @@ MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram);
MVM_DEBUGFS_READ_FILE_OPS(stations); MVM_DEBUGFS_READ_FILE_OPS(stations);
MVM_DEBUGFS_READ_FILE_OPS(bt_notif); MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off);
MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram); MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram);
#endif #endif
...@@ -1087,10 +1185,14 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) ...@@ -1087,10 +1185,14 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)
MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir,
S_IRUSR | S_IWUSR);
MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
S_IWUSR | S_IRUSR);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR); MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR);
......
...@@ -82,6 +82,8 @@ ...@@ -82,6 +82,8 @@
* @BT_USE_DEFAULTS: * @BT_USE_DEFAULTS:
* @BT_SYNC_2_BT_DISABLE: * @BT_SYNC_2_BT_DISABLE:
* @BT_COEX_CORUNNING_TBL_EN: * @BT_COEX_CORUNNING_TBL_EN:
*
* The COEX_MODE must be set for each command. Even if it is not changed.
*/ */
enum iwl_bt_coex_flags { enum iwl_bt_coex_flags {
BT_CH_PRIMARY_EN = BIT(0), BT_CH_PRIMARY_EN = BIT(0),
...@@ -95,14 +97,16 @@ enum iwl_bt_coex_flags { ...@@ -95,14 +97,16 @@ enum iwl_bt_coex_flags {
BT_COEX_NW = 0x3 << BT_COEX_MODE_POS, BT_COEX_NW = 0x3 << BT_COEX_MODE_POS,
BT_USE_DEFAULTS = BIT(6), BT_USE_DEFAULTS = BIT(6),
BT_SYNC_2_BT_DISABLE = BIT(7), BT_SYNC_2_BT_DISABLE = BIT(7),
/* BT_COEX_CORUNNING_TBL_EN = BIT(8),
* For future use - when the flags will be enlarged BT_COEX_MPLUT_TBL_EN = BIT(9),
* BT_COEX_CORUNNING_TBL_EN = BIT(8), /* Bit 10 is reserved */
*/ BT_COEX_WF_PRIO_BOOST_CHECK_EN = BIT(11),
}; };
/* /*
* indicates what has changed in the BT_COEX command. * indicates what has changed in the BT_COEX command.
* BT_VALID_ENABLE must be set for each command. Commands without this bit will
* discarded by the firmware
*/ */
enum iwl_bt_coex_valid_bit_msk { enum iwl_bt_coex_valid_bit_msk {
BT_VALID_ENABLE = BIT(0), BT_VALID_ENABLE = BIT(0),
...@@ -121,11 +125,8 @@ enum iwl_bt_coex_valid_bit_msk { ...@@ -121,11 +125,8 @@ enum iwl_bt_coex_valid_bit_msk {
BT_VALID_CORUN_LUT_40 = BIT(13), BT_VALID_CORUN_LUT_40 = BIT(13),
BT_VALID_ANT_ISOLATION = BIT(14), BT_VALID_ANT_ISOLATION = BIT(14),
BT_VALID_ANT_ISOLATION_THRS = BIT(15), BT_VALID_ANT_ISOLATION_THRS = BIT(15),
/* BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),
* For future use - when the valid flags will be enlarged BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),
* BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16),
* BT_VALID_TXRX_MAX_FREQ_0 = BIT(17),
*/
}; };
/** /**
...@@ -142,48 +143,88 @@ enum iwl_bt_reduced_tx_power { ...@@ -142,48 +143,88 @@ enum iwl_bt_reduced_tx_power {
BT_REDUCED_TX_POWER_DATA = BIT(1), BT_REDUCED_TX_POWER_DATA = BIT(1),
}; };
enum iwl_bt_coex_lut_type {
BT_COEX_TIGHT_LUT = 0,
BT_COEX_LOOSE_LUT,
BT_COEX_TX_DIS_LUT,
BT_COEX_MAX_LUT,
};
#define BT_COEX_LUT_SIZE (12) #define BT_COEX_LUT_SIZE (12)
#define BT_COEX_CORUN_LUT_SIZE (32)
#define BT_COEX_MULTI_PRIO_LUT_SIZE (2)
#define BT_COEX_BOOST_SIZE (4)
#define BT_REDUCED_TX_POWER_BIT BIT(7)
/** /**
* struct iwl_bt_coex_cmd - bt coex configuration command * struct iwl_bt_coex_cmd - bt coex configuration command
* @flags:&enum iwl_bt_coex_flags * @flags:&enum iwl_bt_coex_flags
* @lead_time:
* @max_kill: * @max_kill:
* @bt3_time_t7_value:
* @kill_ack_msk:
* @kill_cts_msk:
* @bt3_prio_sample_time:
* @bt3_timer_t2_value:
* @bt4_reaction_time:
* @decision_lut[12]:
* @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power
* @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk * @bt4_antenna_isolation:
* @bt_prio_boost: values for PTA boost register * @bt4_antenna_isolation_thr:
* @bt4_tx_tx_delta_freq_thr:
* @bt4_tx_rx_max_freq0:
* @bt_prio_boost:
* @wifi_tx_prio_boost: SW boost of wifi tx priority * @wifi_tx_prio_boost: SW boost of wifi tx priority
* @wifi_rx_prio_boost: SW boost of wifi rx priority * @wifi_rx_prio_boost: SW boost of wifi rx priority
* @kill_ack_msk:
* @kill_cts_msk:
* @decision_lut:
* @bt4_multiprio_lut:
* @bt4_corun_lut20:
* @bt4_corun_lut40:
* @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk
* *
* The structure is used for the BT_COEX command. * The structure is used for the BT_COEX command.
*/ */
struct iwl_bt_coex_cmd { struct iwl_bt_coex_cmd {
u8 flags; __le32 flags;
u8 lead_time;
u8 max_kill; u8 max_kill;
u8 bt3_time_t7_value; u8 bt_reduced_tx_power;
u8 reserved[2];
u8 bt4_antenna_isolation;
u8 bt4_antenna_isolation_thr;
u8 bt4_tx_tx_delta_freq_thr;
u8 bt4_tx_rx_max_freq0;
__le32 bt_prio_boost[BT_COEX_BOOST_SIZE];
__le32 wifi_tx_prio_boost;
__le32 wifi_rx_prio_boost;
__le32 kill_ack_msk; __le32 kill_ack_msk;
__le32 kill_cts_msk; __le32 kill_cts_msk;
u8 bt3_prio_sample_time;
u8 bt3_timer_t2_value; __le32 decision_lut[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE];
__le16 bt4_reaction_time; __le32 bt4_multiprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE];
__le32 decision_lut[BT_COEX_LUT_SIZE]; __le32 bt4_corun_lut20[BT_COEX_CORUN_LUT_SIZE];
u8 bt_reduced_tx_power; __le32 bt4_corun_lut40[BT_COEX_CORUN_LUT_SIZE];
u8 reserved;
__le16 valid_bit_msk; __le32 valid_bit_msk;
__le32 bt_prio_boost;
u8 reserved2;
u8 wifi_tx_prio_boost;
__le16 wifi_rx_prio_boost;
} __packed; /* BT_COEX_CMD_API_S_VER_3 */ } __packed; /* BT_COEX_CMD_API_S_VER_3 */
/**
* struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command
* @bt_primary_ci:
* @bt_secondary_ci:
* @co_run_bw_primary:
* @co_run_bw_secondary:
* @primary_ch_phy_id:
* @secondary_ch_phy_id:
*
* Used for BT_COEX_CI command
*/
struct iwl_bt_coex_ci_cmd {
__le64 bt_primary_ci;
__le64 bt_secondary_ci;
u8 co_run_bw_primary;
u8 co_run_bw_secondary;
u8 primary_ch_phy_id;
u8 secondary_ch_phy_id;
} __packed; /* BT_CI_MSG_API_S_VER_1 */
#define BT_MBOX(n_dw, _msg, _pos, _nbits) \ #define BT_MBOX(n_dw, _msg, _pos, _nbits) \
BT_MBOX##n_dw##_##_msg##_POS = (_pos), \ BT_MBOX##n_dw##_##_msg##_POS = (_pos), \
BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS
...@@ -244,23 +285,39 @@ enum iwl_bt_mxbox_dw3 { ...@@ -244,23 +285,39 @@ enum iwl_bt_mxbox_dw3 {
((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
>> BT_MBOX##_num##_##_field##_POS) >> BT_MBOX##_num##_##_field##_POS)
enum iwl_bt_activity_grading {
BT_OFF = 0,
BT_ON_NO_CONNECTION = 1,
BT_LOW_TRAFFIC = 2,
BT_HIGH_TRAFFIC = 3,
};
/** /**
* struct iwl_bt_coex_profile_notif - notification about BT coex * struct iwl_bt_coex_profile_notif - notification about BT coex
* @mbox_msg: message from BT to WiFi * @mbox_msg: message from BT to WiFi
* @:bt_status: 0 - off, 1 - on * @msg_idx: the index of the message
* @:bt_open_conn: number of BT connections open * @bt_status: 0 - off, 1 - on
* @:bt_traffic_load: load of BT traffic * @bt_open_conn: number of BT connections open
* @:bt_agg_traffic_load: aggregated load of BT traffic * @bt_traffic_load: load of BT traffic
* @:bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant * @bt_agg_traffic_load: aggregated load of BT traffic
* @bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
* @primary_ch_lut: LUT used for primary channel
* @secondary_ch_lut: LUT used for secondary channel
* @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading
*/ */
struct iwl_bt_coex_profile_notif { struct iwl_bt_coex_profile_notif {
__le32 mbox_msg[4]; __le32 mbox_msg[4];
__le32 msg_idx;
u8 bt_status; u8 bt_status;
u8 bt_open_conn; u8 bt_open_conn;
u8 bt_traffic_load; u8 bt_traffic_load;
u8 bt_agg_traffic_load; u8 bt_agg_traffic_load;
u8 bt_ci_compliance; u8 bt_ci_compliance;
u8 reserved[3]; u8 reserved[3];
__le32 primary_ch_lut;
__le32 secondary_ch_lut;
__le32 bt_activity_grading;
} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */ } __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */
enum iwl_bt_coex_prio_table_event { enum iwl_bt_coex_prio_table_event {
...@@ -300,20 +357,4 @@ struct iwl_bt_coex_prio_tbl_cmd { ...@@ -300,20 +357,4 @@ struct iwl_bt_coex_prio_tbl_cmd {
u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];
} __packed; } __packed;
enum iwl_bt_coex_env_action {
BT_COEX_ENV_CLOSE = 0,
BT_COEX_ENV_OPEN = 1,
}; /* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */
/**
* struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope
* @action: enum %iwl_bt_coex_env_action
* @type: enum %iwl_bt_coex_prio_table_event
*/
struct iwl_bt_coex_prot_env_cmd {
u8 action; /* 0 = closed, 1 = open */
u8 type; /* 0 .. 15 */
u8 reserved[2];
} __packed;
#endif /* __fw_api_bt_coex_h__ */ #endif /* __fw_api_bt_coex_h__ */
...@@ -100,7 +100,12 @@ enum iwl_proto_offloads { ...@@ -100,7 +100,12 @@ enum iwl_proto_offloads {
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1 2 #define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1 2
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2 6 #define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2 6
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX 6 #define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L 12
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S 4
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX 12
#define IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L 4
#define IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S 2
/** /**
* struct iwl_proto_offload_cmd_common - ARP/NS offload common part * struct iwl_proto_offload_cmd_common - ARP/NS offload common part
...@@ -155,6 +160,43 @@ struct iwl_proto_offload_cmd_v2 { ...@@ -155,6 +160,43 @@ struct iwl_proto_offload_cmd_v2 {
u8 reserved2[3]; u8 reserved2[3];
} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_2 */ } __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_2 */
struct iwl_ns_config {
struct in6_addr source_ipv6_addr;
struct in6_addr dest_ipv6_addr;
u8 target_mac_addr[ETH_ALEN];
__le16 reserved;
} __packed; /* NS_OFFLOAD_CONFIG */
struct iwl_targ_addr {
struct in6_addr addr;
__le32 config_num;
} __packed; /* TARGET_IPV6_ADDRESS */
/**
* struct iwl_proto_offload_cmd_v3_small - ARP/NS offload configuration
* @common: common/IPv4 configuration
* @target_ipv6_addr: target IPv6 addresses
* @ns_config: NS offload configurations
*/
struct iwl_proto_offload_cmd_v3_small {
struct iwl_proto_offload_cmd_common common;
__le32 num_valid_ipv6_addrs;
struct iwl_targ_addr targ_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S];
struct iwl_ns_config ns_config[IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S];
} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_3 */
/**
* struct iwl_proto_offload_cmd_v3_large - ARP/NS offload configuration
* @common: common/IPv4 configuration
* @target_ipv6_addr: target IPv6 addresses
* @ns_config: NS offload configurations
*/
struct iwl_proto_offload_cmd_v3_large {
struct iwl_proto_offload_cmd_common common;
__le32 num_valid_ipv6_addrs;
struct iwl_targ_addr targ_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L];
struct iwl_ns_config ns_config[IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L];
} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_3 */
/* /*
* WOWLAN_PATTERNS * WOWLAN_PATTERNS
...@@ -293,7 +335,7 @@ enum iwl_wowlan_wakeup_reason { ...@@ -293,7 +335,7 @@ enum iwl_wowlan_wakeup_reason {
IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12),
}; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ }; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */
struct iwl_wowlan_status { struct iwl_wowlan_status_v4 {
__le64 replay_ctr; __le64 replay_ctr;
__le16 pattern_number; __le16 pattern_number;
__le16 non_qos_seq_ctr; __le16 non_qos_seq_ctr;
...@@ -308,6 +350,29 @@ struct iwl_wowlan_status { ...@@ -308,6 +350,29 @@ struct iwl_wowlan_status {
u8 wake_packet[]; /* can be truncated from _length to _bufsize */ u8 wake_packet[]; /* can be truncated from _length to _bufsize */
} __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ } __packed; /* WOWLAN_STATUSES_API_S_VER_4 */
struct iwl_wowlan_gtk_status {
u8 key_index;
u8 reserved[3];
u8 decrypt_key[16];
u8 tkip_mic_key[8];
struct iwl_wowlan_rsc_tsc_params_cmd rsc;
} __packed;
struct iwl_wowlan_status_v6 {
struct iwl_wowlan_gtk_status gtk;
__le64 replay_ctr;
__le16 pattern_number;
__le16 non_qos_seq_ctr;
__le16 qos_seq_ctr[8];
__le32 wakeup_reasons;
__le32 num_of_gtk_rekeys;
__le32 transmitted_ndps;
__le32 received_beacons;
__le32 wake_packet_length;
__le32 wake_packet_bufsize;
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
} __packed; /* WOWLAN_STATUSES_API_S_VER_6 */
#define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64 #define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64
#define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128 #define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128
#define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048 #define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048
......
...@@ -170,12 +170,14 @@ struct iwl_mac_data_ap { ...@@ -170,12 +170,14 @@ struct iwl_mac_data_ap {
* @beacon_tsf: beacon transmit time in TSF * @beacon_tsf: beacon transmit time in TSF
* @bi: beacon interval in TU * @bi: beacon interval in TU
* @bi_reciprocal: 2^32 / bi * @bi_reciprocal: 2^32 / bi
* @beacon_template: beacon template ID
*/ */
struct iwl_mac_data_ibss { struct iwl_mac_data_ibss {
__le32 beacon_time; __le32 beacon_time;
__le64 beacon_tsf; __le64 beacon_tsf;
__le32 bi; __le32 bi;
__le32 bi_reciprocal; __le32 bi_reciprocal;
__le32 beacon_template;
} __packed; /* IBSS_MAC_DATA_API_S_VER_1 */ } __packed; /* IBSS_MAC_DATA_API_S_VER_1 */
/** /**
...@@ -372,4 +374,13 @@ static inline u32 iwl_mvm_reciprocal(u32 v) ...@@ -372,4 +374,13 @@ static inline u32 iwl_mvm_reciprocal(u32 v)
return 0xFFFFFFFF / v; return 0xFFFFFFFF / v;
} }
#define IWL_NONQOS_SEQ_GET 0x1
#define IWL_NONQOS_SEQ_SET 0x2
struct iwl_nonqos_seq_query_cmd {
__le32 get_set_flag;
__le32 mac_id_n_color;
__le16 value;
__le16 reserved;
} __packed; /* NON_QOS_TX_COUNTER_GET_SET_API_S_VER_1 */
#endif /* __fw_api_mac_h__ */ #endif /* __fw_api_mac_h__ */
...@@ -131,6 +131,33 @@ struct iwl_powertable_cmd { ...@@ -131,6 +131,33 @@ struct iwl_powertable_cmd {
__le32 lprx_rssi_threshold; __le32 lprx_rssi_threshold;
} __packed; } __packed;
/**
* enum iwl_device_power_flags - masks for device power command flags
* @DEVIC_POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
* receiver and transmitter. '0' - does not allow. This flag should be
* always set to '1' unless one need to disable actual power down for debug
* purposes.
* @DEVICE_POWER_FLAGS_CAM_MSK: '1' CAM (Continuous Active Mode) is set, meaning
* that power management is disabled. '0' Power management is enabled, one
* of power schemes is applied.
*/
enum iwl_device_power_flags {
DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0),
DEVICE_POWER_FLAGS_CAM_MSK = BIT(13),
};
/**
* struct iwl_device_power_cmd - device wide power command.
* DEVICE_POWER_CMD = 0x77 (command, has simple generic response)
*
* @flags: Power table command flags from DEVICE_POWER_FLAGS_*
*/
struct iwl_device_power_cmd {
/* PM_POWER_TABLE_CMD_API_S_VER_6 */
__le16 flags;
__le16 reserved;
} __packed;
/** /**
* struct iwl_mac_power_cmd - New power command containing uAPSD support * struct iwl_mac_power_cmd - New power command containing uAPSD support
* MAC_PM_POWER_TABLE = 0xA9 (command, has simple generic response) * MAC_PM_POWER_TABLE = 0xA9 (command, has simple generic response)
...@@ -290,7 +317,7 @@ struct iwl_beacon_filter_cmd { ...@@ -290,7 +317,7 @@ struct iwl_beacon_filter_cmd {
#define IWL_BF_ESCAPE_TIMER_MIN 0 #define IWL_BF_ESCAPE_TIMER_MIN 0
#define IWL_BA_ESCAPE_TIMER_DEFAULT 6 #define IWL_BA_ESCAPE_TIMER_DEFAULT 6
#define IWL_BA_ESCAPE_TIMER_D3 6 #define IWL_BA_ESCAPE_TIMER_D3 9
#define IWL_BA_ESCAPE_TIMER_MAX 1024 #define IWL_BA_ESCAPE_TIMER_MAX 1024
#define IWL_BA_ESCAPE_TIMER_MIN 0 #define IWL_BA_ESCAPE_TIMER_MIN 0
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
/* /*
* These serve as indexes into * These serve as indexes into
* struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT]; * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT];
* TODO: avoid overlap between legacy and HT rates
*/ */
enum { enum {
IWL_RATE_1M_INDEX = 0, IWL_RATE_1M_INDEX = 0,
...@@ -78,18 +79,31 @@ enum { ...@@ -78,18 +79,31 @@ enum {
IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
IWL_RATE_MCS_0_INDEX = IWL_RATE_6M_INDEX,
IWL_FIRST_HT_RATE = IWL_RATE_MCS_0_INDEX,
IWL_FIRST_VHT_RATE = IWL_RATE_MCS_0_INDEX,
IWL_RATE_9M_INDEX, IWL_RATE_9M_INDEX,
IWL_RATE_12M_INDEX, IWL_RATE_12M_INDEX,
IWL_RATE_MCS_1_INDEX = IWL_RATE_12M_INDEX,
IWL_RATE_18M_INDEX, IWL_RATE_18M_INDEX,
IWL_RATE_MCS_2_INDEX = IWL_RATE_18M_INDEX,
IWL_RATE_24M_INDEX, IWL_RATE_24M_INDEX,
IWL_RATE_MCS_3_INDEX = IWL_RATE_24M_INDEX,
IWL_RATE_36M_INDEX, IWL_RATE_36M_INDEX,
IWL_RATE_MCS_4_INDEX = IWL_RATE_36M_INDEX,
IWL_RATE_48M_INDEX, IWL_RATE_48M_INDEX,
IWL_RATE_MCS_5_INDEX = IWL_RATE_48M_INDEX,
IWL_RATE_54M_INDEX, IWL_RATE_54M_INDEX,
IWL_RATE_MCS_6_INDEX = IWL_RATE_54M_INDEX,
IWL_LAST_NON_HT_RATE = IWL_RATE_54M_INDEX, IWL_LAST_NON_HT_RATE = IWL_RATE_54M_INDEX,
IWL_RATE_60M_INDEX, IWL_RATE_60M_INDEX,
IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX, IWL_RATE_MCS_7_INDEX = IWL_RATE_60M_INDEX,
IWL_LAST_HT_RATE = IWL_RATE_MCS_7_INDEX,
IWL_RATE_MCS_8_INDEX,
IWL_RATE_MCS_9_INDEX,
IWL_LAST_VHT_RATE = IWL_RATE_MCS_9_INDEX,
IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1, IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1,
IWL_RATE_COUNT, IWL_RATE_COUNT = IWL_LAST_VHT_RATE + 1,
}; };
#define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX) #define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX)
...@@ -108,6 +122,7 @@ enum { ...@@ -108,6 +122,7 @@ enum {
IWL_RATE_2M_PLCP = 20, IWL_RATE_2M_PLCP = 20,
IWL_RATE_5M_PLCP = 55, IWL_RATE_5M_PLCP = 55,
IWL_RATE_11M_PLCP = 110, IWL_RATE_11M_PLCP = 110,
IWL_RATE_INVM_PLCP = -1,
}; };
/* /*
...@@ -164,6 +179,8 @@ enum { ...@@ -164,6 +179,8 @@ enum {
* which is the duplicate 20 MHz MCS (bit 5 set, all others zero.) * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.)
*/ */
#define RATE_HT_MCS_RATE_CODE_MSK 0x7 #define RATE_HT_MCS_RATE_CODE_MSK 0x7
#define RATE_HT_MCS_NSS_POS 3
#define RATE_HT_MCS_NSS_MSK (3 << RATE_HT_MCS_NSS_POS)
/* Bit 10: (1) Use Green Field preamble */ /* Bit 10: (1) Use Green Field preamble */
#define RATE_HT_MCS_GF_POS 10 #define RATE_HT_MCS_GF_POS 10
......
...@@ -356,6 +356,7 @@ struct iwl_scan_complete_notif { ...@@ -356,6 +356,7 @@ struct iwl_scan_complete_notif {
/* scan offload */ /* scan offload */
#define IWL_MAX_SCAN_CHANNELS 40 #define IWL_MAX_SCAN_CHANNELS 40
#define IWL_SCAN_MAX_BLACKLIST_LEN 64 #define IWL_SCAN_MAX_BLACKLIST_LEN 64
#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
#define IWL_SCAN_MAX_PROFILES 11 #define IWL_SCAN_MAX_PROFILES 11
#define SCAN_OFFLOAD_PROBE_REQ_SIZE 512 #define SCAN_OFFLOAD_PROBE_REQ_SIZE 512
...@@ -368,6 +369,12 @@ struct iwl_scan_complete_notif { ...@@ -368,6 +369,12 @@ struct iwl_scan_complete_notif {
#define IWL_FULL_SCAN_MULTIPLIER 5 #define IWL_FULL_SCAN_MULTIPLIER 5
#define IWL_FAST_SCHED_SCAN_ITERATIONS 3 #define IWL_FAST_SCHED_SCAN_ITERATIONS 3
enum scan_framework_client {
SCAN_CLIENT_SCHED_SCAN = BIT(0),
SCAN_CLIENT_NETDETECT = BIT(1),
SCAN_CLIENT_ASSET_TRACKING = BIT(2),
};
/** /**
* struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6 * struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6
* @scan_flags: see enum iwl_scan_flags * @scan_flags: see enum iwl_scan_flags
...@@ -449,11 +456,12 @@ struct iwl_scan_offload_cfg { ...@@ -449,11 +456,12 @@ struct iwl_scan_offload_cfg {
* iwl_scan_offload_blacklist - SCAN_OFFLOAD_BLACKLIST_S * iwl_scan_offload_blacklist - SCAN_OFFLOAD_BLACKLIST_S
* @ssid: MAC address to filter out * @ssid: MAC address to filter out
* @reported_rssi: AP rssi reported to the host * @reported_rssi: AP rssi reported to the host
* @client_bitmap: clients ignore this entry - enum scan_framework_client
*/ */
struct iwl_scan_offload_blacklist { struct iwl_scan_offload_blacklist {
u8 ssid[ETH_ALEN]; u8 ssid[ETH_ALEN];
u8 reported_rssi; u8 reported_rssi;
u8 reserved; u8 client_bitmap;
} __packed; } __packed;
enum iwl_scan_offload_network_type { enum iwl_scan_offload_network_type {
...@@ -475,6 +483,7 @@ enum iwl_scan_offload_band_selection { ...@@ -475,6 +483,7 @@ enum iwl_scan_offload_band_selection {
* @aut_alg: authentication olgorithm to match - bitmap * @aut_alg: authentication olgorithm to match - bitmap
* @network_type: enum iwl_scan_offload_network_type * @network_type: enum iwl_scan_offload_network_type
* @band_selection: enum iwl_scan_offload_band_selection * @band_selection: enum iwl_scan_offload_band_selection
* @client_bitmap: clients waiting for match - enum scan_framework_client
*/ */
struct iwl_scan_offload_profile { struct iwl_scan_offload_profile {
u8 ssid_index; u8 ssid_index;
...@@ -482,7 +491,8 @@ struct iwl_scan_offload_profile { ...@@ -482,7 +491,8 @@ struct iwl_scan_offload_profile {
u8 auth_alg; u8 auth_alg;
u8 network_type; u8 network_type;
u8 band_selection; u8 band_selection;
u8 reserved[3]; u8 client_bitmap;
u8 reserved[2];
} __packed; } __packed;
/** /**
...@@ -491,13 +501,18 @@ struct iwl_scan_offload_profile { ...@@ -491,13 +501,18 @@ struct iwl_scan_offload_profile {
* @profiles: profiles to search for match * @profiles: profiles to search for match
* @blacklist_len: length of blacklist * @blacklist_len: length of blacklist
* @num_profiles: num of profiles in the list * @num_profiles: num of profiles in the list
* @match_notify: clients waiting for match found notification
* @pass_match: clients waiting for the results
* @active_clients: active clients bitmap - enum scan_framework_client
*/ */
struct iwl_scan_offload_profile_cfg { struct iwl_scan_offload_profile_cfg {
struct iwl_scan_offload_blacklist blacklist[IWL_SCAN_MAX_BLACKLIST_LEN];
struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES];
u8 blacklist_len; u8 blacklist_len;
u8 num_profiles; u8 num_profiles;
u8 reserved[2]; u8 match_notify;
u8 pass_match;
u8 active_clients;
u8 reserved[3];
} __packed; } __packed;
/** /**
...@@ -560,4 +575,15 @@ struct iwl_scan_offload_complete { ...@@ -560,4 +575,15 @@ struct iwl_scan_offload_complete {
u8 reserved; u8 reserved;
} __packed; } __packed;
/**
* iwl_sched_scan_results - SCAN_OFFLOAD_MATCH_FOUND_NTF_API_S_VER_1
* @ssid_bitmap: SSIDs indexes found in this iteration
* @client_bitmap: clients that are active and wait for this notification
*/
struct iwl_sched_scan_results {
__le16 ssid_bitmap;
u8 client_bitmap;
u8 reserved;
};
#endif #endif
...@@ -247,7 +247,7 @@ struct iwl_mvm_keyinfo { ...@@ -247,7 +247,7 @@ struct iwl_mvm_keyinfo {
} __packed; } __packed;
/** /**
* struct iwl_mvm_add_sta_cmd - Add / modify a station in the fw's station table * struct iwl_mvm_add_sta_cmd_v5 - Add/modify a station in the fw's sta table.
* ( REPLY_ADD_STA = 0x18 ) * ( REPLY_ADD_STA = 0x18 )
* @add_modify: 1: modify existing, 0: add new station * @add_modify: 1: modify existing, 0: add new station
* @unicast_tx_key_id: unicast tx key id. Relevant only when unicast key sent * @unicast_tx_key_id: unicast tx key id. Relevant only when unicast key sent
...@@ -286,7 +286,7 @@ struct iwl_mvm_keyinfo { ...@@ -286,7 +286,7 @@ struct iwl_mvm_keyinfo {
* ADD_STA sets up the table entry for one station, either creating a new * ADD_STA sets up the table entry for one station, either creating a new
* entry, or modifying a pre-existing one. * entry, or modifying a pre-existing one.
*/ */
struct iwl_mvm_add_sta_cmd { struct iwl_mvm_add_sta_cmd_v5 {
u8 add_modify; u8 add_modify;
u8 unicast_tx_key_id; u8 unicast_tx_key_id;
u8 multicast_tx_key_id; u8 multicast_tx_key_id;
...@@ -312,6 +312,57 @@ struct iwl_mvm_add_sta_cmd { ...@@ -312,6 +312,57 @@ struct iwl_mvm_add_sta_cmd {
__le32 tfd_queue_msk; __le32 tfd_queue_msk;
} __packed; /* ADD_STA_CMD_API_S_VER_5 */ } __packed; /* ADD_STA_CMD_API_S_VER_5 */
/**
* struct iwl_mvm_add_sta_cmd_v6 - Add / modify a station
* VER_6 of this command is quite similar to VER_5 except
* exclusion of all fields related to the security key installation.
*/
struct iwl_mvm_add_sta_cmd_v6 {
u8 add_modify;
u8 reserved1;
__le16 tid_disable_tx;
__le32 mac_id_n_color;
u8 addr[ETH_ALEN]; /* _STA_ID_MODIFY_INFO_API_S_VER_1 */
__le16 reserved2;
u8 sta_id;
u8 modify_mask;
__le16 reserved3;
__le32 station_flags;
__le32 station_flags_msk;
u8 add_immediate_ba_tid;
u8 remove_immediate_ba_tid;
__le16 add_immediate_ba_ssn;
__le16 sleep_tx_count;
__le16 sleep_state_flags;
__le16 assoc_id;
__le16 beamform_flags;
__le32 tfd_queue_msk;
} __packed; /* ADD_STA_CMD_API_S_VER_6 */
/**
* struct iwl_mvm_add_sta_key_cmd - add/modify sta key
* ( REPLY_ADD_STA_KEY = 0x17 )
* @sta_id: index of station in uCode's station table
* @key_offset: key offset in key storage
* @key_flags: type %iwl_sta_key_flag
* @key: key material data
* @key2: key material data
* @rx_secur_seq_cnt: RX security sequence counter for the key
* @tkip_rx_tsc_byte2: TSC[2] for key mix ph1 detection
* @tkip_rx_ttak: 10-byte unicast TKIP TTAK for Rx
*/
struct iwl_mvm_add_sta_key_cmd {
u8 sta_id;
u8 key_offset;
__le16 key_flags;
u8 key[16];
u8 key2[16];
u8 rx_secur_seq_cnt[16];
u8 tkip_rx_tsc_byte2;
u8 reserved;
__le16 tkip_rx_ttak[5];
} __packed; /* ADD_MODIFY_STA_KEY_API_S_VER_1 */
/** /**
* enum iwl_mvm_add_sta_rsp_status - status in the response to ADD_STA command * enum iwl_mvm_add_sta_rsp_status - status in the response to ADD_STA command
* @ADD_STA_SUCCESS: operation was executed successfully * @ADD_STA_SUCCESS: operation was executed successfully
......
...@@ -72,17 +72,17 @@ ...@@ -72,17 +72,17 @@
#include "fw-api-d3.h" #include "fw-api-d3.h"
#include "fw-api-bt-coex.h" #include "fw-api-bt-coex.h"
/* queue and FIFO numbers by usage */ /* maximal number of Tx queues in any platform */
#define IWL_MVM_MAX_QUEUES 20
/* Tx queue numbers */
enum { enum {
IWL_MVM_OFFCHANNEL_QUEUE = 8, IWL_MVM_OFFCHANNEL_QUEUE = 8,
IWL_MVM_CMD_QUEUE = 9, IWL_MVM_CMD_QUEUE = 9,
IWL_MVM_AUX_QUEUE = 15,
IWL_MVM_FIRST_AGG_QUEUE = 16,
IWL_MVM_NUM_QUEUES = 20,
IWL_MVM_LAST_AGG_QUEUE = IWL_MVM_NUM_QUEUES - 1,
IWL_MVM_CMD_FIFO = 7
}; };
#define IWL_MVM_CMD_FIFO 7
#define IWL_MVM_STATION_COUNT 16 #define IWL_MVM_STATION_COUNT 16
/* commands */ /* commands */
...@@ -97,6 +97,7 @@ enum { ...@@ -97,6 +97,7 @@ enum {
DBG_CFG = 0x9, DBG_CFG = 0x9,
/* station table */ /* station table */
ADD_STA_KEY = 0x17,
ADD_STA = 0x18, ADD_STA = 0x18,
REMOVE_STA = 0x19, REMOVE_STA = 0x19,
...@@ -114,6 +115,7 @@ enum { ...@@ -114,6 +115,7 @@ enum {
TIME_EVENT_NOTIFICATION = 0x2a, TIME_EVENT_NOTIFICATION = 0x2a,
BINDING_CONTEXT_CMD = 0x2b, BINDING_CONTEXT_CMD = 0x2b,
TIME_QUOTA_CMD = 0x2c, TIME_QUOTA_CMD = 0x2c,
NON_QOS_TX_COUNTER_CMD = 0x2d,
LQ_CMD = 0x4e, LQ_CMD = 0x4e,
...@@ -130,6 +132,7 @@ enum { ...@@ -130,6 +132,7 @@ enum {
SCAN_OFFLOAD_COMPLETE = 0x6D, SCAN_OFFLOAD_COMPLETE = 0x6D,
SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E, SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E,
SCAN_OFFLOAD_CONFIG_CMD = 0x6f, SCAN_OFFLOAD_CONFIG_CMD = 0x6f,
MATCH_FOUND_NOTIFICATION = 0xd9,
/* Phy */ /* Phy */
PHY_CONFIGURATION_CMD = 0x6a, PHY_CONFIGURATION_CMD = 0x6a,
...@@ -178,6 +181,7 @@ enum { ...@@ -178,6 +181,7 @@ enum {
BT_COEX_PRIO_TABLE = 0xcc, BT_COEX_PRIO_TABLE = 0xcc,
BT_COEX_PROT_ENV = 0xcd, BT_COEX_PROT_ENV = 0xcd,
BT_PROFILE_NOTIFICATION = 0xce, BT_PROFILE_NOTIFICATION = 0xce,
BT_COEX_CI = 0x5d,
REPLY_BEACON_FILTERING_CMD = 0xd2, REPLY_BEACON_FILTERING_CMD = 0xd2,
......
...@@ -199,7 +199,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, ...@@ -199,7 +199,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
*/ */
for (i = 0; i < IWL_MAX_HW_QUEUES; i++) { for (i = 0; i < IWL_MAX_HW_QUEUES; i++) {
if (i < IWL_MVM_FIRST_AGG_QUEUE && i != IWL_MVM_CMD_QUEUE) if (i < mvm->first_agg_queue && i != IWL_MVM_CMD_QUEUE)
mvm->queue_to_mac80211[i] = i; mvm->queue_to_mac80211[i] = i;
else else
mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE; mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE;
...@@ -243,7 +243,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -243,7 +243,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
if (mvm->init_ucode_run) if (mvm->init_ucode_complete)
return 0; return 0;
iwl_init_notification_wait(&mvm->notif_wait, iwl_init_notification_wait(&mvm->notif_wait,
...@@ -264,6 +264,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -264,6 +264,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
if (ret) if (ret)
goto error; goto error;
/* Read the NVM only at driver load time, no need to do this twice */
if (read_nvm) { if (read_nvm) {
/* Read nvm */ /* Read nvm */
ret = iwl_nvm_init(mvm); ret = iwl_nvm_init(mvm);
...@@ -273,6 +274,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -273,6 +274,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
} }
} }
/* In case we read the NVM from external file, load it to the NIC */
if (iwlwifi_mod_params.nvm_file)
iwl_mvm_load_nvm_to_nic(mvm);
ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans);
WARN_ON(ret); WARN_ON(ret);
...@@ -310,7 +315,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -310,7 +315,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait, ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
MVM_UCODE_CALIB_TIMEOUT); MVM_UCODE_CALIB_TIMEOUT);
if (!ret) if (!ret)
mvm->init_ucode_run = true; mvm->init_ucode_complete = true;
goto out; goto out;
error: error:
...@@ -353,8 +358,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm) ...@@ -353,8 +358,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
if (ret) if (ret)
return ret; return ret;
/* If we were in RFKILL during module loading, load init ucode now */ /*
if (!mvm->init_ucode_run) { * If we haven't completed the run of the init ucode during
* module loading, load init ucode now
* (for example, if we were in RFKILL)
*/
if (!mvm->init_ucode_complete) {
ret = iwl_run_init_mvm_ucode(mvm, false); ret = iwl_run_init_mvm_ucode(mvm, false);
if (ret && !iwlmvm_mod_params.init_dbg) { if (ret && !iwlmvm_mod_params.init_dbg) {
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
...@@ -424,6 +433,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm) ...@@ -424,6 +433,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error; goto error;
} }
ret = iwl_mvm_power_update_device_mode(mvm);
if (ret)
goto error;
IWL_DEBUG_INFO(mvm, "RT uCode started.\n"); IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
return 0; return 0;
error: error:
......
...@@ -80,7 +80,7 @@ struct iwl_mvm_mac_iface_iterator_data { ...@@ -80,7 +80,7 @@ struct iwl_mvm_mac_iface_iterator_data {
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)];
unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)]; unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)];
unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_FIRST_AGG_QUEUE)]; unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_MAX_QUEUES)];
enum iwl_tsf_id preferred_tsf; enum iwl_tsf_id preferred_tsf;
bool found_vif; bool found_vif;
}; };
...@@ -218,7 +218,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, ...@@ -218,7 +218,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
.preferred_tsf = NUM_TSF_IDS, .preferred_tsf = NUM_TSF_IDS,
.used_hw_queues = { .used_hw_queues = {
BIT(IWL_MVM_OFFCHANNEL_QUEUE) | BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
BIT(IWL_MVM_AUX_QUEUE) | BIT(mvm->aux_queue) |
BIT(IWL_MVM_CMD_QUEUE) BIT(IWL_MVM_CMD_QUEUE)
}, },
.found_vif = false, .found_vif = false,
...@@ -242,9 +242,17 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, ...@@ -242,9 +242,17 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
* that we should share it with another interface. * that we should share it with another interface.
*/ */
/* Currently, MAC ID 0 should be used only for the managed vif */ /* Currently, MAC ID 0 should be used only for the managed/IBSS vif */
if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) switch (vif->type) {
case NL80211_IFTYPE_ADHOC:
break;
case NL80211_IFTYPE_STATION:
if (!vif->p2p)
break;
/* fall through */
default:
__clear_bit(0, data.available_mac_ids); __clear_bit(0, data.available_mac_ids);
}
ieee80211_iterate_active_interfaces_atomic( ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
...@@ -302,9 +310,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, ...@@ -302,9 +310,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
/* Find available queues, and allocate them to the ACs */ /* Find available queues, and allocate them to the ACs */
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
u8 queue = find_first_zero_bit(data.used_hw_queues, u8 queue = find_first_zero_bit(data.used_hw_queues,
IWL_MVM_FIRST_AGG_QUEUE); mvm->first_agg_queue);
if (queue >= IWL_MVM_FIRST_AGG_QUEUE) { if (queue >= mvm->first_agg_queue) {
IWL_ERR(mvm, "Failed to allocate queue\n"); IWL_ERR(mvm, "Failed to allocate queue\n");
ret = -EIO; ret = -EIO;
goto exit_fail; goto exit_fail;
...@@ -317,9 +325,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, ...@@ -317,9 +325,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
/* Allocate the CAB queue for softAP and GO interfaces */ /* Allocate the CAB queue for softAP and GO interfaces */
if (vif->type == NL80211_IFTYPE_AP) { if (vif->type == NL80211_IFTYPE_AP) {
u8 queue = find_first_zero_bit(data.used_hw_queues, u8 queue = find_first_zero_bit(data.used_hw_queues,
IWL_MVM_FIRST_AGG_QUEUE); mvm->first_agg_queue);
if (queue >= IWL_MVM_FIRST_AGG_QUEUE) { if (queue >= mvm->first_agg_queue) {
IWL_ERR(mvm, "Failed to allocate cab queue\n"); IWL_ERR(mvm, "Failed to allocate cab queue\n");
ret = -EIO; ret = -EIO;
goto exit_fail; goto exit_fail;
...@@ -559,8 +567,12 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, ...@@ -559,8 +567,12 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
/* Don't use cts to self as the fw doesn't support it currently. */ /* Don't use cts to self as the fw doesn't support it currently. */
if (vif->bss_conf.use_cts_prot) if (vif->bss_conf.use_cts_prot) {
cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
cmd->protection_flags |=
cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN);
}
/* /*
* I think that we should enable these 2 flags regardless the HT PROT * I think that we should enable these 2 flags regardless the HT PROT
...@@ -712,6 +724,31 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm, ...@@ -712,6 +724,31 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
} }
static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
u32 action)
{
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mac_ctx_cmd cmd = {};
WARN_ON(vif->type != NL80211_IFTYPE_ADHOC);
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON |
MAC_FILTER_IN_PROBE_REQUEST);
/* cmd.ibss.beacon_time/cmd.ibss.beacon_tsf are curently ignored */
cmd.ibss.bi = cpu_to_le32(vif->bss_conf.beacon_int);
cmd.ibss.bi_reciprocal =
cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
/* TODO: Assumes that the beacon id == mac context id */
cmd.ibss.beacon_template = cpu_to_le32(mvmvif->id);
return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
}
struct iwl_mvm_go_iterator_data { struct iwl_mvm_go_iterator_data {
bool go_active; bool go_active;
}; };
...@@ -721,7 +758,8 @@ static void iwl_mvm_go_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif) ...@@ -721,7 +758,8 @@ static void iwl_mvm_go_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif)
struct iwl_mvm_go_iterator_data *data = _data; struct iwl_mvm_go_iterator_data *data = _data;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
if (vif->type == NL80211_IFTYPE_AP && vif->p2p && mvmvif->ap_active) if (vif->type == NL80211_IFTYPE_AP && vif->p2p &&
mvmvif->ap_ibss_active)
data->go_active = true; data->go_active = true;
} }
...@@ -833,6 +871,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, ...@@ -833,6 +871,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate)); cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate));
/* Set up TX beacon command fields */ /* Set up TX beacon command fields */
if (vif->type == NL80211_IFTYPE_AP)
iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd, iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd,
beacon->data, beacon->data,
beacon_skb_len); beacon_skb_len);
...@@ -848,14 +887,15 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, ...@@ -848,14 +887,15 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
return iwl_mvm_send_cmd(mvm, &cmd); return iwl_mvm_send_cmd(mvm, &cmd);
} }
/* The beacon template for the AP/GO context has changed and needs update */ /* The beacon template for the AP/GO/IBSS has changed and needs update */
int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
struct sk_buff *beacon; struct sk_buff *beacon;
int ret; int ret;
WARN_ON(vif->type != NL80211_IFTYPE_AP); WARN_ON(vif->type != NL80211_IFTYPE_AP &&
vif->type != NL80211_IFTYPE_ADHOC);
beacon = ieee80211_beacon_get(mvm->hw, vif); beacon = ieee80211_beacon_get(mvm->hw, vif);
if (!beacon) if (!beacon)
...@@ -1018,6 +1058,8 @@ static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -1018,6 +1058,8 @@ static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return iwl_mvm_mac_ctxt_cmd_listener(mvm, vif, action); return iwl_mvm_mac_ctxt_cmd_listener(mvm, vif, action);
case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_P2P_DEVICE:
return iwl_mvm_mac_ctxt_cmd_p2p_device(mvm, vif, action); return iwl_mvm_mac_ctxt_cmd_p2p_device(mvm, vif, action);
case NL80211_IFTYPE_ADHOC:
return iwl_mvm_mac_ctxt_cmd_ibss(mvm, vif, action);
default: default:
break; break;
} }
...@@ -1038,6 +1080,9 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif) ...@@ -1038,6 +1080,9 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
if (ret) if (ret)
return ret; return ret;
/* will only do anything at resume from D3 time */
iwl_mvm_set_last_nonqos_seq(mvm, vif);
mvmvif->uploaded = true; mvmvif->uploaded = true;
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -162,6 +162,7 @@ enum iwl_power_scheme { ...@@ -162,6 +162,7 @@ enum iwl_power_scheme {
struct iwl_mvm_power_ops { struct iwl_mvm_power_ops {
int (*power_update_mode)(struct iwl_mvm *mvm, int (*power_update_mode)(struct iwl_mvm *mvm,
struct ieee80211_vif *vif); struct ieee80211_vif *vif);
int (*power_update_device_mode)(struct iwl_mvm *mvm);
int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
...@@ -241,12 +242,18 @@ enum iwl_mvm_smps_type_request { ...@@ -241,12 +242,18 @@ enum iwl_mvm_smps_type_request {
* @last_beacon_signal: last beacon rssi signal in dbm * @last_beacon_signal: last beacon rssi signal in dbm
* @ave_beacon_signal: average beacon signal * @ave_beacon_signal: average beacon signal
* @last_cqm_event: rssi of the last cqm event * @last_cqm_event: rssi of the last cqm event
* @bt_coex_min_thold: minimum threshold for BT coex
* @bt_coex_max_thold: maximum threshold for BT coex
* @last_bt_coex_event: rssi of the last BT coex event
*/ */
struct iwl_mvm_vif_bf_data { struct iwl_mvm_vif_bf_data {
bool bf_enabled; bool bf_enabled;
bool ba_enabled; bool ba_enabled;
s8 ave_beacon_signal; s8 ave_beacon_signal;
s8 last_cqm_event; s8 last_cqm_event;
s8 bt_coex_min_thold;
s8 bt_coex_max_thold;
s8 last_bt_coex_event;
}; };
/** /**
...@@ -255,7 +262,7 @@ struct iwl_mvm_vif_bf_data { ...@@ -255,7 +262,7 @@ struct iwl_mvm_vif_bf_data {
* @color: to solve races upon MAC addition and removal * @color: to solve races upon MAC addition and removal
* @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA
* @uploaded: indicates the MAC context has been added to the device * @uploaded: indicates the MAC context has been added to the device
* @ap_active: indicates that ap context is configured, and that the interface * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface
* should get quota etc. * should get quota etc.
* @monitor_active: indicates that monitor context is configured, and that the * @monitor_active: indicates that monitor context is configured, and that the
* interface should get quota etc. * interface should get quota etc.
...@@ -272,7 +279,7 @@ struct iwl_mvm_vif { ...@@ -272,7 +279,7 @@ struct iwl_mvm_vif {
u8 ap_sta_id; u8 ap_sta_id;
bool uploaded; bool uploaded;
bool ap_active; bool ap_ibss_active;
bool monitor_active; bool monitor_active;
struct iwl_mvm_vif_bf_data bf_data; struct iwl_mvm_vif_bf_data bf_data;
...@@ -306,6 +313,9 @@ struct iwl_mvm_vif { ...@@ -306,6 +313,9 @@ struct iwl_mvm_vif {
int tx_key_idx; int tx_key_idx;
bool seqno_valid;
u16 seqno;
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
/* IPv6 addresses for WoWLAN */ /* IPv6 addresses for WoWLAN */
struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX]; struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX];
...@@ -333,6 +343,7 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif) ...@@ -333,6 +343,7 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif)
enum iwl_scan_status { enum iwl_scan_status {
IWL_MVM_SCAN_NONE, IWL_MVM_SCAN_NONE,
IWL_MVM_SCAN_OS, IWL_MVM_SCAN_OS,
IWL_MVM_SCAN_SCHED,
}; };
/** /**
...@@ -434,7 +445,7 @@ struct iwl_mvm { ...@@ -434,7 +445,7 @@ struct iwl_mvm {
enum iwl_ucode_type cur_ucode; enum iwl_ucode_type cur_ucode;
bool ucode_loaded; bool ucode_loaded;
bool init_ucode_run; bool init_ucode_complete;
u32 error_event_table; u32 error_event_table;
u32 log_event_table; u32 log_event_table;
...@@ -470,6 +481,9 @@ struct iwl_mvm { ...@@ -470,6 +481,9 @@ struct iwl_mvm {
enum iwl_scan_status scan_status; enum iwl_scan_status scan_status;
struct iwl_scan_cmd *scan_cmd; struct iwl_scan_cmd *scan_cmd;
/* rx chain antennas set through debugfs for the scan command */
u8 scan_rx_ant;
/* Internal station */ /* Internal station */
struct iwl_mvm_int_sta aux_sta; struct iwl_mvm_int_sta aux_sta;
...@@ -479,7 +493,8 @@ struct iwl_mvm { ...@@ -479,7 +493,8 @@ struct iwl_mvm {
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
u32 dbgfs_sram_offset, dbgfs_sram_len; u32 dbgfs_sram_offset, dbgfs_sram_len;
bool prevent_power_down_d3; bool disable_power_off;
bool disable_power_off_d3;
#endif #endif
struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX]; struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
...@@ -523,12 +538,23 @@ struct iwl_mvm { ...@@ -523,12 +538,23 @@ struct iwl_mvm {
/* BT-Coex */ /* BT-Coex */
u8 bt_kill_msk; u8 bt_kill_msk;
struct iwl_bt_coex_profile_notif last_bt_notif; struct iwl_bt_coex_profile_notif last_bt_notif;
struct iwl_bt_coex_ci_cmd last_bt_ci_cmd;
/* Thermal Throttling and CTkill */ /* Thermal Throttling and CTkill */
struct iwl_mvm_tt_mgmt thermal_throttle; struct iwl_mvm_tt_mgmt thermal_throttle;
s32 temperature; /* Celsius */ s32 temperature; /* Celsius */
const struct iwl_mvm_power_ops *pm_ops; const struct iwl_mvm_power_ops *pm_ops;
#ifdef CONFIG_NL80211_TESTMODE
u32 noa_duration;
struct ieee80211_vif *noa_vif;
#endif
/* Tx queues */
u8 aux_queue;
u8 first_agg_queue;
u8 last_agg_queue;
}; };
/* Extract MVM priv from op_mode and _hw */ /* Extract MVM priv from op_mode and _hw */
...@@ -570,6 +596,9 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm); ...@@ -570,6 +596,9 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm);
/* Utils */ /* Utils */
int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
enum ieee80211_band band); enum ieee80211_band band);
void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
enum ieee80211_band band,
struct ieee80211_tx_rate *r);
u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx); u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm); void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm);
void iwl_mvm_dump_sram(struct iwl_mvm *mvm); void iwl_mvm_dump_sram(struct iwl_mvm *mvm);
...@@ -608,6 +637,7 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm, ...@@ -608,6 +637,7 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
/* NVM */ /* NVM */
int iwl_nvm_init(struct iwl_mvm *mvm); int iwl_nvm_init(struct iwl_mvm *mvm);
int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
int iwl_mvm_up(struct iwl_mvm *mvm); int iwl_mvm_up(struct iwl_mvm *mvm);
int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm); int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm);
...@@ -682,6 +712,23 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, ...@@ -682,6 +712,23 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd); struct iwl_device_cmd *cmd);
void iwl_mvm_cancel_scan(struct iwl_mvm *mvm); void iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
/* Scheduled scan */
int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd);
int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *req,
struct ieee80211_sched_scan_ies *ies);
int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
struct cfg80211_sched_scan_request *req);
int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
struct cfg80211_sched_scan_request *req);
void iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm);
int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm,
struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd);
/* MVM debugfs */ /* MVM debugfs */
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir);
...@@ -720,6 +767,13 @@ static inline int iwl_mvm_power_disable(struct iwl_mvm *mvm, ...@@ -720,6 +767,13 @@ static inline int iwl_mvm_power_disable(struct iwl_mvm *mvm,
return mvm->pm_ops->power_disable(mvm, vif); return mvm->pm_ops->power_disable(mvm, vif);
} }
static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm)
{
if (mvm->pm_ops->power_update_device_mode)
return mvm->pm_ops->power_update_device_mode(mvm);
return 0;
}
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm, static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
...@@ -745,6 +799,15 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw, ...@@ -745,6 +799,15 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, int idx); struct ieee80211_vif *vif, int idx);
extern const struct file_operations iwl_dbgfs_d3_test_ops; extern const struct file_operations iwl_dbgfs_d3_test_ops;
#ifdef CONFIG_PM_SLEEP
void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm,
struct ieee80211_vif *vif);
#else
static inline void
iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
}
#endif
/* BT Coex */ /* BT Coex */
int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
...@@ -754,7 +817,20 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, ...@@ -754,7 +817,20 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
struct iwl_device_cmd *cmd); struct iwl_device_cmd *cmd);
void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
enum ieee80211_rssi_event rssi_event); enum ieee80211_rssi_event rssi_event);
void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm);
u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,
struct ieee80211_sta *sta);
bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
struct ieee80211_sta *sta);
enum iwl_bt_kill_msk {
BT_KILL_MSK_DEFAULT,
BT_KILL_MSK_SCO_HID_A2DP,
BT_KILL_MSK_REDUCED_TXPOW,
BT_KILL_MSK_MAX,
};
extern const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX];
extern const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX];
/* beacon filtering */ /* beacon filtering */
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
......
...@@ -77,7 +77,7 @@ static const int nvm_to_read[] = { ...@@ -77,7 +77,7 @@ static const int nvm_to_read[] = {
/* Default NVM size to read */ /* Default NVM size to read */
#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024) #define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
#define IWL_MAX_NVM_SECTION_SIZE 6000 #define IWL_MAX_NVM_SECTION_SIZE 7000
#define NVM_WRITE_OPCODE 1 #define NVM_WRITE_OPCODE 1
#define NVM_READ_OPCODE 0 #define NVM_READ_OPCODE 0
...@@ -259,6 +259,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) ...@@ -259,6 +259,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
#define MAX_NVM_FILE_LEN 16384 #define MAX_NVM_FILE_LEN 16384
/* /*
* Reads external NVM from a file into mvm->nvm_sections
*
* HOW TO CREATE THE NVM FILE FORMAT: * HOW TO CREATE THE NVM FILE FORMAT:
* ------------------------------ * ------------------------------
* 1. create hex file, format: * 1. create hex file, format:
...@@ -277,20 +279,23 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) ...@@ -277,20 +279,23 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
* *
* 4. save as "iNVM_xxx.bin" under /lib/firmware * 4. save as "iNVM_xxx.bin" under /lib/firmware
*/ */
static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm) static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
{ {
int ret, section_id, section_size; int ret, section_size;
u16 section_id;
const struct firmware *fw_entry; const struct firmware *fw_entry;
const struct { const struct {
__le16 word1; __le16 word1;
__le16 word2; __le16 word2;
u8 data[]; u8 data[];
} *file_sec; } *file_sec;
const u8 *eof; const u8 *eof, *temp;
#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF)) #define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
#define NVM_WORD2_ID(x) (x >> 12) #define NVM_WORD2_ID(x) (x >> 12)
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
/* /*
* Obtain NVM image via request_firmware. Since we already used * Obtain NVM image via request_firmware. Since we already used
* request_firmware_nowait() for the firmware binary load and only * request_firmware_nowait() for the firmware binary load and only
...@@ -362,12 +367,18 @@ static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm) ...@@ -362,12 +367,18 @@ static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm)
break; break;
} }
ret = iwl_nvm_write_section(mvm, section_id, file_sec->data, temp = kmemdup(file_sec->data, section_size, GFP_KERNEL);
section_size); if (!temp) {
if (ret < 0) { ret = -ENOMEM;
IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);
break; break;
} }
if (WARN_ON(section_id >= NVM_NUM_OF_SECTIONS)) {
IWL_ERR(mvm, "Invalid NVM section ID\n");
ret = -EINVAL;
break;
}
mvm->nvm_sections[section_id].data = temp;
mvm->nvm_sections[section_id].length = section_size;
/* advance to the next section */ /* advance to the next section */
file_sec = (void *)(file_sec->data + section_size); file_sec = (void *)(file_sec->data + section_size);
...@@ -377,6 +388,28 @@ static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm) ...@@ -377,6 +388,28 @@ static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm)
return ret; return ret;
} }
/* Loads the NVM data stored in mvm->nvm_sections into the NIC */
int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
{
int i, ret;
u16 section_id;
struct iwl_nvm_section *sections = mvm->nvm_sections;
IWL_DEBUG_EEPROM(mvm->trans->dev, "'Write to NVM\n");
for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
section_id = nvm_to_read[i];
ret = iwl_nvm_write_section(mvm, section_id,
sections[section_id].data,
sections[section_id].length);
if (ret < 0) {
IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);
break;
}
}
return ret;
}
int iwl_nvm_init(struct iwl_mvm *mvm) int iwl_nvm_init(struct iwl_mvm *mvm)
{ {
int ret, i, section; int ret, i, section;
...@@ -385,11 +418,10 @@ int iwl_nvm_init(struct iwl_mvm *mvm) ...@@ -385,11 +418,10 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
/* load external NVM if configured */ /* load external NVM if configured */
if (iwlwifi_mod_params.nvm_file) { if (iwlwifi_mod_params.nvm_file) {
/* move to External NVM flow */ /* move to External NVM flow */
ret = iwl_mvm_load_external_nvm(mvm); ret = iwl_mvm_read_external_nvm(mvm);
if (ret) if (ret)
return ret; return ret;
} } else {
/* Read From FW NVM */ /* Read From FW NVM */
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
...@@ -415,6 +447,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm) ...@@ -415,6 +447,7 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
kfree(nvm_buffer); kfree(nvm_buffer);
if (ret < 0) if (ret < 0)
return ret; return ret;
}
mvm->nvm_data = iwl_parse_nvm_sections(mvm); mvm->nvm_data = iwl_parse_nvm_sections(mvm);
if (!mvm->nvm_data) if (!mvm->nvm_data)
......
...@@ -224,6 +224,10 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { ...@@ -224,6 +224,10 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
iwl_mvm_rx_scan_offload_complete_notif, false),
RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results,
false),
RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
...@@ -249,6 +253,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { ...@@ -249,6 +253,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(TIME_EVENT_NOTIFICATION), CMD(TIME_EVENT_NOTIFICATION),
CMD(BINDING_CONTEXT_CMD), CMD(BINDING_CONTEXT_CMD),
CMD(TIME_QUOTA_CMD), CMD(TIME_QUOTA_CMD),
CMD(NON_QOS_TX_COUNTER_CMD),
CMD(RADIO_VERSION_NOTIFICATION), CMD(RADIO_VERSION_NOTIFICATION),
CMD(SCAN_REQUEST_CMD), CMD(SCAN_REQUEST_CMD),
CMD(SCAN_ABORT_CMD), CMD(SCAN_ABORT_CMD),
...@@ -260,10 +265,12 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { ...@@ -260,10 +265,12 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(CALIB_RES_NOTIF_PHY_DB), CMD(CALIB_RES_NOTIF_PHY_DB),
CMD(SET_CALIB_DEFAULT_CMD), CMD(SET_CALIB_DEFAULT_CMD),
CMD(CALIBRATION_COMPLETE_NOTIFICATION), CMD(CALIBRATION_COMPLETE_NOTIFICATION),
CMD(ADD_STA_KEY),
CMD(ADD_STA), CMD(ADD_STA),
CMD(REMOVE_STA), CMD(REMOVE_STA),
CMD(LQ_CMD), CMD(LQ_CMD),
CMD(SCAN_OFFLOAD_CONFIG_CMD), CMD(SCAN_OFFLOAD_CONFIG_CMD),
CMD(MATCH_FOUND_NOTIFICATION),
CMD(SCAN_OFFLOAD_REQUEST_CMD), CMD(SCAN_OFFLOAD_REQUEST_CMD),
CMD(SCAN_OFFLOAD_ABORT_CMD), CMD(SCAN_OFFLOAD_ABORT_CMD),
CMD(SCAN_OFFLOAD_COMPLETE), CMD(SCAN_OFFLOAD_COMPLETE),
...@@ -303,6 +310,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { ...@@ -303,6 +310,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(REPLY_BEACON_FILTERING_CMD), CMD(REPLY_BEACON_FILTERING_CMD),
CMD(REPLY_THERMAL_MNG_BACKOFF), CMD(REPLY_THERMAL_MNG_BACKOFF),
CMD(MAC_PM_POWER_TABLE), CMD(MAC_PM_POWER_TABLE),
CMD(BT_COEX_CI),
}; };
#undef CMD #undef CMD
...@@ -344,6 +352,14 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -344,6 +352,14 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0; mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0;
mvm->aux_queue = 15;
mvm->first_agg_queue = 16;
mvm->last_agg_queue = mvm->cfg->base_params->num_of_queues - 1;
if (mvm->cfg->base_params->num_of_queues == 16) {
mvm->aux_queue = 11;
mvm->first_agg_queue = 12;
}
mutex_init(&mvm->mutex); mutex_init(&mvm->mutex);
spin_lock_init(&mvm->async_handlers_lock); spin_lock_init(&mvm->async_handlers_lock);
INIT_LIST_HEAD(&mvm->time_event_list); INIT_LIST_HEAD(&mvm->time_event_list);
...@@ -401,12 +417,19 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -401,12 +417,19 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
IWL_INFO(mvm, "Detected %s, REV=0x%X\n", IWL_INFO(mvm, "Detected %s, REV=0x%X\n",
mvm->cfg->name, mvm->trans->hw_rev); mvm->cfg->name, mvm->trans->hw_rev);
iwl_mvm_tt_initialize(mvm);
/*
* If the NVM exists in an external file,
* there is no need to unnecessarily power up the NIC at driver load
*/
if (iwlwifi_mod_params.nvm_file) {
iwl_nvm_init(mvm);
} else {
err = iwl_trans_start_hw(mvm->trans); err = iwl_trans_start_hw(mvm->trans);
if (err) if (err)
goto out_free; goto out_free;
iwl_mvm_tt_initialize(mvm);
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
err = iwl_run_init_mvm_ucode(mvm, true); err = iwl_run_init_mvm_ucode(mvm, true);
mutex_unlock(&mvm->mutex); mutex_unlock(&mvm->mutex);
...@@ -419,6 +442,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -419,6 +442,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
/* Stop the hw after the ALIVE and NVM has been read */ /* Stop the hw after the ALIVE and NVM has been read */
if (!iwlmvm_mod_params.init_dbg) if (!iwlmvm_mod_params.init_dbg)
iwl_trans_stop_hw(mvm->trans, false); iwl_trans_stop_hw(mvm->trans, false);
}
scan_size = sizeof(struct iwl_scan_cmd) + scan_size = sizeof(struct iwl_scan_cmd) +
mvm->fw->ucode_capa.max_probe_length + mvm->fw->ucode_capa.max_probe_length +
...@@ -449,6 +473,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, ...@@ -449,6 +473,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
out_free: out_free:
iwl_phy_db_free(mvm->phy_db); iwl_phy_db_free(mvm->phy_db);
kfree(mvm->scan_cmd); kfree(mvm->scan_cmd);
if (!iwlwifi_mod_params.nvm_file)
iwl_trans_stop_hw(trans, true); iwl_trans_stop_hw(trans, true);
ieee80211_free_hw(mvm->hw); ieee80211_free_hw(mvm->hw);
return NULL; return NULL;
...@@ -715,6 +740,9 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) ...@@ -715,6 +740,9 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
case IWL_MVM_SCAN_OS: case IWL_MVM_SCAN_OS:
ieee80211_scan_completed(mvm->hw, true); ieee80211_scan_completed(mvm->hw, true);
break; break;
case IWL_MVM_SCAN_SCHED:
ieee80211_sched_scan_stopped(mvm->hw);
break;
} }
if (mvm->restart_fw > 0) if (mvm->restart_fw > 0)
......
...@@ -297,11 +297,6 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, ...@@ -297,11 +297,6 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
} }
if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) { if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) {
cmd->rx_data_timeout_uapsd =
cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
cmd->tx_data_timeout_uapsd =
cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) | if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) |
BIT(IEEE80211_AC_VI) | BIT(IEEE80211_AC_VI) |
BIT(IEEE80211_AC_BE) | BIT(IEEE80211_AC_BE) |
...@@ -316,10 +311,31 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, ...@@ -316,10 +311,31 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
} }
cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP; cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP;
if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags &
cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
cmd->rx_data_timeout_uapsd =
cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT);
cmd->tx_data_timeout_uapsd =
cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT);
} else {
cmd->rx_data_timeout_uapsd =
cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT);
cmd->tx_data_timeout_uapsd =
cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT);
}
if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) {
cmd->heavy_tx_thld_packets =
IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS;
cmd->heavy_rx_thld_packets =
IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS;
} else {
cmd->heavy_tx_thld_packets = cmd->heavy_tx_thld_packets =
IWL_MVM_PS_HEAVY_TX_THLD_PACKETS; IWL_MVM_PS_HEAVY_TX_THLD_PACKETS;
cmd->heavy_rx_thld_packets = cmd->heavy_rx_thld_packets =
IWL_MVM_PS_HEAVY_RX_THLD_PACKETS; IWL_MVM_PS_HEAVY_RX_THLD_PACKETS;
}
cmd->heavy_tx_thld_percentage = cmd->heavy_tx_thld_percentage =
IWL_MVM_PS_HEAVY_TX_THLD_PERCENT; IWL_MVM_PS_HEAVY_TX_THLD_PERCENT;
cmd->heavy_rx_thld_percentage = cmd->heavy_rx_thld_percentage =
...@@ -427,6 +443,32 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm, ...@@ -427,6 +443,32 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
sizeof(cmd), &cmd); sizeof(cmd), &cmd);
} }
static int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
{
struct iwl_device_power_cmd cmd = {
.flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
};
if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
return 0;
if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)
cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK);
#ifdef CONFIG_IWLWIFI_DEBUGFS
if ((mvm->cur_ucode == IWL_UCODE_WOWLAN) ? mvm->disable_power_off_d3 :
mvm->disable_power_off)
cmd.flags &=
cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK);
#endif
IWL_DEBUG_POWER(mvm,
"Sending device power command with flags = 0x%X\n",
cmd.flags);
return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, sizeof(cmd),
&cmd);
}
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, char *buf, struct ieee80211_vif *vif, char *buf,
...@@ -437,6 +479,7 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, ...@@ -437,6 +479,7 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm,
iwl_mvm_power_build_cmd(mvm, vif, &cmd); iwl_mvm_power_build_cmd(mvm, vif, &cmd);
if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n", pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n",
(cmd.flags & (cmd.flags &
cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ? cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ?
...@@ -606,6 +649,7 @@ int iwl_mvm_update_beacon_filter(struct iwl_mvm *mvm, ...@@ -606,6 +649,7 @@ int iwl_mvm_update_beacon_filter(struct iwl_mvm *mvm,
const struct iwl_mvm_power_ops pm_mac_ops = { const struct iwl_mvm_power_ops pm_mac_ops = {
.power_update_mode = iwl_mvm_power_mac_update_mode, .power_update_mode = iwl_mvm_power_mac_update_mode,
.power_update_device_mode = iwl_mvm_power_update_device,
.power_disable = iwl_mvm_power_mac_disable, .power_disable = iwl_mvm_power_mac_disable,
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
.power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read,
......
...@@ -110,7 +110,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac, ...@@ -110,7 +110,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
data->n_interfaces[id]++; data->n_interfaces[id]++;
break; break;
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
if (mvmvif->ap_active) case NL80211_IFTYPE_ADHOC:
if (mvmvif->ap_ibss_active)
data->n_interfaces[id]++; data->n_interfaces[id]++;
break; break;
case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_MONITOR:
...@@ -119,16 +120,45 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac, ...@@ -119,16 +120,45 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
break; break;
case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_P2P_DEVICE:
break; break;
case NL80211_IFTYPE_ADHOC:
if (vif->bss_conf.ibss_joined)
data->n_interfaces[id]++;
break;
default: default:
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
break; break;
} }
} }
static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
struct iwl_time_quota_cmd *cmd)
{
#ifdef CONFIG_NL80211_TESTMODE
struct iwl_mvm_vif *mvmvif;
int i, phy_id = -1, beacon_int = 0;
if (!mvm->noa_duration || !mvm->noa_vif)
return;
mvmvif = iwl_mvm_vif_from_mac80211(mvm->noa_vif);
if (!mvmvif->ap_ibss_active)
return;
phy_id = mvmvif->phy_ctxt->id;
beacon_int = mvm->noa_vif->bss_conf.beacon_int;
for (i = 0; i < MAX_BINDINGS; i++) {
u32 id_n_c = le32_to_cpu(cmd->quotas[i].id_and_color);
u32 id = (id_n_c & FW_CTXT_ID_MSK) >> FW_CTXT_ID_POS;
u32 quota = le32_to_cpu(cmd->quotas[i].quota);
if (id != phy_id)
continue;
quota *= (beacon_int - mvm->noa_duration);
quota /= beacon_int;
cmd->quotas[i].quota = cpu_to_le32(quota);
}
#endif
}
int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
{ {
struct iwl_time_quota_cmd cmd = {}; struct iwl_time_quota_cmd cmd = {};
...@@ -196,6 +226,8 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) ...@@ -196,6 +226,8 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
/* Give the remainder of the session to the first binding */ /* Give the remainder of the session to the first binding */
le32_add_cpu(&cmd.quotas[0].quota, quota_rem); le32_add_cpu(&cmd.quotas[0].quota, quota_rem);
iwl_mvm_adjust_quota_for_noa(mvm, &cmd);
ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC, ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC,
sizeof(cmd), &cmd); sizeof(cmd), &cmd);
if (ret) if (ret)
......
This diff is collapsed.
...@@ -36,8 +36,10 @@ ...@@ -36,8 +36,10 @@
struct iwl_rs_rate_info { struct iwl_rs_rate_info {
u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ u8 plcp_ht_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */ u8 plcp_ht_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
u8 plcp_vht_siso;
u8 plcp_vht_mimo2;
u8 prev_rs; /* previous rate used in rs algo */ u8 prev_rs; /* previous rate used in rs algo */
u8 next_rs; /* next rate used in rs algo */ u8 next_rs; /* next rate used in rs algo */
}; };
...@@ -83,35 +85,52 @@ enum { ...@@ -83,35 +85,52 @@ enum {
#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX) #define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
/* uCode API values for OFDM high-throughput (HT) bit rates */ /* uCode API values for HT/VHT bit rates */
enum { enum {
IWL_RATE_SISO_6M_PLCP = 0, IWL_RATE_HT_SISO_MCS_0_PLCP = 0,
IWL_RATE_SISO_12M_PLCP = 1, IWL_RATE_HT_SISO_MCS_1_PLCP = 1,
IWL_RATE_SISO_18M_PLCP = 2, IWL_RATE_HT_SISO_MCS_2_PLCP = 2,
IWL_RATE_SISO_24M_PLCP = 3, IWL_RATE_HT_SISO_MCS_3_PLCP = 3,
IWL_RATE_SISO_36M_PLCP = 4, IWL_RATE_HT_SISO_MCS_4_PLCP = 4,
IWL_RATE_SISO_48M_PLCP = 5, IWL_RATE_HT_SISO_MCS_5_PLCP = 5,
IWL_RATE_SISO_54M_PLCP = 6, IWL_RATE_HT_SISO_MCS_6_PLCP = 6,
IWL_RATE_SISO_60M_PLCP = 7, IWL_RATE_HT_SISO_MCS_7_PLCP = 7,
IWL_RATE_MIMO2_6M_PLCP = 0x8, IWL_RATE_HT_MIMO2_MCS_0_PLCP = 0x8,
IWL_RATE_MIMO2_12M_PLCP = 0x9, IWL_RATE_HT_MIMO2_MCS_1_PLCP = 0x9,
IWL_RATE_MIMO2_18M_PLCP = 0xa, IWL_RATE_HT_MIMO2_MCS_2_PLCP = 0xA,
IWL_RATE_MIMO2_24M_PLCP = 0xb, IWL_RATE_HT_MIMO2_MCS_3_PLCP = 0xB,
IWL_RATE_MIMO2_36M_PLCP = 0xc, IWL_RATE_HT_MIMO2_MCS_4_PLCP = 0xC,
IWL_RATE_MIMO2_48M_PLCP = 0xd, IWL_RATE_HT_MIMO2_MCS_5_PLCP = 0xD,
IWL_RATE_MIMO2_54M_PLCP = 0xe, IWL_RATE_HT_MIMO2_MCS_6_PLCP = 0xE,
IWL_RATE_MIMO2_60M_PLCP = 0xf, IWL_RATE_HT_MIMO2_MCS_7_PLCP = 0xF,
IWL_RATE_MIMO3_6M_PLCP = 0x10, IWL_RATE_VHT_SISO_MCS_0_PLCP = 0,
IWL_RATE_MIMO3_12M_PLCP = 0x11, IWL_RATE_VHT_SISO_MCS_1_PLCP = 1,
IWL_RATE_MIMO3_18M_PLCP = 0x12, IWL_RATE_VHT_SISO_MCS_2_PLCP = 2,
IWL_RATE_MIMO3_24M_PLCP = 0x13, IWL_RATE_VHT_SISO_MCS_3_PLCP = 3,
IWL_RATE_MIMO3_36M_PLCP = 0x14, IWL_RATE_VHT_SISO_MCS_4_PLCP = 4,
IWL_RATE_MIMO3_48M_PLCP = 0x15, IWL_RATE_VHT_SISO_MCS_5_PLCP = 5,
IWL_RATE_MIMO3_54M_PLCP = 0x16, IWL_RATE_VHT_SISO_MCS_6_PLCP = 6,
IWL_RATE_MIMO3_60M_PLCP = 0x17, IWL_RATE_VHT_SISO_MCS_7_PLCP = 7,
IWL_RATE_SISO_INVM_PLCP, IWL_RATE_VHT_SISO_MCS_8_PLCP = 8,
IWL_RATE_MIMO2_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP, IWL_RATE_VHT_SISO_MCS_9_PLCP = 9,
IWL_RATE_MIMO3_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP, IWL_RATE_VHT_MIMO2_MCS_0_PLCP = 0x10,
IWL_RATE_VHT_MIMO2_MCS_1_PLCP = 0x11,
IWL_RATE_VHT_MIMO2_MCS_2_PLCP = 0x12,
IWL_RATE_VHT_MIMO2_MCS_3_PLCP = 0x13,
IWL_RATE_VHT_MIMO2_MCS_4_PLCP = 0x14,
IWL_RATE_VHT_MIMO2_MCS_5_PLCP = 0x15,
IWL_RATE_VHT_MIMO2_MCS_6_PLCP = 0x16,
IWL_RATE_VHT_MIMO2_MCS_7_PLCP = 0x17,
IWL_RATE_VHT_MIMO2_MCS_8_PLCP = 0x18,
IWL_RATE_VHT_MIMO2_MCS_9_PLCP = 0x19,
IWL_RATE_HT_SISO_MCS_INV_PLCP,
IWL_RATE_HT_MIMO2_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
IWL_RATE_VHT_SISO_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
IWL_RATE_VHT_MIMO2_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
IWL_RATE_HT_SISO_MCS_8_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
IWL_RATE_HT_SISO_MCS_9_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
IWL_RATE_HT_MIMO2_MCS_8_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
IWL_RATE_HT_MIMO2_MCS_9_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP,
}; };
#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) #define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
...@@ -139,25 +158,33 @@ enum { ...@@ -139,25 +158,33 @@ enum {
#define IWL_RATE_DECREASE_TH 1920 /* 15% */ #define IWL_RATE_DECREASE_TH 1920 /* 15% */
/* possible actions when in legacy mode */ /* possible actions when in legacy mode */
#define IWL_LEGACY_SWITCH_ANTENNA1 0 enum {
#define IWL_LEGACY_SWITCH_ANTENNA2 1 IWL_LEGACY_SWITCH_ANTENNA,
#define IWL_LEGACY_SWITCH_SISO 2 IWL_LEGACY_SWITCH_SISO,
#define IWL_LEGACY_SWITCH_MIMO2 3 IWL_LEGACY_SWITCH_MIMO2,
IWL_LEGACY_FIRST_ACTION = IWL_LEGACY_SWITCH_ANTENNA,
IWL_LEGACY_LAST_ACTION = IWL_LEGACY_SWITCH_MIMO2,
};
/* possible actions when in siso mode */ /* possible actions when in siso mode */
#define IWL_SISO_SWITCH_ANTENNA1 0 enum {
#define IWL_SISO_SWITCH_ANTENNA2 1 IWL_SISO_SWITCH_ANTENNA,
#define IWL_SISO_SWITCH_MIMO2 2 IWL_SISO_SWITCH_MIMO2,
#define IWL_SISO_SWITCH_GI 3 IWL_SISO_SWITCH_GI,
IWL_SISO_FIRST_ACTION = IWL_SISO_SWITCH_ANTENNA,
IWL_SISO_LAST_ACTION = IWL_SISO_SWITCH_GI,
};
/* possible actions when in mimo mode */ /* possible actions when in mimo mode */
#define IWL_MIMO2_SWITCH_ANTENNA1 0 enum {
#define IWL_MIMO2_SWITCH_ANTENNA2 1 IWL_MIMO2_SWITCH_SISO_A,
#define IWL_MIMO2_SWITCH_SISO_A 2 IWL_MIMO2_SWITCH_SISO_B,
#define IWL_MIMO2_SWITCH_SISO_B 3 IWL_MIMO2_SWITCH_GI,
#define IWL_MIMO2_SWITCH_GI 4 IWL_MIMO2_FIRST_ACTION = IWL_MIMO2_SWITCH_SISO_A,
IWL_MIMO2_LAST_ACTION = IWL_MIMO2_SWITCH_GI,
};
#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_GI #define IWL_MAX_SEARCH IWL_MIMO2_LAST_ACTION
#define IWL_ACTION_LIMIT 3 /* # possible actions */ #define IWL_ACTION_LIMIT 3 /* # possible actions */
...@@ -188,20 +215,31 @@ enum { ...@@ -188,20 +215,31 @@ enum {
enum iwl_table_type { enum iwl_table_type {
LQ_NONE, LQ_NONE,
LQ_G, /* legacy types */ LQ_LEGACY_G, /* legacy types */
LQ_A, LQ_LEGACY_A,
LQ_SISO, /* high-throughput types */ LQ_HT_SISO, /* HT types */
LQ_MIMO2, LQ_HT_MIMO2,
LQ_VHT_SISO, /* VHT types */
LQ_VHT_MIMO2,
LQ_MAX, LQ_MAX,
}; };
#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A)) #define is_legacy(tbl) (((tbl) == LQ_LEGACY_G) || ((tbl) == LQ_LEGACY_A))
#define is_siso(tbl) ((tbl) == LQ_SISO) #define is_ht_siso(tbl) ((tbl) == LQ_HT_SISO)
#define is_mimo2(tbl) ((tbl) == LQ_MIMO2) #define is_ht_mimo2(tbl) ((tbl) == LQ_HT_MIMO2)
#define is_mimo(tbl) is_mimo2(tbl) #define is_vht_siso(tbl) ((tbl) == LQ_VHT_SISO)
#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl)) #define is_vht_mimo2(tbl) ((tbl) == LQ_VHT_MIMO2)
#define is_a_band(tbl) ((tbl) == LQ_A) #define is_siso(tbl) (is_ht_siso(tbl) || is_vht_siso(tbl))
#define is_g_and(tbl) ((tbl) == LQ_G) #define is_mimo2(tbl) (is_ht_mimo2(tbl) || is_vht_mimo2(tbl))
#define is_mimo(tbl) (is_mimo2(tbl))
#define is_ht(tbl) (is_ht_siso(tbl) || is_ht_mimo2(tbl))
#define is_vht(tbl) (is_vht_siso(tbl) || is_vht_mimo2(tbl))
#define is_a_band(tbl) ((tbl) == LQ_LEGACY_A)
#define is_g_band(tbl) ((tbl) == LQ_LEGACY_G)
#define is_ht20(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_20)
#define is_ht40(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_40)
#define is_ht80(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_80)
#define IWL_MAX_MCS_DISPLAY_SIZE 12 #define IWL_MAX_MCS_DISPLAY_SIZE 12
...@@ -232,7 +270,7 @@ struct iwl_scale_tbl_info { ...@@ -232,7 +270,7 @@ struct iwl_scale_tbl_info {
enum iwl_table_type lq_type; enum iwl_table_type lq_type;
u8 ant_type; u8 ant_type;
u8 is_SGI; /* 1 = short guard interval */ u8 is_SGI; /* 1 = short guard interval */
u8 is_ht40; /* 1 = 40 MHz channel width */ u32 bw; /* channel bandwidth; RATE_MCS_CHAN_WIDTH_XX */
u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
u8 max_search; /* maximun number of tables we can search */ u8 max_search; /* maximun number of tables we can search */
s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
...@@ -262,7 +300,7 @@ struct iwl_lq_sta { ...@@ -262,7 +300,7 @@ struct iwl_lq_sta {
u64 flush_timer; /* time staying in mode before new search */ u64 flush_timer; /* time staying in mode before new search */
u8 action_counter; /* # mode-switch actions tried */ u8 action_counter; /* # mode-switch actions tried */
u8 is_green; bool is_vht;
enum ieee80211_band band; enum ieee80211_band band;
/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
......
...@@ -422,6 +422,27 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac, ...@@ -422,6 +422,27 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
mvmvif->bf_data.ave_beacon_signal = sig; mvmvif->bf_data.ave_beacon_signal = sig;
/* BT Coex */
if (mvmvif->bf_data.bt_coex_min_thold !=
mvmvif->bf_data.bt_coex_max_thold) {
last_event = mvmvif->bf_data.last_bt_coex_event;
if (sig > mvmvif->bf_data.bt_coex_max_thold &&
(last_event <= mvmvif->bf_data.bt_coex_min_thold ||
last_event == 0)) {
mvmvif->bf_data.last_bt_coex_event = sig;
IWL_DEBUG_RX(mvm, "cqm_iterator bt coex high %d\n",
sig);
iwl_mvm_bt_rssi_event(mvm, vif, RSSI_EVENT_HIGH);
} else if (sig < mvmvif->bf_data.bt_coex_min_thold &&
(last_event >= mvmvif->bf_data.bt_coex_max_thold ||
last_event == 0)) {
mvmvif->bf_data.last_bt_coex_event = sig;
IWL_DEBUG_RX(mvm, "cqm_iterator bt coex low %d\n",
sig);
iwl_mvm_bt_rssi_event(mvm, vif, RSSI_EVENT_LOW);
}
}
if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI))
return; return;
......
This diff is collapsed.
This diff is collapsed.
...@@ -293,10 +293,6 @@ struct iwl_mvm_sta { ...@@ -293,10 +293,6 @@ struct iwl_mvm_sta {
struct iwl_lq_sta lq_sta; struct iwl_lq_sta lq_sta;
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
#ifdef CONFIG_PM_SLEEP
u16 last_seq_ctl;
#endif
/* Temporary, until the new TLC will control the Tx protection */ /* Temporary, until the new TLC will control the Tx protection */
s8 tx_protection; s8 tx_protection;
bool tt_tx_protection; bool tt_tx_protection;
......
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2013 Intel Corporation. All rights reserved.
*
* 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
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
* USA
*
* The full GNU General Public License is included in this distribution
* in the file called COPYING.
*
* Contact Information:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
* Copyright(c) 2013 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
#ifndef __IWL_MVM_TESTMODE_H__
#define __IWL_MVM_TESTMODE_H__
/**
* enum iwl_mvm_testmode_attrs - testmode attributes inside NL80211_ATTR_TESTDATA
* @IWL_MVM_TM_ATTR_UNSPEC: (invalid attribute)
* @IWL_MVM_TM_ATTR_CMD: sub command, see &enum iwl_mvm_testmode_commands (u32)
* @IWL_MVM_TM_ATTR_NOA_DURATION: requested NoA duration (u32)
* @IWL_MVM_TM_ATTR_BEACON_FILTER_STATE: beacon filter state (0 or 1, u32)
*/
enum iwl_mvm_testmode_attrs {
IWL_MVM_TM_ATTR_UNSPEC,
IWL_MVM_TM_ATTR_CMD,
IWL_MVM_TM_ATTR_NOA_DURATION,
IWL_MVM_TM_ATTR_BEACON_FILTER_STATE,
/* keep last */
NUM_IWL_MVM_TM_ATTRS,
IWL_MVM_TM_ATTR_MAX = NUM_IWL_MVM_TM_ATTRS - 1,
};
/**
* enum iwl_mvm_testmode_commands - MVM testmode commands
* @IWL_MVM_TM_CMD_SET_NOA: set NoA on GO vif for testing
* @IWL_MVM_TM_CMD_SET_BEACON_FILTER: turn beacon filtering off/on
*/
enum iwl_mvm_testmode_commands {
IWL_MVM_TM_CMD_SET_NOA,
IWL_MVM_TM_CMD_SET_BEACON_FILTER,
};
#endif /* __IWL_MVM_TESTMODE_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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