linux/drivers/net/wireless/ath/ath11k/hal_rx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause-Clear
   2/*
   3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
   4 */
   5
   6#include "debug.h"
   7#include "hal.h"
   8#include "hal_tx.h"
   9#include "hal_rx.h"
  10#include "hal_desc.h"
  11#include "hif.h"
  12
  13static void ath11k_hal_reo_set_desc_hdr(struct hal_desc_header *hdr,
  14                                        u8 owner, u8 buffer_type, u32 magic)
  15{
  16        hdr->info0 = FIELD_PREP(HAL_DESC_HDR_INFO0_OWNER, owner) |
  17                     FIELD_PREP(HAL_DESC_HDR_INFO0_BUF_TYPE, buffer_type);
  18
  19        /* Magic pattern in reserved bits for debugging */
  20        hdr->info0 |= FIELD_PREP(HAL_DESC_HDR_INFO0_DBG_RESERVED, magic);
  21}
  22
  23static int ath11k_hal_reo_cmd_queue_stats(struct hal_tlv_hdr *tlv,
  24                                          struct ath11k_hal_reo_cmd *cmd)
  25{
  26        struct hal_reo_get_queue_stats *desc;
  27
  28        tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_GET_QUEUE_STATS) |
  29                  FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc));
  30
  31        desc = (struct hal_reo_get_queue_stats *)tlv->value;
  32        memset(&desc->queue_addr_lo, 0,
  33               (sizeof(*desc) - sizeof(struct hal_reo_cmd_hdr)));
  34
  35        desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;
  36        if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS)
  37                desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;
  38
  39        desc->queue_addr_lo = cmd->addr_lo;
  40        desc->info0 = FIELD_PREP(HAL_REO_GET_QUEUE_STATS_INFO0_QUEUE_ADDR_HI,
  41                                 cmd->addr_hi);
  42        if (cmd->flag & HAL_REO_CMD_FLG_STATS_CLEAR)
  43                desc->info0 |= HAL_REO_GET_QUEUE_STATS_INFO0_CLEAR_STATS;
  44
  45        return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0);
  46}
  47
  48static int ath11k_hal_reo_cmd_flush_cache(struct ath11k_hal *hal, struct hal_tlv_hdr *tlv,
  49                                          struct ath11k_hal_reo_cmd *cmd)
  50{
  51        struct hal_reo_flush_cache *desc;
  52        u8 avail_slot = ffz(hal->avail_blk_resource);
  53
  54        if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) {
  55                if (avail_slot >= HAL_MAX_AVAIL_BLK_RES)
  56                        return -ENOSPC;
  57
  58                hal->current_blk_index = avail_slot;
  59        }
  60
  61        tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_FLUSH_CACHE) |
  62                  FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc));
  63
  64        desc = (struct hal_reo_flush_cache *)tlv->value;
  65        memset(&desc->cache_addr_lo, 0,
  66               (sizeof(*desc) - sizeof(struct hal_reo_cmd_hdr)));
  67
  68        desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;
  69        if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS)
  70                desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;
  71
  72        desc->cache_addr_lo = cmd->addr_lo;
  73        desc->info0 = FIELD_PREP(HAL_REO_FLUSH_CACHE_INFO0_CACHE_ADDR_HI,
  74                                 cmd->addr_hi);
  75
  76        if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_FWD_ALL_MPDUS)
  77                desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FWD_ALL_MPDUS;
  78
  79        if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_BLOCK_LATER) {
  80                desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_BLOCK_CACHE_USAGE;
  81                desc->info0 |=
  82                        FIELD_PREP(HAL_REO_FLUSH_CACHE_INFO0_BLOCK_RESRC_IDX,
  83                                   avail_slot);
  84        }
  85
  86        if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_NO_INVAL)
  87                desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FLUSH_WO_INVALIDATE;
  88
  89        if (cmd->flag & HAL_REO_CMD_FLG_FLUSH_ALL)
  90                desc->info0 |= HAL_REO_FLUSH_CACHE_INFO0_FLUSH_ALL;
  91
  92        return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0);
  93}
  94
  95static int ath11k_hal_reo_cmd_update_rx_queue(struct hal_tlv_hdr *tlv,
  96                                              struct ath11k_hal_reo_cmd *cmd)
  97{
  98        struct hal_reo_update_rx_queue *desc;
  99
 100        tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_REO_UPDATE_RX_REO_QUEUE) |
 101                  FIELD_PREP(HAL_TLV_HDR_LEN, sizeof(*desc));
 102
 103        desc = (struct hal_reo_update_rx_queue *)tlv->value;
 104        memset(&desc->queue_addr_lo, 0,
 105               (sizeof(*desc) - sizeof(struct hal_reo_cmd_hdr)));
 106
 107        desc->cmd.info0 &= ~HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;
 108        if (cmd->flag & HAL_REO_CMD_FLG_NEED_STATUS)
 109                desc->cmd.info0 |= HAL_REO_CMD_HDR_INFO0_STATUS_REQUIRED;
 110
 111        desc->queue_addr_lo = cmd->addr_lo;
 112        desc->info0 =
 113                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_QUEUE_ADDR_HI,
 114                           cmd->addr_hi) |
 115                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RX_QUEUE_NUM,
 116                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_RX_QUEUE_NUM)) |
 117                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_VLD,
 118                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_VLD)) |
 119                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_ASSOC_LNK_DESC_CNT,
 120                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_ALDC)) |
 121                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_DIS_DUP_DETECTION,
 122                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_DIS_DUP_DETECTION)) |
 123                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SOFT_REORDER_EN,
 124                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_SOFT_REORDER_EN)) |
 125                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_AC,
 126                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_AC)) |
 127                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BAR,
 128                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_BAR)) |
 129                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_RETRY,
 130                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_RETRY)) |
 131                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_CHECK_2K_MODE,
 132                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_CHECK_2K_MODE)) |
 133                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_OOR_MODE,
 134                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_OOR_MODE)) |
 135                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_BA_WINDOW_SIZE,
 136                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_BA_WINDOW_SIZE)) |
 137                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_CHECK,
 138                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_CHECK)) |
 139                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_EVEN_PN,
 140                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_EVEN_PN)) |
 141                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_UNEVEN_PN,
 142                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_UNEVEN_PN)) |
 143                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_HANDLE_ENABLE,
 144                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_HANDLE_ENABLE)) |
 145                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_SIZE,
 146                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_SIZE)) |
 147                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_IGNORE_AMPDU_FLG,
 148                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_IGNORE_AMPDU_FLG)) |
 149                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SVLD,
 150                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_SVLD)) |
 151                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SSN,
 152                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_SSN)) |
 153                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_SEQ_2K_ERR,
 154                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_SEQ_2K_ERR)) |
 155                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN_VALID,
 156                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN_VALID)) |
 157                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO0_UPD_PN,
 158                           !!(cmd->upd0 & HAL_REO_CMD_UPD0_PN));
 159
 160        desc->info1 =
 161                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_RX_QUEUE_NUMBER,
 162                           cmd->rx_queue_num) |
 163                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_VLD,
 164                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_VLD)) |
 165                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_ASSOC_LNK_DESC_COUNTER,
 166                           FIELD_GET(HAL_REO_CMD_UPD1_ALDC, cmd->upd1)) |
 167                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_DIS_DUP_DETECTION,
 168                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_DIS_DUP_DETECTION)) |
 169                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_SOFT_REORDER_EN,
 170                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_SOFT_REORDER_EN)) |
 171                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_AC,
 172                           FIELD_GET(HAL_REO_CMD_UPD1_AC, cmd->upd1)) |
 173                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_BAR,
 174                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_BAR)) |
 175                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_CHECK_2K_MODE,
 176                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_CHECK_2K_MODE)) |
 177                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_RETRY,
 178                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_RETRY)) |
 179                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_OOR_MODE,
 180                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_OOR_MODE)) |
 181                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_PN_CHECK,
 182                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_CHECK)) |
 183                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_EVEN_PN,
 184                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_EVEN_PN)) |
 185                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_UNEVEN_PN,
 186                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_UNEVEN_PN)) |
 187                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_PN_HANDLE_ENABLE,
 188                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_PN_HANDLE_ENABLE)) |
 189                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO1_IGNORE_AMPDU_FLG,
 190                           !!(cmd->upd1 & HAL_REO_CMD_UPD1_IGNORE_AMPDU_FLG));
 191
 192        if (cmd->pn_size == 24)
 193                cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_24;
 194        else if (cmd->pn_size == 48)
 195                cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_48;
 196        else if (cmd->pn_size == 128)
 197                cmd->pn_size = HAL_RX_REO_QUEUE_PN_SIZE_128;
 198
 199        if (cmd->ba_window_size < 1)
 200                cmd->ba_window_size = 1;
 201
 202        if (cmd->ba_window_size == 1)
 203                cmd->ba_window_size++;
 204
 205        desc->info2 =
 206                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_BA_WINDOW_SIZE,
 207                           cmd->ba_window_size - 1) |
 208                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_PN_SIZE, cmd->pn_size) |
 209                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SVLD,
 210                           !!(cmd->upd2 & HAL_REO_CMD_UPD2_SVLD)) |
 211                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SSN,
 212                           FIELD_GET(HAL_REO_CMD_UPD2_SSN, cmd->upd2)) |
 213                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_SEQ_2K_ERR,
 214                           !!(cmd->upd2 & HAL_REO_CMD_UPD2_SEQ_2K_ERR)) |
 215                FIELD_PREP(HAL_REO_UPD_RX_QUEUE_INFO2_PN_ERR,
 216                           !!(cmd->upd2 & HAL_REO_CMD_UPD2_PN_ERR));
 217
 218        return FIELD_GET(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, desc->cmd.info0);
 219}
 220
 221int ath11k_hal_reo_cmd_send(struct ath11k_base *ab, struct hal_srng *srng,
 222                            enum hal_reo_cmd_type type,
 223                            struct ath11k_hal_reo_cmd *cmd)
 224{
 225        struct hal_tlv_hdr *reo_desc;
 226        int ret;
 227
 228        spin_lock_bh(&srng->lock);
 229
 230        ath11k_hal_srng_access_begin(ab, srng);
 231        reo_desc = (struct hal_tlv_hdr *)ath11k_hal_srng_src_get_next_entry(ab, srng);
 232        if (!reo_desc) {
 233                ret = -ENOBUFS;
 234                goto out;
 235        }
 236
 237        switch (type) {
 238        case HAL_REO_CMD_GET_QUEUE_STATS:
 239                ret = ath11k_hal_reo_cmd_queue_stats(reo_desc, cmd);
 240                break;
 241        case HAL_REO_CMD_FLUSH_CACHE:
 242                ret = ath11k_hal_reo_cmd_flush_cache(&ab->hal, reo_desc, cmd);
 243                break;
 244        case HAL_REO_CMD_UPDATE_RX_QUEUE:
 245                ret = ath11k_hal_reo_cmd_update_rx_queue(reo_desc, cmd);
 246                break;
 247        case HAL_REO_CMD_FLUSH_QUEUE:
 248        case HAL_REO_CMD_UNBLOCK_CACHE:
 249        case HAL_REO_CMD_FLUSH_TIMEOUT_LIST:
 250                ath11k_warn(ab, "Unsupported reo command %d\n", type);
 251                ret = -ENOTSUPP;
 252                break;
 253        default:
 254                ath11k_warn(ab, "Unknown reo command %d\n", type);
 255                ret = -EINVAL;
 256                break;
 257        }
 258
 259        ath11k_dp_shadow_start_timer(ab, srng, &ab->dp.reo_cmd_timer);
 260
 261out:
 262        ath11k_hal_srng_access_end(ab, srng);
 263        spin_unlock_bh(&srng->lock);
 264
 265        return ret;
 266}
 267
 268void ath11k_hal_rx_buf_addr_info_set(void *desc, dma_addr_t paddr,
 269                                     u32 cookie, u8 manager)
 270{
 271        struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc;
 272        u32 paddr_lo, paddr_hi;
 273
 274        paddr_lo = lower_32_bits(paddr);
 275        paddr_hi = upper_32_bits(paddr);
 276        binfo->info0 = FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, paddr_lo);
 277        binfo->info1 = FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, paddr_hi) |
 278                       FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, cookie) |
 279                       FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, manager);
 280}
 281
 282void ath11k_hal_rx_buf_addr_info_get(void *desc, dma_addr_t *paddr,
 283                                     u32 *cookie, u8 *rbm)
 284{
 285        struct ath11k_buffer_addr *binfo = (struct ath11k_buffer_addr *)desc;
 286
 287        *paddr =
 288                (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR, binfo->info1)) << 32) |
 289                FIELD_GET(BUFFER_ADDR_INFO0_ADDR, binfo->info0);
 290        *cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, binfo->info1);
 291        *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR, binfo->info1);
 292}
 293
 294void ath11k_hal_rx_msdu_link_info_get(void *link_desc, u32 *num_msdus,
 295                                      u32 *msdu_cookies,
 296                                      enum hal_rx_buf_return_buf_manager *rbm)
 297{
 298        struct hal_rx_msdu_link *link = (struct hal_rx_msdu_link *)link_desc;
 299        struct hal_rx_msdu_details *msdu;
 300        int i;
 301
 302        *num_msdus = HAL_NUM_RX_MSDUS_PER_LINK_DESC;
 303
 304        msdu = &link->msdu_link[0];
 305        *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
 306                         msdu->buf_addr_info.info1);
 307
 308        for (i = 0; i < *num_msdus; i++) {
 309                msdu = &link->msdu_link[i];
 310
 311                if (!FIELD_GET(BUFFER_ADDR_INFO0_ADDR,
 312                               msdu->buf_addr_info.info0)) {
 313                        *num_msdus = i;
 314                        break;
 315                }
 316                *msdu_cookies = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
 317                                          msdu->buf_addr_info.info1);
 318                msdu_cookies++;
 319        }
 320}
 321
 322int ath11k_hal_desc_reo_parse_err(struct ath11k_base *ab, u32 *rx_desc,
 323                                  dma_addr_t *paddr, u32 *desc_bank)
 324{
 325        struct hal_reo_dest_ring *desc = (struct hal_reo_dest_ring *)rx_desc;
 326        enum hal_reo_dest_ring_push_reason push_reason;
 327        enum hal_reo_dest_ring_error_code err_code;
 328
 329        push_reason = FIELD_GET(HAL_REO_DEST_RING_INFO0_PUSH_REASON,
 330                                desc->info0);
 331        err_code = FIELD_GET(HAL_REO_DEST_RING_INFO0_ERROR_CODE,
 332                             desc->info0);
 333        ab->soc_stats.reo_error[err_code]++;
 334
 335        if (push_reason != HAL_REO_DEST_RING_PUSH_REASON_ERR_DETECTED &&
 336            push_reason != HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
 337                ath11k_warn(ab, "expected error push reason code, received %d\n",
 338                            push_reason);
 339                return -EINVAL;
 340        }
 341
 342        if (FIELD_GET(HAL_REO_DEST_RING_INFO0_BUFFER_TYPE, desc->info0) !=
 343            HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) {
 344                ath11k_warn(ab, "expected buffer type link_desc");
 345                return -EINVAL;
 346        }
 347
 348        ath11k_hal_rx_reo_ent_paddr_get(ab, rx_desc, paddr, desc_bank);
 349
 350        return 0;
 351}
 352
 353int ath11k_hal_wbm_desc_parse_err(struct ath11k_base *ab, void *desc,
 354                                  struct hal_rx_wbm_rel_info *rel_info)
 355{
 356        struct hal_wbm_release_ring *wbm_desc = desc;
 357        enum hal_wbm_rel_desc_type type;
 358        enum hal_wbm_rel_src_module rel_src;
 359
 360        type = FIELD_GET(HAL_WBM_RELEASE_INFO0_DESC_TYPE,
 361                         wbm_desc->info0);
 362        /* We expect only WBM_REL buffer type */
 363        if (type != HAL_WBM_REL_DESC_TYPE_REL_MSDU) {
 364                WARN_ON(1);
 365                return -EINVAL;
 366        }
 367
 368        rel_src = FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE,
 369                            wbm_desc->info0);
 370        if (rel_src != HAL_WBM_REL_SRC_MODULE_RXDMA &&
 371            rel_src != HAL_WBM_REL_SRC_MODULE_REO)
 372                return -EINVAL;
 373
 374        if (FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
 375                      wbm_desc->buf_addr_info.info1) != HAL_RX_BUF_RBM_SW3_BM) {
 376                ab->soc_stats.invalid_rbm++;
 377                return -EINVAL;
 378        }
 379
 380        rel_info->cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
 381                                     wbm_desc->buf_addr_info.info1);
 382        rel_info->err_rel_src = rel_src;
 383        if (rel_src == HAL_WBM_REL_SRC_MODULE_REO) {
 384                rel_info->push_reason =
 385                        FIELD_GET(HAL_WBM_RELEASE_INFO0_REO_PUSH_REASON,
 386                                  wbm_desc->info0);
 387                rel_info->err_code =
 388                        FIELD_GET(HAL_WBM_RELEASE_INFO0_REO_ERROR_CODE,
 389                                  wbm_desc->info0);
 390        } else {
 391                rel_info->push_reason =
 392                        FIELD_GET(HAL_WBM_RELEASE_INFO0_RXDMA_PUSH_REASON,
 393                                  wbm_desc->info0);
 394                rel_info->err_code =
 395                        FIELD_GET(HAL_WBM_RELEASE_INFO0_RXDMA_ERROR_CODE,
 396                                  wbm_desc->info0);
 397        }
 398
 399        rel_info->first_msdu = FIELD_GET(HAL_WBM_RELEASE_INFO2_FIRST_MSDU,
 400                                         wbm_desc->info2);
 401        rel_info->last_msdu = FIELD_GET(HAL_WBM_RELEASE_INFO2_LAST_MSDU,
 402                                        wbm_desc->info2);
 403        return 0;
 404}
 405
 406void ath11k_hal_rx_reo_ent_paddr_get(struct ath11k_base *ab, void *desc,
 407                                     dma_addr_t *paddr, u32 *desc_bank)
 408{
 409        struct ath11k_buffer_addr *buff_addr = desc;
 410
 411        *paddr = ((u64)(FIELD_GET(BUFFER_ADDR_INFO1_ADDR, buff_addr->info1)) << 32) |
 412                  FIELD_GET(BUFFER_ADDR_INFO0_ADDR, buff_addr->info0);
 413
 414        *desc_bank = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE, buff_addr->info1);
 415}
 416
 417void ath11k_hal_rx_msdu_link_desc_set(struct ath11k_base *ab, void *desc,
 418                                      void *link_desc,
 419                                      enum hal_wbm_rel_bm_act action)
 420{
 421        struct hal_wbm_release_ring *dst_desc = desc;
 422        struct hal_wbm_release_ring *src_desc = link_desc;
 423
 424        dst_desc->buf_addr_info = src_desc->buf_addr_info;
 425        dst_desc->info0 |= FIELD_PREP(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE,
 426                                      HAL_WBM_REL_SRC_MODULE_SW) |
 427                           FIELD_PREP(HAL_WBM_RELEASE_INFO0_BM_ACTION, action) |
 428                           FIELD_PREP(HAL_WBM_RELEASE_INFO0_DESC_TYPE,
 429                                      HAL_WBM_REL_DESC_TYPE_MSDU_LINK);
 430}
 431
 432void ath11k_hal_reo_status_queue_stats(struct ath11k_base *ab, u32 *reo_desc,
 433                                       struct hal_reo_status *status)
 434{
 435        struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;
 436        struct hal_reo_get_queue_stats_status *desc =
 437                (struct hal_reo_get_queue_stats_status *)tlv->value;
 438
 439        status->uniform_hdr.cmd_num =
 440                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,
 441                                          desc->hdr.info0);
 442        status->uniform_hdr.cmd_status =
 443                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,
 444                                          desc->hdr.info0);
 445
 446        ath11k_dbg(ab, ATH11k_DBG_HAL, "Queue stats status:\n");
 447        ath11k_dbg(ab, ATH11k_DBG_HAL, "header: cmd_num %d status %d\n",
 448                   status->uniform_hdr.cmd_num,
 449                   status->uniform_hdr.cmd_status);
 450        ath11k_dbg(ab, ATH11k_DBG_HAL, "ssn %ld cur_idx %ld\n",
 451                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_SSN,
 452                             desc->info0),
 453                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO0_CUR_IDX,
 454                             desc->info0));
 455        ath11k_dbg(ab, ATH11k_DBG_HAL, "pn = [%08x, %08x, %08x, %08x]\n",
 456                   desc->pn[0], desc->pn[1], desc->pn[2], desc->pn[3]);
 457        ath11k_dbg(ab, ATH11k_DBG_HAL, "last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n",
 458                   desc->last_rx_enqueue_timestamp,
 459                   desc->last_rx_dequeue_timestamp);
 460        ath11k_dbg(ab, ATH11k_DBG_HAL, "rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n",
 461                   desc->rx_bitmap[0], desc->rx_bitmap[1], desc->rx_bitmap[2],
 462                   desc->rx_bitmap[3], desc->rx_bitmap[4], desc->rx_bitmap[5],
 463                   desc->rx_bitmap[6], desc->rx_bitmap[7]);
 464        ath11k_dbg(ab, ATH11k_DBG_HAL, "count: cur_mpdu %ld cur_msdu %ld\n",
 465                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MPDU_COUNT,
 466                             desc->info1),
 467                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO1_MSDU_COUNT,
 468                             desc->info1));
 469        ath11k_dbg(ab, ATH11k_DBG_HAL, "fwd_timeout %ld fwd_bar %ld dup_count %ld\n",
 470                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_TIMEOUT_COUNT,
 471                             desc->info2),
 472                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_FDTB_COUNT,
 473                             desc->info2),
 474                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO2_DUPLICATE_COUNT,
 475                             desc->info2));
 476        ath11k_dbg(ab, ATH11k_DBG_HAL, "frames_in_order %ld bar_rcvd %ld\n",
 477                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_FIO_COUNT,
 478                             desc->info3),
 479                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO3_BAR_RCVD_CNT,
 480                             desc->info3));
 481        ath11k_dbg(ab, ATH11k_DBG_HAL, "num_mpdus %d num_msdus %d total_bytes %d\n",
 482                   desc->num_mpdu_frames, desc->num_msdu_frames,
 483                   desc->total_bytes);
 484        ath11k_dbg(ab, ATH11k_DBG_HAL, "late_rcvd %ld win_jump_2k %ld hole_cnt %ld\n",
 485                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_LATE_RX_MPDU,
 486                             desc->info4),
 487                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_WINDOW_JMP2K,
 488                             desc->info4),
 489                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO4_HOLE_COUNT,
 490                             desc->info4));
 491        ath11k_dbg(ab, ATH11k_DBG_HAL, "looping count %ld\n",
 492                   FIELD_GET(HAL_REO_GET_QUEUE_STATS_STATUS_INFO5_LOOPING_CNT,
 493                             desc->info5));
 494}
 495
 496int ath11k_hal_reo_process_status(u8 *reo_desc, u8 *status)
 497{
 498        struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;
 499        struct hal_reo_status_hdr *hdr;
 500
 501        hdr = (struct hal_reo_status_hdr *)tlv->value;
 502        *status = FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS, hdr->info0);
 503
 504        return FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM, hdr->info0);
 505}
 506
 507void ath11k_hal_reo_flush_queue_status(struct ath11k_base *ab, u32 *reo_desc,
 508                                       struct hal_reo_status *status)
 509{
 510        struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;
 511        struct hal_reo_flush_queue_status *desc =
 512                (struct hal_reo_flush_queue_status *)tlv->value;
 513
 514        status->uniform_hdr.cmd_num =
 515                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,
 516                                          desc->hdr.info0);
 517        status->uniform_hdr.cmd_status =
 518                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,
 519                                          desc->hdr.info0);
 520        status->u.flush_queue.err_detected =
 521                FIELD_GET(HAL_REO_FLUSH_QUEUE_INFO0_ERR_DETECTED,
 522                          desc->info0);
 523}
 524
 525void ath11k_hal_reo_flush_cache_status(struct ath11k_base *ab, u32 *reo_desc,
 526                                       struct hal_reo_status *status)
 527{
 528        struct ath11k_hal *hal = &ab->hal;
 529        struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;
 530        struct hal_reo_flush_cache_status *desc =
 531                (struct hal_reo_flush_cache_status *)tlv->value;
 532
 533        status->uniform_hdr.cmd_num =
 534                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,
 535                                          desc->hdr.info0);
 536        status->uniform_hdr.cmd_status =
 537                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,
 538                                          desc->hdr.info0);
 539
 540        status->u.flush_cache.err_detected =
 541                        FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_IS_ERR,
 542                                  desc->info0);
 543        status->u.flush_cache.err_code =
 544                FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_BLOCK_ERR_CODE,
 545                          desc->info0);
 546        if (!status->u.flush_cache.err_code)
 547                hal->avail_blk_resource |= BIT(hal->current_blk_index);
 548
 549        status->u.flush_cache.cache_controller_flush_status_hit =
 550                FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_STATUS_HIT,
 551                          desc->info0);
 552
 553        status->u.flush_cache.cache_controller_flush_status_desc_type =
 554                FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_DESC_TYPE,
 555                          desc->info0);
 556        status->u.flush_cache.cache_controller_flush_status_client_id =
 557                FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_CLIENT_ID,
 558                          desc->info0);
 559        status->u.flush_cache.cache_controller_flush_status_err =
 560                FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_ERR,
 561                          desc->info0);
 562        status->u.flush_cache.cache_controller_flush_status_cnt =
 563                FIELD_GET(HAL_REO_FLUSH_CACHE_STATUS_INFO0_FLUSH_COUNT,
 564                          desc->info0);
 565}
 566
 567void ath11k_hal_reo_unblk_cache_status(struct ath11k_base *ab, u32 *reo_desc,
 568                                       struct hal_reo_status *status)
 569{
 570        struct ath11k_hal *hal = &ab->hal;
 571        struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;
 572        struct hal_reo_unblock_cache_status *desc =
 573                (struct hal_reo_unblock_cache_status *)tlv->value;
 574
 575        status->uniform_hdr.cmd_num =
 576                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,
 577                                          desc->hdr.info0);
 578        status->uniform_hdr.cmd_status =
 579                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,
 580                                          desc->hdr.info0);
 581
 582        status->u.unblock_cache.err_detected =
 583                        FIELD_GET(HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_IS_ERR,
 584                                  desc->info0);
 585        status->u.unblock_cache.unblock_type =
 586                        FIELD_GET(HAL_REO_UNBLOCK_CACHE_STATUS_INFO0_TYPE,
 587                                  desc->info0);
 588
 589        if (!status->u.unblock_cache.err_detected &&
 590            status->u.unblock_cache.unblock_type ==
 591            HAL_REO_STATUS_UNBLOCK_BLOCKING_RESOURCE)
 592                hal->avail_blk_resource &= ~BIT(hal->current_blk_index);
 593}
 594
 595void ath11k_hal_reo_flush_timeout_list_status(struct ath11k_base *ab,
 596                                              u32 *reo_desc,
 597                                              struct hal_reo_status *status)
 598{
 599        struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;
 600        struct hal_reo_flush_timeout_list_status *desc =
 601                (struct hal_reo_flush_timeout_list_status *)tlv->value;
 602
 603        status->uniform_hdr.cmd_num =
 604                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,
 605                                          desc->hdr.info0);
 606        status->uniform_hdr.cmd_status =
 607                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,
 608                                          desc->hdr.info0);
 609
 610        status->u.timeout_list.err_detected =
 611                        FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_IS_ERR,
 612                                  desc->info0);
 613        status->u.timeout_list.list_empty =
 614                        FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO0_LIST_EMPTY,
 615                                  desc->info0);
 616
 617        status->u.timeout_list.release_desc_cnt =
 618                FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_REL_DESC_COUNT,
 619                          desc->info1);
 620        status->u.timeout_list.fwd_buf_cnt =
 621                FIELD_GET(HAL_REO_FLUSH_TIMEOUT_STATUS_INFO1_FWD_BUF_COUNT,
 622                          desc->info1);
 623}
 624
 625void ath11k_hal_reo_desc_thresh_reached_status(struct ath11k_base *ab,
 626                                               u32 *reo_desc,
 627                                               struct hal_reo_status *status)
 628{
 629        struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;
 630        struct hal_reo_desc_thresh_reached_status *desc =
 631                (struct hal_reo_desc_thresh_reached_status *)tlv->value;
 632
 633        status->uniform_hdr.cmd_num =
 634                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,
 635                                          desc->hdr.info0);
 636        status->uniform_hdr.cmd_status =
 637                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,
 638                                          desc->hdr.info0);
 639
 640        status->u.desc_thresh_reached.threshold_idx =
 641                FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO0_THRESH_INDEX,
 642                          desc->info0);
 643
 644        status->u.desc_thresh_reached.link_desc_counter0 =
 645                FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO1_LINK_DESC_COUNTER0,
 646                          desc->info1);
 647
 648        status->u.desc_thresh_reached.link_desc_counter1 =
 649                FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO2_LINK_DESC_COUNTER1,
 650                          desc->info2);
 651
 652        status->u.desc_thresh_reached.link_desc_counter2 =
 653                FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO3_LINK_DESC_COUNTER2,
 654                          desc->info3);
 655
 656        status->u.desc_thresh_reached.link_desc_counter_sum =
 657                FIELD_GET(HAL_REO_DESC_THRESH_STATUS_INFO4_LINK_DESC_COUNTER_SUM,
 658                          desc->info4);
 659}
 660
 661void ath11k_hal_reo_update_rx_reo_queue_status(struct ath11k_base *ab,
 662                                               u32 *reo_desc,
 663                                               struct hal_reo_status *status)
 664{
 665        struct hal_tlv_hdr *tlv = (struct hal_tlv_hdr *)reo_desc;
 666        struct hal_reo_status_hdr *desc =
 667                (struct hal_reo_status_hdr *)tlv->value;
 668
 669        status->uniform_hdr.cmd_num =
 670                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_STATUS_NUM,
 671                                          desc->info0);
 672        status->uniform_hdr.cmd_status =
 673                                FIELD_GET(HAL_REO_STATUS_HDR_INFO0_EXEC_STATUS,
 674                                          desc->info0);
 675}
 676
 677u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid)
 678{
 679        u32 num_ext_desc;
 680
 681        if (ba_window_size <= 1) {
 682                if (tid != HAL_DESC_REO_NON_QOS_TID)
 683                        num_ext_desc = 1;
 684                else
 685                        num_ext_desc = 0;
 686        } else if (ba_window_size <= 105) {
 687                num_ext_desc = 1;
 688        } else if (ba_window_size <= 210) {
 689                num_ext_desc = 2;
 690        } else {
 691                num_ext_desc = 3;
 692        }
 693
 694        return sizeof(struct hal_rx_reo_queue) +
 695                (num_ext_desc * sizeof(struct hal_rx_reo_queue_ext));
 696}
 697
 698void ath11k_hal_reo_qdesc_setup(void *vaddr, int tid, u32 ba_window_size,
 699                                u32 start_seq, enum hal_pn_type type)
 700{
 701        struct hal_rx_reo_queue *qdesc = (struct hal_rx_reo_queue *)vaddr;
 702        struct hal_rx_reo_queue_ext *ext_desc;
 703
 704        memset(qdesc, 0, sizeof(*qdesc));
 705
 706        ath11k_hal_reo_set_desc_hdr(&qdesc->desc_hdr, HAL_DESC_REO_OWNED,
 707                                    HAL_DESC_REO_QUEUE_DESC,
 708                                    REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_0);
 709
 710        qdesc->rx_queue_num = FIELD_PREP(HAL_RX_REO_QUEUE_RX_QUEUE_NUMBER, tid);
 711
 712        qdesc->info0 =
 713                FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_VLD, 1) |
 714                FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_ASSOC_LNK_DESC_COUNTER, 1) |
 715                FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_AC, ath11k_tid_to_ac(tid));
 716
 717        if (ba_window_size < 1)
 718                ba_window_size = 1;
 719
 720        if (ba_window_size == 1 && tid != HAL_DESC_REO_NON_QOS_TID)
 721                ba_window_size++;
 722
 723        if (ba_window_size == 1)
 724                qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_RETRY, 1);
 725
 726        qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_BA_WINDOW_SIZE,
 727                                   ba_window_size - 1);
 728        switch (type) {
 729        case HAL_PN_TYPE_NONE:
 730        case HAL_PN_TYPE_WAPI_EVEN:
 731        case HAL_PN_TYPE_WAPI_UNEVEN:
 732                break;
 733        case HAL_PN_TYPE_WPA:
 734                qdesc->info0 |=
 735                        FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_CHECK, 1) |
 736                        FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_PN_SIZE,
 737                                   HAL_RX_REO_QUEUE_PN_SIZE_48);
 738                break;
 739        }
 740
 741        /* TODO: Set Ignore ampdu flags based on BA window size and/or
 742         * AMPDU capabilities
 743         */
 744        qdesc->info0 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO0_IGNORE_AMPDU_FLG, 1);
 745
 746        qdesc->info1 |= FIELD_PREP(HAL_RX_REO_QUEUE_INFO1_SVLD, 0);
 747
 748        if (start_seq <= 0xfff)
 749                qdesc->info1 = FIELD_PREP(HAL_RX_REO_QUEUE_INFO1_SSN,
 750                                          start_seq);
 751
 752        if (tid == HAL_DESC_REO_NON_QOS_TID)
 753                return;
 754
 755        ext_desc = qdesc->ext_desc;
 756
 757        /* TODO: HW queue descriptors are currently allocated for max BA
 758         * window size for all QOS TIDs so that same descriptor can be used
 759         * later when ADDBA request is recevied. This should be changed to
 760         * allocate HW queue descriptors based on BA window size being
 761         * negotiated (0 for non BA cases), and reallocate when BA window
 762         * size changes and also send WMI message to FW to change the REO
 763         * queue descriptor in Rx peer entry as part of dp_rx_tid_update.
 764         */
 765        memset(ext_desc, 0, 3 * sizeof(*ext_desc));
 766        ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED,
 767                                    HAL_DESC_REO_QUEUE_EXT_DESC,
 768                                    REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_1);
 769        ext_desc++;
 770        ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED,
 771                                    HAL_DESC_REO_QUEUE_EXT_DESC,
 772                                    REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_2);
 773        ext_desc++;
 774        ath11k_hal_reo_set_desc_hdr(&ext_desc->desc_hdr, HAL_DESC_REO_OWNED,
 775                                    HAL_DESC_REO_QUEUE_EXT_DESC,
 776                                    REO_QUEUE_DESC_MAGIC_DEBUG_PATTERN_3);
 777}
 778
 779void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab,
 780                                  struct hal_srng *srng)
 781{
 782        struct hal_srng_params params;
 783        struct hal_tlv_hdr *tlv;
 784        struct hal_reo_get_queue_stats *desc;
 785        int i, cmd_num = 1;
 786        int entry_size;
 787        u8 *entry;
 788
 789        memset(&params, 0, sizeof(params));
 790
 791        entry_size = ath11k_hal_srng_get_entrysize(ab, HAL_REO_CMD);
 792        ath11k_hal_srng_get_params(ab, srng, &params);
 793        entry = (u8 *)params.ring_base_vaddr;
 794
 795        for (i = 0; i < params.num_entries; i++) {
 796                tlv = (struct hal_tlv_hdr *)entry;
 797                desc = (struct hal_reo_get_queue_stats *)tlv->value;
 798                desc->cmd.info0 =
 799                        FIELD_PREP(HAL_REO_CMD_HDR_INFO0_CMD_NUMBER, cmd_num++);
 800                entry += entry_size;
 801        }
 802}
 803
 804static enum hal_rx_mon_status
 805ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
 806                                   struct hal_rx_mon_ppdu_info *ppdu_info,
 807                                   u32 tlv_tag, u8 *tlv_data)
 808{
 809        u32 info0, info1;
 810
 811        switch (tlv_tag) {
 812        case HAL_RX_PPDU_START: {
 813                struct hal_rx_ppdu_start *ppdu_start =
 814                        (struct hal_rx_ppdu_start *)tlv_data;
 815
 816                ppdu_info->ppdu_id =
 817                        FIELD_GET(HAL_RX_PPDU_START_INFO0_PPDU_ID,
 818                                  __le32_to_cpu(ppdu_start->info0));
 819                ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num);
 820                ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts);
 821                break;
 822        }
 823        case HAL_RX_PPDU_END_USER_STATS: {
 824                struct hal_rx_ppdu_end_user_stats *eu_stats =
 825                        (struct hal_rx_ppdu_end_user_stats *)tlv_data;
 826
 827                info0 = __le32_to_cpu(eu_stats->info0);
 828                info1 = __le32_to_cpu(eu_stats->info1);
 829
 830                ppdu_info->tid =
 831                        ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP,
 832                                      __le32_to_cpu(eu_stats->info6))) - 1;
 833                ppdu_info->tcp_msdu_count =
 834                        FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT,
 835                                  __le32_to_cpu(eu_stats->info4));
 836                ppdu_info->udp_msdu_count =
 837                        FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT,
 838                                  __le32_to_cpu(eu_stats->info4));
 839                ppdu_info->other_msdu_count =
 840                        FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT,
 841                                  __le32_to_cpu(eu_stats->info5));
 842                ppdu_info->tcp_ack_msdu_count =
 843                        FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT,
 844                                  __le32_to_cpu(eu_stats->info5));
 845                ppdu_info->preamble_type =
 846                        FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE, info1);
 847                ppdu_info->num_mpdu_fcs_ok =
 848                        FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK,
 849                                  info1);
 850                ppdu_info->num_mpdu_fcs_err =
 851                        FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR,
 852                                  info0);
 853                break;
 854        }
 855        case HAL_PHYRX_HT_SIG: {
 856                struct hal_rx_ht_sig_info *ht_sig =
 857                        (struct hal_rx_ht_sig_info *)tlv_data;
 858
 859                info0 = __le32_to_cpu(ht_sig->info0);
 860                info1 = __le32_to_cpu(ht_sig->info1);
 861
 862                ppdu_info->mcs = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO0_MCS, info0);
 863                ppdu_info->bw = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO0_BW, info0);
 864                ppdu_info->is_stbc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_STBC,
 865                                               info1);
 866                ppdu_info->ldpc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING, info1);
 867                ppdu_info->gi = info1 & HAL_RX_HT_SIG_INFO_INFO1_GI;
 868
 869                switch (ppdu_info->mcs) {
 870                case 0 ... 7:
 871                        ppdu_info->nss = 1;
 872                        break;
 873                case 8 ... 15:
 874                        ppdu_info->nss = 2;
 875                        break;
 876                case 16 ... 23:
 877                        ppdu_info->nss = 3;
 878                        break;
 879                case 24 ... 31:
 880                        ppdu_info->nss = 4;
 881                        break;
 882                }
 883
 884                if (ppdu_info->nss > 1)
 885                        ppdu_info->mcs = ppdu_info->mcs % 8;
 886
 887                ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
 888                break;
 889        }
 890        case HAL_PHYRX_L_SIG_B: {
 891                struct hal_rx_lsig_b_info *lsigb =
 892                        (struct hal_rx_lsig_b_info *)tlv_data;
 893
 894                ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_B_INFO_INFO0_RATE,
 895                                            __le32_to_cpu(lsigb->info0));
 896                ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
 897                break;
 898        }
 899        case HAL_PHYRX_L_SIG_A: {
 900                struct hal_rx_lsig_a_info *lsiga =
 901                        (struct hal_rx_lsig_a_info *)tlv_data;
 902
 903                ppdu_info->rate = FIELD_GET(HAL_RX_LSIG_A_INFO_INFO0_RATE,
 904                                            __le32_to_cpu(lsiga->info0));
 905                ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
 906                break;
 907        }
 908        case HAL_PHYRX_VHT_SIG_A: {
 909                struct hal_rx_vht_sig_a_info *vht_sig =
 910                        (struct hal_rx_vht_sig_a_info *)tlv_data;
 911                u32 nsts;
 912                u32 group_id;
 913                u8 gi_setting;
 914
 915                info0 = __le32_to_cpu(vht_sig->info0);
 916                info1 = __le32_to_cpu(vht_sig->info1);
 917
 918                ppdu_info->ldpc = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING,
 919                                            info0);
 920                ppdu_info->mcs = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_MCS,
 921                                           info1);
 922                gi_setting = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING,
 923                                       info1);
 924                switch (gi_setting) {
 925                case HAL_RX_VHT_SIG_A_NORMAL_GI:
 926                        ppdu_info->gi = HAL_RX_GI_0_8_US;
 927                        break;
 928                case HAL_RX_VHT_SIG_A_SHORT_GI:
 929                case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY:
 930                        ppdu_info->gi = HAL_RX_GI_0_4_US;
 931                        break;
 932                }
 933
 934                ppdu_info->is_stbc = info0 & HAL_RX_VHT_SIG_A_INFO_INFO0_STBC;
 935                nsts = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS, info0);
 936                if (ppdu_info->is_stbc && nsts > 0)
 937                        nsts = ((nsts + 1) >> 1) - 1;
 938
 939                ppdu_info->nss = (nsts & VHT_SIG_SU_NSS_MASK) + 1;
 940                ppdu_info->bw = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_BW,
 941                                          info0);
 942                ppdu_info->beamformed = info1 &
 943                                        HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED;
 944                group_id = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID,
 945                                     info0);
 946                if (group_id == 0 || group_id == 63)
 947                        ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
 948                else
 949                        ppdu_info->reception_type =
 950                                HAL_RX_RECEPTION_TYPE_MU_MIMO;
 951                break;
 952        }
 953        case HAL_PHYRX_HE_SIG_A_SU: {
 954                struct hal_rx_he_sig_a_su_info *he_sig_a =
 955                        (struct hal_rx_he_sig_a_su_info *)tlv_data;
 956                u32 nsts, cp_ltf, dcm;
 957
 958                info0 = __le32_to_cpu(he_sig_a->info0);
 959                info1 = __le32_to_cpu(he_sig_a->info1);
 960
 961                ppdu_info->mcs =
 962                        FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS,
 963                                  info0);
 964                ppdu_info->bw =
 965                        FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW,
 966                                  info0);
 967                ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING, info0);
 968                ppdu_info->is_stbc = info1 &
 969                                     HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC;
 970                ppdu_info->beamformed = info1 &
 971                                        HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF;
 972                dcm = info0 & HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM;
 973                cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE,
 974                                   info0);
 975                nsts = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0);
 976
 977                switch (cp_ltf) {
 978                case 0:
 979                case 1:
 980                        ppdu_info->gi = HAL_RX_GI_0_8_US;
 981                        break;
 982                case 2:
 983                        ppdu_info->gi = HAL_RX_GI_1_6_US;
 984                        break;
 985                case 3:
 986                        if (dcm && ppdu_info->is_stbc)
 987                                ppdu_info->gi = HAL_RX_GI_0_8_US;
 988                        else
 989                                ppdu_info->gi = HAL_RX_GI_3_2_US;
 990                        break;
 991                }
 992
 993                ppdu_info->nss = nsts + 1;
 994                ppdu_info->dcm = dcm;
 995                ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
 996                break;
 997        }
 998        case HAL_PHYRX_HE_SIG_A_MU_DL: {
 999                struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl =
1000                        (struct hal_rx_he_sig_a_mu_dl_info *)tlv_data;
1001
1002                u32 cp_ltf;
1003
1004                info0 = __le32_to_cpu(he_sig_a_mu_dl->info0);
1005                info1 = __le32_to_cpu(he_sig_a_mu_dl->info1);
1006
1007                ppdu_info->bw =
1008                        FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW,
1009                                  info0);
1010                cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE,
1011                                   info0);
1012
1013                switch (cp_ltf) {
1014                case 0:
1015                case 1:
1016                        ppdu_info->gi = HAL_RX_GI_0_8_US;
1017                        break;
1018                case 2:
1019                        ppdu_info->gi = HAL_RX_GI_1_6_US;
1020                        break;
1021                case 3:
1022                        ppdu_info->gi = HAL_RX_GI_3_2_US;
1023                        break;
1024                }
1025
1026                ppdu_info->is_stbc = info1 &
1027                                     HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC;
1028                ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;
1029                break;
1030        }
1031        case HAL_PHYRX_HE_SIG_B1_MU: {
1032                struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu =
1033                        (struct hal_rx_he_sig_b1_mu_info *)tlv_data;
1034                u16 ru_tones;
1035
1036                info0 = __le32_to_cpu(he_sig_b1_mu->info0);
1037
1038                ru_tones = FIELD_GET(HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION,
1039                                     info0);
1040                ppdu_info->ru_alloc = ath11k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones);
1041                ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;
1042                break;
1043        }
1044        case HAL_PHYRX_HE_SIG_B2_MU: {
1045                struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu =
1046                        (struct hal_rx_he_sig_b2_mu_info *)tlv_data;
1047
1048                info0 = __le32_to_cpu(he_sig_b2_mu->info0);
1049
1050                ppdu_info->mcs =
1051                        FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS,
1052                                  info0);
1053                ppdu_info->nss =
1054                        FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS,
1055                                  info0) + 1;
1056                ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING,
1057                                            info0);
1058                break;
1059        }
1060        case HAL_PHYRX_HE_SIG_B2_OFDMA: {
1061                struct hal_rx_he_sig_b2_ofdma_info *he_sig_b2_ofdma =
1062                        (struct hal_rx_he_sig_b2_ofdma_info *)tlv_data;
1063
1064                info0 = __le32_to_cpu(he_sig_b2_ofdma->info0);
1065
1066                ppdu_info->mcs =
1067                        FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS,
1068                                  info0);
1069                ppdu_info->nss =
1070                        FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS,
1071                                  info0) + 1;
1072                ppdu_info->beamformed =
1073                        info0 &
1074                        HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF;
1075                ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING,
1076                                            info0);
1077                ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA;
1078                break;
1079        }
1080        case HAL_PHYRX_RSSI_LEGACY: {
1081                struct hal_rx_phyrx_rssi_legacy_info *rssi =
1082                        (struct hal_rx_phyrx_rssi_legacy_info *)tlv_data;
1083
1084                /* TODO: Please note that the combined rssi will not be accurate
1085                 * in MU case. Rssi in MU needs to be retrieved from
1086                 * PHYRX_OTHER_RECEIVE_INFO TLV.
1087                 */
1088                ppdu_info->rssi_comb =
1089                        FIELD_GET(HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB,
1090                                  __le32_to_cpu(rssi->info0));
1091                break;
1092        }
1093        case HAL_RX_MPDU_START: {
1094                u16 peer_id;
1095
1096                peer_id = ab->hw_params.hw_ops->mpdu_info_get_peerid(tlv_data);
1097                if (peer_id)
1098                        ppdu_info->peer_id = peer_id;
1099                break;
1100        }
1101        case HAL_RXPCU_PPDU_END_INFO: {
1102                struct hal_rx_ppdu_end_duration *ppdu_rx_duration =
1103                        (struct hal_rx_ppdu_end_duration *)tlv_data;
1104                ppdu_info->rx_duration =
1105                        FIELD_GET(HAL_RX_PPDU_END_DURATION,
1106                                  __le32_to_cpu(ppdu_rx_duration->info0));
1107                break;
1108        }
1109        case HAL_DUMMY:
1110                return HAL_RX_MON_STATUS_BUF_DONE;
1111        case HAL_RX_PPDU_END_STATUS_DONE:
1112        case 0:
1113                return HAL_RX_MON_STATUS_PPDU_DONE;
1114        default:
1115                break;
1116        }
1117
1118        return HAL_RX_MON_STATUS_PPDU_NOT_DONE;
1119}
1120
1121enum hal_rx_mon_status
1122ath11k_hal_rx_parse_mon_status(struct ath11k_base *ab,
1123                               struct hal_rx_mon_ppdu_info *ppdu_info,
1124                               struct sk_buff *skb)
1125{
1126        struct hal_tlv_hdr *tlv;
1127        enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE;
1128        u16 tlv_tag;
1129        u16 tlv_len;
1130        u8 *ptr = skb->data;
1131
1132        do {
1133                tlv = (struct hal_tlv_hdr *)ptr;
1134                tlv_tag = FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl);
1135                tlv_len = FIELD_GET(HAL_TLV_HDR_LEN, tlv->tl);
1136                ptr += sizeof(*tlv);
1137
1138                /* The actual length of PPDU_END is the combined length of many PHY
1139                 * TLVs that follow. Skip the TLV header and
1140                 * rx_rxpcu_classification_overview that follows the header to get to
1141                 * next TLV.
1142                 */
1143                if (tlv_tag == HAL_RX_PPDU_END)
1144                        tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview);
1145
1146                hal_status = ath11k_hal_rx_parse_mon_status_tlv(ab, ppdu_info,
1147                                                                tlv_tag, ptr);
1148                ptr += tlv_len;
1149                ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN);
1150
1151                if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE)
1152                        break;
1153        } while (hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE);
1154
1155        return hal_status;
1156}
1157
1158void ath11k_hal_rx_reo_ent_buf_paddr_get(void *rx_desc, dma_addr_t *paddr,
1159                                         u32 *sw_cookie, void **pp_buf_addr,
1160                                         u8 *rbm, u32 *msdu_cnt)
1161{
1162        struct hal_reo_entrance_ring *reo_ent_ring =
1163                (struct hal_reo_entrance_ring *)rx_desc;
1164        struct ath11k_buffer_addr *buf_addr_info;
1165        struct rx_mpdu_desc *rx_mpdu_desc_info_details;
1166
1167        rx_mpdu_desc_info_details =
1168                        (struct rx_mpdu_desc *)&reo_ent_ring->rx_mpdu_info;
1169
1170        *msdu_cnt = FIELD_GET(RX_MPDU_DESC_INFO0_MSDU_COUNT,
1171                              rx_mpdu_desc_info_details->info0);
1172
1173        buf_addr_info = (struct ath11k_buffer_addr *)&reo_ent_ring->buf_addr_info;
1174
1175        *paddr = (((u64)FIELD_GET(BUFFER_ADDR_INFO1_ADDR,
1176                                  buf_addr_info->info1)) << 32) |
1177                        FIELD_GET(BUFFER_ADDR_INFO0_ADDR,
1178                                  buf_addr_info->info0);
1179
1180        *sw_cookie = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
1181                               buf_addr_info->info1);
1182        *rbm = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
1183                         buf_addr_info->info1);
1184
1185        *pp_buf_addr = (void *)buf_addr_info;
1186}
1187