Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git

ath.git patches for v6.7.

Major changes:

ath12k

* WCN7850: enable 320 MHz channels in 6 GHz band

* WCN7850: hardware rfkill support

* WCN7850: enable IEEE80211_HW_SINGLE_SCAN_ON_ALL_BANDS to make scan faster

ath11k

* add chip id board name while searching board-2.bin
This commit is contained in:
Kalle Valo 2023-09-28 19:27:58 +03:00
commit 9896f0608f
46 changed files with 660 additions and 264 deletions

View File

@ -256,7 +256,7 @@ static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata,
/* always bulk-out a multiple of 4 bytes */
xferlen = (sizeof(struct ar5523_cmd_hdr) + ilen + 3) & ~3;
hdr = (struct ar5523_cmd_hdr *)cmd->buf_tx;
hdr = cmd->buf_tx;
memset(hdr, 0, sizeof(struct ar5523_cmd_hdr));
hdr->len = cpu_to_be32(xferlen);
hdr->code = cpu_to_be32(code);

View File

@ -110,7 +110,7 @@ struct ath10k_ce_ring {
struct ce_desc_64 *shadow_base;
/* keep last */
void *per_transfer_context[];
void *per_transfer_context[] __counted_by(nentries);
};
struct ath10k_ce_pipe {

View File

@ -1140,7 +1140,7 @@ void ath10k_debug_get_et_strings(struct ieee80211_hw *hw,
u32 sset, u8 *data)
{
if (sset == ETH_SS_STATS)
memcpy(data, *ath10k_gstrings_stats,
memcpy(data, ath10k_gstrings_stats,
sizeof(ath10k_gstrings_stats));
}

View File

@ -880,8 +880,7 @@ enum htt_data_tx_status {
HTT_DATA_TX_STATUS_OK = 0,
HTT_DATA_TX_STATUS_DISCARD = 1,
HTT_DATA_TX_STATUS_NO_ACK = 2,
HTT_DATA_TX_STATUS_POSTPONE = 3, /* HL only */
HTT_DATA_TX_STATUS_DOWNLOAD_FAIL = 128
HTT_DATA_TX_STATUS_POSTPONE = 3 /* HL only */
};
enum htt_data_tx_flags {

View File

@ -2964,7 +2964,6 @@ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
break;
case HTT_DATA_TX_STATUS_DISCARD:
case HTT_DATA_TX_STATUS_POSTPONE:
case HTT_DATA_TX_STATUS_DOWNLOAD_FAIL:
tx_done.status = HTT_TX_COMPL_STATE_DISCARD;
break;
default:

View File

@ -796,20 +796,16 @@ static int ath10k_htt_send_frag_desc_bank_cfg_64(struct ath10k_htt *htt)
return 0;
}
static void ath10k_htt_fill_rx_desc_offset_32(struct ath10k_hw_params *hw, void *rx_ring)
static void ath10k_htt_fill_rx_desc_offset_32(struct ath10k_hw_params *hw,
struct htt_rx_ring_setup_ring32 *rx_ring)
{
struct htt_rx_ring_setup_ring32 *ring =
(struct htt_rx_ring_setup_ring32 *)rx_ring;
ath10k_htt_rx_desc_get_offsets(hw, &ring->offsets);
ath10k_htt_rx_desc_get_offsets(hw, &rx_ring->offsets);
}
static void ath10k_htt_fill_rx_desc_offset_64(struct ath10k_hw_params *hw, void *rx_ring)
static void ath10k_htt_fill_rx_desc_offset_64(struct ath10k_hw_params *hw,
struct htt_rx_ring_setup_ring64 *rx_ring)
{
struct htt_rx_ring_setup_ring64 *ring =
(struct htt_rx_ring_setup_ring64 *)rx_ring;
ath10k_htt_rx_desc_get_offsets(hw, &ring->offsets);
ath10k_htt_rx_desc_get_offsets(hw, &rx_ring->offsets);
}
static int ath10k_htt_send_rx_ring_cfg_32(struct ath10k_htt *htt)

View File

@ -985,9 +985,15 @@ int ath11k_core_check_dt(struct ath11k_base *ab)
return 0;
}
enum ath11k_bdf_name_type {
ATH11K_BDF_NAME_FULL,
ATH11K_BDF_NAME_BUS_NAME,
ATH11K_BDF_NAME_CHIP_ID,
};
static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
size_t name_len, bool with_variant,
bool bus_type_mode)
enum ath11k_bdf_name_type name_type)
{
/* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
@ -998,11 +1004,8 @@ static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
switch (ab->id.bdf_search) {
case ATH11K_BDF_SEARCH_BUS_AND_BOARD:
if (bus_type_mode)
scnprintf(name, name_len,
"bus=%s",
ath11k_bus_str(ab->hif.bus));
else
switch (name_type) {
case ATH11K_BDF_NAME_FULL:
scnprintf(name, name_len,
"bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
ath11k_bus_str(ab->hif.bus),
@ -1012,6 +1015,19 @@ static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
ab->qmi.target.chip_id,
ab->qmi.target.board_id,
variant);
break;
case ATH11K_BDF_NAME_BUS_NAME:
scnprintf(name, name_len,
"bus=%s",
ath11k_bus_str(ab->hif.bus));
break;
case ATH11K_BDF_NAME_CHIP_ID:
scnprintf(name, name_len,
"bus=%s,qmi-chip-id=%d",
ath11k_bus_str(ab->hif.bus),
ab->qmi.target.chip_id);
break;
}
break;
default:
scnprintf(name, name_len,
@ -1030,19 +1046,29 @@ static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
size_t name_len)
{
return __ath11k_core_create_board_name(ab, name, name_len, true, false);
return __ath11k_core_create_board_name(ab, name, name_len, true,
ATH11K_BDF_NAME_FULL);
}
static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name,
size_t name_len)
{
return __ath11k_core_create_board_name(ab, name, name_len, false, false);
return __ath11k_core_create_board_name(ab, name, name_len, false,
ATH11K_BDF_NAME_FULL);
}
static int ath11k_core_create_bus_type_board_name(struct ath11k_base *ab, char *name,
size_t name_len)
{
return __ath11k_core_create_board_name(ab, name, name_len, false, true);
return __ath11k_core_create_board_name(ab, name, name_len, false,
ATH11K_BDF_NAME_BUS_NAME);
}
static int ath11k_core_create_chip_id_board_name(struct ath11k_base *ab, char *name,
size_t name_len)
{
return __ath11k_core_create_board_name(ab, name, name_len, false,
ATH11K_BDF_NAME_CHIP_ID);
}
const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
@ -1289,16 +1315,21 @@ int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
#define BOARD_NAME_SIZE 200
int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
{
char boardname[BOARD_NAME_SIZE], fallback_boardname[BOARD_NAME_SIZE];
char *boardname = NULL, *fallback_boardname = NULL, *chip_id_boardname = NULL;
char *filename, filepath[100];
int ret;
int ret = 0;
filename = ATH11K_BOARD_API2_FILE;
boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
if (!boardname) {
ret = -ENOMEM;
goto exit;
}
ret = ath11k_core_create_board_name(ab, boardname, sizeof(boardname));
ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
if (ret) {
ath11k_err(ab, "failed to create board name: %d", ret);
return ret;
goto exit;
}
ab->bd_api = 2;
@ -1307,13 +1338,19 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
ATH11K_BD_IE_BOARD_NAME,
ATH11K_BD_IE_BOARD_DATA);
if (!ret)
goto success;
goto exit;
fallback_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
if (!fallback_boardname) {
ret = -ENOMEM;
goto exit;
}
ret = ath11k_core_create_fallback_board_name(ab, fallback_boardname,
sizeof(fallback_boardname));
BOARD_NAME_SIZE);
if (ret) {
ath11k_err(ab, "failed to create fallback board name: %d", ret);
return ret;
goto exit;
}
ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname,
@ -1321,7 +1358,28 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
ATH11K_BD_IE_BOARD_NAME,
ATH11K_BD_IE_BOARD_DATA);
if (!ret)
goto success;
goto exit;
chip_id_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
if (!chip_id_boardname) {
ret = -ENOMEM;
goto exit;
}
ret = ath11k_core_create_chip_id_board_name(ab, chip_id_boardname,
BOARD_NAME_SIZE);
if (ret) {
ath11k_err(ab, "failed to create chip id board name: %d", ret);
goto exit;
}
ret = ath11k_core_fetch_board_data_api_n(ab, bd, chip_id_boardname,
ATH11K_BD_IE_BOARD,
ATH11K_BD_IE_BOARD_NAME,
ATH11K_BD_IE_BOARD_DATA);
if (!ret)
goto exit;
ab->bd_api = 1;
ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE);
@ -1334,14 +1392,22 @@ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
ath11k_err(ab, "failed to fetch board data for %s from %s\n",
fallback_boardname, filepath);
ath11k_err(ab, "failed to fetch board data for %s from %s\n",
chip_id_boardname, filepath);
ath11k_err(ab, "failed to fetch board.bin from %s\n",
ab->hw_params.fw.dir);
return ret;
}
success:
ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
return 0;
exit:
kfree(boardname);
kfree(fallback_boardname);
kfree(chip_id_boardname);
if (!ret)
ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
return ret;
}
int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd)

View File

@ -901,8 +901,6 @@ struct ath11k_base {
struct list_head peers;
wait_queue_head_t peer_mapping_wq;
u8 mac_addr[ETH_ALEN];
bool wmi_ready;
u32 wlan_init_status;
int irq_num[ATH11K_IRQ_NUM_MAX];
struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX];
struct ath11k_targ_cap target_caps;

View File

@ -1009,7 +1009,7 @@ void ath11k_dp_vdev_tx_attach(struct ath11k *ar, struct ath11k_vif *arvif)
static int ath11k_dp_tx_pending_cleanup(int buf_id, void *skb, void *ctx)
{
struct ath11k_base *ab = (struct ath11k_base *)ctx;
struct ath11k_base *ab = ctx;
struct sk_buff *msdu = skb;
dma_unmap_single(ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len,

View File

@ -1256,7 +1256,7 @@ static int ath11k_htt_tlv_ppdu_stats_parse(struct ath11k_base *ab,
int cur_user;
u16 peer_id;
ppdu_info = (struct htt_ppdu_stats_info *)data;
ppdu_info = data;
switch (tag) {
case HTT_PPDU_STATS_TAG_COMMON:
@ -1388,9 +1388,6 @@ ath11k_update_per_peer_tx_stats(struct ath11k *ar,
u8 tid = HTT_PPDU_STATS_NON_QOS_TID;
bool is_ampdu = false;
if (!usr_stats)
return;
if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE)))
return;
@ -4489,8 +4486,7 @@ int ath11k_dp_rx_monitor_link_desc_return(struct ath11k *ar,
src_srng_desc = ath11k_hal_srng_src_get_next_entry(ar->ab, hal_srng);
if (src_srng_desc) {
struct ath11k_buffer_addr *src_desc =
(struct ath11k_buffer_addr *)src_srng_desc;
struct ath11k_buffer_addr *src_desc = src_srng_desc;
*src_desc = *((struct ath11k_buffer_addr *)p_last_buf_addr_info);
} else {
@ -4509,8 +4505,7 @@ void ath11k_dp_rx_mon_next_link_desc_get(void *rx_msdu_link_desc,
u8 *rbm,
void **pp_buf_addr_info)
{
struct hal_rx_msdu_link *msdu_link =
(struct hal_rx_msdu_link *)rx_msdu_link_desc;
struct hal_rx_msdu_link *msdu_link = rx_msdu_link_desc;
struct ath11k_buffer_addr *buf_addr_info;
buf_addr_info = (struct ath11k_buffer_addr *)&msdu_link->buf_addr_info;
@ -4551,7 +4546,7 @@ static void ath11k_hal_rx_msdu_list_get(struct ath11k *ar,
u32 first = FIELD_PREP(RX_MSDU_DESC_INFO0_FIRST_MSDU_IN_MPDU, 1);
u8 tmp = 0;
msdu_link = (struct hal_rx_msdu_link *)msdu_link_desc;
msdu_link = msdu_link_desc;
msdu_details = &msdu_link->msdu_link[0];
for (i = 0; i < HAL_RX_NUM_MSDU_DESC; i++) {
@ -4648,8 +4643,7 @@ ath11k_dp_rx_mon_mpdu_pop(struct ath11k *ar, int mac_id,
bool is_frag, is_first_msdu;
bool drop_mpdu = false;
struct ath11k_skb_rxcb *rxcb;
struct hal_reo_entrance_ring *ent_desc =
(struct hal_reo_entrance_ring *)ring_entry;
struct hal_reo_entrance_ring *ent_desc = ring_entry;
int buf_id;
u32 rx_link_buf_info[2];
u8 rbm;
@ -5097,13 +5091,6 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
mon_dst_srng = &ar->ab->hal.srng_list[ring_id];
if (!mon_dst_srng) {
ath11k_warn(ar->ab,
"HAL Monitor Destination Ring Init Failed -- %p",
mon_dst_srng);
return;
}
spin_lock_bh(&pmon->mon_lock);
ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng);

View File

@ -571,7 +571,7 @@ u32 ath11k_hal_ce_get_desc_size(enum hal_ce_desc type)
void ath11k_hal_ce_src_set_desc(void *buf, dma_addr_t paddr, u32 len, u32 id,
u8 byte_swap_data)
{
struct hal_ce_srng_src_desc *desc = (struct hal_ce_srng_src_desc *)buf;
struct hal_ce_srng_src_desc *desc = buf;
desc->buffer_addr_low = paddr & HAL_ADDR_LSB_REG_MASK;
desc->buffer_addr_info =
@ -586,8 +586,7 @@ void ath11k_hal_ce_src_set_desc(void *buf, dma_addr_t paddr, u32 len, u32 id,
void ath11k_hal_ce_dst_set_desc(void *buf, dma_addr_t paddr)
{
struct hal_ce_srng_dest_desc *desc =
(struct hal_ce_srng_dest_desc *)buf;
struct hal_ce_srng_dest_desc *desc = buf;
desc->buffer_addr_low = paddr & HAL_ADDR_LSB_REG_MASK;
desc->buffer_addr_info =
@ -597,8 +596,7 @@ void ath11k_hal_ce_dst_set_desc(void *buf, dma_addr_t paddr)
u32 ath11k_hal_ce_dst_status_get_length(void *buf)
{
struct hal_ce_srng_dst_status_desc *desc =
(struct hal_ce_srng_dst_status_desc *)buf;
struct hal_ce_srng_dst_status_desc *desc = buf;
u32 len;
len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, desc->flags);

View File

@ -265,7 +265,7 @@ int ath11k_hal_reo_cmd_send(struct ath11k_base *ab, struct hal_srng *srng,
void ath11k_hal_rx_buf_addr_info_set(void *desc, dma_addr_t paddr,
u32 cookie, u8 manager)
{
struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc;
struct ath11k_buffer_addr *binfo = desc;
u32 paddr_lo, paddr_hi;
paddr_lo = lower_32_bits(paddr);
@ -279,7 +279,7 @@ void ath11k_hal_rx_buf_addr_info_set(void *desc, dma_addr_t paddr,
void ath11k_hal_rx_buf_addr_info_get(void *desc, dma_addr_t *paddr,
u32 *cookie, u8 *rbm)
{
struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc;
struct ath11k_buffer_addr *binfo = desc;
*paddr =
(((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, binfo->info1)) << 32) |
@ -292,7 +292,7 @@ void ath11k_hal_rx_msdu_link_info_get(void *link_desc, u32 *num_msdus,
u32 *msdu_cookies,
enum hal_rx_buf_return_buf_manager *rbm)
{
struct hal_rx_msdu_link *link = (struct hal_rx_msdu_link *)link_desc;
struct hal_rx_msdu_link *link = link_desc;
struct hal_rx_msdu_details *msdu;
int i;
@ -699,7 +699,7 @@ u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid)
void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size,
u32 start_seq, enum hal_pn_type type)
{
struct hal_rx_reo_queue *qdesc = (struct hal_rx_reo_queue *)vaddr;
struct hal_rx_reo_queue *qdesc = vaddr;
struct hal_rx_reo_queue_ext *ext_desc;
memset(qdesc, 0, sizeof(*qdesc));
@ -809,27 +809,25 @@ static inline void
ath11k_hal_rx_handle_ofdma_info(void *rx_tlv,
struct hal_rx_user_status *rx_user_status)
{
struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
(struct hal_rx_ppdu_end_user_stats *)rx_tlv;
struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;
rx_user_status->ul_ofdma_user_v0_word0 = __le32_to_cpu(ppdu_end_user->info6);
rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->rsvd2[10]);
rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->info10);
}
static inline void
ath11k_hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,
struct hal_rx_user_status *rx_user_status)
{
struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
(struct hal_rx_ppdu_end_user_stats *)rx_tlv;
struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;
rx_user_status->mpdu_ok_byte_count =
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_RSVD2_6_MPDU_OK_BYTE_COUNT,
__le32_to_cpu(ppdu_end_user->rsvd2[6]));
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_OK_BYTE_COUNT,
__le32_to_cpu(ppdu_end_user->info8));
rx_user_status->mpdu_err_byte_count =
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_RSVD2_8_MPDU_ERR_BYTE_COUNT,
__le32_to_cpu(ppdu_end_user->rsvd2[8]));
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO9_MPDU_ERR_BYTE_COUNT,
__le32_to_cpu(ppdu_end_user->info9));
}
static inline void
@ -903,8 +901,8 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX,
__le32_to_cpu(eu_stats->info2));
ppdu_info->tid =
ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP,
__le32_to_cpu(eu_stats->info6))) - 1;
ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO7_TID_BITMAP,
__le32_to_cpu(eu_stats->info7))) - 1;
ppdu_info->tcp_msdu_count =
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT,
__le32_to_cpu(eu_stats->info4));
@ -1540,8 +1538,7 @@ void ath11k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr,
u32 *sw_cookie, void **pp_buf_addr,
u8 *rbm, u32 *msdu_cnt)
{
struct hal_reo_entrance_ring *reo_ent_ring =
(struct hal_reo_entrance_ring *)rx_desc;
struct hal_reo_entrance_ring *reo_ent_ring = rx_desc;
struct ath11k_buffer_addr *buf_addr_info;
struct rx_mpdu_desc *rx_mpdu_desc_info_details;

View File

@ -149,7 +149,7 @@ struct hal_rx_mon_ppdu_info {
u8 beamformed;
u8 rssi_comb;
u8 rssi_chain_pri20[HAL_RX_MAX_NSS];
u8 tid;
u16 tid;
u16 ht_flags;
u16 vht_flags;
u16 he_flags;
@ -219,11 +219,11 @@ struct hal_rx_ppdu_start {
#define HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT GENMASK(15, 0)
#define HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT GENMASK(31, 16)
#define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP GENMASK(15, 0)
#define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_EOSP_BITMAP GENMASK(31, 16)
#define HAL_RX_PPDU_END_USER_STATS_INFO7_TID_BITMAP GENMASK(15, 0)
#define HAL_RX_PPDU_END_USER_STATS_INFO7_TID_EOSP_BITMAP GENMASK(31, 16)
#define HAL_RX_PPDU_END_USER_STATS_RSVD2_6_MPDU_OK_BYTE_COUNT GENMASK(24, 0)
#define HAL_RX_PPDU_END_USER_STATS_RSVD2_8_MPDU_ERR_BYTE_COUNT GENMASK(24, 0)
#define HAL_RX_PPDU_END_USER_STATS_INFO8_MPDU_OK_BYTE_COUNT GENMASK(24, 0)
#define HAL_RX_PPDU_END_USER_STATS_INFO9_MPDU_ERR_BYTE_COUNT GENMASK(24, 0)
struct hal_rx_ppdu_end_user_stats {
__le32 rsvd0[2];
@ -236,7 +236,13 @@ struct hal_rx_ppdu_end_user_stats {
__le32 info4;
__le32 info5;
__le32 info6;
__le32 rsvd2[11];
__le32 info7;
__le32 rsvd2[4];
__le32 info8;
__le32 rsvd3;
__le32 info9;
__le32 rsvd4[2];
__le32 info10;
} __packed;
struct hal_rx_ppdu_end_user_stats_ext {

View File

@ -37,7 +37,7 @@ static const u8 dscp_tid_map[DSCP_TID_MAP_TBL_ENTRY_SIZE] = {
void ath11k_hal_tx_cmd_desc_setup(struct ath11k_base *ab, void *cmd,
struct hal_tx_info *ti)
{
struct hal_tcl_data_cmd *tcl_cmd = (struct hal_tcl_data_cmd *)cmd;
struct hal_tcl_data_cmd *tcl_cmd = cmd;
tcl_cmd->buf_addr_info.info0 =
FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, ti->paddr);

View File

@ -6970,8 +6970,8 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
static int ath11k_mac_vif_unref(int buf_id, void *skb, void *ctx)
{
struct ieee80211_vif *vif = (struct ieee80211_vif *)ctx;
struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB((struct sk_buff *)skb);
struct ieee80211_vif *vif = ctx;
struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
if (skb_cb->vif == vif)
skb_cb->vif = NULL;
@ -7913,12 +7913,14 @@ ath11k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap)
static bool
ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,
struct ath11k_vif *arvif,
enum nl80211_band band,
const struct cfg80211_bitrate_mask *mask,
int *nss)
{
struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
const struct ieee80211_sta_he_cap *he_cap;
u16 he_mcs_map = 0;
u8 ht_nss_mask = 0;
u8 vht_nss_mask = 0;
@ -7949,7 +7951,11 @@ ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,
return false;
}
he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(&sband->iftype_data->he_cap));
he_cap = ieee80211_get_he_iftype_cap_vif(sband, arvif->vif);
if (!he_cap)
return false;
he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(he_cap));
for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
if (mask->control[band].he_mcs[i] == 0)
@ -8365,7 +8371,7 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
ieee80211_iterate_stations_atomic(ar->hw,
ath11k_mac_disable_peer_fixed_rate,
arvif);
} else if (ath11k_mac_bitrate_mask_get_single_nss(ar, band, mask,
} else if (ath11k_mac_bitrate_mask_get_single_nss(ar, arvif, band, mask,
&single_nss)) {
rate = WMI_FIXED_RATE_NONE;
nss = single_nss;
@ -8908,7 +8914,7 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
{
struct ath11k *ar = hw->priv;
struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
struct scan_req_params arg;
struct scan_req_params *arg;
int ret;
u32 scan_time_msec;
@ -8940,27 +8946,31 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2;
memset(&arg, 0, sizeof(arg));
ath11k_wmi_start_scan_init(ar, &arg);
arg.num_chan = 1;
arg.chan_list = kcalloc(arg.num_chan, sizeof(*arg.chan_list),
GFP_KERNEL);
if (!arg.chan_list) {
arg = kzalloc(sizeof(*arg), GFP_KERNEL);
if (!arg) {
ret = -ENOMEM;
goto exit;
}
ath11k_wmi_start_scan_init(ar, arg);
arg->num_chan = 1;
arg->chan_list = kcalloc(arg->num_chan, sizeof(*arg->chan_list),
GFP_KERNEL);
if (!arg->chan_list) {
ret = -ENOMEM;
goto free_arg;
}
arg.vdev_id = arvif->vdev_id;
arg.scan_id = ATH11K_SCAN_ID;
arg.chan_list[0] = chan->center_freq;
arg.dwell_time_active = scan_time_msec;
arg.dwell_time_passive = scan_time_msec;
arg.max_scan_time = scan_time_msec;
arg.scan_flags |= WMI_SCAN_FLAG_PASSIVE;
arg.scan_flags |= WMI_SCAN_FILTER_PROBE_REQ;
arg.burst_duration = duration;
arg->vdev_id = arvif->vdev_id;
arg->scan_id = ATH11K_SCAN_ID;
arg->chan_list[0] = chan->center_freq;
arg->dwell_time_active = scan_time_msec;
arg->dwell_time_passive = scan_time_msec;
arg->max_scan_time = scan_time_msec;
arg->scan_flags |= WMI_SCAN_FLAG_PASSIVE;
arg->scan_flags |= WMI_SCAN_FILTER_PROBE_REQ;
arg->burst_duration = duration;
ret = ath11k_start_scan(ar, &arg);
ret = ath11k_start_scan(ar, arg);
if (ret) {
ath11k_warn(ar->ab, "failed to start roc scan: %d\n", ret);
@ -8986,7 +8996,9 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw,
ret = 0;
free_chan_list:
kfree(arg.chan_list);
kfree(arg->chan_list);
free_arg:
kfree(arg);
exit:
mutex_unlock(&ar->conf_mutex);
return ret;

View File

@ -333,6 +333,7 @@ static void ath11k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
ath11k_warn(ab, "firmware crashed: MHI_CB_SYS_ERROR\n");
break;
case MHI_CB_EE_RDDM:
ath11k_warn(ab, "firmware crashed: MHI_CB_EE_RDDM\n");
if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
queue_work(ab->workqueue_aux, &ab->reset_work);
break;

View File

@ -852,10 +852,16 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
if (ret)
goto err_pci_disable_msi;
ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
if (ret) {
ath11k_err(ab, "failed to set irq affinity %d\n", ret);
goto err_pci_disable_msi;
}
ret = ath11k_mhi_register(ab_pci);
if (ret) {
ath11k_err(ab, "failed to register mhi: %d\n", ret);
goto err_pci_disable_msi;
goto err_irq_affinity_cleanup;
}
ret = ath11k_hal_srng_init(ab);
@ -876,12 +882,6 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
goto err_ce_free;
}
ret = ath11k_pci_set_irq_affinity_hint(ab_pci, cpumask_of(0));
if (ret) {
ath11k_err(ab, "failed to set irq affinity %d\n", ret);
goto err_free_irq;
}
/* kernel may allocate a dummy vector before request_irq and
* then allocate a real vector when request_irq is called.
* So get msi_data here again to avoid spurious interrupt
@ -890,20 +890,17 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
ret = ath11k_pci_config_msi_data(ab_pci);
if (ret) {
ath11k_err(ab, "failed to config msi_data: %d\n", ret);
goto err_irq_affinity_cleanup;
goto err_free_irq;
}
ret = ath11k_core_init(ab);
if (ret) {
ath11k_err(ab, "failed to init core: %d\n", ret);
goto err_irq_affinity_cleanup;
goto err_free_irq;
}
ath11k_qmi_fwreset_from_cold_boot(ab);
return 0;
err_irq_affinity_cleanup:
ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
err_free_irq:
ath11k_pcic_free_irq(ab);
@ -916,6 +913,9 @@ static int ath11k_pci_probe(struct pci_dev *pdev,
err_mhi_unregister:
ath11k_mhi_unregister(ab_pci);
err_irq_affinity_cleanup:
ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
err_pci_disable_msi:
ath11k_pci_free_msi(ab_pci);

View File

@ -382,16 +382,11 @@ static ssize_t ath11k_write_file_spectral_count(struct file *file,
{
struct ath11k *ar = file->private_data;
unsigned long val;
char buf[32];
ssize_t len;
ssize_t ret;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;
buf[len] = '\0';
if (kstrtoul(buf, 0, &val))
return -EINVAL;
ret = kstrtoul_from_user(user_buf, count, 0, &val);
if (ret)
return ret;
if (val > ATH11K_SPECTRAL_SCAN_COUNT_MAX)
return -EINVAL;
@ -437,16 +432,11 @@ static ssize_t ath11k_write_file_spectral_bins(struct file *file,
{
struct ath11k *ar = file->private_data;
unsigned long val;
char buf[32];
ssize_t len;
ssize_t ret;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;
buf[len] = '\0';
if (kstrtoul(buf, 0, &val))
return -EINVAL;
ret = kstrtoul_from_user(user_buf, count, 0, &val);
if (ret)
return ret;
if (val < ATH11K_SPECTRAL_MIN_BINS ||
val > ar->ab->hw_params.spectral.max_fft_bins)
@ -598,7 +588,7 @@ int ath11k_spectral_process_fft(struct ath11k *ar,
return -EINVAL;
}
tlv = (struct spectral_tlv *)data;
tlv = data;
tlv_len = FIELD_GET(SPECTRAL_TLV_HDR_LEN, __le32_to_cpu(tlv->header));
/* convert Dword into bytes */
tlv_len *= ATH11K_SPECTRAL_DWORD_SIZE;

View File

@ -2281,7 +2281,7 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) |
FIELD_PREP(WMI_TLV_LEN, len);
ptr += TLV_HDR_SIZE;
tmp_ptr = (u32 *)ptr;
tmp_ptr = ptr;
for (i = 0; i < params->num_chan; ++i)
tmp_ptr[i] = params->chan_list[i];
@ -4148,7 +4148,7 @@ static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
ptr += TLV_HDR_SIZE + len;
if (param->hw_mode_id != WMI_HOST_HW_MODE_MAX) {
hw_mode = (struct wmi_pdev_set_hw_mode_cmd_param *)ptr;
hw_mode = ptr;
hw_mode->tlv_header = FIELD_PREP(WMI_TLV_TAG,
WMI_TAG_PDEV_SET_HW_MODE_CMD) |
FIELD_PREP(WMI_TLV_LEN,
@ -4168,7 +4168,7 @@ static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
len = sizeof(*band_to_mac);
for (idx = 0; idx < param->num_band_to_mac; idx++) {
band_to_mac = (void *)ptr;
band_to_mac = ptr;
band_to_mac->tlv_header = FIELD_PREP(WMI_TLV_TAG,
WMI_TAG_PDEV_BAND_TO_MAC) |
@ -7222,14 +7222,12 @@ static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len,
memset(&fixed_param, 0, sizeof(fixed_param));
memcpy(&fixed_param, (struct wmi_ready_event *)ptr,
min_t(u16, sizeof(fixed_param), len));
ab->wlan_init_status = fixed_param.ready_event_min.status;
rdy_parse->num_extra_mac_addr =
fixed_param.ready_event_min.num_extra_mac_addr;
ether_addr_copy(ab->mac_addr,
fixed_param.ready_event_min.mac_addr.addr);
ab->pktlog_defs_checksum = fixed_param.pktlog_defs_checksum;
ab->wmi_ready = true;
break;
case WMI_TAG_ARRAY_FIXED_STRUCT:
addr_list = (struct wmi_mac_addr *)ptr;

View File

@ -19,6 +19,27 @@ unsigned int ath12k_debug_mask;
module_param_named(debug_mask, ath12k_debug_mask, uint, 0644);
MODULE_PARM_DESC(debug_mask, "Debugging mask");
static int ath12k_core_rfkill_config(struct ath12k_base *ab)
{
struct ath12k *ar;
int ret = 0, i;
if (!(ab->target_caps.sys_cap_info & WMI_SYS_CAP_INFO_RFKILL))
return 0;
for (i = 0; i < ab->num_radios; i++) {
ar = ab->pdevs[i].ar;
ret = ath12k_mac_rfkill_config(ar);
if (ret && ret != -EOPNOTSUPP) {
ath12k_warn(ab, "failed to configure rfkill: %d", ret);
return ret;
}
}
return ret;
}
int ath12k_core_suspend(struct ath12k_base *ab)
{
int ret;
@ -603,6 +624,13 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
goto err_core_stop;
}
ath12k_hif_irq_enable(ab);
ret = ath12k_core_rfkill_config(ab);
if (ret && ret != -EOPNOTSUPP) {
ath12k_err(ab, "failed to config rfkill: %d\n", ret);
goto err_core_stop;
}
mutex_unlock(&ab->core_lock);
return 0;
@ -655,6 +683,27 @@ static int ath12k_core_reconfigure_on_crash(struct ath12k_base *ab)
return ret;
}
static void ath12k_rfkill_work(struct work_struct *work)
{
struct ath12k_base *ab = container_of(work, struct ath12k_base, rfkill_work);
struct ath12k *ar;
bool rfkill_radio_on;
int i;
spin_lock_bh(&ab->base_lock);
rfkill_radio_on = ab->rfkill_radio_on;
spin_unlock_bh(&ab->base_lock);
for (i = 0; i < ab->num_radios; i++) {
ar = ab->pdevs[i].ar;
if (!ar)
continue;
ath12k_mac_rfkill_enable_radio(ar, rfkill_radio_on);
wiphy_rfkill_set_hw_state(ar->hw->wiphy, !rfkill_radio_on);
}
}
void ath12k_core_halt(struct ath12k *ar)
{
struct ath12k_base *ab = ar->ab;
@ -668,6 +717,7 @@ void ath12k_core_halt(struct ath12k *ar)
ath12k_mac_peer_cleanup_all(ar);
cancel_delayed_work_sync(&ar->scan.timeout);
cancel_work_sync(&ar->regd_update_work);
cancel_work_sync(&ab->rfkill_work);
rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
synchronize_rcu();
@ -685,6 +735,9 @@ static void ath12k_core_pre_reconfigure_recovery(struct ath12k_base *ab)
ab->stats.fw_crash_counter++;
spin_unlock_bh(&ab->base_lock);
if (ab->is_reset)
set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
for (i = 0; i < ab->num_radios; i++) {
pdev = &ab->pdevs[i];
ar = pdev->ar;
@ -823,6 +876,8 @@ static void ath12k_core_reset(struct work_struct *work)
ath12k_dbg(ab, ATH12K_DBG_BOOT, "reset starting\n");
ab->is_reset = true;
atomic_set(&ab->recovery_start_count, 0);
reinit_completion(&ab->recovery_start);
atomic_set(&ab->recovery_count, 0);
ath12k_core_pre_reconfigure_recovery(ab);
@ -830,9 +885,6 @@ static void ath12k_core_reset(struct work_struct *work)
reinit_completion(&ab->reconfigure_complete);
ath12k_core_post_reconfigure_recovery(ab);
reinit_completion(&ab->recovery_start);
atomic_set(&ab->recovery_start_count, 0);
ath12k_dbg(ab, ATH12K_DBG_BOOT, "waiting recovery start...\n");
time_left = wait_for_completion_timeout(&ab->recovery_start,
@ -922,6 +974,8 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
INIT_WORK(&ab->restart_work, ath12k_core_restart);
INIT_WORK(&ab->reset_work, ath12k_core_reset);
INIT_WORK(&ab->rfkill_work, ath12k_rfkill_work);
timer_setup(&ab->rx_replenish_retry, ath12k_ce_rx_replenish_retry, 0);
init_completion(&ab->htc_suspend);

View File

@ -771,6 +771,10 @@ struct ath12k_base {
u64 fw_soc_drop_count;
bool static_window_map;
struct work_struct rfkill_work;
/* true means radio is on */
bool rfkill_radio_on;
/* must be last */
u8 drv_priv[] __aligned(sizeof(void *));
};

View File

@ -38,6 +38,7 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr)
ath12k_dp_rx_peer_tid_cleanup(ar, peer);
crypto_free_shash(peer->tfm_mmic);
peer->dp_setup_done = false;
spin_unlock_bh(&ab->base_lock);
}

View File

@ -13,8 +13,7 @@
static void ath12k_dp_mon_rx_handle_ofdma_info(void *rx_tlv,
struct hal_rx_user_status *rx_user_status)
{
struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
(struct hal_rx_ppdu_end_user_stats *)rx_tlv;
struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;
rx_user_status->ul_ofdma_user_v0_word0 =
__le32_to_cpu(ppdu_end_user->usr_resp_ref);
@ -23,13 +22,12 @@ static void ath12k_dp_mon_rx_handle_ofdma_info(void *rx_tlv,
}
static void
ath12k_dp_mon_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,
ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats,
void *ppduinfo,
struct hal_rx_user_status *rx_user_status)
{
struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
(struct hal_rx_ppdu_end_user_stats *)rx_tlv;
u32 mpdu_ok_byte_count = __le32_to_cpu(ppdu_end_user->mpdu_ok_cnt);
u32 mpdu_err_byte_count = __le32_to_cpu(ppdu_end_user->mpdu_err_cnt);
u32 mpdu_ok_byte_count = __le32_to_cpu(stats->mpdu_ok_cnt);
u32 mpdu_err_byte_count = __le32_to_cpu(stats->mpdu_err_cnt);
rx_user_status->mpdu_ok_byte_count =
u32_get_bits(mpdu_ok_byte_count,

View File

@ -1555,6 +1555,13 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab,
msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data;
len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE);
if (len > (skb->len - struct_size(msg, data, 0))) {
ath12k_warn(ab,
"HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n",
len, skb->len);
return -EINVAL;
}
pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID);
ppdu_id = le32_to_cpu(msg->ppdu_id);
@ -1583,6 +1590,16 @@ static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab,
goto exit;
}
if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) {
spin_unlock_bh(&ar->data_lock);
ath12k_warn(ab,
"HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n",
ppdu_info->ppdu_stats.common.num_users,
HTT_PPDU_STATS_MAX_USERS);
ret = -EINVAL;
goto exit;
}
/* back up data rate tlv for all peers */
if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA &&
(ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) &&
@ -2748,6 +2765,7 @@ int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev
}
peer->tfm_mmic = tfm;
peer->dp_setup_done = true;
spin_unlock_bh(&ab->base_lock);
return 0;
@ -3214,6 +3232,14 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
ret = -ENOENT;
goto out_unlock;
}
if (!peer->dp_setup_done) {
ath12k_warn(ab, "The peer %pM [%d] has uninitialized datapath\n",
peer->addr, peer_id);
ret = -ENOENT;
goto out_unlock;
}
rx_tid = &peer->rx_tid[tid];
if ((!skb_queue_empty(&rx_tid->rx_frags) && seqno != rx_tid->cur_sn) ||
@ -3229,7 +3255,7 @@ static int ath12k_dp_rx_frag_h_mpdu(struct ath12k *ar,
goto out_unlock;
}
if (frag_no > __fls(rx_tid->rx_frag_bitmap))
if ((!rx_tid->rx_frag_bitmap || frag_no > __fls(rx_tid->rx_frag_bitmap)))
__skb_queue_tail(&rx_tid->rx_frags, msdu);
else
ath12k_dp_rx_h_sort_frags(ab, &rx_tid->rx_frags, msdu);
@ -3730,7 +3756,7 @@ int ath12k_dp_rx_process_wbm_err(struct ath12k_base *ab,
continue;
}
desc_info = (struct ath12k_rx_desc_info *)err_info.rx_desc;
desc_info = err_info.rx_desc;
/* retry manual desc retrieval if hw cc is not done */
if (!desc_info) {

View File

@ -106,11 +106,10 @@ static struct ath12k_tx_desc_info *ath12k_dp_tx_assign_buffer(struct ath12k_dp *
return desc;
}
static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab, void *cmd,
static void ath12k_hal_tx_cmd_ext_desc_setup(struct ath12k_base *ab,
struct hal_tx_msdu_ext_desc *tcl_ext_cmd,
struct hal_tx_info *ti)
{
struct hal_tx_msdu_ext_desc *tcl_ext_cmd = (struct hal_tx_msdu_ext_desc *)cmd;
tcl_ext_cmd->info0 = le32_encode_bits(ti->paddr,
HAL_TX_MSDU_EXT_INFO0_BUF_PTR_LO);
tcl_ext_cmd->info1 = le32_encode_bits(0x0,
@ -330,8 +329,11 @@ int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
fail_unmap_dma:
dma_unmap_single(ab->dev, ti.paddr, ti.data_len, DMA_TO_DEVICE);
dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
sizeof(struct hal_tx_msdu_ext_desc), DMA_TO_DEVICE);
if (skb_cb->paddr_ext_desc)
dma_unmap_single(ab->dev, skb_cb->paddr_ext_desc,
sizeof(struct hal_tx_msdu_ext_desc),
DMA_TO_DEVICE);
fail_remove_tx_buf:
ath12k_dp_tx_release_txbuf(dp, tx_desc, pool_id);

View File

@ -385,13 +385,13 @@ static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc)
static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_nss(struct hal_rx_desc *desc)
{
return le32_get_bits(desc->u.qcn9274.msdu_end.info12,
RX_MSDU_END_INFO12_MIMO_SS_BITMAP);
RX_MSDU_END_QCN9274_INFO12_MIMO_SS_BITMAP);
}
static u8 ath12k_hw_qcn9274_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc)
{
return le16_get_bits(desc->u.qcn9274.msdu_end.info5,
RX_MSDU_END_INFO5_TID);
RX_MSDU_END_QCN9274_INFO5_TID);
}
static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc)
@ -819,13 +819,13 @@ static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc)
static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc)
{
return le32_get_bits(desc->u.wcn7850.msdu_end.info12,
RX_MSDU_END_INFO12_MIMO_SS_BITMAP);
RX_MSDU_END_WCN7850_INFO12_MIMO_SS_BITMAP);
}
static u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc)
{
return le16_get_bits(desc->u.wcn7850.msdu_end.info5,
RX_MSDU_END_INFO5_TID);
return le32_get_bits(desc->u.wcn7850.mpdu_start.info2,
RX_MPDU_START_INFO2_TID);
}
static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc)
@ -837,7 +837,7 @@ static void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc,
struct hal_rx_desc *ldesc)
{
memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end,
sizeof(struct rx_msdu_end_qcn9274));
sizeof(struct rx_msdu_end_wcn7850));
}
static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc)

