linux/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
<<
>>
Prefs
   1/*******************************************************************************
   2 *
   3 * Intel Ethernet Controller XL710 Family Linux Driver
   4 * Copyright(c) 2013 Intel Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 * You should have received a copy of the GNU General Public License along with
  16 * this program; if not, write to the Free Software Foundation, Inc.,
  17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  18 *
  19 * The full GNU General Public License is included in this distribution in
  20 * the file called "COPYING".
  21 *
  22 * Contact Information:
  23 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
  24 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  25 *
  26 ******************************************************************************/
  27
  28#include "i40e_osdep.h"
  29#include "i40e_register.h"
  30#include "i40e_type.h"
  31#include "i40e_hmc.h"
  32#include "i40e_lan_hmc.h"
  33#include "i40e_prototype.h"
  34
  35/* lan specific interface functions */
  36
  37/**
  38 * i40e_align_l2obj_base - aligns base object pointer to 512 bytes
  39 * @offset: base address offset needing alignment
  40 *
  41 * Aligns the layer 2 function private memory so it's 512-byte aligned.
  42 **/
  43static u64 i40e_align_l2obj_base(u64 offset)
  44{
  45        u64 aligned_offset = offset;
  46
  47        if ((offset % I40E_HMC_L2OBJ_BASE_ALIGNMENT) > 0)
  48                aligned_offset += (I40E_HMC_L2OBJ_BASE_ALIGNMENT -
  49                                   (offset % I40E_HMC_L2OBJ_BASE_ALIGNMENT));
  50
  51        return aligned_offset;
  52}
  53
  54/**
  55 * i40e_calculate_l2fpm_size - calculates layer 2 FPM memory size
  56 * @txq_num: number of Tx queues needing backing context
  57 * @rxq_num: number of Rx queues needing backing context
  58 * @fcoe_cntx_num: amount of FCoE statefull contexts needing backing context
  59 * @fcoe_filt_num: number of FCoE filters needing backing context
  60 *
  61 * Calculates the maximum amount of memory for the function required, based
  62 * on the number of resources it must provide context for.
  63 **/
  64static u64 i40e_calculate_l2fpm_size(u32 txq_num, u32 rxq_num,
  65                              u32 fcoe_cntx_num, u32 fcoe_filt_num)
  66{
  67        u64 fpm_size = 0;
  68
  69        fpm_size = txq_num * I40E_HMC_OBJ_SIZE_TXQ;
  70        fpm_size = i40e_align_l2obj_base(fpm_size);
  71
  72        fpm_size += (rxq_num * I40E_HMC_OBJ_SIZE_RXQ);
  73        fpm_size = i40e_align_l2obj_base(fpm_size);
  74
  75        fpm_size += (fcoe_cntx_num * I40E_HMC_OBJ_SIZE_FCOE_CNTX);
  76        fpm_size = i40e_align_l2obj_base(fpm_size);
  77
  78        fpm_size += (fcoe_filt_num * I40E_HMC_OBJ_SIZE_FCOE_FILT);
  79        fpm_size = i40e_align_l2obj_base(fpm_size);
  80
  81        return fpm_size;
  82}
  83
  84/**
  85 * i40e_init_lan_hmc - initialize i40e_hmc_info struct
  86 * @hw: pointer to the HW structure
  87 * @txq_num: number of Tx queues needing backing context
  88 * @rxq_num: number of Rx queues needing backing context
  89 * @fcoe_cntx_num: amount of FCoE statefull contexts needing backing context
  90 * @fcoe_filt_num: number of FCoE filters needing backing context
  91 *
  92 * This function will be called once per physical function initialization.
  93 * It will fill out the i40e_hmc_obj_info structure for LAN objects based on
  94 * the driver's provided input, as well as information from the HMC itself
  95 * loaded from NVRAM.
  96 *
  97 * Assumptions:
  98 *   - HMC Resource Profile has been selected before calling this function.
  99 **/
 100i40e_status i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
 101                                        u32 rxq_num, u32 fcoe_cntx_num,
 102                                        u32 fcoe_filt_num)
 103{
 104        struct i40e_hmc_obj_info *obj, *full_obj;
 105        i40e_status ret_code = 0;
 106        u64 l2fpm_size;
 107        u32 size_exp;
 108
 109        hw->hmc.signature = I40E_HMC_INFO_SIGNATURE;
 110        hw->hmc.hmc_fn_id = hw->pf_id;
 111
 112        /* allocate memory for hmc_obj */
 113        ret_code = i40e_allocate_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem,
 114                        sizeof(struct i40e_hmc_obj_info) * I40E_HMC_LAN_MAX);
 115        if (ret_code)
 116                goto init_lan_hmc_out;
 117        hw->hmc.hmc_obj = (struct i40e_hmc_obj_info *)
 118                          hw->hmc.hmc_obj_virt_mem.va;
 119
 120        /* The full object will be used to create the LAN HMC SD */
 121        full_obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_FULL];
 122        full_obj->max_cnt = 0;
 123        full_obj->cnt = 0;
 124        full_obj->base = 0;
 125        full_obj->size = 0;
 126
 127        /* Tx queue context information */
 128        obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX];
 129        obj->max_cnt = rd32(hw, I40E_GLHMC_LANQMAX);
 130        obj->cnt = txq_num;
 131        obj->base = 0;
 132        size_exp = rd32(hw, I40E_GLHMC_LANTXOBJSZ);
 133        obj->size = (u64)1 << size_exp;
 134
 135        /* validate values requested by driver don't exceed HMC capacity */
 136        if (txq_num > obj->max_cnt) {
 137                ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
 138                hw_dbg(hw, "i40e_init_lan_hmc: Tx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
 139                          txq_num, obj->max_cnt, ret_code);
 140                goto init_lan_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        /* Rx queue context information */
 148        obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX];
 149        obj->max_cnt = rd32(hw, I40E_GLHMC_LANQMAX);
 150        obj->cnt = rxq_num;
 151        obj->base = hw->hmc.hmc_obj[I40E_HMC_LAN_TX].base +
 152                    (hw->hmc.hmc_obj[I40E_HMC_LAN_TX].cnt *
 153                     hw->hmc.hmc_obj[I40E_HMC_LAN_TX].size);
 154        obj->base = i40e_align_l2obj_base(obj->base);
 155        size_exp = rd32(hw, I40E_GLHMC_LANRXOBJSZ);
 156        obj->size = (u64)1 << size_exp;
 157
 158        /* validate values requested by driver don't exceed HMC capacity */
 159        if (rxq_num > obj->max_cnt) {
 160                ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
 161                hw_dbg(hw, "i40e_init_lan_hmc: Rx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
 162                          rxq_num, obj->max_cnt, ret_code);
 163                goto init_lan_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 context information */
 171        obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX];
 172        obj->max_cnt = rd32(hw, I40E_GLHMC_FCOEMAX);
 173        obj->cnt = fcoe_cntx_num;
 174        obj->base = hw->hmc.hmc_obj[I40E_HMC_LAN_RX].base +
 175                    (hw->hmc.hmc_obj[I40E_HMC_LAN_RX].cnt *
 176                     hw->hmc.hmc_obj[I40E_HMC_LAN_RX].size);
 177        obj->base = i40e_align_l2obj_base(obj->base);
 178        size_exp = rd32(hw, I40E_GLHMC_FCOEDDPOBJSZ);
 179        obj->size = (u64)1 << size_exp;
 180
 181        /* validate values requested by driver don't exceed HMC capacity */
 182        if (fcoe_cntx_num > obj->max_cnt) {
 183                ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
 184                hw_dbg(hw, "i40e_init_lan_hmc: FCoE context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
 185                          fcoe_cntx_num, obj->max_cnt, ret_code);
 186                goto init_lan_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        /* FCoE filter information */
 194        obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT];
 195        obj->max_cnt = rd32(hw, I40E_GLHMC_FCOEFMAX);
 196        obj->cnt = fcoe_filt_num;
 197        obj->base = hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].base +
 198                    (hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].cnt *
 199                     hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].size);
 200        obj->base = i40e_align_l2obj_base(obj->base);
 201        size_exp = rd32(hw, I40E_GLHMC_FCOEFOBJSZ);
 202        obj->size = (u64)1 << size_exp;
 203
 204        /* validate values requested by driver don't exceed HMC capacity */
 205        if (fcoe_filt_num > obj->max_cnt) {
 206                ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
 207                hw_dbg(hw, "i40e_init_lan_hmc: FCoE filter: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
 208                          fcoe_filt_num, obj->max_cnt, ret_code);
 209                goto init_lan_hmc_out;
 210        }
 211
 212        /* aggregate values into the full LAN object for later */
 213        full_obj->max_cnt += obj->max_cnt;
 214        full_obj->cnt += obj->cnt;
 215
 216        hw->hmc.first_sd_index = 0;
 217        hw->hmc.sd_table.ref_cnt = 0;
 218        l2fpm_size = i40e_calculate_l2fpm_size(txq_num, rxq_num, fcoe_cntx_num,
 219                                               fcoe_filt_num);
 220        if (NULL == hw->hmc.sd_table.sd_entry) {
 221                hw->hmc.sd_table.sd_cnt = (u32)
 222                                   (l2fpm_size + I40E_HMC_DIRECT_BP_SIZE - 1) /
 223                                   I40E_HMC_DIRECT_BP_SIZE;
 224
 225                /* allocate the sd_entry members in the sd_table */
 226                ret_code = i40e_allocate_virt_mem(hw, &hw->hmc.sd_table.addr,
 227                                          (sizeof(struct i40e_hmc_sd_entry) *
 228                                          hw->hmc.sd_table.sd_cnt));
 229                if (ret_code)
 230                        goto init_lan_hmc_out;
 231                hw->hmc.sd_table.sd_entry =
 232                        (struct i40e_hmc_sd_entry *)hw->hmc.sd_table.addr.va;
 233        }
 234        /* store in the LAN full object for later */
 235        full_obj->size = l2fpm_size;
 236
 237init_lan_hmc_out:
 238        return ret_code;
 239}
 240
 241/**
 242 * i40e_remove_pd_page - Remove a page from the page descriptor table
 243 * @hw: pointer to the HW structure
 244 * @hmc_info: pointer to the HMC configuration information structure
 245 * @idx: segment descriptor index to find the relevant page descriptor
 246 *
 247 * This function:
 248 *      1. Marks the entry in pd table (for paged address mode) invalid
 249 *      2. write to register PMPDINV to invalidate the backing page in FV cache
 250 *      3. Decrement the ref count for  pd_entry
 251 * assumptions:
 252 *      1. caller can deallocate the memory used by pd after this function
 253 *         returns.
 254 **/
 255static i40e_status i40e_remove_pd_page(struct i40e_hw *hw,
 256                                                 struct i40e_hmc_info *hmc_info,
 257                                                 u32 idx)
 258{
 259        i40e_status ret_code = 0;
 260
 261        if (!i40e_prep_remove_pd_page(hmc_info, idx))
 262                ret_code = i40e_remove_pd_page_new(hw, hmc_info, idx, true);
 263
 264        return ret_code;
 265}
 266
 267/**
 268 * i40e_remove_sd_bp - remove a backing page from a segment descriptor
 269 * @hw: pointer to our HW structure
 270 * @hmc_info: pointer to the HMC configuration information structure
 271 * @idx: the page index
 272 *
 273 * This function:
 274 *      1. Marks the entry in sd table (for direct address mode) invalid
 275 *      2. write to register PMSDCMD, PMSDDATALOW(PMSDDATALOW.PMSDVALID set
 276 *         to 0) and PMSDDATAHIGH to invalidate the sd page
 277 *      3. Decrement the ref count for the sd_entry
 278 * assumptions:
 279 *      1. caller can deallocate the memory used by backing storage after this
 280 *         function returns.
 281 **/
 282static i40e_status i40e_remove_sd_bp(struct i40e_hw *hw,
 283                                               struct i40e_hmc_info *hmc_info,
 284                                               u32 idx)
 285{
 286        i40e_status ret_code = 0;
 287
 288        if (!i40e_prep_remove_sd_bp(hmc_info, idx))
 289                ret_code = i40e_remove_sd_bp_new(hw, hmc_info, idx, true);
 290
 291        return ret_code;
 292}
 293
 294/**
 295 * i40e_create_lan_hmc_object - allocate backing store for hmc objects
 296 * @hw: pointer to the HW structure
 297 * @info: pointer to i40e_hmc_create_obj_info struct
 298 *
 299 * This will allocate memory for PDs and backing pages and populate
 300 * the sd and pd entries.
 301 **/
 302static i40e_status i40e_create_lan_hmc_object(struct i40e_hw *hw,
 303                                struct i40e_hmc_lan_create_obj_info *info)
 304{
 305        i40e_status ret_code = 0;
 306        struct i40e_hmc_sd_entry *sd_entry;
 307        u32 pd_idx1 = 0, pd_lmt1 = 0;
 308        u32 pd_idx = 0, pd_lmt = 0;
 309        bool pd_error = false;
 310        u32 sd_idx, sd_lmt;
 311        u64 sd_size;
 312        u32 i, j;
 313
 314        if (NULL == info) {
 315                ret_code = I40E_ERR_BAD_PTR;
 316                hw_dbg(hw, "i40e_create_lan_hmc_object: bad info ptr\n");
 317                goto exit;
 318        }
 319        if (NULL == info->hmc_info) {
 320                ret_code = I40E_ERR_BAD_PTR;
 321                hw_dbg(hw, "i40e_create_lan_hmc_object: bad hmc_info ptr\n");
 322                goto exit;
 323        }
 324        if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) {
 325                ret_code = I40E_ERR_BAD_PTR;
 326                hw_dbg(hw, "i40e_create_lan_hmc_object: bad signature\n");
 327                goto exit;
 328        }
 329
 330        if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
 331                ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
 332                hw_dbg(hw, "i40e_create_lan_hmc_object: returns error %d\n",
 333                          ret_code);
 334                goto exit;
 335        }
 336        if ((info->start_idx + info->count) >
 337            info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
 338                ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
 339                hw_dbg(hw, "i40e_create_lan_hmc_object: returns error %d\n",
 340                          ret_code);
 341                goto exit;
 342        }
 343
 344        /* find sd index and limit */
 345        I40E_FIND_SD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
 346                                 info->start_idx, info->count,
 347                                 &sd_idx, &sd_lmt);
 348        if (sd_idx >= info->hmc_info->sd_table.sd_cnt ||
 349            sd_lmt > info->hmc_info->sd_table.sd_cnt) {
 350                        ret_code = I40E_ERR_INVALID_SD_INDEX;
 351                        goto exit;
 352        }
 353        /* find pd index */
 354        I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
 355                                 info->start_idx, info->count, &pd_idx,
 356                                 &pd_lmt);
 357
 358        /* This is to cover for cases where you may not want to have an SD with
 359         * the full 2M memory but something smaller. By not filling out any
 360         * size, the function will default the SD size to be 2M.
 361         */
 362        if (info->direct_mode_sz == 0)
 363                sd_size = I40E_HMC_DIRECT_BP_SIZE;
 364        else
 365                sd_size = info->direct_mode_sz;
 366
 367        /* check if all the sds are valid. If not, allocate a page and
 368         * initialize it.
 369         */
 370        for (j = sd_idx; j < sd_lmt; j++) {
 371                /* update the sd table entry */
 372                ret_code = i40e_add_sd_table_entry(hw, info->hmc_info, j,
 373                                                   info->entry_type,
 374                                                   sd_size);
 375                if (ret_code)
 376                        goto exit_sd_error;
 377                sd_entry = &info->hmc_info->sd_table.sd_entry[j];
 378                if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) {
 379                        /* check if all the pds in this sd are valid. If not,
 380                         * allocate a page and initialize it.
 381                         */
 382
 383                        /* find pd_idx and pd_lmt in this sd */
 384                        pd_idx1 = max(pd_idx, (j * I40E_HMC_MAX_BP_COUNT));
 385                        pd_lmt1 = min(pd_lmt,
 386                                      ((j + 1) * I40E_HMC_MAX_BP_COUNT));
 387                        for (i = pd_idx1; i < pd_lmt1; i++) {
 388                                /* update the pd table entry */
 389                                ret_code = i40e_add_pd_table_entry(hw,
 390                                                                info->hmc_info,
 391                                                                i);
 392                                if (ret_code) {
 393                                        pd_error = true;
 394                                        break;
 395                                }
 396                        }
 397                        if (pd_error) {
 398                                /* remove the backing pages from pd_idx1 to i */
 399                                while (i && (i > pd_idx1)) {
 400                                        i40e_remove_pd_bp(hw, info->hmc_info,
 401                                                          (i - 1), true);
 402                                        i--;
 403                                }
 404                        }
 405                }
 406                if (!sd_entry->valid) {
 407                        sd_entry->valid = true;
 408                        switch (sd_entry->entry_type) {
 409                        case I40E_SD_TYPE_PAGED:
 410                                I40E_SET_PF_SD_ENTRY(hw,
 411                                        sd_entry->u.pd_table.pd_page_addr.pa,
 412                                        j, sd_entry->entry_type);
 413                                break;
 414                        case I40E_SD_TYPE_DIRECT:
 415                                I40E_SET_PF_SD_ENTRY(hw, sd_entry->u.bp.addr.pa,
 416                                                     j, sd_entry->entry_type);
 417                                break;
 418                        default:
 419                                ret_code = I40E_ERR_INVALID_SD_TYPE;
 420                                goto exit;
 421                                break;
 422                        }
 423                }
 424        }
 425        goto exit;
 426
 427exit_sd_error:
 428        /* cleanup for sd entries from j to sd_idx */
 429        while (j && (j > sd_idx)) {
 430                sd_entry = &info->hmc_info->sd_table.sd_entry[j - 1];
 431                switch (sd_entry->entry_type) {
 432                case I40E_SD_TYPE_PAGED:
 433                        pd_idx1 = max(pd_idx,
 434                                      ((j - 1) * I40E_HMC_MAX_BP_COUNT));
 435                        pd_lmt1 = min(pd_lmt, (j * I40E_HMC_MAX_BP_COUNT));
 436                        for (i = pd_idx1; i < pd_lmt1; i++) {
 437                                i40e_remove_pd_bp(
 438                                        hw,
 439                                        info->hmc_info,
 440                                        i,
 441                                        true);
 442                        }
 443                        i40e_remove_pd_page(hw, info->hmc_info, (j - 1));
 444                        break;
 445                case I40E_SD_TYPE_DIRECT:
 446                        i40e_remove_sd_bp(hw, info->hmc_info, (j - 1));
 447                        break;
 448                default:
 449                        ret_code = I40E_ERR_INVALID_SD_TYPE;
 450                        break;
 451                }
 452                j--;
 453        }
 454exit:
 455        return ret_code;
 456}
 457
 458/**
 459 * i40e_configure_lan_hmc - prepare the HMC backing store
 460 * @hw: pointer to the hw structure
 461 * @model: the model for the layout of the SD/PD tables
 462 *
 463 * - This function will be called once per physical function initialization.
 464 * - This function will be called after i40e_init_lan_hmc() and before
 465 *   any LAN/FCoE HMC objects can be created.
 466 **/
 467i40e_status i40e_configure_lan_hmc(struct i40e_hw *hw,
 468                                             enum i40e_hmc_model model)
 469{
 470        struct i40e_hmc_lan_create_obj_info info;
 471        i40e_status ret_code = 0;
 472        u8 hmc_fn_id = hw->hmc.hmc_fn_id;
 473        struct i40e_hmc_obj_info *obj;
 474
 475        /* Initialize part of the create object info struct */
 476        info.hmc_info = &hw->hmc;
 477        info.rsrc_type = I40E_HMC_LAN_FULL;
 478        info.start_idx = 0;
 479        info.direct_mode_sz = hw->hmc.hmc_obj[I40E_HMC_LAN_FULL].size;
 480
 481        /* Build the SD entry for the LAN objects */
 482        switch (model) {
 483        case I40E_HMC_MODEL_DIRECT_PREFERRED:
 484        case I40E_HMC_MODEL_DIRECT_ONLY:
 485                info.entry_type = I40E_SD_TYPE_DIRECT;
 486                /* Make one big object, a single SD */
 487                info.count = 1;
 488                ret_code = i40e_create_lan_hmc_object(hw, &info);
 489                if ((ret_code) &&
 490                    (model == I40E_HMC_MODEL_DIRECT_PREFERRED))
 491                        goto try_type_paged;
 492                else if (ret_code)
 493                        goto configure_lan_hmc_out;
 494                /* else clause falls through the break */
 495                break;
 496        case I40E_HMC_MODEL_PAGED_ONLY:
 497try_type_paged:
 498                info.entry_type = I40E_SD_TYPE_PAGED;
 499                /* Make one big object in the PD table */
 500                info.count = 1;
 501                ret_code = i40e_create_lan_hmc_object(hw, &info);
 502                if (ret_code)
 503                        goto configure_lan_hmc_out;
 504                break;
 505        default:
 506                /* unsupported type */
 507                ret_code = I40E_ERR_INVALID_SD_TYPE;
 508                hw_dbg(hw, "i40e_configure_lan_hmc: Unknown SD type: %d\n",
 509                          ret_code);
 510                goto configure_lan_hmc_out;
 511                break;
 512        }
 513
 514        /* Configure and program the FPM registers so objects can be created */
 515
 516        /* Tx contexts */
 517        obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX];
 518        wr32(hw, I40E_GLHMC_LANTXBASE(hmc_fn_id),
 519             (u32)((obj->base & I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK) / 512));
 520        wr32(hw, I40E_GLHMC_LANTXCNT(hmc_fn_id), obj->cnt);
 521
 522        /* Rx contexts */
 523        obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX];
 524        wr32(hw, I40E_GLHMC_LANRXBASE(hmc_fn_id),
 525             (u32)((obj->base & I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK) / 512));
 526        wr32(hw, I40E_GLHMC_LANRXCNT(hmc_fn_id), obj->cnt);
 527
 528        /* FCoE contexts */
 529        obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX];
 530        wr32(hw, I40E_GLHMC_FCOEDDPBASE(hmc_fn_id),
 531         (u32)((obj->base & I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK) / 512));
 532        wr32(hw, I40E_GLHMC_FCOEDDPCNT(hmc_fn_id), obj->cnt);
 533
 534        /* FCoE filters */
 535        obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT];
 536        wr32(hw, I40E_GLHMC_FCOEFBASE(hmc_fn_id),
 537             (u32)((obj->base & I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK) / 512));
 538        wr32(hw, I40E_GLHMC_FCOEFCNT(hmc_fn_id), obj->cnt);
 539
 540configure_lan_hmc_out:
 541        return ret_code;
 542}
 543
 544/**
 545 * i40e_delete_hmc_object - remove hmc objects
 546 * @hw: pointer to the HW structure
 547 * @info: pointer to i40e_hmc_delete_obj_info struct
 548 *
 549 * This will de-populate the SDs and PDs.  It frees
 550 * the memory for PDS and backing storage.  After this function is returned,
 551 * caller should deallocate memory allocated previously for
 552 * book-keeping information about PDs and backing storage.
 553 **/
 554static i40e_status i40e_delete_lan_hmc_object(struct i40e_hw *hw,
 555                                struct i40e_hmc_lan_delete_obj_info *info)
 556{
 557        i40e_status ret_code = 0;
 558        struct i40e_hmc_pd_table *pd_table;
 559        u32 pd_idx, pd_lmt, rel_pd_idx;
 560        u32 sd_idx, sd_lmt;
 561        u32 i, j;
 562
 563        if (NULL == info) {
 564                ret_code = I40E_ERR_BAD_PTR;
 565                hw_dbg(hw, "i40e_delete_hmc_object: bad info ptr\n");
 566                goto exit;
 567        }
 568        if (NULL == info->hmc_info) {
 569                ret_code = I40E_ERR_BAD_PTR;
 570                hw_dbg(hw, "i40e_delete_hmc_object: bad info->hmc_info ptr\n");
 571                goto exit;
 572        }
 573        if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) {
 574                ret_code = I40E_ERR_BAD_PTR;
 575                hw_dbg(hw, "i40e_delete_hmc_object: bad hmc_info->signature\n");
 576                goto exit;
 577        }
 578
 579        if (NULL == info->hmc_info->sd_table.sd_entry) {
 580                ret_code = I40E_ERR_BAD_PTR;
 581                hw_dbg(hw, "i40e_delete_hmc_object: bad sd_entry\n");
 582                goto exit;
 583        }
 584
 585        if (NULL == info->hmc_info->hmc_obj) {
 586                ret_code = I40E_ERR_BAD_PTR;
 587                hw_dbg(hw, "i40e_delete_hmc_object: bad hmc_info->hmc_obj\n");
 588                goto exit;
 589        }
 590        if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
 591                ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
 592                hw_dbg(hw, "i40e_delete_hmc_object: returns error %d\n",
 593                          ret_code);
 594                goto exit;
 595        }
 596
 597        if ((info->start_idx + info->count) >
 598            info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
 599                ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
 600                hw_dbg(hw, "i40e_delete_hmc_object: returns error %d\n",
 601                          ret_code);
 602                goto exit;
 603        }
 604
 605        I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
 606                                 info->start_idx, info->count, &pd_idx,
 607                                 &pd_lmt);
 608
 609        for (j = pd_idx; j < pd_lmt; j++) {
 610                sd_idx = j / I40E_HMC_PD_CNT_IN_SD;
 611
 612                if (I40E_SD_TYPE_PAGED !=
 613                    info->hmc_info->sd_table.sd_entry[sd_idx].entry_type)
 614                        continue;
 615
 616                rel_pd_idx = j % I40E_HMC_PD_CNT_IN_SD;
 617
 618                pd_table =
 619                        &info->hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
 620                if (pd_table->pd_entry[rel_pd_idx].valid) {
 621                        ret_code = i40e_remove_pd_bp(hw, info->hmc_info,
 622                                                     j, true);
 623                        if (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 (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 (ret_code)
 650                                goto exit;
 651                        break;
 652                default:
 653                        break;
 654                }
 655        }
 656exit:
 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 **/
 667i40e_status i40e_shutdown_lan_hmc(struct i40e_hw *hw)
 668{
 669        struct i40e_hmc_lan_delete_obj_info info;
 670        i40e_status 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
 696struct i40e_context_ele {
 697        u16 offset;
 698        u16 size_of;
 699        u16 width;
 700        u16 lsb;
 701};
 702
 703/* LAN Tx Queue Context */
 704static 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 */
 730static 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        { 0 }
 753};
 754
 755/**
 756 * i40e_clear_hmc_context - zero out the HMC context bits
 757 * @hw:       the hardware struct
 758 * @context_bytes: pointer to the context bit array (DMA memory)
 759 * @hmc_type: the type of HMC resource
 760 **/
 761static i40e_status i40e_clear_hmc_context(struct i40e_hw *hw,
 762                                        u8 *context_bytes,
 763                                        enum i40e_hmc_lan_rsrc_type hmc_type)
 764{
 765        /* clean the bit array */
 766        memset(context_bytes, 0, (u32)hw->hmc.hmc_obj[hmc_type].size);
 767
 768        return 0;
 769}
 770
 771/**
 772 * i40e_set_hmc_context - replace HMC context bits
 773 * @context_bytes: pointer to the context bit array
 774 * @ce_info:  a description of the struct to be filled
 775 * @dest:     the struct to be filled
 776 **/
 777static i40e_status i40e_set_hmc_context(u8 *context_bytes,
 778                                        struct i40e_context_ele *ce_info,
 779                                        u8 *dest)
 780{
 781        u16 shift_width;
 782        u64 bitfield;
 783        u8 hi_byte;
 784        u8 hi_mask;
 785        u64 t_bits;
 786        u64 mask;
 787        u8 *p;
 788        int f;
 789
 790        for (f = 0; ce_info[f].width != 0; f++) {
 791                /* clear out the field */
 792                bitfield = 0;
 793
 794                /* copy from the next struct field */
 795                p = dest + ce_info[f].offset;
 796                switch (ce_info[f].size_of) {
 797                case 1:
 798                        bitfield = *p;
 799                        break;
 800                case 2:
 801                        bitfield = cpu_to_le16(*(u16 *)p);
 802                        break;
 803                case 4:
 804                        bitfield = cpu_to_le32(*(u32 *)p);
 805                        break;
 806                case 8:
 807                        bitfield = cpu_to_le64(*(u64 *)p);
 808                        break;
 809                }
 810
 811                /* prepare the bits and mask */
 812                shift_width = ce_info[f].lsb % 8;
 813                mask = ((u64)1 << ce_info[f].width) - 1;
 814
 815                /* save upper bytes for special case */
 816                hi_mask = (u8)((mask >> 56) & 0xff);
 817                hi_byte = (u8)((bitfield >> 56) & 0xff);
 818
 819                /* shift to correct alignment */
 820                mask <<= shift_width;
 821                bitfield <<= shift_width;
 822
 823                /* get the current bits from the target bit string */
 824                p = context_bytes + (ce_info[f].lsb / 8);
 825                memcpy(&t_bits, p, sizeof(u64));
 826
 827                t_bits &= ~mask;          /* get the bits not changing */
 828                t_bits |= bitfield;       /* add in the new bits */
 829
 830                /* put it all back */
 831                memcpy(p, &t_bits, sizeof(u64));
 832
 833                /* deal with the special case if needed
 834                 * example: 62 bit field that starts in bit 5 of first byte
 835                 *          will overlap 3 bits into byte 9
 836                 */
 837                if ((shift_width + ce_info[f].width) > 64) {
 838                        u8 byte;
 839
 840                        hi_mask >>= (8 - shift_width);
 841                        hi_byte >>= (8 - shift_width);
 842                        byte = p[8] & ~hi_mask;  /* get the bits not changing */
 843                        byte |= hi_byte;         /* add in the new bits */
 844                        p[8] = byte;             /* put it back */
 845                }
 846        }
 847
 848        return 0;
 849}
 850
 851/**
 852 * i40e_hmc_get_object_va - retrieves an object's virtual address
 853 * @hmc_info: pointer to i40e_hmc_info struct
 854 * @object_base: pointer to u64 to get the va
 855 * @rsrc_type: the hmc resource type
 856 * @obj_idx: hmc object index
 857 *
 858 * This function retrieves the object's virtual address from the object
 859 * base pointer.  This function is used for LAN Queue contexts.
 860 **/
 861static
 862i40e_status i40e_hmc_get_object_va(struct i40e_hmc_info *hmc_info,
 863                                        u8 **object_base,
 864                                        enum i40e_hmc_lan_rsrc_type rsrc_type,
 865                                        u32 obj_idx)
 866{
 867        u32 obj_offset_in_sd, obj_offset_in_pd;
 868        i40e_status ret_code = 0;
 869        struct i40e_hmc_sd_entry *sd_entry;
 870        struct i40e_hmc_pd_entry *pd_entry;
 871        u32 pd_idx, pd_lmt, rel_pd_idx;
 872        u64 obj_offset_in_fpm;
 873        u32 sd_idx, sd_lmt;
 874
 875        if (NULL == hmc_info) {
 876                ret_code = I40E_ERR_BAD_PTR;
 877                hw_dbg(hw, "i40e_hmc_get_object_va: bad hmc_info ptr\n");
 878                goto exit;
 879        }
 880        if (NULL == hmc_info->hmc_obj) {
 881                ret_code = I40E_ERR_BAD_PTR;
 882                hw_dbg(hw, "i40e_hmc_get_object_va: bad hmc_info->hmc_obj ptr\n");
 883                goto exit;
 884        }
 885        if (NULL == object_base) {
 886                ret_code = I40E_ERR_BAD_PTR;
 887                hw_dbg(hw, "i40e_hmc_get_object_va: bad object_base ptr\n");
 888                goto exit;
 889        }
 890        if (I40E_HMC_INFO_SIGNATURE != hmc_info->signature) {
 891                ret_code = I40E_ERR_BAD_PTR;
 892                hw_dbg(hw, "i40e_hmc_get_object_va: bad hmc_info->signature\n");
 893                goto exit;
 894        }
 895        if (obj_idx >= hmc_info->hmc_obj[rsrc_type].cnt) {
 896                hw_dbg(hw, "i40e_hmc_get_object_va: returns error %d\n",
 897                          ret_code);
 898                ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
 899                goto exit;
 900        }
 901        /* find sd index and limit */
 902        I40E_FIND_SD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1,
 903                                 &sd_idx, &sd_lmt);
 904
 905        sd_entry = &hmc_info->sd_table.sd_entry[sd_idx];
 906        obj_offset_in_fpm = hmc_info->hmc_obj[rsrc_type].base +
 907                            hmc_info->hmc_obj[rsrc_type].size * obj_idx;
 908
 909        if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) {
 910                I40E_FIND_PD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1,
 911                                         &pd_idx, &pd_lmt);
 912                rel_pd_idx = pd_idx % I40E_HMC_PD_CNT_IN_SD;
 913                pd_entry = &sd_entry->u.pd_table.pd_entry[rel_pd_idx];
 914                obj_offset_in_pd = (u32)(obj_offset_in_fpm %
 915                                         I40E_HMC_PAGED_BP_SIZE);
 916                *object_base = (u8 *)pd_entry->bp.addr.va + obj_offset_in_pd;
 917        } else {
 918                obj_offset_in_sd = (u32)(obj_offset_in_fpm %
 919                                         I40E_HMC_DIRECT_BP_SIZE);
 920                *object_base = (u8 *)sd_entry->u.bp.addr.va + obj_offset_in_sd;
 921        }
 922exit:
 923        return ret_code;
 924}
 925
 926/**
 927 * i40e_clear_lan_tx_queue_context - clear the HMC context for the queue
 928 * @hw:    the hardware struct
 929 * @queue: the queue we care about
 930 **/
 931i40e_status i40e_clear_lan_tx_queue_context(struct i40e_hw *hw,
 932                                                      u16 queue)
 933{
 934        i40e_status err;
 935        u8 *context_bytes;
 936
 937        err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes,
 938                                     I40E_HMC_LAN_TX, queue);
 939        if (err < 0)
 940                return err;
 941
 942        return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_TX);
 943}
 944
 945/**
 946 * i40e_set_lan_tx_queue_context - set the HMC context for the queue
 947 * @hw:    the hardware struct
 948 * @queue: the queue we care about
 949 * @s:     the struct to be filled
 950 **/
 951i40e_status i40e_set_lan_tx_queue_context(struct i40e_hw *hw,
 952                                                    u16 queue,
 953                                                    struct i40e_hmc_obj_txq *s)
 954{
 955        i40e_status err;
 956        u8 *context_bytes;
 957
 958        err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes,
 959                                     I40E_HMC_LAN_TX, queue);
 960        if (err < 0)
 961                return err;
 962
 963        return i40e_set_hmc_context(context_bytes,
 964                                    i40e_hmc_txq_ce_info, (u8 *)s);
 965}
 966
 967/**
 968 * i40e_clear_lan_rx_queue_context - clear the HMC context for the queue
 969 * @hw:    the hardware struct
 970 * @queue: the queue we care about
 971 **/
 972i40e_status i40e_clear_lan_rx_queue_context(struct i40e_hw *hw,
 973                                                      u16 queue)
 974{
 975        i40e_status err;
 976        u8 *context_bytes;
 977
 978        err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes,
 979                                     I40E_HMC_LAN_RX, queue);
 980        if (err < 0)
 981                return err;
 982
 983        return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_RX);
 984}
 985
 986/**
 987 * i40e_set_lan_rx_queue_context - set the HMC context for the queue
 988 * @hw:    the hardware struct
 989 * @queue: the queue we care about
 990 * @s:     the struct to be filled
 991 **/
 992i40e_status i40e_set_lan_rx_queue_context(struct i40e_hw *hw,
 993                                                    u16 queue,
 994                                                    struct i40e_hmc_obj_rxq *s)
 995{
 996        i40e_status err;
 997        u8 *context_bytes;
 998
 999        err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes,
1000                                     I40E_HMC_LAN_RX, queue);
1001        if (err < 0)
1002                return err;
1003
1004        return i40e_set_hmc_context(context_bytes,
1005                                    i40e_hmc_rxq_ce_info, (u8 *)s);
1006}
1007