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