View File

@ -907,6 +907,10 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.hal_ops = &hal_qcn9274_ops,
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
.rfkill_pin = 0,
.rfkill_cfg = 0,
.rfkill_on_level = 0,
},
{
.name = "wcn7850 hw2.0",
@ -964,6 +968,10 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01) |
BIT(CNSS_PCIE_PERST_NO_PULL_V01),
.rfkill_pin = 48,
.rfkill_cfg = 0,
.rfkill_on_level = 1,
},
{
.name = "qcn9274 hw2.0",
@ -1019,6 +1027,10 @@ static const struct ath12k_hw_params ath12k_hw_params[] = {
.hal_ops = &hal_qcn9274_ops,
.qmi_cnss_feature_bitmap = BIT(CNSS_QDSS_CFG_MISS_V01),
.rfkill_pin = 0,
.rfkill_cfg = 0,
.rfkill_on_level = 0,
},
};

View File

@ -186,6 +186,10 @@ struct ath12k_hw_params {
const struct hal_ops *hal_ops;
u64 qmi_cnss_feature_bitmap;
u32 rfkill_pin;
u32 rfkill_cfg;
u32 rfkill_on_level;
};
struct ath12k_hw_ops {

View File

@ -2525,7 +2525,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
if (changed & BSS_CHANGED_BEACON) {
param_id = WMI_PDEV_PARAM_BEACON_TX_MODE;
param_value = WMI_BEACON_STAGGERED_MODE;
param_value = WMI_BEACON_BURST_MODE;
ret = ath12k_wmi_pdev_set_param(ar, param_id,
param_value, ar->pdev->pdev_id);
if (ret)
@ -2533,7 +2533,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
arvif->vdev_id);
else
ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
"Set staggered beacon mode for VDEV: %d\n",
"Set burst beacon mode for VDEV: %d\n",
arvif->vdev_id);
ret = ath12k_mac_setup_bcn_tmpl(arvif);
@ -2761,9 +2761,7 @@ static void ath12k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
}
}
if (changed & BSS_CHANGED_FILS_DISCOVERY ||
changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP)
ath12k_mac_fils_discovery(arvif, info);
ath12k_mac_fils_discovery(arvif, info);
if (changed & BSS_CHANGED_EHT_PUNCTURING)
arvif->punct_bitmap = info->eht_puncturing;
@ -2780,18 +2778,21 @@ void __ath12k_mac_scan_finish(struct ath12k *ar)
break;
case ATH12K_SCAN_RUNNING:
case ATH12K_SCAN_ABORTING:
if (ar->scan.is_roc && ar->scan.roc_notify)
ieee80211_remain_on_channel_expired(ar->hw);
fallthrough;
case ATH12K_SCAN_STARTING:
if (!ar->scan.is_roc) {
struct cfg80211_scan_info info = {
.aborted = (ar->scan.state ==
ATH12K_SCAN_ABORTING),
.aborted = ((ar->scan.state ==
ATH12K_SCAN_ABORTING) ||
(ar->scan.state ==
ATH12K_SCAN_STARTING)),
};
ieee80211_scan_completed(ar->hw, &info);
} else if (ar->scan.roc_notify) {
ieee80211_remain_on_channel_expired(ar->hw);
}
fallthrough;
case ATH12K_SCAN_STARTING:
ar->scan.state = ATH12K_SCAN_IDLE;
ar->scan_channel = NULL;
ar->scan.roc_freq = 0;
@ -5108,6 +5109,63 @@ static int ath12k_mac_op_start(struct ieee80211_hw *hw)
return ret;
}
int ath12k_mac_rfkill_config(struct ath12k *ar)
{
struct ath12k_base *ab = ar->ab;
u32 param;
int ret;
if (ab->hw_params->rfkill_pin == 0)
return -EOPNOTSUPP;
ath12k_dbg(ab, ATH12K_DBG_MAC,
"mac rfkill_pin %d rfkill_cfg %d rfkill_on_level %d",
ab->hw_params->rfkill_pin, ab->hw_params->rfkill_cfg,
ab->hw_params->rfkill_on_level);
param = u32_encode_bits(ab->hw_params->rfkill_on_level,
WMI_RFKILL_CFG_RADIO_LEVEL) |
u32_encode_bits(ab->hw_params->rfkill_pin,
WMI_RFKILL_CFG_GPIO_PIN_NUM) |
u32_encode_bits(ab->hw_params->rfkill_cfg,
WMI_RFKILL_CFG_PIN_AS_GPIO);
ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_HW_RFKILL_CONFIG,
param, ar->pdev->pdev_id);
if (ret) {
ath12k_warn(ab,
"failed to set rfkill config 0x%x: %d\n",
param, ret);
return ret;
}
return 0;
}
int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable)
{
enum wmi_rfkill_enable_radio param;
int ret;
if (enable)
param = WMI_RFKILL_ENABLE_RADIO_ON;
else
param = WMI_RFKILL_ENABLE_RADIO_OFF;
ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac %d rfkill enable %d",
ar->pdev_idx, param);
ret = ath12k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_RFKILL_ENABLE,
param, ar->pdev->pdev_id);
if (ret) {
ath12k_warn(ar->ab, "failed to set rfkill enable param %d: %d\n",
param, ret);
return ret;
}
return 0;
}
static void ath12k_mac_op_stop(struct ieee80211_hw *hw)
{
struct ath12k *ar = hw->priv;
@ -5128,6 +5186,7 @@ static void ath12k_mac_op_stop(struct ieee80211_hw *hw)
cancel_delayed_work_sync(&ar->scan.timeout);
cancel_work_sync(&ar->regd_update_work);
cancel_work_sync(&ar->ab->rfkill_work);
spin_lock_bh(&ar->data_lock);
list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) {
@ -5790,12 +5849,13 @@ static void ath12k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
static int
ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif,
const struct cfg80211_chan_def *chandef,
struct ieee80211_chanctx_conf *ctx,
bool restart)
{
struct ath12k *ar = arvif->ar;
struct ath12k_base *ab = ar->ab;
struct wmi_vdev_start_req_arg arg = {};
const struct cfg80211_chan_def *chandef = &ctx->def;
int he_support = arvif->vif->bss_conf.he_support;
int ret;
@ -5829,6 +5889,8 @@ ath12k_mac_vdev_start_restart(struct ath12k_vif *arvif,
/* For now allow DFS for AP mode */
arg.chan_radar = !!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
arg.freq2_radar = ctx->radar_enabled;
arg.passive = arg.chan_radar;
spin_lock_bh(&ab->base_lock);
@ -5936,15 +5998,15 @@ static int ath12k_mac_vdev_stop(struct ath12k_vif *arvif)
}
static int ath12k_mac_vdev_start(struct ath12k_vif *arvif,
const struct cfg80211_chan_def *chandef)
struct ieee80211_chanctx_conf *ctx)
{
return ath12k_mac_vdev_start_restart(arvif, chandef, false);
return ath12k_mac_vdev_start_restart(arvif, ctx, false);
}
static int ath12k_mac_vdev_restart(struct ath12k_vif *arvif,
const struct cfg80211_chan_def *chandef)
struct ieee80211_chanctx_conf *ctx)
{
return ath12k_mac_vdev_start_restart(arvif, chandef, true);
return ath12k_mac_vdev_start_restart(arvif, ctx, true);
}
struct ath12k_mac_change_chanctx_arg {
@ -6039,13 +6101,28 @@ ath12k_mac_update_vif_chan(struct ath12k *ar,
if (WARN_ON(!arvif->is_started))
continue;
if (WARN_ON(!arvif->is_up))
continue;
/* Firmware expect vdev_restart only if vdev is up.
* If vdev is down then it expect vdev_stop->vdev_start.
*/
if (arvif->is_up) {
ret = ath12k_mac_vdev_restart(arvif, vifs[i].new_ctx);
if (ret) {
ath12k_warn(ab, "failed to restart vdev %d: %d\n",
arvif->vdev_id, ret);
continue;
}
} else {
ret = ath12k_mac_vdev_stop(arvif);
if (ret) {
ath12k_warn(ab, "failed to stop vdev %d: %d\n",
arvif->vdev_id, ret);
continue;
}
ret = ath12k_mac_vdev_restart(arvif, &vifs[i].new_ctx->def);
if (ret) {
ath12k_warn(ab, "failed to restart vdev %d: %d\n",
arvif->vdev_id, ret);
ret = ath12k_mac_vdev_start(arvif, vifs[i].new_ctx);
if (ret)
ath12k_warn(ab, "failed to start vdev %d: %d\n",
arvif->vdev_id, ret);
continue;
}
@ -6118,7 +6195,8 @@ static void ath12k_mac_op_change_chanctx(struct ieee80211_hw *hw,
if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
goto unlock;
if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH)
if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH ||
changed & IEEE80211_CHANCTX_CHANGE_RADAR)
ath12k_mac_update_active_vif_chan(ar, ctx);
/* TODO: Recalc radar detection */
@ -6138,7 +6216,7 @@ static int ath12k_start_vdev_delay(struct ieee80211_hw *hw,
if (WARN_ON(arvif->is_started))
return -EBUSY;
ret = ath12k_mac_vdev_start(arvif, &arvif->chanctx.def);
ret = ath12k_mac_vdev_start(arvif, &arvif->chanctx);
if (ret) {
ath12k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",
arvif->vdev_id, vif->addr,
@ -6218,7 +6296,7 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
goto out;
}
ret = ath12k_mac_vdev_start(arvif, &ctx->def);
ret = ath12k_mac_vdev_start(arvif, ctx);
if (ret) {
ath12k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",
arvif->vdev_id, vif->addr,
@ -7231,6 +7309,11 @@ static int __ath12k_mac_register(struct ath12k *ar)
ar->hw->wiphy->interface_modes = ab->hw_params->interface_modes;
if (ar->hw->wiphy->bands[NL80211_BAND_2GHZ] &&
ar->hw->wiphy->bands[NL80211_BAND_5GHZ] &&
ar->hw->wiphy->bands[NL80211_BAND_6GHZ])
ieee80211_hw_set(ar->hw, SINGLE_SCAN_ON_ALL_BANDS);
ieee80211_hw_set(ar->hw, SIGNAL_DBM);
ieee80211_hw_set(ar->hw, SUPPORTS_PS);
ieee80211_hw_set(ar->hw, SUPPORTS_DYNAMIC_PS);

View File

@ -73,4 +73,6 @@ int ath12k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx);
enum rate_info_bw ath12k_mac_bw_to_mac80211_bw(enum ath12k_supported_bw bw);
enum ath12k_supported_bw ath12k_mac_mac80211_bw_to_ath12k_bw(enum rate_info_bw bw);
enum hal_encrypt_type ath12k_dp_tx_get_encrypt_type(u32 cipher);
int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable);
int ath12k_mac_rfkill_config(struct ath12k *ar);
#endif

View File

@ -44,6 +44,9 @@ struct ath12k_peer {
struct ppdu_user_delayba ppdu_stats_delayba;
bool delayba_flag;
bool is_authorized;
/* protected by ab->data_lock */
bool dp_setup_done;
};
void ath12k_peer_unmap_event(struct ath12k_base *ab, u16 peer_id);

View File

@ -627,17 +627,18 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_END_INFO5_SA_IDX_TIMEOUT BIT(0)
#define RX_MSDU_END_INFO5_DA_IDX_TIMEOUT BIT(1)
#define RX_MSDU_END_INFO5_TO_DS BIT(2)
#define RX_MSDU_END_INFO5_TID GENMASK(6, 3)
#define RX_MSDU_END_INFO5_SA_IS_VALID BIT(7)
#define RX_MSDU_END_INFO5_DA_IS_VALID BIT(8)
#define RX_MSDU_END_INFO5_DA_IS_MCBC BIT(9)
#define RX_MSDU_END_INFO5_L3_HDR_PADDING GENMASK(11, 10)
#define RX_MSDU_END_INFO5_FIRST_MSDU BIT(12)
#define RX_MSDU_END_INFO5_LAST_MSDU BIT(13)
#define RX_MSDU_END_INFO5_FROM_DS BIT(14)
#define RX_MSDU_END_INFO5_IP_CHKSUM_FAIL_COPY BIT(15)
#define RX_MSDU_END_QCN9274_INFO5_TO_DS BIT(2)
#define RX_MSDU_END_QCN9274_INFO5_TID GENMASK(6, 3)
#define RX_MSDU_END_QCN9274_INFO5_FROM_DS BIT(14)
#define RX_MSDU_END_INFO6_MSDU_DROP BIT(0)
#define RX_MSDU_END_INFO6_REO_DEST_IND GENMASK(5, 1)
#define RX_MSDU_END_INFO6_FLOW_IDX GENMASK(25, 6)
@ -650,14 +651,15 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_END_INFO7_AGGR_COUNT GENMASK(7, 0)
#define RX_MSDU_END_INFO7_FLOW_AGGR_CONTN BIT(8)
#define RX_MSDU_END_INFO7_FISA_TIMEOUT BIT(9)
#define RX_MSDU_END_INFO7_TCPUDP_CSUM_FAIL_CPY BIT(10)
#define RX_MSDU_END_INFO7_MSDU_LIMIT_ERROR BIT(11)
#define RX_MSDU_END_INFO7_FLOW_IDX_TIMEOUT BIT(12)
#define RX_MSDU_END_INFO7_FLOW_IDX_INVALID BIT(13)
#define RX_MSDU_END_INFO7_CCE_MATCH BIT(14)
#define RX_MSDU_END_INFO7_AMSDU_PARSER_ERR BIT(15)
#define RX_MSDU_END_INFO8_KEY_ID GENMASK(7, 0)
#define RX_MSDU_END_QCN9274_INFO7_TCPUDP_CSUM_FAIL_CPY BIT(10)
#define RX_MSDU_END_QCN9274_INFO7_MSDU_LIMIT_ERROR BIT(11)
#define RX_MSDU_END_QCN9274_INFO7_FLOW_IDX_TIMEOUT BIT(12)
#define RX_MSDU_END_QCN9274_INFO7_FLOW_IDX_INVALID BIT(13)
#define RX_MSDU_END_QCN9274_INFO7_CCE_MATCH BIT(14)
#define RX_MSDU_END_QCN9274_INFO7_AMSDU_PARSER_ERR BIT(15)
#define RX_MSDU_END_QCN9274_INFO8_KEY_ID GENMASK(7, 0)
#define RX_MSDU_END_INFO9_SERVICE_CODE GENMASK(14, 6)
#define RX_MSDU_END_INFO9_PRIORITY_VALID BIT(15)
@ -698,8 +700,9 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_END_INFO12_RATE_MCS GENMASK(17, 14)
#define RX_MSDU_END_INFO12_RECV_BW GENMASK(20, 18)
#define RX_MSDU_END_INFO12_RECEPTION_TYPE GENMASK(23, 21)
#define RX_MSDU_END_INFO12_MIMO_SS_BITMAP GENMASK(30, 24)
#define RX_MSDU_END_INFO12_MIMO_DONE_COPY BIT(31)
#define RX_MSDU_END_QCN9274_INFO12_MIMO_SS_BITMAP GENMASK(30, 24)
#define RX_MSDU_END_QCN9274_INFO12_MIMO_DONE_COPY BIT(31)
#define RX_MSDU_END_INFO13_FIRST_MPDU BIT(0)
#define RX_MSDU_END_INFO13_MCAST_BCAST BIT(2)
@ -714,7 +717,6 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_END_INFO13_EOSP BIT(11)
#define RX_MSDU_END_INFO13_A_MSDU_ERROR BIT(12)
#define RX_MSDU_END_INFO13_ORDER BIT(14)
#define RX_MSDU_END_INFO13_WIFI_PARSER_ERR BIT(15)
#define RX_MSDU_END_INFO13_OVERFLOW_ERR BIT(16)
#define RX_MSDU_END_INFO13_MSDU_LEN_ERR BIT(17)
#define RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL BIT(18)
@ -732,6 +734,8 @@ enum rx_msdu_start_reception_type {
#define RX_MSDU_END_INFO13_UNDECRYPT_FRAME_ERR BIT(30)
#define RX_MSDU_END_INFO13_FCS_ERR BIT(31)
#define RX_MSDU_END_QCN9274_INFO13_WIFI_PARSER_ERR BIT(15)
#define RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE GENMASK(12, 10)
#define RX_MSDU_END_INFO14_RX_BITMAP_NOT_UPDED BIT(13)
#define RX_MSDU_END_INFO14_MSDU_DONE BIT(31)
@ -782,6 +786,65 @@ struct rx_msdu_end_qcn9274 {
__le32 info14;
} __packed;
/* These macro definitions are only used for WCN7850 */
#define RX_MSDU_END_WCN7850_INFO2_KEY_ID BIT(7, 0)
#define RX_MSDU_END_WCN7850_INFO5_MSDU_LIMIT_ERR BIT(2)
#define RX_MSDU_END_WCN7850_INFO5_IDX_TIMEOUT BIT(3)
#define RX_MSDU_END_WCN7850_INFO5_IDX_INVALID BIT(4)
#define RX_MSDU_END_WCN7850_INFO5_WIFI_PARSE_ERR BIT(5)
#define RX_MSDU_END_WCN7850_INFO5_AMSDU_PARSER_ERR BIT(6)
#define RX_MSDU_END_WCN7850_INFO5_TCPUDP_CSUM_FAIL_CPY BIT(14)
#define RX_MSDU_END_WCN7850_INFO12_MIMO_SS_BITMAP GENMASK(31, 24)
#define RX_MSDU_END_WCN7850_INFO13_FRAGMENT_FLAG BIT(13)
#define RX_MSDU_END_WCN7850_INFO13_CCE_MATCH BIT(15)
struct rx_msdu_end_wcn7850 {
__le16 info0;
__le16 phy_ppdu_id;
__le16 ip_hdr_cksum;
__le16 info1;
__le16 info2;
__le16 cumulative_l3_checksum;
__le32 rule_indication0;
__le32 rule_indication1;
__le16 info3;
__le16 l3_type;
__le32 ipv6_options_crc;
__le32 tcp_seq_num;
__le32 tcp_ack_num;
__le16 info4;
__le16 window_size;
__le16 tcp_udp_chksum;
__le16 info5;
__le16 sa_idx;
__le16 da_idx_or_sw_peer_id;
__le32 info6;
__le32 fse_metadata;
__le16 cce_metadata;
__le16 sa_sw_peer_id;
__le16 info7;
__le16 rsvd0;
__le16 cumulative_l4_checksum;
__le16 cumulative_ip_length;
__le32 info9;
__le32 info10;
__le32 info11;
__le32 toeplitz_hash_2_or_4;
__le32 flow_id_toeplitz;
__le32 info12;
__le32 ppdu_start_timestamp_31_0;
__le32 ppdu_start_timestamp_63_32;
__le32 phy_meta_data;
__le16 vlan_ctag_ci;
__le16 vlan_stag_ci;
__le32 rsvd[3];
__le32 info13;
__le32 info14;
} __packed;
/* rx_msdu_end
*
* rxpcu_mpdu_filter_in_category
@ -1410,7 +1473,7 @@ struct rx_pkt_hdr_tlv {
struct hal_rx_desc_wcn7850 {
__le64 msdu_end_tag;
struct rx_msdu_end_qcn9274 msdu_end;
struct rx_msdu_end_wcn7850 msdu_end;
u8 rx_padding0[RX_BE_PADDING0_BYTES];
__le64 mpdu_start_tag;
struct rx_mpdu_start_qcn9274 mpdu_start;

View File

@ -152,6 +152,8 @@ static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = {
.min_len = sizeof(struct wmi_service_available_event) },
[WMI_TAG_PEER_ASSOC_CONF_EVENT] = {
.min_len = sizeof(struct wmi_peer_assoc_conf_event) },
[WMI_TAG_RFKILL_EVENT] = {
.min_len = sizeof(struct wmi_rfkill_state_change_event) },
[WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT] = {
.min_len = sizeof(struct wmi_pdev_ctl_failsafe_chk_event) },
[WMI_TAG_HOST_SWFDA_EVENT] = {
@ -3876,6 +3878,12 @@ static int ath12k_wmi_ext_hal_reg_caps(struct ath12k_base *soc,
ath12k_warn(soc, "failed to extract reg cap %d\n", i);
return ret;
}
if (reg_cap.phy_id >= MAX_RADIOS) {
ath12k_warn(soc, "unexpected phy id %u\n", reg_cap.phy_id);
return -EINVAL;
}
soc->hal_reg_cap[reg_cap.phy_id] = reg_cap;
}
return 0;
@ -4153,14 +4161,22 @@ static void ath12k_wmi_eht_caps_parse(struct ath12k_pdev *pdev, u32 band,
__le32 cap_info_internal)
{
struct ath12k_band_cap *cap_band = &pdev->cap.band[band];
u32 support_320mhz;
u8 i;
if (band == NL80211_BAND_6GHZ)
support_320mhz = cap_band->eht_cap_phy_info[0] &
IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
for (i = 0; i < WMI_MAX_EHTCAP_MAC_SIZE; i++)
cap_band->eht_cap_mac_info[i] = le32_to_cpu(cap_mac_info[i]);
for (i = 0; i < WMI_MAX_EHTCAP_PHY_SIZE; i++)
cap_band->eht_cap_phy_info[i] = le32_to_cpu(cap_phy_info[i]);
if (band == NL80211_BAND_6GHZ)
cap_band->eht_cap_phy_info[0] |= support_320mhz;
cap_band->eht_mcs_20_only = le32_to_cpu(supp_mcs[0]);
cap_band->eht_mcs_80 = le32_to_cpu(supp_mcs[1]);
if (band != NL80211_BAND_2GHZ) {
@ -4182,10 +4198,19 @@ ath12k_wmi_tlv_mac_phy_caps_ext_parse(struct ath12k_base *ab,
const struct ath12k_wmi_caps_ext_params *caps,
struct ath12k_pdev *pdev)
{
u32 bands;
struct ath12k_band_cap *cap_band;
u32 bands, support_320mhz;
int i;
if (ab->hw_params->single_pdev_only) {
if (caps->hw_mode_id == WMI_HOST_HW_MODE_SINGLE) {
support_320mhz = le32_to_cpu(caps->eht_cap_phy_info_5ghz[0]) &
IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
cap_band = &pdev->cap.band[NL80211_BAND_6GHZ];
cap_band->eht_cap_phy_info[0] |= support_320mhz;
return 0;
}
for (i = 0; i < ab->fw_pdev_count; i++) {
struct ath12k_fw_pdev *fw_pdev = &ab->fw_pdev[i];
@ -4241,7 +4266,8 @@ static int ath12k_wmi_tlv_mac_phy_caps_ext(struct ath12k_base *ab, u16 tag,
return -EPROTO;
if (ab->hw_params->single_pdev_only) {
if (ab->wmi_ab.preferred_hw_mode != le32_to_cpu(caps->hw_mode_id))
if (ab->wmi_ab.preferred_hw_mode != le32_to_cpu(caps->hw_mode_id) &&
caps->hw_mode_id != WMI_HOST_HW_MODE_SINGLE)
return 0;
} else {
for (i = 0; i < ab->num_radios; i++) {
@ -5395,7 +5421,13 @@ static void ath12k_wmi_htc_tx_complete(struct ath12k_base *ab,
static bool ath12k_reg_is_world_alpha(char *alpha)
{
return alpha[0] == '0' && alpha[1] == '0';
if (alpha[0] == '0' && alpha[1] == '0')
return true;
if (alpha[0] == 'n' && alpha[1] == 'a')
return true;
return false;
}
static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *skb)
@ -5867,8 +5899,9 @@ static void ath12k_mgmt_tx_compl_event(struct ath12k_base *ab, struct sk_buff *s
rcu_read_unlock();
}
static struct ath12k *ath12k_get_ar_on_scan_abort(struct ath12k_base *ab,
u32 vdev_id)
static struct ath12k *ath12k_get_ar_on_scan_state(struct ath12k_base *ab,
u32 vdev_id,
enum ath12k_scan_state state)
{
int i;
struct ath12k_pdev *pdev;
@ -5880,7 +5913,7 @@ static struct ath12k *ath12k_get_ar_on_scan_abort(struct ath12k_base *ab,
ar = pdev->ar;
spin_lock_bh(&ar->data_lock);
if (ar->scan.state == ATH12K_SCAN_ABORTING &&
if (ar->scan.state == state &&
ar->scan.vdev_id == vdev_id) {
spin_unlock_bh(&ar->data_lock);
return ar;
@ -5910,10 +5943,15 @@ static void ath12k_scan_event(struct ath12k_base *ab, struct sk_buff *skb)
* aborting scan's vdev id matches this event info.
*/
if (le32_to_cpu(scan_ev.event_type) == WMI_SCAN_EVENT_COMPLETED &&
le32_to_cpu(scan_ev.reason) == WMI_SCAN_REASON_CANCELLED)
ar = ath12k_get_ar_on_scan_abort(ab, le32_to_cpu(scan_ev.vdev_id));
else
le32_to_cpu(scan_ev.reason) == WMI_SCAN_REASON_CANCELLED) {
ar = ath12k_get_ar_on_scan_state(ab, le32_to_cpu(scan_ev.vdev_id),
ATH12K_SCAN_ABORTING);
if (!ar)
ar = ath12k_get_ar_on_scan_state(ab, le32_to_cpu(scan_ev.vdev_id),
ATH12K_SCAN_RUNNING);
} else {
ar = ath12k_mac_get_ar_by_vdev_id(ab, le32_to_cpu(scan_ev.vdev_id));
}
if (!ar) {
ath12k_warn(ab, "Received scan event for unknown vdev");
@ -6580,6 +6618,40 @@ static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
kfree(tb);
}
static void ath12k_rfkill_state_change_event(struct ath12k_base *ab,
struct sk_buff *skb)
{
const struct wmi_rfkill_state_change_event *ev;
const void **tb;
int ret;
tb = ath12k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
return;
}
ev = tb[WMI_TAG_RFKILL_EVENT];
if (!ev) {
kfree(tb);
return;
}
ath12k_dbg(ab, ATH12K_DBG_MAC,
"wmi tlv rfkill state change gpio %d type %d radio_state %d\n",
le32_to_cpu(ev->gpio_pin_num),
le32_to_cpu(ev->int_type),
le32_to_cpu(ev->radio_state));
spin_lock_bh(&ab->base_lock);
ab->rfkill_radio_on = (ev->radio_state == cpu_to_le32(WMI_RFKILL_RADIO_STATE_ON));
spin_unlock_bh(&ab->base_lock);
queue_work(ab->workqueue, &ab->rfkill_work);
kfree(tb);
}
static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
{
struct wmi_cmd_hdr *cmd_hdr;
@ -6672,6 +6744,9 @@ static void ath12k_wmi_op_rx(struct ath12k_base *ab, struct sk_buff *skb)
case WMI_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID:
ath12k_probe_resp_tx_status_event(ab, skb);
break;
case WMI_RFKILL_STATE_CHANGE_EVENTID:
ath12k_rfkill_state_change_event(ab, skb);
break;
/* add Unsupported events here */
case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
case WMI_PEER_OPER_MODE_CHANGE_EVENTID:

View File

@ -4793,6 +4793,31 @@ struct ath12k_wmi_base {
#define ATH12K_FW_STATS_BUF_SIZE (1024 * 1024)
enum wmi_sys_cap_info_flags {
WMI_SYS_CAP_INFO_RXTX_LED = BIT(0),
WMI_SYS_CAP_INFO_RFKILL = BIT(1),
};
#define WMI_RFKILL_CFG_GPIO_PIN_NUM GENMASK(5, 0)
#define WMI_RFKILL_CFG_RADIO_LEVEL BIT(6)
#define WMI_RFKILL_CFG_PIN_AS_GPIO GENMASK(10, 7)
enum wmi_rfkill_enable_radio {
WMI_RFKILL_ENABLE_RADIO_ON = 0,
WMI_RFKILL_ENABLE_RADIO_OFF = 1,
};
enum wmi_rfkill_radio_state {
WMI_RFKILL_RADIO_STATE_OFF = 1,
WMI_RFKILL_RADIO_STATE_ON = 2,
};
struct wmi_rfkill_state_change_event {
__le32 gpio_pin_num;
__le32 int_type;
__le32 radio_state;
} __packed;
void ath12k_wmi_init_qcn9274(struct ath12k_base *ab,
struct ath12k_wmi_resource_config_arg *config);
void ath12k_wmi_init_wcn7850(struct ath12k_base *ab,

View File

@ -230,13 +230,13 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
}
static unsigned int ath5k_ioread32(void *hw_priv, u32 reg_offset)
{
struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
struct ath5k_hw *ah = hw_priv;
return ath5k_hw_reg_read(ah, reg_offset);
}
static void ath5k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
{
struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
struct ath5k_hw *ah = hw_priv;
ath5k_hw_reg_write(ah, val, reg_offset);
}

View File

@ -54,7 +54,7 @@ MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
/* return bus cachesize in 4B word units */
static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
{
struct ath5k_hw *ah = (struct ath5k_hw *) common->priv;
struct ath5k_hw *ah = common->priv;
u8 u8tmp;
pci_read_config_byte(ah->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
@ -76,7 +76,7 @@ static void ath5k_pci_read_cachesize(struct ath_common *common, int *csz)
static bool
ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
{
struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
struct ath5k_hw *ah = common->ah;
u32 status, timeout;
/*

View File

@ -852,14 +852,14 @@ void ath6kl_tgt_stats_event(struct ath6kl_vif *vif, u8 *ptr, u32 len)
void ath6kl_wakeup_event(void *dev)
{
struct ath6kl *ar = (struct ath6kl *) dev;
struct ath6kl *ar = dev;
wake_up(&ar->event_wq);
}
void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr)
{
struct ath6kl *ar = (struct ath6kl *) devt;
struct ath6kl *ar = devt;
ar->tx_pwr = tx_pwr;
wake_up(&ar->event_wq);

View File

@ -708,7 +708,7 @@ void ath6kl_tx_complete(struct htc_target *target,
packet->endpoint >= ENDPOINT_MAX))
continue;
ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt;
ath6kl_cookie = packet->pkt_cntxt;
if (WARN_ON_ONCE(!ath6kl_cookie))
continue;

View File

@ -766,10 +766,10 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
}
}
static int ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
static u32 ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
struct ath9k_channel *chan)
{
int ret;
u32 ret;
if (IS_CHAN_2GHZ(chan)) {
if (IS_CHAN_HT40(chan))
@ -791,7 +791,7 @@ static int ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
return ret;
}
static int ar9561_hw_get_modes_txgain_index(struct ath_hw *ah,
static u32 ar9561_hw_get_modes_txgain_index(struct ath_hw *ah,
struct ath9k_channel *chan)
{
if (IS_CHAN_2GHZ(chan)) {
@ -916,7 +916,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
* TXGAIN initvals.
*/
if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
int modes_txgain_index = 1;
u32 modes_txgain_index = 1;
if (AR_SREV_9550(ah))
modes_txgain_index = ar9550_hw_get_modes_txgain_index(ah, chan);
@ -925,9 +925,6 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
modes_txgain_index =
ar9561_hw_get_modes_txgain_index(ah, chan);
if (modes_txgain_index < 0)
return -EINVAL;
REG_WRITE_ARRAY(&ah->iniModesTxGain, modes_txgain_index,
regWrites);
} else {

View File

@ -1293,7 +1293,7 @@ void ath9k_get_et_strings(struct ieee80211_hw *hw,
u32 sset, u8 *data)
{
if (sset == ETH_SS_STATS)
memcpy(data, *ath9k_gstrings_stats,
memcpy(data, ath9k_gstrings_stats,
sizeof(ath9k_gstrings_stats));
}

View File

@ -1481,31 +1481,31 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface)
{
struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
struct htc_target *htc_handle = hif_dev->htc_handle;
int ret;
const struct firmware *fw;
int ret;
ret = ath9k_hif_usb_alloc_urbs(hif_dev);
if (ret)
return ret;
if (hif_dev->flags & HIF_USB_READY) {
/* request cached firmware during suspend/resume cycle */
ret = request_firmware(&fw, hif_dev->fw_name,
&hif_dev->udev->dev);
if (ret)
goto fail_resume;
hif_dev->fw_data = fw->data;
hif_dev->fw_size = fw->size;
ret = ath9k_hif_usb_download_fw(hif_dev);
release_firmware(fw);
if (ret)
goto fail_resume;
} else {
ath9k_hif_usb_dealloc_urbs(hif_dev);
return -EIO;
if (!(hif_dev->flags & HIF_USB_READY)) {
ret = -EIO;
goto fail_resume;
}
/* request cached firmware during suspend/resume cycle */
ret = request_firmware(&fw, hif_dev->fw_name,
&hif_dev->udev->dev);
if (ret)
goto fail_resume;
hif_dev->fw_data = fw->data;
hif_dev->fw_size = fw->size;
ret = ath9k_hif_usb_download_fw(hif_dev);
release_firmware(fw);
if (ret)
goto fail_resume;
mdelay(100);
ret = ath9k_htc_resume(htc_handle);

View File

@ -423,7 +423,7 @@ void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
u32 sset, u8 *data)
{
if (sset == ETH_SS_STATS)
memcpy(data, *ath9k_htc_gstrings_stats,
memcpy(data, ath9k_htc_gstrings_stats,
sizeof(ath9k_htc_gstrings_stats));
}

View File

@ -180,7 +180,7 @@ static int wcn36xx_dxe_init_descs(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *wc
if (!wcn_ch->cpu_addr)
return -ENOMEM;
cur_dxe = (struct wcn36xx_dxe_desc *)wcn_ch->cpu_addr;
cur_dxe = wcn_ch->cpu_addr;
cur_ctl = wcn_ch->head_blk_ctl;
for (i = 0; i < wcn_ch->desc_num; i++) {
@ -453,7 +453,7 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch)
static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
{
struct wcn36xx *wcn = (struct wcn36xx *)dev;
struct wcn36xx *wcn = dev;
int int_src, int_reason;
wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src);
@ -541,7 +541,7 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
static irqreturn_t wcn36xx_irq_rx_ready(int irq, void *dev)
{
struct wcn36xx *wcn = (struct wcn36xx *)dev;
struct wcn36xx *wcn = dev;
wcn36xx_dxe_rx_frame(wcn);

View File

@ -576,7 +576,7 @@ static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, void *buf, size_t len)
if (len < sizeof(*rsp))
return -EIO;
rsp = (struct wcn36xx_hal_mac_start_rsp_msg *)buf;
rsp = buf;
if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->start_rsp_params.status)
return -EIO;
@ -1025,7 +1025,7 @@ static int wcn36xx_smd_switch_channel_rsp(void *buf, size_t len)
ret = wcn36xx_smd_rsp_status_check(buf, len);
if (ret)
return ret;
rsp = (struct wcn36xx_hal_switch_channel_rsp_msg *)buf;
rsp = buf;
wcn36xx_dbg(WCN36XX_DBG_HAL, "channel switched to: %d, status: %d\n",
rsp->channel_number, rsp->status);
return ret;
@ -1072,7 +1072,7 @@ static int wcn36xx_smd_process_ptt_msg_rsp(void *buf, size_t len,
if (ret)
return ret;
rsp = (struct wcn36xx_hal_process_ptt_msg_rsp_msg *)buf;
rsp = buf;
wcn36xx_dbg(WCN36XX_DBG_HAL, "process ptt msg responded with length %d\n",
rsp->header.len);
@ -1131,7 +1131,7 @@ static int wcn36xx_smd_update_scan_params_rsp(void *buf, size_t len)
{
struct wcn36xx_hal_update_scan_params_resp *rsp;
rsp = (struct wcn36xx_hal_update_scan_params_resp *)buf;
rsp = buf;
/* Remove the PNO version bit */
rsp->status &= (~(WCN36XX_FW_MSG_PNO_VERSION_MASK));
@ -1198,7 +1198,7 @@ static int wcn36xx_smd_add_sta_self_rsp(struct wcn36xx *wcn,
if (len < sizeof(*rsp))
return -EINVAL;
rsp = (struct wcn36xx_hal_add_sta_self_rsp_msg *)buf;
rsp = buf;
if (rsp->status != WCN36XX_FW_MSG_RESULT_SUCCESS) {
wcn36xx_warn("hal add sta self failure: %d\n",
@ -1316,7 +1316,7 @@ static int wcn36xx_smd_join_rsp(void *buf, size_t len)
if (wcn36xx_smd_rsp_status_check(buf, len))
return -EIO;
rsp = (struct wcn36xx_hal_join_rsp_msg *)buf;
rsp = buf;
wcn36xx_dbg(WCN36XX_DBG_HAL,
"hal rsp join status %d tx_mgmt_power %d\n",
@ -1481,7 +1481,7 @@ static int wcn36xx_smd_config_sta_rsp(struct wcn36xx *wcn,
if (len < sizeof(*rsp))
return -EINVAL;
rsp = (struct wcn36xx_hal_config_sta_rsp_msg *)buf;
rsp = buf;
params = &rsp->params;
if (params->status != WCN36XX_FW_MSG_RESULT_SUCCESS) {
@ -1849,7 +1849,7 @@ static int wcn36xx_smd_config_bss_rsp(struct wcn36xx *wcn,
if (len < sizeof(*rsp))
return -EINVAL;
rsp = (struct wcn36xx_hal_config_bss_rsp_msg *)buf;
rsp = buf;
params = &rsp->bss_rsp_params;
if (params->status != WCN36XX_FW_MSG_RESULT_SUCCESS) {
@ -2476,7 +2476,7 @@ static int wcn36xx_smd_add_ba_session_rsp(void *buf, int len, u8 *session)
if (len < sizeof(*rsp))
return -EINVAL;
rsp = (struct wcn36xx_hal_add_ba_session_rsp_msg *)buf;
rsp = buf;
if (rsp->status != WCN36XX_FW_MSG_RESULT_SUCCESS)
return rsp->status;
@ -2654,7 +2654,7 @@ static int wcn36xx_smd_trigger_ba_rsp(void *buf, int len, struct add_ba_info *ba
if (len < sizeof(*rsp))
return -EINVAL;
rsp = (struct wcn36xx_hal_trigger_ba_rsp_msg *) buf;
rsp = buf;
if (rsp->candidate_cnt < 1)
return rsp->status ? rsp->status : -EINVAL;

View File

@ -47,7 +47,7 @@ struct wcn36xx_fw_msg_status_rsp {
struct wcn36xx_hal_ind_msg {
struct list_head list;
size_t msg_len;
u8 msg[];
u8 msg[] __counted_by(msg_len);
};
struct wcn36xx;

View File

@ -53,7 +53,7 @@ static int wcn36xx_tm_cmd_ptt(struct wcn36xx *wcn, struct ieee80211_vif *vif,
buf = nla_data(tb[WCN36XX_TM_ATTR_DATA]);
buf_len = nla_len(tb[WCN36XX_TM_ATTR_DATA]);
msg = (struct ftm_rsp_msg *)buf;
msg = buf;
wcn36xx_dbg(WCN36XX_DBG_TESTMODE,
"testmode cmd wmi msg_id 0x%04X msg_len %d buf %pK buf_len %d\n",