1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 5 */ 6 7 #include "hal_desc.h" 8 #include "hal.h" 9 #include "hal_tx.h" 10 #include "hif.h" 11 12 #define DSCP_TID_MAP_TBL_ENTRY_SIZE 64 13 14 /* dscp_tid_map - Default DSCP-TID mapping 15 * 16 * DSCP TID 17 * 000000 0 18 * 001000 1 19 * 010000 2 20 * 011000 3 21 * 100000 4 22 * 101000 5 23 * 110000 6 24 * 111000 7 25 */ 26 static const u8 dscp_tid_map[DSCP_TID_MAP_TBL_ENTRY_SIZE] = { 27 0, 0, 0, 0, 0, 0, 0, 0, 28 1, 1, 1, 1, 1, 1, 1, 1, 29 2, 2, 2, 2, 2, 2, 2, 2, 30 3, 3, 3, 3, 3, 3, 3, 3, 31 4, 4, 4, 4, 4, 4, 4, 4, 32 5, 5, 5, 5, 5, 5, 5, 5, 33 6, 6, 6, 6, 6, 6, 6, 6, 34 7, 7, 7, 7, 7, 7, 7, 7, 35 }; 36 37 void ath11k_hal_tx_cmd_desc_setup(struct ath11k_base *ab, void *cmd, 38 struct hal_tx_info *ti) 39 { 40 struct hal_tcl_data_cmd *tcl_cmd = (struct hal_tcl_data_cmd *)cmd; 41 42 tcl_cmd->buf_addr_info.info0 = 43 FIELD_PREP(BUFFER_ADDR_INFO0_ADDR, ti->paddr); 44 tcl_cmd->buf_addr_info.info1 = 45 FIELD_PREP(BUFFER_ADDR_INFO1_ADDR, 46 ((uint64_t)ti->paddr >> HAL_ADDR_MSB_REG_SHIFT)); 47 tcl_cmd->buf_addr_info.info1 |= 48 FIELD_PREP(BUFFER_ADDR_INFO1_RET_BUF_MGR, ti->rbm_id) | 49 FIELD_PREP(BUFFER_ADDR_INFO1_SW_COOKIE, ti->desc_id); 50 51 tcl_cmd->info0 = 52 FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_DESC_TYPE, ti->type) | 53 FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ENCAP_TYPE, ti->encap_type) | 54 FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ENCRYPT_TYPE, 55 ti->encrypt_type) | 56 FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_SEARCH_TYPE, 57 ti->search_type) | 58 FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_ADDR_EN, 59 ti->addr_search_flags) | 60 FIELD_PREP(HAL_TCL_DATA_CMD_INFO0_CMD_NUM, 61 ti->meta_data_flags); 62 63 tcl_cmd->info1 = ti->flags0 | 64 FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_DATA_LEN, ti->data_len) | 65 FIELD_PREP(HAL_TCL_DATA_CMD_INFO1_PKT_OFFSET, ti->pkt_offset); 66 67 tcl_cmd->info2 = ti->flags1 | 68 FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_TID, ti->tid) | 69 FIELD_PREP(HAL_TCL_DATA_CMD_INFO2_LMAC_ID, ti->lmac_id); 70 71 tcl_cmd->info3 = FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_DSCP_TID_TABLE_IDX, 72 ti->dscp_tid_tbl_idx) | 73 FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_SEARCH_INDEX, 74 ti->bss_ast_idx) | 75 FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_CACHE_SET_NUM, 76 ti->bss_ast_hash); 77 tcl_cmd->info4 = 0; 78 79 if (ti->enable_mesh) 80 ab->hw_params.hw_ops->tx_mesh_enable(ab, tcl_cmd); 81 } 82 83 void ath11k_hal_tx_set_dscp_tid_map(struct ath11k_base *ab, int id) 84 { 85 u32 ctrl_reg_val; 86 u32 addr; 87 u8 hw_map_val[HAL_DSCP_TID_TBL_SIZE]; 88 int i; 89 u32 value; 90 int cnt = 0; 91 92 ctrl_reg_val = ath11k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + 93 HAL_TCL1_RING_CMN_CTRL_REG); 94 /* Enable read/write access */ 95 ctrl_reg_val |= HAL_TCL1_RING_CMN_CTRL_DSCP_TID_MAP_PROG_EN; 96 ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + 97 HAL_TCL1_RING_CMN_CTRL_REG, ctrl_reg_val); 98 99 addr = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_DSCP_TID_MAP + 100 (4 * id * (HAL_DSCP_TID_TBL_SIZE / 4)); 101 102 /* Configure each DSCP-TID mapping in three bits there by configure 103 * three bytes in an iteration. 104 */ 105 for (i = 0; i < DSCP_TID_MAP_TBL_ENTRY_SIZE; i += 8) { 106 value = FIELD_PREP(HAL_TCL1_RING_FIELD_DSCP_TID_MAP0, 107 dscp_tid_map[i]) | 108 FIELD_PREP(HAL_TCL1_RING_FIELD_DSCP_TID_MAP1, 109 dscp_tid_map[i + 1]) | 110 FIELD_PREP(HAL_TCL1_RING_FIELD_DSCP_TID_MAP2, 111 dscp_tid_map[i + 2]) | 112 FIELD_PREP(HAL_TCL1_RING_FIELD_DSCP_TID_MAP3, 113 dscp_tid_map[i + 3]) | 114 FIELD_PREP(HAL_TCL1_RING_FIELD_DSCP_TID_MAP4, 115 dscp_tid_map[i + 4]) | 116 FIELD_PREP(HAL_TCL1_RING_FIELD_DSCP_TID_MAP5, 117 dscp_tid_map[i + 5]) | 118 FIELD_PREP(HAL_TCL1_RING_FIELD_DSCP_TID_MAP6, 119 dscp_tid_map[i + 6]) | 120 FIELD_PREP(HAL_TCL1_RING_FIELD_DSCP_TID_MAP7, 121 dscp_tid_map[i + 7]); 122 memcpy(&hw_map_val[cnt], (u8 *)&value, 3); 123 cnt += 3; 124 } 125 126 for (i = 0; i < HAL_DSCP_TID_TBL_SIZE; i += 4) { 127 ath11k_hif_write32(ab, addr, *(u32 *)&hw_map_val[i]); 128 addr += 4; 129 } 130 131 /* Disable read/write access */ 132 ctrl_reg_val = ath11k_hif_read32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + 133 HAL_TCL1_RING_CMN_CTRL_REG); 134 ctrl_reg_val &= ~HAL_TCL1_RING_CMN_CTRL_DSCP_TID_MAP_PROG_EN; 135 ath11k_hif_write32(ab, HAL_SEQ_WCSS_UMAC_TCL_REG + 136 HAL_TCL1_RING_CMN_CTRL_REG, 137 ctrl_reg_val); 138 } 139 140 void ath11k_hal_tx_init_data_ring(struct ath11k_base *ab, struct hal_srng *srng) 141 { 142 struct hal_srng_params params; 143 struct hal_tlv_hdr *tlv; 144 int i, entry_size; 145 u8 *desc; 146 147 memset(¶ms, 0, sizeof(params)); 148 149 entry_size = ath11k_hal_srng_get_entrysize(ab, HAL_TCL_DATA); 150 ath11k_hal_srng_get_params(ab, srng, ¶ms); 151 desc = (u8 *)params.ring_base_vaddr; 152 153 for (i = 0; i < params.num_entries; i++) { 154 tlv = (struct hal_tlv_hdr *)desc; 155 tlv->tl = FIELD_PREP(HAL_TLV_HDR_TAG, HAL_TCL_DATA_CMD) | 156 FIELD_PREP(HAL_TLV_HDR_LEN, 157 sizeof(struct hal_tcl_data_cmd)); 158 desc += entry_size; 159 } 160 } 161