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