Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for v5.10. Major changes: ath10k * support SDIO firmware codedumps * support station specific TID configurations ath11k * add support for IPQ6018
This commit is contained in:
commit
5941d003f0
@ -65,7 +65,8 @@ Optional properties:
|
||||
the length can vary between hw versions.
|
||||
- <supply-name>-supply: handle to the regulator device tree node
|
||||
optional "supply-name" are "vdd-0.8-cx-mx",
|
||||
"vdd-1.8-xo", "vdd-1.3-rfa" and "vdd-3.3-ch0".
|
||||
"vdd-1.8-xo", "vdd-1.3-rfa", "vdd-3.3-ch0",
|
||||
and "vdd-3.3-ch1".
|
||||
- memory-region:
|
||||
Usage: optional
|
||||
Value type: <phandle>
|
||||
@ -204,6 +205,7 @@ wifi@18000000 {
|
||||
vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
|
||||
vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
|
||||
vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
|
||||
vdd-3.3-ch1-supply = <&vreg_l26a_3p3>;
|
||||
memory-region = <&wifi_msa_mem>;
|
||||
iommus = <&apps_smmu 0x0040 0x1>;
|
||||
qcom,msa-fixed-perm;
|
||||
|
@ -17,7 +17,9 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,ipq8074-wifi
|
||||
enum:
|
||||
- qcom,ipq8074-wifi
|
||||
- qcom,ipq6018-wifi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -16,6 +16,7 @@ void ath10k_bmi_start(struct ath10k *ar)
|
||||
|
||||
ar->bmi.done_sent = false;
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_bmi_start);
|
||||
|
||||
int ath10k_bmi_done(struct ath10k *ar)
|
||||
{
|
||||
@ -189,6 +190,7 @@ int ath10k_bmi_read_memory(struct ath10k *ar,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_bmi_read_memory);
|
||||
|
||||
int ath10k_bmi_write_soc_reg(struct ath10k *ar, u32 address, u32 reg_val)
|
||||
{
|
||||
|
@ -481,15 +481,6 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar,
|
||||
ath10k_ce_write32(ar, ce_ctrl_addr + wm_regs->addr, mask);
|
||||
}
|
||||
|
||||
static inline bool ath10k_ce_engine_int_status_check(struct ath10k *ar,
|
||||
u32 ce_ctrl_addr,
|
||||
unsigned int mask)
|
||||
{
|
||||
struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs;
|
||||
|
||||
return ath10k_ce_read32(ar, ce_ctrl_addr + wm_regs->addr) & mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Guts of ath10k_ce_send.
|
||||
* The caller takes responsibility for any needed locking.
|
||||
@ -1308,32 +1299,24 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
|
||||
struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs;
|
||||
u32 ctrl_addr = ce_state->ctrl_addr;
|
||||
|
||||
spin_lock_bh(&ce->ce_lock);
|
||||
|
||||
if (ath10k_ce_engine_int_status_check(ar, ctrl_addr,
|
||||
wm_regs->cc_mask)) {
|
||||
/* Clear before handling */
|
||||
ath10k_ce_engine_int_status_clear(ar, ctrl_addr,
|
||||
wm_regs->cc_mask);
|
||||
|
||||
spin_unlock_bh(&ce->ce_lock);
|
||||
|
||||
if (ce_state->recv_cb)
|
||||
ce_state->recv_cb(ce_state);
|
||||
|
||||
if (ce_state->send_cb)
|
||||
ce_state->send_cb(ce_state);
|
||||
|
||||
spin_lock_bh(&ce->ce_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear before handling
|
||||
*
|
||||
* Misc CE interrupts are not being handled, but still need
|
||||
* to be cleared.
|
||||
*
|
||||
* NOTE: When the last copy engine interrupt is cleared the
|
||||
* hardware will go to sleep. Once this happens any access to
|
||||
* the CE registers can cause a hardware fault.
|
||||
*/
|
||||
ath10k_ce_engine_int_status_clear(ar, ctrl_addr, wm_regs->wm_mask);
|
||||
ath10k_ce_engine_int_status_clear(ar, ctrl_addr,
|
||||
wm_regs->cc_mask | wm_regs->wm_mask);
|
||||
|
||||
spin_unlock_bh(&ce->ce_lock);
|
||||
if (ce_state->recv_cb)
|
||||
ce_state->recv_cb(ce_state);
|
||||
|
||||
if (ce_state->send_cb)
|
||||
ce_state->send_cb(ce_state);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_ce_per_engine_service);
|
||||
|
||||
@ -1384,45 +1367,55 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state)
|
||||
ath10k_ce_watermark_intr_disable(ar, ctrl_addr);
|
||||
}
|
||||
|
||||
int ath10k_ce_disable_interrupts(struct ath10k *ar)
|
||||
void ath10k_ce_disable_interrupt(struct ath10k *ar, int ce_id)
|
||||
{
|
||||
struct ath10k_ce *ce = ath10k_ce_priv(ar);
|
||||
struct ath10k_ce_pipe *ce_state;
|
||||
u32 ctrl_addr;
|
||||
|
||||
ce_state = &ce->ce_states[ce_id];
|
||||
if (ce_state->attr_flags & CE_ATTR_POLL)
|
||||
return;
|
||||
|
||||
ctrl_addr = ath10k_ce_base_address(ar, ce_id);
|
||||
|
||||
ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr);
|
||||
ath10k_ce_error_intr_disable(ar, ctrl_addr);
|
||||
ath10k_ce_watermark_intr_disable(ar, ctrl_addr);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_ce_disable_interrupt);
|
||||
|
||||
void ath10k_ce_disable_interrupts(struct ath10k *ar)
|
||||
{
|
||||
int ce_id;
|
||||
|
||||
for (ce_id = 0; ce_id < CE_COUNT; ce_id++) {
|
||||
ce_state = &ce->ce_states[ce_id];
|
||||
if (ce_state->attr_flags & CE_ATTR_POLL)
|
||||
continue;
|
||||
|
||||
ctrl_addr = ath10k_ce_base_address(ar, ce_id);
|
||||
|
||||
ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr);
|
||||
ath10k_ce_error_intr_disable(ar, ctrl_addr);
|
||||
ath10k_ce_watermark_intr_disable(ar, ctrl_addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
for (ce_id = 0; ce_id < CE_COUNT; ce_id++)
|
||||
ath10k_ce_disable_interrupt(ar, ce_id);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_ce_disable_interrupts);
|
||||
|
||||
void ath10k_ce_enable_interrupts(struct ath10k *ar)
|
||||
void ath10k_ce_enable_interrupt(struct ath10k *ar, int ce_id)
|
||||
{
|
||||
struct ath10k_ce *ce = ath10k_ce_priv(ar);
|
||||
int ce_id;
|
||||
struct ath10k_ce_pipe *ce_state;
|
||||
|
||||
ce_state = &ce->ce_states[ce_id];
|
||||
if (ce_state->attr_flags & CE_ATTR_POLL)
|
||||
return;
|
||||
|
||||
ath10k_ce_per_engine_handler_adjust(ce_state);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_ce_enable_interrupt);
|
||||
|
||||
void ath10k_ce_enable_interrupts(struct ath10k *ar)
|
||||
{
|
||||
int ce_id;
|
||||
|
||||
/* Enable interrupts for copy engine that
|
||||
* are not using polling mode.
|
||||
*/
|
||||
for (ce_id = 0; ce_id < CE_COUNT; ce_id++) {
|
||||
ce_state = &ce->ce_states[ce_id];
|
||||
if (ce_state->attr_flags & CE_ATTR_POLL)
|
||||
continue;
|
||||
|
||||
ath10k_ce_per_engine_handler_adjust(ce_state);
|
||||
}
|
||||
for (ce_id = 0; ce_id < CE_COUNT; ce_id++)
|
||||
ath10k_ce_enable_interrupt(ar, ce_id);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_ce_enable_interrupts);
|
||||
|
||||
|
@ -255,10 +255,13 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state,
|
||||
/*==================CE Interrupt Handlers====================*/
|
||||
void ath10k_ce_per_engine_service_any(struct ath10k *ar);
|
||||
void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
|
||||
int ath10k_ce_disable_interrupts(struct ath10k *ar);
|
||||
void ath10k_ce_disable_interrupt(struct ath10k *ar, int ce_id);
|
||||
void ath10k_ce_disable_interrupts(struct ath10k *ar);
|
||||
void ath10k_ce_enable_interrupt(struct ath10k *ar, int ce_id);
|
||||
void ath10k_ce_enable_interrupts(struct ath10k *ar);
|
||||
void ath10k_ce_dump_registers(struct ath10k *ar,
|
||||
struct ath10k_fw_crash_data *crash_data);
|
||||
|
||||
void ath10k_ce_alloc_rri(struct ath10k *ar);
|
||||
void ath10k_ce_free_rri(struct ath10k *ar);
|
||||
|
||||
@ -369,18 +372,14 @@ static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id)
|
||||
(((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> \
|
||||
CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB)
|
||||
#define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000
|
||||
#define CE_INTERRUPT_SUMMARY (GENMASK(CE_COUNT_MAX - 1, 0))
|
||||
|
||||
static inline u32 ath10k_ce_interrupt_summary(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_ce *ce = ath10k_ce_priv(ar);
|
||||
|
||||
if (!ar->hw_params.per_ce_irq)
|
||||
return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(
|
||||
ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS +
|
||||
CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS));
|
||||
else
|
||||
return CE_INTERRUPT_SUMMARY;
|
||||
return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(
|
||||
ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS +
|
||||
CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS));
|
||||
}
|
||||
|
||||
/* Host software's Copy Engine configuration. */
|
||||
|
@ -119,7 +119,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -155,7 +154,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -220,7 +218,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -255,7 +252,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -290,7 +286,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -328,7 +323,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -370,7 +364,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -418,7 +411,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -463,7 +455,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -498,7 +489,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -535,7 +525,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -604,7 +593,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = 0x20,
|
||||
.target_64bit = false,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
||||
.per_ce_irq = false,
|
||||
.shadow_reg_support = false,
|
||||
.rri_on_ddr = false,
|
||||
.hw_filter_reset_required = true,
|
||||
@ -632,7 +620,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.num_wds_entries = TARGET_HL_TLV_NUM_WDS_ENTRIES,
|
||||
.target_64bit = true,
|
||||
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL_DUAL_MAC,
|
||||
.per_ce_irq = true,
|
||||
.shadow_reg_support = true,
|
||||
.rri_on_ddr = true,
|
||||
.hw_filter_reset_required = false,
|
||||
@ -741,6 +728,16 @@ static int ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ath10k_bmi_read32(ar, hi_option_flag2, ¶m);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
param |= HI_OPTION_SDIO_CRASH_DUMP_ENHANCEMENT_HOST;
|
||||
|
||||
ret = ath10k_bmi_write32(ar, hi_option_flag2, param);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2805,6 +2802,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
|
||||
if (test_bit(WMI_SERVICE_REPORT_AIRTIME, ar->wmi.svc_map))
|
||||
val |= WMI_10_4_REPORT_AIRTIME;
|
||||
|
||||
if (test_bit(WMI_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT,
|
||||
ar->wmi.svc_map))
|
||||
val |= WMI_10_4_EXT_PEER_TID_CONFIGS_SUPPORT;
|
||||
|
||||
status = ath10k_mac_ext_resource_config(ar, val);
|
||||
if (status) {
|
||||
ath10k_err(ar,
|
||||
|
@ -82,6 +82,8 @@
|
||||
/* Default Airtime weight multipler (Tuned for multiclient performance) */
|
||||
#define ATH10K_AIRTIME_WEIGHT_MULTIPLIER 4
|
||||
|
||||
#define ATH10K_MAX_RETRY_COUNT 30
|
||||
|
||||
struct ath10k;
|
||||
|
||||
static inline const char *ath10k_bus_str(enum ath10k_bus bus)
|
||||
@ -109,6 +111,7 @@ enum ath10k_skb_flags {
|
||||
ATH10K_SKB_F_MGMT = BIT(3),
|
||||
ATH10K_SKB_F_QOS = BIT(4),
|
||||
ATH10K_SKB_F_RAW_TX = BIT(5),
|
||||
ATH10K_SKB_F_NOACK_TID = BIT(6),
|
||||
};
|
||||
|
||||
struct ath10k_skb_cb {
|
||||
@ -509,6 +512,8 @@ struct ath10k_htt_tx_stats {
|
||||
u64 ack_fails;
|
||||
};
|
||||
|
||||
#define ATH10K_TID_MAX 8
|
||||
|
||||
struct ath10k_sta {
|
||||
struct ath10k_vif *arvif;
|
||||
|
||||
@ -542,6 +547,13 @@ struct ath10k_sta {
|
||||
#endif
|
||||
/* Protected with ar->data_lock */
|
||||
u32 peer_ps_state;
|
||||
struct work_struct tid_config_wk;
|
||||
int noack[ATH10K_TID_MAX];
|
||||
int retry_long[ATH10K_TID_MAX];
|
||||
int ampdu[ATH10K_TID_MAX];
|
||||
u8 rate_ctrl[ATH10K_TID_MAX];
|
||||
u32 rate_code[ATH10K_TID_MAX];
|
||||
int rtscts[ATH10K_TID_MAX];
|
||||
};
|
||||
|
||||
#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ)
|
||||
@ -614,6 +626,14 @@ struct ath10k_vif {
|
||||
/* For setting VHT peer fixed rate, protected by conf_mutex */
|
||||
int vht_num_rates;
|
||||
u8 vht_pfr;
|
||||
u32 tid_conf_changed[ATH10K_TID_MAX];
|
||||
int noack[ATH10K_TID_MAX];
|
||||
int retry_long[ATH10K_TID_MAX];
|
||||
int ampdu[ATH10K_TID_MAX];
|
||||
u8 rate_ctrl[ATH10K_TID_MAX];
|
||||
u32 rate_code[ATH10K_TID_MAX];
|
||||
int rtscts[ATH10K_TID_MAX];
|
||||
u32 tids_rst;
|
||||
};
|
||||
|
||||
struct ath10k_vif_iter {
|
||||
|
@ -270,6 +270,277 @@ static const struct ath10k_mem_section qca6174_hw21_register_sections[] = {
|
||||
{0x80010, 0x80020},
|
||||
};
|
||||
|
||||
static const struct ath10k_mem_section qca6174_hw30_sdio_register_sections[] = {
|
||||
{0x800, 0x810},
|
||||
{0x820, 0x82C},
|
||||
{0x830, 0x8F4},
|
||||
{0x90C, 0x91C},
|
||||
{0xA14, 0xA18},
|
||||
{0xA84, 0xA94},
|
||||
{0xAA8, 0xAD4},
|
||||
{0xADC, 0xB40},
|
||||
{0x1000, 0x10A4},
|
||||
{0x10BC, 0x111C},
|
||||
{0x1134, 0x1138},
|
||||
{0x1144, 0x114C},
|
||||
{0x1150, 0x115C},
|
||||
{0x1160, 0x1178},
|
||||
{0x1240, 0x1260},
|
||||
{0x2000, 0x207C},
|
||||
{0x3000, 0x3014},
|
||||
{0x4000, 0x4014},
|
||||
{0x5000, 0x5124},
|
||||
{0x6000, 0x6040},
|
||||
{0x6080, 0x60CC},
|
||||
{0x6100, 0x611C},
|
||||
{0x6140, 0x61D8},
|
||||
{0x6200, 0x6238},
|
||||
{0x6240, 0x628C},
|
||||
{0x62C0, 0x62EC},
|
||||
{0x6380, 0x63E8},
|
||||
{0x6400, 0x6440},
|
||||
{0x6480, 0x64CC},
|
||||
{0x6500, 0x651C},
|
||||
{0x6540, 0x6580},
|
||||
{0x6600, 0x6638},
|
||||
{0x6640, 0x668C},
|
||||
{0x66C0, 0x66EC},
|
||||
{0x6780, 0x67E8},
|
||||
{0x7080, 0x708C},
|
||||
{0x70C0, 0x70C8},
|
||||
{0x7400, 0x741C},
|
||||
{0x7440, 0x7454},
|
||||
{0x7800, 0x7818},
|
||||
{0x8010, 0x8060},
|
||||
{0x8080, 0x8084},
|
||||
{0x80A0, 0x80A4},
|
||||
{0x80C0, 0x80C4},
|
||||
{0x80E0, 0x80ec},
|
||||
{0x8110, 0x8128},
|
||||
{0x9000, 0x9004},
|
||||
{0xF000, 0xF0E0},
|
||||
{0xF140, 0xF190},
|
||||
{0xF250, 0xF25C},
|
||||
{0xF260, 0xF268},
|
||||
{0xF26C, 0xF2A8},
|
||||
{0x10008, 0x1000C},
|
||||
{0x10014, 0x10018},
|
||||
{0x1001C, 0x10020},
|
||||
{0x10024, 0x10028},
|
||||
{0x10030, 0x10034},
|
||||
{0x10040, 0x10054},
|
||||
{0x10058, 0x1007C},
|
||||
{0x10080, 0x100C4},
|
||||
{0x100C8, 0x10114},
|
||||
{0x1012C, 0x10130},
|
||||
{0x10138, 0x10144},
|
||||
{0x10200, 0x10220},
|
||||
{0x10230, 0x10250},
|
||||
{0x10260, 0x10280},
|
||||
{0x10290, 0x102B0},
|
||||
{0x102C0, 0x102DC},
|
||||
{0x102E0, 0x102F4},
|
||||
{0x102FC, 0x1037C},
|
||||
{0x10380, 0x10390},
|
||||
{0x10800, 0x10828},
|
||||
{0x10840, 0x10844},
|
||||
{0x10880, 0x10884},
|
||||
{0x108C0, 0x108E8},
|
||||
{0x10900, 0x10928},
|
||||
{0x10940, 0x10944},
|
||||
{0x10980, 0x10984},
|
||||
{0x109C0, 0x109E8},
|
||||
{0x10A00, 0x10A28},
|
||||
{0x10A40, 0x10A50},
|
||||
{0x11000, 0x11028},
|
||||
{0x11030, 0x11034},
|
||||
{0x11038, 0x11068},
|
||||
{0x11070, 0x11074},
|
||||
{0x11078, 0x110A8},
|
||||
{0x110B0, 0x110B4},
|
||||
{0x110B8, 0x110E8},
|
||||
{0x110F0, 0x110F4},
|
||||
{0x110F8, 0x11128},
|
||||
{0x11138, 0x11144},
|
||||
{0x11178, 0x11180},
|
||||
{0x111B8, 0x111C0},
|
||||
{0x111F8, 0x11200},
|
||||
{0x11238, 0x1123C},
|
||||
{0x11270, 0x11274},
|
||||
{0x11278, 0x1127C},
|
||||
{0x112B0, 0x112B4},
|
||||
{0x112B8, 0x112BC},
|
||||
{0x112F0, 0x112F4},
|
||||
{0x112F8, 0x112FC},
|
||||
{0x11338, 0x1133C},
|
||||
{0x11378, 0x1137C},
|
||||
{0x113B8, 0x113BC},
|
||||
{0x113F8, 0x113FC},
|
||||
{0x11438, 0x11440},
|
||||
{0x11478, 0x11480},
|
||||
{0x114B8, 0x114BC},
|
||||
{0x114F8, 0x114FC},
|
||||
{0x11538, 0x1153C},
|
||||
{0x11578, 0x1157C},
|
||||
{0x115B8, 0x115BC},
|
||||
{0x115F8, 0x115FC},
|
||||
{0x11638, 0x1163C},
|
||||
{0x11678, 0x1167C},
|
||||
{0x116B8, 0x116BC},
|
||||
{0x116F8, 0x116FC},
|
||||
{0x11738, 0x1173C},
|
||||
{0x11778, 0x1177C},
|
||||
{0x117B8, 0x117BC},
|
||||
{0x117F8, 0x117FC},
|
||||
{0x17000, 0x1701C},
|
||||
{0x17020, 0x170AC},
|
||||
{0x18000, 0x18050},
|
||||
{0x18054, 0x18074},
|
||||
{0x18080, 0x180D4},
|
||||
{0x180DC, 0x18104},
|
||||
{0x18108, 0x1813C},
|
||||
{0x18144, 0x18148},
|
||||
{0x18168, 0x18174},
|
||||
{0x18178, 0x18180},
|
||||
{0x181C8, 0x181E0},
|
||||
{0x181E4, 0x181E8},
|
||||
{0x181EC, 0x1820C},
|
||||
{0x1825C, 0x18280},
|
||||
{0x18284, 0x18290},
|
||||
{0x18294, 0x182A0},
|
||||
{0x18300, 0x18304},
|
||||
{0x18314, 0x18320},
|
||||
{0x18328, 0x18350},
|
||||
{0x1835C, 0x1836C},
|
||||
{0x18370, 0x18390},
|
||||
{0x18398, 0x183AC},
|
||||
{0x183BC, 0x183D8},
|
||||
{0x183DC, 0x183F4},
|
||||
{0x18400, 0x186F4},
|
||||
{0x186F8, 0x1871C},
|
||||
{0x18720, 0x18790},
|
||||
{0x19800, 0x19830},
|
||||
{0x19834, 0x19840},
|
||||
{0x19880, 0x1989C},
|
||||
{0x198A4, 0x198B0},
|
||||
{0x198BC, 0x19900},
|
||||
{0x19C00, 0x19C88},
|
||||
{0x19D00, 0x19D20},
|
||||
{0x19E00, 0x19E7C},
|
||||
{0x19E80, 0x19E94},
|
||||
{0x19E98, 0x19EAC},
|
||||
{0x19EB0, 0x19EBC},
|
||||
{0x19F70, 0x19F74},
|
||||
{0x19F80, 0x19F8C},
|
||||
{0x19FA0, 0x19FB4},
|
||||
{0x19FC0, 0x19FD8},
|
||||
{0x1A000, 0x1A200},
|
||||
{0x1A204, 0x1A210},
|
||||
{0x1A228, 0x1A22C},
|
||||
{0x1A230, 0x1A248},
|
||||
{0x1A250, 0x1A270},
|
||||
{0x1A280, 0x1A290},
|
||||
{0x1A2A0, 0x1A2A4},
|
||||
{0x1A2C0, 0x1A2EC},
|
||||
{0x1A300, 0x1A3BC},
|
||||
{0x1A3F0, 0x1A3F4},
|
||||
{0x1A3F8, 0x1A434},
|
||||
{0x1A438, 0x1A444},
|
||||
{0x1A448, 0x1A468},
|
||||
{0x1A580, 0x1A58C},
|
||||
{0x1A644, 0x1A654},
|
||||
{0x1A670, 0x1A698},
|
||||
{0x1A6AC, 0x1A6B0},
|
||||
{0x1A6D0, 0x1A6D4},
|
||||
{0x1A6EC, 0x1A70C},
|
||||
{0x1A710, 0x1A738},
|
||||
{0x1A7C0, 0x1A7D0},
|
||||
{0x1A7D4, 0x1A7D8},
|
||||
{0x1A7DC, 0x1A7E4},
|
||||
{0x1A7F0, 0x1A7F8},
|
||||
{0x1A888, 0x1A89C},
|
||||
{0x1A8A8, 0x1A8AC},
|
||||
{0x1A8C0, 0x1A8DC},
|
||||
{0x1A8F0, 0x1A8FC},
|
||||
{0x1AE04, 0x1AE08},
|
||||
{0x1AE18, 0x1AE24},
|
||||
{0x1AF80, 0x1AF8C},
|
||||
{0x1AFA0, 0x1AFB4},
|
||||
{0x1B000, 0x1B200},
|
||||
{0x1B284, 0x1B288},
|
||||
{0x1B2D0, 0x1B2D8},
|
||||
{0x1B2DC, 0x1B2EC},
|
||||
{0x1B300, 0x1B340},
|
||||
{0x1B374, 0x1B378},
|
||||
{0x1B380, 0x1B384},
|
||||
{0x1B388, 0x1B38C},
|
||||
{0x1B404, 0x1B408},
|
||||
{0x1B420, 0x1B428},
|
||||
{0x1B440, 0x1B444},
|
||||
{0x1B448, 0x1B44C},
|
||||
{0x1B450, 0x1B458},
|
||||
{0x1B45C, 0x1B468},
|
||||
{0x1B584, 0x1B58C},
|
||||
{0x1B68C, 0x1B690},
|
||||
{0x1B6AC, 0x1B6B0},
|
||||
{0x1B7F0, 0x1B7F8},
|
||||
{0x1C800, 0x1CC00},
|
||||
{0x1CE00, 0x1CE04},
|
||||
{0x1CF80, 0x1CF84},
|
||||
{0x1D200, 0x1D800},
|
||||
{0x1E000, 0x20014},
|
||||
{0x20100, 0x20124},
|
||||
{0x21400, 0x217A8},
|
||||
{0x21800, 0x21BA8},
|
||||
{0x21C00, 0x21FA8},
|
||||
{0x22000, 0x223A8},
|
||||
{0x22400, 0x227A8},
|
||||
{0x22800, 0x22BA8},
|
||||
{0x22C00, 0x22FA8},
|
||||
{0x23000, 0x233A8},
|
||||
{0x24000, 0x24034},
|
||||
|
||||
/* EFUSE0,1,2 is disabled here
|
||||
* because its state may be reset
|
||||
*
|
||||
* {0x24800, 0x24804},
|
||||
* {0x25000, 0x25004},
|
||||
* {0x25800, 0x25804},
|
||||
*/
|
||||
|
||||
{0x26000, 0x26064},
|
||||
{0x27000, 0x27024},
|
||||
{0x34000, 0x3400C},
|
||||
{0x34400, 0x3445C},
|
||||
{0x34800, 0x3485C},
|
||||
{0x34C00, 0x34C5C},
|
||||
{0x35000, 0x3505C},
|
||||
{0x35400, 0x3545C},
|
||||
{0x35800, 0x3585C},
|
||||
{0x35C00, 0x35C5C},
|
||||
{0x36000, 0x3605C},
|
||||
{0x38000, 0x38064},
|
||||
{0x38070, 0x380E0},
|
||||
{0x3A000, 0x3A074},
|
||||
|
||||
/* DBI windows is skipped here, it can be only accessed when pcie
|
||||
* is active (not in reset) and CORE_CTRL_PCIE_LTSSM_EN = 0 &&
|
||||
* PCIE_CTRL_APP_LTSSM_ENALBE=0.
|
||||
* {0x3C000 , 0x3C004},
|
||||
*/
|
||||
|
||||
{0x40000, 0x400A4},
|
||||
|
||||
/* SI register is skiped here.
|
||||
* Because it will cause bus hang
|
||||
*
|
||||
* {0x50000, 0x50018},
|
||||
*/
|
||||
|
||||
{0x80000, 0x8000C},
|
||||
{0x80010, 0x80020},
|
||||
};
|
||||
|
||||
static const struct ath10k_mem_section qca6174_hw30_register_sections[] = {
|
||||
{0x800, 0x810},
|
||||
{0x820, 0x82C},
|
||||
@ -602,6 +873,59 @@ static const struct ath10k_mem_region qca6174_hw21_mem_regions[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ath10k_mem_region qca6174_hw30_sdio_mem_regions[] = {
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_DRAM,
|
||||
.start = 0x400000,
|
||||
.len = 0xa8000,
|
||||
.name = "DRAM",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_AXI,
|
||||
.start = 0xa0000,
|
||||
.len = 0x18000,
|
||||
.name = "AXI",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_IRAM1,
|
||||
.start = 0x00980000,
|
||||
.len = 0x00080000,
|
||||
.name = "IRAM1",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_IRAM2,
|
||||
.start = 0x00a00000,
|
||||
.len = 0x00040000,
|
||||
.name = "IRAM2",
|
||||
.section_table = {
|
||||
.sections = NULL,
|
||||
.size = 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_REG,
|
||||
.start = 0x800,
|
||||
.len = 0x80020 - 0x800,
|
||||
.name = "REG_TOTAL",
|
||||
.section_table = {
|
||||
.sections = qca6174_hw30_sdio_register_sections,
|
||||
.size = ARRAY_SIZE(qca6174_hw30_sdio_register_sections),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ath10k_mem_region qca6174_hw30_mem_regions[] = {
|
||||
{
|
||||
.type = ATH10K_MEM_REGION_TYPE_DRAM,
|
||||
@ -968,6 +1292,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA6174_HW_1_0_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA6174,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca6174_hw10_mem_regions,
|
||||
.size = ARRAY_SIZE(qca6174_hw10_mem_regions),
|
||||
@ -976,6 +1301,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA6174_HW_1_1_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA6174,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca6174_hw10_mem_regions,
|
||||
.size = ARRAY_SIZE(qca6174_hw10_mem_regions),
|
||||
@ -984,6 +1310,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA6174_HW_1_3_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA6174,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca6174_hw10_mem_regions,
|
||||
.size = ARRAY_SIZE(qca6174_hw10_mem_regions),
|
||||
@ -992,6 +1319,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA6174_HW_2_1_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA6174,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca6174_hw21_mem_regions,
|
||||
.size = ARRAY_SIZE(qca6174_hw21_mem_regions),
|
||||
@ -1000,6 +1328,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA6174_HW_3_0_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA6174,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca6174_hw30_mem_regions,
|
||||
.size = ARRAY_SIZE(qca6174_hw30_mem_regions),
|
||||
@ -1008,14 +1337,25 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA6174_HW_3_2_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA6174,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca6174_hw30_mem_regions,
|
||||
.size = ARRAY_SIZE(qca6174_hw30_mem_regions),
|
||||
},
|
||||
},
|
||||
{
|
||||
.hw_id = QCA6174_HW_3_2_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA6174,
|
||||
.bus = ATH10K_BUS_SDIO,
|
||||
.region_table = {
|
||||
.regions = qca6174_hw30_sdio_mem_regions,
|
||||
.size = ARRAY_SIZE(qca6174_hw30_sdio_mem_regions),
|
||||
},
|
||||
},
|
||||
{
|
||||
.hw_id = QCA9377_HW_1_1_DEV_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA9377,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca6174_hw30_mem_regions,
|
||||
.size = ARRAY_SIZE(qca6174_hw30_mem_regions),
|
||||
@ -1024,6 +1364,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA988X_HW_2_0_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA988X,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca988x_hw20_mem_regions,
|
||||
.size = ARRAY_SIZE(qca988x_hw20_mem_regions),
|
||||
@ -1032,6 +1373,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA9984_HW_1_0_DEV_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA9984,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca9984_hw10_mem_regions,
|
||||
.size = ARRAY_SIZE(qca9984_hw10_mem_regions),
|
||||
@ -1040,6 +1382,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA9888_HW_2_0_DEV_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA9888,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca9984_hw10_mem_regions,
|
||||
.size = ARRAY_SIZE(qca9984_hw10_mem_regions),
|
||||
@ -1048,6 +1391,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA99X0_HW_2_0_DEV_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA99X0,
|
||||
.bus = ATH10K_BUS_PCI,
|
||||
.region_table = {
|
||||
.regions = qca99x0_hw20_mem_regions,
|
||||
.size = ARRAY_SIZE(qca99x0_hw20_mem_regions),
|
||||
@ -1056,6 +1400,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = QCA4019_HW_1_0_DEV_VERSION,
|
||||
.hw_rev = ATH10K_HW_QCA4019,
|
||||
.bus = ATH10K_BUS_AHB,
|
||||
.region_table = {
|
||||
.regions = qca4019_hw10_mem_regions,
|
||||
.size = ARRAY_SIZE(qca4019_hw10_mem_regions),
|
||||
@ -1064,6 +1409,7 @@ static const struct ath10k_hw_mem_layout hw_mem_layouts[] = {
|
||||
{
|
||||
.hw_id = WCN3990_HW_1_0_DEV_VERSION,
|
||||
.hw_rev = ATH10K_HW_WCN3990,
|
||||
.bus = ATH10K_BUS_SNOC,
|
||||
.region_table = {
|
||||
.regions = wcn399x_hw10_mem_regions,
|
||||
.size = ARRAY_SIZE(wcn399x_hw10_mem_regions),
|
||||
@ -1111,7 +1457,8 @@ const struct ath10k_hw_mem_layout *ath10k_coredump_get_mem_layout(struct ath10k
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hw_mem_layouts); i++) {
|
||||
if (ar->target_version == hw_mem_layouts[i].hw_id &&
|
||||
ar->hw_rev == hw_mem_layouts[i].hw_rev)
|
||||
ar->hw_rev == hw_mem_layouts[i].hw_rev &&
|
||||
hw_mem_layouts[i].bus == ar->hif.bus)
|
||||
return &hw_mem_layouts[i];
|
||||
}
|
||||
|
||||
|
@ -156,6 +156,7 @@ struct ath10k_mem_region {
|
||||
struct ath10k_hw_mem_layout {
|
||||
u32 hw_id;
|
||||
u32 hw_rev;
|
||||
enum ath10k_bus bus;
|
||||
|
||||
struct {
|
||||
const struct ath10k_mem_region *regions;
|
||||
|
@ -593,9 +593,6 @@ struct ath10k_hw_params {
|
||||
/* Target rx ring fill level */
|
||||
u32 rx_ring_fill_level;
|
||||
|
||||
/* target supporting per ce IRQ */
|
||||
bool per_ce_irq;
|
||||
|
||||
/* target supporting shadow register for ce write */
|
||||
bool shadow_reg_support;
|
||||
|
||||
|
@ -3013,6 +3013,69 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
|
||||
cancel_delayed_work_sync(&arvif->connection_loss_work);
|
||||
}
|
||||
|
||||
static int ath10k_new_peer_tid_config(struct ath10k *ar,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ath10k_vif *arvif)
|
||||
{
|
||||
struct wmi_per_peer_per_tid_cfg_arg arg = {};
|
||||
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
bool config_apply;
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; i < ATH10K_TID_MAX; i++) {
|
||||
config_apply = false;
|
||||
if (arvif->retry_long[i] || arvif->ampdu[i] ||
|
||||
arvif->rate_ctrl[i] || arvif->rtscts[i]) {
|
||||
config_apply = true;
|
||||
arg.tid = i;
|
||||
arg.vdev_id = arvif->vdev_id;
|
||||
arg.retry_count = arvif->retry_long[i];
|
||||
arg.aggr_control = arvif->ampdu[i];
|
||||
arg.rate_ctrl = arvif->rate_ctrl[i];
|
||||
arg.rcode_flags = arvif->rate_code[i];
|
||||
|
||||
if (arvif->rtscts[i])
|
||||
arg.ext_tid_cfg_bitmap =
|
||||
WMI_EXT_TID_RTS_CTS_CONFIG;
|
||||
else
|
||||
arg.ext_tid_cfg_bitmap = 0;
|
||||
|
||||
arg.rtscts_ctrl = arvif->rtscts[i];
|
||||
}
|
||||
|
||||
if (arvif->noack[i]) {
|
||||
arg.ack_policy = arvif->noack[i];
|
||||
arg.rate_ctrl = WMI_TID_CONFIG_RATE_CONTROL_DEFAULT_LOWEST_RATE;
|
||||
arg.aggr_control = WMI_TID_CONFIG_AGGR_CONTROL_DISABLE;
|
||||
config_apply = true;
|
||||
}
|
||||
|
||||
/* Assign default value(-1) to newly connected station.
|
||||
* This is to identify station specific tid configuration not
|
||||
* configured for the station.
|
||||
*/
|
||||
arsta->retry_long[i] = -1;
|
||||
arsta->noack[i] = -1;
|
||||
arsta->ampdu[i] = -1;
|
||||
|
||||
if (!config_apply)
|
||||
continue;
|
||||
|
||||
ether_addr_copy(arg.peer_macaddr.addr, sta->addr);
|
||||
|
||||
ret = ath10k_wmi_set_per_peer_per_tid_cfg(ar, &arg);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to set per tid retry/aggr config for sta %pM: %d\n",
|
||||
sta->addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_station_assoc(struct ath10k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@ -3078,7 +3141,10 @@ static int ath10k_station_assoc(struct ath10k *ar,
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (!test_bit(WMI_SERVICE_PEER_TID_CONFIGS_SUPPORT, ar->wmi.svc_map))
|
||||
return ret;
|
||||
|
||||
return ath10k_new_peer_tid_config(ar, sta, arvif);
|
||||
}
|
||||
|
||||
static int ath10k_station_disassoc(struct ath10k *ar,
|
||||
@ -3626,7 +3692,10 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
|
||||
const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
bool is_data = ieee80211_is_data(hdr->frame_control) ||
|
||||
ieee80211_is_data_qos(hdr->frame_control);
|
||||
struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
struct ath10k_sta *arsta;
|
||||
u8 tid, *qos_ctl;
|
||||
bool noack = false;
|
||||
|
||||
cb->flags = 0;
|
||||
if (!ath10k_tx_h_use_hwcrypto(vif, skb))
|
||||
@ -3635,8 +3704,27 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
|
||||
if (ieee80211_is_mgmt(hdr->frame_control))
|
||||
cb->flags |= ATH10K_SKB_F_MGMT;
|
||||
|
||||
if (ieee80211_is_data_qos(hdr->frame_control))
|
||||
if (ieee80211_is_data_qos(hdr->frame_control)) {
|
||||
cb->flags |= ATH10K_SKB_F_QOS;
|
||||
qos_ctl = ieee80211_get_qos_ctl(hdr);
|
||||
tid = (*qos_ctl) & IEEE80211_QOS_CTL_TID_MASK;
|
||||
|
||||
if (arvif->noack[tid] == WMI_PEER_TID_CONFIG_NOACK)
|
||||
noack = true;
|
||||
|
||||
if (sta) {
|
||||
arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
|
||||
if (arsta->noack[tid] == WMI_PEER_TID_CONFIG_NOACK)
|
||||
noack = true;
|
||||
|
||||
if (arsta->noack[tid] == WMI_PEER_TID_CONFIG_ACK)
|
||||
noack = false;
|
||||
}
|
||||
|
||||
if (noack)
|
||||
cb->flags |= ATH10K_SKB_F_NOACK_TID;
|
||||
}
|
||||
|
||||
/* Data frames encrypted in software will be posted to firmware
|
||||
* with tx encap mode set to RAW. Ex: Multicast traffic generated
|
||||
@ -6597,6 +6685,581 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct ath10k_mac_iter_tid_conf_data {
|
||||
struct ieee80211_vif *curr_vif;
|
||||
struct ath10k *ar;
|
||||
bool reset_config;
|
||||
};
|
||||
|
||||
static bool
|
||||
ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
|
||||
enum nl80211_band band,
|
||||
const struct cfg80211_bitrate_mask *mask,
|
||||
int *vht_num_rates)
|
||||
{
|
||||
int num_rates = 0;
|
||||
int i, tmp;
|
||||
|
||||
num_rates += hweight32(mask->control[band].legacy);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
|
||||
num_rates += hweight8(mask->control[band].ht_mcs[i]);
|
||||
|
||||
*vht_num_rates = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
|
||||
tmp = hweight16(mask->control[band].vht_mcs[i]);
|
||||
num_rates += tmp;
|
||||
*vht_num_rates += tmp;
|
||||
}
|
||||
|
||||
return num_rates == 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
|
||||
enum nl80211_band band,
|
||||
const struct cfg80211_bitrate_mask *mask,
|
||||
u8 *rate, u8 *nss, bool vht_only)
|
||||
{
|
||||
int rate_idx;
|
||||
int i;
|
||||
u16 bitrate;
|
||||
u8 preamble;
|
||||
u8 hw_rate;
|
||||
|
||||
if (vht_only)
|
||||
goto next;
|
||||
|
||||
if (hweight32(mask->control[band].legacy) == 1) {
|
||||
rate_idx = ffs(mask->control[band].legacy) - 1;
|
||||
|
||||
if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
|
||||
rate_idx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
|
||||
|
||||
hw_rate = ath10k_wmi_legacy_rates[rate_idx].hw_value;
|
||||
bitrate = ath10k_wmi_legacy_rates[rate_idx].bitrate;
|
||||
|
||||
if (ath10k_mac_bitrate_is_cck(bitrate))
|
||||
preamble = WMI_RATE_PREAMBLE_CCK;
|
||||
else
|
||||
preamble = WMI_RATE_PREAMBLE_OFDM;
|
||||
|
||||
*nss = 1;
|
||||
*rate = preamble << 6 |
|
||||
(*nss - 1) << 4 |
|
||||
hw_rate << 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
|
||||
if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
|
||||
*nss = i + 1;
|
||||
*rate = WMI_RATE_PREAMBLE_HT << 6 |
|
||||
(*nss - 1) << 4 |
|
||||
(ffs(mask->control[band].ht_mcs[i]) - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
next:
|
||||
for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
|
||||
if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
|
||||
*nss = i + 1;
|
||||
*rate = WMI_RATE_PREAMBLE_VHT << 6 |
|
||||
(*nss - 1) << 4 |
|
||||
(ffs(mask->control[band].vht_mcs[i]) - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int ath10k_mac_validate_rate_mask(struct ath10k *ar,
|
||||
struct ieee80211_sta *sta,
|
||||
u32 rate_ctrl_flag, u8 nss)
|
||||
{
|
||||
if (nss > sta->rx_nss) {
|
||||
ath10k_warn(ar, "Invalid nss field, configured %u limit %u\n",
|
||||
nss, sta->rx_nss);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ATH10K_HW_PREAMBLE(rate_ctrl_flag) == WMI_RATE_PREAMBLE_VHT) {
|
||||
if (!sta->vht_cap.vht_supported) {
|
||||
ath10k_warn(ar, "Invalid VHT rate for sta %pM\n",
|
||||
sta->addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else if (ATH10K_HW_PREAMBLE(rate_ctrl_flag) == WMI_RATE_PREAMBLE_HT) {
|
||||
if (!sta->ht_cap.ht_supported || sta->vht_cap.vht_supported) {
|
||||
ath10k_warn(ar, "Invalid HT rate for sta %pM\n",
|
||||
sta->addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (sta->ht_cap.ht_supported || sta->vht_cap.vht_supported)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ath10k_mac_tid_bitrate_config(struct ath10k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
u32 *rate_ctrl_flag, u8 *rate_ctrl,
|
||||
enum nl80211_tx_rate_setting txrate_type,
|
||||
const struct cfg80211_bitrate_mask *mask)
|
||||
{
|
||||
struct cfg80211_chan_def def;
|
||||
enum nl80211_band band;
|
||||
u8 nss, rate;
|
||||
int vht_num_rates, ret;
|
||||
|
||||
if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
|
||||
return -EINVAL;
|
||||
|
||||
if (txrate_type == NL80211_TX_RATE_AUTOMATIC) {
|
||||
*rate_ctrl = WMI_TID_CONFIG_RATE_CONTROL_AUTO;
|
||||
*rate_ctrl_flag = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
band = def.chan->band;
|
||||
|
||||
if (!ath10k_mac_bitrate_mask_has_single_rate(ar, band, mask,
|
||||
&vht_num_rates)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ath10k_mac_bitrate_mask_get_single_rate(ar, band, mask,
|
||||
&rate, &nss, false);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to get single rate: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*rate_ctrl_flag = rate;
|
||||
|
||||
if (sta && ath10k_mac_validate_rate_mask(ar, sta, *rate_ctrl_flag, nss))
|
||||
return -EINVAL;
|
||||
|
||||
if (txrate_type == NL80211_TX_RATE_FIXED)
|
||||
*rate_ctrl = WMI_TID_CONFIG_RATE_CONTROL_FIXED_RATE;
|
||||
else if (txrate_type == NL80211_TX_RATE_LIMITED &&
|
||||
(test_bit(WMI_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT,
|
||||
ar->wmi.svc_map)))
|
||||
*rate_ctrl = WMI_PEER_TID_CONFIG_RATE_UPPER_CAP;
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_mac_set_tid_config(struct ath10k *ar, struct ieee80211_sta *sta,
|
||||
struct ieee80211_vif *vif, u32 changed,
|
||||
struct wmi_per_peer_per_tid_cfg_arg *arg)
|
||||
{
|
||||
struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
struct ath10k_sta *arsta;
|
||||
int ret;
|
||||
|
||||
if (sta) {
|
||||
if (!sta->wme)
|
||||
return -ENOTSUPP;
|
||||
|
||||
arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_NOACK)) {
|
||||
if ((arsta->retry_long[arg->tid] > 0 ||
|
||||
arsta->rate_code[arg->tid] > 0 ||
|
||||
arsta->ampdu[arg->tid] ==
|
||||
WMI_TID_CONFIG_AGGR_CONTROL_ENABLE) &&
|
||||
arg->ack_policy == WMI_PEER_TID_CONFIG_NOACK) {
|
||||
changed &= ~BIT(NL80211_TID_CONFIG_ATTR_NOACK);
|
||||
arg->ack_policy = 0;
|
||||
arg->aggr_control = 0;
|
||||
arg->rate_ctrl = 0;
|
||||
arg->rcode_flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) {
|
||||
if (arsta->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK ||
|
||||
arvif->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK) {
|
||||
arg->aggr_control = 0;
|
||||
changed &= ~BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & (BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE))) {
|
||||
if (arsta->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK ||
|
||||
arvif->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK) {
|
||||
arg->rate_ctrl = 0;
|
||||
arg->rcode_flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ether_addr_copy(arg->peer_macaddr.addr, sta->addr);
|
||||
|
||||
ret = ath10k_wmi_set_per_peer_per_tid_cfg(ar, arg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Store the configured parameters in success case */
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_NOACK)) {
|
||||
arsta->noack[arg->tid] = arg->ack_policy;
|
||||
arg->ack_policy = 0;
|
||||
arg->aggr_control = 0;
|
||||
arg->rate_ctrl = 0;
|
||||
arg->rcode_flags = 0;
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG)) {
|
||||
arsta->retry_long[arg->tid] = arg->retry_count;
|
||||
arg->retry_count = 0;
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) {
|
||||
arsta->ampdu[arg->tid] = arg->aggr_control;
|
||||
arg->aggr_control = 0;
|
||||
}
|
||||
|
||||
if (changed & (BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE))) {
|
||||
arsta->rate_ctrl[arg->tid] = arg->rate_ctrl;
|
||||
arg->rate_ctrl = 0;
|
||||
arg->rcode_flags = 0;
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL)) {
|
||||
arsta->rtscts[arg->tid] = arg->rtscts_ctrl;
|
||||
arg->ext_tid_cfg_bitmap = 0;
|
||||
}
|
||||
} else {
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_NOACK)) {
|
||||
if ((arvif->retry_long[arg->tid] ||
|
||||
arvif->rate_code[arg->tid] ||
|
||||
arvif->ampdu[arg->tid] ==
|
||||
WMI_TID_CONFIG_AGGR_CONTROL_ENABLE) &&
|
||||
arg->ack_policy == WMI_PEER_TID_CONFIG_NOACK) {
|
||||
changed &= ~BIT(NL80211_TID_CONFIG_ATTR_NOACK);
|
||||
} else {
|
||||
arvif->noack[arg->tid] = arg->ack_policy;
|
||||
arvif->ampdu[arg->tid] = arg->aggr_control;
|
||||
arvif->rate_ctrl[arg->tid] = arg->rate_ctrl;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG)) {
|
||||
if (arvif->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK)
|
||||
changed &= ~BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);
|
||||
else
|
||||
arvif->retry_long[arg->tid] = arg->retry_count;
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) {
|
||||
if (arvif->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK)
|
||||
changed &= ~BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);
|
||||
else
|
||||
arvif->ampdu[arg->tid] = arg->aggr_control;
|
||||
}
|
||||
|
||||
if (changed & (BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE))) {
|
||||
if (arvif->noack[arg->tid] == WMI_PEER_TID_CONFIG_NOACK) {
|
||||
changed &= ~(BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE));
|
||||
} else {
|
||||
arvif->rate_ctrl[arg->tid] = arg->rate_ctrl;
|
||||
arvif->rate_code[arg->tid] = arg->rcode_flags;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL)) {
|
||||
arvif->rtscts[arg->tid] = arg->rtscts_ctrl;
|
||||
arg->ext_tid_cfg_bitmap = 0;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
arvif->tid_conf_changed[arg->tid] |= changed;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ath10k_mac_parse_tid_config(struct ath10k *ar,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_tid_cfg *tid_conf,
|
||||
struct wmi_per_peer_per_tid_cfg_arg *arg)
|
||||
{
|
||||
u32 changed = tid_conf->mask;
|
||||
int ret = 0, i = 0;
|
||||
|
||||
if (!changed)
|
||||
return -EINVAL;
|
||||
|
||||
while (i < ATH10K_TID_MAX) {
|
||||
if (!(tid_conf->tids & BIT(i))) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
arg->tid = i;
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_NOACK)) {
|
||||
if (tid_conf->noack == NL80211_TID_CONFIG_ENABLE) {
|
||||
arg->ack_policy = WMI_PEER_TID_CONFIG_NOACK;
|
||||
arg->rate_ctrl =
|
||||
WMI_TID_CONFIG_RATE_CONTROL_DEFAULT_LOWEST_RATE;
|
||||
arg->aggr_control =
|
||||
WMI_TID_CONFIG_AGGR_CONTROL_DISABLE;
|
||||
} else {
|
||||
arg->ack_policy =
|
||||
WMI_PEER_TID_CONFIG_ACK;
|
||||
arg->rate_ctrl =
|
||||
WMI_TID_CONFIG_RATE_CONTROL_AUTO;
|
||||
arg->aggr_control =
|
||||
WMI_TID_CONFIG_AGGR_CONTROL_ENABLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG))
|
||||
arg->retry_count = tid_conf->retry_long;
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) {
|
||||
if (tid_conf->noack == NL80211_TID_CONFIG_ENABLE)
|
||||
arg->aggr_control = WMI_TID_CONFIG_AGGR_CONTROL_ENABLE;
|
||||
else
|
||||
arg->aggr_control = WMI_TID_CONFIG_AGGR_CONTROL_DISABLE;
|
||||
}
|
||||
|
||||
if (changed & (BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE))) {
|
||||
ret = ath10k_mac_tid_bitrate_config(ar, vif, sta,
|
||||
&arg->rcode_flags,
|
||||
&arg->rate_ctrl,
|
||||
tid_conf->txrate_type,
|
||||
&tid_conf->txrate_mask);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to configure bitrate mask %d\n",
|
||||
ret);
|
||||
arg->rcode_flags = 0;
|
||||
arg->rate_ctrl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL)) {
|
||||
if (tid_conf->rtscts)
|
||||
arg->rtscts_ctrl = tid_conf->rtscts;
|
||||
|
||||
arg->ext_tid_cfg_bitmap = WMI_EXT_TID_RTS_CTS_CONFIG;
|
||||
}
|
||||
|
||||
ret = ath10k_mac_set_tid_config(ar, sta, vif, changed, arg);
|
||||
if (ret)
|
||||
return ret;
|
||||
i++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_mac_reset_tid_config(struct ath10k *ar,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ath10k_vif *arvif,
|
||||
u8 tids)
|
||||
{
|
||||
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
struct wmi_per_peer_per_tid_cfg_arg arg;
|
||||
int ret = 0, i = 0;
|
||||
|
||||
arg.vdev_id = arvif->vdev_id;
|
||||
while (i < ATH10K_TID_MAX) {
|
||||
if (!(tids & BIT(i))) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
arg.tid = i;
|
||||
arg.ack_policy = WMI_PEER_TID_CONFIG_ACK;
|
||||
arg.retry_count = ATH10K_MAX_RETRY_COUNT;
|
||||
arg.rate_ctrl = WMI_TID_CONFIG_RATE_CONTROL_AUTO;
|
||||
arg.aggr_control = WMI_TID_CONFIG_AGGR_CONTROL_ENABLE;
|
||||
arg.rtscts_ctrl = WMI_TID_CONFIG_RTSCTS_CONTROL_ENABLE;
|
||||
arg.ext_tid_cfg_bitmap = WMI_EXT_TID_RTS_CTS_CONFIG;
|
||||
|
||||
ether_addr_copy(arg.peer_macaddr.addr, sta->addr);
|
||||
|
||||
ret = ath10k_wmi_set_per_peer_per_tid_cfg(ar, &arg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!arvif->tids_rst) {
|
||||
arsta->retry_long[i] = -1;
|
||||
arsta->noack[i] = -1;
|
||||
arsta->ampdu[i] = -1;
|
||||
arsta->rate_code[i] = -1;
|
||||
arsta->rate_ctrl[i] = 0;
|
||||
arsta->rtscts[i] = -1;
|
||||
} else {
|
||||
arvif->retry_long[i] = 0;
|
||||
arvif->noack[i] = 0;
|
||||
arvif->ampdu[i] = 0;
|
||||
arvif->rate_code[i] = 0;
|
||||
arvif->rate_ctrl[i] = 0;
|
||||
arvif->rtscts[i] = 0;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath10k_sta_tid_cfg_wk(struct work_struct *wk)
|
||||
{
|
||||
struct wmi_per_peer_per_tid_cfg_arg arg = {};
|
||||
struct ieee80211_sta *sta;
|
||||
struct ath10k_sta *arsta;
|
||||
struct ath10k_vif *arvif;
|
||||
struct ath10k *ar;
|
||||
bool config_apply;
|
||||
int ret, i;
|
||||
u32 changed;
|
||||
u8 nss;
|
||||
|
||||
arsta = container_of(wk, struct ath10k_sta, tid_config_wk);
|
||||
sta = container_of((void *)arsta, struct ieee80211_sta, drv_priv);
|
||||
arvif = arsta->arvif;
|
||||
ar = arvif->ar;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (arvif->tids_rst) {
|
||||
ret = ath10k_mac_reset_tid_config(ar, sta, arvif,
|
||||
arvif->tids_rst);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ether_addr_copy(arg.peer_macaddr.addr, sta->addr);
|
||||
|
||||
for (i = 0; i < ATH10K_TID_MAX; i++) {
|
||||
config_apply = false;
|
||||
changed = arvif->tid_conf_changed[i];
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_NOACK)) {
|
||||
if (arsta->noack[i] != -1) {
|
||||
arg.ack_policy = 0;
|
||||
} else {
|
||||
config_apply = true;
|
||||
arg.ack_policy = arvif->noack[i];
|
||||
arg.aggr_control = arvif->ampdu[i];
|
||||
arg.rate_ctrl = arvif->rate_ctrl[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG)) {
|
||||
if (arsta->retry_long[i] != -1 ||
|
||||
arsta->noack[i] == WMI_PEER_TID_CONFIG_NOACK ||
|
||||
arvif->noack[i] == WMI_PEER_TID_CONFIG_NOACK) {
|
||||
arg.retry_count = 0;
|
||||
} else {
|
||||
arg.retry_count = arvif->retry_long[i];
|
||||
config_apply = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL)) {
|
||||
if (arsta->ampdu[i] != -1 ||
|
||||
arsta->noack[i] == WMI_PEER_TID_CONFIG_NOACK ||
|
||||
arvif->noack[i] == WMI_PEER_TID_CONFIG_NOACK) {
|
||||
arg.aggr_control = 0;
|
||||
} else {
|
||||
arg.aggr_control = arvif->ampdu[i];
|
||||
config_apply = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & (BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE))) {
|
||||
nss = ATH10K_HW_NSS(arvif->rate_code[i]);
|
||||
ret = ath10k_mac_validate_rate_mask(ar, sta,
|
||||
arvif->rate_code[i],
|
||||
nss);
|
||||
if (ret &&
|
||||
arvif->rate_ctrl[i] > WMI_TID_CONFIG_RATE_CONTROL_AUTO) {
|
||||
arg.rate_ctrl = 0;
|
||||
arg.rcode_flags = 0;
|
||||
}
|
||||
|
||||
if (arsta->rate_ctrl[i] >
|
||||
WMI_TID_CONFIG_RATE_CONTROL_AUTO ||
|
||||
arsta->noack[i] == WMI_PEER_TID_CONFIG_NOACK ||
|
||||
arvif->noack[i] == WMI_PEER_TID_CONFIG_NOACK) {
|
||||
arg.rate_ctrl = 0;
|
||||
arg.rcode_flags = 0;
|
||||
} else {
|
||||
arg.rate_ctrl = arvif->rate_ctrl[i];
|
||||
arg.rcode_flags = arvif->rate_code[i];
|
||||
config_apply = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL)) {
|
||||
if (arsta->rtscts[i]) {
|
||||
arg.rtscts_ctrl = 0;
|
||||
arg.ext_tid_cfg_bitmap = 0;
|
||||
} else {
|
||||
arg.rtscts_ctrl = arvif->rtscts[i] - 1;
|
||||
arg.ext_tid_cfg_bitmap =
|
||||
WMI_EXT_TID_RTS_CTS_CONFIG;
|
||||
config_apply = true;
|
||||
}
|
||||
}
|
||||
|
||||
arg.tid = i;
|
||||
|
||||
if (config_apply) {
|
||||
ret = ath10k_wmi_set_per_peer_per_tid_cfg(ar, &arg);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to set per tid config for sta %pM: %d\n",
|
||||
sta->addr, ret);
|
||||
}
|
||||
|
||||
arg.ack_policy = 0;
|
||||
arg.retry_count = 0;
|
||||
arg.aggr_control = 0;
|
||||
arg.rate_ctrl = 0;
|
||||
arg.rcode_flags = 0;
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
static void ath10k_mac_vif_stations_tid_conf(void *data,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
struct ath10k_mac_iter_tid_conf_data *iter_data = data;
|
||||
struct ieee80211_vif *sta_vif = arsta->arvif->vif;
|
||||
|
||||
if (sta_vif != iter_data->curr_vif || !sta->wme)
|
||||
return;
|
||||
|
||||
ieee80211_queue_work(iter_data->ar->hw, &arsta->tid_config_wk);
|
||||
}
|
||||
|
||||
static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@ -6616,6 +7279,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
arsta->arvif = arvif;
|
||||
arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
|
||||
INIT_WORK(&arsta->update_wk, ath10k_sta_rc_update_wk);
|
||||
INIT_WORK(&arsta->tid_config_wk, ath10k_sta_tid_cfg_wk);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sta->txq); i++)
|
||||
ath10k_mac_txq_init(sta->txq[i]);
|
||||
@ -6623,8 +7287,10 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
|
||||
/* cancel must be done outside the mutex to avoid deadlock */
|
||||
if ((old_state == IEEE80211_STA_NONE &&
|
||||
new_state == IEEE80211_STA_NOTEXIST))
|
||||
new_state == IEEE80211_STA_NOTEXIST)) {
|
||||
cancel_work_sync(&arsta->update_wk);
|
||||
cancel_work_sync(&arsta->tid_config_wk);
|
||||
}
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
@ -7033,8 +7699,6 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define ATH10K_ROC_TIMEOUT_HZ (2 * HZ)
|
||||
|
||||
static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel *chan,
|
||||
@ -7346,30 +8010,6 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
|
||||
enum nl80211_band band,
|
||||
const struct cfg80211_bitrate_mask *mask,
|
||||
int *vht_num_rates)
|
||||
{
|
||||
int num_rates = 0;
|
||||
int i, tmp;
|
||||
|
||||
num_rates += hweight32(mask->control[band].legacy);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
|
||||
num_rates += hweight8(mask->control[band].ht_mcs[i]);
|
||||
|
||||
*vht_num_rates = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
|
||||
tmp = hweight16(mask->control[band].vht_mcs[i]);
|
||||
num_rates += tmp;
|
||||
*vht_num_rates += tmp;
|
||||
}
|
||||
|
||||
return num_rates == 1;
|
||||
}
|
||||
|
||||
static bool
|
||||
ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
|
||||
enum nl80211_band band,
|
||||
@ -7419,69 +8059,6 @@ ath10k_mac_bitrate_mask_get_single_nss(struct ath10k *ar,
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
|
||||
enum nl80211_band band,
|
||||
const struct cfg80211_bitrate_mask *mask,
|
||||
u8 *rate, u8 *nss, bool vht_only)
|
||||
{
|
||||
int rate_idx;
|
||||
int i;
|
||||
u16 bitrate;
|
||||
u8 preamble;
|
||||
u8 hw_rate;
|
||||
|
||||
if (vht_only)
|
||||
goto next;
|
||||
|
||||
if (hweight32(mask->control[band].legacy) == 1) {
|
||||
rate_idx = ffs(mask->control[band].legacy) - 1;
|
||||
|
||||
if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
|
||||
rate_idx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;
|
||||
|
||||
hw_rate = ath10k_wmi_legacy_rates[rate_idx].hw_value;
|
||||
bitrate = ath10k_wmi_legacy_rates[rate_idx].bitrate;
|
||||
|
||||
if (ath10k_mac_bitrate_is_cck(bitrate))
|
||||
preamble = WMI_RATE_PREAMBLE_CCK;
|
||||
else
|
||||
preamble = WMI_RATE_PREAMBLE_OFDM;
|
||||
|
||||
*nss = 1;
|
||||
*rate = preamble << 6 |
|
||||
(*nss - 1) << 4 |
|
||||
hw_rate << 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++) {
|
||||
if (hweight8(mask->control[band].ht_mcs[i]) == 1) {
|
||||
*nss = i + 1;
|
||||
*rate = WMI_RATE_PREAMBLE_HT << 6 |
|
||||
(*nss - 1) << 4 |
|
||||
(ffs(mask->control[band].ht_mcs[i]) - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
next:
|
||||
for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
|
||||
if (hweight16(mask->control[band].vht_mcs[i]) == 1) {
|
||||
*nss = i + 1;
|
||||
*rate = WMI_RATE_PREAMBLE_VHT << 6 |
|
||||
(*nss - 1) << 4 |
|
||||
(ffs(mask->control[band].vht_mcs[i]) - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int ath10k_mac_set_fixed_rate_params(struct ath10k_vif *arvif,
|
||||
u8 rate, u8 nss, u8 sgi, u8 ldpc)
|
||||
{
|
||||
@ -8567,6 +9144,76 @@ static void ath10k_sta_statistics(struct ieee80211_hw *hw,
|
||||
ath10k_mac_sta_get_peer_stats_info(ar, sta, sinfo);
|
||||
}
|
||||
|
||||
static int ath10k_mac_op_set_tid_config(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct cfg80211_tid_config *tid_config)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
struct ath10k_mac_iter_tid_conf_data data = {};
|
||||
struct wmi_per_peer_per_tid_cfg_arg arg = {};
|
||||
int ret, i;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
arg.vdev_id = arvif->vdev_id;
|
||||
|
||||
arvif->tids_rst = 0;
|
||||
memset(arvif->tid_conf_changed, 0, sizeof(arvif->tid_conf_changed));
|
||||
|
||||
for (i = 0; i < tid_config->n_tid_conf; i++) {
|
||||
ret = ath10k_mac_parse_tid_config(ar, sta, vif,
|
||||
&tid_config->tid_conf[i],
|
||||
&arg);
|
||||
if (ret)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (sta)
|
||||
goto exit;
|
||||
|
||||
ret = 0;
|
||||
arvif->tids_rst = 0;
|
||||
data.curr_vif = vif;
|
||||
data.ar = ar;
|
||||
|
||||
ieee80211_iterate_stations_atomic(hw, ath10k_mac_vif_stations_tid_conf,
|
||||
&data);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_mac_op_reset_tid_config(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
u8 tids)
|
||||
{
|
||||
struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
struct ath10k_mac_iter_tid_conf_data data = {};
|
||||
struct ath10k *ar = hw->priv;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (sta) {
|
||||
arvif->tids_rst = 0;
|
||||
ret = ath10k_mac_reset_tid_config(ar, sta, arvif, tids);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
arvif->tids_rst = tids;
|
||||
data.curr_vif = vif;
|
||||
data.ar = ar;
|
||||
ieee80211_iterate_stations_atomic(hw, ath10k_mac_vif_stations_tid_conf,
|
||||
&data);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct ieee80211_ops ath10k_ops = {
|
||||
.tx = ath10k_mac_op_tx,
|
||||
.wake_tx_queue = ath10k_mac_op_wake_tx_queue,
|
||||
@ -8610,6 +9257,8 @@ static const struct ieee80211_ops ath10k_ops = {
|
||||
.switch_vif_chanctx = ath10k_mac_op_switch_vif_chanctx,
|
||||
.sta_pre_rcu_remove = ath10k_mac_op_sta_pre_rcu_remove,
|
||||
.sta_statistics = ath10k_sta_statistics,
|
||||
.set_tid_config = ath10k_mac_op_set_tid_config,
|
||||
.reset_tid_config = ath10k_mac_op_reset_tid_config,
|
||||
|
||||
CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
|
||||
|
||||
@ -9280,6 +9929,28 @@ int ath10k_mac_register(struct ath10k *ar)
|
||||
if (test_bit(WMI_SERVICE_TX_PWR_PER_PEER, ar->wmi.svc_map))
|
||||
wiphy_ext_feature_set(ar->hw->wiphy,
|
||||
NL80211_EXT_FEATURE_STA_TX_PWR);
|
||||
|
||||
if (test_bit(WMI_SERVICE_PEER_TID_CONFIGS_SUPPORT, ar->wmi.svc_map)) {
|
||||
ar->hw->wiphy->tid_config_support.vif |=
|
||||
BIT(NL80211_TID_CONFIG_ATTR_NOACK) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_RETRY_SHORT) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_TX_RATE) |
|
||||
BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE);
|
||||
|
||||
if (test_bit(WMI_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT,
|
||||
ar->wmi.svc_map)) {
|
||||
ar->hw->wiphy->tid_config_support.vif |=
|
||||
BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL);
|
||||
}
|
||||
|
||||
ar->hw->wiphy->tid_config_support.peer =
|
||||
ar->hw->wiphy->tid_config_support.vif;
|
||||
ar->hw->wiphy->max_data_retry_count = ATH10K_MAX_RETRY_COUNT;
|
||||
} else {
|
||||
ar->ops->set_tid_config = NULL;
|
||||
}
|
||||
/*
|
||||
* on LL hardware queues are managed entirely by the FW
|
||||
* so we only advertise to mac we can do the queues thing
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include "targaddrs.h"
|
||||
#include "trace.h"
|
||||
#include "sdio.h"
|
||||
#include "coredump.h"
|
||||
|
||||
void ath10k_sdio_fw_crashed_dump(struct ath10k *ar);
|
||||
|
||||
#define ATH10K_SDIO_VSG_BUF_SIZE (64 * 1024)
|
||||
|
||||
@ -916,10 +919,9 @@ static int ath10k_sdio_mbox_proc_cpu_intr(struct ath10k *ar)
|
||||
|
||||
out:
|
||||
mutex_unlock(&irq_data->mtx);
|
||||
if (cpu_int_status & MBOX_CPU_STATUS_ENABLE_ASSERT_MASK) {
|
||||
ath10k_err(ar, "firmware crashed!\n");
|
||||
queue_work(ar->workqueue, &ar->restart_work);
|
||||
}
|
||||
if (cpu_int_status & MBOX_CPU_STATUS_ENABLE_ASSERT_MASK)
|
||||
ath10k_sdio_fw_crashed_dump(ar);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2185,6 +2187,323 @@ static int ath10k_sdio_napi_poll(struct napi_struct *ctx, int budget)
|
||||
return done;
|
||||
}
|
||||
|
||||
static int ath10k_sdio_read_host_interest_value(struct ath10k *ar,
|
||||
u32 item_offset,
|
||||
u32 *val)
|
||||
{
|
||||
u32 addr;
|
||||
int ret;
|
||||
|
||||
addr = host_interest_item_address(item_offset);
|
||||
|
||||
ret = ath10k_sdio_diag_read32(ar, addr, val);
|
||||
|
||||
if (ret)
|
||||
ath10k_warn(ar, "unable to read host interest offset %d value\n",
|
||||
item_offset);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_sdio_read_mem(struct ath10k *ar, u32 address, void *buf,
|
||||
u32 buf_len)
|
||||
{
|
||||
u32 val;
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < buf_len; i += 4) {
|
||||
ret = ath10k_sdio_diag_read32(ar, address + i, &val);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "unable to read mem %d value\n", address + i);
|
||||
break;
|
||||
}
|
||||
memcpy(buf + i, &val, 4);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool ath10k_sdio_is_fast_dump_supported(struct ath10k *ar)
|
||||
{
|
||||
u32 param;
|
||||
|
||||
ath10k_sdio_read_host_interest_value(ar, HI_ITEM(hi_option_flag2), ¶m);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_SDIO, "sdio hi_option_flag2 %x\n", param);
|
||||
|
||||
return param & HI_OPTION_SDIO_CRASH_DUMP_ENHANCEMENT_FW;
|
||||
}
|
||||
|
||||
static void ath10k_sdio_dump_registers(struct ath10k *ar,
|
||||
struct ath10k_fw_crash_data *crash_data,
|
||||
bool fast_dump)
|
||||
{
|
||||
u32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {};
|
||||
int i, ret;
|
||||
u32 reg_dump_area;
|
||||
|
||||
ret = ath10k_sdio_read_host_interest_value(ar, HI_ITEM(hi_failure_state),
|
||||
®_dump_area);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to read firmware dump area: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fast_dump)
|
||||
ret = ath10k_bmi_read_memory(ar, reg_dump_area, reg_dump_values,
|
||||
sizeof(reg_dump_values));
|
||||
else
|
||||
ret = ath10k_sdio_read_mem(ar, reg_dump_area, reg_dump_values,
|
||||
sizeof(reg_dump_values));
|
||||
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to read firmware dump value: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ath10k_err(ar, "firmware register dump:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(reg_dump_values); i += 4)
|
||||
ath10k_err(ar, "[%02d]: 0x%08X 0x%08X 0x%08X 0x%08X\n",
|
||||
i,
|
||||
reg_dump_values[i],
|
||||
reg_dump_values[i + 1],
|
||||
reg_dump_values[i + 2],
|
||||
reg_dump_values[i + 3]);
|
||||
|
||||
if (!crash_data)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(reg_dump_values); i++)
|
||||
crash_data->registers[i] = __cpu_to_le32(reg_dump_values[i]);
|
||||
}
|
||||
|
||||
static int ath10k_sdio_dump_memory_section(struct ath10k *ar,
|
||||
const struct ath10k_mem_region *mem_region,
|
||||
u8 *buf, size_t buf_len)
|
||||
{
|
||||
const struct ath10k_mem_section *cur_section, *next_section;
|
||||
unsigned int count, section_size, skip_size;
|
||||
int ret, i, j;
|
||||
|
||||
if (!mem_region || !buf)
|
||||
return 0;
|
||||
|
||||
cur_section = &mem_region->section_table.sections[0];
|
||||
|
||||
if (mem_region->start > cur_section->start) {
|
||||
ath10k_warn(ar, "incorrect memdump region 0x%x with section start address 0x%x.\n",
|
||||
mem_region->start, cur_section->start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
skip_size = cur_section->start - mem_region->start;
|
||||
|
||||
/* fill the gap between the first register section and register
|
||||
* start address
|
||||
*/
|
||||
for (i = 0; i < skip_size; i++) {
|
||||
*buf = ATH10K_MAGIC_NOT_COPIED;
|
||||
buf++;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
|
||||
for (i = 0; cur_section; i++) {
|
||||
section_size = cur_section->end - cur_section->start;
|
||||
|
||||
if (section_size <= 0) {
|
||||
ath10k_warn(ar, "incorrect ramdump format with start address 0x%x and stop address 0x%x\n",
|
||||
cur_section->start,
|
||||
cur_section->end);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((i + 1) == mem_region->section_table.size) {
|
||||
/* last section */
|
||||
next_section = NULL;
|
||||
skip_size = 0;
|
||||
} else {
|
||||
next_section = cur_section + 1;
|
||||
|
||||
if (cur_section->end > next_section->start) {
|
||||
ath10k_warn(ar, "next ramdump section 0x%x is smaller than current end address 0x%x\n",
|
||||
next_section->start,
|
||||
cur_section->end);
|
||||
break;
|
||||
}
|
||||
|
||||
skip_size = next_section->start - cur_section->end;
|
||||
}
|
||||
|
||||
if (buf_len < (skip_size + section_size)) {
|
||||
ath10k_warn(ar, "ramdump buffer is too small: %zu\n", buf_len);
|
||||
break;
|
||||
}
|
||||
|
||||
buf_len -= skip_size + section_size;
|
||||
|
||||
/* read section to dest memory */
|
||||
ret = ath10k_sdio_read_mem(ar, cur_section->start,
|
||||
buf, section_size);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to read ramdump from section 0x%x: %d\n",
|
||||
cur_section->start, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
buf += section_size;
|
||||
count += section_size;
|
||||
|
||||
/* fill in the gap between this section and the next */
|
||||
for (j = 0; j < skip_size; j++) {
|
||||
*buf = ATH10K_MAGIC_NOT_COPIED;
|
||||
buf++;
|
||||
}
|
||||
|
||||
count += skip_size;
|
||||
|
||||
if (!next_section)
|
||||
/* this was the last section */
|
||||
break;
|
||||
|
||||
cur_section = next_section;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* if an error happened returns < 0, otherwise the length */
|
||||
static int ath10k_sdio_dump_memory_generic(struct ath10k *ar,
|
||||
const struct ath10k_mem_region *current_region,
|
||||
u8 *buf,
|
||||
bool fast_dump)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (current_region->section_table.size > 0)
|
||||
/* Copy each section individually. */
|
||||
return ath10k_sdio_dump_memory_section(ar,
|
||||
current_region,
|
||||
buf,
|
||||
current_region->len);
|
||||
|
||||
/* No individiual memory sections defined so we can
|
||||
* copy the entire memory region.
|
||||
*/
|
||||
if (fast_dump)
|
||||
ret = ath10k_bmi_read_memory(ar,
|
||||
current_region->start,
|
||||
buf,
|
||||
current_region->len);
|
||||
else
|
||||
ret = ath10k_sdio_read_mem(ar,
|
||||
current_region->start,
|
||||
buf,
|
||||
current_region->len);
|
||||
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to copy ramdump region %s: %d\n",
|
||||
current_region->name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return current_region->len;
|
||||
}
|
||||
|
||||
static void ath10k_sdio_dump_memory(struct ath10k *ar,
|
||||
struct ath10k_fw_crash_data *crash_data,
|
||||
bool fast_dump)
|
||||
{
|
||||
const struct ath10k_hw_mem_layout *mem_layout;
|
||||
const struct ath10k_mem_region *current_region;
|
||||
struct ath10k_dump_ram_data_hdr *hdr;
|
||||
u32 count;
|
||||
size_t buf_len;
|
||||
int ret, i;
|
||||
u8 *buf;
|
||||
|
||||
if (!crash_data)
|
||||
return;
|
||||
|
||||
mem_layout = ath10k_coredump_get_mem_layout(ar);
|
||||
if (!mem_layout)
|
||||
return;
|
||||
|
||||
current_region = &mem_layout->region_table.regions[0];
|
||||
|
||||
buf = crash_data->ramdump_buf;
|
||||
buf_len = crash_data->ramdump_buf_len;
|
||||
|
||||
memset(buf, 0, buf_len);
|
||||
|
||||
for (i = 0; i < mem_layout->region_table.size; i++) {
|
||||
count = 0;
|
||||
|
||||
if (current_region->len > buf_len) {
|
||||
ath10k_warn(ar, "memory region %s size %d is larger that remaining ramdump buffer size %zu\n",
|
||||
current_region->name,
|
||||
current_region->len,
|
||||
buf_len);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reserve space for the header. */
|
||||
hdr = (void *)buf;
|
||||
buf += sizeof(*hdr);
|
||||
buf_len -= sizeof(*hdr);
|
||||
|
||||
ret = ath10k_sdio_dump_memory_generic(ar, current_region, buf,
|
||||
fast_dump);
|
||||
if (ret >= 0)
|
||||
count = ret;
|
||||
|
||||
hdr->region_type = cpu_to_le32(current_region->type);
|
||||
hdr->start = cpu_to_le32(current_region->start);
|
||||
hdr->length = cpu_to_le32(count);
|
||||
|
||||
if (count == 0)
|
||||
/* Note: the header remains, just with zero length. */
|
||||
break;
|
||||
|
||||
buf += count;
|
||||
buf_len -= count;
|
||||
|
||||
current_region++;
|
||||
}
|
||||
}
|
||||
|
||||
void ath10k_sdio_fw_crashed_dump(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_fw_crash_data *crash_data;
|
||||
char guid[UUID_STRING_LEN + 1];
|
||||
bool fast_dump;
|
||||
|
||||
fast_dump = ath10k_sdio_is_fast_dump_supported(ar);
|
||||
|
||||
if (fast_dump)
|
||||
ath10k_bmi_start(ar);
|
||||
|
||||
ar->stats.fw_crash_counter++;
|
||||
|
||||
ath10k_sdio_disable_intrs(ar);
|
||||
|
||||
crash_data = ath10k_coredump_new(ar);
|
||||
|
||||
if (crash_data)
|
||||
scnprintf(guid, sizeof(guid), "%pUl", &crash_data->guid);
|
||||
else
|
||||
scnprintf(guid, sizeof(guid), "n/a");
|
||||
|
||||
ath10k_err(ar, "firmware crashed! (guid %s)\n", guid);
|
||||
ath10k_print_driver_info(ar);
|
||||
ath10k_sdio_dump_registers(ar, crash_data, fast_dump);
|
||||
ath10k_sdio_dump_memory(ar, crash_data, fast_dump);
|
||||
|
||||
ath10k_sdio_enable_intrs(ar);
|
||||
|
||||
queue_work(ar->workqueue, &ar->restart_work);
|
||||
}
|
||||
|
||||
static int ath10k_sdio_probe(struct sdio_func *func,
|
||||
const struct sdio_device_id *id)
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
@ -45,6 +46,7 @@ static const char * const ath10k_regulators[] = {
|
||||
"vdd-1.8-xo",
|
||||
"vdd-1.3-rfa",
|
||||
"vdd-3.3-ch0",
|
||||
"vdd-3.3-ch1",
|
||||
};
|
||||
|
||||
static const char * const ath10k_clocks[] = {
|
||||
@ -923,6 +925,7 @@ static int ath10k_snoc_hif_start(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
|
||||
|
||||
bitmap_clear(ar_snoc->pending_ce_irqs, 0, CE_COUNT_MAX);
|
||||
napi_enable(&ar->napi);
|
||||
ath10k_snoc_irq_enable(ar);
|
||||
ath10k_snoc_rx_post(ar);
|
||||
@ -1158,7 +1161,9 @@ static irqreturn_t ath10k_snoc_per_engine_handler(int irq, void *arg)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
ath10k_snoc_irq_disable(ar);
|
||||
ath10k_ce_disable_interrupt(ar, ce_id);
|
||||
set_bit(ce_id, ar_snoc->pending_ce_irqs);
|
||||
|
||||
napi_schedule(&ar->napi);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
@ -1167,20 +1172,25 @@ static irqreturn_t ath10k_snoc_per_engine_handler(int irq, void *arg)
|
||||
static int ath10k_snoc_napi_poll(struct napi_struct *ctx, int budget)
|
||||
{
|
||||
struct ath10k *ar = container_of(ctx, struct ath10k, napi);
|
||||
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
|
||||
int done = 0;
|
||||
int ce_id;
|
||||
|
||||
if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) {
|
||||
napi_complete(ctx);
|
||||
return done;
|
||||
}
|
||||
|
||||
ath10k_ce_per_engine_service_any(ar);
|
||||
for (ce_id = 0; ce_id < CE_COUNT; ce_id++)
|
||||
if (test_and_clear_bit(ce_id, ar_snoc->pending_ce_irqs)) {
|
||||
ath10k_ce_per_engine_service(ar, ce_id);
|
||||
ath10k_ce_enable_interrupt(ar, ce_id);
|
||||
}
|
||||
|
||||
done = ath10k_htt_txrx_compl_task(ar, budget);
|
||||
|
||||
if (done < budget) {
|
||||
if (done < budget)
|
||||
napi_complete(ctx);
|
||||
ath10k_snoc_irq_enable(ar);
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ struct ath10k_snoc {
|
||||
unsigned long flags;
|
||||
bool xo_cal_supported;
|
||||
u32 xo_cal_data;
|
||||
DECLARE_BITMAP(pending_ce_irqs, CE_COUNT_MAX);
|
||||
};
|
||||
|
||||
static inline struct ath10k_snoc *ath10k_snoc_priv(struct ath10k *ar)
|
||||
|
@ -333,6 +333,17 @@ struct host_interest {
|
||||
#define HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_FW_ACK (1 << 16)
|
||||
#define HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_FW_ACK (1 << 17)
|
||||
|
||||
/*
|
||||
* If both SDIO_CRASH_DUMP_ENHANCEMENT_HOST and SDIO_CRASH_DUMP_ENHANCEMENT_FW
|
||||
* flags are set, then crashdump upload will be done using the BMI host/target
|
||||
* communication channel.
|
||||
*/
|
||||
/* HOST to support using BMI dump FW memory when hit assert */
|
||||
#define HI_OPTION_SDIO_CRASH_DUMP_ENHANCEMENT_HOST 0x400
|
||||
|
||||
/* FW to support using BMI dump FW memory when hit assert */
|
||||
#define HI_OPTION_SDIO_CRASH_DUMP_ENHANCEMENT_FW 0x800
|
||||
|
||||
/*
|
||||
* CONSOLE FLAGS
|
||||
*
|
||||
|
@ -50,6 +50,7 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
||||
struct ath10k_skb_cb *skb_cb;
|
||||
struct ath10k_txq *artxq;
|
||||
struct sk_buff *msdu;
|
||||
u8 flags;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_HTT,
|
||||
"htt tx completion msdu_id %u status %d\n",
|
||||
@ -78,6 +79,7 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
||||
artxq->num_fw_queued--;
|
||||
}
|
||||
|
||||
flags = skb_cb->flags;
|
||||
ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id);
|
||||
ath10k_htt_tx_dec_pending(htt);
|
||||
if (htt->num_pending_tx == 0)
|
||||
@ -101,18 +103,21 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
||||
|
||||
trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id);
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
|
||||
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
|
||||
!(flags & ATH10K_SKB_F_NOACK_TID))
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
|
||||
if (tx_done->status == HTT_TX_COMPL_STATE_NOACK)
|
||||
info->flags &= ~IEEE80211_TX_STAT_ACK;
|
||||
|
||||
if ((tx_done->status == HTT_TX_COMPL_STATE_ACK) &&
|
||||
(info->flags & IEEE80211_TX_CTL_NO_ACK))
|
||||
((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
|
||||
(flags & ATH10K_SKB_F_NOACK_TID)))
|
||||
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
||||
|
||||
if (tx_done->status == HTT_TX_COMPL_STATE_DISCARD) {
|
||||
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
|
||||
if ((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
|
||||
(flags & ATH10K_SKB_F_NOACK_TID))
|
||||
info->flags &= ~IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
||||
else
|
||||
info->flags &= ~IEEE80211_TX_STAT_ACK;
|
||||
|
@ -224,6 +224,8 @@ struct wmi_ops {
|
||||
struct sk_buff *(*gen_bb_timing)
|
||||
(struct ath10k *ar,
|
||||
const struct wmi_bb_timing_cfg_arg *arg);
|
||||
struct sk_buff *(*gen_per_peer_per_tid_cfg)(struct ath10k *ar,
|
||||
const struct wmi_per_peer_per_tid_cfg_arg *arg);
|
||||
|
||||
};
|
||||
|
||||
@ -1656,4 +1658,21 @@ ath10k_wmi_pdev_bb_timing(struct ath10k *ar,
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->set_bb_timing_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_set_per_peer_per_tid_cfg(struct ath10k *ar,
|
||||
const struct wmi_per_peer_per_tid_cfg_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_per_peer_per_tid_cfg)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_per_peer_per_tid_cfg(ar, arg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->per_peer_per_tid_config_cmdid);
|
||||
}
|
||||
#endif
|
||||
|
@ -740,6 +740,7 @@ static struct wmi_cmd_map wmi_10_4_cmd_map = {
|
||||
.tdls_peer_update_cmdid = WMI_10_4_TDLS_PEER_UPDATE_CMDID,
|
||||
.tdls_set_offchan_mode_cmdid = WMI_10_4_TDLS_SET_OFFCHAN_MODE_CMDID,
|
||||
.radar_found_cmdid = WMI_10_4_RADAR_FOUND_CMDID,
|
||||
.per_peer_per_tid_config_cmdid = WMI_10_4_PER_PEER_PER_TID_CONFIG_CMDID,
|
||||
};
|
||||
|
||||
static struct wmi_peer_param_map wmi_peer_param_map = {
|
||||
@ -6551,7 +6552,7 @@ static struct sk_buff *ath10k_wmi_op_gen_init(struct ath10k *ar)
|
||||
struct wmi_init_cmd *cmd;
|
||||
struct sk_buff *buf;
|
||||
struct wmi_resource_config config = {};
|
||||
u32 len, val;
|
||||
u32 val;
|
||||
|
||||
config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS);
|
||||
config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS);
|
||||
@ -6603,10 +6604,8 @@ static struct sk_buff *ath10k_wmi_op_gen_init(struct ath10k *ar)
|
||||
config.num_msdu_desc = __cpu_to_le32(TARGET_NUM_MSDU_DESC);
|
||||
config.max_frag_entries = __cpu_to_le32(TARGET_MAX_FRAG_ENTRIES);
|
||||
|
||||
len = sizeof(*cmd) +
|
||||
(sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks);
|
||||
|
||||
buf = ath10k_wmi_alloc_skb(ar, len);
|
||||
buf = ath10k_wmi_alloc_skb(ar, struct_size(cmd, mem_chunks.items,
|
||||
ar->wmi.num_mem_chunks));
|
||||
if (!buf)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -6624,7 +6623,7 @@ static struct sk_buff *ath10k_wmi_10_1_op_gen_init(struct ath10k *ar)
|
||||
struct wmi_init_cmd_10x *cmd;
|
||||
struct sk_buff *buf;
|
||||
struct wmi_resource_config_10x config = {};
|
||||
u32 len, val;
|
||||
u32 val;
|
||||
|
||||
config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS);
|
||||
config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS);
|
||||
@ -6668,10 +6667,8 @@ static struct sk_buff *ath10k_wmi_10_1_op_gen_init(struct ath10k *ar)
|
||||
config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC);
|
||||
config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES);
|
||||
|
||||
len = sizeof(*cmd) +
|
||||
(sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks);
|
||||
|
||||
buf = ath10k_wmi_alloc_skb(ar, len);
|
||||
buf = ath10k_wmi_alloc_skb(ar, struct_size(cmd, mem_chunks.items,
|
||||
ar->wmi.num_mem_chunks));
|
||||
if (!buf)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -6689,7 +6686,7 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
|
||||
struct wmi_init_cmd_10_2 *cmd;
|
||||
struct sk_buff *buf;
|
||||
struct wmi_resource_config_10x config = {};
|
||||
u32 len, val, features;
|
||||
u32 val, features;
|
||||
|
||||
config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS);
|
||||
config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS);
|
||||
@ -6741,10 +6738,8 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
|
||||
config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC);
|
||||
config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES);
|
||||
|
||||
len = sizeof(*cmd) +
|
||||
(sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks);
|
||||
|
||||
buf = ath10k_wmi_alloc_skb(ar, len);
|
||||
buf = ath10k_wmi_alloc_skb(ar, struct_size(cmd, mem_chunks.items,
|
||||
ar->wmi.num_mem_chunks));
|
||||
if (!buf)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -6776,7 +6771,6 @@ static struct sk_buff *ath10k_wmi_10_4_op_gen_init(struct ath10k *ar)
|
||||
struct wmi_init_cmd_10_4 *cmd;
|
||||
struct sk_buff *buf;
|
||||
struct wmi_resource_config_10_4 config = {};
|
||||
u32 len;
|
||||
|
||||
config.num_vdevs = __cpu_to_le32(ar->max_num_vdevs);
|
||||
config.num_peers = __cpu_to_le32(ar->max_num_peers);
|
||||
@ -6838,10 +6832,8 @@ static struct sk_buff *ath10k_wmi_10_4_op_gen_init(struct ath10k *ar)
|
||||
config.iphdr_pad_config = __cpu_to_le32(TARGET_10_4_IPHDR_PAD_CONFIG);
|
||||
config.qwrap_config = __cpu_to_le32(TARGET_10_4_QWRAP_CONFIG);
|
||||
|
||||
len = sizeof(*cmd) +
|
||||
(sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks);
|
||||
|
||||
buf = ath10k_wmi_alloc_skb(ar, len);
|
||||
buf = ath10k_wmi_alloc_skb(ar, struct_size(cmd, mem_chunks.items,
|
||||
ar->wmi.num_mem_chunks));
|
||||
if (!buf)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -7549,12 +7541,9 @@ ath10k_wmi_op_gen_scan_chan_list(struct ath10k *ar,
|
||||
struct sk_buff *skb;
|
||||
struct wmi_channel_arg *ch;
|
||||
struct wmi_channel *ci;
|
||||
int len;
|
||||
int i;
|
||||
|
||||
len = sizeof(*cmd) + arg->n_channels * sizeof(struct wmi_channel);
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, len);
|
||||
skb = ath10k_wmi_alloc_skb(ar, struct_size(cmd, chan_info, arg->n_channels));
|
||||
if (!skb)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
@ -9004,6 +8993,39 @@ ath10k_wmi_10_4_gen_radar_found(struct ath10k *ar,
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_10_4_gen_per_peer_per_tid_cfg(struct ath10k *ar,
|
||||
const struct wmi_per_peer_per_tid_cfg_arg *arg)
|
||||
{
|
||||
struct wmi_peer_per_tid_cfg_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
memset(skb->data, 0, sizeof(*cmd));
|
||||
|
||||
cmd = (struct wmi_peer_per_tid_cfg_cmd *)skb->data;
|
||||
cmd->vdev_id = cpu_to_le32(arg->vdev_id);
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, arg->peer_macaddr.addr);
|
||||
cmd->tid = cpu_to_le32(arg->tid);
|
||||
cmd->ack_policy = cpu_to_le32(arg->ack_policy);
|
||||
cmd->aggr_control = cpu_to_le32(arg->aggr_control);
|
||||
cmd->rate_control = cpu_to_le32(arg->rate_ctrl);
|
||||
cmd->retry_count = cpu_to_le32(arg->retry_count);
|
||||
cmd->rcode_flags = cpu_to_le32(arg->rcode_flags);
|
||||
cmd->ext_tid_cfg_bitmap = cpu_to_le32(arg->ext_tid_cfg_bitmap);
|
||||
cmd->rtscts_ctrl = cpu_to_le32(arg->rtscts_ctrl);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi noack tid %d vdev id %d ack_policy %d aggr %u rate_ctrl %u rcflag %u retry_count %d rtscts %d ext_tid_cfg_bitmap %d mac_addr %pM\n",
|
||||
arg->tid, arg->vdev_id, arg->ack_policy, arg->aggr_control,
|
||||
arg->rate_ctrl, arg->rcode_flags, arg->retry_count,
|
||||
arg->rtscts_ctrl, arg->ext_tid_cfg_bitmap, arg->peer_macaddr.addr);
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_op_gen_echo(struct ath10k *ar, u32 value)
|
||||
{
|
||||
@ -9413,6 +9435,7 @@ static const struct wmi_ops wmi_10_4_ops = {
|
||||
.gen_pdev_get_tpc_table_cmdid =
|
||||
ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid,
|
||||
.gen_radar_found = ath10k_wmi_10_4_gen_radar_found,
|
||||
.gen_per_peer_per_tid_cfg = ath10k_wmi_10_4_gen_per_peer_per_tid_cfg,
|
||||
|
||||
/* shared with 10.2 */
|
||||
.pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
|
||||
|
@ -203,6 +203,8 @@ enum wmi_service {
|
||||
WMI_SERVICE_SYNC_DELETE_CMDS,
|
||||
WMI_SERVICE_TX_PWR_PER_PEER,
|
||||
WMI_SERVICE_SUPPORT_EXTEND_ADDRESS,
|
||||
WMI_SERVICE_PEER_TID_CONFIGS_SUPPORT,
|
||||
WMI_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT,
|
||||
|
||||
/* Remember to add the new value to wmi_service_name()! */
|
||||
|
||||
@ -503,6 +505,8 @@ static inline char *wmi_service_name(enum wmi_service service_id)
|
||||
SVCSTR(WMI_SERVICE_SYNC_DELETE_CMDS);
|
||||
SVCSTR(WMI_SERVICE_TX_PWR_PER_PEER);
|
||||
SVCSTR(WMI_SERVICE_SUPPORT_EXTEND_ADDRESS);
|
||||
SVCSTR(WMI_SERVICE_PEER_TID_CONFIGS_SUPPORT);
|
||||
SVCSTR(WMI_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT);
|
||||
|
||||
case WMI_SERVICE_MAX:
|
||||
return NULL;
|
||||
@ -834,6 +838,10 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
|
||||
WMI_SERVICE_TX_PWR_PER_PEER, len);
|
||||
SVCMAP(WMI_10_4_SERVICE_RESET_CHIP,
|
||||
WMI_SERVICE_RESET_CHIP, len);
|
||||
SVCMAP(WMI_10_4_SERVICE_PEER_TID_CONFIGS_SUPPORT,
|
||||
WMI_SERVICE_PEER_TID_CONFIGS_SUPPORT, len);
|
||||
SVCMAP(WMI_10_4_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT,
|
||||
WMI_SERVICE_PEER_TID_CONFIGS_SUPPORT, len);
|
||||
}
|
||||
|
||||
#undef SVCMAP
|
||||
@ -1036,6 +1044,7 @@ struct wmi_cmd_map {
|
||||
u32 tdls_set_offchan_mode_cmdid;
|
||||
u32 radar_found_cmdid;
|
||||
u32 set_bb_timing_cmdid;
|
||||
u32 per_peer_per_tid_config_cmdid;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1877,6 +1886,8 @@ enum wmi_10_4_cmd_id {
|
||||
WMI_10_4_PDEV_SET_BRIDGE_MACADDR_CMDID,
|
||||
WMI_10_4_ATF_GROUP_WMM_AC_CONFIG_REQUEST_CMDID,
|
||||
WMI_10_4_RADAR_FOUND_CMDID,
|
||||
WMI_10_4_PEER_CFR_CAPTURE_CMDID,
|
||||
WMI_10_4_PER_PEER_PER_TID_CONFIG_CMDID,
|
||||
WMI_10_4_PDEV_UTF_CMDID = WMI_10_4_END_CMDID - 1,
|
||||
};
|
||||
|
||||
@ -7220,6 +7231,71 @@ struct wmi_tdls_peer_event {
|
||||
__le32 vdev_id;
|
||||
} __packed;
|
||||
|
||||
enum wmi_tid_aggr_control_conf {
|
||||
WMI_TID_CONFIG_AGGR_CONTROL_IGNORE,
|
||||
WMI_TID_CONFIG_AGGR_CONTROL_ENABLE,
|
||||
WMI_TID_CONFIG_AGGR_CONTROL_DISABLE,
|
||||
};
|
||||
|
||||
enum wmi_noack_tid_conf {
|
||||
WMI_NOACK_TID_CONFIG_IGNORE_ACK_POLICY,
|
||||
WMI_PEER_TID_CONFIG_ACK,
|
||||
WMI_PEER_TID_CONFIG_NOACK,
|
||||
};
|
||||
|
||||
enum wmi_tid_rate_ctrl_conf {
|
||||
WMI_TID_CONFIG_RATE_CONTROL_IGNORE,
|
||||
WMI_TID_CONFIG_RATE_CONTROL_AUTO,
|
||||
WMI_TID_CONFIG_RATE_CONTROL_FIXED_RATE,
|
||||
WMI_TID_CONFIG_RATE_CONTROL_DEFAULT_LOWEST_RATE,
|
||||
WMI_PEER_TID_CONFIG_RATE_UPPER_CAP,
|
||||
};
|
||||
|
||||
enum wmi_tid_rtscts_control_conf {
|
||||
WMI_TID_CONFIG_RTSCTS_CONTROL_ENABLE,
|
||||
WMI_TID_CONFIG_RTSCTS_CONTROL_DISABLE,
|
||||
};
|
||||
|
||||
enum wmi_ext_tid_config_map {
|
||||
WMI_EXT_TID_RTS_CTS_CONFIG = BIT(0),
|
||||
};
|
||||
|
||||
struct wmi_per_peer_per_tid_cfg_arg {
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
u32 tid;
|
||||
enum wmi_noack_tid_conf ack_policy;
|
||||
enum wmi_tid_aggr_control_conf aggr_control;
|
||||
u8 rate_ctrl;
|
||||
u32 retry_count;
|
||||
u32 rcode_flags;
|
||||
u32 ext_tid_cfg_bitmap;
|
||||
u32 rtscts_ctrl;
|
||||
};
|
||||
|
||||
struct wmi_peer_per_tid_cfg_cmd {
|
||||
__le32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
__le32 tid;
|
||||
|
||||
/* see enum wmi_noack_tid_conf */
|
||||
__le32 ack_policy;
|
||||
|
||||
/* see enum wmi_tid_aggr_control_conf */
|
||||
__le32 aggr_control;
|
||||
|
||||
/* see enum wmi_tid_rate_ctrl_conf */
|
||||
__le32 rate_control;
|
||||
__le32 rcode_flags;
|
||||
__le32 retry_count;
|
||||
|
||||
/* See enum wmi_ext_tid_config_map */
|
||||
__le32 ext_tid_cfg_bitmap;
|
||||
|
||||
/* see enum wmi_tid_rtscts_control_conf */
|
||||
__le32 rtscts_ctrl;
|
||||
} __packed;
|
||||
|
||||
enum wmi_txbf_conf {
|
||||
WMI_TXBF_CONF_UNSUPPORTED,
|
||||
WMI_TXBF_CONF_BEFORE_ASSOC,
|
||||
|
@ -20,6 +20,9 @@ static const struct of_device_id ath11k_ahb_of_match[] = {
|
||||
{ .compatible = "qcom,ipq8074-wifi",
|
||||
.data = (void *)ATH11K_HW_IPQ8074,
|
||||
},
|
||||
{ .compatible = "qcom,ipq6018-wifi",
|
||||
.data = (void *)ATH11K_HW_IPQ6018_HW10,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -32,245 +35,6 @@ static const struct ath11k_bus_params ath11k_ahb_bus_params = {
|
||||
.fixed_mem_region = true,
|
||||
};
|
||||
|
||||
/* Target firmware's Copy Engine configuration. */
|
||||
static const struct ce_pipe_config target_ce_config_wlan[] = {
|
||||
/* CE0: host->target HTC control and raw streams */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE1: target->host HTT + HTC control */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE2: target->host WMI */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE3: host->target WMI */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE4: host->target HTT */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(4),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(256),
|
||||
.nbytes_max = __cpu_to_le32(256),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE5: target->host Pktlog */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(5),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(0),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE6: Reserved for target autonomous hif_memcpy */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(6),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(65535),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE7 used only by Host */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(7),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE8 target->host used only by IPA */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(8),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(65535),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE9 host->target HTT */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(9),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE10 target->host HTT */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(10),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H),
|
||||
.nentries = __cpu_to_le32(0),
|
||||
.nbytes_max = __cpu_to_le32(0),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE11 Not used */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
.pipedir = __cpu_to_le32(0),
|
||||
.nentries = __cpu_to_le32(0),
|
||||
.nbytes_max = __cpu_to_le32(0),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
};
|
||||
|
||||
/* Map from service/endpoint to Copy Engine.
|
||||
* This table is derived from the CE_PCI TABLE, above.
|
||||
* It is passed to the Target at startup for use by firmware.
|
||||
*/
|
||||
static const struct service_to_pipe target_service_to_ce_map_wlan[] = {
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(7),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(9),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
},
|
||||
{ /* not used */
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
},
|
||||
{ /* not used */
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(4),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_PKT_LOG),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(5),
|
||||
},
|
||||
|
||||
/* (Additions here) */
|
||||
|
||||
{ /* terminator entry */ }
|
||||
};
|
||||
|
||||
#define ATH11K_IRQ_CE0_OFFSET 4
|
||||
|
||||
static const char *irq_name[ATH11K_IRQ_NUM_MAX] = {
|
||||
@ -444,7 +208,7 @@ static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id)
|
||||
{
|
||||
const struct ce_pipe_config *ce_config;
|
||||
|
||||
ce_config = &target_ce_config_wlan[ce_id];
|
||||
ce_config = &ab->hw_params.target_ce_config[ce_id];
|
||||
if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_OUT)
|
||||
ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
|
||||
|
||||
@ -459,7 +223,7 @@ static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id)
|
||||
{
|
||||
const struct ce_pipe_config *ce_config;
|
||||
|
||||
ce_config = &target_ce_config_wlan[ce_id];
|
||||
ce_config = &ab->hw_params.target_ce_config[ce_id];
|
||||
if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_OUT)
|
||||
ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS);
|
||||
|
||||
@ -577,10 +341,10 @@ static void ath11k_ahb_init_qmi_ce_config(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
|
||||
|
||||
cfg->tgt_ce_len = ARRAY_SIZE(target_ce_config_wlan) - 1;
|
||||
cfg->tgt_ce = target_ce_config_wlan;
|
||||
cfg->svc_to_ce_map_len = ARRAY_SIZE(target_service_to_ce_map_wlan);
|
||||
cfg->svc_to_ce_map = target_service_to_ce_map_wlan;
|
||||
cfg->tgt_ce_len = ab->hw_params.target_ce_count;
|
||||
cfg->tgt_ce = ab->hw_params.target_ce_config;
|
||||
cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
|
||||
cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
|
||||
ab->qmi.service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074;
|
||||
}
|
||||
|
||||
@ -611,9 +375,9 @@ static void ath11k_ahb_free_irq(struct ath11k_base *ab)
|
||||
ath11k_ahb_free_ext_irq(ab);
|
||||
}
|
||||
|
||||
static void ath11k_ahb_ce_tasklet(unsigned long data)
|
||||
static void ath11k_ahb_ce_tasklet(struct tasklet_struct *t)
|
||||
{
|
||||
struct ath11k_ce_pipe *ce_pipe = (struct ath11k_ce_pipe *)data;
|
||||
struct ath11k_ce_pipe *ce_pipe = from_tasklet(ce_pipe, t, intr_tq);
|
||||
|
||||
ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num);
|
||||
|
||||
@ -764,8 +528,7 @@ static int ath11k_ahb_config_irq(struct ath11k_base *ab)
|
||||
|
||||
irq_idx = ATH11K_IRQ_CE0_OFFSET + i;
|
||||
|
||||
tasklet_init(&ce_pipe->intr_tq, ath11k_ahb_ce_tasklet,
|
||||
(unsigned long)ce_pipe);
|
||||
tasklet_setup(&ce_pipe->intr_tq, ath11k_ahb_ce_tasklet);
|
||||
irq = platform_get_irq_byname(ab->pdev, irq_name[irq_idx]);
|
||||
ret = request_irq(irq, ath11k_ahb_ce_interrupt_handler,
|
||||
IRQF_TRIGGER_RISING, irq_name[irq_idx],
|
||||
@ -789,8 +552,8 @@ static int ath11k_ahb_map_service_to_pipe(struct ath11k_base *ab, u16 service_id
|
||||
bool ul_set = false, dl_set = false;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) {
|
||||
entry = &target_service_to_ce_map_wlan[i];
|
||||
for (i = 0; i < ab->hw_params.svc_to_ce_map_len; i++) {
|
||||
entry = &ab->hw_params.svc_to_ce_map[i];
|
||||
|
||||
if (__le32_to_cpu(entry->service_id) != service_id)
|
||||
continue;
|
||||
|
@ -18,6 +18,16 @@ EXPORT_SYMBOL(ath11k_debug_mask);
|
||||
module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
|
||||
MODULE_PARM_DESC(debug_mask, "Debugging mask");
|
||||
|
||||
static unsigned int ath11k_crypto_mode;
|
||||
module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
|
||||
MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
|
||||
|
||||
/* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
|
||||
unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
|
||||
module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
|
||||
MODULE_PARM_DESC(frame_mode,
|
||||
"Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
|
||||
|
||||
static const struct ath11k_hw_params ath11k_hw_params[] = {
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ8074,
|
||||
@ -35,6 +45,39 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
||||
.regs = &ipq8074_regs,
|
||||
.host_ce_config = ath11k_host_ce_config_ipq8074,
|
||||
.ce_count = 12,
|
||||
.target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
|
||||
.target_ce_count = 11,
|
||||
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
|
||||
.svc_to_ce_map_len = 21,
|
||||
.single_pdev_only = false,
|
||||
.needs_band_to_mac = true,
|
||||
.rxdma1_enable = true,
|
||||
.num_rxmda_per_pdev = 1,
|
||||
.rx_mac_buf_ring = false,
|
||||
.vdev_start_delay = false,
|
||||
.htt_peer_map_v2 = true,
|
||||
.tcl_0_only = false,
|
||||
},
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ6018_HW10,
|
||||
.name = "ipq6018 hw1.0",
|
||||
.fw = {
|
||||
.dir = "IPQ6018/hw1.0",
|
||||
.board_size = 256 * 1024,
|
||||
.cal_size = 256 * 1024,
|
||||
},
|
||||
.max_radios = 2,
|
||||
.bdf_addr = 0x4ABC0000,
|
||||
.hw_ops = &ipq6018_ops,
|
||||
.ring_mask = &ath11k_hw_ring_mask_ipq8074,
|
||||
.internal_sleep_clock = false,
|
||||
.regs = &ipq8074_regs,
|
||||
.host_ce_config = ath11k_host_ce_config_ipq8074,
|
||||
.ce_count = 12,
|
||||
.target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
|
||||
.target_ce_count = 11,
|
||||
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
|
||||
.svc_to_ce_map_len = 19,
|
||||
.single_pdev_only = false,
|
||||
.needs_band_to_mac = true,
|
||||
.rxdma1_enable = true,
|
||||
@ -60,6 +103,10 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
||||
.regs = &qca6390_regs,
|
||||
.host_ce_config = ath11k_host_ce_config_qca6390,
|
||||
.ce_count = 9,
|
||||
.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
|
||||
.target_ce_count = 9,
|
||||
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
|
||||
.svc_to_ce_map_len = 14,
|
||||
.single_pdev_only = true,
|
||||
.needs_band_to_mac = false,
|
||||
.rxdma1_enable = false,
|
||||
@ -580,6 +627,23 @@ int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (ath11k_crypto_mode) {
|
||||
case ATH11K_CRYPT_MODE_SW:
|
||||
set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
|
||||
set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
|
||||
break;
|
||||
case ATH11K_CRYPT_MODE_HW:
|
||||
clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
|
||||
clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
|
||||
break;
|
||||
default:
|
||||
ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
|
||||
set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
|
||||
|
||||
mutex_lock(&ab->core_lock);
|
||||
ret = ath11k_core_start(ab, ATH11K_FIRMWARE_MODE_NORMAL);
|
||||
if (ret) {
|
||||
@ -784,6 +848,9 @@ static int ath11k_core_get_rproc(struct ath11k_base *ab)
|
||||
struct rproc *prproc;
|
||||
phandle rproc_phandle;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_REMOTEPROC))
|
||||
return 0;
|
||||
|
||||
if (ab->bus_params.mhi_support)
|
||||
return 0;
|
||||
|
||||
@ -812,12 +879,6 @@ int ath11k_core_init(struct ath11k_base *ab)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath11k_init_hw_params(ab);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to get hw params %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath11k_core_soc_create(ab);
|
||||
if (ret) {
|
||||
ath11k_err(ab, "failed to create soc core: %d\n", ret);
|
||||
|
@ -35,6 +35,8 @@
|
||||
|
||||
#define ATH11K_INVALID_HW_MAC_ID 0xFF
|
||||
|
||||
extern unsigned int ath11k_frame_mode;
|
||||
|
||||
enum ath11k_supported_bw {
|
||||
ATH11K_BW_20 = 0,
|
||||
ATH11K_BW_40 = 1,
|
||||
@ -54,6 +56,13 @@ enum wme_ac {
|
||||
#define ATH11K_VHT_MCS_MAX 9
|
||||
#define ATH11K_HE_MCS_MAX 11
|
||||
|
||||
enum ath11k_crypt_mode {
|
||||
/* Only use hardware crypto engine */
|
||||
ATH11K_CRYPT_MODE_HW,
|
||||
/* Only use software crypto */
|
||||
ATH11K_CRYPT_MODE_SW,
|
||||
};
|
||||
|
||||
static inline enum wme_ac ath11k_tid_to_ac(u32 tid)
|
||||
{
|
||||
return (((tid == 0) || (tid == 3)) ? WME_AC_BE :
|
||||
@ -91,6 +100,7 @@ struct ath11k_skb_rxcb {
|
||||
enum ath11k_hw_rev {
|
||||
ATH11K_HW_IPQ8074,
|
||||
ATH11K_HW_QCA6390_HW20,
|
||||
ATH11K_HW_IPQ6018_HW10,
|
||||
};
|
||||
|
||||
enum ath11k_firmware_mode {
|
||||
@ -845,6 +855,13 @@ struct ath11k_fw_stats_bcn {
|
||||
u32 tx_bcn_outage_cnt;
|
||||
};
|
||||
|
||||
extern const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq8074[];
|
||||
extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq8074[];
|
||||
extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq6018[];
|
||||
|
||||
extern const struct ce_pipe_config ath11k_target_ce_config_wlan_qca6390[];
|
||||
extern const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qca6390[];
|
||||
|
||||
void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);
|
||||
void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id,
|
||||
u8 *mac_addr, u16 ast_hash);
|
||||
|
@ -1097,7 +1097,7 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file,
|
||||
DP_RX_BUFFER_SIZE, &tlv_filter);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to set rx filter for moniter status ring\n");
|
||||
ath11k_warn(ab, "failed to set rx filter for monitor status ring\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ enum ath11k_debug_mask {
|
||||
ATH11K_DBG_TESTMODE = 0x00000400,
|
||||
ATH11k_DBG_HAL = 0x00000800,
|
||||
ATH11K_DBG_PCI = 0x00001000,
|
||||
ATH11K_DBG_DP_TX = 0x00001000,
|
||||
ATH11K_DBG_DP_RX = 0x00002000,
|
||||
ATH11K_DBG_ANY = 0xffffffff,
|
||||
};
|
||||
|
||||
|
@ -3895,50 +3895,6 @@ static inline void htt_print_backpressure_stats_tlv_v(const u32 *tag_buf,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void htt_htt_stats_debug_dump(const u32 *tag_buf,
|
||||
struct debug_htt_stats_req *stats_req)
|
||||
{
|
||||
u8 *buf = stats_req->buf;
|
||||
u32 len = stats_req->buf_len;
|
||||
u32 buf_len = ATH11K_HTT_STATS_BUF_SIZE;
|
||||
u32 tlv_len = 0, i = 0, word_len = 0;
|
||||
|
||||
tlv_len = FIELD_GET(HTT_TLV_LEN, *tag_buf) + HTT_TLV_HDR_LEN;
|
||||
word_len = (tlv_len % 4) == 0 ? (tlv_len / 4) : ((tlv_len / 4) + 1);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"============================================");
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"HKDBG TLV DUMP: (tag_len=%u bytes, words=%u)",
|
||||
tlv_len, word_len);
|
||||
|
||||
for (i = 0; i + 3 < word_len; i += 4) {
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"0x%08x 0x%08x 0x%08x 0x%08x",
|
||||
tag_buf[i], tag_buf[i + 1],
|
||||
tag_buf[i + 2], tag_buf[i + 3]);
|
||||
}
|
||||
|
||||
if (i + 3 == word_len) {
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "0x%08x 0x%08x 0x%08x ",
|
||||
tag_buf[i], tag_buf[i + 1], tag_buf[i + 2]);
|
||||
} else if (i + 2 == word_len) {
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "0x%08x 0x%08x ",
|
||||
tag_buf[i], tag_buf[i + 1]);
|
||||
} else if (i + 1 == word_len) {
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "0x%08x ",
|
||||
tag_buf[i]);
|
||||
}
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len,
|
||||
"============================================");
|
||||
|
||||
if (len >= buf_len)
|
||||
buf[buf_len - 1] = 0;
|
||||
else
|
||||
buf[len] = 0;
|
||||
|
||||
stats_req->buf_len = len;
|
||||
}
|
||||
|
||||
static int ath11k_dbg_htt_ext_stats_parse(struct ath11k_base *ab,
|
||||
u16 tag, u16 len, const void *tag_buf,
|
||||
void *user_data)
|
||||
|
@ -2133,8 +2133,6 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar,
|
||||
mcast = is_multicast_ether_addr(hdr->addr1);
|
||||
fill_crypto_hdr = mcast;
|
||||
|
||||
is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc);
|
||||
|
||||
spin_lock_bh(&ar->ab->base_lock);
|
||||
peer = ath11k_peer_find_by_addr(ar->ab, hdr->addr2);
|
||||
if (peer) {
|
||||
@ -2148,6 +2146,8 @@ static void ath11k_dp_rx_h_mpdu(struct ath11k *ar,
|
||||
spin_unlock_bh(&ar->ab->base_lock);
|
||||
|
||||
err_bitmap = ath11k_dp_rx_h_attn_mpdu_err(rx_desc);
|
||||
if (enctype != HAL_ENCRYPT_TYPE_OPEN && !err_bitmap)
|
||||
is_decrypted = ath11k_dp_rx_h_attn_is_decrypted(rx_desc);
|
||||
|
||||
/* Clear per-MPDU flags while leaving per-PPDU flags intact */
|
||||
rx_status->flag &= ~(RX_FLAG_FAILED_FCS_CRC |
|
||||
@ -2350,6 +2350,9 @@ static void ath11k_dp_rx_deliver_msdu(struct ath11k *ar, struct napi_struct *nap
|
||||
!!(status->flag & RX_FLAG_MMIC_ERROR),
|
||||
!!(status->flag & RX_FLAG_AMSDU_MORE));
|
||||
|
||||
ath11k_dbg_dump(ar->ab, ATH11K_DBG_DP_RX, NULL, "dp rx msdu: ",
|
||||
msdu->data, msdu->len);
|
||||
|
||||
/* TODO: trace rx packet */
|
||||
|
||||
ieee80211_rx_napi(ar->hw, NULL, msdu, napi);
|
||||
|
@ -13,6 +13,10 @@ static enum hal_tcl_encap_type
|
||||
ath11k_dp_tx_get_encap_type(struct ath11k_vif *arvif, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
struct ath11k_base *ab = arvif->ar->ab;
|
||||
|
||||
if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
|
||||
return HAL_TCL_ENCAP_TYPE_RAW;
|
||||
|
||||
if (tx_info->control.flags & IEEE80211_TX_CTRL_HW_80211_ENCAP)
|
||||
return HAL_TCL_ENCAP_TYPE_ETHERNET;
|
||||
@ -79,6 +83,7 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
struct ath11k_dp *dp = &ab->dp;
|
||||
struct hal_tx_info ti = {0};
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_key_conf *key = info->control.hw_key;
|
||||
struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
|
||||
struct hal_srng *tcl_ring;
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
@ -142,11 +147,17 @@ tcl_ring_sel:
|
||||
ti.encap_type = ath11k_dp_tx_get_encap_type(arvif, skb);
|
||||
ti.meta_data_flags = arvif->tcl_metadata;
|
||||
|
||||
if (info->control.hw_key)
|
||||
ti.encrypt_type =
|
||||
ath11k_dp_tx_get_encrypt_type(info->control.hw_key->cipher);
|
||||
else
|
||||
ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
|
||||
if (ti.encap_type == HAL_TCL_ENCAP_TYPE_RAW) {
|
||||
if (key) {
|
||||
ti.encrypt_type =
|
||||
ath11k_dp_tx_get_encrypt_type(key->cipher);
|
||||
|
||||
if (ieee80211_has_protected(hdr->frame_control))
|
||||
skb_put(skb, IEEE80211_CCMP_MIC_LEN);
|
||||
} else {
|
||||
ti.encrypt_type = HAL_ENCRYPT_TYPE_OPEN;
|
||||
}
|
||||
}
|
||||
|
||||
ti.addr_search_flags = arvif->hal_addr_search_flags;
|
||||
ti.search_type = arvif->search_type;
|
||||
@ -156,7 +167,8 @@ tcl_ring_sel:
|
||||
ti.bss_ast_hash = arvif->ast_hash;
|
||||
ti.dscp_tid_tbl_idx = 0;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL &&
|
||||
ti.encap_type != HAL_TCL_ENCAP_TYPE_RAW) {
|
||||
ti.flags0 |= FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_IP4_CKSUM_EN, 1) |
|
||||
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_UDP4_CKSUM_EN, 1) |
|
||||
FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_UDP6_CKSUM_EN, 1) |
|
||||
@ -176,10 +188,11 @@ tcl_ring_sel:
|
||||
ath11k_dp_tx_encap_nwifi(skb);
|
||||
break;
|
||||
case HAL_TCL_ENCAP_TYPE_RAW:
|
||||
/* TODO: for CHECKSUM_PARTIAL case in raw mode, HW checksum offload
|
||||
* is not applicable, hence manual checksum calculation using
|
||||
* skb_checksum_help() is needed
|
||||
*/
|
||||
if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {
|
||||
ret = -EINVAL;
|
||||
goto fail_remove_idr;
|
||||
}
|
||||
break;
|
||||
case HAL_TCL_ENCAP_TYPE_ETHERNET:
|
||||
/* no need to encap */
|
||||
break;
|
||||
@ -242,6 +255,9 @@ tcl_ring_sel:
|
||||
|
||||
spin_unlock_bh(&tcl_ring->lock);
|
||||
|
||||
ath11k_dbg_dump(ab, ATH11K_DBG_DP_TX, NULL, "dp tx msdu: ",
|
||||
skb->data, skb->len);
|
||||
|
||||
atomic_inc(&ar->dp.num_tx_pending);
|
||||
|
||||
return 0;
|
||||
@ -352,7 +368,6 @@ ath11k_dp_tx_process_htt_tx_complete(struct ath11k_base *ab,
|
||||
|
||||
wbm_status = FIELD_GET(HTT_TX_WBM_COMP_INFO0_STATUS,
|
||||
status_desc->info0);
|
||||
|
||||
switch (wbm_status) {
|
||||
case HAL_WBM_REL_HTT_TX_COMP_STATUS_OK:
|
||||
case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP:
|
||||
|
@ -276,6 +276,518 @@ const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390 = {
|
||||
},
|
||||
};
|
||||
|
||||
/* Target firmware's Copy Engine configuration. */
|
||||
const struct ce_pipe_config ath11k_target_ce_config_wlan_ipq8074[] = {
|
||||
/* CE0: host->target HTC control and raw streams */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE1: target->host HTT + HTC control */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE2: target->host WMI */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE3: host->target WMI */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE4: host->target HTT */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(4),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(256),
|
||||
.nbytes_max = __cpu_to_le32(256),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE5: target->host Pktlog */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(5),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(0),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE6: Reserved for target autonomous hif_memcpy */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(6),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(65535),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE7 used only by Host */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(7),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE8 target->host used only by IPA */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(8),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(65535),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE9 host->target HTT */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(9),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE10 target->host HTT */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(10),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H),
|
||||
.nentries = __cpu_to_le32(0),
|
||||
.nbytes_max = __cpu_to_le32(0),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE11 Not used */
|
||||
};
|
||||
|
||||
/* Map from service/endpoint to Copy Engine.
|
||||
* This table is derived from the CE_PCI TABLE, above.
|
||||
* It is passed to the Target at startup for use by firmware.
|
||||
*/
|
||||
const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq8074[] = {
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(7),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(9),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC2),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
},
|
||||
{ /* not used */
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
},
|
||||
{ /* not used */
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(4),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_PKT_LOG),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(5),
|
||||
},
|
||||
|
||||
/* (Additions here) */
|
||||
|
||||
{ /* terminator entry */ }
|
||||
};
|
||||
|
||||
const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_ipq6018[] = {
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(7),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL_MAC1),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
},
|
||||
{ /* not used */
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
},
|
||||
{ /* not used */
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_TEST_RAW_STREAMS),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
.pipenum = __cpu_to_le32(4),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
},
|
||||
{
|
||||
.service_id = __cpu_to_le32(ATH11K_HTC_SVC_ID_PKT_LOG),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
.pipenum = __cpu_to_le32(5),
|
||||
},
|
||||
|
||||
/* (Additions here) */
|
||||
|
||||
{ /* terminator entry */ }
|
||||
};
|
||||
|
||||
/* Target firmware's Copy Engine configuration. */
|
||||
const struct ce_pipe_config ath11k_target_ce_config_wlan_qca6390[] = {
|
||||
/* CE0: host->target HTC control and raw streams */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE1: target->host HTT + HTC control */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE2: target->host WMI */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE3: host->target WMI */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE4: host->target HTT */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(4),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(256),
|
||||
.nbytes_max = __cpu_to_le32(256),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE5: target->host Pktlog */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(5),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE6: Reserved for target autonomous hif_memcpy */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(6),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(16384),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE7 used only by Host */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(7),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H),
|
||||
.nentries = __cpu_to_le32(0),
|
||||
.nbytes_max = __cpu_to_le32(0),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE8 target->host used only by IPA */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(8),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(16384),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
/* CE 9, 10, 11 are used by MHI driver */
|
||||
};
|
||||
|
||||
/* Map from service/endpoint to Copy Engine.
|
||||
* This table is derived from the CE_PCI TABLE, above.
|
||||
* It is passed to the Target at startup for use by firmware.
|
||||
*/
|
||||
const struct service_to_pipe ath11k_target_service_to_ce_map_wlan_qca6390[] = {
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(0),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(4),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(1),
|
||||
},
|
||||
|
||||
/* (Additions here) */
|
||||
|
||||
{ /* must be last */
|
||||
__cpu_to_le32(0),
|
||||
__cpu_to_le32(0),
|
||||
__cpu_to_le32(0),
|
||||
},
|
||||
};
|
||||
|
||||
const struct ath11k_hw_regs ipq8074_regs = {
|
||||
/* SW2TCL(x) R0 ring configuration address */
|
||||
.hal_tcl1_ring_base_lsb = 0x00000510,
|
||||
|
@ -129,7 +129,6 @@ struct ath11k_hw_params {
|
||||
} fw;
|
||||
|
||||
const struct ath11k_hw_ops *hw_ops;
|
||||
|
||||
const struct ath11k_hw_ring_mask *ring_mask;
|
||||
|
||||
bool internal_sleep_clock;
|
||||
@ -137,6 +136,10 @@ struct ath11k_hw_params {
|
||||
const struct ath11k_hw_regs *regs;
|
||||
const struct ce_attr *host_ce_config;
|
||||
u32 ce_count;
|
||||
const struct ce_pipe_config *target_ce_config;
|
||||
u32 target_ce_count;
|
||||
const struct service_to_pipe *svc_to_ce_map;
|
||||
u32 svc_to_ce_map_len;
|
||||
|
||||
bool single_pdev_only;
|
||||
|
||||
|
@ -42,12 +42,6 @@
|
||||
.max_power = 30, \
|
||||
}
|
||||
|
||||
/* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
|
||||
static unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
|
||||
module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
|
||||
MODULE_PARM_DESC(frame_mode,
|
||||
"Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
|
||||
|
||||
static const struct ieee80211_channel ath11k_2ghz_channels[] = {
|
||||
CHAN2G(1, 2412, 0),
|
||||
CHAN2G(2, 2417, 0),
|
||||
@ -1276,6 +1270,7 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
|
||||
struct peer_assoc_params *arg)
|
||||
{
|
||||
const struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
|
||||
u8 ampdu_factor;
|
||||
u16 v;
|
||||
|
||||
if (!he_cap->has_he)
|
||||
@ -1292,6 +1287,30 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar,
|
||||
/* the top most byte is used to indicate BSS color info */
|
||||
arg->peer_he_ops &= 0xffffff;
|
||||
|
||||
/* As per section 26.6.1 11ax Draft5.0, if the Max AMPDU Exponent Extension
|
||||
* in HE cap is zero, use the arg->peer_max_mpdu as calculated while parsing
|
||||
* VHT caps(if VHT caps is present) or HT caps (if VHT caps is not present).
|
||||
*
|
||||
* For non-zero value of Max AMPDU Extponent Extension in HE MAC caps,
|
||||
* if a HE STA sends VHT cap and HE cap IE in assoc request then, use
|
||||
* MAX_AMPDU_LEN_FACTOR as 20 to calculate max_ampdu length.
|
||||
* If a HE STA that does not send VHT cap, but HE and HT cap in assoc
|
||||
* request, then use MAX_AMPDU_LEN_FACTOR as 16 to calculate max_ampdu
|
||||
* length.
|
||||
*/
|
||||
ampdu_factor = (he_cap->he_cap_elem.mac_cap_info[3] &
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) >>
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT;
|
||||
|
||||
if (ampdu_factor) {
|
||||
if (sta->vht_cap.vht_supported)
|
||||
arg->peer_max_mpdu = (1 << (IEEE80211_HE_VHT_MAX_AMPDU_FACTOR +
|
||||
ampdu_factor)) - 1;
|
||||
else if (sta->ht_cap.ht_supported)
|
||||
arg->peer_max_mpdu = (1 << (IEEE80211_HE_HT_MAX_AMPDU_FACTOR +
|
||||
ampdu_factor)) - 1;
|
||||
}
|
||||
|
||||
if (he_cap->he_cap_elem.phy_cap_info[6] &
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
|
||||
int bit = 7;
|
||||
@ -2380,6 +2399,9 @@ static int ath11k_install_key(struct ath11k_vif *arvif,
|
||||
|
||||
reinit_completion(&ar->install_key_done);
|
||||
|
||||
if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
|
||||
return 0;
|
||||
|
||||
if (cmd == DISABLE_KEY) {
|
||||
/* TODO: Check if FW expects value other than NONE for del */
|
||||
/* arg.key_cipher = WMI_CIPHER_NONE; */
|
||||
@ -2411,8 +2433,13 @@ static int ath11k_install_key(struct ath11k_vif *arvif,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (test_bit(ATH11K_FLAG_RAW_MODE, &ar->ab->dev_flags))
|
||||
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV |
|
||||
IEEE80211_KEY_FLAG_RESERVE_TAILROOM;
|
||||
|
||||
install:
|
||||
ret = ath11k_wmi_vdev_install_key(arvif->ar, &arg);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -2484,6 +2511,9 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
key->cipher == WLAN_CIPHER_SUITE_BIP_CMAC_256)
|
||||
return 1;
|
||||
|
||||
if (test_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ar->ab->dev_flags))
|
||||
return 1;
|
||||
|
||||
if (key->keyidx > WMI_MAX_KEY_INDEX)
|
||||
return -ENOSPC;
|
||||
|
||||
@ -4436,6 +4466,8 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
|
||||
if (ieee80211_set_hw_80211_encap(vif, hw_encap))
|
||||
param_value = ATH11K_HW_TXRX_ETHERNET;
|
||||
else if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
|
||||
param_value = ATH11K_HW_TXRX_RAW;
|
||||
else
|
||||
param_value = ATH11K_HW_TXRX_NATIVE_WIFI;
|
||||
|
||||
@ -6089,7 +6121,7 @@ static int __ath11k_mac_register(struct ath11k *ar)
|
||||
ret = ath11k_mac_setup_channels_rates(ar,
|
||||
cap->supported_bands);
|
||||
if (ret)
|
||||
goto err_free;
|
||||
goto err;
|
||||
|
||||
ath11k_mac_setup_ht_vht_cap(ar, cap, &ht_cap);
|
||||
ath11k_mac_setup_he_cap(ar, cap);
|
||||
@ -6109,7 +6141,6 @@ static int __ath11k_mac_register(struct ath11k *ar)
|
||||
ieee80211_hw_set(ar->hw, HAS_RATE_CONTROL);
|
||||
ieee80211_hw_set(ar->hw, AP_LINK_PS);
|
||||
ieee80211_hw_set(ar->hw, SPECTRUM_MGMT);
|
||||
ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
|
||||
ieee80211_hw_set(ar->hw, CONNECTION_MONITOR);
|
||||
ieee80211_hw_set(ar->hw, SUPPORTS_PER_STA_GTK);
|
||||
ieee80211_hw_set(ar->hw, WANT_MONITOR_VIF);
|
||||
@ -6176,8 +6207,11 @@ static int __ath11k_mac_register(struct ath11k *ar)
|
||||
|
||||
ath11k_reg_init(ar);
|
||||
|
||||
/* advertise HW checksum offload capabilities */
|
||||
ar->hw->netdev_features = NETIF_F_HW_CSUM;
|
||||
if (!test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags)) {
|
||||
ar->hw->netdev_features = NETIF_F_HW_CSUM;
|
||||
ieee80211_hw_set(ar->hw, SW_CRYPTO_CONTROL);
|
||||
ieee80211_hw_set(ar->hw, SUPPORT_FAST_XMIT);
|
||||
}
|
||||
|
||||
ret = ieee80211_register_hw(ar->hw);
|
||||
if (ret) {
|
||||
@ -6203,7 +6237,9 @@ static int __ath11k_mac_register(struct ath11k *ar)
|
||||
err_free:
|
||||
kfree(ar->mac.sbands[NL80211_BAND_2GHZ].channels);
|
||||
kfree(ar->mac.sbands[NL80211_BAND_5GHZ].channels);
|
||||
kfree(ar->mac.sbands[NL80211_BAND_6GHZ].channels);
|
||||
|
||||
err:
|
||||
SET_IEEE80211_DEV(ar->hw, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
|
||||
|
||||
mhi_ctrl = kzalloc(sizeof(*mhi_ctrl), GFP_KERNEL);
|
||||
if (!mhi_ctrl)
|
||||
return PTR_ERR(mhi_ctrl);
|
||||
return -ENOMEM;
|
||||
|
||||
ath11k_core_create_firmware_path(ab, ATH11K_AMSS_FILE,
|
||||
ab_pci->amss_path,
|
||||
|
@ -51,187 +51,6 @@ static const struct ath11k_msi_config msi_config = {
|
||||
},
|
||||
};
|
||||
|
||||
/* Target firmware's Copy Engine configuration. */
|
||||
static const struct ce_pipe_config target_ce_config_wlan[] = {
|
||||
/* CE0: host->target HTC control and raw streams */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(0),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE1: target->host HTT + HTC control */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(1),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE2: target->host WMI */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(2),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE3: host->target WMI */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(3),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE4: host->target HTT */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(4),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_OUT),
|
||||
.nentries = __cpu_to_le32(256),
|
||||
.nbytes_max = __cpu_to_le32(256),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE5: target->host Pktlog */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(5),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_IN),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(2048),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE6: Reserved for target autonomous hif_memcpy */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(6),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(16384),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE7 used only by Host */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(7),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT_H2H),
|
||||
.nentries = __cpu_to_le32(0),
|
||||
.nbytes_max = __cpu_to_le32(0),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
|
||||
/* CE8 target->host used only by IPA */
|
||||
{
|
||||
.pipenum = __cpu_to_le32(8),
|
||||
.pipedir = __cpu_to_le32(PIPEDIR_INOUT),
|
||||
.nentries = __cpu_to_le32(32),
|
||||
.nbytes_max = __cpu_to_le32(16384),
|
||||
.flags = __cpu_to_le32(CE_ATTR_FLAGS),
|
||||
.reserved = __cpu_to_le32(0),
|
||||
},
|
||||
/* CE 9, 10, 11 are used by MHI driver */
|
||||
};
|
||||
|
||||
/* Map from service/endpoint to Copy Engine.
|
||||
* This table is derived from the CE_PCI TABLE, above.
|
||||
* It is passed to the Target at startup for use by firmware.
|
||||
*/
|
||||
static const struct service_to_pipe target_service_to_ce_map_wlan[] = {
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VO),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BK),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_BE),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_DATA_VI),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(3),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_WMI_CONTROL),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(0),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_RSVD_CTRL),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(2),
|
||||
},
|
||||
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
||||
__cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */
|
||||
__cpu_to_le32(4),
|
||||
},
|
||||
{
|
||||
__cpu_to_le32(ATH11K_HTC_SVC_ID_HTT_DATA_MSG),
|
||||
__cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */
|
||||
__cpu_to_le32(1),
|
||||
},
|
||||
|
||||
/* (Additions here) */
|
||||
|
||||
{ /* must be last */
|
||||
__cpu_to_le32(0),
|
||||
__cpu_to_le32(0),
|
||||
__cpu_to_le32(0),
|
||||
},
|
||||
};
|
||||
|
||||
static const char *irq_name[ATH11K_IRQ_NUM_MAX] = {
|
||||
"bhi",
|
||||
"mhi-er0",
|
||||
@ -648,9 +467,12 @@ static int ath11k_pci_ext_irq_config(struct ath11k_base *ab)
|
||||
int i, j, ret, num_vectors = 0;
|
||||
u32 user_base_data = 0, base_vector = 0;
|
||||
|
||||
ath11k_pci_get_user_msi_assignment(ath11k_pci_priv(ab), "DP",
|
||||
&num_vectors, &user_base_data,
|
||||
&base_vector);
|
||||
ret = ath11k_pci_get_user_msi_assignment(ath11k_pci_priv(ab), "DP",
|
||||
&num_vectors,
|
||||
&user_base_data,
|
||||
&base_vector);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) {
|
||||
struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
|
||||
@ -754,11 +576,11 @@ static void ath11k_pci_init_qmi_ce_config(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg;
|
||||
|
||||
cfg->tgt_ce = target_ce_config_wlan;
|
||||
cfg->tgt_ce_len = ARRAY_SIZE(target_ce_config_wlan);
|
||||
cfg->tgt_ce = ab->hw_params.target_ce_config;
|
||||
cfg->tgt_ce_len = ab->hw_params.target_ce_count;
|
||||
|
||||
cfg->svc_to_ce_map = target_service_to_ce_map_wlan;
|
||||
cfg->svc_to_ce_map_len = ARRAY_SIZE(target_service_to_ce_map_wlan);
|
||||
cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map;
|
||||
cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len;
|
||||
ab->qmi.service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390;
|
||||
}
|
||||
|
||||
@ -962,8 +784,8 @@ static int ath11k_pci_map_service_to_pipe(struct ath11k_base *ab, u16 service_id
|
||||
bool ul_set = false, dl_set = false;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) {
|
||||
entry = &target_service_to_ce_map_wlan[i];
|
||||
for (i = 0; i < ab->hw_params.svc_to_ce_map_len; i++) {
|
||||
entry = &ab->hw_params.svc_to_ce_map[i];
|
||||
|
||||
if (__le32_to_cpu(entry->service_id) != service_id)
|
||||
continue;
|
||||
|
@ -1868,16 +1868,16 @@ ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type,
|
||||
const struct firmware *fw_entry;
|
||||
struct ath11k_board_data bd;
|
||||
u32 fw_size;
|
||||
int ret = 0;
|
||||
|
||||
memset(&bd, 0, sizeof(bd));
|
||||
int ret;
|
||||
|
||||
switch (type) {
|
||||
case ATH11K_QMI_FILE_TYPE_BDF_GOLDEN:
|
||||
memset(&bd, 0, sizeof(bd));
|
||||
|
||||
ret = ath11k_core_fetch_bdf(ab, &bd);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "qmi failed to load BDF\n");
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
|
||||
@ -1886,10 +1886,11 @@ ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type,
|
||||
break;
|
||||
case ATH11K_QMI_FILE_TYPE_CALDATA:
|
||||
fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
|
||||
if (ret) {
|
||||
if (IS_ERR(fw_entry)) {
|
||||
ret = PTR_ERR(fw_entry);
|
||||
ath11k_warn(ab, "failed to load %s: %d\n",
|
||||
ATH11K_DEFAULT_CAL_FILE, ret);
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
|
||||
fw_size = min_t(u32, ab->hw_params.fw.board_size,
|
||||
@ -1901,14 +1902,11 @@ ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type,
|
||||
release_firmware(fw_entry);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
req->total_size = fw_size;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab)
|
||||
|
@ -773,6 +773,8 @@ static int ath11k_spectral_process_data(struct ath11k *ar,
|
||||
i += sizeof(*tlv) + tlv_len;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
err:
|
||||
kfree(fft_sample);
|
||||
unlock:
|
||||
|
@ -3366,6 +3366,10 @@ int ath11k_wmi_cmd_init(struct ath11k_base *ab)
|
||||
config.rx_timeout_pri[2] = TARGET_RX_TIMEOUT_LO_PRI;
|
||||
config.rx_timeout_pri[3] = TARGET_RX_TIMEOUT_HI_PRI;
|
||||
config.rx_decap_mode = TARGET_DECAP_MODE_NATIVE_WIFI;
|
||||
|
||||
if (test_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags))
|
||||
config.rx_decap_mode = TARGET_DECAP_MODE_RAW;
|
||||
|
||||
config.scan_max_pending_req = TARGET_SCAN_MAX_PENDING_REQS;
|
||||
config.bmiss_offload_max_vdev = TARGET_BMISS_OFFLOAD_MAX_VDEV;
|
||||
config.roam_offload_max_vdev = TARGET_ROAM_OFFLOAD_MAX_VDEV;
|
||||
|
@ -1536,12 +1536,12 @@ ath5k_set_current_imask(struct ath5k_hw *ah)
|
||||
}
|
||||
|
||||
static void
|
||||
ath5k_tasklet_rx(unsigned long data)
|
||||
ath5k_tasklet_rx(struct tasklet_struct *t)
|
||||
{
|
||||
struct ath5k_rx_status rs = {};
|
||||
struct sk_buff *skb, *next_skb;
|
||||
dma_addr_t next_skb_addr;
|
||||
struct ath5k_hw *ah = (void *)data;
|
||||
struct ath5k_hw *ah = from_tasklet(ah, t, rxtq);
|
||||
struct ath_common *common = ath5k_hw_common(ah);
|
||||
struct ath5k_buf *bf;
|
||||
struct ath5k_desc *ds;
|
||||
@ -1784,10 +1784,10 @@ ath5k_tx_processq(struct ath5k_hw *ah, struct ath5k_txq *txq)
|
||||
}
|
||||
|
||||
static void
|
||||
ath5k_tasklet_tx(unsigned long data)
|
||||
ath5k_tasklet_tx(struct tasklet_struct *t)
|
||||
{
|
||||
int i;
|
||||
struct ath5k_hw *ah = (void *)data;
|
||||
struct ath5k_hw *ah = from_tasklet(ah, t, txtq);
|
||||
|
||||
for (i = 0; i < AR5K_NUM_TX_QUEUES; i++)
|
||||
if (ah->txqs[i].setup && (ah->ah_txq_isr_txok_all & BIT(i)))
|
||||
@ -2176,9 +2176,9 @@ ath5k_beacon_config(struct ath5k_hw *ah)
|
||||
spin_unlock_bh(&ah->block);
|
||||
}
|
||||
|
||||
static void ath5k_tasklet_beacon(unsigned long data)
|
||||
static void ath5k_tasklet_beacon(struct tasklet_struct *t)
|
||||
{
|
||||
struct ath5k_hw *ah = (struct ath5k_hw *) data;
|
||||
struct ath5k_hw *ah = from_tasklet(ah, t, beacontq);
|
||||
|
||||
/*
|
||||
* Software beacon alert--time to send a beacon.
|
||||
@ -2447,9 +2447,9 @@ ath5k_calibrate_work(struct work_struct *work)
|
||||
|
||||
|
||||
static void
|
||||
ath5k_tasklet_ani(unsigned long data)
|
||||
ath5k_tasklet_ani(struct tasklet_struct *t)
|
||||
{
|
||||
struct ath5k_hw *ah = (void *)data;
|
||||
struct ath5k_hw *ah = from_tasklet(ah, t, ani_tasklet);
|
||||
|
||||
ah->ah_cal_mask |= AR5K_CALIBRATION_ANI;
|
||||
ath5k_ani_calibration(ah);
|
||||
@ -3069,10 +3069,10 @@ ath5k_init(struct ieee80211_hw *hw)
|
||||
hw->queues = 1;
|
||||
}
|
||||
|
||||
tasklet_init(&ah->rxtq, ath5k_tasklet_rx, (unsigned long)ah);
|
||||
tasklet_init(&ah->txtq, ath5k_tasklet_tx, (unsigned long)ah);
|
||||
tasklet_init(&ah->beacontq, ath5k_tasklet_beacon, (unsigned long)ah);
|
||||
tasklet_init(&ah->ani_tasklet, ath5k_tasklet_ani, (unsigned long)ah);
|
||||
tasklet_setup(&ah->rxtq, ath5k_tasklet_rx);
|
||||
tasklet_setup(&ah->txtq, ath5k_tasklet_tx);
|
||||
tasklet_setup(&ah->beacontq, ath5k_tasklet_beacon);
|
||||
tasklet_setup(&ah->ani_tasklet, ath5k_tasklet_ani);
|
||||
|
||||
INIT_WORK(&ah->reset_work, ath5k_reset_work);
|
||||
INIT_WORK(&ah->calib_work, ath5k_calibrate_work);
|
||||
|
@ -73,9 +73,9 @@ ath5k_is_rfkill_set(struct ath5k_hw *ah)
|
||||
}
|
||||
|
||||
static void
|
||||
ath5k_tasklet_rfkill_toggle(unsigned long data)
|
||||
ath5k_tasklet_rfkill_toggle(struct tasklet_struct *t)
|
||||
{
|
||||
struct ath5k_hw *ah = (void *)data;
|
||||
struct ath5k_hw *ah = from_tasklet(ah, t, rf_kill.toggleq);
|
||||
bool blocked;
|
||||
|
||||
blocked = ath5k_is_rfkill_set(ah);
|
||||
@ -90,8 +90,7 @@ ath5k_rfkill_hw_start(struct ath5k_hw *ah)
|
||||
ah->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin;
|
||||
ah->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol;
|
||||
|
||||
tasklet_init(&ah->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle,
|
||||
(unsigned long)ah);
|
||||
tasklet_setup(&ah->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle);
|
||||
|
||||
ath5k_rfkill_disable(ah);
|
||||
|
||||
|
@ -1201,8 +1201,7 @@ static int ath6kl_wmi_pstream_timeout_event_rx(struct wmi *wmi, u8 *datap,
|
||||
static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
|
||||
{
|
||||
struct wmi_bit_rate_reply *reply;
|
||||
s32 rate;
|
||||
u32 sgi, index;
|
||||
u32 index;
|
||||
|
||||
if (len < sizeof(struct wmi_bit_rate_reply))
|
||||
return -EINVAL;
|
||||
@ -1211,15 +1210,10 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_WMI, "rateindex %d\n", reply->rate_index);
|
||||
|
||||
if (reply->rate_index == (s8) RATE_AUTO) {
|
||||
rate = RATE_AUTO;
|
||||
} else {
|
||||
if (reply->rate_index != (s8) RATE_AUTO) {
|
||||
index = reply->rate_index & 0x7f;
|
||||
if (WARN_ON_ONCE(index > (RATE_MCS_7_40 + 1)))
|
||||
return -EINVAL;
|
||||
|
||||
sgi = (reply->rate_index & 0x80) ? 1 : 0;
|
||||
rate = wmi_rate_tbl[index][sgi];
|
||||
}
|
||||
|
||||
ath6kl_wakeup_event(wmi->parent_dev);
|
||||
|
@ -22,10 +22,10 @@ config ATH9K
|
||||
tristate "Atheros 802.11n wireless cards support"
|
||||
depends on MAC80211 && HAS_DMA
|
||||
select ATH9K_HW
|
||||
select MAC80211_LEDS
|
||||
select LEDS_CLASS
|
||||
select NEW_LEDS
|
||||
select ATH9K_COMMON
|
||||
imply NEW_LEDS
|
||||
imply LEDS_CLASS
|
||||
imply MAC80211_LEDS
|
||||
help
|
||||
This module adds support for wireless adapters based on
|
||||
Atheros IEEE 802.11n AR5008, AR9001 and AR9002 family
|
||||
@ -177,10 +177,10 @@ config ATH9K_HTC
|
||||
tristate "Atheros HTC based wireless cards support"
|
||||
depends on USB && MAC80211
|
||||
select ATH9K_HW
|
||||
select MAC80211_LEDS
|
||||
select LEDS_CLASS
|
||||
select NEW_LEDS
|
||||
select ATH9K_COMMON
|
||||
imply NEW_LEDS
|
||||
imply LEDS_CLASS
|
||||
imply MAC80211_LEDS
|
||||
help
|
||||
Support for Atheros HTC based cards.
|
||||
Chipsets supported: AR9271
|
||||
|
@ -459,12 +459,6 @@ static const u32 ar5416Common[][2] = {
|
||||
{0x0000a3e0, 0x000001ce},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x000098b0, 0x1e5795e5},
|
||||
{0x000098e0, 0x02008020},
|
||||
};
|
||||
|
||||
static const u32 ar5416BB_RfGain[][3] = {
|
||||
/* Addr 5G 2G */
|
||||
{0x00009a00, 0x00000000, 0x00000000},
|
||||
@ -533,60 +527,6 @@ static const u32 ar5416BB_RfGain[][3] = {
|
||||
{0x00009afc, 0x000000f9, 0x000000f9},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank1[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x000098b0, 0x02108421},
|
||||
{0x000098ec, 0x00000008},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank2[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x000098b0, 0x0e73ff17},
|
||||
{0x000098e0, 0x00000420},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank3[][3] = {
|
||||
/* Addr 5G 2G */
|
||||
{0x000098f0, 0x01400018, 0x01c00018},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank6[][3] = {
|
||||
/* Addr 5G 2G */
|
||||
{0x0000989c, 0x00000000, 0x00000000},
|
||||
{0x0000989c, 0x00000000, 0x00000000},
|
||||
{0x0000989c, 0x00000000, 0x00000000},
|
||||
{0x0000989c, 0x00e00000, 0x00e00000},
|
||||
{0x0000989c, 0x005e0000, 0x005e0000},
|
||||
{0x0000989c, 0x00120000, 0x00120000},
|
||||
{0x0000989c, 0x00620000, 0x00620000},
|
||||
{0x0000989c, 0x00020000, 0x00020000},
|
||||
{0x0000989c, 0x00ff0000, 0x00ff0000},
|
||||
{0x0000989c, 0x00ff0000, 0x00ff0000},
|
||||
{0x0000989c, 0x00ff0000, 0x00ff0000},
|
||||
{0x0000989c, 0x40ff0000, 0x40ff0000},
|
||||
{0x0000989c, 0x005f0000, 0x005f0000},
|
||||
{0x0000989c, 0x00870000, 0x00870000},
|
||||
{0x0000989c, 0x00f90000, 0x00f90000},
|
||||
{0x0000989c, 0x007b0000, 0x007b0000},
|
||||
{0x0000989c, 0x00ff0000, 0x00ff0000},
|
||||
{0x0000989c, 0x00f50000, 0x00f50000},
|
||||
{0x0000989c, 0x00dc0000, 0x00dc0000},
|
||||
{0x0000989c, 0x00110000, 0x00110000},
|
||||
{0x0000989c, 0x006100a8, 0x006100a8},
|
||||
{0x0000989c, 0x004210a2, 0x004210a2},
|
||||
{0x0000989c, 0x0014008f, 0x0014008f},
|
||||
{0x0000989c, 0x00c40003, 0x00c40003},
|
||||
{0x0000989c, 0x003000f2, 0x003000f2},
|
||||
{0x0000989c, 0x00440016, 0x00440016},
|
||||
{0x0000989c, 0x00410040, 0x00410040},
|
||||
{0x0000989c, 0x0001805e, 0x0001805e},
|
||||
{0x0000989c, 0x0000c0ab, 0x0000c0ab},
|
||||
{0x0000989c, 0x000000f1, 0x000000f1},
|
||||
{0x0000989c, 0x00002081, 0x00002081},
|
||||
{0x0000989c, 0x000000d4, 0x000000d4},
|
||||
{0x000098d0, 0x0000000f, 0x0010000f},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank6TPC[][3] = {
|
||||
/* Addr 5G 2G */
|
||||
{0x0000989c, 0x00000000, 0x00000000},
|
||||
@ -624,13 +564,6 @@ static const u32 ar5416Bank6TPC[][3] = {
|
||||
{0x000098d0, 0x0000000f, 0x0010000f},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank7[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000989c, 0x00000500},
|
||||
{0x0000989c, 0x00000800},
|
||||
{0x000098cc, 0x0000000e},
|
||||
};
|
||||
|
||||
static const u32 ar5416Addac[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000989c, 0x00000000},
|
||||
@ -671,4 +604,3 @@ static const u32 ar5416Addac[][2] = {
|
||||
{0x0000989c, 0x00000000},
|
||||
{0x000098c4, 0x00000000},
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "hw-ops.h"
|
||||
#include "../regd.h"
|
||||
#include "ar9002_phy.h"
|
||||
#include "ar5008_initvals.h"
|
||||
|
||||
/* All code below is for AR5008, AR9001, AR9002 */
|
||||
|
||||
@ -51,6 +50,36 @@ static const int m2ThreshLowExt_off = 127;
|
||||
static const int m1ThreshExt_off = 127;
|
||||
static const int m2ThreshExt_off = 127;
|
||||
|
||||
static const u32 ar5416Bank0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x000098b0, 0x1e5795e5},
|
||||
{0x000098e0, 0x02008020},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank1[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x000098b0, 0x02108421},
|
||||
{0x000098ec, 0x00000008},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank2[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x000098b0, 0x0e73ff17},
|
||||
{0x000098e0, 0x00000420},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank3[][3] = {
|
||||
/* Addr 5G 2G */
|
||||
{0x000098f0, 0x01400018, 0x01c00018},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank7[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000989c, 0x00000500},
|
||||
{0x0000989c, 0x00000800},
|
||||
{0x000098cc, 0x0000000e},
|
||||
};
|
||||
|
||||
static const struct ar5416IniArray bank0 = STATIC_INI_ARRAY(ar5416Bank0);
|
||||
static const struct ar5416IniArray bank1 = STATIC_INI_ARRAY(ar5416Bank1);
|
||||
static const struct ar5416IniArray bank2 = STATIC_INI_ARRAY(ar5416Bank2);
|
||||
|
@ -459,43 +459,6 @@ static const u32 ar5416Common_9100[][2] = {
|
||||
{0x0000a3e0, 0x000001ce},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank6_9100[][3] = {
|
||||
/* Addr 5G 2G */
|
||||
{0x0000989c, 0x00000000, 0x00000000},
|
||||
{0x0000989c, 0x00000000, 0x00000000},
|
||||
{0x0000989c, 0x00000000, 0x00000000},
|
||||
{0x0000989c, 0x00e00000, 0x00e00000},
|
||||
{0x0000989c, 0x005e0000, 0x005e0000},
|
||||
{0x0000989c, 0x00120000, 0x00120000},
|
||||
{0x0000989c, 0x00620000, 0x00620000},
|
||||
{0x0000989c, 0x00020000, 0x00020000},
|
||||
{0x0000989c, 0x00ff0000, 0x00ff0000},
|
||||
{0x0000989c, 0x00ff0000, 0x00ff0000},
|
||||
{0x0000989c, 0x00ff0000, 0x00ff0000},
|
||||
{0x0000989c, 0x00ff0000, 0x00ff0000},
|
||||
{0x0000989c, 0x005f0000, 0x005f0000},
|
||||
{0x0000989c, 0x00870000, 0x00870000},
|
||||
{0x0000989c, 0x00f90000, 0x00f90000},
|
||||
{0x0000989c, 0x007b0000, 0x007b0000},
|
||||
{0x0000989c, 0x00ff0000, 0x00ff0000},
|
||||
{0x0000989c, 0x00f50000, 0x00f50000},
|
||||
{0x0000989c, 0x00dc0000, 0x00dc0000},
|
||||
{0x0000989c, 0x00110000, 0x00110000},
|
||||
{0x0000989c, 0x006100a8, 0x006100a8},
|
||||
{0x0000989c, 0x004210a2, 0x004210a2},
|
||||
{0x0000989c, 0x0014000f, 0x0014000f},
|
||||
{0x0000989c, 0x00c40002, 0x00c40002},
|
||||
{0x0000989c, 0x003000f2, 0x003000f2},
|
||||
{0x0000989c, 0x00440016, 0x00440016},
|
||||
{0x0000989c, 0x00410040, 0x00410040},
|
||||
{0x0000989c, 0x000180d6, 0x000180d6},
|
||||
{0x0000989c, 0x0000c0aa, 0x0000c0aa},
|
||||
{0x0000989c, 0x000000b1, 0x000000b1},
|
||||
{0x0000989c, 0x00002000, 0x00002000},
|
||||
{0x0000989c, 0x000000d4, 0x000000d4},
|
||||
{0x000098d0, 0x0000000f, 0x0010000f},
|
||||
};
|
||||
|
||||
static const u32 ar5416Bank6TPC_9100[][3] = {
|
||||
/* Addr 5G 2G */
|
||||
{0x0000989c, 0x00000000, 0x00000000},
|
||||
|
@ -897,20 +897,6 @@ static const u32 ar9280Modes_original_tx_gain_9280_2[][5] = {
|
||||
{0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480},
|
||||
};
|
||||
|
||||
static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00004040, 0x9248fd00},
|
||||
{0x00004040, 0x24924924},
|
||||
{0x00004040, 0xa8000019},
|
||||
{0x00004040, 0x13160820},
|
||||
{0x00004040, 0xe5980560},
|
||||
{0x00004040, 0xc01dcffc},
|
||||
{0x00004040, 0x1aaabe41},
|
||||
{0x00004040, 0xbe105554},
|
||||
{0x00004040, 0x00043007},
|
||||
{0x00004044, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00004040, 0x9248fd00},
|
||||
|
@ -713,7 +713,7 @@ struct ath_beacon {
|
||||
bool tx_last;
|
||||
};
|
||||
|
||||
void ath9k_beacon_tasklet(unsigned long data);
|
||||
void ath9k_beacon_tasklet(struct tasklet_struct *t);
|
||||
void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif,
|
||||
bool beacons);
|
||||
void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
|
||||
@ -1117,7 +1117,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
|
||||
common->bus_ops->read_cachesize(common, csz);
|
||||
}
|
||||
|
||||
void ath9k_tasklet(unsigned long data);
|
||||
void ath9k_tasklet(struct tasklet_struct *t);
|
||||
int ath_cabq_update(struct ath_softc *);
|
||||
u8 ath9k_parse_mpdudensity(u8 mpdudensity);
|
||||
irqreturn_t ath_isr(int irq, void *dev);
|
||||
|
@ -385,9 +385,9 @@ void ath9k_csa_update(struct ath_softc *sc)
|
||||
ath9k_csa_update_vif, sc);
|
||||
}
|
||||
|
||||
void ath9k_beacon_tasklet(unsigned long data)
|
||||
void ath9k_beacon_tasklet(struct tasklet_struct *t)
|
||||
{
|
||||
struct ath_softc *sc = (struct ath_softc *)data;
|
||||
struct ath_softc *sc = from_tasklet(sc, t, bcon_tasklet);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath_buf *bf = NULL;
|
||||
|
@ -583,14 +583,14 @@ int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv);
|
||||
void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot);
|
||||
void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv);
|
||||
void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event);
|
||||
void ath9k_tx_failed_tasklet(unsigned long data);
|
||||
void ath9k_tx_failed_tasklet(struct tasklet_struct *t);
|
||||
void ath9k_htc_tx_cleanup_timer(struct timer_list *t);
|
||||
bool ath9k_htc_csa_is_finished(struct ath9k_htc_priv *priv);
|
||||
|
||||
int ath9k_rx_init(struct ath9k_htc_priv *priv);
|
||||
void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
|
||||
void ath9k_host_rx_init(struct ath9k_htc_priv *priv);
|
||||
void ath9k_rx_tasklet(unsigned long data);
|
||||
void ath9k_rx_tasklet(struct tasklet_struct *t);
|
||||
u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv);
|
||||
|
||||
void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv);
|
||||
|
@ -645,10 +645,8 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
|
||||
spin_lock_init(&priv->tx.tx_lock);
|
||||
mutex_init(&priv->mutex);
|
||||
mutex_init(&priv->htc_pm_lock);
|
||||
tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
|
||||
(unsigned long)priv);
|
||||
tasklet_init(&priv->tx_failed_tasklet, ath9k_tx_failed_tasklet,
|
||||
(unsigned long)priv);
|
||||
tasklet_setup(&priv->rx_tasklet, ath9k_rx_tasklet);
|
||||
tasklet_setup(&priv->tx_failed_tasklet, ath9k_tx_failed_tasklet);
|
||||
INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work);
|
||||
INIT_WORK(&priv->ps_work, ath9k_ps_work);
|
||||
INIT_WORK(&priv->fatal_work, ath9k_fatal_work);
|
||||
|
@ -570,9 +570,9 @@ void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv)
|
||||
spin_unlock_bh(&priv->tx.tx_lock);
|
||||
}
|
||||
|
||||
void ath9k_tx_failed_tasklet(unsigned long data)
|
||||
void ath9k_tx_failed_tasklet(struct tasklet_struct *t)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
|
||||
struct ath9k_htc_priv *priv = from_tasklet(priv, t, tx_failed_tasklet);
|
||||
|
||||
spin_lock(&priv->tx.tx_lock);
|
||||
if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
|
||||
@ -1062,9 +1062,9 @@ rx_next:
|
||||
/*
|
||||
* FIXME: Handle FLUSH later on.
|
||||
*/
|
||||
void ath9k_rx_tasklet(unsigned long data)
|
||||
void ath9k_rx_tasklet(struct tasklet_struct *t)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
|
||||
struct ath9k_htc_priv *priv = from_tasklet(priv, t, rx_tasklet);
|
||||
struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
|
||||
struct ieee80211_rx_status rx_status;
|
||||
struct sk_buff *skb;
|
||||
|
@ -728,9 +728,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
|
||||
spin_lock_init(&sc->sc_pm_lock);
|
||||
spin_lock_init(&sc->chan_lock);
|
||||
mutex_init(&sc->mutex);
|
||||
tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
|
||||
tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
|
||||
(unsigned long)sc);
|
||||
tasklet_setup(&sc->intr_tq, ath9k_tasklet);
|
||||
tasklet_setup(&sc->bcon_tasklet, ath9k_beacon_tasklet);
|
||||
|
||||
timer_setup(&sc->sleep_timer, ath_ps_full_sleep, 0);
|
||||
INIT_WORK(&sc->hw_reset_work, ath_reset_work);
|
||||
|
@ -371,9 +371,9 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
|
||||
ath_dynack_node_deinit(sc->sc_ah, an);
|
||||
}
|
||||
|
||||
void ath9k_tasklet(unsigned long data)
|
||||
void ath9k_tasklet(struct tasklet_struct *t)
|
||||
{
|
||||
struct ath_softc *sc = (struct ath_softc *)data;
|
||||
struct ath_softc *sc = from_tasklet(sc, t, intr_tq);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
enum ath_reset_type type;
|
||||
|
@ -106,8 +106,7 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
|
||||
mutex_init(&wmi->multi_rmw_mutex);
|
||||
init_completion(&wmi->cmd_wait);
|
||||
INIT_LIST_HEAD(&wmi->pending_tx_events);
|
||||
tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
|
||||
(unsigned long)wmi);
|
||||
tasklet_setup(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet);
|
||||
|
||||
return wmi;
|
||||
}
|
||||
@ -136,9 +135,9 @@ void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv)
|
||||
spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
|
||||
}
|
||||
|
||||
void ath9k_wmi_event_tasklet(unsigned long data)
|
||||
void ath9k_wmi_event_tasklet(struct tasklet_struct *t)
|
||||
{
|
||||
struct wmi *wmi = (struct wmi *)data;
|
||||
struct wmi *wmi = from_tasklet(wmi, t, wmi_event_tasklet);
|
||||
struct ath9k_htc_priv *priv = wmi->drv_priv;
|
||||
struct wmi_cmd_hdr *hdr;
|
||||
void *wmi_event;
|
||||
|
@ -185,7 +185,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
|
||||
u8 *cmd_buf, u32 cmd_len,
|
||||
u8 *rsp_buf, u32 rsp_len,
|
||||
u32 timeout);
|
||||
void ath9k_wmi_event_tasklet(unsigned long data);
|
||||
void ath9k_wmi_event_tasklet(struct tasklet_struct *t);
|
||||
void ath9k_fatal_work(struct work_struct *work);
|
||||
void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv);
|
||||
void ath9k_stop_wmi(struct ath9k_htc_priv *priv);
|
||||
|
@ -68,7 +68,10 @@
|
||||
|
||||
#define PAYLOAD_MAX (CARL9170_MAX_CMD_LEN / 4 - 1)
|
||||
|
||||
static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 };
|
||||
static inline u8 ar9170_qmap(u8 idx)
|
||||
{
|
||||
return 3 - idx; /* { 3, 2, 1, 0 } */
|
||||
}
|
||||
|
||||
#define CARL9170_MAX_RX_BUFFER_SIZE 8192
|
||||
|
||||
|
@ -1374,7 +1374,7 @@ static int carl9170_op_conf_tx(struct ieee80211_hw *hw,
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ar->mutex);
|
||||
memcpy(&ar->edcf[ar9170_qmap[queue]], param, sizeof(*param));
|
||||
memcpy(&ar->edcf[ar9170_qmap(queue)], param, sizeof(*param));
|
||||
ret = carl9170_set_qos(ar);
|
||||
mutex_unlock(&ar->mutex);
|
||||
return ret;
|
||||
|
@ -766,7 +766,7 @@ static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len)
|
||||
|
||||
goto drop;
|
||||
}
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
|
||||
case AR9170_RX_STATUS_MPDU_MIDDLE:
|
||||
/* These are just data + mac status */
|
||||
|
@ -663,7 +663,7 @@ static void __carl9170_tx_process_status(struct ar9170 *ar,
|
||||
unsigned int r, t, q;
|
||||
bool success = true;
|
||||
|
||||
q = ar9170_qmap[info & CARL9170_TX_STATUS_QUEUE];
|
||||
q = ar9170_qmap(info & CARL9170_TX_STATUS_QUEUE);
|
||||
|
||||
skb = carl9170_get_queued_skb(ar, cookie, &ar->tx_status[q]);
|
||||
if (!skb) {
|
||||
@ -830,12 +830,12 @@ static bool carl9170_tx_rts_check(struct ar9170 *ar,
|
||||
case CARL9170_ERP_AUTO:
|
||||
if (ampdu)
|
||||
break;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
|
||||
case CARL9170_ERP_MAC80211:
|
||||
if (!(rate->flags & IEEE80211_TX_RC_USE_RTS_CTS))
|
||||
break;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
|
||||
case CARL9170_ERP_RTS:
|
||||
if (likely(!multi))
|
||||
@ -856,7 +856,7 @@ static bool carl9170_tx_cts_check(struct ar9170 *ar,
|
||||
case CARL9170_ERP_MAC80211:
|
||||
if (!(rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
|
||||
break;
|
||||
/* fall through */
|
||||
fallthrough;
|
||||
|
||||
case CARL9170_ERP_CTS:
|
||||
return true;
|
||||
@ -979,7 +979,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar,
|
||||
((CARL9170_TX_SUPER_MISC_VIF_ID >>
|
||||
CARL9170_TX_SUPER_MISC_VIF_ID_S) + 1));
|
||||
|
||||
hw_queue = ar9170_qmap[carl9170_get_queue(ar, skb)];
|
||||
hw_queue = ar9170_qmap(carl9170_get_queue(ar, skb));
|
||||
|
||||
hdr = (void *)skb->data;
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
@ -1279,7 +1279,7 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb)
|
||||
|
||||
super = (void *)skb->data;
|
||||
SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, q,
|
||||
ar9170_qmap[carl9170_get_queue(ar, skb)]);
|
||||
ar9170_qmap(carl9170_get_queue(ar, skb)));
|
||||
__carl9170_tx_process_status(ar, super->s.cookie, q);
|
||||
}
|
||||
|
||||
|
@ -377,9 +377,9 @@ void carl9170_usb_handle_tx_err(struct ar9170 *ar)
|
||||
}
|
||||
}
|
||||
|
||||
static void carl9170_usb_tasklet(unsigned long data)
|
||||
static void carl9170_usb_tasklet(struct tasklet_struct *t)
|
||||
{
|
||||
struct ar9170 *ar = (struct ar9170 *) data;
|
||||
struct ar9170 *ar = from_tasklet(ar, t, usb_tasklet);
|
||||
|
||||
if (!IS_INITIALIZED(ar))
|
||||
return;
|
||||
@ -1082,8 +1082,7 @@ static int carl9170_usb_probe(struct usb_interface *intf,
|
||||
init_completion(&ar->cmd_wait);
|
||||
init_completion(&ar->fw_boot_wait);
|
||||
init_completion(&ar->fw_load_wait);
|
||||
tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet,
|
||||
(unsigned long)ar);
|
||||
tasklet_setup(&ar->usb_tasklet, carl9170_usb_tasklet);
|
||||
|
||||
atomic_set(&ar->tx_cmd_urbs, 0);
|
||||
atomic_set(&ar->tx_anch_urbs, 0);
|
||||
|
@ -728,6 +728,14 @@ enum pe_stats_mask {
|
||||
#define WCN36XX_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE 104
|
||||
#define WCN36XX_HAL_CFG_MAX_PARAMS 105
|
||||
|
||||
/* Specify the starting bitrate, 11B and 11A/G rates can be specified in
|
||||
* multiples of 0.5 So for 5.5 mbps => 11. for MCS 0 - 7 rates, Bit 7 should
|
||||
* set to 1 and Bit 0-6 represent the MCS index. so for MCS2 => 130.
|
||||
* Any invalid non-zero value or unsupported rate will set the start rate
|
||||
* to 6 mbps.
|
||||
*/
|
||||
#define WCN36XX_HAL_CFG_ENABLE_DYNAMIC_RA_START_RATE 210
|
||||
|
||||
/* Message definitons - All the messages below need to be packed */
|
||||
|
||||
/* Definition for HAL API Version. */
|
||||
@ -1405,6 +1413,76 @@ struct wcn36xx_hal_config_sta_req_msg {
|
||||
struct wcn36xx_hal_config_sta_params sta_params;
|
||||
} __packed;
|
||||
|
||||
struct wcn36xx_hal_supported_rates_v1 {
|
||||
/* For Self STA Entry: this represents Self Mode.
|
||||
* For Peer Stations, this represents the mode of the peer.
|
||||
* On Station:
|
||||
*
|
||||
* --this mode is updated when PE adds the Self Entry.
|
||||
*
|
||||
* -- OR when PE sends 'ADD_BSS' message and station context in BSS
|
||||
* is used to indicate the mode of the AP.
|
||||
*
|
||||
* ON AP:
|
||||
*
|
||||
* -- this mode is updated when PE sends 'ADD_BSS' and Sta entry
|
||||
* for that BSS is used to indicate the self mode of the AP.
|
||||
*
|
||||
* -- OR when a station is associated, PE sends 'ADD_STA' message
|
||||
* with this mode updated.
|
||||
*/
|
||||
|
||||
enum sta_rate_mode op_rate_mode;
|
||||
|
||||
/* 11b, 11a and aniLegacyRates are IE rates which gives rate in
|
||||
* unit of 500Kbps
|
||||
*/
|
||||
u16 dsss_rates[WCN36XX_HAL_NUM_DSSS_RATES];
|
||||
u16 ofdm_rates[WCN36XX_HAL_NUM_OFDM_RATES];
|
||||
u16 legacy_rates[WCN36XX_HAL_NUM_POLARIS_RATES];
|
||||
u16 reserved;
|
||||
|
||||
/* Taurus only supports 26 Titan Rates(no ESF/concat Rates will be
|
||||
* supported) First 26 bits are reserved for those Titan rates and
|
||||
* the last 4 bits(bit28-31) for Taurus, 2(bit26-27) bits are
|
||||
* reserved
|
||||
* Titan and Taurus Rates
|
||||
*/
|
||||
u32 enhanced_rate_bitmap;
|
||||
|
||||
/* 0-76 bits used, remaining reserved
|
||||
* bits 0-15 and 32 should be set.
|
||||
*/
|
||||
u8 supported_mcs_set[WCN36XX_HAL_MAC_MAX_SUPPORTED_MCS_SET];
|
||||
|
||||
/* RX Highest Supported Data Rate defines the highest data
|
||||
* rate that the STA is able to receive, in unites of 1Mbps.
|
||||
* This value is derived from "Supported MCS Set field" inside
|
||||
* the HT capability element.
|
||||
*/
|
||||
u16 rx_highest_data_rate;
|
||||
|
||||
/* Indicates the Maximum MCS that can be received for each spatial
|
||||
* stream.
|
||||
*/
|
||||
u16 vht_rx_mcs_map;
|
||||
|
||||
/* Indicates the highest VHT data rate that the STA is able to
|
||||
* receive.
|
||||
*/
|
||||
u16 vht_rx_highest_data_rate;
|
||||
|
||||
/* Indicates the Maximum MCS that can be transmitted for each spatial
|
||||
* stream.
|
||||
*/
|
||||
u16 vht_tx_mcs_map;
|
||||
|
||||
/* Indicates the highest VHT data rate that the STA is able to
|
||||
* transmit.
|
||||
*/
|
||||
u16 vht_tx_highest_data_rate;
|
||||
} __packed;
|
||||
|
||||
struct wcn36xx_hal_config_sta_params_v1 {
|
||||
/* BSSID of STA */
|
||||
u8 bssid[ETH_ALEN];
|
||||
@ -1507,7 +1585,11 @@ struct wcn36xx_hal_config_sta_params_v1 {
|
||||
u8 p2p;
|
||||
|
||||
/* Reserved to align next field on a dword boundary */
|
||||
u8 reserved;
|
||||
u8 ht_ldpc_enabled:1;
|
||||
u8 vht_ldpc_enabled:1;
|
||||
u8 vht_tx_bf_enabled:1;
|
||||
u8 vht_tx_mu_beamformee_capable:1;
|
||||
u8 reserved:4;
|
||||
|
||||
/* These rates are the intersection of peer and self capabilities. */
|
||||
struct wcn36xx_hal_supported_rates supported_rates;
|
||||
|
@ -354,8 +354,6 @@ static void wcn36xx_stop(struct ieee80211_hw *hw)
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac stop\n");
|
||||
|
||||
cancel_work_sync(&wcn->scan_work);
|
||||
|
||||
mutex_lock(&wcn->scan_lock);
|
||||
if (wcn->scan_req) {
|
||||
struct cfg80211_scan_info scan_info = {
|
||||
@ -378,11 +376,36 @@ static void wcn36xx_stop(struct ieee80211_hw *hw)
|
||||
kfree(wcn->hal_buf);
|
||||
}
|
||||
|
||||
static void wcn36xx_change_ps(struct wcn36xx *wcn, bool enable)
|
||||
{
|
||||
struct ieee80211_vif *vif = NULL;
|
||||
struct wcn36xx_vif *tmp;
|
||||
|
||||
list_for_each_entry(tmp, &wcn->vif_list, list) {
|
||||
vif = wcn36xx_priv_to_vif(tmp);
|
||||
if (enable && !wcn->sw_scan) {
|
||||
if (vif->bss_conf.ps) /* ps allowed ? */
|
||||
wcn36xx_pmc_enter_bmps_state(wcn, vif);
|
||||
} else {
|
||||
wcn36xx_pmc_exit_bmps_state(wcn, vif);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch)
|
||||
{
|
||||
struct ieee80211_vif *vif = NULL;
|
||||
struct wcn36xx_vif *tmp;
|
||||
|
||||
list_for_each_entry(tmp, &wcn->vif_list, list) {
|
||||
vif = wcn36xx_priv_to_vif(tmp);
|
||||
wcn36xx_smd_switch_channel(wcn, vif, ch);
|
||||
}
|
||||
}
|
||||
|
||||
static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
|
||||
{
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
struct ieee80211_vif *vif = NULL;
|
||||
struct wcn36xx_vif *tmp;
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x\n", changed);
|
||||
|
||||
@ -392,23 +415,28 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
|
||||
int ch = WCN36XX_HW_CHANNEL(wcn);
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n",
|
||||
ch);
|
||||
list_for_each_entry(tmp, &wcn->vif_list, list) {
|
||||
vif = wcn36xx_priv_to_vif(tmp);
|
||||
wcn36xx_smd_switch_channel(wcn, vif, ch);
|
||||
|
||||
if (wcn->sw_scan_opchannel == ch) {
|
||||
/* If channel is the initial operating channel, we may
|
||||
* want to receive/transmit regular data packets, then
|
||||
* simply stop the scan session and exit PS mode.
|
||||
*/
|
||||
wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN,
|
||||
wcn->sw_scan_vif);
|
||||
} else if (wcn->sw_scan) {
|
||||
/* A scan is ongoing, do not change the operating
|
||||
* channel, but start a scan session on the channel.
|
||||
*/
|
||||
wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN,
|
||||
wcn->sw_scan_vif);
|
||||
wcn36xx_smd_start_scan(wcn, ch);
|
||||
} else {
|
||||
wcn36xx_change_opchannel(wcn, ch);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_PS) {
|
||||
list_for_each_entry(tmp, &wcn->vif_list, list) {
|
||||
vif = wcn36xx_priv_to_vif(tmp);
|
||||
if (hw->conf.flags & IEEE80211_CONF_PS) {
|
||||
if (vif->bss_conf.ps) /* ps allowed ? */
|
||||
wcn36xx_pmc_enter_bmps_state(wcn, vif);
|
||||
} else {
|
||||
wcn36xx_pmc_exit_bmps_state(wcn, vif);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed & IEEE80211_CONF_CHANGE_PS)
|
||||
wcn36xx_change_ps(wcn, hw->conf.flags & IEEE80211_CONF_PS);
|
||||
|
||||
mutex_unlock(&wcn->conf_mutex);
|
||||
|
||||
@ -582,6 +610,15 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
}
|
||||
}
|
||||
}
|
||||
/* FIXME: Only enable bmps support when encryption is enabled.
|
||||
* For any reasons, when connected to open/no-security BSS,
|
||||
* the wcn36xx controller in bmps mode does not forward
|
||||
* 'wake-up' beacons despite AP sends DTIM with station AID.
|
||||
* It could be due to a firmware issue or to the way driver
|
||||
* configure the station.
|
||||
*/
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
vif_priv->allow_bmps = true;
|
||||
break;
|
||||
case DISABLE_KEY:
|
||||
if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) {
|
||||
@ -614,55 +651,26 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wcn36xx_hw_scan_worker(struct work_struct *work)
|
||||
{
|
||||
struct wcn36xx *wcn = container_of(work, struct wcn36xx, scan_work);
|
||||
struct cfg80211_scan_request *req = wcn->scan_req;
|
||||
u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX];
|
||||
struct cfg80211_scan_info scan_info = {};
|
||||
bool aborted = false;
|
||||
int i;
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 scan %d channels worker\n", req->n_channels);
|
||||
|
||||
for (i = 0; i < req->n_channels; i++)
|
||||
channels[i] = req->channels[i]->hw_value;
|
||||
|
||||
wcn36xx_smd_update_scan_params(wcn, channels, req->n_channels);
|
||||
|
||||
wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN);
|
||||
for (i = 0; i < req->n_channels; i++) {
|
||||
mutex_lock(&wcn->scan_lock);
|
||||
aborted = wcn->scan_aborted;
|
||||
mutex_unlock(&wcn->scan_lock);
|
||||
|
||||
if (aborted)
|
||||
break;
|
||||
|
||||
wcn->scan_freq = req->channels[i]->center_freq;
|
||||
wcn->scan_band = req->channels[i]->band;
|
||||
|
||||
wcn36xx_smd_start_scan(wcn, req->channels[i]->hw_value);
|
||||
msleep(30);
|
||||
wcn36xx_smd_end_scan(wcn, req->channels[i]->hw_value);
|
||||
|
||||
wcn->scan_freq = 0;
|
||||
}
|
||||
wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN);
|
||||
|
||||
scan_info.aborted = aborted;
|
||||
ieee80211_scan_completed(wcn->hw, &scan_info);
|
||||
|
||||
mutex_lock(&wcn->scan_lock);
|
||||
wcn->scan_req = NULL;
|
||||
mutex_unlock(&wcn->scan_lock);
|
||||
}
|
||||
|
||||
static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_scan_request *hw_req)
|
||||
{
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
int i;
|
||||
|
||||
if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
|
||||
/* fallback to mac80211 software scan */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* For unknown reason, the hardware offloaded scan only works with
|
||||
* 2.4Ghz channels, fallback to software scan in other cases.
|
||||
*/
|
||||
for (i = 0; i < hw_req->req.n_channels; i++) {
|
||||
if (hw_req->req.channels[i]->band != NL80211_BAND_2GHZ)
|
||||
return 1;
|
||||
}
|
||||
|
||||
mutex_lock(&wcn->scan_lock);
|
||||
if (wcn->scan_req) {
|
||||
mutex_unlock(&wcn->scan_lock);
|
||||
@ -674,12 +682,6 @@ static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
|
||||
|
||||
mutex_unlock(&wcn->scan_lock);
|
||||
|
||||
if (!get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
|
||||
/* legacy manual/sw scan */
|
||||
schedule_work(&wcn->scan_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req);
|
||||
}
|
||||
|
||||
@ -696,16 +698,35 @@ static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw,
|
||||
/* ieee80211_scan_completed will be called on FW scan
|
||||
* indication */
|
||||
wcn36xx_smd_stop_hw_scan(wcn);
|
||||
} else {
|
||||
struct cfg80211_scan_info scan_info = {
|
||||
.aborted = true,
|
||||
};
|
||||
|
||||
cancel_work_sync(&wcn->scan_work);
|
||||
ieee80211_scan_completed(wcn->hw, &scan_info);
|
||||
}
|
||||
}
|
||||
|
||||
static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
const u8 *mac_addr)
|
||||
{
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
|
||||
|
||||
wcn->sw_scan = true;
|
||||
wcn->sw_scan_vif = vif;
|
||||
if (vif_priv->sta_assoc)
|
||||
wcn->sw_scan_opchannel = WCN36XX_HW_CHANNEL(wcn);
|
||||
else
|
||||
wcn->sw_scan_opchannel = 0;
|
||||
}
|
||||
|
||||
static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct wcn36xx *wcn = hw->priv;
|
||||
|
||||
/* ensure that any scan session is finished */
|
||||
wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN, wcn->sw_scan_vif);
|
||||
wcn->sw_scan = false;
|
||||
wcn->sw_scan_opchannel = 0;
|
||||
}
|
||||
|
||||
static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
|
||||
enum nl80211_band band)
|
||||
{
|
||||
@ -879,6 +900,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
|
||||
vif->addr,
|
||||
bss_conf->aid);
|
||||
vif_priv->sta_assoc = false;
|
||||
vif_priv->allow_bmps = false;
|
||||
wcn36xx_smd_set_link_st(wcn,
|
||||
bss_conf->bssid,
|
||||
vif->addr,
|
||||
@ -1151,6 +1173,8 @@ static const struct ieee80211_ops wcn36xx_ops = {
|
||||
.set_key = wcn36xx_set_key,
|
||||
.hw_scan = wcn36xx_hw_scan,
|
||||
.cancel_hw_scan = wcn36xx_cancel_hw_scan,
|
||||
.sw_scan_start = wcn36xx_sw_scan_start,
|
||||
.sw_scan_complete = wcn36xx_sw_scan_complete,
|
||||
.bss_info_changed = wcn36xx_bss_info_changed,
|
||||
.set_rts_threshold = wcn36xx_set_rts_threshold,
|
||||
.sta_add = wcn36xx_sta_add,
|
||||
@ -1283,6 +1307,8 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
|
||||
if (iris_node) {
|
||||
if (of_device_is_compatible(iris_node, "qcom,wcn3620"))
|
||||
wcn->rf_id = RF_IRIS_WCN3620;
|
||||
if (of_device_is_compatible(iris_node, "qcom,wcn3680"))
|
||||
wcn->rf_id = RF_IRIS_WCN3680;
|
||||
of_node_put(iris_node);
|
||||
}
|
||||
|
||||
@ -1329,8 +1355,6 @@ static int wcn36xx_probe(struct platform_device *pdev)
|
||||
goto out_wq;
|
||||
}
|
||||
|
||||
INIT_WORK(&wcn->scan_work, wcn36xx_hw_scan_worker);
|
||||
|
||||
wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process, hw);
|
||||
if (IS_ERR(wcn->smd_channel)) {
|
||||
wcn36xx_err("failed to open WLAN_CTRL channel\n");
|
||||
|
@ -23,7 +23,10 @@ int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn,
|
||||
{
|
||||
int ret = 0;
|
||||
struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
|
||||
/* TODO: Make sure the TX chain clean */
|
||||
|
||||
if (!vif_priv->allow_bmps)
|
||||
return -ENOTSUPP;
|
||||
|
||||
ret = wcn36xx_smd_enter_bmps(wcn, vif);
|
||||
if (!ret) {
|
||||
wcn36xx_dbg(WCN36XX_DBG_PMC, "Entered BMPS\n");
|
||||
|
@ -77,6 +77,7 @@ static struct wcn36xx_cfg_val wcn36xx_cfg_vals[] = {
|
||||
WCN36XX_CFG_VAL(BTC_STATIC_LEN_LE_WLAN, 30000),
|
||||
WCN36XX_CFG_VAL(MAX_ASSOC_LIMIT, 10),
|
||||
WCN36XX_CFG_VAL(ENABLE_MCC_ADAPTIVE_SCHEDULER, 0),
|
||||
WCN36XX_CFG_VAL(ENABLE_DYNAMIC_RA_START_RATE, 133), /* MCS 5 */
|
||||
};
|
||||
|
||||
static int put_cfg_tlv_u32(struct wcn36xx *wcn, size_t *len, u32 id, u32 value)
|
||||
@ -517,8 +518,10 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode)
|
||||
int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
|
||||
struct wcn36xx_hal_init_scan_req_msg msg_body;
|
||||
int ret;
|
||||
|
||||
@ -526,6 +529,13 @@ int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode)
|
||||
INIT_HAL_MSG(msg_body, WCN36XX_HAL_INIT_SCAN_REQ);
|
||||
|
||||
msg_body.mode = mode;
|
||||
if (vif_priv->bss_index != WCN36XX_HAL_BSS_INVALID_IDX) {
|
||||
/* Notify BSSID with null DATA packet */
|
||||
msg_body.frame_type = 2;
|
||||
msg_body.notify = 1;
|
||||
msg_body.scan_entry.bss_index[0] = vif_priv->bss_index;
|
||||
msg_body.scan_entry.active_bss_count = 1;
|
||||
}
|
||||
|
||||
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
|
||||
|
||||
@ -607,8 +617,10 @@ out:
|
||||
}
|
||||
|
||||
int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
|
||||
enum wcn36xx_hal_sys_mode mode)
|
||||
enum wcn36xx_hal_sys_mode mode,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
|
||||
struct wcn36xx_hal_finish_scan_req_msg msg_body;
|
||||
int ret;
|
||||
|
||||
@ -616,6 +628,14 @@ int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
|
||||
INIT_HAL_MSG(msg_body, WCN36XX_HAL_FINISH_SCAN_REQ);
|
||||
|
||||
msg_body.mode = mode;
|
||||
msg_body.oper_channel = WCN36XX_HW_CHANNEL(wcn);
|
||||
if (vif_priv->bss_index != WCN36XX_HAL_BSS_INVALID_IDX) {
|
||||
/* Notify BSSID with null data packet */
|
||||
msg_body.notify = 1;
|
||||
msg_body.frame_type = 2;
|
||||
msg_body.scan_entry.bss_index[0] = vif_priv->bss_index;
|
||||
msg_body.scan_entry.active_bss_count = 1;
|
||||
}
|
||||
|
||||
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
|
||||
|
||||
@ -1279,87 +1299,71 @@ static int wcn36xx_smd_config_bss_v1(struct wcn36xx *wcn,
|
||||
sta = &bss->sta;
|
||||
|
||||
/* convert orig to v1 */
|
||||
memcpy(&msg_body->bss_params.bssid,
|
||||
&orig->bss_params.bssid, ETH_ALEN);
|
||||
memcpy(&msg_body->bss_params.self_mac_addr,
|
||||
&orig->bss_params.self_mac_addr, ETH_ALEN);
|
||||
memcpy(bss->bssid, &orig->bss_params.bssid, ETH_ALEN);
|
||||
memcpy(bss->self_mac_addr, &orig->bss_params.self_mac_addr, ETH_ALEN);
|
||||
|
||||
msg_body->bss_params.bss_type = orig->bss_params.bss_type;
|
||||
msg_body->bss_params.oper_mode = orig->bss_params.oper_mode;
|
||||
msg_body->bss_params.nw_type = orig->bss_params.nw_type;
|
||||
bss->bss_type = orig->bss_params.bss_type;
|
||||
bss->oper_mode = orig->bss_params.oper_mode;
|
||||
bss->nw_type = orig->bss_params.nw_type;
|
||||
|
||||
msg_body->bss_params.short_slot_time_supported =
|
||||
bss->short_slot_time_supported =
|
||||
orig->bss_params.short_slot_time_supported;
|
||||
msg_body->bss_params.lla_coexist = orig->bss_params.lla_coexist;
|
||||
msg_body->bss_params.llb_coexist = orig->bss_params.llb_coexist;
|
||||
msg_body->bss_params.llg_coexist = orig->bss_params.llg_coexist;
|
||||
msg_body->bss_params.ht20_coexist = orig->bss_params.ht20_coexist;
|
||||
msg_body->bss_params.lln_non_gf_coexist =
|
||||
orig->bss_params.lln_non_gf_coexist;
|
||||
bss->lla_coexist = orig->bss_params.lla_coexist;
|
||||
bss->llb_coexist = orig->bss_params.llb_coexist;
|
||||
bss->llg_coexist = orig->bss_params.llg_coexist;
|
||||
bss->ht20_coexist = orig->bss_params.ht20_coexist;
|
||||
bss->lln_non_gf_coexist = orig->bss_params.lln_non_gf_coexist;
|
||||
|
||||
msg_body->bss_params.lsig_tx_op_protection_full_support =
|
||||
bss->lsig_tx_op_protection_full_support =
|
||||
orig->bss_params.lsig_tx_op_protection_full_support;
|
||||
msg_body->bss_params.rifs_mode = orig->bss_params.rifs_mode;
|
||||
msg_body->bss_params.beacon_interval = orig->bss_params.beacon_interval;
|
||||
msg_body->bss_params.dtim_period = orig->bss_params.dtim_period;
|
||||
msg_body->bss_params.tx_channel_width_set =
|
||||
orig->bss_params.tx_channel_width_set;
|
||||
msg_body->bss_params.oper_channel = orig->bss_params.oper_channel;
|
||||
msg_body->bss_params.ext_channel = orig->bss_params.ext_channel;
|
||||
bss->rifs_mode = orig->bss_params.rifs_mode;
|
||||
bss->beacon_interval = orig->bss_params.beacon_interval;
|
||||
bss->dtim_period = orig->bss_params.dtim_period;
|
||||
bss->tx_channel_width_set = orig->bss_params.tx_channel_width_set;
|
||||
bss->oper_channel = orig->bss_params.oper_channel;
|
||||
bss->ext_channel = orig->bss_params.ext_channel;
|
||||
|
||||
msg_body->bss_params.reserved = orig->bss_params.reserved;
|
||||
bss->reserved = orig->bss_params.reserved;
|
||||
|
||||
memcpy(&msg_body->bss_params.ssid,
|
||||
&orig->bss_params.ssid,
|
||||
memcpy(&bss->ssid, &orig->bss_params.ssid,
|
||||
sizeof(orig->bss_params.ssid));
|
||||
|
||||
msg_body->bss_params.action = orig->bss_params.action;
|
||||
msg_body->bss_params.rateset = orig->bss_params.rateset;
|
||||
msg_body->bss_params.ht = orig->bss_params.ht;
|
||||
msg_body->bss_params.obss_prot_enabled =
|
||||
orig->bss_params.obss_prot_enabled;
|
||||
msg_body->bss_params.rmf = orig->bss_params.rmf;
|
||||
msg_body->bss_params.ht_oper_mode = orig->bss_params.ht_oper_mode;
|
||||
msg_body->bss_params.dual_cts_protection =
|
||||
orig->bss_params.dual_cts_protection;
|
||||
bss->action = orig->bss_params.action;
|
||||
bss->rateset = orig->bss_params.rateset;
|
||||
bss->ht = orig->bss_params.ht;
|
||||
bss->obss_prot_enabled = orig->bss_params.obss_prot_enabled;
|
||||
bss->rmf = orig->bss_params.rmf;
|
||||
bss->ht_oper_mode = orig->bss_params.ht_oper_mode;
|
||||
bss->dual_cts_protection = orig->bss_params.dual_cts_protection;
|
||||
|
||||
msg_body->bss_params.max_probe_resp_retry_limit =
|
||||
bss->max_probe_resp_retry_limit =
|
||||
orig->bss_params.max_probe_resp_retry_limit;
|
||||
msg_body->bss_params.hidden_ssid = orig->bss_params.hidden_ssid;
|
||||
msg_body->bss_params.proxy_probe_resp =
|
||||
orig->bss_params.proxy_probe_resp;
|
||||
msg_body->bss_params.edca_params_valid =
|
||||
orig->bss_params.edca_params_valid;
|
||||
bss->hidden_ssid = orig->bss_params.hidden_ssid;
|
||||
bss->proxy_probe_resp = orig->bss_params.proxy_probe_resp;
|
||||
bss->edca_params_valid = orig->bss_params.edca_params_valid;
|
||||
|
||||
memcpy(&msg_body->bss_params.acbe,
|
||||
&orig->bss_params.acbe,
|
||||
memcpy(&bss->acbe, &orig->bss_params.acbe,
|
||||
sizeof(orig->bss_params.acbe));
|
||||
memcpy(&msg_body->bss_params.acbk,
|
||||
&orig->bss_params.acbk,
|
||||
memcpy(&bss->acbk, &orig->bss_params.acbk,
|
||||
sizeof(orig->bss_params.acbk));
|
||||
memcpy(&msg_body->bss_params.acvi,
|
||||
&orig->bss_params.acvi,
|
||||
memcpy(&bss->acvi, &orig->bss_params.acvi,
|
||||
sizeof(orig->bss_params.acvi));
|
||||
memcpy(&msg_body->bss_params.acvo,
|
||||
&orig->bss_params.acvo,
|
||||
memcpy(&bss->acvo, &orig->bss_params.acvo,
|
||||
sizeof(orig->bss_params.acvo));
|
||||
|
||||
msg_body->bss_params.ext_set_sta_key_param_valid =
|
||||
bss->ext_set_sta_key_param_valid =
|
||||
orig->bss_params.ext_set_sta_key_param_valid;
|
||||
|
||||
memcpy(&msg_body->bss_params.ext_set_sta_key_param,
|
||||
memcpy(&bss->ext_set_sta_key_param,
|
||||
&orig->bss_params.ext_set_sta_key_param,
|
||||
sizeof(orig->bss_params.acvo));
|
||||
|
||||
msg_body->bss_params.wcn36xx_hal_persona =
|
||||
orig->bss_params.wcn36xx_hal_persona;
|
||||
msg_body->bss_params.spectrum_mgt_enable =
|
||||
orig->bss_params.spectrum_mgt_enable;
|
||||
msg_body->bss_params.tx_mgmt_power = orig->bss_params.tx_mgmt_power;
|
||||
msg_body->bss_params.max_tx_power = orig->bss_params.max_tx_power;
|
||||
bss->wcn36xx_hal_persona = orig->bss_params.wcn36xx_hal_persona;
|
||||
bss->spectrum_mgt_enable = orig->bss_params.spectrum_mgt_enable;
|
||||
bss->tx_mgmt_power = orig->bss_params.tx_mgmt_power;
|
||||
bss->max_tx_power = orig->bss_params.max_tx_power;
|
||||
|
||||
wcn36xx_smd_convert_sta_to_v1(wcn, &orig->bss_params.sta,
|
||||
&msg_body->bss_params.sta);
|
||||
wcn36xx_smd_convert_sta_to_v1(wcn, &orig->bss_params.sta, sta);
|
||||
|
||||
PREPARE_HAL_BUF(wcn->hal_buf, (*msg_body));
|
||||
|
||||
@ -2080,6 +2084,8 @@ int wcn36xx_smd_feature_caps_exchange(struct wcn36xx *wcn)
|
||||
INIT_HAL_MSG(msg_body, WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_REQ);
|
||||
|
||||
set_feat_caps(msg_body.feat_caps, STA_POWERSAVE);
|
||||
if (wcn->rf_id == RF_IRIS_WCN3680)
|
||||
set_feat_caps(msg_body.feat_caps, DOT11AC);
|
||||
|
||||
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
|
||||
|
||||
|
@ -59,11 +59,13 @@ void wcn36xx_smd_close(struct wcn36xx *wcn);
|
||||
int wcn36xx_smd_load_nv(struct wcn36xx *wcn);
|
||||
int wcn36xx_smd_start(struct wcn36xx *wcn);
|
||||
int wcn36xx_smd_stop(struct wcn36xx *wcn);
|
||||
int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode);
|
||||
int wcn36xx_smd_start_scan(struct wcn36xx *wcn, u8 scan_channel);
|
||||
int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel);
|
||||
int wcn36xx_smd_finish_scan(struct wcn36xx *wcn,
|
||||
enum wcn36xx_hal_sys_mode mode);
|
||||
int wcn36xx_smd_finish_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode,
|
||||
struct ieee80211_vif *vif);
|
||||
int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode,
|
||||
struct ieee80211_vif *vif);
|
||||
|
||||
int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn, u8 *channels, size_t channel_count);
|
||||
int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif,
|
||||
struct cfg80211_scan_request *req);
|
||||
|
@ -114,7 +114,114 @@ static const struct wcn36xx_rate wcn36xx_rate_table[] = {
|
||||
{ 1215, 6, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_40 },
|
||||
{ 1350, 7, RX_ENC_HT, RX_ENC_FLAG_HT_GF, RATE_INFO_BW_40 },
|
||||
|
||||
/* TODO: AC rates */
|
||||
/* 11ac reserved indices */
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac 20 MHz 800ns GI MCS 0-8 */
|
||||
{ 65, 0, RX_ENC_HT, 0, RATE_INFO_BW_20 },
|
||||
{ 130, 1, RX_ENC_HT, 0, RATE_INFO_BW_20 },
|
||||
{ 195, 2, RX_ENC_HT, 0, RATE_INFO_BW_20 },
|
||||
{ 260, 3, RX_ENC_HT, 0, RATE_INFO_BW_20 },
|
||||
{ 390, 4, RX_ENC_HT, 0, RATE_INFO_BW_20 },
|
||||
{ 520, 5, RX_ENC_HT, 0, RATE_INFO_BW_20 },
|
||||
{ 585, 6, RX_ENC_HT, 0, RATE_INFO_BW_20 },
|
||||
{ 650, 7, RX_ENC_HT, 0, RATE_INFO_BW_20 },
|
||||
{ 780, 8, RX_ENC_HT, 0, RATE_INFO_BW_20 },
|
||||
|
||||
/* 11ac reserved indices */
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac 20 MHz 400ns SGI MCS 6-8 */
|
||||
{ 655, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 },
|
||||
{ 722, 7, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 },
|
||||
{ 866, 8, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_20 },
|
||||
|
||||
/* 11ac reserved indices */
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac 40 MHz 800ns GI MCS 0-9 */
|
||||
{ 135, 0, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
{ 270, 1, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
{ 405, 2, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
{ 540, 3, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
{ 810, 4, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
{ 1080, 5, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
{ 1215, 6, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
{ 1350, 7, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
{ 1350, 7, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
{ 1620, 8, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
{ 1800, 9, RX_ENC_HT, 0, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac reserved indices */
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac 40 MHz 400ns SGI MCS 5-7 */
|
||||
{ 1200, 5, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1500, 7, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac reserved index */
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac 40 MHz 400ns SGI MCS 5-7 */
|
||||
{ 1800, 8, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 2000, 9, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac reserved index */
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac 80 MHz 800ns GI MCS 0-7 */
|
||||
{ 292, 0, RX_ENC_HT, 0, RATE_INFO_BW_80},
|
||||
{ 585, 1, RX_ENC_HT, 0, RATE_INFO_BW_80},
|
||||
{ 877, 2, RX_ENC_HT, 0, RATE_INFO_BW_80},
|
||||
{ 1170, 3, RX_ENC_HT, 0, RATE_INFO_BW_80},
|
||||
{ 1755, 4, RX_ENC_HT, 0, RATE_INFO_BW_80},
|
||||
{ 2340, 5, RX_ENC_HT, 0, RATE_INFO_BW_80},
|
||||
{ 2632, 6, RX_ENC_HT, 0, RATE_INFO_BW_80},
|
||||
{ 2925, 7, RX_ENC_HT, 0, RATE_INFO_BW_80},
|
||||
|
||||
/* 11 ac reserved index */
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac 80 MHz 800 ns GI MCS 8-9 */
|
||||
{ 3510, 8, RX_ENC_HT, 0, RATE_INFO_BW_80},
|
||||
{ 3900, 9, RX_ENC_HT, 0, RATE_INFO_BW_80},
|
||||
|
||||
/* 11 ac reserved indices */
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac 80 MHz 400 ns SGI MCS 6-7 */
|
||||
{ 2925, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 },
|
||||
{ 3250, 7, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 },
|
||||
|
||||
/* 11ac reserved index */
|
||||
{ 1350, 6, RX_ENC_HT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_40 },
|
||||
|
||||
/* 11ac 80 MHz 400ns SGI MCS 8-9 */
|
||||
{ 3900, 8, RX_ENC_VHT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 },
|
||||
{ 4333, 9, RX_ENC_VHT, RX_ENC_FLAG_SHORT_GI, RATE_INFO_BW_80 },
|
||||
};
|
||||
|
||||
int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
|
||||
@ -123,6 +230,7 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
|
||||
const struct wcn36xx_rate *rate;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct wcn36xx_rx_bd *bd;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u16 fc, sn;
|
||||
|
||||
/*
|
||||
@ -144,15 +252,8 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
|
||||
fc = __le16_to_cpu(hdr->frame_control);
|
||||
sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl));
|
||||
|
||||
/* When scanning associate beacons to this */
|
||||
if (ieee80211_is_beacon(hdr->frame_control) && wcn->scan_freq) {
|
||||
status.freq = wcn->scan_freq;
|
||||
status.band = wcn->scan_band;
|
||||
} else {
|
||||
status.freq = WCN36XX_CENTER_FREQ(wcn);
|
||||
status.band = WCN36XX_BAND(wcn);
|
||||
}
|
||||
|
||||
status.freq = WCN36XX_CENTER_FREQ(wcn);
|
||||
status.band = WCN36XX_BAND(wcn);
|
||||
status.mactime = 10;
|
||||
status.signal = -get_rssi0(bd);
|
||||
status.antenna = 1;
|
||||
@ -170,6 +271,15 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
|
||||
status.enc_flags = rate->encoding_flags;
|
||||
status.bw = rate->bw;
|
||||
status.rate_idx = rate->mcs_or_legacy_index;
|
||||
sband = wcn->hw->wiphy->bands[status.band];
|
||||
status.nss = 1;
|
||||
|
||||
if (status.band == NL80211_BAND_5GHZ &&
|
||||
status.encoding == RX_ENC_LEGACY &&
|
||||
status.rate_idx >= sband->n_bitrates) {
|
||||
/* no dsss rates in 5Ghz rates table */
|
||||
status.rate_idx -= 4;
|
||||
}
|
||||
} else {
|
||||
status.encoding = 0;
|
||||
status.bw = 0;
|
||||
|
@ -92,6 +92,7 @@ enum wcn36xx_ampdu_state {
|
||||
|
||||
#define RF_UNKNOWN 0x0000
|
||||
#define RF_IRIS_WCN3620 0x3620
|
||||
#define RF_IRIS_WCN3680 0x3680
|
||||
|
||||
static inline void buff_to_be(u32 *buf, size_t len)
|
||||
{
|
||||
@ -122,6 +123,7 @@ struct wcn36xx_vif {
|
||||
enum wcn36xx_hal_bss_type bss_type;
|
||||
|
||||
/* Power management */
|
||||
bool allow_bmps;
|
||||
enum wcn36xx_power_state pw_state;
|
||||
|
||||
u8 bss_index;
|
||||
@ -223,10 +225,10 @@ struct wcn36xx {
|
||||
spinlock_t hal_ind_lock;
|
||||
struct list_head hal_ind_queue;
|
||||
|
||||
struct work_struct scan_work;
|
||||
struct cfg80211_scan_request *scan_req;
|
||||
int scan_freq;
|
||||
int scan_band;
|
||||
bool sw_scan;
|
||||
u8 sw_scan_opchannel;
|
||||
struct ieee80211_vif *sw_scan_vif;
|
||||
struct mutex scan_lock;
|
||||
bool scan_aborted;
|
||||
|
||||
|
@ -443,10 +443,10 @@ DEFINE_DEBUGFS_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get,
|
||||
|
||||
/**
|
||||
* wil6210_debugfs_init_offset - create set of debugfs files
|
||||
* @wil - driver's context, used for printing
|
||||
* @dbg - directory on the debugfs, where files will be created
|
||||
* @base - base address used in address calculation
|
||||
* @tbl - table with file descriptions. Should be terminated with empty element.
|
||||
* @wil: driver's context, used for printing
|
||||
* @dbg: directory on the debugfs, where files will be created
|
||||
* @base: base address used in address calculation
|
||||
* @tbl: table with file descriptions. Should be terminated with empty element.
|
||||
*
|
||||
* Creates files accordingly to the @tbl.
|
||||
*/
|
||||
|
@ -645,9 +645,7 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* thread IRQ handler
|
||||
*/
|
||||
/* thread IRQ handler */
|
||||
static irqreturn_t wil6210_thread_irq(int irq, void *cookie)
|
||||
{
|
||||
struct wil6210_priv *wil = cookie;
|
||||
|
@ -29,8 +29,7 @@ void wil_pmc_init(struct wil6210_priv *wil)
|
||||
mutex_init(&wil->pmc.lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate the physical ring (p-ring) and the required
|
||||
/* Allocate the physical ring (p-ring) and the required
|
||||
* number of descriptors of required size.
|
||||
* Initialize the descriptors as required by pmc dma.
|
||||
* The descriptors' buffers dwords are initialized to hold
|
||||
@ -221,8 +220,7 @@ no_release_err:
|
||||
mutex_unlock(&pmc->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse the p-ring and release all buffers.
|
||||
/* Traverse the p-ring and release all buffers.
|
||||
* At the end release the p-ring memory
|
||||
*/
|
||||
void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
|
||||
@ -299,8 +297,7 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
|
||||
mutex_unlock(&pmc->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Status of the last operation requested via debugfs: alloc/free/read.
|
||||
/* Status of the last operation requested via debugfs: alloc/free/read.
|
||||
* 0 - success or negative errno
|
||||
*/
|
||||
int wil_pmc_last_cmd_status(struct wil6210_priv *wil)
|
||||
@ -311,8 +308,7 @@ int wil_pmc_last_cmd_status(struct wil6210_priv *wil)
|
||||
return wil->pmc.last_cmd_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from required position up to the end of current descriptor,
|
||||
/* Read from required position up to the end of current descriptor,
|
||||
* depends on descriptor size configured during alloc request.
|
||||
*/
|
||||
ssize_t wil_pmc_read(struct file *filp, char __user *buf, size_t count,
|
||||
|
@ -249,8 +249,7 @@ static void wil_vring_free(struct wil6210_priv *wil, struct wil_ring *vring)
|
||||
vring->ctx = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate one skb for Rx VRING
|
||||
/* Allocate one skb for Rx VRING
|
||||
*
|
||||
* Safe to call from IRQ
|
||||
*/
|
||||
@ -295,8 +294,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct wil_ring *vring,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds radiotap header
|
||||
/* Adds radiotap header
|
||||
*
|
||||
* Any error indicated as "Bad FCS"
|
||||
*
|
||||
@ -432,8 +430,7 @@ static int wil_rx_get_cid_by_skb(struct wil6210_priv *wil, struct sk_buff *skb)
|
||||
return cid;
|
||||
}
|
||||
|
||||
/**
|
||||
* reap 1 frame from @swhead
|
||||
/* reap 1 frame from @swhead
|
||||
*
|
||||
* Rx descriptor copied to skb->cb
|
||||
*
|
||||
@ -597,8 +594,7 @@ again:
|
||||
return skb;
|
||||
}
|
||||
|
||||
/**
|
||||
* allocate and fill up to @count buffers in rx ring
|
||||
/* allocate and fill up to @count buffers in rx ring
|
||||
* buffers posted at @swtail
|
||||
* Note: we have a single RX queue for servicing all VIFs, but we
|
||||
* allocate skbs with headroom according to main interface only. This
|
||||
@ -1002,8 +998,7 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
|
||||
wil_netif_rx(skb, ndev, cid, stats, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Proceed all completed skb's from Rx VRING
|
||||
/* Proceed all completed skb's from Rx VRING
|
||||
*
|
||||
* Safe to call from NAPI poll, i.e. softirq with interrupts enabled
|
||||
*/
|
||||
@ -1629,8 +1624,7 @@ void wil_tx_desc_set_nr_frags(struct vring_tx_desc *d, int nr_frags)
|
||||
d->mac.d[2] |= (nr_frags << MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the descriptor @d up for csum and/or TSO offloading. The corresponding
|
||||
/* Sets the descriptor @d up for csum and/or TSO offloading. The corresponding
|
||||
* @skb is used to obtain the protocol and headers length.
|
||||
* @tso_desc_type is a descriptor type for TSO: 0 - a header, 1 - first data,
|
||||
* 2 - middle, 3 - last descriptor.
|
||||
@ -1660,8 +1654,7 @@ static void wil_tx_desc_offload_setup_tso(struct vring_tx_desc *d,
|
||||
d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_PSEUDO_HEADER_CALC_EN_POS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the descriptor @d up for csum. The corresponding
|
||||
/* Sets the descriptor @d up for csum. The corresponding
|
||||
* @skb is used to obtain the protocol and headers length.
|
||||
* Returns the protocol: 0 - not TCP, 1 - TCPv4, 2 - TCPv6.
|
||||
* Note, if d==NULL, the function only returns the protocol result.
|
||||
@ -2216,8 +2209,7 @@ static int wil_tx_ring(struct wil6210_priv *wil, struct wil6210_vif *vif,
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check status of tx vrings and stop/wake net queues if needed
|
||||
/* Check status of tx vrings and stop/wake net queues if needed
|
||||
* It will start/stop net queues of a specific VIF net_device.
|
||||
*
|
||||
* This function does one of two checks:
|
||||
@ -2419,8 +2411,7 @@ void wil_tx_latency_calc(struct wil6210_priv *wil, struct sk_buff *skb,
|
||||
sta->stats.tx_latency_max_us = skb_time_us;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up transmitted skb's from the Tx VRING
|
||||
/* Clean up transmitted skb's from the Tx VRING
|
||||
*
|
||||
* Return number of descriptors cleared
|
||||
*
|
||||
@ -2460,8 +2451,7 @@ int wil_tx_complete(struct wil6210_vif *vif, int ringid)
|
||||
while (!wil_ring_is_empty(vring)) {
|
||||
int new_swtail;
|
||||
struct wil_ctx *ctx = &vring->ctx[vring->swtail];
|
||||
/**
|
||||
* For the fragmented skb, HW will set DU bit only for the
|
||||
/* For the fragmented skb, HW will set DU bit only for the
|
||||
* last fragment. look for it.
|
||||
* In TSO the first DU will include hdr desc
|
||||
*/
|
||||
|
@ -147,9 +147,7 @@ out_free:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate one skb for Rx descriptor RING
|
||||
*/
|
||||
/* Allocate one skb for Rx descriptor RING */
|
||||
static int wil_ring_alloc_skb_edma(struct wil6210_priv *wil,
|
||||
struct wil_ring *ring, u32 i)
|
||||
{
|
||||
@ -1152,8 +1150,7 @@ wil_get_next_tx_status_msg(struct wil_status_ring *sring, u8 *dr_bit,
|
||||
*msg = *_msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up transmitted skb's from the Tx descriptor RING.
|
||||
/* Clean up transmitted skb's from the Tx descriptor RING.
|
||||
* Return number of descriptors cleared.
|
||||
*/
|
||||
int wil_tx_sring_handler(struct wil6210_priv *wil,
|
||||
@ -1314,8 +1311,7 @@ again:
|
||||
return desc_cnt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the descriptor @d up for csum and/or TSO offloading. The corresponding
|
||||
/* Sets the descriptor @d up for csum and/or TSO offloading. The corresponding
|
||||
* @skb is used to obtain the protocol and headers length.
|
||||
* @tso_desc_type is a descriptor type for TSO: 0 - a header, 1 - first data,
|
||||
* 2 - middle, 3 - last descriptor.
|
||||
|
@ -15,8 +15,7 @@ void wil_platform_modexit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* wil_platform_init() - wil6210 platform module init
|
||||
/* wil_platform_init() - wil6210 platform module init
|
||||
*
|
||||
* The function must be called before all other functions in this module.
|
||||
* It returns a handle which is used with the rest of the API
|
||||
|
@ -32,7 +32,7 @@ MODULE_PARM_DESC(led_id,
|
||||
#define WIL_WMI_PCP_STOP_TO_MS 5000
|
||||
|
||||
/**
|
||||
* WMI event receiving - theory of operations
|
||||
* DOC: WMI event receiving - theory of operations
|
||||
*
|
||||
* When firmware about to report WMI event, it fills memory area
|
||||
* in the mailbox and raises misc. IRQ. Thread interrupt handler invoked for
|
||||
@ -49,7 +49,7 @@ MODULE_PARM_DESC(led_id,
|
||||
*/
|
||||
|
||||
/**
|
||||
* Addressing - theory of operations
|
||||
* DOC: Addressing - theory of operations
|
||||
*
|
||||
* There are several buses present on the WIL6210 card.
|
||||
* Same memory areas are visible at different address on
|
||||
@ -66,8 +66,7 @@ MODULE_PARM_DESC(led_id,
|
||||
* AHB address must be used.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @sparrow_fw_mapping provides memory remapping table for sparrow
|
||||
/* sparrow_fw_mapping provides memory remapping table for sparrow
|
||||
*
|
||||
* array size should be in sync with the declaration in the wil6210.h
|
||||
*
|
||||
@ -103,16 +102,14 @@ const struct fw_map sparrow_fw_mapping[] = {
|
||||
{0x800000, 0x804000, 0x940000, "uc_data", false, false},
|
||||
};
|
||||
|
||||
/**
|
||||
* @sparrow_d0_mac_rgf_ext - mac_rgf_ext section for Sparrow D0
|
||||
/* sparrow_d0_mac_rgf_ext - mac_rgf_ext section for Sparrow D0
|
||||
* it is a bit larger to support extra features
|
||||
*/
|
||||
const struct fw_map sparrow_d0_mac_rgf_ext = {
|
||||
0x88c000, 0x88c500, 0x88c000, "mac_rgf_ext", true, true
|
||||
};
|
||||
|
||||
/**
|
||||
* @talyn_fw_mapping provides memory remapping table for Talyn
|
||||
/* talyn_fw_mapping provides memory remapping table for Talyn
|
||||
*
|
||||
* array size should be in sync with the declaration in the wil6210.h
|
||||
*
|
||||
@ -154,8 +151,7 @@ const struct fw_map talyn_fw_mapping[] = {
|
||||
{0x800000, 0x808000, 0xa78000, "uc_data", false, false},
|
||||
};
|
||||
|
||||
/**
|
||||
* @talyn_mb_fw_mapping provides memory remapping table for Talyn-MB
|
||||
/* talyn_mb_fw_mapping provides memory remapping table for Talyn-MB
|
||||
*
|
||||
* array size should be in sync with the declaration in the wil6210.h
|
||||
*
|
||||
@ -229,7 +225,7 @@ u8 led_polarity = LED_POLARITY_LOW_ACTIVE;
|
||||
|
||||
/**
|
||||
* return AHB address for given firmware internal (linker) address
|
||||
* @x - internal address
|
||||
* @x: internal address
|
||||
* If address have no valid AHB mapping, return 0
|
||||
*/
|
||||
static u32 wmi_addr_remap(u32 x)
|
||||
@ -247,7 +243,7 @@ static u32 wmi_addr_remap(u32 x)
|
||||
|
||||
/**
|
||||
* find fw_mapping entry by section name
|
||||
* @section - section name
|
||||
* @section: section name
|
||||
*
|
||||
* Return pointer to section or NULL if not found
|
||||
*/
|
||||
@ -265,8 +261,9 @@ struct fw_map *wil_find_fw_mapping(const char *section)
|
||||
|
||||
/**
|
||||
* Check address validity for WMI buffer; remap if needed
|
||||
* @ptr - internal (linker) fw/ucode address
|
||||
* @size - if non zero, validate the block does not
|
||||
* @wil: driver data
|
||||
* @ptr: internal (linker) fw/ucode address
|
||||
* @size: if non zero, validate the block does not
|
||||
* exceed the device memory (bar)
|
||||
*
|
||||
* Valid buffer should be DWORD aligned
|
||||
@ -300,9 +297,7 @@ void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_)
|
||||
return wmi_buffer_block(wil, ptr_, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check address validity
|
||||
*/
|
||||
/* Check address validity */
|
||||
void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr)
|
||||
{
|
||||
u32 off;
|
||||
@ -1577,8 +1572,7 @@ wmi_evt_link_stats(struct wil6210_vif *vif, int id, void *d, int len)
|
||||
evt->payload, payload_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* find cid and ringid for the station vif
|
||||
/* find cid and ringid for the station vif
|
||||
*
|
||||
* return error, if other interfaces are used or ring was not found
|
||||
*/
|
||||
@ -1868,8 +1862,7 @@ wmi_evt_link_monitor(struct wil6210_vif *vif, int id, void *d, int len)
|
||||
cfg80211_cqm_rssi_notify(ndev, event_type, evt->rssi_level, GFP_KERNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some events are ignored for purpose; and need not be interpreted as
|
||||
/* Some events are ignored for purpose; and need not be interpreted as
|
||||
* "unhandled events"
|
||||
*/
|
||||
static void wmi_evt_ignore(struct wil6210_vif *vif, int id, void *d, int len)
|
||||
@ -2578,6 +2571,7 @@ out:
|
||||
|
||||
/**
|
||||
* wmi_rxon - turn radio on/off
|
||||
* @wil: driver data
|
||||
* @on: turn on if true, off otherwise
|
||||
*
|
||||
* Only switch radio. Channel should be set separately.
|
||||
|
Loading…
x
Reference in New Issue
Block a user