/* Do not direct RSS traffic to Q 0 which is our fallback queue */ for (i = 0; i < ARRAY_SIZE(cmd.indirection_table); i++)
cmd.indirection_table[i] =
1 + (i % (mvm->trans->info.num_rxqs - 1));
netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key));
if (!mvm->trans->dbg.imr_data.imr_enable) { for (i = 0; i < ARRAY_SIZE(mvm->trans->dbg.active_regions); i++) { struct iwl_ucode_tlv *reg_tlv; struct iwl_fw_ini_region_tlv *reg;
reg_tlv = mvm->trans->dbg.active_regions[i]; if (!reg_tlv) continue;
reg = (void *)reg_tlv->data; /* * We have only one DRAM IMR region, so we * can break as soon as we find the first * one.
*/ if (reg->type == IWL_FW_INI_REGION_DRAM_IMR) {
mvm->trans->dbg.unsupported_region_msk |= BIT(i); break;
}
}
}
/* * We want to load the INIT firmware even in RFKILL * For the unified firmware case, the ucode_type is not * INIT, but we still need to run it.
*/
ret = iwl_trans_start_fw(mvm->trans, mvm->fw, ucode_type,
run_in_rfkill); if (ret) {
iwl_fw_set_current_image(&mvm->fwrt, old_type);
iwl_remove_notification(&mvm->notif_wait, &alive_wait); return ret;
}
/* * Some things may run in the background now, but we * just wait for the ALIVE notification here.
*/
ret = iwl_wait_notification(&mvm->notif_wait, &alive_wait,
MVM_UCODE_ALIVE_TIMEOUT);
if (!alive_data.valid) {
IWL_ERR(mvm, "Loaded ucode is not valid!\n");
iwl_fw_set_current_image(&mvm->fwrt, old_type); return -EIO;
}
/* if reached this point, Alive notification was received */
iwl_mei_alive_notif(true);
iwl_trans_fw_alive(mvm->trans);
ret = iwl_pnvm_load(mvm->trans, &mvm->notif_wait,
mvm->fw, alive_data.sku_id); if (ret) {
IWL_ERR(mvm, "Timeout waiting for PNVM load!\n");
iwl_fw_set_current_image(&mvm->fwrt, old_type); return ret;
}
/* * Note: all the queues are enabled as part of the interface * initialization, but in firmware restart scenarios they * could be stopped, so wake them up. In firmware restart, * mac80211 will have the queues stopped as well until the * reconfiguration completes. During normal startup, they * will be empty.
*/
memset(&mvm->queue_info, 0, sizeof(mvm->queue_info)); /* * Set a 'fake' TID for the command queue, since we use the * hweight() of the tid_bitmap as a refcount now. Not that * we ever even consider the command queue as one we might * want to reuse, but be safe nevertheless.
*/
mvm->queue_info[IWL_MVM_DQA_CMD_QUEUE].tid_bitmap =
BIT(IWL_MAX_TID_COUNT + 2);
/* * For pre-MLD API (MLD API doesn't use the timestamps): * All the BSSes in the BSS table include the GP2 in the system * at the beacon Rx time, this is of course no longer relevant * since we are resetting the firmware. * Purge all the BSS table.
*/ if (!mvm->mld_api_is_used)
cfg80211_bss_flush(mvm->hw->wiphy);
if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) {
IWL_DEBUG_RADIO(mvm, "UATS feature is not supported\n"); return;
}
cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, cmd.id,
IWL_FW_CMD_VER_UNKNOWN); if (cmd_ver != 1) {
IWL_DEBUG_RADIO(mvm, "MCC_ALLOWED_AP_TYPE_CMD ver %d not supported\n",
cmd_ver); return;
}
iwl_uefi_get_uats_table(mvm->trans, &mvm->fwrt);
if (!mvm->fwrt.uats_valid) return;
ret = iwl_mvm_send_cmd(mvm, &cmd); if (ret < 0)
IWL_ERR(mvm, "failed to send MCC_ALLOWED_AP_TYPE_CMD (%d)\n",
ret); else
IWL_DEBUG_RADIO(mvm, "MCC_ALLOWED_AP_TYPE_CMD sent to FW\n");
}
if (iwl_mvm_has_unified_ucode(mvm) &&
!mvm->trans->cfg->tx_with_siso_diversity) return 0;
if (mvm->trans->cfg->tx_with_siso_diversity) { /* * TODO: currently we don't set the antenna but letting the NIC * to decide which antenna to use. This should come from BIOS.
*/
phy_cfg_cmd.phy_cfg =
cpu_to_le32(FW_PHY_CFG_CHAIN_SAD_ENABLED);
}
/* Set parameters */
phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_get_phy_config(mvm));
/* set flags extra PHY configuration flags from the device's cfg */
phy_cfg_cmd.phy_cfg |=
cpu_to_le32(mvm->trans->mac_cfg->extra_phy_cfg_flags);
if (mvm->trans->cfg->tx_with_siso_diversity)
init_cfg.init_flags |= cpu_to_le32(BIT(IWL_INIT_PHY));
lockdep_assert_held(&mvm->mutex);
mvm->rfkill_safe_init_done = false;
if (mvm->trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
sb_cfg = iwl_read_umac_prph(mvm->trans, SB_MODIFY_CFG_FLAG); /* if needed, we'll reset this on our way out later */
mvm->fw_product_reset = sb_cfg == SB_CFG_RESIDES_IN_ROM; if (mvm->fw_product_reset && iwl_mei_pldr_req()) return -EBUSY;
}
/* Will also start the device */
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR); if (ret) {
IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
/* if we needed reset then fail here, but notify and remove */ if (mvm->fw_product_reset) {
iwl_mei_alive_notif(false);
iwl_trans_pcie_reset(mvm->trans,
IWL_RESET_MODE_RESCAN);
}
/* Send init config command to mark that we are sending NVM access * commands
*/
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(SYSTEM_GROUP,
INIT_EXTENDED_CFG_CMD),
CMD_SEND_IN_RFKILL, sizeof(init_cfg), &init_cfg); if (ret) {
IWL_ERR(mvm, "Failed to run init config command: %d\n",
ret); goto error;
}
/* Load NVM to NIC if needed */ if (mvm->nvm_file_name) {
ret = iwl_read_external_nvm(mvm->trans, mvm->nvm_file_name,
mvm->nvm_sections); if (ret) goto error;
ret = iwl_mvm_load_nvm_to_nic(mvm); if (ret) goto error;
}
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(REGULATORY_AND_NVM_GROUP,
NVM_ACCESS_COMPLETE),
CMD_SEND_IN_RFKILL, sizeof(nvm_complete), &nvm_complete); if (ret) {
IWL_ERR(mvm, "Failed to run complete NVM access: %d\n",
ret); goto error;
}
ret = iwl_send_phy_cfg_cmd(mvm); if (ret) {
IWL_ERR(mvm, "Failed to run PHY configuration: %d\n",
ret); goto error;
}
/* We wait for the INIT complete notification */
ret = iwl_wait_notification(&mvm->notif_wait, &init_wait,
MVM_UCODE_ALIVE_TIMEOUT); if (ret) return ret;
/* Read the NVM only at driver load time, no need to do this twice */ if (!mvm->nvm_data) {
mvm->nvm_data = iwl_get_nvm(mvm->trans, mvm->fw,
mvm->set_tx_ant, mvm->set_rx_ant); if (IS_ERR(mvm->nvm_data)) {
ret = PTR_ERR(mvm->nvm_data);
mvm->nvm_data = NULL;
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret); return ret;
}
}
/* Will also start the device */
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_INIT); if (ret) {
IWL_ERR(mvm, "Failed to start INIT ucode: %d\n", ret); goto remove_notif;
}
if (mvm->trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_8000) {
ret = iwl_mvm_send_bt_init_conf(mvm); if (ret) goto remove_notif;
}
/* Read the NVM only at driver load time, no need to do this twice */ if (!mvm->nvm_data) {
ret = iwl_nvm_init(mvm); if (ret) {
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret); goto remove_notif;
}
}
/* In case we read the NVM from external file, load it to the NIC */ if (mvm->nvm_file_name) {
ret = iwl_mvm_load_nvm_to_nic(mvm); if (ret) goto remove_notif;
}
WARN_ONCE(mvm->nvm_data->nvm_version < mvm->trans->cfg->nvm_ver, "Too old NVM version (0x%0x, required = 0x%0x)",
mvm->nvm_data->nvm_version, mvm->trans->cfg->nvm_ver);
/* * abort after reading the nvm in case RF Kill is on, we will complete * the init seq later when RF kill will switch to off
*/ if (iwl_mvm_is_radio_hw_killed(mvm)) {
IWL_DEBUG_RF_KILL(mvm, "jump over all phy activities due to RF kill\n"); goto remove_notif;
}
mvm->rfkill_safe_init_done = true;
/* Send TX valid antennas before triggering calibrations */
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm)); if (ret) goto remove_notif;
ret = iwl_send_phy_cfg_cmd(mvm); if (ret) {
IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
ret); goto remove_notif;
}
/* * Some things may run in the background now, but we * just wait for the calibration complete notification.
*/
ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
MVM_UCODE_CALIB_TIMEOUT); if (!ret) goto out;
if (iwl_mvm_is_radio_hw_killed(mvm)) {
IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
ret = 0;
} else {
IWL_ERR(mvm, "Failed to run INIT calibrations: %d\n",
ret);
}
goto out;
remove_notif:
iwl_remove_notification(&mvm->notif_wait, &calib_wait);
out:
mvm->rfkill_safe_init_done = false; if (!mvm->nvm_data) { /* we want to debug INIT and we have no NVM - fake */
mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) + sizeof(struct ieee80211_channel) + sizeof(struct ieee80211_rate),
GFP_KERNEL); if (!mvm->nvm_data) return -ENOMEM;
mvm->nvm_data->bands[0].channels = mvm->nvm_data->channels;
mvm->nvm_data->bands[0].n_channels = 1;
mvm->nvm_data->bands[0].n_bitrates = 1;
mvm->nvm_data->bands[0].bitrates =
(void *)(mvm->nvm_data->channels + 1);
mvm->nvm_data->bands[0].bitrates->hw_value = 10;
}
BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v1, table) !=
offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, table) ||
offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, table) !=
offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, table) ||
offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, table) !=
offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, table) ||
offsetof(struct iwl_geo_tx_power_profiles_cmd_v4, table) !=
offsetof(struct iwl_geo_tx_power_profiles_cmd_v5, table)); /* the table is at the same position for all versions, so set use v1 */
ret = iwl_sar_geo_fill_table(&mvm->fwrt, &cmd.v1.table[0][0],
n_bands, n_profiles);
/* * It is a valid scenario to not support SAR, or miss wgds table, * but in that case there is no need to send the command.
*/ if (ret) return 0;
int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
{ union iwl_ppag_table_cmd cmd; int ret, cmd_size;
ret = iwl_fill_ppag_table(&mvm->fwrt, &cmd, &cmd_size); /* Not supporting PPAG table is a valid scenario */ if (ret < 0) return 0;
IWL_DEBUG_RADIO(mvm, "Sending PER_PLATFORM_ANT_GAIN_CMD\n");
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP,
PER_PLATFORM_ANT_GAIN_CMD),
0, cmd_size, &cmd); if (ret < 0)
IWL_ERR(mvm, "failed to send PER_PLATFORM_ANT_GAIN_CMD (%d)\n",
ret);
return ret;
}
staticint iwl_mvm_ppag_init(struct iwl_mvm *mvm)
{ /* no need to read the table, done in INIT stage */ if (!(iwl_is_ppag_approved(&mvm->fwrt))) return 0;
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TAS_CFG)) {
IWL_DEBUG_RADIO(mvm, "TAS not enabled in FW\n"); return;
}
ret = iwl_bios_get_tas_table(&mvm->fwrt, &data); if (ret < 0) {
IWL_DEBUG_RADIO(mvm, "TAS table invalid or unavailable. (%d)\n",
ret); return;
}
if (ret == 0 && fw_ver < 5) return;
if (!iwl_is_tas_approved()) {
IWL_DEBUG_RADIO(mvm, "System vendor '%s' is not in the approved list, disabling TAS in US and Canada.\n",
dmi_get_system_info(DMI_SYS_VENDOR) ?: ""); if ((!iwl_add_mcc_to_tas_block_list(data.block_list_array,
&data.block_list_size,
IWL_MCC_US)) ||
(!iwl_add_mcc_to_tas_block_list(data.block_list_array,
&data.block_list_size,
IWL_MCC_CANADA))) {
IWL_DEBUG_RADIO(mvm, "Unable to add US/Canada to TAS block list, disabling TAS\n"); return;
}
} else {
IWL_DEBUG_RADIO(mvm, "System vendor '%s' is in the approved list.\n",
dmi_get_system_info(DMI_SYS_VENDOR) ?: "");
}
if (fw_ver < 5) {
selection_data = iwl_parse_tas_selection(data.tas_selection,
data.table_revision);
cmd_v2_v4.common.block_list_size =
cpu_to_le32(data.block_list_size); for (u8 i = 0; i < data.block_list_size; i++)
cmd_v2_v4.common.block_list_array[i] =
cpu_to_le32(data.block_list_array[i]);
}
ret = iwl_fill_lari_config(&mvm->fwrt, &cmd, &cmd_size); if (!ret) {
ret = iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(REGULATORY_AND_NVM_GROUP,
LARI_CONFIG_CHANGE),
0, cmd_size, &cmd); if (ret < 0)
IWL_DEBUG_RADIO(mvm, "Failed to send LARI_CONFIG_CHANGE (%d)\n",
ret);
}
}
void iwl_mvm_get_bios_tables(struct iwl_mvm *mvm)
{ int ret;
iwl_acpi_get_guid_lock_status(&mvm->fwrt);
/* read PPAG table */
ret = iwl_bios_get_ppag_table(&mvm->fwrt); if (ret < 0) {
IWL_DEBUG_RADIO(mvm, "PPAG BIOS table invalid or unavailable. (%d)\n",
ret);
}
/* read SAR tables */
ret = iwl_bios_get_wrds_table(&mvm->fwrt); if (ret < 0) {
IWL_DEBUG_RADIO(mvm, "WRDS SAR BIOS table invalid or unavailable. (%d)\n",
ret); /* * If not available, don't fail and don't bother with EWRD and
* WGDS */
if (!iwl_bios_get_wgds_table(&mvm->fwrt)) { /* * If basic SAR is not available, we check for WGDS, * which should *not* be available either. If it is * available, issue an error, because we can't use SAR * Geo without basic SAR.
*/
IWL_ERR(mvm, "BIOS contains WGDS but no WRDS\n");
}
} else {
ret = iwl_bios_get_ewrd_table(&mvm->fwrt); /* if EWRD is not available, we can still use
* WRDS, so don't fail */ if (ret < 0)
IWL_DEBUG_RADIO(mvm, "EWRD SAR BIOS table invalid or unavailable. (%d)\n",
ret);
/* read geo SAR table */ if (iwl_sar_geo_support(&mvm->fwrt)) {
ret = iwl_bios_get_wgds_table(&mvm->fwrt); if (ret < 0)
IWL_DEBUG_RADIO(mvm, "Geo SAR BIOS table invalid or unavailable. (%d)\n",
ret); /* we don't fail if the table is not available */
}
}
iwl_acpi_get_phy_filters(&mvm->fwrt);
if (iwl_bios_get_eckv(&mvm->fwrt, &mvm->ext_clock_valid))
IWL_DEBUG_RADIO(mvm, "ECKV table doesn't exist in BIOS\n");
}
ret = iwl_mvm_send_cmd_status(mvm, &host_cmd, &status);
kfree(mvm->error_recovery_buf);
mvm->error_recovery_buf = NULL;
if (ret) {
IWL_ERR(mvm, "Failed to send recovery cmd %d\n", ret); return;
}
/* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */ if (flags & ERROR_RECOVERY_UPDATE_DB) { if (status) {
IWL_ERR(mvm, "Failed to send recovery cmd blob was invalid %d\n",
status);
ret = iwl_mvm_sf_update(mvm, NULL, false); if (ret)
IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
if (!iwl_trans_dbg_ini_valid(mvm->trans)) {
mvm->fwrt.dump.conf = FW_DBG_INVALID; /* if we have a destination, assume EARLY START */ if (mvm->fw->dbg.dest_tlv)
mvm->fwrt.dump.conf = FW_DBG_START_FROM_ALIVE;
iwl_fw_start_dbg_conf(&mvm->fwrt, FW_DBG_START_FROM_ALIVE);
}
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm)); if (ret) goto error;
if (!iwl_mvm_has_unified_ucode(mvm)) { /* Send phy db control command and then phy db calibration */
ret = iwl_send_phy_db_data(mvm->phy_db); if (ret) goto error;
ret = iwl_send_phy_cfg_cmd(mvm); if (ret) goto error;
}
ret = iwl_mvm_send_bt_init_conf(mvm); if (ret) goto error;
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_SOC_LATENCY_SUPPORT)) {
ret = iwl_set_soc_latency(&mvm->fwrt); if (ret) goto error;
}
iwl_mvm_lari_cfg(mvm);
/* Init RSS configuration */
ret = iwl_configure_rxq(&mvm->fwrt); if (ret) goto error;
if (iwl_mvm_has_new_rx_api(mvm)) {
ret = iwl_send_rss_cfg_cmd(mvm); if (ret) {
IWL_ERR(mvm, "Failed to configure RSS queues: %d\n",
ret); goto error;
}
}
/* init the fw <-> mac80211 STA mapping */ for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
RCU_INIT_POINTER(mvm->fw_id_to_link_sta[i], NULL);
}
mvm->tdls_cs.peer.sta_id = IWL_INVALID_STA;
/* reset quota debouncing buffer - 0xff will yield invalid data */
memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd));
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_DQA_SUPPORT)) {
ret = iwl_mvm_send_dqa_cmd(mvm); if (ret) goto error;
}
/* * Add auxiliary station for scanning. * Newer versions of this command implies that the fw uses * internal aux station for all aux activities that don't * requires a dedicated data queue.
*/ if (!iwl_mvm_has_new_station_api(mvm->fw)) { /* * In old version the aux station uses mac id like other * station and not lmac id
*/
ret = iwl_mvm_add_aux_sta(mvm, MAC_INDEX_AUX); if (ret) goto error;
}
/* Add all the PHY contexts */
i = 0; while (!sband && i < NUM_NL80211_BANDS)
sband = mvm->hw->wiphy->bands[i++];
if (WARN_ON_ONCE(!sband)) {
ret = -ENODEV; goto error;
}
if (iwl_mvm_is_tt_in_fw(mvm)) { /* in order to give the responsibility of ct-kill and * TX backoff to FW we need to send empty temperature reporting * cmd during init time
*/
iwl_mvm_send_temp_report_ths_cmd(mvm);
} else { /* Initialize tx backoffs to the minimal possible */
iwl_mvm_tt_tx_backoff(mvm, 0);
}
#ifdef CONFIG_THERMAL /* TODO: read the budget from BIOS / Platform NVM */
/* * In case there is no budget from BIOS / Platform NVM the default * budget should be 2000mW (cooling state 0).
*/ if (iwl_mvm_is_ctdp_supported(mvm)) {
ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START,
mvm->cooling_dev.cur_state); if (ret) goto error;
} #endif
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2))
WARN_ON(iwl_mvm_config_ltr(mvm));
ret = iwl_mvm_power_update_device(mvm); if (ret) goto error;
/* * RTNL is not taken during Ct-kill, but we don't need to scan/Tx * anyway, so don't init MCC.
*/ if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) {
ret = iwl_mvm_init_mcc(mvm); if (ret) goto error;
}
if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
mvm->scan_type = IWL_SCAN_TYPE_NOT_SET;
mvm->hb_scan_type = IWL_SCAN_TYPE_NOT_SET;
ret = iwl_mvm_config_scan(mvm); if (ret) goto error;
}
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_UPDATE_DB);
if (mvm->time_sync.active)
iwl_mvm_time_sync_config(mvm, mvm->time_sync.peer_addr,
IWL_TIME_SYNC_PROTOCOL_TM |
IWL_TIME_SYNC_PROTOCOL_FTM);
}
if (!mvm->ptp_data.ptp_clock)
iwl_mvm_ptp_init(mvm);
ret = iwl_mvm_ppag_init(mvm); if (ret) goto error;
ret = iwl_mvm_sar_init(mvm); if (ret == 0)
ret = iwl_mvm_sar_geo_init(mvm); if (ret < 0) goto error;
ret = iwl_mvm_sgom_init(mvm); if (ret) goto error;
ret = iwl_trans_start_hw(mvm->trans); if (ret) return ret;
ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_WOWLAN); if (ret) {
IWL_ERR(mvm, "Failed to start WoWLAN firmware: %d\n", ret); goto error;
}
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm)); if (ret) goto error;
/* Send phy db control command and then phy db calibration*/
ret = iwl_send_phy_db_data(mvm->phy_db); if (ret) goto error;
ret = iwl_send_phy_cfg_cmd(mvm); if (ret) goto error;
/* init the fw <-> mac80211 STA mapping */ for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
RCU_INIT_POINTER(mvm->fw_id_to_link_sta[i], NULL);
}
if (!iwl_mvm_has_new_station_api(mvm->fw)) { /* * Add auxiliary station for scanning. * Newer versions of this command implies that the fw uses * internal aux station for all aux activities that don't * requires a dedicated data queue. * In old version the aux station uses mac id like other * station and not lmac id
*/
ret = iwl_mvm_add_aux_sta(mvm, MAC_INDEX_AUX); if (ret) goto error;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.