wireless-drivers-next patches for v5.10
Fourth and last set of patches for v5.10. Most of these are iwlwifi patches, but few small fixes to other drivers as well. Major changes: iwlwifi * PNVM support (platform-specific phy config data) * bump the FW API support to 59 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJfgIilAAoJEG4XJFUm622b/MoH+wfx+CnW2J49uRAlAiAyJ8oW pBKvJF1b6kbLeWurQPQH6ecmmYy0H/Cr8Zy4IW+YP7XN5PbSpDe4HXH6GkLP41fv 73kd0qHPFp42dmArImCqd8+9vAuh6C/taHSPV8klGaSfATUvvDIwgPrxGJnaGvwm 3E+SOnGcvqRV1fkBi7CArdIa1DzZwyu9q9zvQKbElmL7lX/r5kAzkHZqlMr3ZyjO Gvuzvz9FIKvkU81IxtR8VXJh5RQ9WCXvsa00ZoP489jUz/lUoC2Rjofn55BcdAIh 1V4N7yOM2KFjDo3RWGZo+fqNo6LXREMyVQetmXCWPzFzCkMTN5FCWuj182dnYIM= =9NpN -----END PGP SIGNATURE----- Merge tag 'wireless-drivers-next-2020-10-09' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next Kalle Valo says: ==================== wireless-drivers-next patches for v5.10 Fourth and last set of patches for v5.10. Most of these are iwlwifi patches, but few small fixes to other drivers as well. Major changes: iwlwifi * PNVM support (platform-specific phy config data) * bump the FW API support to 59 ==================== Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Коммит
8df245c40a
|
@ -6041,8 +6041,10 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
|
|||
n_limits = 2;
|
||||
|
||||
limits = kcalloc(n_limits, sizeof(*limits), GFP_KERNEL);
|
||||
if (!limits)
|
||||
if (!limits) {
|
||||
kfree(combinations);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
limits[0].max = 1;
|
||||
limits[0].types |= BIT(NL80211_IFTYPE_STATION);
|
||||
|
|
|
@ -16,7 +16,7 @@ iwlwifi-objs += iwl-trans.o
|
|||
iwlwifi-objs += queue/tx.o
|
||||
|
||||
iwlwifi-objs += fw/img.o fw/notif-wait.o
|
||||
iwlwifi-objs += fw/dbg.o
|
||||
iwlwifi-objs += fw/dbg.o fw/pnvm.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o
|
||||
iwlwifi-$(CONFIG_ACPI) += fw/acpi.o
|
||||
iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += fw/debugfs.o
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
#include "iwl-prph.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL_22000_UCODE_API_MAX 57
|
||||
#define IWL_22000_UCODE_API_MAX 59
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL_22000_UCODE_API_MIN 39
|
||||
|
@ -253,7 +253,7 @@ const struct iwl_cfg_trans_params iwl_qu_trans_cfg = {
|
|||
.device_family = IWL_DEVICE_FAMILY_22000,
|
||||
.base_params = &iwl_22000_base_params,
|
||||
.integrated = true,
|
||||
.xtal_latency = 5000,
|
||||
.xtal_latency = 500,
|
||||
.ltr_delay = IWL_CFG_TRANS_LTR_DELAY_200US,
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
* Copyright(c) 2018 - 2020 Intel Corporation
|
||||
*
|
||||
* 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
|
||||
|
@ -20,7 +20,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
* Copyright(c) 2018 - 2020 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -180,7 +180,16 @@ const struct iwl_cfg_trans_params iwl9560_trans_cfg = {
|
|||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.integrated = true,
|
||||
.xtal_latency = 5000,
|
||||
.xtal_latency = 650,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl9560_long_latency_trans_cfg = {
|
||||
.device_family = IWL_DEVICE_FAMILY_9000,
|
||||
.base_params = &iwl9000_base_params,
|
||||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.integrated = true,
|
||||
.xtal_latency = 2820,
|
||||
};
|
||||
|
||||
const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg = {
|
||||
|
@ -189,7 +198,7 @@ const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg = {
|
|||
.mq_rx_supported = true,
|
||||
.rf_id = true,
|
||||
.integrated = true,
|
||||
.xtal_latency = 5000,
|
||||
.xtal_latency = 670,
|
||||
.extra_phy_cfg_flags = FW_PHY_CFG_SHARED_CLK
|
||||
};
|
||||
|
||||
|
|
|
@ -761,7 +761,7 @@ static inline u8 find_first_chain(u8 mask)
|
|||
return CHAIN_C;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Run disconnected antenna algorithm to find out which antennas are
|
||||
* disconnected.
|
||||
*/
|
||||
|
|
|
@ -58,8 +58,8 @@ static void iwl1000_nic_config(struct iwl_priv *priv)
|
|||
|
||||
/**
|
||||
* iwl_beacon_time_mask_low - mask of lower 32 bit of beacon time
|
||||
* @priv -- pointer to iwl_priv data structure
|
||||
* @tsf_bits -- number of bits need to shift for masking)
|
||||
* @priv: pointer to iwl_priv data structure
|
||||
* @tsf_bits: number of bits need to shift for masking)
|
||||
*/
|
||||
static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv,
|
||||
u16 tsf_bits)
|
||||
|
@ -69,8 +69,8 @@ static inline u32 iwl_beacon_time_mask_low(struct iwl_priv *priv,
|
|||
|
||||
/**
|
||||
* iwl_beacon_time_mask_high - mask of higher 32 bit of beacon time
|
||||
* @priv -- pointer to iwl_priv data structure
|
||||
* @tsf_bits -- number of bits need to shift for masking)
|
||||
* @priv: pointer to iwl_priv data structure
|
||||
* @tsf_bits: number of bits need to shift for masking)
|
||||
*/
|
||||
static inline u32 iwl_beacon_time_mask_high(struct iwl_priv *priv,
|
||||
u16 tsf_bits)
|
||||
|
|
|
@ -110,7 +110,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
|
|||
vif->bss_conf.bssid);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwlagn_txfifo_flush: send REPLY_TXFIFO_FLUSH command to uCode
|
||||
*
|
||||
* pre-requirements:
|
||||
|
@ -769,7 +769,7 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
|
|||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwlagn_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
|
||||
*
|
||||
* Selects how many and which Rx receivers/antennas/chains to use.
|
||||
|
|
|
@ -374,7 +374,7 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear)
|
|||
&statistics_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_bg_statistics_periodic - Timer callback to queue statistics
|
||||
*
|
||||
* This callback is provided in order to send a statistics request.
|
||||
|
@ -533,7 +533,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv)
|
|||
priv->event_log.next_entry = next_entry;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_bg_ucode_trace - Timer callback to log ucode event
|
||||
*
|
||||
* The timer is continually set to execute every
|
||||
|
@ -762,7 +762,7 @@ static void iwl_send_bt_config(struct iwl_priv *priv)
|
|||
IWL_ERR(priv, "failed to send BT Coex Config\n");
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_alive_start - called after REPLY_ALIVE notification received
|
||||
* from protocol/runtime uCode (initialization uCode's
|
||||
* Alive gets handled by iwl_init_alive_start()).
|
||||
|
@ -1682,9 +1682,8 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
|
|||
|
||||
#define EVENT_START_OFFSET (4 * sizeof(u32))
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_print_event_log - Dump error event log to syslog
|
||||
*
|
||||
*/
|
||||
static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
|
||||
u32 num_events, u32 mode,
|
||||
|
@ -1762,7 +1761,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
|
|||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_print_last_event_logs - Dump the newest # of event log to syslog
|
||||
*/
|
||||
static int iwl_print_last_event_logs(struct iwl_priv *priv, u32 capacity,
|
||||
|
|
|
@ -151,7 +151,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
|
|||
{}
|
||||
#endif
|
||||
|
||||
/**
|
||||
/*
|
||||
* The following tables contain the expected throughput metrics for all rates
|
||||
*
|
||||
* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
|
||||
|
@ -318,7 +318,7 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
/**
|
||||
/*
|
||||
* Program the device to use fixed rate for frame transmit
|
||||
* This is for debugging/testing only
|
||||
* once the device start use fixed rate, we need to reload the module
|
||||
|
@ -440,7 +440,7 @@ static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* rs_collect_tx_data - Update the success/failure sliding window
|
||||
*
|
||||
* We keep a sliding window of the last 62 packets transmitted
|
||||
|
@ -673,7 +673,7 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Green-field mode is valid if the station supports it and
|
||||
* there are no non-GF stations present in the BSS.
|
||||
*/
|
||||
|
@ -689,7 +689,7 @@ static bool rs_use_green(struct ieee80211_sta *sta)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* rs_get_supported_rates - get the available rates
|
||||
*
|
||||
* if management frame or broadcast frame only return
|
||||
|
@ -2612,7 +2612,7 @@ out:
|
|||
lq_sta->last_txrate_idx = index;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* rs_initialize_lq - Initialize a station's hardware rate table
|
||||
*
|
||||
* The uCode's station table contains a table of fallback rates
|
||||
|
|
|
@ -132,7 +132,7 @@ static void iwlagn_rx_beacon_notif(struct iwl_priv *priv,
|
|||
priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_good_plcp_health - checks for plcp error.
|
||||
*
|
||||
* When the plcp error is exceeding the thresholds, reset the radio
|
||||
|
@ -929,7 +929,7 @@ static void iwlagn_rx_noa_notification(struct iwl_priv *priv,
|
|||
kfree_rcu(old_data, rcu_head);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_setup_rx_handlers - Initialize Rx handler callbacks
|
||||
*
|
||||
* Setup the RX handlers for each of the reply types sent from the uCode
|
||||
|
|
|
@ -689,7 +689,7 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
|
|||
_iwl_set_rxon_ht(priv, ht_conf, ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_set_rxon_channel - Set the band and channel values in staging RXON
|
||||
* @ch: requested channel as a pointer to struct ieee80211_channel
|
||||
|
||||
|
@ -826,7 +826,7 @@ static int iwl_check_rxon_cmd(struct iwl_priv *priv,
|
|||
return errors ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
|
||||
* @priv: staging_rxon is compared to active_rxon
|
||||
*
|
||||
|
@ -1007,7 +1007,7 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv,
|
|||
ctx->staging.ofdm_basic_rates = ofdm;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwlagn_commit_rxon - commit staging_rxon to hardware
|
||||
*
|
||||
* The RXON command in staging_rxon is committed to the hardware and
|
||||
|
|
|
@ -186,7 +186,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
|
|||
IWL_DEBUG_SCAN(priv, "Successfully send scan abort\n");
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_scan_cancel - Cancel any currently executing HW scan
|
||||
*/
|
||||
int iwl_scan_cancel(struct iwl_priv *priv)
|
||||
|
@ -196,10 +196,9 @@ int iwl_scan_cancel(struct iwl_priv *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_scan_cancel_timeout - Cancel any currently executing HW scan
|
||||
* @ms: amount of time to wait (in milliseconds) for scan to abort
|
||||
*
|
||||
*/
|
||||
void iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
|
||||
{
|
||||
|
@ -560,10 +559,9 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
|
|||
return added;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_fill_probe_req - fill in all required fields and IE for probe request
|
||||
*/
|
||||
|
||||
static u16 iwl_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
|
||||
const u8 *ies, int ie_len, const u8 *ssid,
|
||||
u8 ssid_len, int left)
|
||||
|
|
|
@ -234,7 +234,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
|
|||
priv->stations[index].sta.station_flags |= flags;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_prep_station - Prepare station information for addition
|
||||
*
|
||||
* should be called with sta_lock held
|
||||
|
@ -323,7 +323,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
|
|||
|
||||
#define STA_WAIT_TIMEOUT (HZ/2)
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_add_station_common -
|
||||
*/
|
||||
int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
|
||||
|
@ -383,7 +383,7 @@ int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_sta_ucode_deactivate - deactivate ucode status for a station
|
||||
*/
|
||||
static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
|
||||
|
@ -451,7 +451,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_remove_station - Remove driver's knowledge of station.
|
||||
*/
|
||||
int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
|
||||
|
@ -601,7 +601,7 @@ static void iwl_sta_fill_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
|
|||
link_cmd->sta_id = sta_id;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_clear_ucode_stations - clear ucode station table bits
|
||||
*
|
||||
* This function clears all the bits in the driver indicating
|
||||
|
@ -636,7 +636,7 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv,
|
|||
"No active stations found to be cleared\n");
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_restore_stations() - Restore driver known stations to device
|
||||
*
|
||||
* All stations considered active by driver, but not present in ucode, is
|
||||
|
@ -773,7 +773,7 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
/*
|
||||
* is_lq_table_valid() - Test one aspect of LQ cmd for validity
|
||||
*
|
||||
* It sometimes happens when a HT rate has been in use and we
|
||||
|
@ -807,7 +807,7 @@ static bool is_lq_table_valid(struct iwl_priv *priv,
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_send_lq_cmd() - Send link quality command
|
||||
* @init: This command is sent as part of station initialization right
|
||||
* after station has been added.
|
||||
|
@ -1258,7 +1258,7 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwlagn_alloc_bcast_station - add broadcast station into driver's station table.
|
||||
*
|
||||
* This adds the broadcast station into the driver's station table
|
||||
|
@ -1298,7 +1298,7 @@ int iwlagn_alloc_bcast_station(struct iwl_priv *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_update_bcast_station - update broadcast station's LQ command
|
||||
*
|
||||
* Only used by iwlagn. Placed here to have all bcast station management
|
||||
|
@ -1341,7 +1341,7 @@ int iwl_update_bcast_stations(struct iwl_priv *priv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
|
||||
*/
|
||||
int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
|
||||
|
|
|
@ -803,7 +803,7 @@ static void iwlagn_non_agg_tx_status(struct iwl_priv *priv,
|
|||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* translate ucode response to mac80211 tx status control values
|
||||
*/
|
||||
static void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
|
||||
|
@ -1256,7 +1256,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwlagn_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
|
||||
*
|
||||
* Handles block-acknowledge notification from device, which reports success
|
||||
|
|
|
@ -662,17 +662,25 @@ int iwl_sar_geo_init(struct iwl_fw_runtime *fwrt,
|
|||
}
|
||||
|
||||
for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
|
||||
struct iwl_per_chain_offset *chain =
|
||||
(struct iwl_per_chain_offset *)&table[i];
|
||||
|
||||
for (j = 0; j < n_bands; j++) {
|
||||
struct iwl_per_chain_offset *chain =
|
||||
&table[i * n_bands + j];
|
||||
u8 *value;
|
||||
|
||||
if (j * ACPI_GEO_PER_CHAIN_SIZE >=
|
||||
ARRAY_SIZE(fwrt->geo_profiles[0].values))
|
||||
/*
|
||||
* Currently we only store lb an hb values, and
|
||||
* don't have any special ones for uhb. So leave
|
||||
* those empty for the time being
|
||||
*/
|
||||
break;
|
||||
|
||||
value = &fwrt->geo_profiles[i].values[j *
|
||||
ACPI_GEO_PER_CHAIN_SIZE];
|
||||
chain[j].max_tx_power = cpu_to_le16(value[0]);
|
||||
chain[j].chain_a = value[1];
|
||||
chain[j].chain_b = value[2];
|
||||
chain->max_tx_power = cpu_to_le16(value[0]);
|
||||
chain->chain_a = value[1];
|
||||
chain->chain_b = value[2];
|
||||
IWL_DEBUG_RADIO(fwrt,
|
||||
"SAR geographic profile[%d] Band[%d]: chain A = %d chain B = %d max_tx_power = %d\n",
|
||||
i, j, value[1], value[2], value[0]);
|
||||
|
|
|
@ -105,7 +105,6 @@
|
|||
#define APCI_WTAS_BLACK_LIST_MAX 16
|
||||
#define ACPI_WTAS_WIFI_DATA_SIZE (3 + APCI_WTAS_BLACK_LIST_MAX)
|
||||
|
||||
#define ACPI_WGDS_NUM_BANDS 2
|
||||
#define ACPI_WGDS_TABLE_SIZE 3
|
||||
|
||||
#define ACPI_PPAG_WIFI_DATA_SIZE ((IWL_NUM_CHAIN_LIMITS * \
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2012 - 2014, 2020 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
*
|
||||
|
@ -27,7 +27,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2012 - 2014, 2020 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
|
@ -59,10 +59,12 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __iwl_fw_api_binding_h__
|
||||
#define __iwl_fw_api_binding_h__
|
||||
|
||||
#include <fw/file.h>
|
||||
#include <fw/img.h>
|
||||
|
||||
#define MAX_MACS_IN_BINDING (3)
|
||||
#define MAX_BINDINGS (4)
|
||||
|
||||
|
@ -112,6 +114,14 @@ struct iwl_binding_cmd {
|
|||
#define IWL_LMAC_24G_INDEX 0
|
||||
#define IWL_LMAC_5G_INDEX 1
|
||||
|
||||
static inline u32 iwl_mvm_get_lmac_id(const struct iwl_fw *fw,
|
||||
enum nl80211_band band){
|
||||
if (!fw_has_capa(&fw->ucode_capa, IWL_UCODE_TLV_CAPA_CDB_SUPPORT) ||
|
||||
band == NL80211_BAND_2GHZ)
|
||||
return IWL_LMAC_24G_INDEX;
|
||||
return IWL_LMAC_5G_INDEX;
|
||||
}
|
||||
|
||||
/* The maximal number of fragments in the FW's schedule session */
|
||||
#define IWL_MVM_MAX_QUOTA 128
|
||||
|
||||
|
|
|
@ -411,7 +411,8 @@ enum iwl_legacy_cmds {
|
|||
* one of &struct iwl_statistics_cmd,
|
||||
* &struct iwl_notif_statistics_v11,
|
||||
* &struct iwl_notif_statistics_v10,
|
||||
* &struct iwl_notif_statistics
|
||||
* &struct iwl_notif_statistics,
|
||||
* &struct iwl_statistics_operational_ntfy
|
||||
*/
|
||||
STATISTICS_CMD = 0x9c,
|
||||
|
||||
|
@ -419,7 +420,8 @@ enum iwl_legacy_cmds {
|
|||
* @STATISTICS_NOTIFICATION:
|
||||
* one of &struct iwl_notif_statistics_v10,
|
||||
* &struct iwl_notif_statistics_v11,
|
||||
* &struct iwl_notif_statistics
|
||||
* &struct iwl_notif_statistic,
|
||||
* &struct iwl_statistics_operational_ntfy
|
||||
*/
|
||||
STATISTICS_NOTIFICATION = 0x9d,
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
#define NUM_MAC_INDEX (NUM_MAC_INDEX_DRIVER + 1)
|
||||
#define NUM_MAC_INDEX_CDB (NUM_MAC_INDEX_DRIVER + 2)
|
||||
|
||||
#define IWL_MVM_STATION_COUNT 16
|
||||
#define IWL_MVM_STATION_COUNT_MAX 16
|
||||
#define IWL_MVM_INVALID_STA 0xFF
|
||||
|
||||
enum iwl_ac {
|
||||
|
|
|
@ -90,6 +90,11 @@ enum iwl_regulatory_and_nvm_subcmd_ids {
|
|||
* @TAS_CONFIG: &struct iwl_tas_config_cmd
|
||||
*/
|
||||
TAS_CONFIG = 0x3,
|
||||
|
||||
/**
|
||||
* @PNVM_INIT_COMPLETE_NTFY: &struct iwl_pnvm_init_complete_ntfy
|
||||
*/
|
||||
PNVM_INIT_COMPLETE_NTFY = 0xFE,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -476,4 +481,12 @@ struct iwl_lari_config_change_cmd {
|
|||
__le32 config_bitmap;
|
||||
} __packed; /* LARI_CHANGE_CONF_CMD_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_pnvm_init_complete_ntfy - PNVM initialization complete
|
||||
* @status: PNVM image loading status
|
||||
*/
|
||||
struct iwl_pnvm_init_complete_ntfy {
|
||||
__le32 status;
|
||||
} __packed; /* PNVM_INIT_COMPLETE_NTFY_S_VER_1 */
|
||||
|
||||
#endif /* __iwl_fw_api_nvm_reg_h__ */
|
||||
|
|
|
@ -193,6 +193,8 @@ enum IWL_TLC_HT_BW_RATES {
|
|||
* @sgi_ch_width_supp: bitmap of SGI support per channel width
|
||||
* use BIT(@enum iwl_tlc_mng_cfg_cw)
|
||||
* @reserved2: reserved
|
||||
* @max_tx_op: max TXOP in uSecs for all AC (BK, BE, VO, VI),
|
||||
* set zero for no limit.
|
||||
*/
|
||||
struct iwl_tlc_config_cmd {
|
||||
u8 sta_id;
|
||||
|
@ -206,8 +208,9 @@ struct iwl_tlc_config_cmd {
|
|||
__le16 ht_rates[IWL_TLC_NSS_MAX][2];
|
||||
__le16 max_mpdu_len;
|
||||
u8 sgi_ch_width_supp;
|
||||
u8 reserved2[1];
|
||||
} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_2 */
|
||||
u8 reserved2;
|
||||
__le32 max_tx_op;
|
||||
} __packed; /* TLC_MNG_CONFIG_CMD_API_S_VER_3 */
|
||||
|
||||
/**
|
||||
* enum iwl_tlc_update_flags - updated fields
|
||||
|
|
|
@ -380,7 +380,7 @@ struct iwl_mvm_add_sta_cmd {
|
|||
u8 add_modify;
|
||||
u8 awake_acs;
|
||||
__le16 tid_disable_tx;
|
||||
__le32 mac_id_n_color;
|
||||
__le32 mac_id_n_color; /* can be used for lmac id when using cmd v12 */
|
||||
u8 addr[ETH_ALEN]; /* _STA_ID_MODIFY_INFO_API_S_VER_1 */
|
||||
__le16 reserved2;
|
||||
u8 sta_id;
|
||||
|
|
|
@ -5,10 +5,9 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright(c) 2012 - 2014, 2018, 2020 Intel Corporation
|
||||
*
|
||||
* 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
|
||||
|
@ -28,9 +27,8 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright(c) 2012 - 2014, 2018, 2020 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -383,14 +381,14 @@ struct mvm_statistics_load {
|
|||
__le32 air_time[MAC_INDEX_AUX];
|
||||
__le32 byte_count[MAC_INDEX_AUX];
|
||||
__le32 pkt_count[MAC_INDEX_AUX];
|
||||
u8 avg_energy[IWL_MVM_STATION_COUNT];
|
||||
u8 avg_energy[IWL_MVM_STATION_COUNT_MAX];
|
||||
} __packed; /* STATISTICS_RX_MAC_STATION_S_VER_3 */
|
||||
|
||||
struct mvm_statistics_load_v1 {
|
||||
__le32 air_time[NUM_MAC_INDEX];
|
||||
__le32 byte_count[NUM_MAC_INDEX];
|
||||
__le32 pkt_count[NUM_MAC_INDEX];
|
||||
u8 avg_energy[IWL_MVM_STATION_COUNT];
|
||||
u8 avg_energy[IWL_MVM_STATION_COUNT_MAX];
|
||||
} __packed; /* STATISTICS_RX_MAC_STATION_S_VER_1 */
|
||||
|
||||
struct mvm_statistics_rx {
|
||||
|
@ -466,4 +464,465 @@ struct iwl_statistics_cmd {
|
|||
__le32 flags;
|
||||
} __packed; /* STATISTICS_CMD_API_S_VER_1 */
|
||||
|
||||
#define MAX_BCAST_FILTER_NUM 8
|
||||
|
||||
/**
|
||||
* enum iwl_fw_statistics_type
|
||||
*
|
||||
* @FW_STATISTICS_OPERATIONAL: operational statistics
|
||||
* @FW_STATISTICS_PHY: phy statistics
|
||||
* @FW_STATISTICS_MAC: mac statistics
|
||||
* @FW_STATISTICS_RX: rx statistics
|
||||
* @FW_STATISTICS_TX: tx statistics
|
||||
* @FW_STATISTICS_DURATION: duration statistics
|
||||
* @FW_STATISTICS_HE: he statistics
|
||||
*/
|
||||
enum iwl_fw_statistics_type {
|
||||
FW_STATISTICS_OPERATIONAL,
|
||||
FW_STATISTICS_PHY,
|
||||
FW_STATISTICS_MAC,
|
||||
FW_STATISTICS_RX,
|
||||
FW_STATISTICS_TX,
|
||||
FW_STATISTICS_DURATION,
|
||||
FW_STATISTICS_HE,
|
||||
}; /* FW_STATISTICS_TYPE_API_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_ntfy_hdr
|
||||
*
|
||||
* @type: struct type
|
||||
* @version: version of the struct
|
||||
* @size: size in bytes
|
||||
*/
|
||||
struct iwl_statistics_ntfy_hdr {
|
||||
u8 type;
|
||||
u8 version;
|
||||
__le16 size;
|
||||
}; /* STATISTICS_NTFY_HDR_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_operational_ntfy
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @flags: bitmap of possible notification structures
|
||||
* @mac_id: mac on which the beacon was received
|
||||
* @beacon_filter_average_energy: Average energy [-dBm] of the 2
|
||||
* antennas.
|
||||
* @beacon_filter_reason: beacon filter reason
|
||||
* @radio_temperature: radio temperature
|
||||
* @air_time: air time
|
||||
* @beacon_counter: all beacons (both filtered and not filtered)
|
||||
* @beacon_average_energy: all beacons (both filtered and not
|
||||
* filtered)
|
||||
* @beacon_rssi_a: beacon RSSI on antenna A
|
||||
* @beacon_rssi_b: beacon RSSI on antenna B
|
||||
* @rx_bytes: per MAC RX byte count
|
||||
* @rx_time: rx time
|
||||
* @tx_time: usec the radio is transmitting.
|
||||
* @on_time_rf: The total time in usec the RF is awake.
|
||||
* @on_time_scan: usec the radio is awake due to scan.
|
||||
* @average_energy: in fact it is minus the energy..
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_statistics_operational_ntfy {
|
||||
struct iwl_statistics_ntfy_hdr hdr;
|
||||
__le32 flags;
|
||||
__le32 mac_id;
|
||||
__le32 beacon_filter_average_energy;
|
||||
__le32 beacon_filter_reason;
|
||||
__le32 radio_temperature;
|
||||
__le32 air_time[MAC_INDEX_AUX];
|
||||
__le32 beacon_counter[MAC_INDEX_AUX];
|
||||
__le32 beacon_average_energy[MAC_INDEX_AUX];
|
||||
__le32 beacon_rssi_a;
|
||||
__le32 beacon_rssi_b;
|
||||
__le32 rx_bytes[MAC_INDEX_AUX];
|
||||
__le64 rx_time;
|
||||
__le64 tx_time;
|
||||
__le64 on_time_rf;
|
||||
__le64 on_time_scan;
|
||||
__le32 average_energy[IWL_MVM_STATION_COUNT_MAX];
|
||||
__le32 reserved;
|
||||
} __packed; /* STATISTICS_OPERATIONAL_NTFY_API_S_VER_14 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_phy_ntfy
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* RX PHY related statistics
|
||||
* @energy_and_config: ???
|
||||
* @rssi_band: @31:24 rssiAllBand_B, 23:16 rssiInBand_B, 15:8
|
||||
* rssiAllBand_A, 7:0 rssiInBand_A
|
||||
* @agc_word: @31:16 agcWord_B, 15:0 agcWord_A
|
||||
* @agc_gain: @19:10 agcGain_B, 9:0 agcGain_A
|
||||
* @dfe_gain: @19:10 dfeGain_B, 9:0 dfeGain_A
|
||||
* @snr_calc_main: @18:0 snrCalcMain
|
||||
* @energy_calc_main: @18:0 energyCalcMain
|
||||
* @snr_calc_aux: @18:0 snrCalcAux
|
||||
* @dsp_dc_estim_a: @27:14 dspDcEstimQA, 13:0 dspDcEstimIA
|
||||
* @dsp_dc_estim_b: @27:14 dspDcEstimQB, 13:0 dspDcEstimIB
|
||||
* @ina_detec_type_and_ofdm_corr_comb: @31:31 inaDetectCckMrc,
|
||||
* 30:27 inaDetectType, 26:0 ofdmCorrComb
|
||||
* @cw_corr_comb: @26:0 cwCorrComb
|
||||
* @rssi_comb: @25:0 rssiComb
|
||||
* @auto_corr_cck: @23:12 autoCck, 11:00 crossCck
|
||||
* @ofdm_fine_freq_and_pina_freq_err: @18:7 ofdmFineFreq, 6:0
|
||||
* ofdmPinaFreqErr
|
||||
* @snrm_evm_main: @31:0 snrmEvmMain
|
||||
* @snrm_evm_aux: @31:0 snrmEvmAux
|
||||
* @rx_rate: @31:0 rate
|
||||
* TX PHY related statistics
|
||||
* @per_chain_enums_and_dsp_atten_a: @perChainEnumsAndDspAtten
|
||||
* (per version)
|
||||
* @target_power_and_power_meas_a: @31:16 targetPower_A, 15:0
|
||||
* powerMeasuredCalc_A
|
||||
* @tx_config_as_i_and_ac_a: @31:16 txConfigAsI_A, 15:0
|
||||
* txConfigAc_A
|
||||
* @predist_dcq_and_dci_a: @31:16 predist_dci_A, 15:0
|
||||
* predist_dcq_A
|
||||
* @per_chain_enums_and_dsp_atten_b: @perChainEnumsAndDspAtten
|
||||
* (per version)
|
||||
* @target_power_and_power_meas_b: @31:16 targetPower_B, 15:0
|
||||
* powerMeasuredCalc_B
|
||||
* @tx_config_as_i_and_ac_b: @31:16 txConfigAsI_B, 15:0
|
||||
* txConfigAc_B
|
||||
* @predist_dcq_and_dci_b: @31:16 predist_dci_B, 15:0
|
||||
* predist_dcq_B
|
||||
* @tx_rate: @31:0 rate
|
||||
* @tlc_backoff: @31:0 tlcBackoff
|
||||
* @mpapd_calib_mode_mpapd_calib_type_a: @31:16
|
||||
* mpapdCalibMode_A, 15:0 mpapdCalibType_A
|
||||
* @psat_and_phy_power_limit_a: @31:16 psat_A, 15:0
|
||||
* phyPowerLimit_A
|
||||
* @sar_and_regulatory_power_limit_a: @31:16 sarPowerLimit_A,
|
||||
* 15:0 regulatoryPowerLimit_A
|
||||
* @mpapd_calib_mode_mpapd_calib_type_b: @31:16
|
||||
* mpapdCalibMode_B, 15:0 mpapdCalibType_B
|
||||
* @psat_and_phy_power_limit_b: @31:16 psat_B, 15:0
|
||||
* phyPowerLimit_B
|
||||
* @sar_and_regulatory_power_limit_b: @31:16 sarPowerLimit_B,
|
||||
* 15:0 regulatoryPowerLimit_B
|
||||
* @srd_and_driver_power_limits: @31:16 srdPowerLimit, 15:0
|
||||
* driverPowerLimit
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_statistics_phy_ntfy {
|
||||
struct iwl_statistics_ntfy_hdr hdr;
|
||||
__le32 energy_and_config;
|
||||
__le32 rssi_band;
|
||||
__le32 agc_word;
|
||||
__le32 agc_gain;
|
||||
__le32 dfe_gain;
|
||||
__le32 snr_calc_main;
|
||||
__le32 energy_calc_main;
|
||||
__le32 snr_calc_aux;
|
||||
__le32 dsp_dc_estim_a;
|
||||
__le32 dsp_dc_estim_b;
|
||||
__le32 ina_detec_type_and_ofdm_corr_comb;
|
||||
__le32 cw_corr_comb;
|
||||
__le32 rssi_comb;
|
||||
__le32 auto_corr_cck;
|
||||
__le32 ofdm_fine_freq_and_pina_freq_err;
|
||||
__le32 snrm_evm_main;
|
||||
__le32 snrm_evm_aux;
|
||||
__le32 rx_rate;
|
||||
__le32 per_chain_enums_and_dsp_atten_a;
|
||||
__le32 target_power_and_power_meas_a;
|
||||
__le32 tx_config_as_i_and_ac_a;
|
||||
__le32 predist_dcq_and_dci_a;
|
||||
__le32 per_chain_enums_and_dsp_atten_b;
|
||||
__le32 target_power_and_power_meas_b;
|
||||
__le32 tx_config_as_i_and_ac_b;
|
||||
__le32 predist_dcq_and_dci_b;
|
||||
__le32 tx_rate;
|
||||
__le32 tlc_backoff;
|
||||
__le32 mpapd_calib_mode_mpapd_calib_type_a;
|
||||
__le32 psat_and_phy_power_limit_a;
|
||||
__le32 sar_and_regulatory_power_limit_a;
|
||||
__le32 mpapd_calib_mode_mpapd_calib_type_b;
|
||||
__le32 psat_and_phy_power_limit_b;
|
||||
__le32 sar_and_regulatory_power_limit_b;
|
||||
__le32 srd_and_driver_power_limits;
|
||||
__le32 reserved;
|
||||
} __packed; /* STATISTICS_PHY_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_mac_ntfy
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @bcast_filter_passed_per_mac: bcast filter passed per mac
|
||||
* @bcast_filter_dropped_per_mac: bcast filter dropped per mac
|
||||
* @bcast_filter_passed_per_filter: bcast filter passed per filter
|
||||
* @bcast_filter_dropped_per_filter: bcast filter dropped per filter
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_statistics_mac_ntfy {
|
||||
struct iwl_statistics_ntfy_hdr hdr;
|
||||
__le32 bcast_filter_passed_per_mac[NUM_MAC_INDEX_CDB];
|
||||
__le32 bcast_filter_dropped_per_mac[NUM_MAC_INDEX_CDB];
|
||||
__le32 bcast_filter_passed_per_filter[MAX_BCAST_FILTER_NUM];
|
||||
__le32 bcast_filter_dropped_per_filter[MAX_BCAST_FILTER_NUM];
|
||||
__le32 reserved;
|
||||
} __packed; /* STATISTICS_MAC_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_rx_ntfy
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @rx_agg_mpdu_cnt: aggregation frame count (number of
|
||||
* delimiters)
|
||||
* @rx_agg_cnt: number of RX Aggregations
|
||||
* @unsupported_mcs: number of PLCP headers that have rate which
|
||||
* is unsupported by DSP
|
||||
* @bogus_cts: CTS received when not expecting CTS
|
||||
* @bogus_ack: ACK received when not expecting ACK
|
||||
* @rx_byte_count: ???
|
||||
* @rx_packet_count: ???
|
||||
* @missed_beacons: ???
|
||||
* @unresponded_rts: un-responded RTS, due to NAV not zero
|
||||
* @rxe_frame_limit_overrun: RXE got frame limit overrun
|
||||
* @sent_ba_rsp_cnt: BA response TX count
|
||||
* @late_rx_handle: count the number of times the RX path was
|
||||
* aborted due to late entry
|
||||
* @num_bt_kills: ???
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_statistics_rx_ntfy {
|
||||
struct iwl_statistics_ntfy_hdr hdr;
|
||||
__le32 rx_agg_mpdu_cnt;
|
||||
__le32 rx_agg_cnt;
|
||||
__le32 unsupported_mcs;
|
||||
__le32 bogus_cts;
|
||||
__le32 bogus_ack;
|
||||
__le32 rx_byte_count[MAC_INDEX_AUX];
|
||||
__le32 rx_packet_count[MAC_INDEX_AUX];
|
||||
__le32 missed_beacons;
|
||||
__le32 unresponded_rts;
|
||||
__le32 rxe_frame_limit_overrun;
|
||||
__le32 sent_ba_rsp_cnt;
|
||||
__le32 late_rx_handle;
|
||||
__le32 num_bt_kills;
|
||||
__le32 reserved;
|
||||
} __packed; /* STATISTICS_RX_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_tx_ntfy
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @cts_timeout: timeout when waiting for CTS
|
||||
* @ack_timeout: timeout when waiting for ACK
|
||||
* @dump_msdu_cnt: number of MSDUs that were dumped due to any
|
||||
* reason
|
||||
* @burst_abort_missing_next_frame_cnt: number of times a burst
|
||||
* was aborted due to missing next frame bytes in txfifo
|
||||
* number of times got timeout when waiting for CTS/ACK/BA and energy was
|
||||
* detected just after sending the RTS/DATA. this statistics may help getting
|
||||
* interesting indicators, like the likelihood of collision (so the benefit of
|
||||
* protection may be estimated Vs. its cost). Or how many of the failures are
|
||||
* due to collision and how many due to SNR.
|
||||
* For Link-quality the CTS collision indication is more reliable then the ACK
|
||||
* collision indication as the RTS frame is short and has more chance that the
|
||||
* frame/s which caused the collision continue after the RTS was sent.
|
||||
* @cts_timeout_collision: ???
|
||||
* ACK/BA failed and energy as detected after DATA
|
||||
* Note: to get the collision ratio need to:
|
||||
* ackOrBaTimeoutCollision / (ack_timeout + ba_timeout)
|
||||
* @ack_or_ba_timeout_collision: ???
|
||||
* @ba_timeout: timeout when waiting for immediate BA response
|
||||
* @ba_reschedule_frames: failed to get BA response and
|
||||
* rescheduled all the non-ACKed frames
|
||||
* gives the avarage number of frames inside aggregation
|
||||
* @scd_query_agg_frame_cnt: ???
|
||||
* @scd_query_no_agg: scheduler query prevented aggregation
|
||||
* @scd_query_agg: scheduler query allowed aggregation
|
||||
* @scd_query_mismatch: scheduler query inaccurate, either too
|
||||
* short or too long
|
||||
* @agg_terminated_underrun: aggregation was terminated due to
|
||||
* underrun
|
||||
* @agg_terminated_bt_prio_kill: aggregation was terminated due
|
||||
* to BT
|
||||
* @tx_kill_on_long_retry: count the tx frames dropped due to
|
||||
* long retry limit (DATA frame failed)
|
||||
* @tx_kill_on_short_retry: count the tx frames dropped due to
|
||||
* short retry limit (RTS frame failed)
|
||||
* TX deffer on energy. This counter is reset on each successful transmit.
|
||||
* When timer exceed TX deffer limit than will be uCode assert.
|
||||
* @tx_deffer_counter: ???
|
||||
* @tx_deffer_base_time: Keep the time of the last successful
|
||||
* transmit
|
||||
* @tx_underrun: TX killed due to underrun
|
||||
* @bt_defer: TX deferred due to BT priority, so probably TX was
|
||||
* not started.
|
||||
* @tx_kill_on_dsp_timeout: TX killed on DSP problem detected
|
||||
* @tx_kill_on_immediate_quiet: TX killed due to immediate quiet
|
||||
* @kill_ba_cnt: number of times sending BA failed
|
||||
* @kill_ack_cnt: number of times sending ACK failed
|
||||
* @kill_cts_cnt: number of times sending CTS failed
|
||||
* @burst_terminated: Count burst or fragmentation termination
|
||||
* occurrence
|
||||
* @late_tx_vec_wr_cnt: ???
|
||||
* TX is not sent because ucode failed to notify the TRM in SIFS-delta from
|
||||
* ON_AIR deassertion.
|
||||
* @late_rx2_tx_cnt: ???
|
||||
* @scd_query_cnt: count the times SCD query was done to check
|
||||
* for TX AGG
|
||||
* @tx_frames_acked_in_agg: count the number of frames
|
||||
* transmitted inside AGG and were successful
|
||||
* @last_tx_ch_width_indx: ???
|
||||
* number of deferred TX per channel width, 0 - 20, 1/2/3 - 40/80/160
|
||||
* @rx_detected_per_ch_width: ???
|
||||
* @success_per_ch_width: ???
|
||||
* @fail_per_ch_width: ???
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_statistics_tx_ntfy {
|
||||
struct iwl_statistics_ntfy_hdr hdr;
|
||||
__le32 cts_timeout;
|
||||
__le32 ack_timeout;
|
||||
__le32 dump_msdu_cnt;
|
||||
__le32 burst_abort_missing_next_frame_cnt;
|
||||
__le32 cts_timeout_collision;
|
||||
__le32 ack_or_ba_timeout_collision;
|
||||
__le32 ba_timeout;
|
||||
__le32 ba_reschedule_frames;
|
||||
__le32 scd_query_agg_frame_cnt;
|
||||
__le32 scd_query_no_agg;
|
||||
__le32 scd_query_agg;
|
||||
__le32 scd_query_mismatch;
|
||||
__le32 agg_terminated_underrun;
|
||||
__le32 agg_terminated_bt_prio_kill;
|
||||
__le32 tx_kill_on_long_retry;
|
||||
__le32 tx_kill_on_short_retry;
|
||||
__le32 tx_deffer_counter;
|
||||
__le32 tx_deffer_base_time;
|
||||
__le32 tx_underrun;
|
||||
__le32 bt_defer;
|
||||
__le32 tx_kill_on_dsp_timeout;
|
||||
__le32 tx_kill_on_immediate_quiet;
|
||||
__le32 kill_ba_cnt;
|
||||
__le32 kill_ack_cnt;
|
||||
__le32 kill_cts_cnt;
|
||||
__le32 burst_terminated;
|
||||
__le32 late_tx_vec_wr_cnt;
|
||||
__le32 late_rx2_tx_cnt;
|
||||
__le32 scd_query_cnt;
|
||||
__le32 tx_frames_acked_in_agg;
|
||||
__le32 last_tx_ch_width_indx;
|
||||
__le32 rx_detected_per_ch_width[4];
|
||||
__le32 success_per_ch_width[4];
|
||||
__le32 fail_per_ch_width[4];
|
||||
__le32 reserved;
|
||||
} __packed; /* STATISTICS_TX_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_duration_ntfy
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* @cont_burst_chk_cnt: number of times continuation or
|
||||
* fragmentation or bursting was checked
|
||||
* @cont_burst_cnt: number of times continuation or fragmentation
|
||||
* or bursting was successful
|
||||
* @wait_for_silence_timeout_cnt: ???
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_statistics_duration_ntfy {
|
||||
struct iwl_statistics_ntfy_hdr hdr;
|
||||
__le32 cont_burst_chk_cnt;
|
||||
__le32 cont_burst_cnt;
|
||||
__le32 wait_for_silence_timeout_cnt;
|
||||
__le32 reserved;
|
||||
} __packed; /* STATISTICS_DURATION_NTFY_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_statistics_he_ntfy
|
||||
*
|
||||
* @hdr: general statistics header
|
||||
* received HE frames
|
||||
* @rx_siga_valid_cnt: rx HE SIG-A valid
|
||||
* @rx_siga_invalid_cnt: rx HE SIG-A invalid
|
||||
* received HE frames w/ valid Sig-A
|
||||
* @rx_trig_based_frame_cnt: rx HE-TB (trig-based)
|
||||
* @rx_su_frame_cnt: rx HE-SU
|
||||
* @rx_sigb_invalid_cnt: rx (suspected) HE-MU w/ bad SIG-B
|
||||
* @rx_our_bss_color_cnt: rx valid HE SIG-A w/ our BSS color
|
||||
* @rx_other_bss_color_cnt: rx valid HE SIG-A w/ other BSS color
|
||||
* @rx_zero_bss_color_cnt: ???
|
||||
* received HE-MU frames w/ good Sig-B
|
||||
* @rx_mu_for_us_cnt: match AID
|
||||
* @rx_mu_not_for_us_cnt: no matched AID
|
||||
* received HE-MU frames for us (w/ our AID)
|
||||
* @rx_mu_nss_ar: 0 - SISO, 1 - MIMO2
|
||||
* @rx_mu_mimo_cnt: full BW RU, compressed SIG-B
|
||||
* @rx_mu_ru_bw_ar: MU alloc, MHz: 0 - 2, 1 - 5, 2 - 10, 3 - 20,
|
||||
* 4 - 40, 5 - 80, 6 - 160
|
||||
* received trigger frames
|
||||
* @rx_trig_for_us_cnt: ???
|
||||
* @rx_trig_not_for_us_cnt: ???
|
||||
* trigger for us
|
||||
* @rx_trig_with_cs_req_cnt: ???
|
||||
* @rx_trig_type_ar: ???
|
||||
* @rx_trig_in_agg_cnt: ???
|
||||
* basic trigger for us allocations
|
||||
* @rx_basic_trig_alloc_nss_ar: ???
|
||||
* @rx_basic_trig_alloc_mu_mimo_cnt: ???
|
||||
* @rx_basic_trig_alloc_ru_bw_ar: ???
|
||||
* @rx_basic_trig_total_byte_cnt: ???
|
||||
* trig-based TX
|
||||
* @tx_trig_based_cs_req_fail_cnt: ???
|
||||
* @tx_trig_based_sifs_ok_cnt: ???
|
||||
* @tx_trig_based_sifs_fail_cnt: ???
|
||||
* @tx_trig_based_byte_cnt: ???
|
||||
* @tx_trig_based_pad_byte_cnt: ???
|
||||
* @tx_trig_based_frame_cnt: ???
|
||||
* @tx_trig_based_acked_frame_cnt: ???
|
||||
* @tx_trig_based_ack_timeout_cnt: ???
|
||||
* HE-SU TX
|
||||
* @tx_su_frame_cnt: ???
|
||||
* EDCA <--> MU-EDCA transitions
|
||||
* @tx_edca_to_mu_edca_cnt: ???
|
||||
* @tx_mu_edca_to_edca_by_timeout_cnt: ???
|
||||
* @tx_mu_edca_to_edca_by_ack_fail_cnt: ???
|
||||
* @tx_mu_edca_to_edca_by_small_alloc_cnt: ???
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_statistics_he_ntfy {
|
||||
struct iwl_statistics_ntfy_hdr hdr;
|
||||
__le32 rx_siga_valid_cnt;
|
||||
__le32 rx_siga_invalid_cnt;
|
||||
__le32 rx_trig_based_frame_cnt;
|
||||
__le32 rx_su_frame_cnt;
|
||||
__le32 rx_sigb_invalid_cnt;
|
||||
__le32 rx_our_bss_color_cnt;
|
||||
__le32 rx_other_bss_color_cnt;
|
||||
__le32 rx_zero_bss_color_cnt;
|
||||
__le32 rx_mu_for_us_cnt;
|
||||
__le32 rx_mu_not_for_us_cnt;
|
||||
__le32 rx_mu_nss_ar[2];
|
||||
__le32 rx_mu_mimo_cnt;
|
||||
__le32 rx_mu_ru_bw_ar[7];
|
||||
__le32 rx_trig_for_us_cnt;
|
||||
__le32 rx_trig_not_for_us_cnt;
|
||||
__le32 rx_trig_with_cs_req_cnt;
|
||||
__le32 rx_trig_type_ar[8 + 1];
|
||||
__le32 rx_trig_in_agg_cnt;
|
||||
__le32 rx_basic_trig_alloc_nss_ar[2];
|
||||
__le32 rx_basic_trig_alloc_mu_mimo_cnt;
|
||||
__le32 rx_basic_trig_alloc_ru_bw_ar[7];
|
||||
__le32 rx_basic_trig_total_byte_cnt;
|
||||
__le32 tx_trig_based_cs_req_fail_cnt;
|
||||
__le32 tx_trig_based_sifs_ok_cnt;
|
||||
__le32 tx_trig_based_sifs_fail_cnt;
|
||||
__le32 tx_trig_based_byte_cnt;
|
||||
__le32 tx_trig_based_pad_byte_cnt;
|
||||
__le32 tx_trig_based_frame_cnt;
|
||||
__le32 tx_trig_based_acked_frame_cnt;
|
||||
__le32 tx_trig_based_ack_timeout_cnt;
|
||||
__le32 tx_su_frame_cnt;
|
||||
__le32 tx_edca_to_mu_edca_cnt;
|
||||
__le32 tx_mu_edca_to_edca_by_timeout_cnt;
|
||||
__le32 tx_mu_edca_to_edca_by_ack_fail_cnt;
|
||||
__le32 tx_mu_edca_to_edca_by_small_alloc_cnt;
|
||||
__le32 reserved;
|
||||
} __packed; /* STATISTICS_HE_NTFY_API_S_VER_1 */
|
||||
|
||||
#endif /* __iwl_fw_api_stats_h__ */
|
||||
|
|
|
@ -90,6 +90,7 @@ struct iwl_ucode_header {
|
|||
};
|
||||
|
||||
#define IWL_UCODE_TLV_DEBUG_BASE 0x1000005
|
||||
#define IWL_UCODE_TLV_CONST_BASE 0x100
|
||||
|
||||
/*
|
||||
* new TLV uCode file layout
|
||||
|
@ -145,7 +146,13 @@ enum iwl_ucode_tlv_type {
|
|||
IWL_UCODE_TLV_UMAC_DEBUG_ADDRS = 54,
|
||||
IWL_UCODE_TLV_LMAC_DEBUG_ADDRS = 55,
|
||||
IWL_UCODE_TLV_FW_RECOVERY_INFO = 57,
|
||||
IWL_UCODE_TLV_FW_FSEQ_VERSION = 60,
|
||||
IWL_UCODE_TLV_HW_TYPE = 58,
|
||||
IWL_UCODE_TLV_FW_FSEQ_VERSION = 60,
|
||||
|
||||
IWL_UCODE_TLV_PNVM_VERSION = 62,
|
||||
IWL_UCODE_TLV_PNVM_SKU = 64,
|
||||
|
||||
IWL_UCODE_TLV_FW_NUM_STATIONS = IWL_UCODE_TLV_CONST_BASE + 0,
|
||||
|
||||
IWL_UCODE_TLV_TYPE_DEBUG_INFO = IWL_UCODE_TLV_DEBUG_BASE + 0,
|
||||
IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION = IWL_UCODE_TLV_DEBUG_BASE + 1,
|
||||
|
|
|
@ -106,6 +106,7 @@ struct iwl_ucode_capabilities {
|
|||
u32 flags;
|
||||
u32 error_log_addr;
|
||||
u32 error_log_size;
|
||||
u32 num_stations;
|
||||
unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)];
|
||||
unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)];
|
||||
|
||||
|
|
|
@ -0,0 +1,274 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2020 Intel Corporation
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "iwl-drv.h"
|
||||
#include "pnvm.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-io.h"
|
||||
#include "fw/api/commands.h"
|
||||
#include "fw/api/nvm-reg.h"
|
||||
#include "fw/api/alive.h"
|
||||
|
||||
struct iwl_pnvm_section {
|
||||
__le32 offset;
|
||||
const u8 data[];
|
||||
} __packed;
|
||||
|
||||
static bool iwl_pnvm_complete_fn(struct iwl_notif_wait_data *notif_wait,
|
||||
struct iwl_rx_packet *pkt, void *data)
|
||||
{
|
||||
struct iwl_trans *trans = (struct iwl_trans *)data;
|
||||
struct iwl_pnvm_init_complete_ntfy *pnvm_ntf = (void *)pkt->data;
|
||||
|
||||
IWL_DEBUG_FW(trans,
|
||||
"PNVM complete notification received with status %d\n",
|
||||
le32_to_cpu(pnvm_ntf->status));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data,
|
||||
size_t len)
|
||||
{
|
||||
struct iwl_ucode_tlv *tlv;
|
||||
u32 sha1 = 0;
|
||||
u16 mac_type = 0, rf_id = 0;
|
||||
u8 *pnvm_data = NULL, *tmp;
|
||||
u32 size = 0;
|
||||
int ret;
|
||||
|
||||
IWL_DEBUG_FW(trans, "Handling PNVM section\n");
|
||||
|
||||
while (len >= sizeof(*tlv)) {
|
||||
u32 tlv_len, tlv_type;
|
||||
|
||||
len -= sizeof(*tlv);
|
||||
tlv = (void *)data;
|
||||
|
||||
tlv_len = le32_to_cpu(tlv->length);
|
||||
tlv_type = le32_to_cpu(tlv->type);
|
||||
|
||||
if (len < tlv_len) {
|
||||
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
|
||||
len, tlv_len);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
data += sizeof(*tlv);
|
||||
|
||||
switch (tlv_type) {
|
||||
case IWL_UCODE_TLV_PNVM_VERSION:
|
||||
if (tlv_len < sizeof(__le32)) {
|
||||
IWL_DEBUG_FW(trans,
|
||||
"Invalid size for IWL_UCODE_TLV_PNVM_VERSION (expected %zd, got %d)\n",
|
||||
sizeof(__le32), tlv_len);
|
||||
break;
|
||||
}
|
||||
|
||||
sha1 = le32_to_cpup((__le32 *)data);
|
||||
|
||||
IWL_DEBUG_FW(trans,
|
||||
"Got IWL_UCODE_TLV_PNVM_VERSION %0x\n",
|
||||
sha1);
|
||||
break;
|
||||
case IWL_UCODE_TLV_HW_TYPE:
|
||||
if (tlv_len < 2 * sizeof(__le16)) {
|
||||
IWL_DEBUG_FW(trans,
|
||||
"Invalid size for IWL_UCODE_TLV_HW_TYPE (expected %zd, got %d)\n",
|
||||
2 * sizeof(__le16), tlv_len);
|
||||
break;
|
||||
}
|
||||
|
||||
mac_type = le16_to_cpup((__le16 *)data);
|
||||
rf_id = le16_to_cpup((__le16 *)(data + sizeof(__le16)));
|
||||
|
||||
IWL_DEBUG_FW(trans,
|
||||
"Got IWL_UCODE_TLV_HW_TYPE mac_type 0x%0x rf_id 0x%0x\n",
|
||||
mac_type, rf_id);
|
||||
|
||||
if (mac_type != CSR_HW_REV_TYPE(trans->hw_rev) ||
|
||||
rf_id != CSR_HW_RFID_TYPE(trans->hw_rf_id)) {
|
||||
IWL_DEBUG_FW(trans,
|
||||
"HW mismatch, skipping PNVM section, mac_type 0x%0x, rf_id 0x%0x.\n",
|
||||
CSR_HW_REV_TYPE(trans->hw_rev), trans->hw_rf_id);
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
break;
|
||||
case IWL_UCODE_TLV_SEC_RT: {
|
||||
struct iwl_pnvm_section *section = (void *)data;
|
||||
u32 data_len = tlv_len - sizeof(*section);
|
||||
|
||||
IWL_DEBUG_FW(trans,
|
||||
"Got IWL_UCODE_TLV_SEC_RT len %d\n",
|
||||
tlv_len);
|
||||
|
||||
/* TODO: remove, this is a deprecated separator */
|
||||
if (le32_to_cpup((__le32 *)data) == 0xddddeeee) {
|
||||
IWL_DEBUG_FW(trans, "Ignoring separator.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
IWL_DEBUG_FW(trans, "Adding data (size %d)\n",
|
||||
data_len);
|
||||
|
||||
tmp = krealloc(pnvm_data, size + data_len, GFP_KERNEL);
|
||||
if (!tmp) {
|
||||
IWL_DEBUG_FW(trans,
|
||||
"Couldn't allocate (more) pnvm_data\n");
|
||||
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pnvm_data = tmp;
|
||||
|
||||
memcpy(pnvm_data + size, section->data, data_len);
|
||||
|
||||
size += data_len;
|
||||
|
||||
break;
|
||||
}
|
||||
case IWL_UCODE_TLV_PNVM_SKU:
|
||||
IWL_DEBUG_FW(trans,
|
||||
"New PNVM section started, stop parsing.\n");
|
||||
goto done;
|
||||
default:
|
||||
IWL_DEBUG_FW(trans, "Found TLV 0x%0x, len %d\n",
|
||||
tlv_type, tlv_len);
|
||||
break;
|
||||
}
|
||||
|
||||
len -= ALIGN(tlv_len, 4);
|
||||
data += ALIGN(tlv_len, 4);
|
||||
}
|
||||
|
||||
done:
|
||||
if (!size) {
|
||||
IWL_DEBUG_FW(trans, "Empty PNVM, skipping.\n");
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
IWL_INFO(trans, "loaded PNVM version 0x%0x\n", sha1);
|
||||
|
||||
ret = iwl_trans_set_pnvm(trans, pnvm_data, size);
|
||||
out:
|
||||
kfree(pnvm_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_pnvm_parse(struct iwl_trans *trans, const u8 *data,
|
||||
size_t len)
|
||||
{
|
||||
struct iwl_ucode_tlv *tlv;
|
||||
|
||||
IWL_DEBUG_FW(trans, "Parsing PNVM file\n");
|
||||
|
||||
while (len >= sizeof(*tlv)) {
|
||||
u32 tlv_len, tlv_type;
|
||||
|
||||
len -= sizeof(*tlv);
|
||||
tlv = (void *)data;
|
||||
|
||||
tlv_len = le32_to_cpu(tlv->length);
|
||||
tlv_type = le32_to_cpu(tlv->type);
|
||||
|
||||
if (len < tlv_len) {
|
||||
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
|
||||
len, tlv_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tlv_type == IWL_UCODE_TLV_PNVM_SKU) {
|
||||
struct iwl_sku_id *sku_id =
|
||||
(void *)(data + sizeof(*tlv));
|
||||
|
||||
IWL_DEBUG_FW(trans,
|
||||
"Got IWL_UCODE_TLV_PNVM_SKU len %d\n",
|
||||
tlv_len);
|
||||
IWL_DEBUG_FW(trans, "sku_id 0x%0x 0x%0x 0x%0x\n",
|
||||
le32_to_cpu(sku_id->data[0]),
|
||||
le32_to_cpu(sku_id->data[1]),
|
||||
le32_to_cpu(sku_id->data[2]));
|
||||
|
||||
if (trans->sku_id[0] == le32_to_cpu(sku_id->data[0]) &&
|
||||
trans->sku_id[1] == le32_to_cpu(sku_id->data[1]) &&
|
||||
trans->sku_id[2] == le32_to_cpu(sku_id->data[2])) {
|
||||
int ret;
|
||||
|
||||
data += sizeof(*tlv) + ALIGN(tlv_len, 4);
|
||||
len -= ALIGN(tlv_len, 4);
|
||||
|
||||
ret = iwl_pnvm_handle_section(trans, data, len);
|
||||
if (!ret)
|
||||
return 0;
|
||||
} else {
|
||||
IWL_DEBUG_FW(trans, "SKU ID didn't match!\n");
|
||||
}
|
||||
} else {
|
||||
data += sizeof(*tlv) + ALIGN(tlv_len, 4);
|
||||
len -= ALIGN(tlv_len, 4);
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int iwl_pnvm_load(struct iwl_trans *trans,
|
||||
struct iwl_notif_wait_data *notif_wait)
|
||||
{
|
||||
const struct firmware *pnvm;
|
||||
struct iwl_notification_wait pnvm_wait;
|
||||
static const u16 ntf_cmds[] = { WIDE_ID(REGULATORY_AND_NVM_GROUP,
|
||||
PNVM_INIT_COMPLETE_NTFY) };
|
||||
char pnvm_name[64];
|
||||
int ret;
|
||||
|
||||
/* if the SKU_ID is empty, there's nothing to do */
|
||||
if (!trans->sku_id[0] && !trans->sku_id[1] && !trans->sku_id[2])
|
||||
return 0;
|
||||
|
||||
/* if we already have it, nothing to do either */
|
||||
if (trans->pnvm_loaded)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The prefix unfortunately includes a hyphen at the end, so
|
||||
* don't add the dot here...
|
||||
*/
|
||||
snprintf(pnvm_name, sizeof(pnvm_name), "%spnvm",
|
||||
trans->cfg->fw_name_pre);
|
||||
|
||||
/* ...but replace the hyphen with the dot here. */
|
||||
if (strlen(trans->cfg->fw_name_pre) < sizeof(pnvm_name))
|
||||
pnvm_name[strlen(trans->cfg->fw_name_pre) - 1] = '.';
|
||||
|
||||
ret = firmware_request_nowarn(&pnvm, pnvm_name, trans->dev);
|
||||
if (ret) {
|
||||
IWL_DEBUG_FW(trans, "PNVM file %s not found %d\n",
|
||||
pnvm_name, ret);
|
||||
} else {
|
||||
iwl_pnvm_parse(trans, pnvm->data, pnvm->size);
|
||||
|
||||
release_firmware(pnvm);
|
||||
}
|
||||
|
||||
iwl_init_notification_wait(notif_wait, &pnvm_wait,
|
||||
ntf_cmds, ARRAY_SIZE(ntf_cmds),
|
||||
iwl_pnvm_complete_fn, trans);
|
||||
|
||||
/* kick the doorbell */
|
||||
iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
|
||||
UREG_DOORBELL_TO_ISR6_PNVM);
|
||||
|
||||
return iwl_wait_notification(notif_wait, &pnvm_wait,
|
||||
MVM_UCODE_PNVM_TIMEOUT);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_pnvm_load);
|
|
@ -0,0 +1,18 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2020 Intel Corporation
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __IWL_PNVM_H__
|
||||
#define __IWL_PNVM_H__
|
||||
|
||||
#include "fw/notif-wait.h"
|
||||
|
||||
#define MVM_UCODE_PNVM_TIMEOUT (HZ / 10)
|
||||
|
||||
int iwl_pnvm_load(struct iwl_trans *trans,
|
||||
struct iwl_notif_wait_data *notif_wait);
|
||||
|
||||
#endif /* __IWL_PNVM_H__ */
|
|
@ -519,6 +519,7 @@ struct iwl_dev_info {
|
|||
*/
|
||||
extern const struct iwl_cfg_trans_params iwl9000_trans_cfg;
|
||||
extern const struct iwl_cfg_trans_params iwl9560_trans_cfg;
|
||||
extern const struct iwl_cfg_trans_params iwl9560_long_latency_trans_cfg;
|
||||
extern const struct iwl_cfg_trans_params iwl9560_shared_clk_trans_cfg;
|
||||
extern const struct iwl_cfg_trans_params iwl_qnj_trans_cfg;
|
||||
extern const struct iwl_cfg_trans_params iwl_qu_trans_cfg;
|
||||
|
|
|
@ -138,16 +138,16 @@ struct iwl_prph_scratch_control {
|
|||
} __packed; /* PERIPH_SCRATCH_CONTROL_S */
|
||||
|
||||
/*
|
||||
* struct iwl_prph_scratch_ror_cfg - ror config
|
||||
* @ror_base_addr: ror start address
|
||||
* @ror_size: ror size in DWs
|
||||
* struct iwl_prph_scratch_pnvm_cfg - ror config
|
||||
* @pnvm_base_addr: PNVM start address
|
||||
* @pnvm_size: PNVM size in DWs
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_prph_scratch_ror_cfg {
|
||||
__le64 ror_base_addr;
|
||||
__le32 ror_size;
|
||||
struct iwl_prph_scratch_pnvm_cfg {
|
||||
__le64 pnvm_base_addr;
|
||||
__le32 pnvm_size;
|
||||
__le32 reserved;
|
||||
} __packed; /* PERIPH_SCRATCH_ROR_CFG_S */
|
||||
} __packed; /* PERIPH_SCRATCH_PNVM_CFG_S */
|
||||
|
||||
/*
|
||||
* struct iwl_prph_scratch_hwm_cfg - hwm config
|
||||
|
@ -175,14 +175,14 @@ struct iwl_prph_scratch_rbd_cfg {
|
|||
* struct iwl_prph_scratch_ctrl_cfg - prph scratch ctrl and config
|
||||
* @version: version information of context info and HW
|
||||
* @control: control flags of FH configurations
|
||||
* @ror_cfg: ror configuration
|
||||
* @pnvm_cfg: ror configuration
|
||||
* @hwm_cfg: hwm configuration
|
||||
* @rbd_cfg: default RX queue configuration
|
||||
*/
|
||||
struct iwl_prph_scratch_ctrl_cfg {
|
||||
struct iwl_prph_scratch_version version;
|
||||
struct iwl_prph_scratch_control control;
|
||||
struct iwl_prph_scratch_ror_cfg ror_cfg;
|
||||
struct iwl_prph_scratch_pnvm_cfg pnvm_cfg;
|
||||
struct iwl_prph_scratch_hwm_cfg hwm_cfg;
|
||||
struct iwl_prph_scratch_rbd_cfg rbd_cfg;
|
||||
} __packed; /* PERIPH_SCRATCH_CTRL_CFG_S */
|
||||
|
@ -291,4 +291,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
|
|||
const struct fw_img *fw);
|
||||
void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans);
|
||||
|
||||
int iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans,
|
||||
const void *data, u32 len);
|
||||
|
||||
#endif /* __iwl_context_info_file_gen3_h__ */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* Copyright(c) 2018 - 2020 Intel Corporation
|
||||
*
|
||||
* 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
|
||||
|
@ -20,7 +20,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* Copyright(c) 2018 - 2020 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -225,5 +225,8 @@ void iwl_pcie_ctxt_info_free_paging(struct iwl_trans *trans);
|
|||
int iwl_pcie_init_fw_sec(struct iwl_trans *trans,
|
||||
const struct fw_img *fw,
|
||||
struct iwl_context_info_dram *ctxt_dram);
|
||||
int iwl_pcie_ctxt_info_alloc_dma(struct iwl_trans *trans,
|
||||
const void *data, u32 len,
|
||||
struct iwl_dram_data *dram);
|
||||
|
||||
#endif /* __iwl_context_info_file_h__ */
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
#include "iwl-config.h"
|
||||
#include "iwl-modparams.h"
|
||||
#include "fw/api/alive.h"
|
||||
#include "fw/api/mac.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
|
@ -102,6 +103,9 @@ static struct dentry *iwl_dbgfs_root;
|
|||
* @fw_index: firmware revision to try loading
|
||||
* @firmware_name: composite filename of ucode file to load
|
||||
* @request_firmware_complete: the firmware has been obtained from user space
|
||||
* @dbgfs_drv: debugfs root directory entry
|
||||
* @dbgfs_trans: debugfs transport directory entry
|
||||
* @dbgfs_op_mode: debugfs op_mode directory entry
|
||||
*/
|
||||
struct iwl_drv {
|
||||
struct list_head list;
|
||||
|
@ -1124,6 +1128,19 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
fseq_ver->version);
|
||||
}
|
||||
break;
|
||||
case IWL_UCODE_TLV_FW_NUM_STATIONS:
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
if (le32_to_cpup((__le32 *)tlv_data) >
|
||||
IWL_MVM_STATION_COUNT_MAX) {
|
||||
IWL_ERR(drv,
|
||||
"%d is an invalid number of station\n",
|
||||
le32_to_cpup((__le32 *)tlv_data));
|
||||
goto tlv_error;
|
||||
}
|
||||
capa->num_stations =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_UMAC_DEBUG_ADDRS: {
|
||||
struct iwl_umac_debug_addrs *dbg_ptrs =
|
||||
(void *)tlv_data;
|
||||
|
@ -1319,7 +1336,7 @@ static void _iwl_op_mode_stop(struct iwl_drv *drv)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_req_fw_callback - callback when firmware was loaded
|
||||
*
|
||||
* If loaded successfully, copies the firmware into buffers
|
||||
|
@ -1345,6 +1362,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
|||
fw->ucode_capa.standard_phy_calibration_size =
|
||||
IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
|
||||
fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS;
|
||||
fw->ucode_capa.num_stations = IWL_MVM_STATION_COUNT_MAX;
|
||||
/* dump all fw memory areas by default */
|
||||
fw->dbg.dump_mask = 0xffffffff;
|
||||
|
||||
|
|
|
@ -460,6 +460,7 @@ enum {
|
|||
#define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0)
|
||||
#define UREG_DOORBELL_TO_ISR6_SUSPEND BIT(18)
|
||||
#define UREG_DOORBELL_TO_ISR6_RESUME BIT(19)
|
||||
#define UREG_DOORBELL_TO_ISR6_PNVM BIT(20)
|
||||
|
||||
#define FSEQ_ERROR_CODE 0xA340C8
|
||||
#define FSEQ_TOP_INIT_VERSION 0xA34038
|
||||
|
|
|
@ -200,7 +200,7 @@ int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
|||
if (!(cmd->flags & CMD_ASYNC))
|
||||
lock_map_acquire_read(&trans->sync_cmd_lockdep_map);
|
||||
|
||||
if (!iwl_cmd_groupid(cmd->id))
|
||||
if (trans->wide_cmd_header && !iwl_cmd_groupid(cmd->id))
|
||||
cmd->id = DEF_ID(cmd->id);
|
||||
|
||||
ret = trans->ops->send_cmd(trans, cmd);
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
#include "iwl-config.h"
|
||||
#include "fw/img.h"
|
||||
#include "iwl-op-mode.h"
|
||||
#include <linux/firmware.h>
|
||||
#include "fw/api/cmdhdr.h"
|
||||
#include "fw/api/txq.h"
|
||||
#include "fw/api/dbg-tlv.h"
|
||||
|
@ -568,6 +569,8 @@ struct iwl_trans_rxq_dma_data {
|
|||
* Note that the transport must fill in the proper file headers.
|
||||
* @debugfs_cleanup: used in the driver unload flow to make a proper cleanup
|
||||
* of the trans debugfs
|
||||
* @set_pnvm: set the pnvm data in the prph scratch buffer, inside the
|
||||
* context info.
|
||||
*/
|
||||
struct iwl_trans_ops {
|
||||
|
||||
|
@ -640,6 +643,7 @@ struct iwl_trans_ops {
|
|||
u32 dump_mask);
|
||||
void (*debugfs_cleanup)(struct iwl_trans *trans);
|
||||
void (*sync_nmi)(struct iwl_trans *trans);
|
||||
int (*set_pnvm)(struct iwl_trans *trans, const void *data, u32 len);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -964,6 +968,7 @@ struct iwl_trans_txqs {
|
|||
* @hw_id_str: a string with info about HW ID. Set during transport allocation.
|
||||
* @pm_support: set to true in start_hw if link pm is supported
|
||||
* @ltr_enabled: set to true if the LTR is enabled
|
||||
* @wide_cmd_header: true when ucode supports wide command header format
|
||||
* @num_rx_queues: number of RX queues allocated by the transport;
|
||||
* the transport must set this before calling iwl_drv_start()
|
||||
* @iml_len: the length of the image loader
|
||||
|
@ -995,14 +1000,17 @@ struct iwl_trans {
|
|||
u32 hw_rf_id;
|
||||
u32 hw_id;
|
||||
char hw_id_str[52];
|
||||
u32 sku_id[3];
|
||||
|
||||
u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size;
|
||||
|
||||
bool pm_support;
|
||||
bool ltr_enabled;
|
||||
u8 pnvm_loaded:1;
|
||||
|
||||
const struct iwl_hcmd_arr *command_groups;
|
||||
int command_groups_size;
|
||||
bool wide_cmd_header;
|
||||
|
||||
u8 num_rx_queues;
|
||||
|
||||
|
@ -1448,6 +1456,21 @@ static inline void iwl_trans_sync_nmi(struct iwl_trans *trans)
|
|||
trans->ops->sync_nmi(trans);
|
||||
}
|
||||
|
||||
static inline int iwl_trans_set_pnvm(struct iwl_trans *trans,
|
||||
const void *data, u32 len)
|
||||
{
|
||||
if (trans->ops->set_pnvm) {
|
||||
int ret = trans->ops->set_pnvm(trans, data, len);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
trans->pnvm_loaded = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans)
|
||||
{
|
||||
return trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED ||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2012 - 2014, 2020 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -26,7 +26,7 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2012 - 2014, 2020 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -86,11 +86,8 @@ static int iwl_mvm_binding_cmd(struct iwl_mvm *mvm, u32 action,
|
|||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT)) {
|
||||
size = sizeof(cmd);
|
||||
if (phyctxt->channel->band == NL80211_BAND_2GHZ ||
|
||||
!iwl_mvm_is_cdb_supported(mvm))
|
||||
cmd.lmac_id = cpu_to_le32(IWL_LMAC_24G_INDEX);
|
||||
else
|
||||
cmd.lmac_id = cpu_to_le32(IWL_LMAC_5G_INDEX);
|
||||
cmd.lmac_id = cpu_to_le32(iwl_mvm_get_lmac_id(mvm->fw,
|
||||
phyctxt->channel->band));
|
||||
} else {
|
||||
size = IWL_BINDING_CMD_SIZE_V1;
|
||||
}
|
||||
|
|
|
@ -344,11 +344,12 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
|
|||
const u8 *pn;
|
||||
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
ptk_pn = rcu_dereference_protected(
|
||||
mvmsta->ptk_pn[key->keyidx],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
if (WARN_ON(!ptk_pn))
|
||||
rcu_read_lock();
|
||||
ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
|
||||
if (WARN_ON(!ptk_pn)) {
|
||||
rcu_read_unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
|
||||
pn = iwl_mvm_find_max_pn(key, ptk_pn, &seq, i,
|
||||
|
@ -360,6 +361,8 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw,
|
|||
((u64)pn[1] << 32) |
|
||||
((u64)pn[0] << 40));
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
} else {
|
||||
for (i = 0; i < IWL_NUM_RSC; i++) {
|
||||
u8 *pn = seq.ccmp.pn;
|
||||
|
@ -870,7 +873,6 @@ static int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
|||
else
|
||||
cmd_size = sizeof(struct iwl_wowlan_kek_kck_material_cmd_v2);
|
||||
|
||||
memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd));
|
||||
memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck,
|
||||
mvmvif->rekey_data.kck_len);
|
||||
kek_kck_cmd.kck_len = cpu_to_le16(mvmvif->rekey_data.kck_len);
|
||||
|
@ -1364,10 +1366,12 @@ static void iwl_mvm_set_aes_rx_seq(struct iwl_mvm *mvm, struct aes_sc *scs,
|
|||
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
ptk_pn = rcu_dereference_protected(mvmsta->ptk_pn[key->keyidx],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
if (WARN_ON(!ptk_pn))
|
||||
rcu_read_lock();
|
||||
ptk_pn = rcu_dereference(mvmsta->ptk_pn[key->keyidx]);
|
||||
if (WARN_ON(!ptk_pn)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
|
||||
struct ieee80211_key_seq seq = {};
|
||||
|
@ -1379,6 +1383,7 @@ static void iwl_mvm_set_aes_rx_seq(struct iwl_mvm *mvm, struct aes_sc *scs,
|
|||
memcpy(ptk_pn->q[i].pn[tid],
|
||||
seq.ccmp.pn, IEEE80211_CCMP_PN_LEN);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
} else {
|
||||
for (tid = 0; tid < IWL_NUM_RSC; tid++) {
|
||||
struct ieee80211_key_seq seq = {};
|
||||
|
|
|
@ -174,7 +174,7 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
|
|||
|
||||
if (sscanf(buf, "%d %d", &sta_id, &drain) != 2)
|
||||
return -EINVAL;
|
||||
if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT)
|
||||
if (sta_id < 0 || sta_id >= mvm->fw->ucode_capa.num_stations)
|
||||
return -EINVAL;
|
||||
if (drain < 0 || drain > 1)
|
||||
return -EINVAL;
|
||||
|
@ -403,7 +403,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
|
|||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%.2d: ", i);
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
|
|
|
@ -354,18 +354,16 @@ int iwl_mvm_ftm_respoder_add_pasn_sta(struct iwl_mvm *mvm,
|
|||
kfree(sta);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(sta->addr, addr, ETH_ALEN);
|
||||
list_add_tail(&sta->list, &mvm->resp_pasn_list);
|
||||
}
|
||||
|
||||
ret = iwl_mvm_ftm_responder_dyn_cfg_v3(mvm, vif, NULL, &hltk_data);
|
||||
if (ret) {
|
||||
if (sta)
|
||||
iwl_mvm_resp_del_pasn_sta(mvm, vif, sta);
|
||||
return ret;
|
||||
}
|
||||
if (ret && sta)
|
||||
iwl_mvm_resp_del_pasn_sta(mvm, vif, sta);
|
||||
|
||||
memcpy(sta->addr, addr, ETH_ALEN);
|
||||
list_add_tail(&sta->list, &mvm->resp_pasn_list);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_ftm_resp_remove_pasn_sta(struct iwl_mvm *mvm,
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "iwl-io.h" /* for iwl_mvm_rx_card_state_notif */
|
||||
#include "iwl-prph.h"
|
||||
#include "fw/acpi.h"
|
||||
#include "fw/pnvm.h"
|
||||
|
||||
#include "mvm.h"
|
||||
#include "fw/dbg.h"
|
||||
|
@ -77,8 +78,8 @@
|
|||
#include "iwl-modparams.h"
|
||||
#include "iwl-nvm-parse.h"
|
||||
|
||||
#define MVM_UCODE_ALIVE_TIMEOUT HZ
|
||||
#define MVM_UCODE_CALIB_TIMEOUT (2*HZ)
|
||||
#define MVM_UCODE_ALIVE_TIMEOUT (HZ)
|
||||
#define MVM_UCODE_CALIB_TIMEOUT (2 * HZ)
|
||||
|
||||
#define UCODE_VALID_OK cpu_to_le32(0x1)
|
||||
|
||||
|
@ -132,7 +133,14 @@ static int iwl_configure_rxq(struct iwl_mvm *mvm)
|
|||
.dataflags[0] = IWL_HCMD_DFL_NOCOPY,
|
||||
};
|
||||
|
||||
/* Do not configure default queue, it is configured via context info */
|
||||
/*
|
||||
* The default queue is configured via context info, so if we
|
||||
* have a single queue, there's nothing to do here.
|
||||
*/
|
||||
if (mvm->trans->num_rx_queues == 1)
|
||||
return 0;
|
||||
|
||||
/* skip the default queue */
|
||||
num_queues = mvm->trans->num_rx_queues - 1;
|
||||
|
||||
size = struct_size(cmd, data, num_queues);
|
||||
|
@ -216,10 +224,29 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
|
|||
u16 status;
|
||||
u32 lmac_error_event_table, umac_error_table;
|
||||
|
||||
/* we don't use the SKU ID from v5 yet, so handle it as v4 */
|
||||
/*
|
||||
* For v5 and above, we can check the version, for older
|
||||
* versions we need to check the size.
|
||||
*/
|
||||
if (iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
|
||||
UCODE_ALIVE_NTFY, 0) == 5 ||
|
||||
iwl_rx_packet_payload_len(pkt) == sizeof(struct iwl_alive_ntf_v4)) {
|
||||
UCODE_ALIVE_NTFY, 0) == 5) {
|
||||
struct iwl_alive_ntf_v5 *palive;
|
||||
|
||||
palive = (void *)pkt->data;
|
||||
umac = &palive->umac_data;
|
||||
lmac1 = &palive->lmac_data[0];
|
||||
lmac2 = &palive->lmac_data[1];
|
||||
status = le16_to_cpu(palive->status);
|
||||
|
||||
mvm->trans->sku_id[0] = le32_to_cpu(palive->sku_id.data[0]);
|
||||
mvm->trans->sku_id[1] = le32_to_cpu(palive->sku_id.data[1]);
|
||||
mvm->trans->sku_id[2] = le32_to_cpu(palive->sku_id.data[2]);
|
||||
|
||||
IWL_DEBUG_FW(mvm, "Got sku_id: 0x0%x 0x0%x 0x0%x\n",
|
||||
mvm->trans->sku_id[0],
|
||||
mvm->trans->sku_id[1],
|
||||
mvm->trans->sku_id[2]);
|
||||
} else if (iwl_rx_packet_payload_len(pkt) == sizeof(struct iwl_alive_ntf_v4)) {
|
||||
struct iwl_alive_ntf_v4 *palive;
|
||||
|
||||
palive = (void *)pkt->data;
|
||||
|
@ -397,6 +424,13 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
|
|||
return -EIO;
|
||||
}
|
||||
|
||||
ret = iwl_pnvm_load(mvm->trans, &mvm->notif_wait);
|
||||
if (ret) {
|
||||
IWL_ERR(mvm, "Timeout waiting for PNVM load!\n");
|
||||
iwl_fw_set_current_image(&mvm->fwrt, old_type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
iwl_trans_fw_alive(mvm->trans, alive_data.scd_base_addr);
|
||||
|
||||
/*
|
||||
|
@ -846,14 +880,39 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
|
|||
{
|
||||
union iwl_geo_tx_power_profiles_cmd cmd;
|
||||
u16 len;
|
||||
u32 n_bands;
|
||||
int ret;
|
||||
u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_OPS_GROUP,
|
||||
GEO_TX_POWER_LIMIT,
|
||||
IWL_FW_CMD_VER_UNKNOWN);
|
||||
|
||||
/* the table is also at the same position both in v1 and v2 */
|
||||
ret = iwl_sar_geo_init(&mvm->fwrt, &cmd.v1.table[0][0],
|
||||
ACPI_WGDS_NUM_BANDS);
|
||||
BUILD_BUG_ON(offsetof(struct iwl_geo_tx_power_profiles_cmd_v1, ops) !=
|
||||
offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, ops) ||
|
||||
offsetof(struct iwl_geo_tx_power_profiles_cmd_v2, ops) !=
|
||||
offsetof(struct iwl_geo_tx_power_profiles_cmd_v3, ops));
|
||||
/* the ops field is at the same spot for all versions, so set in v1 */
|
||||
cmd.v1.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES);
|
||||
|
||||
if (cmd_ver == 3) {
|
||||
len = sizeof(cmd.v3);
|
||||
n_bands = ARRAY_SIZE(cmd.v3.table[0]);
|
||||
cmd.v3.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
|
||||
} else if (fw_has_api(&mvm->fwrt.fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_SAR_TABLE_VER)) {
|
||||
len = sizeof(cmd.v2);
|
||||
n_bands = ARRAY_SIZE(cmd.v2.table[0]);
|
||||
cmd.v2.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
|
||||
} else {
|
||||
len = sizeof(cmd.v1);
|
||||
n_bands = ARRAY_SIZE(cmd.v1.table[0]);
|
||||
}
|
||||
|
||||
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));
|
||||
/* the table is at the same position for all versions, so set use v1 */
|
||||
ret = iwl_sar_geo_init(&mvm->fwrt, &cmd.v1.table[0][0], n_bands);
|
||||
|
||||
/*
|
||||
* It is a valid scenario to not support SAR, or miss wgds table,
|
||||
|
@ -862,20 +921,6 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
|
|||
if (ret)
|
||||
return 0;
|
||||
|
||||
/* the ops field is at the same spot for all versions, so set in v1 */
|
||||
cmd.v1.ops = cpu_to_le32(IWL_PER_CHAIN_OFFSET_SET_TABLES);
|
||||
|
||||
if (cmd_ver == 3) {
|
||||
len = sizeof(cmd.v3);
|
||||
cmd.v3.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
|
||||
} else if (fw_has_api(&mvm->fwrt.fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_SAR_TABLE_VER)) {
|
||||
len = sizeof(cmd.v2);
|
||||
cmd.v2.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
|
||||
} else {
|
||||
len = sizeof(cmd.v1);
|
||||
}
|
||||
|
||||
return iwl_mvm_send_cmd_pdu(mvm,
|
||||
WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT),
|
||||
0, len, &cmd);
|
||||
|
@ -1400,7 +1445,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
|||
}
|
||||
|
||||
/* init the fw <-> mac80211 STA mapping */
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++)
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++)
|
||||
RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
|
||||
|
||||
mvm->tdls_cs.peer.sta_id = IWL_MVM_INVALID_STA;
|
||||
|
@ -1414,10 +1459,23 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
|||
goto error;
|
||||
}
|
||||
|
||||
/* Add auxiliary station for scanning */
|
||||
ret = iwl_mvm_add_aux_sta(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_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
|
||||
ADD_STA,
|
||||
0) < 12) {
|
||||
/*
|
||||
* 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;
|
||||
|
@ -1563,13 +1621,24 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
|
|||
goto error;
|
||||
|
||||
/* init the fw <-> mac80211 STA mapping */
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++)
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++)
|
||||
RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
|
||||
|
||||
/* Add auxiliary station for scanning */
|
||||
ret = iwl_mvm_add_aux_sta(mvm);
|
||||
if (ret)
|
||||
goto error;
|
||||
if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
|
||||
ADD_STA,
|
||||
0) < 12) {
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
|
|
|
@ -663,7 +663,7 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
|
|||
* allow multicast data frames only as long as the station is
|
||||
* authorized, i.e., GTK keys are already installed (if needed)
|
||||
*/
|
||||
if (ap_sta_id < IWL_MVM_STATION_COUNT) {
|
||||
if (ap_sta_id < mvm->fw->ucode_capa.num_stations) {
|
||||
struct ieee80211_sta *sta;
|
||||
|
||||
rcu_read_lock();
|
||||
|
@ -1597,9 +1597,7 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
|
|||
RCU_INIT_POINTER(mvm->csa_vif, NULL);
|
||||
return;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
|
||||
iwl_mvm_csa_client_absent(mvm, vif);
|
||||
iwl_mvm_csa_client_absent(mvm, vif);
|
||||
cancel_delayed_work(&mvmvif->csa_work);
|
||||
ieee80211_chswitch_done(vif, true);
|
||||
break;
|
||||
|
|
|
@ -677,8 +677,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||
NL80211_EXT_FEATURE_SCAN_START_TIME);
|
||||
wiphy_ext_feature_set(hw->wiphy,
|
||||
NL80211_EXT_FEATURE_BSS_PARENT_TSF);
|
||||
wiphy_ext_feature_set(hw->wiphy,
|
||||
NL80211_EXT_FEATURE_SET_SCAN_DWELL);
|
||||
}
|
||||
|
||||
if (iwl_mvm_is_oce_supported(mvm)) {
|
||||
|
@ -826,7 +824,7 @@ static void iwl_mvm_mac_tx(struct ieee80211_hw *hw,
|
|||
iwl_mvm_vif_from_mac80211(info->control.vif);
|
||||
u8 ap_sta_id = READ_ONCE(mvmvif->ap_sta_id);
|
||||
|
||||
if (ap_sta_id < IWL_MVM_STATION_COUNT) {
|
||||
if (ap_sta_id < mvm->fw->ucode_capa.num_stations) {
|
||||
/* mac80211 holds rcu read lock */
|
||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[ap_sta_id]);
|
||||
if (IS_ERR_OR_NULL(sta))
|
||||
|
@ -1225,13 +1223,8 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
|
|||
|
||||
/* async_handlers_wk is now blocked */
|
||||
|
||||
/*
|
||||
* The work item could be running or queued if the
|
||||
* ROC time event stops just as we get here.
|
||||
*/
|
||||
flush_work(&mvm->roc_done_wk);
|
||||
|
||||
iwl_mvm_rm_aux_sta(mvm);
|
||||
if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP, ADD_STA, 0) < 12)
|
||||
iwl_mvm_rm_aux_sta(mvm);
|
||||
|
||||
iwl_mvm_stop_device(mvm);
|
||||
|
||||
|
@ -1286,6 +1279,12 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
|
|||
cancel_delayed_work_sync(&mvm->cs_tx_unblock_dwork);
|
||||
cancel_delayed_work_sync(&mvm->scan_timeout_dwork);
|
||||
|
||||
/*
|
||||
* The work item could be running or queued if the
|
||||
* ROC time event stops just as we get here.
|
||||
*/
|
||||
flush_work(&mvm->roc_done_wk);
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
__iwl_mvm_mac_stop(mvm);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
@ -1372,9 +1371,7 @@ static int iwl_mvm_post_channel_switch(struct ieee80211_hw *hw,
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
|
||||
iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
|
||||
iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
|
||||
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
|
||||
|
@ -1412,10 +1409,14 @@ static void iwl_mvm_abort_channel_switch(struct ieee80211_hw *hw,
|
|||
IWL_DEBUG_MAC80211(mvm, "Abort CSA on mac %d\n", mvmvif->id);
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
WARN_ON(iwl_mvm_send_cmd_pdu(mvm,
|
||||
WIDE_ID(MAC_CONF_GROUP,
|
||||
CHANNEL_SWITCH_TIME_EVENT_CMD),
|
||||
0, sizeof(cmd), &cmd));
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
|
||||
iwl_mvm_remove_csa_period(mvm, vif);
|
||||
else
|
||||
WARN_ON(iwl_mvm_send_cmd_pdu(mvm,
|
||||
WIDE_ID(MAC_CONF_GROUP,
|
||||
CHANNEL_SWITCH_TIME_EVENT_CMD),
|
||||
0, sizeof(cmd), &cmd));
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
WARN_ON(iwl_mvm_post_channel_switch(hw, vif));
|
||||
|
@ -2886,7 +2887,7 @@ void iwl_mvm_sta_pm_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
|
|||
struct iwl_mvm_sta *mvmsta;
|
||||
bool sleeping = (notif->type != IWL_MVM_PM_EVENT_AWAKE);
|
||||
|
||||
if (WARN_ON(notif->sta_id >= ARRAY_SIZE(mvm->fw_id_to_mac_id)))
|
||||
if (WARN_ON(notif->sta_id >= mvm->fw->ucode_capa.num_stations))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
|
@ -3808,6 +3809,17 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
|
|||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT)) {
|
||||
/* Use aux roc framework (HS20) */
|
||||
if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
|
||||
ADD_STA, 0) >= 12) {
|
||||
u32 lmac_id;
|
||||
|
||||
lmac_id = iwl_mvm_get_lmac_id(mvm->fw,
|
||||
channel->band);
|
||||
ret = iwl_mvm_add_aux_sta(mvm, lmac_id);
|
||||
if (WARN(ret,
|
||||
"Failed to allocate aux station"))
|
||||
goto out_unlock;
|
||||
}
|
||||
ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
|
||||
vif, duration);
|
||||
goto out_unlock;
|
||||
|
@ -4686,7 +4698,7 @@ static void iwl_mvm_flush_no_vif(struct iwl_mvm *mvm, u32 queues, bool drop)
|
|||
}
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
|
||||
struct ieee80211_sta *sta;
|
||||
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
|
||||
|
@ -4728,7 +4740,7 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
|
|||
mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
/* flush the AP-station and all TDLS peers */
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
if (IS_ERR_OR_NULL(sta))
|
||||
|
@ -4742,7 +4754,7 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
|
|||
WARN_ON(i != mvmvif->ap_sta_id && !sta->tdls);
|
||||
|
||||
if (drop) {
|
||||
if (iwl_mvm_flush_sta(mvm, mvmsta, false, 0))
|
||||
if (iwl_mvm_flush_sta(mvm, mvmsta, false))
|
||||
IWL_ERR(mvm, "flush request fail\n");
|
||||
} else {
|
||||
msk |= mvmsta->tfd_queue_msk;
|
||||
|
|
|
@ -888,7 +888,7 @@ struct iwl_mvm {
|
|||
|
||||
/* data related to data path */
|
||||
struct iwl_rx_phy_info last_phy_info;
|
||||
struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT];
|
||||
struct ieee80211_sta __rcu *fw_id_to_mac_id[IWL_MVM_STATION_COUNT_MAX];
|
||||
u8 rx_ba_sessions;
|
||||
|
||||
/* configured by mac80211 */
|
||||
|
@ -1205,7 +1205,7 @@ iwl_mvm_sta_from_staid_rcu(struct iwl_mvm *mvm, u8 sta_id)
|
|||
{
|
||||
struct ieee80211_sta *sta;
|
||||
|
||||
if (sta_id >= ARRAY_SIZE(mvm->fw_id_to_mac_id))
|
||||
if (sta_id >= mvm->fw->ucode_capa.num_stations)
|
||||
return NULL;
|
||||
|
||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
|
||||
|
@ -1222,7 +1222,7 @@ iwl_mvm_sta_from_staid_protected(struct iwl_mvm *mvm, u8 sta_id)
|
|||
{
|
||||
struct ieee80211_sta *sta;
|
||||
|
||||
if (sta_id >= ARRAY_SIZE(mvm->fw_id_to_mac_id))
|
||||
if (sta_id >= mvm->fw->ucode_capa.num_stations)
|
||||
return NULL;
|
||||
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
|
||||
|
@ -1528,7 +1528,7 @@ const char *iwl_mvm_get_tx_fail_reason(u32 status);
|
|||
static inline const char *iwl_mvm_get_tx_fail_reason(u32 status) { return ""; }
|
||||
#endif
|
||||
int iwl_mvm_flush_tx_path(struct iwl_mvm *mvm, u32 tfd_msk, u32 flags);
|
||||
int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal, u32 flags);
|
||||
int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal);
|
||||
int iwl_mvm_flush_sta_tids(struct iwl_mvm *mvm, u32 sta_id,
|
||||
u16 tids, u32 flags);
|
||||
|
||||
|
|
|
@ -464,15 +464,6 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
|
|||
HCMD_NAME(RX_QUEUES_NOTIFICATION),
|
||||
};
|
||||
|
||||
/* Please keep this array *SORTED* by hex value.
|
||||
* Access is done through binary search
|
||||
*/
|
||||
static const struct iwl_hcmd_names iwl_mvm_debug_names[] = {
|
||||
HCMD_NAME(DBGC_SUSPEND_RESUME),
|
||||
HCMD_NAME(BUFFER_ALLOCATION),
|
||||
HCMD_NAME(MFU_ASSERT_DUMP_NTF),
|
||||
};
|
||||
|
||||
/* Please keep this array *SORTED* by hex value.
|
||||
* Access is done through binary search
|
||||
*/
|
||||
|
@ -626,11 +617,12 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||
enum iwl_amsdu_size rb_size_default;
|
||||
|
||||
/*
|
||||
* We use IWL_MVM_STATION_COUNT to check the validity of the station
|
||||
* We use IWL_MVM_STATION_COUNT_MAX to check the validity of the station
|
||||
* index all over the driver - check that its value corresponds to the
|
||||
* array size.
|
||||
*/
|
||||
BUILD_BUG_ON(ARRAY_SIZE(mvm->fw_id_to_mac_id) != IWL_MVM_STATION_COUNT);
|
||||
BUILD_BUG_ON(ARRAY_SIZE(mvm->fw_id_to_mac_id) !=
|
||||
IWL_MVM_STATION_COUNT_MAX);
|
||||
|
||||
/********************************
|
||||
* 1. Allocating and configuring HW data
|
||||
|
@ -769,6 +761,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||
trans_cfg.rx_buf_size = rb_size_default;
|
||||
}
|
||||
|
||||
trans->wide_cmd_header = true;
|
||||
trans_cfg.bc_table_dword =
|
||||
mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210;
|
||||
|
||||
|
@ -1118,7 +1111,7 @@ static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode,
|
|||
mvm->tvqm_info[hw_queue].sta_id :
|
||||
mvm->queue_info[hw_queue].ra_sta_id;
|
||||
|
||||
if (WARN_ON_ONCE(sta_id >= ARRAY_SIZE(mvm->fw_id_to_mac_id)))
|
||||
if (WARN_ON_ONCE(sta_id >= mvm->fw->ucode_capa.num_stations))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
|
|
|
@ -194,11 +194,8 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
|
|||
struct cfg80211_chan_def *chandef,
|
||||
u8 chains_static, u8 chains_dynamic)
|
||||
{
|
||||
if (chandef->chan->band == NL80211_BAND_2GHZ ||
|
||||
!iwl_mvm_is_cdb_supported(mvm))
|
||||
cmd->lmac_id = cpu_to_le32(IWL_LMAC_24G_INDEX);
|
||||
else
|
||||
cmd->lmac_id = cpu_to_le32(IWL_LMAC_5G_INDEX);
|
||||
cmd->lmac_id = cpu_to_le32(iwl_mvm_get_lmac_id(mvm->fw,
|
||||
chandef->chan->band));
|
||||
|
||||
/* Set the channel info data */
|
||||
iwl_mvm_set_chan_info_chandef(mvm, &cmd->ci, chandef);
|
||||
|
|
|
@ -468,6 +468,12 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|||
.amsdu = iwl_mvm_is_csum_supported(mvm),
|
||||
};
|
||||
int ret;
|
||||
u16 cmd_size = sizeof(cfg_cmd);
|
||||
|
||||
/* In old versions of the API the struct is 4 bytes smaller */
|
||||
if (iwl_fw_lookup_cmd_ver(mvm->fw, DATA_PATH_GROUP,
|
||||
TLC_MNG_CONFIG_CMD, 0) < 3)
|
||||
cmd_size -= 4;
|
||||
|
||||
memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));
|
||||
|
||||
|
@ -482,7 +488,7 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|||
*/
|
||||
sta->max_amsdu_len = max_amsdu_len;
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, CMD_ASYNC, sizeof(cfg_cmd),
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, CMD_ASYNC, cmd_size,
|
||||
&cfg_cmd);
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret);
|
||||
|
|
|
@ -420,7 +420,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
|
|||
|
||||
id >>= RX_MDPU_RES_STATUS_STA_ID_SHIFT;
|
||||
|
||||
if (!WARN_ON_ONCE(id >= ARRAY_SIZE(mvm->fw_id_to_mac_id))) {
|
||||
if (!WARN_ON_ONCE(id >= mvm->fw->ucode_capa.num_stations)) {
|
||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[id]);
|
||||
if (IS_ERR(sta))
|
||||
sta = NULL;
|
||||
|
@ -569,7 +569,8 @@ struct iwl_mvm_stat_data {
|
|||
__le32 flags;
|
||||
__le32 mac_id;
|
||||
u8 beacon_filter_average_energy;
|
||||
void *general;
|
||||
__le32 *beacon_counter;
|
||||
u8 *beacon_average_energy;
|
||||
};
|
||||
|
||||
static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
|
||||
|
@ -589,23 +590,10 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
|
|||
* data copied into the "data" struct, but rather the data from
|
||||
* the notification directly.
|
||||
*/
|
||||
if (iwl_mvm_has_new_rx_stats_api(mvm)) {
|
||||
struct mvm_statistics_general *general =
|
||||
data->general;
|
||||
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(general->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-general->beacon_average_energy[vif_id];
|
||||
} else {
|
||||
struct mvm_statistics_general_v8 *general =
|
||||
data->general;
|
||||
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(general->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-general->beacon_average_energy[vif_id];
|
||||
}
|
||||
mvmvif->beacon_stats.num_beacons =
|
||||
le32_to_cpu(data->beacon_counter[vif_id]);
|
||||
mvmvif->beacon_stats.avg_signal =
|
||||
-data->beacon_average_energy[vif_id];
|
||||
|
||||
/* make sure that beacon statistics don't go backwards with TCM
|
||||
* request to clear statistics
|
||||
|
@ -701,18 +689,136 @@ iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt)
|
|||
iwl_fw_dbg_collect_trig(&mvm->fwrt, trig, NULL);
|
||||
}
|
||||
|
||||
static void iwl_mvm_update_avg_energy(struct iwl_mvm *mvm,
|
||||
u8 energy[IWL_MVM_STATION_COUNT_MAX])
|
||||
{
|
||||
int i;
|
||||
|
||||
if (WARN_ONCE(mvm->fw->ucode_capa.num_stations >
|
||||
IWL_MVM_STATION_COUNT_MAX,
|
||||
"Driver and FW station count mismatch %d\n",
|
||||
mvm->fw->ucode_capa.num_stations))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
|
||||
struct iwl_mvm_sta *sta;
|
||||
|
||||
if (!energy[i])
|
||||
continue;
|
||||
|
||||
sta = iwl_mvm_sta_from_staid_rcu(mvm, i);
|
||||
if (!sta)
|
||||
continue;
|
||||
sta->avg_energy = energy[i];
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_update_tcm_from_stats(struct iwl_mvm *mvm, __le32 *air_time_le,
|
||||
__le32 *rx_bytes_le)
|
||||
{
|
||||
int i;
|
||||
|
||||
spin_lock(&mvm->tcm.lock);
|
||||
for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
|
||||
struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[i];
|
||||
u32 rx_bytes = le32_to_cpu(rx_bytes_le[i]);
|
||||
u32 airtime = le32_to_cpu(air_time_le[i]);
|
||||
|
||||
mdata->rx.airtime += airtime;
|
||||
mdata->uapsd_nonagg_detect.rx_bytes += rx_bytes;
|
||||
if (airtime) {
|
||||
/* re-init every time to store rate from FW */
|
||||
ewma_rate_init(&mdata->uapsd_nonagg_detect.rate);
|
||||
ewma_rate_add(&mdata->uapsd_nonagg_detect.rate,
|
||||
rx_bytes * 8 / airtime);
|
||||
}
|
||||
}
|
||||
spin_unlock(&mvm->tcm.lock);
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_handle_rx_statistics_tlv(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
struct iwl_mvm_stat_data data = {
|
||||
.mvm = mvm,
|
||||
};
|
||||
u8 beacon_average_energy[MAC_INDEX_AUX];
|
||||
u8 average_energy[IWL_MVM_STATION_COUNT_MAX];
|
||||
struct iwl_statistics_operational_ntfy *stats;
|
||||
int expected_size;
|
||||
__le32 flags;
|
||||
int i;
|
||||
|
||||
expected_size = sizeof(*stats);
|
||||
if (WARN_ONCE(iwl_rx_packet_payload_len(pkt) < expected_size,
|
||||
"received invalid statistics size (%d)!, expected_size: %d\n",
|
||||
iwl_rx_packet_payload_len(pkt), expected_size))
|
||||
return;
|
||||
|
||||
stats = (void *)&pkt->data;
|
||||
|
||||
if (WARN_ONCE(stats->hdr.type != FW_STATISTICS_OPERATIONAL ||
|
||||
stats->hdr.version != 1,
|
||||
"received unsupported hdr type %d, version %d\n",
|
||||
stats->hdr.type, stats->hdr.version))
|
||||
return;
|
||||
|
||||
flags = stats->flags;
|
||||
mvm->radio_stats.rx_time = le64_to_cpu(stats->rx_time);
|
||||
mvm->radio_stats.tx_time = le64_to_cpu(stats->tx_time);
|
||||
mvm->radio_stats.on_time_rf = le64_to_cpu(stats->on_time_rf);
|
||||
mvm->radio_stats.on_time_scan = le64_to_cpu(stats->on_time_scan);
|
||||
|
||||
iwl_mvm_rx_stats_check_trigger(mvm, pkt);
|
||||
|
||||
data.mac_id = stats->mac_id;
|
||||
data.beacon_filter_average_energy =
|
||||
le32_to_cpu(stats->beacon_filter_average_energy);
|
||||
data.flags = flags;
|
||||
data.beacon_counter = stats->beacon_counter;
|
||||
for (i = 0; i < ARRAY_SIZE(beacon_average_energy); i++)
|
||||
beacon_average_energy[i] =
|
||||
le32_to_cpu(stats->beacon_average_energy[i]);
|
||||
|
||||
data.beacon_average_energy = beacon_average_energy;
|
||||
|
||||
ieee80211_iterate_active_interfaces(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_stat_iterator,
|
||||
&data);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(average_energy); i++)
|
||||
average_energy[i] = le32_to_cpu(stats->average_energy[i]);
|
||||
iwl_mvm_update_avg_energy(mvm, average_energy);
|
||||
|
||||
/*
|
||||
* Don't update in case the statistics are not cleared, since
|
||||
* we will end up counting twice the same airtime, once in TCM
|
||||
* request and once in statistics notification.
|
||||
*/
|
||||
if (le32_to_cpu(flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
|
||||
iwl_mvm_update_tcm_from_stats(mvm, stats->air_time,
|
||||
stats->rx_bytes);
|
||||
}
|
||||
|
||||
void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
struct iwl_mvm_stat_data data = {
|
||||
.mvm = mvm,
|
||||
};
|
||||
__le32 *bytes, *air_time, flags;
|
||||
int expected_size;
|
||||
int i;
|
||||
u8 *energy;
|
||||
__le32 *bytes;
|
||||
__le32 *air_time;
|
||||
__le32 flags;
|
||||
|
||||
/* From ver 14 and up we use TLV statistics format */
|
||||
if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
|
||||
STATISTICS_CMD, 0) >= 14)
|
||||
return iwl_mvm_handle_rx_statistics_tlv(mvm, pkt);
|
||||
|
||||
if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
|
||||
if (iwl_mvm_has_new_rx_api(mvm))
|
||||
|
@ -746,8 +852,9 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
|
|||
mvm->radio_stats.on_time_scan =
|
||||
le64_to_cpu(stats->general.common.on_time_scan);
|
||||
|
||||
data.general = &stats->general;
|
||||
|
||||
data.beacon_counter = stats->general.beacon_counter;
|
||||
data.beacon_average_energy =
|
||||
stats->general.beacon_average_energy;
|
||||
flags = stats->flag;
|
||||
} else {
|
||||
struct iwl_notif_statistics *stats = (void *)&pkt->data;
|
||||
|
@ -767,8 +874,9 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
|
|||
mvm->radio_stats.on_time_scan =
|
||||
le64_to_cpu(stats->general.common.on_time_scan);
|
||||
|
||||
data.general = &stats->general;
|
||||
|
||||
data.beacon_counter = stats->general.beacon_counter;
|
||||
data.beacon_average_energy =
|
||||
stats->general.beacon_average_energy;
|
||||
flags = stats->flag;
|
||||
}
|
||||
data.flags = flags;
|
||||
|
@ -797,45 +905,16 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
|
|||
air_time = (void *)&stats->load_stats.air_time;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
|
||||
struct iwl_mvm_sta *sta;
|
||||
|
||||
if (!energy[i])
|
||||
continue;
|
||||
|
||||
sta = iwl_mvm_sta_from_staid_rcu(mvm, i);
|
||||
if (!sta)
|
||||
continue;
|
||||
sta->avg_energy = energy[i];
|
||||
}
|
||||
rcu_read_unlock();
|
||||
iwl_mvm_update_avg_energy(mvm, energy);
|
||||
|
||||
/*
|
||||
* Don't update in case the statistics are not cleared, since
|
||||
* we will end up counting twice the same airtime, once in TCM
|
||||
* request and once in statistics notification.
|
||||
*/
|
||||
if (!(le32_to_cpu(flags) & IWL_STATISTICS_REPLY_FLG_CLEAR))
|
||||
return;
|
||||
if (le32_to_cpu(flags) & IWL_STATISTICS_REPLY_FLG_CLEAR)
|
||||
iwl_mvm_update_tcm_from_stats(mvm, air_time, bytes);
|
||||
|
||||
spin_lock(&mvm->tcm.lock);
|
||||
for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) {
|
||||
struct iwl_mvm_tcm_mac *mdata = &mvm->tcm.data[i];
|
||||
u32 airtime = le32_to_cpu(air_time[i]);
|
||||
u32 rx_bytes = le32_to_cpu(bytes[i]);
|
||||
|
||||
mdata->uapsd_nonagg_detect.rx_bytes += rx_bytes;
|
||||
if (airtime) {
|
||||
/* re-init every time to store rate from FW */
|
||||
ewma_rate_init(&mdata->uapsd_nonagg_detect.rate);
|
||||
ewma_rate_add(&mdata->uapsd_nonagg_detect.rate,
|
||||
rx_bytes * 8 / airtime);
|
||||
}
|
||||
|
||||
mdata->rx.airtime += airtime;
|
||||
}
|
||||
spin_unlock(&mvm->tcm.lock);
|
||||
}
|
||||
|
||||
void iwl_mvm_rx_statistics(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
|
||||
|
|
|
@ -1773,7 +1773,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
|||
if (desc->status & cpu_to_le32(IWL_RX_MPDU_STATUS_SRC_STA_FOUND)) {
|
||||
u8 id = le32_get_bits(desc->status, IWL_RX_MPDU_STATUS_STA_ID);
|
||||
|
||||
if (!WARN_ON_ONCE(id >= ARRAY_SIZE(mvm->fw_id_to_mac_id))) {
|
||||
if (!WARN_ON_ONCE(id >= mvm->fw->ucode_capa.num_stations)) {
|
||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[id]);
|
||||
if (IS_ERR(sta))
|
||||
sta = NULL;
|
||||
|
|
|
@ -698,14 +698,28 @@ static void iwl_mvm_scan_fill_tx_cmd(struct iwl_mvm *mvm,
|
|||
tx_cmd[0].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
|
||||
NL80211_BAND_2GHZ,
|
||||
no_cck);
|
||||
tx_cmd[0].sta_id = mvm->aux_sta.sta_id;
|
||||
|
||||
if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
|
||||
ADD_STA,
|
||||
0) < 12) {
|
||||
tx_cmd[0].sta_id = mvm->aux_sta.sta_id;
|
||||
tx_cmd[1].sta_id = mvm->aux_sta.sta_id;
|
||||
|
||||
/*
|
||||
* Fw doesn't use this sta anymore, pending deprecation via HOST API
|
||||
* change
|
||||
*/
|
||||
} else {
|
||||
tx_cmd[0].sta_id = 0xff;
|
||||
tx_cmd[1].sta_id = 0xff;
|
||||
}
|
||||
|
||||
tx_cmd[1].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
|
||||
TX_CMD_FLG_BT_DIS);
|
||||
|
||||
tx_cmd[1].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
|
||||
NL80211_BAND_5GHZ,
|
||||
no_cck);
|
||||
tx_cmd[1].sta_id = mvm->aux_sta.sta_id;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1117,6 +1131,10 @@ static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
|
|||
|
||||
memcpy(&cfg->mac_addr, &mvm->addresses[0].addr, ETH_ALEN);
|
||||
|
||||
/* This function should not be called when using ADD_STA ver >=12 */
|
||||
WARN_ON_ONCE(iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
|
||||
ADD_STA, 0) >= 12);
|
||||
|
||||
cfg->bcast_sta_id = mvm->aux_sta.sta_id;
|
||||
cfg->channel_flags = channel_flags;
|
||||
|
||||
|
@ -1165,6 +1183,10 @@ static void iwl_mvm_fill_scan_config_v2(struct iwl_mvm *mvm, void *config,
|
|||
|
||||
memcpy(&cfg->mac_addr, &mvm->addresses[0].addr, ETH_ALEN);
|
||||
|
||||
/* This function should not be called when using ADD_STA ver >=12 */
|
||||
WARN_ON_ONCE(iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
|
||||
ADD_STA, 0) >= 12);
|
||||
|
||||
cfg->bcast_sta_id = mvm->aux_sta.sta_id;
|
||||
cfg->channel_flags = channel_flags;
|
||||
|
||||
|
@ -1278,7 +1300,16 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
|
|||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.bcast_sta_id = mvm->aux_sta.sta_id;
|
||||
if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
|
||||
ADD_STA, 0) < 12)
|
||||
cfg.bcast_sta_id = mvm->aux_sta.sta_id;
|
||||
/*
|
||||
* Fw doesn't use this sta anymore, pending deprecation via HOST API
|
||||
* change.
|
||||
*/
|
||||
else
|
||||
cfg.bcast_sta_id = 0xff;
|
||||
|
||||
cfg.tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
|
||||
cfg.rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm,
|
|||
int sta_id;
|
||||
u32 reserved_ids = 0;
|
||||
|
||||
BUILD_BUG_ON(IWL_MVM_STATION_COUNT > 32);
|
||||
BUILD_BUG_ON(IWL_MVM_STATION_COUNT_MAX > 32);
|
||||
WARN_ON_ONCE(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status));
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
@ -95,7 +95,7 @@ static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm,
|
|||
reserved_ids = BIT(0);
|
||||
|
||||
/* Don't take rcu_read_lock() since we are protected by mvm->mutex */
|
||||
for (sta_id = 0; sta_id < ARRAY_SIZE(mvm->fw_id_to_mac_id); sta_id++) {
|
||||
for (sta_id = 0; sta_id < mvm->fw->ucode_capa.num_stations; sta_id++) {
|
||||
if (BIT(sta_id) & reserved_ids)
|
||||
continue;
|
||||
|
||||
|
@ -1538,8 +1538,15 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
|
|||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.sta_id = sta->sta_id;
|
||||
cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
|
||||
color));
|
||||
|
||||
if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP, ADD_STA,
|
||||
0) >= 12 &&
|
||||
sta->type == IWL_STA_AUX_ACTIVITY)
|
||||
cmd.mac_id_n_color = cpu_to_le32(mac_id);
|
||||
else
|
||||
cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
|
||||
color));
|
||||
|
||||
if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
|
||||
cmd.station_type = sta->type;
|
||||
|
||||
|
@ -1856,7 +1863,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
|
|||
return ret;
|
||||
|
||||
/* flush its queues here since we are freeing mvm_sta */
|
||||
ret = iwl_mvm_flush_sta(mvm, mvm_sta, false, 0);
|
||||
ret = iwl_mvm_flush_sta(mvm, mvm_sta, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (iwl_mvm_has_new_tx_api(mvm)) {
|
||||
|
@ -2032,7 +2039,7 @@ static int iwl_mvm_add_int_sta_with_queue(struct iwl_mvm *mvm, int macidx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
|
||||
int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm, u32 lmac_id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -2045,7 +2052,11 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = iwl_mvm_add_int_sta_with_queue(mvm, MAC_INDEX_AUX, 0, NULL,
|
||||
/*
|
||||
* In CDB NICs we need to specify which lmac to use for aux activity
|
||||
* using the mac_id argument place to send lmac_id to the function
|
||||
*/
|
||||
ret = iwl_mvm_add_int_sta_with_queue(mvm, lmac_id, 0, NULL,
|
||||
&mvm->aux_sta, &mvm->aux_queue,
|
||||
IWL_MVM_TX_FIFO_MCAST);
|
||||
if (ret) {
|
||||
|
@ -2188,7 +2199,7 @@ static void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm,
|
|||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
iwl_mvm_flush_sta(mvm, &mvmvif->bcast_sta, true, 0);
|
||||
iwl_mvm_flush_sta(mvm, &mvmvif->bcast_sta, true);
|
||||
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
|
@ -2437,7 +2448,7 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
iwl_mvm_flush_sta(mvm, &mvmvif->mcast_sta, true, 0);
|
||||
iwl_mvm_flush_sta(mvm, &mvmvif->mcast_sta, true);
|
||||
|
||||
iwl_mvm_disable_txq(mvm, NULL, mvmvif->cab_queue, 0, 0);
|
||||
|
||||
|
@ -3760,7 +3771,7 @@ void iwl_mvm_rx_eosp_notif(struct iwl_mvm *mvm,
|
|||
struct ieee80211_sta *sta;
|
||||
u32 sta_id = le32_to_cpu(notif->sta_id);
|
||||
|
||||
if (WARN_ON_ONCE(sta_id >= IWL_MVM_STATION_COUNT))
|
||||
if (WARN_ON_ONCE(sta_id >= mvm->fw->ucode_capa.num_stations))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
|
@ -3843,7 +3854,7 @@ void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
|
|||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
/* Block/unblock all the stations of the given mvmvif */
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
if (IS_ERR_OR_NULL(sta))
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
#include <linux/wait.h>
|
||||
|
||||
#include "iwl-trans.h" /* for IWL_MAX_TID_COUNT */
|
||||
#include "fw-api.h" /* IWL_MVM_STATION_COUNT */
|
||||
#include "fw-api.h" /* IWL_MVM_STATION_COUNT_MAX */
|
||||
#include "rs.h"
|
||||
|
||||
struct iwl_mvm;
|
||||
|
@ -540,7 +540,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
int tid, u8 queue, bool start);
|
||||
|
||||
int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm, u32 lmac_id);
|
||||
int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm);
|
||||
|
||||
int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
|
@ -582,5 +582,4 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk);
|
|||
int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct iwl_mvm_int_sta *sta, u8 *addr, u32 cipher,
|
||||
u8 *key, u32 key_len);
|
||||
|
||||
#endif /* __sta_h__ */
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(C) 2018 - 2019 Intel Corporation
|
||||
* Copyright(C) 2018 - 2020 Intel Corporation
|
||||
*
|
||||
* 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
|
||||
|
@ -29,7 +29,7 @@
|
|||
*
|
||||
* Copyright(c) 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(C) 2018 - 2019 Intel Corporation
|
||||
* Copyright(C) 2018 - 2020 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -77,7 +77,7 @@ void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm)
|
|||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
if (!sta || IS_ERR(sta) || !sta->tdls)
|
||||
|
@ -100,7 +100,7 @@ int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
if (!sta || IS_ERR(sta) || !sta->tdls)
|
||||
|
@ -144,7 +144,7 @@ static void iwl_mvm_tdls_config(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
|
||||
/* populate TDLS peer data */
|
||||
cnt = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
|
||||
lockdep_is_held(&mvm->mutex));
|
||||
if (IS_ERR_OR_NULL(sta) || !sta->tdls)
|
||||
|
@ -273,7 +273,7 @@ void iwl_mvm_rx_tdls_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
|
|||
return;
|
||||
}
|
||||
|
||||
if (WARN_ON(sta_id >= IWL_MVM_STATION_COUNT))
|
||||
if (WARN_ON(sta_id >= mvm->fw->ucode_capa.num_stations))
|
||||
return;
|
||||
|
||||
sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id],
|
||||
|
|
|
@ -5,10 +5,9 @@
|
|||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
|
||||
*
|
||||
* 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
|
||||
|
@ -28,10 +27,9 @@
|
|||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation
|
||||
* Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -116,14 +114,9 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
|||
* event finishes or is canceled, so that frames queued for it
|
||||
* won't get stuck on the queue and be transmitted in the next
|
||||
* time event.
|
||||
* We have to send the command asynchronously since this cannot
|
||||
* be under the mutex for locking reasons, but that's not an
|
||||
* issue as it will have to complete before the next command is
|
||||
* executed, and a new time event means a new command.
|
||||
*/
|
||||
iwl_mvm_flush_sta(mvm, &mvm->aux_sta, true, CMD_ASYNC);
|
||||
|
||||
/* Do the same for the P2P device queue (STA) */
|
||||
mutex_lock(&mvm->mutex);
|
||||
if (test_and_clear_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status)) {
|
||||
struct iwl_mvm_vif *mvmvif;
|
||||
|
||||
|
@ -136,10 +129,20 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
|
|||
|
||||
if (!WARN_ON(!mvm->p2p_device_vif)) {
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(mvm->p2p_device_vif);
|
||||
iwl_mvm_flush_sta(mvm, &mvmvif->bcast_sta, true,
|
||||
CMD_ASYNC);
|
||||
iwl_mvm_flush_sta(mvm, &mvmvif->bcast_sta, true);
|
||||
}
|
||||
} else {
|
||||
/* do the same in case of hot spot 2.0 */
|
||||
iwl_mvm_flush_sta(mvm, &mvm->aux_sta, true);
|
||||
/* In newer version of this command an aux station is added only
|
||||
* in cases of dedicated tx queue and need to be removed in end
|
||||
* of use */
|
||||
if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
|
||||
ADD_STA, 0) >= 12)
|
||||
iwl_mvm_rm_aux_sta(mvm);
|
||||
}
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
|
||||
|
@ -1013,6 +1016,28 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
iwl_mvm_roc_finished(mvm);
|
||||
}
|
||||
|
||||
void iwl_mvm_remove_csa_period(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
|
||||
u32 id;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
if (!te_data->running)
|
||||
return;
|
||||
|
||||
spin_lock_bh(&mvm->time_event_lock);
|
||||
id = te_data->id;
|
||||
spin_unlock_bh(&mvm->time_event_lock);
|
||||
|
||||
if (id != TE_CHANNEL_SWITCH_PERIOD)
|
||||
return;
|
||||
|
||||
iwl_mvm_remove_time_event(mvm, mvmvif, te_data);
|
||||
}
|
||||
|
||||
int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
u32 duration, u32 apply_time)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019 - 2020 Intel Corporation
|
||||
*
|
||||
* 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
|
||||
|
@ -29,7 +29,7 @@
|
|||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2019 Intel Corporation
|
||||
* Copyright (C) 2019 - 2020 Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -216,6 +216,9 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
|
|||
void iwl_mvm_cleanup_roc_te(struct iwl_mvm *mvm);
|
||||
void iwl_mvm_roc_done_wk(struct work_struct *wk);
|
||||
|
||||
void iwl_mvm_remove_csa_period(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif);
|
||||
|
||||
/**
|
||||
* iwl_mvm_schedule_csa_period - request channel switch absence period
|
||||
* @mvm: the mvm component
|
||||
|
|
|
@ -349,6 +349,8 @@ static void check_exit_ctkill(struct work_struct *work)
|
|||
|
||||
duration = tt->params.ct_kill_duration;
|
||||
|
||||
flush_work(&mvm->roc_done_wk);
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
if (__iwl_mvm_mac_start(mvm))
|
||||
|
@ -399,7 +401,7 @@ static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
|
|||
struct iwl_mvm_sta *mvmsta;
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) {
|
||||
for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
|
||||
mvmsta = iwl_mvm_sta_from_staid_protected(mvm, i);
|
||||
if (!mvmsta)
|
||||
continue;
|
||||
|
|
|
@ -793,11 +793,7 @@ unsigned int iwl_mvm_max_amsdu_size(struct iwl_mvm *mvm,
|
|||
enum nl80211_band band = mvmsta->vif->bss_conf.chandef.chan->band;
|
||||
u8 ac = tid_to_mac80211_ac[tid];
|
||||
unsigned int txf;
|
||||
int lmac = IWL_LMAC_24G_INDEX;
|
||||
|
||||
if (iwl_mvm_is_cdb_supported(mvm) &&
|
||||
band == NL80211_BAND_5GHZ)
|
||||
lmac = IWL_LMAC_5G_INDEX;
|
||||
int lmac = iwl_mvm_get_lmac_id(mvm->fw, band);
|
||||
|
||||
/* For HE redirect to trigger based fifos */
|
||||
if (sta->he_cap.has_he && !WARN_ON(!iwl_mvm_has_new_tx_api(mvm)))
|
||||
|
@ -1371,7 +1367,7 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* translate ucode response to mac80211 tx status control values
|
||||
*/
|
||||
static void iwl_mvm_hwrate_to_tx_status(u32 rate_n_flags,
|
||||
|
@ -1413,7 +1409,7 @@ static void iwl_mvm_tx_status_check_trigger(struct iwl_mvm *mvm,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* iwl_mvm_get_scd_ssn - returns the SSN of the SCD
|
||||
* @tx_resp: the Tx response from the fw (agg or non-agg)
|
||||
*
|
||||
|
@ -1774,7 +1770,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
|
|||
struct sk_buff *skb;
|
||||
int freed;
|
||||
|
||||
if (WARN_ONCE(sta_id >= IWL_MVM_STATION_COUNT ||
|
||||
if (WARN_ONCE(sta_id >= mvm->fw->ucode_capa.num_stations ||
|
||||
tid > IWL_MAX_TID_COUNT,
|
||||
"sta_id %d tid %d", sta_id, tid))
|
||||
return;
|
||||
|
@ -2059,7 +2055,7 @@ int iwl_mvm_flush_sta_tids(struct iwl_mvm *mvm, u32 sta_id,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal, u32 flags)
|
||||
int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal)
|
||||
{
|
||||
struct iwl_mvm_int_sta *int_sta = sta;
|
||||
struct iwl_mvm_sta *mvm_sta = sta;
|
||||
|
@ -2068,12 +2064,10 @@ int iwl_mvm_flush_sta(struct iwl_mvm *mvm, void *sta, bool internal, u32 flags)
|
|||
offsetof(struct iwl_mvm_sta, sta_id));
|
||||
|
||||
if (iwl_mvm_has_new_tx_api(mvm))
|
||||
return iwl_mvm_flush_sta_tids(mvm, mvm_sta->sta_id,
|
||||
0xffff, flags);
|
||||
return iwl_mvm_flush_sta_tids(mvm, mvm_sta->sta_id, 0xffff, 0);
|
||||
|
||||
if (internal)
|
||||
return iwl_mvm_flush_tx_path(mvm, int_sta->tfd_queue_msk,
|
||||
flags);
|
||||
return iwl_mvm_flush_tx_path(mvm, int_sta->tfd_queue_msk, 0);
|
||||
|
||||
return iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, flags);
|
||||
return iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, 0);
|
||||
}
|
||||
|
|
|
@ -620,7 +620,8 @@ int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id,
|
|||
|
||||
/**
|
||||
* iwl_mvm_send_lq_cmd() - Send link quality command
|
||||
* @sync: This command can be sent synchronously.
|
||||
* @mvm: Driver data.
|
||||
* @lq: Link quality command to send.
|
||||
*
|
||||
* The link quality command is sent as the last step of station creation.
|
||||
* This is the special case in which init is set and we call a callback in
|
||||
|
@ -645,8 +646,10 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq)
|
|||
|
||||
/**
|
||||
* iwl_mvm_update_smps - Get a request to change the SMPS mode
|
||||
* @mvm: Driver data.
|
||||
* @vif: Pointer to the ieee80211_vif structure
|
||||
* @req_type: The part of the driver who call for a change.
|
||||
* @smps_requests: The request to change the SMPS mode.
|
||||
* @smps_request: The request to change the SMPS mode.
|
||||
*
|
||||
* Get a requst to change the SMPS mode,
|
||||
* and change it according to all other requests in the driver.
|
||||
|
|
|
@ -301,3 +301,30 @@ void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans)
|
|||
trans_pcie->prph_info_dma_addr = 0;
|
||||
trans_pcie->prph_info = NULL;
|
||||
}
|
||||
|
||||
int iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans,
|
||||
const void *data, u32 len)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl =
|
||||
&trans_pcie->prph_scratch->ctrl_cfg;
|
||||
int ret;
|
||||
|
||||
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
|
||||
return 0;
|
||||
|
||||
ret = iwl_pcie_ctxt_info_alloc_dma(trans, data, len,
|
||||
&trans_pcie->pnvm_dram);
|
||||
if (ret < 0) {
|
||||
IWL_DEBUG_FW(trans, "Failed to allocate PNVM DMA %d.\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
prph_sc_ctrl->pnvm_cfg.pnvm_base_addr =
|
||||
cpu_to_le64(trans_pcie->pnvm_dram.physical);
|
||||
prph_sc_ctrl->pnvm_cfg.pnvm_size =
|
||||
cpu_to_le32(trans_pcie->pnvm_dram.size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -93,17 +93,17 @@ static void *iwl_pcie_ctxt_info_dma_alloc_coherent(struct iwl_trans *trans,
|
|||
return _iwl_pcie_ctxt_info_dma_alloc_coherent(trans, size, phys, 0);
|
||||
}
|
||||
|
||||
static int iwl_pcie_ctxt_info_alloc_dma(struct iwl_trans *trans,
|
||||
const struct fw_desc *sec,
|
||||
struct iwl_dram_data *dram)
|
||||
int iwl_pcie_ctxt_info_alloc_dma(struct iwl_trans *trans,
|
||||
const void *data, u32 len,
|
||||
struct iwl_dram_data *dram)
|
||||
{
|
||||
dram->block = iwl_pcie_ctxt_info_dma_alloc_coherent(trans, sec->len,
|
||||
dram->block = iwl_pcie_ctxt_info_dma_alloc_coherent(trans, len,
|
||||
&dram->physical);
|
||||
if (!dram->block)
|
||||
return -ENOMEM;
|
||||
|
||||
dram->size = sec->len;
|
||||
memcpy(dram->block, sec->data, sec->len);
|
||||
dram->size = len;
|
||||
memcpy(dram->block, data, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -156,7 +156,8 @@ int iwl_pcie_init_fw_sec(struct iwl_trans *trans,
|
|||
|
||||
/* initialize lmac sections */
|
||||
for (i = 0; i < lmac_cnt; i++) {
|
||||
ret = iwl_pcie_ctxt_info_alloc_dma(trans, &fw->sec[i],
|
||||
ret = iwl_pcie_ctxt_info_alloc_dma(trans, fw->sec[i].data,
|
||||
fw->sec[i].len,
|
||||
&dram->fw[dram->fw_cnt]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -169,7 +170,8 @@ int iwl_pcie_init_fw_sec(struct iwl_trans *trans,
|
|||
for (i = 0; i < umac_cnt; i++) {
|
||||
/* access FW with +1 to make up for lmac separator */
|
||||
ret = iwl_pcie_ctxt_info_alloc_dma(trans,
|
||||
&fw->sec[dram->fw_cnt + 1],
|
||||
fw->sec[dram->fw_cnt + 1].data,
|
||||
fw->sec[dram->fw_cnt + 1].len,
|
||||
&dram->fw[dram->fw_cnt]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -192,7 +194,8 @@ int iwl_pcie_init_fw_sec(struct iwl_trans *trans,
|
|||
/* access FW with +2 to make up for lmac & umac separators */
|
||||
int fw_idx = dram->fw_cnt + i + 2;
|
||||
|
||||
ret = iwl_pcie_ctxt_info_alloc_dma(trans, &fw->sec[fw_idx],
|
||||
ret = iwl_pcie_ctxt_info_alloc_dma(trans, fw->sec[fw_idx].data,
|
||||
fw->sec[fw_idx].len,
|
||||
&dram->paging[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -512,9 +512,9 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
|
|||
|
||||
/* 9000 Series */
|
||||
{IWL_PCI_DEVICE(0x2526, PCI_ANY_ID, iwl9000_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x271B, PCI_ANY_ID, iwl9560_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x271C, PCI_ANY_ID, iwl9560_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x30DC, PCI_ANY_ID, iwl9560_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x271B, PCI_ANY_ID, iwl9000_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x271C, PCI_ANY_ID, iwl9000_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x30DC, PCI_ANY_ID, iwl9560_long_latency_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x31DC, PCI_ANY_ID, iwl9560_shared_clk_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0x9DF0, PCI_ANY_ID, iwl9560_trans_cfg)},
|
||||
{IWL_PCI_DEVICE(0xA370, PCI_ANY_ID, iwl9560_trans_cfg)},
|
||||
|
@ -632,6 +632,7 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
|
|||
IWL_DEV_INFO(0xA0F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL),
|
||||
IWL_DEV_INFO(0x02F0, 0x0070, iwl_ax201_cfg_quz_hr, NULL),
|
||||
IWL_DEV_INFO(0x02F0, 0x0074, iwl_ax201_cfg_quz_hr, NULL),
|
||||
IWL_DEV_INFO(0x02F0, 0x6074, iwl_ax201_cfg_quz_hr, NULL),
|
||||
IWL_DEV_INFO(0x02F0, 0x0078, iwl_ax201_cfg_quz_hr, NULL),
|
||||
IWL_DEV_INFO(0x02F0, 0x007C, iwl_ax201_cfg_quz_hr, NULL),
|
||||
IWL_DEV_INFO(0x02F0, 0x0310, iwl_ax201_cfg_quz_hr, NULL),
|
||||
|
|
|
@ -339,6 +339,7 @@ struct cont_rec {
|
|||
* @trans: pointer to the generic transport area
|
||||
* @scd_base_addr: scheduler sram base address in SRAM
|
||||
* @kw: keep warm address
|
||||
* @pnvm_dram: DRAM area that contains the PNVM data
|
||||
* @pci_dev: basic pci-network driver stuff
|
||||
* @hw_base: pci hardware address support
|
||||
* @ucode_write_complete: indicates that the ucode has been copied.
|
||||
|
@ -410,6 +411,8 @@ struct iwl_trans_pcie {
|
|||
u32 scd_base_addr;
|
||||
struct iwl_dma_ptr kw;
|
||||
|
||||
struct iwl_dram_data pnvm_dram;
|
||||
|
||||
struct iwl_txq *txq_memory;
|
||||
|
||||
/* PCI bus related data */
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
#include "fw/api/tx.h"
|
||||
#include "internal.h"
|
||||
#include "iwl-fh.h"
|
||||
#include "iwl-context-info-gen3.h"
|
||||
|
||||
/* extended range in FW SRAM */
|
||||
#define IWL_FW_MEM_EXTENDED_START 0x40000
|
||||
|
@ -1979,6 +1980,11 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
|
|||
|
||||
iwl_pcie_free_fw_monitor(trans);
|
||||
|
||||
if (trans_pcie->pnvm_dram.size)
|
||||
dma_free_coherent(trans->dev, trans_pcie->pnvm_dram.size,
|
||||
trans_pcie->pnvm_dram.block,
|
||||
trans_pcie->pnvm_dram.physical);
|
||||
|
||||
mutex_destroy(&trans_pcie->mutex);
|
||||
iwl_trans_free(trans);
|
||||
}
|
||||
|
@ -3451,6 +3457,7 @@ static const struct iwl_trans_ops trans_ops_pcie_gen2 = {
|
|||
.txq_free = iwl_txq_dyn_free,
|
||||
.wait_txq_empty = iwl_trans_pcie_wait_txq_empty,
|
||||
.rxq_dma_data = iwl_trans_pcie_rxq_dma_data,
|
||||
.set_pnvm = iwl_trans_pcie_ctx_info_gen3_set_pnvm,
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
.debugfs_cleanup = iwl_trans_pcie_debugfs_cleanup,
|
||||
#endif
|
||||
|
|
|
@ -1180,6 +1180,11 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
|
|||
const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD];
|
||||
u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD];
|
||||
|
||||
if (WARN(!trans->wide_cmd_header &&
|
||||
group_id > IWL_ALWAYS_LONG_GROUP,
|
||||
"unsupported wide command %#x\n", cmd->id))
|
||||
return -EINVAL;
|
||||
|
||||
if (group_id != 0) {
|
||||
copy_size = sizeof(struct iwl_cmd_header_wide);
|
||||
cmd_size = sizeof(struct iwl_cmd_header_wide);
|
||||
|
|
|
@ -2403,6 +2403,8 @@ error:
|
|||
kfree(card->mpa_rx.buf);
|
||||
card->mpa_tx.buf_size = 0;
|
||||
card->mpa_rx.buf_size = 0;
|
||||
card->mpa_tx.buf = NULL;
|
||||
card->mpa_rx.buf = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -1905,7 +1905,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
|
|||
* index diff of legacy to HT OFDM rate. */
|
||||
tempval = hwinfo[EEPROM_RFIND_POWERDIFF] & 0xff;
|
||||
rtlefuse->eeprom_txpowerdiff = tempval;
|
||||
rtlefuse->legacy_httxpowerdiff =
|
||||
rtlefuse->legacy_ht_txpowerdiff =
|
||||
rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0];
|
||||
|
||||
RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
|
||||
|
|
|
@ -25,7 +25,7 @@ static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel,
|
|||
|
||||
/* We only care about the path A for legacy. */
|
||||
if (rtlefuse->eeprom_version < 2) {
|
||||
pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_httxpowerdiff & 0xf);
|
||||
pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_ht_txpowerdiff & 0xf);
|
||||
} else {
|
||||
legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff
|
||||
[RF90_PATH_A][chnl - 1];
|
||||
|
|
|
@ -1966,7 +1966,6 @@ struct rtl_efuse {
|
|||
|
||||
u8 txpwr_safetyflag; /* Band edge enable flag */
|
||||
u16 eeprom_txpowerdiff;
|
||||
u8 legacy_httxpowerdiff; /* Legacy to HT rate power diff */
|
||||
u8 antenna_txpwdiff[3];
|
||||
|
||||
u8 eeprom_regulatory;
|
||||
|
|
Загрузка…
Ссылка в новой задаче