1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* Marvell RVU Admin Function driver |
3 | * |
4 | * Copyright (C) 2022 Marvell. |
5 | * |
6 | */ |
7 | |
8 | #ifndef __RVU_NPC_HASH_H |
9 | #define __RVU_NPC_HASH_H |
10 | |
11 | #define RVU_NPC_HASH_SECRET_KEY0 0xa9d5af4c9fbc76b1 |
12 | #define RVU_NPC_HASH_SECRET_KEY1 0xa9d5af4c9fbc87b4 |
13 | #define RVU_NPC_HASH_SECRET_KEY2 0x5954c9e7 |
14 | |
15 | #define NPC_MAX_HASH 2 |
16 | #define NPC_MAX_HASH_MASK 2 |
17 | |
18 | #define KEX_LD_CFG_USE_HASH(use_hash, bytesm1, hdr_ofs, ena, flags_ena, key_ofs) \ |
19 | ((use_hash) << 20 | ((bytesm1) << 16) | ((hdr_ofs) << 8) | \ |
20 | ((ena) << 7) | ((flags_ena) << 6) | ((key_ofs) & 0x3F)) |
21 | #define KEX_LD_CFG_HASH(hdr_ofs, bytesm1, lt_en, lid_en, lid, ltype_match, ltype_mask) \ |
22 | (((hdr_ofs) << 32) | ((bytesm1) << 16) | \ |
23 | ((lt_en) << 12) | ((lid_en) << 11) | ((lid) << 8) | \ |
24 | ((ltype_match) << 4) | ((ltype_mask) & 0xF)) |
25 | |
26 | #define SET_KEX_LD_HASH(intf, ld, cfg) \ |
27 | rvu_write64(rvu, blkaddr, \ |
28 | NPC_AF_INTFX_HASHX_CFG(intf, ld), cfg) |
29 | |
30 | #define SET_KEX_LD_HASH_MASK(intf, ld, mask_idx, cfg) \ |
31 | rvu_write64(rvu, blkaddr, \ |
32 | NPC_AF_INTFX_HASHX_MASKX(intf, ld, mask_idx), cfg) |
33 | |
34 | #define GET_KEX_LD_HASH_CTRL(intf, ld) \ |
35 | rvu_read64(rvu, blkaddr, NPC_AF_INTFX_HASHX_RESULT_CTRL(intf, ld)) |
36 | |
37 | #define GET_KEX_LD_HASH_MASK(intf, ld, mask_idx) \ |
38 | rvu_read64(rvu, blkaddr, NPC_AF_INTFX_HASHX_MASKX(intf, ld, mask_idx)) |
39 | |
40 | #define SET_KEX_LD_HASH_CTRL(intf, ld, cfg) \ |
41 | rvu_write64(rvu, blkaddr, \ |
42 | NPC_AF_INTFX_HASHX_RESULT_CTRL(intf, ld), cfg) |
43 | |
44 | struct npc_mcam_kex_hash { |
45 | /* NPC_AF_INTF(0..1)_LID(0..7)_LT(0..15)_LD(0..1)_CFG */ |
46 | bool lid_lt_ld_hash_en[NPC_MAX_INTF][NPC_MAX_LID][NPC_MAX_LT][NPC_MAX_LD]; |
47 | /* NPC_AF_INTF(0..1)_HASH(0..1)_CFG */ |
48 | u64 hash[NPC_MAX_INTF][NPC_MAX_HASH]; |
49 | /* NPC_AF_INTF(0..1)_HASH(0..1)_MASK(0..1) */ |
50 | u64 hash_mask[NPC_MAX_INTF][NPC_MAX_HASH][NPC_MAX_HASH_MASK]; |
51 | /* NPC_AF_INTF(0..1)_HASH(0..1)_RESULT_CTRL */ |
52 | u64 hash_ctrl[NPC_MAX_INTF][NPC_MAX_HASH]; |
53 | } __packed; |
54 | |
55 | void npc_update_field_hash(struct rvu *rvu, u8 intf, |
56 | struct mcam_entry *entry, |
57 | int blkaddr, |
58 | u64 features, |
59 | struct flow_msg *pkt, |
60 | struct flow_msg *mask, |
61 | struct flow_msg *opkt, |
62 | struct flow_msg *omask); |
63 | void npc_config_secret_key(struct rvu *rvu, int blkaddr); |
64 | void npc_program_mkex_hash(struct rvu *rvu, int blkaddr); |
65 | u32 npc_field_hash_calc(u64 *ldata, struct npc_get_field_hash_info_rsp rsp, |
66 | u8 intf, u8 hash_idx); |
67 | |
68 | static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = { |
69 | .lid_lt_ld_hash_en = { |
70 | [NIX_INTF_RX] = { |
71 | [NPC_LID_LC] = { |
72 | [NPC_LT_LC_IP6] = { |
73 | false, |
74 | false, |
75 | }, |
76 | }, |
77 | }, |
78 | |
79 | [NIX_INTF_TX] = { |
80 | [NPC_LID_LC] = { |
81 | [NPC_LT_LC_IP6] = { |
82 | false, |
83 | false, |
84 | }, |
85 | }, |
86 | }, |
87 | }, |
88 | |
89 | .hash = { |
90 | [NIX_INTF_RX] = { |
91 | KEX_LD_CFG_HASH(0x8ULL, 0xf, 0x1, 0x1, NPC_LID_LC, NPC_LT_LC_IP6, 0xf), |
92 | KEX_LD_CFG_HASH(0x18ULL, 0xf, 0x1, 0x1, NPC_LID_LC, NPC_LT_LC_IP6, 0xf), |
93 | }, |
94 | |
95 | [NIX_INTF_TX] = { |
96 | KEX_LD_CFG_HASH(0x8ULL, 0xf, 0x1, 0x1, NPC_LID_LC, NPC_LT_LC_IP6, 0xf), |
97 | KEX_LD_CFG_HASH(0x18ULL, 0xf, 0x1, 0x1, NPC_LID_LC, NPC_LT_LC_IP6, 0xf), |
98 | }, |
99 | }, |
100 | |
101 | .hash_mask = { |
102 | [NIX_INTF_RX] = { |
103 | [0] = { |
104 | GENMASK_ULL(63, 0), |
105 | GENMASK_ULL(63, 0), |
106 | }, |
107 | [1] = { |
108 | GENMASK_ULL(63, 0), |
109 | GENMASK_ULL(63, 0), |
110 | }, |
111 | }, |
112 | |
113 | [NIX_INTF_TX] = { |
114 | [0] = { |
115 | GENMASK_ULL(63, 0), |
116 | GENMASK_ULL(63, 0), |
117 | }, |
118 | [1] = { |
119 | GENMASK_ULL(63, 0), |
120 | GENMASK_ULL(63, 0), |
121 | }, |
122 | }, |
123 | }, |
124 | |
125 | .hash_ctrl = { |
126 | [NIX_INTF_RX] = { |
127 | [0] = GENMASK_ULL(63, 32), /* MSB 32 bit is mask and LSB 32 bit is offset. */ |
128 | [1] = GENMASK_ULL(63, 32), /* MSB 32 bit is mask and LSB 32 bit is offset. */ |
129 | }, |
130 | |
131 | [NIX_INTF_TX] = { |
132 | [0] = GENMASK_ULL(63, 32), /* MSB 32 bit is mask and LSB 32 bit is offset. */ |
133 | [1] = GENMASK_ULL(63, 32), /* MSB 32 bit is mask and LSB 32 bit is offset. */ |
134 | }, |
135 | }, |
136 | }; |
137 | |
138 | /* If exact match table support is enabled, enable drop rules */ |
139 | #define NPC_MCAM_DROP_RULE_MAX 30 |
140 | #define NPC_MCAM_SDP_DROP_RULE_IDX 0 |
141 | |
142 | #define RVU_PFFUNC(pf, func) \ |
143 | ((((pf) & RVU_PFVF_PF_MASK) << RVU_PFVF_PF_SHIFT) | \ |
144 | (((func) & RVU_PFVF_FUNC_MASK) << RVU_PFVF_FUNC_SHIFT)) |
145 | |
146 | enum npc_exact_opc_type { |
147 | NPC_EXACT_OPC_MEM, |
148 | NPC_EXACT_OPC_CAM, |
149 | }; |
150 | |
151 | struct npc_exact_table_entry { |
152 | struct list_head list; |
153 | struct list_head glist; |
154 | u32 seq_id; /* Sequence number of entry */ |
155 | u32 index; /* Mem table or cam table index */ |
156 | u32 mcam_idx; |
157 | /* Mcam index. This is valid only if "cmd" field is false */ |
158 | enum npc_exact_opc_type opc_type; |
159 | u16 chan; |
160 | u16 pcifunc; |
161 | u8 ways; |
162 | u8 mac[ETH_ALEN]; |
163 | u8 ctype; |
164 | u8 cgx_id; |
165 | u8 lmac_id; |
166 | bool cmd; /* Is added by ethtool command ? */ |
167 | }; |
168 | |
169 | struct npc_exact_table { |
170 | struct mutex lock; /* entries update lock */ |
171 | unsigned long *id_bmap; |
172 | int num_drop_rules; |
173 | u32 tot_ids; |
174 | u16 cnt_cmd_rules[NPC_MCAM_DROP_RULE_MAX]; |
175 | u16 counter_idx[NPC_MCAM_DROP_RULE_MAX]; |
176 | bool promisc_mode[NPC_MCAM_DROP_RULE_MAX]; |
177 | struct { |
178 | int ways; |
179 | int depth; |
180 | unsigned long *bmap; |
181 | u64 mask; // Masks before hash calculation. |
182 | u16 hash_mask; // 11 bits for hash mask |
183 | u16 hash_offset; // 11 bits offset |
184 | } mem_table; |
185 | |
186 | struct { |
187 | int depth; |
188 | unsigned long *bmap; |
189 | } cam_table; |
190 | |
191 | struct { |
192 | bool valid; |
193 | u16 chan_val; |
194 | u16 chan_mask; |
195 | u16 pcifunc; |
196 | u8 drop_rule_idx; |
197 | } drop_rule_map[NPC_MCAM_DROP_RULE_MAX]; |
198 | |
199 | #define NPC_EXACT_TBL_MAX_WAYS 4 |
200 | |
201 | struct list_head lhead_mem_tbl_entry[NPC_EXACT_TBL_MAX_WAYS]; |
202 | int mem_tbl_entry_cnt; |
203 | |
204 | struct list_head lhead_cam_tbl_entry; |
205 | int cam_tbl_entry_cnt; |
206 | |
207 | struct list_head lhead_gbl; |
208 | }; |
209 | |
210 | bool rvu_npc_exact_has_match_table(struct rvu *rvu); |
211 | u32 rvu_npc_exact_get_max_entries(struct rvu *rvu); |
212 | int rvu_npc_exact_init(struct rvu *rvu); |
213 | int rvu_npc_exact_mac_addr_reset(struct rvu *rvu, struct cgx_mac_addr_reset_req *req, |
214 | struct msg_rsp *rsp); |
215 | |
216 | int rvu_npc_exact_mac_addr_update(struct rvu *rvu, |
217 | struct cgx_mac_addr_update_req *req, |
218 | struct cgx_mac_addr_update_rsp *rsp); |
219 | |
220 | int rvu_npc_exact_mac_addr_add(struct rvu *rvu, |
221 | struct cgx_mac_addr_add_req *req, |
222 | struct cgx_mac_addr_add_rsp *rsp); |
223 | |
224 | int rvu_npc_exact_mac_addr_del(struct rvu *rvu, |
225 | struct cgx_mac_addr_del_req *req, |
226 | struct msg_rsp *rsp); |
227 | |
228 | int rvu_npc_exact_mac_addr_set(struct rvu *rvu, struct cgx_mac_addr_set_or_get *req, |
229 | struct cgx_mac_addr_set_or_get *rsp); |
230 | |
231 | void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc); |
232 | |
233 | bool rvu_npc_exact_can_disable_feature(struct rvu *rvu); |
234 | void rvu_npc_exact_disable_feature(struct rvu *rvu); |
235 | void rvu_npc_exact_reset(struct rvu *rvu, u16 pcifunc); |
236 | u16 rvu_npc_exact_drop_rule_to_pcifunc(struct rvu *rvu, u32 drop_rule_idx); |
237 | int rvu_npc_exact_promisc_disable(struct rvu *rvu, u16 pcifunc); |
238 | int rvu_npc_exact_promisc_enable(struct rvu *rvu, u16 pcifunc); |
239 | #endif /* RVU_NPC_HASH_H */ |
240 | |