1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2001-2021 Intel Corporation 3 */ 4 5 #include "ice_common.h" 6 7 /** 8 * ice_pkg_get_supported_vlan_mode - chk if DDP supports Double VLAN mode (DVM) 9 * @hw: pointer to the HW struct 10 * @dvm: output variable to determine if DDP supports DVM(true) or SVM(false) 11 */ 12 static enum ice_status 13 ice_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 /* if anything fails, we assume there is no DVM support */ 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 /* only need to read a single section */ 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 /* convert to host bitmap format */ 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 /* check if DVM is supported */ 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 * ice_aq_get_vlan_mode - get the VLAN mode of the device 58 * @hw: pointer to the HW structure 59 * @get_params: structure FW fills in based on the current VLAN mode config 60 * 61 * Get VLAN Mode Parameters (0x020D) 62 */ 63 static enum ice_status 64 ice_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 * ice_aq_is_dvm_ena - query FW to check if double VLAN mode is enabled 81 * @hw: pointer to the HW structure 82 * 83 * Returns true if the hardware/firmware is configured in double VLAN mode, 84 * else return false signaling that the hardware/firmware is configured in 85 * single VLAN mode. 86 * 87 * Also, return false if this call fails for any reason (i.e. firmware doesn't 88 * support this AQ call). 89 */ 90 static 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 * ice_is_dvm_ena - check if double VLAN mode is enabled 107 * @hw: pointer to the HW structure 108 * 109 * The device is configured in single or double VLAN mode on initialization and 110 * this cannot be dynamically changed during runtime. Based on this there is no 111 * need to make an AQ call every time the driver needs to know the VLAN mode. 112 * Instead, use the cached VLAN mode. 113 */ 114 bool ice_is_dvm_ena(struct ice_hw *hw) 115 { 116 return hw->dvm_ena; 117 } 118 119 /** 120 * ice_cache_vlan_mode - cache VLAN mode after DDP is downloaded 121 * @hw: pointer to the HW structure 122 * 123 * This is only called after downloading the DDP and after the global 124 * configuration lock has been released because all ports on a device need to 125 * cache the VLAN mode. 126 */ 127 static 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 * ice_pkg_supports_dvm - find out if DDP supports DVM 134 * @hw: pointer to the HW structure 135 */ 136 static 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 * ice_fw_supports_dvm - find out if FW supports DVM 153 * @hw: pointer to the HW structure 154 */ 155 static 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 /* If firmware returns success, then it supports DVM, else it only 161 * supports SVM 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 * ice_is_dvm_supported - check if Double VLAN Mode is supported 175 * @hw: pointer to the hardware structure 176 * 177 * Returns true if Double VLAN Mode (DVM) is supported and false if only Single 178 * VLAN Mode (SVM) is supported. In order for DVM to be supported the DDP and 179 * firmware must support it, otherwise only SVM is supported. This function 180 * should only be called while the global config lock is held and after the 181 * package has been successfully downloaded. 182 */ 183 static 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 204 static struct ice_update_recipe_lkup_idx_params ice_dvm_dflt_recipes[] = { 205 { 206 /* Update recipe ICE_SW_LKUP_VLAN to filter based on the 207 * outer/single VLAN in DVM 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, /* use pre-existing mask */ 214 .lkup_idx = ICE_SW_LKUP_VLAN_LOC_LKUP_IDX, 215 }, 216 { 217 /* Update recipe ICE_SW_LKUP_VLAN to filter based on the VLAN 218 * packet flags to support VLAN filtering on multiple VLAN 219 * ethertypes (i.e. 0x8100 and 0x88a8) in DVM 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 /* Update recipe ICE_SW_LKUP_PROMISC_VLAN to filter based on the 230 * outer/single VLAN in DVM 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, /* use pre-existing mask */ 237 .lkup_idx = ICE_SW_LKUP_PROMISC_VLAN_LOC_LKUP_IDX, 238 }, 239 }; 240 241 /** 242 * ice_dvm_update_dflt_recipes - update default switch recipes in DVM 243 * @hw: hardware structure used to update the recipes 244 */ 245 static 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 * ice_aq_set_vlan_mode - set the VLAN mode of the device 270 * @hw: pointer to the HW structure 271 * @set_params: requested VLAN mode configuration 272 * 273 * Set VLAN Mode Parameters (0x020C) 274 */ 275 static enum ice_status 276 ice_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 * ice_set_dvm - sets up software and hardware for double VLAN mode 308 * @hw: pointer to the hardware structure 309 */ 310 static 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 * ice_set_svm - set single VLAN mode 353 * @hw: pointer to the HW structure 354 */ 355 static 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 /* default configuration for SVM configurations */ 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 * ice_set_vlan_mode 386 * @hw: pointer to the HW structure 387 */ 388 enum ice_status ice_set_vlan_mode(struct ice_hw *hw) 389 { 390 /* DCF only has the ability to query the VLAN mode. Setting the VLAN 391 * mode is done by the PF. 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 * ice_print_dvm_not_supported - print if DDP and/or FW doesn't support DVM 407 * @hw: pointer to the HW structure 408 * 409 * The purpose of this function is to print that QinQ is not supported due to 410 * incompatibilty from the DDP and/or FW. This will give a hint to the user to 411 * update one and/or both components if they expect QinQ functionality. 412 */ 413 static 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 * ice_post_pkg_dwnld_vlan_mode_cfg - configure VLAN mode after DDP download 431 * @hw: pointer to the HW structure 432 * 433 * This function is meant to configure any VLAN mode specific functionality 434 * after the global configuration lock has been released and the DDP has been 435 * downloaded. 436 * 437 * Since only one PF downloads the DDP and configures the VLAN mode there needs 438 * to be a way to configure the other PFs after the DDP has been downloaded and 439 * the global configuration lock has been released. All such code should go in 440 * this function. 441 */ 442 void 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