The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/qlnx/qlnxe/ecore_init_ops.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2017-2018 Cavium, Inc. 
    3  * All rights reserved.
    4  *
    5  *  Redistribution and use in source and binary forms, with or without
    6  *  modification, are permitted provided that the following conditions
    7  *  are met:
    8  *
    9  *  1. Redistributions of source code must retain the above copyright
   10  *     notice, this list of conditions and the following disclaimer.
   11  *  2. Redistributions in binary form must reproduce the above copyright
   12  *     notice, this list of conditions and the following disclaimer in the
   13  *     documentation and/or other materials provided with the distribution.
   14  *
   15  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   16  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   19  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   20  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   21  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   22  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   23  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   24  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   25  *  POSSIBILITY OF SUCH DAMAGE.
   26  */
   27 
   28 /*
   29  * File : ecore_init_ops.c
   30  */
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 /* include the precompiled configuration values - only once */
   35 #include "bcm_osal.h"
   36 #include "ecore_hsi_common.h"
   37 #include "ecore.h"
   38 #include "ecore_hw.h"
   39 #include "ecore_status.h"
   40 #include "ecore_rt_defs.h"
   41 #include "ecore_init_fw_funcs.h"
   42 
   43 #ifndef CONFIG_ECORE_BINARY_FW
   44 #ifdef CONFIG_ECORE_ZIPPED_FW
   45 #include "ecore_init_values_zipped.h"
   46 #else
   47 #include "ecore_init_values.h"
   48 #endif
   49 #endif
   50 
   51 #include "ecore_iro_values.h"
   52 #include "ecore_sriov.h"
   53 #include "ecore_gtt_values.h"
   54 #include "reg_addr.h"
   55 #include "ecore_init_ops.h"
   56 
   57 #define ECORE_INIT_MAX_POLL_COUNT       100
   58 #define ECORE_INIT_POLL_PERIOD_US       500
   59 
   60 void ecore_init_iro_array(struct ecore_dev *p_dev)
   61 {
   62         p_dev->iro_arr = iro_arr;
   63 }
   64 
   65 /* Runtime configuration helpers */
   66 void ecore_init_clear_rt_data(struct ecore_hwfn *p_hwfn)
   67 {
   68         int i;
   69 
   70         for (i = 0; i < RUNTIME_ARRAY_SIZE; i++)
   71                 p_hwfn->rt_data.b_valid[i] = false;
   72 }
   73 
   74 void ecore_init_store_rt_reg(struct ecore_hwfn *p_hwfn,
   75                              u32 rt_offset, u32 val)
   76 {
   77         if (rt_offset >= RUNTIME_ARRAY_SIZE) {
   78                 DP_ERR(p_hwfn,
   79                        "Avoid storing %u in rt_data at index %u since RUNTIME_ARRAY_SIZE is %u!\n",
   80                        val, rt_offset, RUNTIME_ARRAY_SIZE);
   81                 return;
   82         }
   83 
   84         p_hwfn->rt_data.init_val[rt_offset] = val;
   85         p_hwfn->rt_data.b_valid[rt_offset] = true;
   86 }
   87 
   88 void ecore_init_store_rt_agg(struct ecore_hwfn *p_hwfn,
   89                              u32 rt_offset, u32 *p_val,
   90                              osal_size_t size)
   91 {
   92         osal_size_t i;
   93 
   94         if ((rt_offset + size - 1) >= RUNTIME_ARRAY_SIZE) {
   95                 DP_ERR(p_hwfn,
   96                        "Avoid storing values in rt_data at indices %u-%u since RUNTIME_ARRAY_SIZE is %u!\n",
   97                        rt_offset, (u32)(rt_offset + size - 1),
   98                        RUNTIME_ARRAY_SIZE);
   99                 return;
  100         }
  101 
  102         for (i = 0; i < size / sizeof(u32); i++) {
  103                 p_hwfn->rt_data.init_val[rt_offset + i] = p_val[i];
  104                 p_hwfn->rt_data.b_valid[rt_offset + i] = true;
  105         }
  106 }
  107 
  108 static enum _ecore_status_t ecore_init_rt(struct ecore_hwfn *p_hwfn,
  109                                           struct ecore_ptt *p_ptt,
  110                                           u32 addr,
  111                                           u16 rt_offset,
  112                                           u16 size,
  113                                           bool b_must_dmae)
  114 {
  115         u32 *p_init_val = &p_hwfn->rt_data.init_val[rt_offset];
  116         bool *p_valid = &p_hwfn->rt_data.b_valid[rt_offset];
  117         u16 i, segment;
  118         enum _ecore_status_t rc = ECORE_SUCCESS;
  119 
  120         /* Since not all RT entries are initialized, go over the RT and
  121          * for each segment of initialized values use DMA.
  122          */
  123         for (i = 0; i < size; i++) {
  124                 if (!p_valid[i])
  125                         continue;
  126 
  127                 /* In case there isn't any wide-bus configuration here,
  128                  * simply write the data instead of using dmae.
  129                  */
  130                 if (!b_must_dmae) {
  131                         ecore_wr(p_hwfn, p_ptt, addr + (i << 2),
  132                                  p_init_val[i]);
  133                         continue;
  134                 }
  135 
  136                 /* Start of a new segment */
  137                 for (segment = 1; i + segment < size; segment++)
  138                         if (!p_valid[i + segment])
  139                                 break;
  140 
  141                 rc = ecore_dmae_host2grc(p_hwfn, p_ptt,
  142                                          (osal_uintptr_t)(p_init_val + i),
  143                                          addr + (i << 2), segment,
  144                                          OSAL_NULL /* default parameters */);
  145                 if (rc != ECORE_SUCCESS)
  146                         return rc;
  147 
  148                 /* Jump over the entire segment, including invalid entry */
  149                 i += segment;
  150         }
  151 
  152         return rc;
  153 }
  154 
  155 enum _ecore_status_t ecore_init_alloc(struct ecore_hwfn *p_hwfn)
  156 {
  157         struct ecore_rt_data *rt_data = &p_hwfn->rt_data;
  158 
  159         if (IS_VF(p_hwfn->p_dev))
  160                 return ECORE_SUCCESS;
  161 
  162         rt_data->b_valid = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
  163                                        sizeof(bool) * RUNTIME_ARRAY_SIZE);
  164         if (!rt_data->b_valid)
  165                 return ECORE_NOMEM;
  166 
  167         rt_data->init_val = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
  168                                         sizeof(u32) * RUNTIME_ARRAY_SIZE);
  169         if (!rt_data->init_val) {
  170                 OSAL_FREE(p_hwfn->p_dev, rt_data->b_valid);
  171                 rt_data->b_valid = OSAL_NULL;
  172                 return ECORE_NOMEM;
  173         }
  174 
  175         return ECORE_SUCCESS;
  176 }
  177 
  178 void ecore_init_free(struct ecore_hwfn *p_hwfn)
  179 {
  180         OSAL_FREE(p_hwfn->p_dev, p_hwfn->rt_data.init_val);
  181         p_hwfn->rt_data.init_val = OSAL_NULL;
  182         OSAL_FREE(p_hwfn->p_dev, p_hwfn->rt_data.b_valid);
  183         p_hwfn->rt_data.b_valid = OSAL_NULL;
  184 }
  185 
  186 static enum _ecore_status_t ecore_init_array_dmae(struct ecore_hwfn *p_hwfn,
  187                                   struct ecore_ptt *p_ptt,
  188                                   u32 addr, u32 dmae_data_offset,
  189                                   u32 size, const u32 *p_buf,
  190                                   bool b_must_dmae, bool b_can_dmae)
  191 {
  192         enum _ecore_status_t rc = ECORE_SUCCESS;
  193 
  194         /* Perform DMAE only for lengthy enough sections or for wide-bus */
  195 #ifndef ASIC_ONLY
  196         if ((CHIP_REV_IS_SLOW(p_hwfn->p_dev) && (size < 16)) ||
  197             !b_can_dmae || (!b_must_dmae && (size < 16))) {
  198 #else
  199         if (!b_can_dmae || (!b_must_dmae && (size < 16))) {
  200 #endif
  201                 const u32 *data = p_buf + dmae_data_offset;
  202                 u32 i;
  203 
  204                 for (i = 0; i < size; i++)
  205                         ecore_wr(p_hwfn, p_ptt, addr + (i << 2), data[i]);
  206         } else {
  207                 rc = ecore_dmae_host2grc(p_hwfn, p_ptt,
  208                                          (osal_uintptr_t)(p_buf +
  209                                                           dmae_data_offset),
  210                                          addr, size,
  211                                          OSAL_NULL /* default parameters */);
  212         }
  213 
  214         return rc;
  215 }
  216 
  217 static enum _ecore_status_t ecore_init_fill_dmae(struct ecore_hwfn *p_hwfn,
  218                                                  struct ecore_ptt *p_ptt,
  219                                                  u32 addr, u32 fill_count)
  220 {
  221         static u32 zero_buffer[DMAE_MAX_RW_SIZE];
  222         struct ecore_dmae_params params;
  223 
  224         OSAL_MEMSET(zero_buffer, 0, sizeof(u32) * DMAE_MAX_RW_SIZE);
  225 
  226         OSAL_MEMSET(&params, 0, sizeof(params));
  227         params.flags = ECORE_DMAE_FLAG_RW_REPL_SRC;
  228         return ecore_dmae_host2grc(p_hwfn, p_ptt,
  229                                    (osal_uintptr_t)(&(zero_buffer[0])),
  230                                    addr, fill_count, &params);
  231 }
  232 
  233 static void ecore_init_fill(struct ecore_hwfn *p_hwfn,
  234                             struct ecore_ptt *p_ptt,
  235                             u32 addr, u32 fill, u32 fill_count)
  236 {
  237         u32 i;
  238 
  239         for (i = 0; i < fill_count; i++, addr += sizeof(u32))
  240                 ecore_wr(p_hwfn, p_ptt, addr, fill);
  241 }
  242 
  243 static enum _ecore_status_t ecore_init_cmd_array(struct ecore_hwfn *p_hwfn,
  244                                                  struct ecore_ptt *p_ptt,
  245                                                  struct init_write_op *cmd,
  246                                                  bool b_must_dmae,
  247                                                  bool b_can_dmae)
  248 {
  249         u32 dmae_array_offset = OSAL_LE32_TO_CPU(cmd->args.array_offset);
  250         u32 data = OSAL_LE32_TO_CPU(cmd->data);
  251         u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
  252 #ifdef CONFIG_ECORE_ZIPPED_FW
  253         u32 offset, output_len, input_len, max_size;
  254 #endif
  255         struct ecore_dev *p_dev = p_hwfn->p_dev;
  256         union init_array_hdr *hdr;
  257         const u32 *array_data;
  258         enum _ecore_status_t rc = ECORE_SUCCESS;
  259         u32 size;
  260 
  261         array_data = p_dev->fw_data->arr_data;
  262 
  263         hdr = (union init_array_hdr *) (array_data +
  264                                         dmae_array_offset);
  265         data = OSAL_LE32_TO_CPU(hdr->raw.data);
  266         switch (GET_FIELD(data, INIT_ARRAY_RAW_HDR_TYPE)) {
  267         case INIT_ARR_ZIPPED:
  268 #ifdef CONFIG_ECORE_ZIPPED_FW
  269                 offset = dmae_array_offset + 1;
  270                 input_len = GET_FIELD(data,
  271                                       INIT_ARRAY_ZIPPED_HDR_ZIPPED_SIZE);
  272                 max_size = MAX_ZIPPED_SIZE * 4;
  273                 OSAL_MEMSET(p_hwfn->unzip_buf, 0, max_size);
  274 
  275                 output_len = OSAL_UNZIP_DATA(p_hwfn, input_len,
  276                                              (u8 *)&array_data[offset],
  277                                              max_size, (u8 *)p_hwfn->unzip_buf);
  278                 if (output_len) {
  279                         rc = ecore_init_array_dmae(p_hwfn, p_ptt, addr, 0,
  280                                                    output_len,
  281                                                    p_hwfn->unzip_buf,
  282                                                    b_must_dmae, b_can_dmae);
  283                 } else {
  284                         DP_NOTICE(p_hwfn, true,
  285                                   "Failed to unzip dmae data\n");
  286                         rc = ECORE_INVAL;
  287                 }
  288 #else
  289                 DP_NOTICE(p_hwfn, true,
  290                           "Using zipped firmware without config enabled\n");
  291                 rc = ECORE_INVAL;
  292 #endif
  293                 break;
  294         case INIT_ARR_PATTERN:
  295         {
  296                 u32 repeats = GET_FIELD(data,
  297                                         INIT_ARRAY_PATTERN_HDR_REPETITIONS);
  298                 u32 i;
  299 
  300                 size = GET_FIELD(data,
  301                                  INIT_ARRAY_PATTERN_HDR_PATTERN_SIZE);
  302 
  303                 for (i = 0; i < repeats; i++, addr += size << 2) {
  304                         rc = ecore_init_array_dmae(p_hwfn, p_ptt, addr,
  305                                                    dmae_array_offset + 1,
  306                                                    size, array_data,
  307                                                    b_must_dmae, b_can_dmae);
  308                         if (rc)
  309                                 break;
  310                 }
  311                 break;
  312         }
  313         case INIT_ARR_STANDARD:
  314                 size = GET_FIELD(data,
  315                                  INIT_ARRAY_STANDARD_HDR_SIZE);
  316                 rc = ecore_init_array_dmae(p_hwfn, p_ptt, addr,
  317                                            dmae_array_offset + 1,
  318                                            size, array_data,
  319                                            b_must_dmae, b_can_dmae);
  320                 break;
  321         }
  322 
  323         return rc;
  324 }
  325 
  326 /* init_ops write command */
  327 static enum _ecore_status_t ecore_init_cmd_wr(struct ecore_hwfn *p_hwfn,
  328                                               struct ecore_ptt *p_ptt,
  329                                               struct init_write_op *p_cmd,
  330                                               bool b_can_dmae)
  331 {
  332         u32 data = OSAL_LE32_TO_CPU(p_cmd->data);
  333         bool b_must_dmae = GET_FIELD(data, INIT_WRITE_OP_WIDE_BUS);
  334         u32 addr = GET_FIELD(data, INIT_WRITE_OP_ADDRESS) << 2;
  335         enum _ecore_status_t rc = ECORE_SUCCESS;
  336 
  337         /* Sanitize */
  338         if (b_must_dmae && !b_can_dmae) {
  339                 DP_NOTICE(p_hwfn, true,
  340                           "Need to write to %08x for Wide-bus but DMAE isn't allowed\n",
  341                           addr);
  342                 return ECORE_INVAL;
  343         }
  344 
  345         switch (GET_FIELD(data, INIT_WRITE_OP_SOURCE)) {
  346         case INIT_SRC_INLINE:
  347                 data = OSAL_LE32_TO_CPU(p_cmd->args.inline_val);
  348                 ecore_wr(p_hwfn, p_ptt, addr, data);
  349                 break;
  350         case INIT_SRC_ZEROS:
  351                 data = OSAL_LE32_TO_CPU(p_cmd->args.zeros_count);
  352                 if (b_must_dmae || (b_can_dmae && (data >= 64)))
  353                         rc = ecore_init_fill_dmae(p_hwfn, p_ptt, addr, data);
  354                 else
  355                         ecore_init_fill(p_hwfn, p_ptt, addr, 0, data);
  356                 break;
  357         case INIT_SRC_ARRAY:
  358                 rc = ecore_init_cmd_array(p_hwfn, p_ptt, p_cmd,
  359                                           b_must_dmae, b_can_dmae);
  360                 break;
  361         case INIT_SRC_RUNTIME:
  362                 rc = ecore_init_rt(p_hwfn, p_ptt, addr,
  363                                    OSAL_LE16_TO_CPU(p_cmd->args.runtime.offset),
  364                                    OSAL_LE16_TO_CPU(p_cmd->args.runtime.size),
  365                                    b_must_dmae);
  366                 break;
  367         }
  368 
  369         return rc;
  370 }
  371 
  372 static OSAL_INLINE bool comp_eq(u32 val, u32 expected_val)
  373 {
  374         return (val == expected_val);
  375 }
  376 
  377 static OSAL_INLINE bool comp_and(u32 val, u32 expected_val)
  378 {
  379         return (val & expected_val) == expected_val;
  380 }
  381 
  382 static OSAL_INLINE bool comp_or(u32 val, u32 expected_val)
  383 {
  384         return (val | expected_val) > 0;
  385 }
  386 
  387 /* init_ops read/poll commands */
  388 static void ecore_init_cmd_rd(struct ecore_hwfn *p_hwfn,
  389                               struct ecore_ptt *p_ptt,
  390                               struct init_read_op *cmd)
  391 {
  392         bool (*comp_check)(u32 val, u32 expected_val);
  393         u32 delay = ECORE_INIT_POLL_PERIOD_US, val;
  394         u32 data, addr, poll;
  395         int i;
  396 
  397         data = OSAL_LE32_TO_CPU(cmd->op_data);
  398         addr = GET_FIELD(data, INIT_READ_OP_ADDRESS) << 2;
  399         poll = GET_FIELD(data, INIT_READ_OP_POLL_TYPE);
  400 
  401 #ifndef ASIC_ONLY
  402         if (CHIP_REV_IS_EMUL(p_hwfn->p_dev))
  403                 delay *= 100;
  404 #endif
  405 
  406         val = ecore_rd(p_hwfn, p_ptt, addr);
  407 
  408         if (poll == INIT_POLL_NONE)
  409                 return;
  410 
  411         switch (poll) {
  412         case INIT_POLL_EQ:
  413                 comp_check = comp_eq;
  414                 break;
  415         case INIT_POLL_OR:
  416                 comp_check = comp_or;
  417                 break;
  418         case INIT_POLL_AND:
  419                 comp_check = comp_and;
  420                 break;
  421         default:
  422                 DP_ERR(p_hwfn, "Invalid poll comparison type %08x\n",
  423                        cmd->op_data);
  424                 return;
  425         }
  426 
  427         data = OSAL_LE32_TO_CPU(cmd->expected_val);
  428         for (i = 0;
  429              i < ECORE_INIT_MAX_POLL_COUNT && !comp_check(val, data);
  430              i++) {
  431                 OSAL_UDELAY(delay);
  432                 val = ecore_rd(p_hwfn, p_ptt, addr);
  433         }
  434 
  435         if (i == ECORE_INIT_MAX_POLL_COUNT)
  436                 DP_ERR(p_hwfn, "Timeout when polling reg: 0x%08x [ Waiting-for: %08x Got: %08x (comparison %08x)]\n",
  437                        addr,
  438                        OSAL_LE32_TO_CPU(cmd->expected_val), val,
  439                        OSAL_LE32_TO_CPU(cmd->op_data));
  440 }
  441 
  442 /* init_ops callbacks entry point */
  443 static enum _ecore_status_t ecore_init_cmd_cb(struct ecore_hwfn *p_hwfn,
  444                                               struct ecore_ptt *p_ptt,
  445                                               struct init_callback_op *p_cmd)
  446 {
  447         enum _ecore_status_t rc;
  448 
  449         switch (p_cmd->callback_id) {
  450         case DMAE_READY_CB:
  451                 rc = ecore_dmae_sanity(p_hwfn, p_ptt, "engine_phase");
  452                 break;
  453         default:
  454                 DP_NOTICE(p_hwfn, false, "Unexpected init op callback ID %d\n",
  455                           p_cmd->callback_id);
  456                 return ECORE_INVAL;
  457         }
  458 
  459         return rc;
  460 }
  461 
  462 static u8 ecore_init_cmd_mode_match(struct ecore_hwfn *p_hwfn,
  463                                     u16 *p_offset, int modes)
  464 {
  465         struct ecore_dev *p_dev = p_hwfn->p_dev;
  466         const u8 *modes_tree_buf;
  467         u8 arg1, arg2, tree_val;
  468 
  469         modes_tree_buf = p_dev->fw_data->modes_tree_buf;
  470         tree_val = modes_tree_buf[(*p_offset)++];
  471         switch(tree_val) {
  472         case INIT_MODE_OP_NOT:
  473                 return ecore_init_cmd_mode_match(p_hwfn, p_offset, modes) ^ 1;
  474         case INIT_MODE_OP_OR:
  475                 arg1 = ecore_init_cmd_mode_match(p_hwfn, p_offset, modes);
  476                 arg2 = ecore_init_cmd_mode_match(p_hwfn, p_offset, modes);
  477                 return arg1 | arg2;
  478         case INIT_MODE_OP_AND:
  479                 arg1 = ecore_init_cmd_mode_match(p_hwfn, p_offset, modes);
  480                 arg2 = ecore_init_cmd_mode_match(p_hwfn, p_offset, modes);
  481                 return arg1 & arg2;
  482         default:
  483                 tree_val -= MAX_INIT_MODE_OPS;
  484                 return (modes & (1 << tree_val)) ? 1 : 0;
  485         }
  486 }
  487 
  488 static u32 ecore_init_cmd_mode(struct ecore_hwfn *p_hwfn,
  489                                struct init_if_mode_op *p_cmd, int modes)
  490 {
  491         u16 offset = OSAL_LE16_TO_CPU(p_cmd->modes_buf_offset);
  492 
  493         if (ecore_init_cmd_mode_match(p_hwfn, &offset, modes))
  494                 return 0;
  495         else
  496                 return GET_FIELD(OSAL_LE32_TO_CPU(p_cmd->op_data),
  497                                  INIT_IF_MODE_OP_CMD_OFFSET);
  498 }
  499 
  500 static u32 ecore_init_cmd_phase(struct init_if_phase_op *p_cmd,
  501                                 u32 phase, u32 phase_id)
  502 {
  503         u32 data = OSAL_LE32_TO_CPU(p_cmd->phase_data);
  504         u32 op_data = OSAL_LE32_TO_CPU(p_cmd->op_data);
  505 
  506         if (!(GET_FIELD(data, INIT_IF_PHASE_OP_PHASE) == phase &&
  507               (GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == ANY_PHASE_ID ||
  508                GET_FIELD(data, INIT_IF_PHASE_OP_PHASE_ID) == phase_id)))
  509                 return GET_FIELD(op_data, INIT_IF_PHASE_OP_CMD_OFFSET);
  510         else
  511                 return 0;
  512 }
  513 
  514 enum _ecore_status_t ecore_init_run(struct ecore_hwfn *p_hwfn,
  515                                     struct ecore_ptt *p_ptt,
  516                                     int phase,
  517                                     int phase_id,
  518                                     int modes)
  519 {
  520         struct ecore_dev *p_dev = p_hwfn->p_dev;
  521         u32 cmd_num, num_init_ops;
  522         union init_op *init_ops;
  523         bool b_dmae = false;
  524         enum _ecore_status_t rc = ECORE_SUCCESS;
  525 
  526         num_init_ops = p_dev->fw_data->init_ops_size;
  527         init_ops = p_dev->fw_data->init_ops;
  528 
  529 #ifdef CONFIG_ECORE_ZIPPED_FW
  530         p_hwfn->unzip_buf = OSAL_ZALLOC(p_hwfn->p_dev, GFP_ATOMIC,
  531                                         MAX_ZIPPED_SIZE * 4);
  532         if (!p_hwfn->unzip_buf) {
  533                 DP_NOTICE(p_hwfn, true, "Failed to allocate unzip buffer\n");
  534                 return ECORE_NOMEM;
  535         }
  536 #endif
  537 
  538         for (cmd_num = 0; cmd_num < num_init_ops; cmd_num++) {
  539                 union init_op *cmd = &init_ops[cmd_num];
  540                 u32 data = OSAL_LE32_TO_CPU(cmd->raw.op_data);
  541 
  542                 switch (GET_FIELD(data, INIT_CALLBACK_OP_OP)) {
  543                 case INIT_OP_WRITE:
  544                         rc = ecore_init_cmd_wr(p_hwfn, p_ptt, &cmd->write,
  545                                                b_dmae);
  546                         break;
  547 
  548                 case INIT_OP_READ:
  549                         ecore_init_cmd_rd(p_hwfn, p_ptt, &cmd->read);
  550                         break;
  551 
  552                 case INIT_OP_IF_MODE:
  553                         cmd_num += ecore_init_cmd_mode(p_hwfn, &cmd->if_mode,
  554                                                        modes);
  555                         break;
  556                 case INIT_OP_IF_PHASE:
  557                         cmd_num += ecore_init_cmd_phase(&cmd->if_phase, phase,
  558                                                         phase_id);
  559                         b_dmae = GET_FIELD(data,
  560                                            INIT_IF_PHASE_OP_DMAE_ENABLE);
  561                         break;
  562                 case INIT_OP_DELAY:
  563                         /* ecore_init_run is always invoked from
  564                          * sleep-able context
  565                          */
  566                         OSAL_UDELAY(cmd->delay.delay);
  567                         break;
  568 
  569                 case INIT_OP_CALLBACK:
  570                         rc = ecore_init_cmd_cb(p_hwfn, p_ptt, &cmd->callback);
  571                         break;
  572                 }
  573 
  574                 if (rc)
  575                         break;
  576         }
  577 #ifdef CONFIG_ECORE_ZIPPED_FW
  578         OSAL_FREE(p_hwfn->p_dev, p_hwfn->unzip_buf);
  579         p_hwfn->unzip_buf = OSAL_NULL;
  580 #endif
  581         return rc;
  582 }
  583 
  584 void ecore_gtt_init(struct ecore_hwfn *p_hwfn,
  585                     struct ecore_ptt *p_ptt)
  586 {
  587         u32 gtt_base;
  588         u32 i;
  589 
  590 #ifndef ASIC_ONLY
  591         if (CHIP_REV_IS_SLOW(p_hwfn->p_dev)) {
  592                 /* This is done by MFW on ASIC; regardless, this should only
  593                  * be done once per chip [i.e., common]. Implementation is
  594                  * not too bright, but it should work on the simple FPGA/EMUL
  595                  * scenarios.
  596                  */
  597                 static bool initialized = false;
  598                 int poll_cnt = 500;
  599                 u32 val;
  600 
  601                 /* initialize PTT/GTT (poll for completion) */
  602                 if (!initialized) {
  603                         ecore_wr(p_hwfn, p_ptt,
  604                                  PGLUE_B_REG_START_INIT_PTT_GTT, 1);
  605                         initialized = true;
  606                 }
  607 
  608                 do {
  609                         /* ptt might be overrided by HW until this is done */
  610                         OSAL_UDELAY(10);
  611                         ecore_ptt_invalidate(p_hwfn);
  612                         val = ecore_rd(p_hwfn, p_ptt,
  613                                        PGLUE_B_REG_INIT_DONE_PTT_GTT);
  614                 } while ((val != 1) && --poll_cnt);
  615 
  616                 if (!poll_cnt)
  617                         DP_ERR(p_hwfn, "PGLUE_B_REG_INIT_DONE didn't complete\n");
  618         }
  619 #endif
  620 
  621         /* Set the global windows */
  622         gtt_base = PXP_PF_WINDOW_ADMIN_START + PXP_PF_WINDOW_ADMIN_GLOBAL_START;
  623 
  624         for (i = 0; i < OSAL_ARRAY_SIZE(pxp_global_win); i++)
  625                 if (pxp_global_win[i])
  626                         REG_WR(p_hwfn, gtt_base + i * PXP_GLOBAL_ENTRY_SIZE,
  627                                pxp_global_win[i]);
  628 }
  629 
  630 enum _ecore_status_t ecore_init_fw_data(struct ecore_dev *p_dev,
  631 #ifdef CONFIG_ECORE_BINARY_FW
  632                                         const u8 *fw_data)
  633 #else
  634                                         const u8 OSAL_UNUSED *fw_data)
  635 #endif
  636 {
  637         struct ecore_fw_data *fw = p_dev->fw_data;
  638 
  639 #ifdef CONFIG_ECORE_BINARY_FW
  640         struct bin_buffer_hdr *buf_hdr;
  641         u32 offset, len;
  642 
  643         if (!fw_data) {
  644                 DP_NOTICE(p_dev, true, "Invalid fw data\n");
  645                 return ECORE_INVAL;
  646         }
  647 
  648         buf_hdr = (struct bin_buffer_hdr *)fw_data;
  649 
  650         offset = buf_hdr[BIN_BUF_INIT_FW_VER_INFO].offset;
  651         fw->fw_ver_info = (struct fw_ver_info *)(fw_data + offset);
  652 
  653         offset = buf_hdr[BIN_BUF_INIT_CMD].offset;
  654         fw->init_ops = (union init_op *)(fw_data + offset);
  655 
  656         offset = buf_hdr[BIN_BUF_INIT_VAL].offset;
  657         fw->arr_data = (u32 *)(fw_data + offset);
  658 
  659         offset = buf_hdr[BIN_BUF_INIT_MODE_TREE].offset;
  660         fw->modes_tree_buf = (u8 *)(fw_data + offset);
  661         len = buf_hdr[BIN_BUF_INIT_CMD].length;
  662         fw->init_ops_size = len / sizeof(struct init_raw_op);
  663 #else
  664         fw->init_ops = (union init_op *)init_ops;
  665         fw->arr_data = (u32 *)init_val;
  666         fw->modes_tree_buf = (u8 *)modes_tree_buf;
  667         fw->init_ops_size = init_ops_size;
  668 #endif
  669 
  670         return ECORE_SUCCESS;
  671 }

Cache object: 02c3b6845f13c66c29dcdd14d6e8b69b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.