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