1
2
3
4
5#include "ice_common.h"
6
7
8
9
10
11
12static enum ice_status
13ice_pkg_get_supported_vlan_mode(struct ice_hw *hw, bool *dvm)
14{
15 u16 meta_init_size = sizeof(struct ice_meta_init_section);
16 struct ice_meta_init_section *sect;
17 struct ice_buf_build *bld;
18 enum ice_status status;
19
20
21 *dvm = false;
22
23 bld = ice_pkg_buf_alloc_single_section(hw,
24 ICE_SID_RXPARSER_METADATA_INIT,
25 meta_init_size, (void **)§);
26 if (!bld)
27 return ICE_ERR_NO_MEMORY;
28
29
30 sect->count = CPU_TO_LE16(1);
31 sect->offset = CPU_TO_LE16(ICE_META_VLAN_MODE_ENTRY);
32
33 status = ice_aq_upload_section(hw,
34 (struct ice_buf_hdr *)ice_pkg_buf(bld),
35 ICE_PKG_BUF_SIZE, NULL);
36 if (!status) {
37 ice_declare_bitmap(entry, ICE_META_INIT_BITS);
38 u32 arr[ICE_META_INIT_DW_CNT];
39 u16 i;
40
41
42 for (i = 0; i < ICE_META_INIT_DW_CNT; i++)
43 arr[i] = LE32_TO_CPU(sect->entry[0].bm[i]);
44
45 ice_bitmap_from_array32(entry, arr, (u16)ICE_META_INIT_BITS);
46
47
48 *dvm = ice_is_bit_set(entry, ICE_META_VLAN_MODE_BIT);
49 }
50
51 ice_pkg_buf_free(hw, bld);
52
53 return status;
54}
55
56
57
58
59
60
61
62
63static enum ice_status
64ice_aq_get_vlan_mode(struct ice_hw *hw,
65 struct ice_aqc_get_vlan_mode *get_params)
66{
67 struct ice_aq_desc desc;
68
69 if (!get_params)
70 return ICE_ERR_PARAM;
71
72 ice_fill_dflt_direct_cmd_desc(&desc,
73 ice_aqc_opc_get_vlan_mode_parameters);
74
75 return ice_aq_send_cmd(hw, &desc, get_params, sizeof(*get_params),
76 NULL);
77}
78
79
80
81
82
83
84
85
86
87
88
89
90static bool ice_aq_is_dvm_ena(struct ice_hw *hw)
91{
92 struct ice_aqc_get_vlan_mode get_params = { 0 };
93 enum ice_status status;
94
95 status = ice_aq_get_vlan_mode(hw, &get_params);
96 if (status) {
97 ice_debug(hw, ICE_DBG_AQ, "Failed to get VLAN mode, status %d\n",
98 status);
99 return false;
100 }
101
102 return (get_params.vlan_mode & ICE_AQ_VLAN_MODE_DVM_ENA);
103}
104
105
106
107
108
109
110
111
112
113
114bool ice_is_dvm_ena(struct ice_hw *hw)
115{
116 return hw->dvm_ena;
117}
118
119
120
121
122
123
124
125
126
127static void ice_cache_vlan_mode(struct ice_hw *hw)
128{
129 hw->dvm_ena = ice_aq_is_dvm_ena(hw) ? true : false;
130}
131
132
133
134
135
136static bool ice_pkg_supports_dvm(struct ice_hw *hw)
137{
138 enum ice_status status;
139 bool pkg_supports_dvm;
140
141 status = ice_pkg_get_supported_vlan_mode(hw, &pkg_supports_dvm);
142 if (status) {
143 ice_debug(hw, ICE_DBG_PKG, "Failed to get supported VLAN mode, status %d\n",
144 status);
145 return false;
146 }
147
148 return pkg_supports_dvm;
149}
150
151
152
153
154
155static bool ice_fw_supports_dvm(struct ice_hw *hw)
156{
157 struct ice_aqc_get_vlan_mode get_vlan_mode = { 0 };
158 enum ice_status status;
159
160
161
162
163 status = ice_aq_get_vlan_mode(hw, &get_vlan_mode);
164 if (status) {
165 ice_debug(hw, ICE_DBG_NVM, "Failed to get VLAN mode, status %d\n",
166 status);
167 return false;
168 }
169
170 return true;
171}
172
173
174
175
176
177
178
179
180
181
182
183static bool ice_is_dvm_supported(struct ice_hw *hw)
184{
185 if (!ice_pkg_supports_dvm(hw)) {
186 ice_debug(hw, ICE_DBG_PKG, "DDP doesn't support DVM\n");
187 return false;
188 }
189
190 if (!ice_fw_supports_dvm(hw)) {
191 ice_debug(hw, ICE_DBG_PKG, "FW doesn't support DVM\n");
192 return false;
193 }
194
195 return true;
196}
197
198#define ICE_EXTERNAL_VLAN_ID_FV_IDX 11
199#define ICE_SW_LKUP_VLAN_LOC_LKUP_IDX 1
200#define ICE_SW_LKUP_VLAN_PKT_FLAGS_LKUP_IDX 2
201#define ICE_SW_LKUP_PROMISC_VLAN_LOC_LKUP_IDX 2
202#define ICE_PKT_FLAGS_0_TO_15_FV_IDX 1
203#define ICE_PKT_FLAGS_0_TO_15_VLAN_FLAGS_MASK 0xD000
204static struct ice_update_recipe_lkup_idx_params ice_dvm_dflt_recipes[] = {
205 {
206
207
208
209 .rid = ICE_SW_LKUP_VLAN,
210 .fv_idx = ICE_EXTERNAL_VLAN_ID_FV_IDX,
211 .ignore_valid = true,
212 .mask = 0,
213 .mask_valid = false,
214 .lkup_idx = ICE_SW_LKUP_VLAN_LOC_LKUP_IDX,
215 },
216 {
217
218
219
220
221 .rid = ICE_SW_LKUP_VLAN,
222 .fv_idx = ICE_PKT_FLAGS_0_TO_15_FV_IDX,
223 .ignore_valid = false,
224 .mask = ICE_PKT_FLAGS_0_TO_15_VLAN_FLAGS_MASK,
225 .mask_valid = true,
226 .lkup_idx = ICE_SW_LKUP_VLAN_PKT_FLAGS_LKUP_IDX,
227 },
228 {
229
230
231
232 .rid = ICE_SW_LKUP_PROMISC_VLAN,
233 .fv_idx = ICE_EXTERNAL_VLAN_ID_FV_IDX,
234 .ignore_valid = true,
235 .mask = 0,
236 .mask_valid = false,
237 .lkup_idx = ICE_SW_LKUP_PROMISC_VLAN_LOC_LKUP_IDX,
238 },
239};
240
241
242
243
244
245static enum ice_status ice_dvm_update_dflt_recipes(struct ice_hw *hw)
246{
247 unsigned long i;
248
249 for (i = 0; i < ARRAY_SIZE(ice_dvm_dflt_recipes); i++) {
250 struct ice_update_recipe_lkup_idx_params *params;
251 enum ice_status status;
252
253 params = &ice_dvm_dflt_recipes[i];
254
255 status = ice_update_recipe_lkup_idx(hw, params);
256 if (status) {
257 ice_debug(hw, ICE_DBG_INIT, "Failed to update RID %d lkup_idx %d fv_idx %d mask_valid %s mask 0x%04x\n",
258 params->rid, params->lkup_idx, params->fv_idx,
259 params->mask_valid ? "true" : "false",
260 params->mask);
261 return status;
262 }
263 }
264
265 return ICE_SUCCESS;
266}
267
268
269
270
271
272
273
274
275static enum ice_status
276ice_aq_set_vlan_mode(struct ice_hw *hw,
277 struct ice_aqc_set_vlan_mode *set_params)
278{
279 u8 rdma_packet, mng_vlan_prot_id;
280 struct ice_aq_desc desc;
281
282 if (!set_params)
283 return ICE_ERR_PARAM;
284
285 if (set_params->l2tag_prio_tagging > ICE_AQ_VLAN_PRIO_TAG_MAX)
286 return ICE_ERR_PARAM;
287
288 rdma_packet = set_params->rdma_packet;
289 if (rdma_packet != ICE_AQ_SVM_VLAN_RDMA_PKT_FLAG_SETTING &&
290 rdma_packet != ICE_AQ_DVM_VLAN_RDMA_PKT_FLAG_SETTING)
291 return ICE_ERR_PARAM;
292
293 mng_vlan_prot_id = set_params->mng_vlan_prot_id;
294 if (mng_vlan_prot_id != ICE_AQ_VLAN_MNG_PROTOCOL_ID_OUTER &&
295 mng_vlan_prot_id != ICE_AQ_VLAN_MNG_PROTOCOL_ID_INNER)
296 return ICE_ERR_PARAM;
297
298 ice_fill_dflt_direct_cmd_desc(&desc,
299 ice_aqc_opc_set_vlan_mode_parameters);
300 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
301
302 return ice_aq_send_cmd(hw, &desc, set_params, sizeof(*set_params),
303 NULL);
304}
305
306
307
308
309
310static enum ice_status ice_set_dvm(struct ice_hw *hw)
311{
312 struct ice_aqc_set_vlan_mode params = { 0 };
313 enum ice_status status;
314
315 params.l2tag_prio_tagging = ICE_AQ_VLAN_PRIO_TAG_OUTER_CTAG;
316 params.rdma_packet = ICE_AQ_DVM_VLAN_RDMA_PKT_FLAG_SETTING;
317 params.mng_vlan_prot_id = ICE_AQ_VLAN_MNG_PROTOCOL_ID_OUTER;
318
319 status = ice_aq_set_vlan_mode(hw, ¶ms);
320 if (status) {
321 ice_debug(hw, ICE_DBG_INIT, "Failed to set double VLAN mode parameters, status %d\n",
322 status);
323 return status;
324 }
325
326 status = ice_dvm_update_dflt_recipes(hw);
327 if (status) {
328 ice_debug(hw, ICE_DBG_INIT, "Failed to update default recipes for double VLAN mode, status %d\n",
329 status);
330 return status;
331 }
332
333 status = ice_aq_set_port_params(hw->port_info, 0, false, false, true,
334 NULL);
335 if (status) {
336 ice_debug(hw, ICE_DBG_INIT, "Failed to set port in double VLAN mode, status %d\n",
337 status);
338 return status;
339 }
340
341 status = ice_set_dvm_boost_entries(hw);
342 if (status) {
343 ice_debug(hw, ICE_DBG_INIT, "Failed to set boost TCAM entries for double VLAN mode, status %d\n",
344 status);
345 return status;
346 }
347
348 return ICE_SUCCESS;
349}
350
351
352
353
354
355static enum ice_status ice_set_svm(struct ice_hw *hw)
356{
357 struct ice_aqc_set_vlan_mode *set_params;
358 enum ice_status status;
359
360 status = ice_aq_set_port_params(hw->port_info, 0, false, false, false, NULL);
361 if (status) {
362 ice_debug(hw, ICE_DBG_INIT, "Failed to set port parameters for single VLAN mode\n");
363 return status;
364 }
365
366 set_params = (struct ice_aqc_set_vlan_mode *)
367 ice_malloc(hw, sizeof(*set_params));
368 if (!set_params)
369 return ICE_ERR_NO_MEMORY;
370
371
372 set_params->l2tag_prio_tagging = ICE_AQ_VLAN_PRIO_TAG_INNER_CTAG;
373 set_params->rdma_packet = ICE_AQ_SVM_VLAN_RDMA_PKT_FLAG_SETTING;
374 set_params->mng_vlan_prot_id = ICE_AQ_VLAN_MNG_PROTOCOL_ID_INNER;
375
376 status = ice_aq_set_vlan_mode(hw, set_params);
377 if (status)
378 ice_debug(hw, ICE_DBG_INIT, "Failed to configure port in single VLAN mode\n");
379
380 ice_free(hw, set_params);
381 return status;
382}
383
384
385
386
387
388enum ice_status ice_set_vlan_mode(struct ice_hw *hw)
389{
390
391
392
393 if (hw->dcf_enabled)
394 return ICE_SUCCESS;
395
396 if (!ice_is_dvm_supported(hw))
397 return ICE_SUCCESS;
398
399 if (!ice_set_dvm(hw))
400 return ICE_SUCCESS;
401
402 return ice_set_svm(hw);
403}
404
405
406
407
408
409
410
411
412
413static void ice_print_dvm_not_supported(struct ice_hw *hw)
414{
415 bool pkg_supports_dvm = ice_pkg_supports_dvm(hw);
416 bool fw_supports_dvm = ice_fw_supports_dvm(hw);
417
418 if (!fw_supports_dvm && !pkg_supports_dvm)
419 ice_info(hw, "QinQ functionality cannot be enabled on this device. "
420 "Update your DDP package and NVM to versions that support QinQ.\n");
421 else if (!pkg_supports_dvm)
422 ice_info(hw, "QinQ functionality cannot be enabled on this device. "
423 "Update your DDP package to a version that supports QinQ.\n");
424 else if (!fw_supports_dvm)
425 ice_info(hw, "QinQ functionality cannot be enabled on this device. "
426 "Update your NVM to a version that supports QinQ.\n");
427}
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442void ice_post_pkg_dwnld_vlan_mode_cfg(struct ice_hw *hw)
443{
444 ice_cache_vlan_mode(hw);
445
446 if (ice_is_dvm_ena(hw))
447 ice_change_proto_id_to_dvm();
448 else
449 ice_print_dvm_not_supported(hw);
450}
451