1 /******************************************************************************* 2 * 3 * Intel Ethernet Controller XL710 Family Linux Driver 4 * Copyright(c) 2013 - 2014 Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 * The full GNU General Public License is included in this distribution in 19 * the file called "COPYING". 20 * 21 * Contact Information: 22 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> 23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 24 * 25 ******************************************************************************/ 26 27 #include "i40e_osdep.h" 28 #include "i40e_register.h" 29 #include "i40e_type.h" 30 #include "i40e_hmc.h" 31 #include "i40e_lan_hmc.h" 32 #include "i40e_prototype.h" 33 34 /* lan specific interface functions */ 35 36 /** 37 * i40e_align_l2obj_base - aligns base object pointer to 512 bytes 38 * @offset: base address offset needing alignment 39 * 40 * Aligns the layer 2 function private memory so it's 512-byte aligned. 41 **/ 42 static u64 i40e_align_l2obj_base(u64 offset) 43 { 44 u64 aligned_offset = offset; 45 46 if ((offset % I40E_HMC_L2OBJ_BASE_ALIGNMENT) > 0) 47 aligned_offset += (I40E_HMC_L2OBJ_BASE_ALIGNMENT - 48 (offset % I40E_HMC_L2OBJ_BASE_ALIGNMENT)); 49 50 return aligned_offset; 51 } 52 53 /** 54 * i40e_calculate_l2fpm_size - calculates layer 2 FPM memory size 55 * @txq_num: number of Tx queues needing backing context 56 * @rxq_num: number of Rx queues needing backing context 57 * @fcoe_cntx_num: amount of FCoE statefull contexts needing backing context 58 * @fcoe_filt_num: number of FCoE filters needing backing context 59 * 60 * Calculates the maximum amount of memory for the function required, based 61 * on the number of resources it must provide context for. 62 **/ 63 static u64 i40e_calculate_l2fpm_size(u32 txq_num, u32 rxq_num, 64 u32 fcoe_cntx_num, u32 fcoe_filt_num) 65 { 66 u64 fpm_size = 0; 67 68 fpm_size = txq_num * I40E_HMC_OBJ_SIZE_TXQ; 69 fpm_size = i40e_align_l2obj_base(fpm_size); 70 71 fpm_size += (rxq_num * I40E_HMC_OBJ_SIZE_RXQ); 72 fpm_size = i40e_align_l2obj_base(fpm_size); 73 74 fpm_size += (fcoe_cntx_num * I40E_HMC_OBJ_SIZE_FCOE_CNTX); 75 fpm_size = i40e_align_l2obj_base(fpm_size); 76 77 fpm_size += (fcoe_filt_num * I40E_HMC_OBJ_SIZE_FCOE_FILT); 78 fpm_size = i40e_align_l2obj_base(fpm_size); 79 80 return fpm_size; 81 } 82 83 /** 84 * i40e_init_lan_hmc - initialize i40e_hmc_info struct 85 * @hw: pointer to the HW structure 86 * @txq_num: number of Tx queues needing backing context 87 * @rxq_num: number of Rx queues needing backing context 88 * @fcoe_cntx_num: amount of FCoE statefull contexts needing backing context 89 * @fcoe_filt_num: number of FCoE filters needing backing context 90 * 91 * This function will be called once per physical function initialization. 92 * It will fill out the i40e_hmc_obj_info structure for LAN objects based on 93 * the driver's provided input, as well as information from the HMC itself 94 * loaded from NVRAM. 95 * 96 * Assumptions: 97 * - HMC Resource Profile has been selected before calling this function. 98 **/ 99 i40e_status i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num, 100 u32 rxq_num, u32 fcoe_cntx_num, 101 u32 fcoe_filt_num) 102 { 103 struct i40e_hmc_obj_info *obj, *full_obj; 104 i40e_status ret_code = 0; 105 u64 l2fpm_size; 106 u32 size_exp; 107 108 hw->hmc.signature = I40E_HMC_INFO_SIGNATURE; 109 hw->hmc.hmc_fn_id = hw->pf_id; 110 111 /* allocate memory for hmc_obj */ 112 ret_code = i40e_allocate_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem, 113 sizeof(struct i40e_hmc_obj_info) * I40E_HMC_LAN_MAX); 114 if (ret_code) 115 goto init_lan_hmc_out; 116 hw->hmc.hmc_obj = (struct i40e_hmc_obj_info *) 117 hw->hmc.hmc_obj_virt_mem.va; 118 119 /* The full object will be used to create the LAN HMC SD */ 120 full_obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_FULL]; 121 full_obj->max_cnt = 0; 122 full_obj->cnt = 0; 123 full_obj->base = 0; 124 full_obj->size = 0; 125 126 /* Tx queue context information */ 127 obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX]; 128 obj->max_cnt = rd32(hw, I40E_GLHMC_LANQMAX); 129 obj->cnt = txq_num; 130 obj->base = 0; 131 size_exp = rd32(hw, I40E_GLHMC_LANTXOBJSZ); 132 obj->size = BIT_ULL(size_exp); 133 134 /* validate values requested by driver don't exceed HMC capacity */ 135 if (txq_num > obj->max_cnt) { 136 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT; 137 hw_dbg(hw, "i40e_init_lan_hmc: Tx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n", 138 txq_num, obj->max_cnt, ret_code); 139 goto init_lan_hmc_out; 140 } 141 142 /* aggregate values into the full LAN object for later */ 143 full_obj->max_cnt += obj->max_cnt; 144 full_obj->cnt += obj->cnt; 145 146 /* Rx queue context information */ 147 obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX]; 148 obj->max_cnt = rd32(hw, I40E_GLHMC_LANQMAX); 149 obj->cnt = rxq_num; 150 obj->base = hw->hmc.hmc_obj[I40E_HMC_LAN_TX].base + 151 (hw->hmc.hmc_obj[I40E_HMC_LAN_TX].cnt * 152 hw->hmc.hmc_obj[I40E_HMC_LAN_TX].size); 153 obj->base = i40e_align_l2obj_base(obj->base); 154 size_exp = rd32(hw, I40E_GLHMC_LANRXOBJSZ); 155 obj->size = BIT_ULL(size_exp); 156 157 /* validate values requested by driver don't exceed HMC capacity */ 158 if (rxq_num > obj->max_cnt) { 159 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT; 160 hw_dbg(hw, "i40e_init_lan_hmc: Rx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n", 161 rxq_num, obj->max_cnt, ret_code); 162 goto init_lan_hmc_out; 163 } 164 165 /* aggregate values into the full LAN object for later */ 166 full_obj->max_cnt += obj->max_cnt; 167 full_obj->cnt += obj->cnt; 168 169 /* FCoE context information */ 170 obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX]; 171 obj->max_cnt = rd32(hw, I40E_GLHMC_FCOEMAX); 172 obj->cnt = fcoe_cntx_num; 173 obj->base = hw->hmc.hmc_obj[I40E_HMC_LAN_RX].base + 174 (hw->hmc.hmc_obj[I40E_HMC_LAN_RX].cnt * 175 hw->hmc.hmc_obj[I40E_HMC_LAN_RX].size); 176 obj->base = i40e_align_l2obj_base(obj->base); 177 size_exp = rd32(hw, I40E_GLHMC_FCOEDDPOBJSZ); 178 obj->size = BIT_ULL(size_exp); 179 180 /* validate values requested by driver don't exceed HMC capacity */ 181 if (fcoe_cntx_num > obj->max_cnt) { 182 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT; 183 hw_dbg(hw, "i40e_init_lan_hmc: FCoE context: asks for 0x%x but max allowed is 0x%x, returns error %d\n", 184 fcoe_cntx_num, obj->max_cnt, ret_code); 185 goto init_lan_hmc_out; 186 } 187 188 /* aggregate values into the full LAN object for later */ 189 full_obj->max_cnt += obj->max_cnt; 190 full_obj->cnt += obj->cnt; 191 192 /* FCoE filter information */ 193 obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT]; 194 obj->max_cnt = rd32(hw, I40E_GLHMC_FCOEFMAX); 195 obj->cnt = fcoe_filt_num; 196 obj->base = hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].base + 197 (hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].cnt * 198 hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].size); 199 obj->base = i40e_align_l2obj_base(obj->base); 200 size_exp = rd32(hw, I40E_GLHMC_FCOEFOBJSZ); 201 obj->size = BIT_ULL(size_exp); 202 203 /* validate values requested by driver don't exceed HMC capacity */ 204 if (fcoe_filt_num > obj->max_cnt) { 205 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT; 206 hw_dbg(hw, "i40e_init_lan_hmc: FCoE filter: asks for 0x%x but max allowed is 0x%x, returns error %d\n", 207 fcoe_filt_num, obj->max_cnt, ret_code); 208 goto init_lan_hmc_out; 209 } 210 211 /* aggregate values into the full LAN object for later */ 212 full_obj->max_cnt += obj->max_cnt; 213 full_obj->cnt += obj->cnt; 214 215 hw->hmc.first_sd_index = 0; 216 hw->hmc.sd_table.ref_cnt = 0; 217 l2fpm_size = i40e_calculate_l2fpm_size(txq_num, rxq_num, fcoe_cntx_num, 218 fcoe_filt_num); 219 if (NULL == hw->hmc.sd_table.sd_entry) { 220 hw->hmc.sd_table.sd_cnt = (u32) 221 (l2fpm_size + I40E_HMC_DIRECT_BP_SIZE - 1) / 222 I40E_HMC_DIRECT_BP_SIZE; 223 224 /* allocate the sd_entry members in the sd_table */ 225 ret_code = i40e_allocate_virt_mem(hw, &hw->hmc.sd_table.addr, 226 (sizeof(struct i40e_hmc_sd_entry) * 227 hw->hmc.sd_table.sd_cnt)); 228 if (ret_code) 229 goto init_lan_hmc_out; 230 hw->hmc.sd_table.sd_entry = 231 (struct i40e_hmc_sd_entry *)hw->hmc.sd_table.addr.va; 232 } 233 /* store in the LAN full object for later */ 234 full_obj->size = l2fpm_size; 235 236 init_lan_hmc_out: 237 return ret_code; 238 } 239 240 /** 241 * i40e_remove_pd_page - Remove a page from the page descriptor table 242 * @hw: pointer to the HW structure 243 * @hmc_info: pointer to the HMC configuration information structure 244 * @idx: segment descriptor index to find the relevant page descriptor 245 * 246 * This function: 247 * 1. Marks the entry in pd table (for paged address mode) invalid 248 * 2. write to register PMPDINV to invalidate the backing page in FV cache 249 * 3. Decrement the ref count for pd_entry 250 * assumptions: 251 * 1. caller can deallocate the memory used by pd after this function 252 * returns. 253 **/ 254 static i40e_status i40e_remove_pd_page(struct i40e_hw *hw, 255 struct i40e_hmc_info *hmc_info, 256 u32 idx) 257 { 258 i40e_status ret_code = 0; 259 260 if (!i40e_prep_remove_pd_page(hmc_info, idx)) 261 ret_code = i40e_remove_pd_page_new(hw, hmc_info, idx, true); 262 263 return ret_code; 264 } 265 266 /** 267 * i40e_remove_sd_bp - remove a backing page from a segment descriptor 268 * @hw: pointer to our HW structure 269 * @hmc_info: pointer to the HMC configuration information structure 270 * @idx: the page index 271 * 272 * This function: 273 * 1. Marks the entry in sd table (for direct address mode) invalid 274 * 2. write to register PMSDCMD, PMSDDATALOW(PMSDDATALOW.PMSDVALID set 275 * to 0) and PMSDDATAHIGH to invalidate the sd page 276 * 3. Decrement the ref count for the sd_entry 277 * assumptions: 278 * 1. caller can deallocate the memory used by backing storage after this 279 * function returns. 280 **/ 281 static i40e_status i40e_remove_sd_bp(struct i40e_hw *hw, 282 struct i40e_hmc_info *hmc_info, 283 u32 idx) 284 { 285 i40e_status ret_code = 0; 286 287 if (!i40e_prep_remove_sd_bp(hmc_info, idx)) 288 ret_code = i40e_remove_sd_bp_new(hw, hmc_info, idx, true); 289 290 return ret_code; 291 } 292 293 /** 294 * i40e_create_lan_hmc_object - allocate backing store for hmc objects 295 * @hw: pointer to the HW structure 296 * @info: pointer to i40e_hmc_create_obj_info struct 297 * 298 * This will allocate memory for PDs and backing pages and populate 299 * the sd and pd entries. 300 **/ 301 static i40e_status i40e_create_lan_hmc_object(struct i40e_hw *hw, 302 struct i40e_hmc_lan_create_obj_info *info) 303 { 304 i40e_status ret_code = 0; 305 struct i40e_hmc_sd_entry *sd_entry; 306 u32 pd_idx1 = 0, pd_lmt1 = 0; 307 u32 pd_idx = 0, pd_lmt = 0; 308 bool pd_error = false; 309 u32 sd_idx, sd_lmt; 310 u64 sd_size; 311 u32 i, j; 312 313 if (NULL == info) { 314 ret_code = I40E_ERR_BAD_PTR; 315 hw_dbg(hw, "i40e_create_lan_hmc_object: bad info ptr\n"); 316 goto exit; 317 } 318 if (NULL == info->hmc_info) { 319 ret_code = I40E_ERR_BAD_PTR; 320 hw_dbg(hw, "i40e_create_lan_hmc_object: bad hmc_info ptr\n"); 321 goto exit; 322 } 323 if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) { 324 ret_code = I40E_ERR_BAD_PTR; 325 hw_dbg(hw, "i40e_create_lan_hmc_object: bad signature\n"); 326 goto exit; 327 } 328 329 if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) { 330 ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX; 331 hw_dbg(hw, "i40e_create_lan_hmc_object: returns error %d\n", 332 ret_code); 333 goto exit; 334 } 335 if ((info->start_idx + info->count) > 336 info->hmc_info->hmc_obj[info->rsrc_type].cnt) { 337 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT; 338 hw_dbg(hw, "i40e_create_lan_hmc_object: returns error %d\n", 339 ret_code); 340 goto exit; 341 } 342 343 /* find sd index and limit */ 344 I40E_FIND_SD_INDEX_LIMIT(info->hmc_info, info->rsrc_type, 345 info->start_idx, info->count, 346 &sd_idx, &sd_lmt); 347 if (sd_idx >= info->hmc_info->sd_table.sd_cnt || 348 sd_lmt > info->hmc_info->sd_table.sd_cnt) { 349 ret_code = I40E_ERR_INVALID_SD_INDEX; 350 goto exit; 351 } 352 /* find pd index */ 353 I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type, 354 info->start_idx, info->count, &pd_idx, 355 &pd_lmt); 356 357 /* This is to cover for cases where you may not want to have an SD with 358 * the full 2M memory but something smaller. By not filling out any 359 * size, the function will default the SD size to be 2M. 360 */ 361 if (info->direct_mode_sz == 0) 362 sd_size = I40E_HMC_DIRECT_BP_SIZE; 363 else 364 sd_size = info->direct_mode_sz; 365 366 /* check if all the sds are valid. If not, allocate a page and 367 * initialize it. 368 */ 369 for (j = sd_idx; j < sd_lmt; j++) { 370 /* update the sd table entry */ 371 ret_code = i40e_add_sd_table_entry(hw, info->hmc_info, j, 372 info->entry_type, 373 sd_size); 374 if (ret_code) 375 goto exit_sd_error; 376 sd_entry = &info->hmc_info->sd_table.sd_entry[j]; 377 if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) { 378 /* check if all the pds in this sd are valid. If not, 379 * allocate a page and initialize it. 380 */ 381 382 /* find pd_idx and pd_lmt in this sd */ 383 pd_idx1 = max(pd_idx, (j * I40E_HMC_MAX_BP_COUNT)); 384 pd_lmt1 = min(pd_lmt, 385 ((j + 1) * I40E_HMC_MAX_BP_COUNT)); 386 for (i = pd_idx1; i < pd_lmt1; i++) { 387 /* update the pd table entry */ 388 ret_code = i40e_add_pd_table_entry(hw, 389 info->hmc_info, 390 i, NULL); 391 if (ret_code) { 392 pd_error = true; 393 break; 394 } 395 } 396 if (pd_error) { 397 /* remove the backing pages from pd_idx1 to i */ 398 while (i && (i > pd_idx1)) { 399 i40e_remove_pd_bp(hw, info->hmc_info, 400 (i - 1)); 401 i--; 402 } 403 } 404 } 405 if (!sd_entry->valid) { 406 sd_entry->valid = true; 407 switch (sd_entry->entry_type) { 408 case I40E_SD_TYPE_PAGED: 409 I40E_SET_PF_SD_ENTRY(hw, 410 sd_entry->u.pd_table.pd_page_addr.pa, 411 j, sd_entry->entry_type); 412 break; 413 case I40E_SD_TYPE_DIRECT: 414 I40E_SET_PF_SD_ENTRY(hw, sd_entry->u.bp.addr.pa, 415 j, sd_entry->entry_type); 416 break; 417 default: 418 ret_code = I40E_ERR_INVALID_SD_TYPE; 419 goto exit; 420 } 421 } 422 } 423 goto exit; 424 425 exit_sd_error: 426 /* cleanup for sd entries from j to sd_idx */ 427 while (j && (j > sd_idx)) { 428 sd_entry = &info->hmc_info->sd_table.sd_entry[j - 1]; 429 switch (sd_entry->entry_type) { 430 case I40E_SD_TYPE_PAGED: 431 pd_idx1 = max(pd_idx, 432 ((j - 1) * I40E_HMC_MAX_BP_COUNT)); 433 pd_lmt1 = min(pd_lmt, (j * I40E_HMC_MAX_BP_COUNT)); 434 for (i = pd_idx1; i < pd_lmt1; i++) 435 i40e_remove_pd_bp(hw, info->hmc_info, i); 436 i40e_remove_pd_page(hw, info->hmc_info, (j - 1)); 437 break; 438 case I40E_SD_TYPE_DIRECT: 439 i40e_remove_sd_bp(hw, info->hmc_info, (j - 1)); 440 break; 441 default: 442 ret_code = I40E_ERR_INVALID_SD_TYPE; 443 break; 444 } 445 j--; 446 } 447 exit: 448 return ret_code; 449 } 450 451 /** 452 * i40e_configure_lan_hmc - prepare the HMC backing store 453 * @hw: pointer to the hw structure 454 * @model: the model for the layout of the SD/PD tables 455 * 456 * - This function will be called once per physical function initialization. 457 * - This function will be called after i40e_init_lan_hmc() and before 458 * any LAN/FCoE HMC objects can be created. 459 **/ 460 i40e_status i40e_configure_lan_hmc(struct i40e_hw *hw, 461 enum i40e_hmc_model model) 462 { 463 struct i40e_hmc_lan_create_obj_info info; 464 i40e_status ret_code = 0; 465 u8 hmc_fn_id = hw->hmc.hmc_fn_id; 466 struct i40e_hmc_obj_info *obj; 467 468 /* Initialize part of the create object info struct */ 469 info.hmc_info = &hw->hmc; 470 info.rsrc_type = I40E_HMC_LAN_FULL; 471 info.start_idx = 0; 472 info.direct_mode_sz = hw->hmc.hmc_obj[I40E_HMC_LAN_FULL].size; 473 474 /* Build the SD entry for the LAN objects */ 475 switch (model) { 476 case I40E_HMC_MODEL_DIRECT_PREFERRED: 477 case I40E_HMC_MODEL_DIRECT_ONLY: 478 info.entry_type = I40E_SD_TYPE_DIRECT; 479 /* Make one big object, a single SD */ 480 info.count = 1; 481 ret_code = i40e_create_lan_hmc_object(hw, &info); 482 if (ret_code && (model == I40E_HMC_MODEL_DIRECT_PREFERRED)) 483 goto try_type_paged; 484 else if (ret_code) 485 goto configure_lan_hmc_out; 486 /* else clause falls through the break */ 487 break; 488 case I40E_HMC_MODEL_PAGED_ONLY: 489 try_type_paged: 490 info.entry_type = I40E_SD_TYPE_PAGED; 491 /* Make one big object in the PD table */ 492 info.count = 1; 493 ret_code = i40e_create_lan_hmc_object(hw, &info); 494 if (ret_code) 495 goto configure_lan_hmc_out; 496 break; 497 default: 498 /* unsupported type */ 499 ret_code = I40E_ERR_INVALID_SD_TYPE; 500 hw_dbg(hw, "i40e_configure_lan_hmc: Unknown SD type: %d\n", 501 ret_code); 502 goto configure_lan_hmc_out; 503 } 504 505 /* Configure and program the FPM registers so objects can be created */ 506 507 /* Tx contexts */ 508 obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX]; 509 wr32(hw, I40E_GLHMC_LANTXBASE(hmc_fn_id), 510 (u32)((obj->base & I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK) / 512)); 511 wr32(hw, I40E_GLHMC_LANTXCNT(hmc_fn_id), obj->cnt); 512 513 /* Rx contexts */ 514 obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX]; 515 wr32(hw, I40E_GLHMC_LANRXBASE(hmc_fn_id), 516 (u32)((obj->base & I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK) / 512)); 517 wr32(hw, I40E_GLHMC_LANRXCNT(hmc_fn_id), obj->cnt); 518 519 /* FCoE contexts */ 520 obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX]; 521 wr32(hw, I40E_GLHMC_FCOEDDPBASE(hmc_fn_id), 522 (u32)((obj->base & I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK) / 512)); 523 wr32(hw, I40E_GLHMC_FCOEDDPCNT(hmc_fn_id), obj->cnt); 524 525 /* FCoE filters */ 526 obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT]; 527 wr32(hw, I40E_GLHMC_FCOEFBASE(hmc_fn_id), 528 (u32)((obj->base & I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK) / 512)); 529 wr32(hw, I40E_GLHMC_FCOEFCNT(hmc_fn_id), obj->cnt); 530 531 configure_lan_hmc_out: 532 return ret_code; 533 } 534 535 /** 536 * i40e_delete_hmc_object - remove hmc objects 537 * @hw: pointer to the HW structure 538 * @info: pointer to i40e_hmc_delete_obj_info struct 539 * 540 * This will de-populate the SDs and PDs. It frees 541 * the memory for PDS and backing storage. After this function is returned, 542 * caller should deallocate memory allocated previously for 543 * book-keeping information about PDs and backing storage. 544 **/ 545 static i40e_status i40e_delete_lan_hmc_object(struct i40e_hw *hw, 546 struct i40e_hmc_lan_delete_obj_info *info) 547 { 548 i40e_status ret_code = 0; 549 struct i40e_hmc_pd_table *pd_table; 550 u32 pd_idx, pd_lmt, rel_pd_idx; 551 u32 sd_idx, sd_lmt; 552 u32 i, j; 553 554 if (NULL == info) { 555 ret_code = I40E_ERR_BAD_PTR; 556 hw_dbg(hw, "i40e_delete_hmc_object: bad info ptr\n"); 557 goto exit; 558 } 559 if (NULL == info->hmc_info) { 560 ret_code = I40E_ERR_BAD_PTR; 561 hw_dbg(hw, "i40e_delete_hmc_object: bad info->hmc_info ptr\n"); 562 goto exit; 563 } 564 if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) { 565 ret_code = I40E_ERR_BAD_PTR; 566 hw_dbg(hw, "i40e_delete_hmc_object: bad hmc_info->signature\n"); 567 goto exit; 568 } 569 570 if (NULL == info->hmc_info->sd_table.sd_entry) { 571 ret_code = I40E_ERR_BAD_PTR; 572 hw_dbg(hw, "i40e_delete_hmc_object: bad sd_entry\n"); 573 goto exit; 574 } 575 576 if (NULL == info->hmc_info->hmc_obj) { 577 ret_code = I40E_ERR_BAD_PTR; 578 hw_dbg(hw, "i40e_delete_hmc_object: bad hmc_info->hmc_obj\n"); 579 goto exit; 580 } 581 if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) { 582 ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX; 583 hw_dbg(hw, "i40e_delete_hmc_object: returns error %d\n", 584 ret_code); 585 goto exit; 586 } 587 588 if ((info->start_idx + info->count) > 589 info->hmc_info->hmc_obj[info->rsrc_type].cnt) { 590 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT; 591 hw_dbg(hw, "i40e_delete_hmc_object: returns error %d\n", 592 ret_code); 593 goto exit; 594 } 595 596 I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type, 597 info->start_idx, info->count, &pd_idx, 598 &pd_lmt); 599 600 for (j = pd_idx; j < pd_lmt; j++) { 601 sd_idx = j / I40E_HMC_PD_CNT_IN_SD; 602 603 if (I40E_SD_TYPE_PAGED != 604 info->hmc_info->sd_table.sd_entry[sd_idx].entry_type) 605 continue; 606 607 rel_pd_idx = j % I40E_HMC_PD_CNT_IN_SD; 608 609 pd_table = 610 &info->hmc_info->sd_table.sd_entry[sd_idx].u.pd_table; 611 if (pd_table->pd_entry[rel_pd_idx].valid) { 612 ret_code = i40e_remove_pd_bp(hw, info->hmc_info, j); 613 if (ret_code) 614 goto exit; 615 } 616 } 617 618 /* find sd index and limit */ 619 I40E_FIND_SD_INDEX_LIMIT(info->hmc_info, info->rsrc_type, 620 info->start_idx, info->count, 621 &sd_idx, &sd_lmt); 622 if (sd_idx >= info->hmc_info->sd_table.sd_cnt || 623 sd_lmt > info->hmc_info->sd_table.sd_cnt) { 624 ret_code = I40E_ERR_INVALID_SD_INDEX; 625 goto exit; 626 } 627 628 for (i = sd_idx; i < sd_lmt; i++) { 629 if (!info->hmc_info->sd_table.sd_entry[i].valid) 630 continue; 631 switch (info->hmc_info->sd_table.sd_entry[i].entry_type) { 632 case I40E_SD_TYPE_DIRECT: 633 ret_code = i40e_remove_sd_bp(hw, info->hmc_info, i); 634 if (ret_code) 635 goto exit; 636 break; 637 case I40E_SD_TYPE_PAGED: 638 ret_code = i40e_remove_pd_page(hw, info->hmc_info, i); 639 if (ret_code) 640 goto exit; 641 break; 642 default: 643 break; 644 } 645 } 646 exit: 647 return ret_code; 648 } 649 650 /** 651 * i40e_shutdown_lan_hmc - Remove HMC backing store, free allocated memory 652 * @hw: pointer to the hw structure 653 * 654 * This must be called by drivers as they are shutting down and being 655 * removed from the OS. 656 **/ 657 i40e_status i40e_shutdown_lan_hmc(struct i40e_hw *hw) 658 { 659 struct i40e_hmc_lan_delete_obj_info info; 660 i40e_status ret_code; 661 662 info.hmc_info = &hw->hmc; 663 info.rsrc_type = I40E_HMC_LAN_FULL; 664 info.start_idx = 0; 665 info.count = 1; 666 667 /* delete the object */ 668 ret_code = i40e_delete_lan_hmc_object(hw, &info); 669 670 /* free the SD table entry for LAN */ 671 i40e_free_virt_mem(hw, &hw->hmc.sd_table.addr); 672 hw->hmc.sd_table.sd_cnt = 0; 673 hw->hmc.sd_table.sd_entry = NULL; 674 675 /* free memory used for hmc_obj */ 676 i40e_free_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem); 677 hw->hmc.hmc_obj = NULL; 678 679 return ret_code; 680 } 681 682 #define I40E_HMC_STORE(_struct, _ele) \ 683 offsetof(struct _struct, _ele), \ 684 FIELD_SIZEOF(struct _struct, _ele) 685 686 struct i40e_context_ele { 687 u16 offset; 688 u16 size_of; 689 u16 width; 690 u16 lsb; 691 }; 692 693 /* LAN Tx Queue Context */ 694 static struct i40e_context_ele i40e_hmc_txq_ce_info[] = { 695 /* Field Width LSB */ 696 {I40E_HMC_STORE(i40e_hmc_obj_txq, head), 13, 0 }, 697 {I40E_HMC_STORE(i40e_hmc_obj_txq, new_context), 1, 30 }, 698 {I40E_HMC_STORE(i40e_hmc_obj_txq, base), 57, 32 }, 699 {I40E_HMC_STORE(i40e_hmc_obj_txq, fc_ena), 1, 89 }, 700 {I40E_HMC_STORE(i40e_hmc_obj_txq, timesync_ena), 1, 90 }, 701 {I40E_HMC_STORE(i40e_hmc_obj_txq, fd_ena), 1, 91 }, 702 {I40E_HMC_STORE(i40e_hmc_obj_txq, alt_vlan_ena), 1, 92 }, 703 {I40E_HMC_STORE(i40e_hmc_obj_txq, cpuid), 8, 96 }, 704 /* line 1 */ 705 {I40E_HMC_STORE(i40e_hmc_obj_txq, thead_wb), 13, 0 + 128 }, 706 {I40E_HMC_STORE(i40e_hmc_obj_txq, head_wb_ena), 1, 32 + 128 }, 707 {I40E_HMC_STORE(i40e_hmc_obj_txq, qlen), 13, 33 + 128 }, 708 {I40E_HMC_STORE(i40e_hmc_obj_txq, tphrdesc_ena), 1, 46 + 128 }, 709 {I40E_HMC_STORE(i40e_hmc_obj_txq, tphrpacket_ena), 1, 47 + 128 }, 710 {I40E_HMC_STORE(i40e_hmc_obj_txq, tphwdesc_ena), 1, 48 + 128 }, 711 {I40E_HMC_STORE(i40e_hmc_obj_txq, head_wb_addr), 64, 64 + 128 }, 712 /* line 7 */ 713 {I40E_HMC_STORE(i40e_hmc_obj_txq, crc), 32, 0 + (7 * 128) }, 714 {I40E_HMC_STORE(i40e_hmc_obj_txq, rdylist), 10, 84 + (7 * 128) }, 715 {I40E_HMC_STORE(i40e_hmc_obj_txq, rdylist_act), 1, 94 + (7 * 128) }, 716 { 0 } 717 }; 718 719 /* LAN Rx Queue Context */ 720 static struct i40e_context_ele i40e_hmc_rxq_ce_info[] = { 721 /* Field Width LSB */ 722 { I40E_HMC_STORE(i40e_hmc_obj_rxq, head), 13, 0 }, 723 { I40E_HMC_STORE(i40e_hmc_obj_rxq, cpuid), 8, 13 }, 724 { I40E_HMC_STORE(i40e_hmc_obj_rxq, base), 57, 32 }, 725 { I40E_HMC_STORE(i40e_hmc_obj_rxq, qlen), 13, 89 }, 726 { I40E_HMC_STORE(i40e_hmc_obj_rxq, dbuff), 7, 102 }, 727 { I40E_HMC_STORE(i40e_hmc_obj_rxq, hbuff), 5, 109 }, 728 { I40E_HMC_STORE(i40e_hmc_obj_rxq, dtype), 2, 114 }, 729 { I40E_HMC_STORE(i40e_hmc_obj_rxq, dsize), 1, 116 }, 730 { I40E_HMC_STORE(i40e_hmc_obj_rxq, crcstrip), 1, 117 }, 731 { I40E_HMC_STORE(i40e_hmc_obj_rxq, fc_ena), 1, 118 }, 732 { I40E_HMC_STORE(i40e_hmc_obj_rxq, l2tsel), 1, 119 }, 733 { I40E_HMC_STORE(i40e_hmc_obj_rxq, hsplit_0), 4, 120 }, 734 { I40E_HMC_STORE(i40e_hmc_obj_rxq, hsplit_1), 2, 124 }, 735 { I40E_HMC_STORE(i40e_hmc_obj_rxq, showiv), 1, 127 }, 736 { I40E_HMC_STORE(i40e_hmc_obj_rxq, rxmax), 14, 174 }, 737 { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphrdesc_ena), 1, 193 }, 738 { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphwdesc_ena), 1, 194 }, 739 { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena), 1, 195 }, 740 { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena), 1, 196 }, 741 { I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh), 3, 198 }, 742 { I40E_HMC_STORE(i40e_hmc_obj_rxq, prefena), 1, 201 }, 743 { 0 } 744 }; 745 746 /** 747 * i40e_write_byte - replace HMC context byte 748 * @hmc_bits: pointer to the HMC memory 749 * @ce_info: a description of the struct to be read from 750 * @src: the struct to be read from 751 **/ 752 static void i40e_write_byte(u8 *hmc_bits, 753 struct i40e_context_ele *ce_info, 754 u8 *src) 755 { 756 u8 src_byte, dest_byte, mask; 757 u8 *from, *dest; 758 u16 shift_width; 759 760 /* copy from the next struct field */ 761 from = src + ce_info->offset; 762 763 /* prepare the bits and mask */ 764 shift_width = ce_info->lsb % 8; 765 mask = (u8)(BIT(ce_info->width) - 1); 766 767 src_byte = *from; 768 src_byte &= mask; 769 770 /* shift to correct alignment */ 771 mask <<= shift_width; 772 src_byte <<= shift_width; 773 774 /* get the current bits from the target bit string */ 775 dest = hmc_bits + (ce_info->lsb / 8); 776 777 memcpy(&dest_byte, dest, sizeof(dest_byte)); 778 779 dest_byte &= ~mask; /* get the bits not changing */ 780 dest_byte |= src_byte; /* add in the new bits */ 781 782 /* put it all back */ 783 memcpy(dest, &dest_byte, sizeof(dest_byte)); 784 } 785 786 /** 787 * i40e_write_word - replace HMC context word 788 * @hmc_bits: pointer to the HMC memory 789 * @ce_info: a description of the struct to be read from 790 * @src: the struct to be read from 791 **/ 792 static void i40e_write_word(u8 *hmc_bits, 793 struct i40e_context_ele *ce_info, 794 u8 *src) 795 { 796 u16 src_word, mask; 797 u8 *from, *dest; 798 u16 shift_width; 799 __le16 dest_word; 800 801 /* copy from the next struct field */ 802 from = src + ce_info->offset; 803 804 /* prepare the bits and mask */ 805 shift_width = ce_info->lsb % 8; 806 mask = BIT(ce_info->width) - 1; 807 808 /* don't swizzle the bits until after the mask because the mask bits 809 * will be in a different bit position on big endian machines 810 */ 811 src_word = *(u16 *)from; 812 src_word &= mask; 813 814 /* shift to correct alignment */ 815 mask <<= shift_width; 816 src_word <<= shift_width; 817 818 /* get the current bits from the target bit string */ 819 dest = hmc_bits + (ce_info->lsb / 8); 820 821 memcpy(&dest_word, dest, sizeof(dest_word)); 822 823 dest_word &= ~(cpu_to_le16(mask)); /* get the bits not changing */ 824 dest_word |= cpu_to_le16(src_word); /* add in the new bits */ 825 826 /* put it all back */ 827 memcpy(dest, &dest_word, sizeof(dest_word)); 828 } 829 830 /** 831 * i40e_write_dword - replace HMC context dword 832 * @hmc_bits: pointer to the HMC memory 833 * @ce_info: a description of the struct to be read from 834 * @src: the struct to be read from 835 **/ 836 static void i40e_write_dword(u8 *hmc_bits, 837 struct i40e_context_ele *ce_info, 838 u8 *src) 839 { 840 u32 src_dword, mask; 841 u8 *from, *dest; 842 u16 shift_width; 843 __le32 dest_dword; 844 845 /* copy from the next struct field */ 846 from = src + ce_info->offset; 847 848 /* prepare the bits and mask */ 849 shift_width = ce_info->lsb % 8; 850 851 /* if the field width is exactly 32 on an x86 machine, then the shift 852 * operation will not work because the SHL instructions count is masked 853 * to 5 bits so the shift will do nothing 854 */ 855 if (ce_info->width < 32) 856 mask = BIT(ce_info->width) - 1; 857 else 858 mask = ~(u32)0; 859 860 /* don't swizzle the bits until after the mask because the mask bits 861 * will be in a different bit position on big endian machines 862 */ 863 src_dword = *(u32 *)from; 864 src_dword &= mask; 865 866 /* shift to correct alignment */ 867 mask <<= shift_width; 868 src_dword <<= shift_width; 869 870 /* get the current bits from the target bit string */ 871 dest = hmc_bits + (ce_info->lsb / 8); 872 873 memcpy(&dest_dword, dest, sizeof(dest_dword)); 874 875 dest_dword &= ~(cpu_to_le32(mask)); /* get the bits not changing */ 876 dest_dword |= cpu_to_le32(src_dword); /* add in the new bits */ 877 878 /* put it all back */ 879 memcpy(dest, &dest_dword, sizeof(dest_dword)); 880 } 881 882 /** 883 * i40e_write_qword - replace HMC context qword 884 * @hmc_bits: pointer to the HMC memory 885 * @ce_info: a description of the struct to be read from 886 * @src: the struct to be read from 887 **/ 888 static void i40e_write_qword(u8 *hmc_bits, 889 struct i40e_context_ele *ce_info, 890 u8 *src) 891 { 892 u64 src_qword, mask; 893 u8 *from, *dest; 894 u16 shift_width; 895 __le64 dest_qword; 896 897 /* copy from the next struct field */ 898 from = src + ce_info->offset; 899 900 /* prepare the bits and mask */ 901 shift_width = ce_info->lsb % 8; 902 903 /* if the field width is exactly 64 on an x86 machine, then the shift 904 * operation will not work because the SHL instructions count is masked 905 * to 6 bits so the shift will do nothing 906 */ 907 if (ce_info->width < 64) 908 mask = BIT_ULL(ce_info->width) - 1; 909 else 910 mask = ~(u64)0; 911 912 /* don't swizzle the bits until after the mask because the mask bits 913 * will be in a different bit position on big endian machines 914 */ 915 src_qword = *(u64 *)from; 916 src_qword &= mask; 917 918 /* shift to correct alignment */ 919 mask <<= shift_width; 920 src_qword <<= shift_width; 921 922 /* get the current bits from the target bit string */ 923 dest = hmc_bits + (ce_info->lsb / 8); 924 925 memcpy(&dest_qword, dest, sizeof(dest_qword)); 926 927 dest_qword &= ~(cpu_to_le64(mask)); /* get the bits not changing */ 928 dest_qword |= cpu_to_le64(src_qword); /* add in the new bits */ 929 930 /* put it all back */ 931 memcpy(dest, &dest_qword, sizeof(dest_qword)); 932 } 933 934 /** 935 * i40e_clear_hmc_context - zero out the HMC context bits 936 * @hw: the hardware struct 937 * @context_bytes: pointer to the context bit array (DMA memory) 938 * @hmc_type: the type of HMC resource 939 **/ 940 static i40e_status i40e_clear_hmc_context(struct i40e_hw *hw, 941 u8 *context_bytes, 942 enum i40e_hmc_lan_rsrc_type hmc_type) 943 { 944 /* clean the bit array */ 945 memset(context_bytes, 0, (u32)hw->hmc.hmc_obj[hmc_type].size); 946 947 return 0; 948 } 949 950 /** 951 * i40e_set_hmc_context - replace HMC context bits 952 * @context_bytes: pointer to the context bit array 953 * @ce_info: a description of the struct to be filled 954 * @dest: the struct to be filled 955 **/ 956 static i40e_status i40e_set_hmc_context(u8 *context_bytes, 957 struct i40e_context_ele *ce_info, 958 u8 *dest) 959 { 960 int f; 961 962 for (f = 0; ce_info[f].width != 0; f++) { 963 964 /* we have to deal with each element of the HMC using the 965 * correct size so that we are correct regardless of the 966 * endianness of the machine 967 */ 968 switch (ce_info[f].size_of) { 969 case 1: 970 i40e_write_byte(context_bytes, &ce_info[f], dest); 971 break; 972 case 2: 973 i40e_write_word(context_bytes, &ce_info[f], dest); 974 break; 975 case 4: 976 i40e_write_dword(context_bytes, &ce_info[f], dest); 977 break; 978 case 8: 979 i40e_write_qword(context_bytes, &ce_info[f], dest); 980 break; 981 } 982 } 983 984 return 0; 985 } 986 987 /** 988 * i40e_hmc_get_object_va - retrieves an object's virtual address 989 * @hmc_info: pointer to i40e_hmc_info struct 990 * @object_base: pointer to u64 to get the va 991 * @rsrc_type: the hmc resource type 992 * @obj_idx: hmc object index 993 * 994 * This function retrieves the object's virtual address from the object 995 * base pointer. This function is used for LAN Queue contexts. 996 **/ 997 static 998 i40e_status i40e_hmc_get_object_va(struct i40e_hmc_info *hmc_info, 999 u8 **object_base, 1000 enum i40e_hmc_lan_rsrc_type rsrc_type, 1001 u32 obj_idx) 1002 { 1003 u32 obj_offset_in_sd, obj_offset_in_pd; 1004 i40e_status ret_code = 0; 1005 struct i40e_hmc_sd_entry *sd_entry; 1006 struct i40e_hmc_pd_entry *pd_entry; 1007 u32 pd_idx, pd_lmt, rel_pd_idx; 1008 u64 obj_offset_in_fpm; 1009 u32 sd_idx, sd_lmt; 1010 1011 if (NULL == hmc_info) { 1012 ret_code = I40E_ERR_BAD_PTR; 1013 hw_dbg(hw, "i40e_hmc_get_object_va: bad hmc_info ptr\n"); 1014 goto exit; 1015 } 1016 if (NULL == hmc_info->hmc_obj) { 1017 ret_code = I40E_ERR_BAD_PTR; 1018 hw_dbg(hw, "i40e_hmc_get_object_va: bad hmc_info->hmc_obj ptr\n"); 1019 goto exit; 1020 } 1021 if (NULL == object_base) { 1022 ret_code = I40E_ERR_BAD_PTR; 1023 hw_dbg(hw, "i40e_hmc_get_object_va: bad object_base ptr\n"); 1024 goto exit; 1025 } 1026 if (I40E_HMC_INFO_SIGNATURE != hmc_info->signature) { 1027 ret_code = I40E_ERR_BAD_PTR; 1028 hw_dbg(hw, "i40e_hmc_get_object_va: bad hmc_info->signature\n"); 1029 goto exit; 1030 } 1031 if (obj_idx >= hmc_info->hmc_obj[rsrc_type].cnt) { 1032 hw_dbg(hw, "i40e_hmc_get_object_va: returns error %d\n", 1033 ret_code); 1034 ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX; 1035 goto exit; 1036 } 1037 /* find sd index and limit */ 1038 I40E_FIND_SD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1, 1039 &sd_idx, &sd_lmt); 1040 1041 sd_entry = &hmc_info->sd_table.sd_entry[sd_idx]; 1042 obj_offset_in_fpm = hmc_info->hmc_obj[rsrc_type].base + 1043 hmc_info->hmc_obj[rsrc_type].size * obj_idx; 1044 1045 if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) { 1046 I40E_FIND_PD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1, 1047 &pd_idx, &pd_lmt); 1048 rel_pd_idx = pd_idx % I40E_HMC_PD_CNT_IN_SD; 1049 pd_entry = &sd_entry->u.pd_table.pd_entry[rel_pd_idx]; 1050 obj_offset_in_pd = (u32)(obj_offset_in_fpm % 1051 I40E_HMC_PAGED_BP_SIZE); 1052 *object_base = (u8 *)pd_entry->bp.addr.va + obj_offset_in_pd; 1053 } else { 1054 obj_offset_in_sd = (u32)(obj_offset_in_fpm % 1055 I40E_HMC_DIRECT_BP_SIZE); 1056 *object_base = (u8 *)sd_entry->u.bp.addr.va + obj_offset_in_sd; 1057 } 1058 exit: 1059 return ret_code; 1060 } 1061 1062 /** 1063 * i40e_clear_lan_tx_queue_context - clear the HMC context for the queue 1064 * @hw: the hardware struct 1065 * @queue: the queue we care about 1066 **/ 1067 i40e_status i40e_clear_lan_tx_queue_context(struct i40e_hw *hw, 1068 u16 queue) 1069 { 1070 i40e_status err; 1071 u8 *context_bytes; 1072 1073 err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, 1074 I40E_HMC_LAN_TX, queue); 1075 if (err < 0) 1076 return err; 1077 1078 return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_TX); 1079 } 1080 1081 /** 1082 * i40e_set_lan_tx_queue_context - set the HMC context for the queue 1083 * @hw: the hardware struct 1084 * @queue: the queue we care about 1085 * @s: the struct to be filled 1086 **/ 1087 i40e_status i40e_set_lan_tx_queue_context(struct i40e_hw *hw, 1088 u16 queue, 1089 struct i40e_hmc_obj_txq *s) 1090 { 1091 i40e_status err; 1092 u8 *context_bytes; 1093 1094 err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, 1095 I40E_HMC_LAN_TX, queue); 1096 if (err < 0) 1097 return err; 1098 1099 return i40e_set_hmc_context(context_bytes, 1100 i40e_hmc_txq_ce_info, (u8 *)s); 1101 } 1102 1103 /** 1104 * i40e_clear_lan_rx_queue_context - clear the HMC context for the queue 1105 * @hw: the hardware struct 1106 * @queue: the queue we care about 1107 **/ 1108 i40e_status i40e_clear_lan_rx_queue_context(struct i40e_hw *hw, 1109 u16 queue) 1110 { 1111 i40e_status err; 1112 u8 *context_bytes; 1113 1114 err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, 1115 I40E_HMC_LAN_RX, queue); 1116 if (err < 0) 1117 return err; 1118 1119 return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_RX); 1120 } 1121 1122 /** 1123 * i40e_set_lan_rx_queue_context - set the HMC context for the queue 1124 * @hw: the hardware struct 1125 * @queue: the queue we care about 1126 * @s: the struct to be filled 1127 **/ 1128 i40e_status i40e_set_lan_rx_queue_context(struct i40e_hw *hw, 1129 u16 queue, 1130 struct i40e_hmc_obj_rxq *s) 1131 { 1132 i40e_status err; 1133 u8 *context_bytes; 1134 1135 err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, 1136 I40E_HMC_LAN_RX, queue); 1137 if (err < 0) 1138 return err; 1139 1140 return i40e_set_hmc_context(context_bytes, 1141 i40e_hmc_rxq_ce_info, (u8 *)s); 1142 } 1143