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_ll2.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) 2018-2019 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_ll2.c
   30  */
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 #include "bcm_osal.h"
   35 
   36 #include "ecore.h"
   37 #include "ecore_status.h"
   38 #include "ecore_ll2.h"
   39 #include "reg_addr.h"
   40 #include "ecore_int.h"
   41 #include "ecore_cxt.h"
   42 #include "ecore_sp_commands.h"
   43 #include "ecore_hw.h"
   44 #include "reg_addr.h"
   45 #include "ecore_dev_api.h"
   46 #include "ecore_iro.h"
   47 #include "ecore_gtt_reg_addr.h"
   48 #include "ecore_ooo.h"
   49 #include "ecore_hw.h"
   50 #include "ecore_mcp.h"
   51 
   52 #define ECORE_LL2_RX_REGISTERED(ll2)    ((ll2)->rx_queue.b_cb_registred)
   53 #define ECORE_LL2_TX_REGISTERED(ll2)    ((ll2)->tx_queue.b_cb_registred)
   54 
   55 #ifdef _NTDDK_
   56 #pragma warning(push)
   57 #pragma warning(disable : 28167)
   58 #pragma warning(disable : 28123)
   59 #pragma warning(disable : 28121)
   60 #endif
   61 
   62 static struct ecore_ll2_info *
   63 __ecore_ll2_handle_sanity(struct ecore_hwfn *p_hwfn,
   64                           u8 connection_handle,
   65                           bool b_lock, bool b_only_active)
   66 {
   67         struct ecore_ll2_info *p_ll2_conn, *p_ret = OSAL_NULL;
   68 
   69         if (connection_handle >= ECORE_MAX_NUM_OF_LL2_CONNECTIONS)
   70                 return OSAL_NULL;
   71 
   72         if (!p_hwfn->p_ll2_info)
   73                 return OSAL_NULL;
   74 
   75         /* TODO - is there really need for the locked vs. unlocked
   76          * variant? I simply used what was already there.
   77          */
   78         p_ll2_conn = &p_hwfn->p_ll2_info[connection_handle];
   79 
   80         if (b_only_active) {
   81                 if (b_lock)
   82                         OSAL_MUTEX_ACQUIRE(&p_ll2_conn->mutex);
   83                 if (p_ll2_conn->b_active)
   84                         p_ret = p_ll2_conn;
   85                 if (b_lock)
   86                         OSAL_MUTEX_RELEASE(&p_ll2_conn->mutex);
   87         } else {
   88                 p_ret = p_ll2_conn;
   89         }
   90 
   91         return p_ret;
   92 }
   93 
   94 static struct ecore_ll2_info *
   95 ecore_ll2_handle_sanity(struct ecore_hwfn *p_hwfn,
   96                         u8 connection_handle)
   97 {
   98         return __ecore_ll2_handle_sanity(p_hwfn, connection_handle,
   99                                          false, true);
  100 }
  101 
  102 static struct ecore_ll2_info *
  103 ecore_ll2_handle_sanity_lock(struct ecore_hwfn *p_hwfn,
  104                              u8 connection_handle)
  105 {
  106         return __ecore_ll2_handle_sanity(p_hwfn, connection_handle,
  107                                          true, true);
  108 }
  109 
  110 static struct ecore_ll2_info *
  111 ecore_ll2_handle_sanity_inactive(struct ecore_hwfn *p_hwfn,
  112                                  u8 connection_handle)
  113 {
  114         return __ecore_ll2_handle_sanity(p_hwfn, connection_handle,
  115                                          false, false);
  116 }
  117 
  118 #ifndef LINUX_REMOVE
  119 /* TODO - is this really been used by anyone? Is it a on future todo list? */
  120 enum _ecore_status_t
  121 ecore_ll2_get_fragment_of_tx_packet(struct ecore_hwfn *p_hwfn,
  122                                     u8 connection_handle,
  123                                     dma_addr_t *p_addr,
  124                                     bool *b_last_fragment)
  125 {
  126         struct ecore_ll2_tx_packet *p_pkt;
  127         struct ecore_ll2_info *p_ll2_conn;
  128         u16 cur_frag_idx = 0;
  129 
  130         p_ll2_conn = ecore_ll2_handle_sanity(p_hwfn, connection_handle);
  131         if (p_ll2_conn == OSAL_NULL)
  132                 return ECORE_INVAL;
  133         p_pkt = &p_ll2_conn->tx_queue.cur_completing_packet;
  134 
  135         if (!p_ll2_conn->tx_queue.b_completing_packet || !p_addr)
  136                 return ECORE_INVAL;
  137 
  138         if (p_ll2_conn->tx_queue.cur_completing_bd_idx == p_pkt->bd_used)
  139                 return ECORE_INVAL;
  140 
  141         /* Packet is available and has at least one more frag - provide it */
  142         cur_frag_idx = p_ll2_conn->tx_queue.cur_completing_bd_idx++;
  143         *p_addr = p_pkt->bds_set[cur_frag_idx].tx_frag;
  144         if (b_last_fragment)
  145                 *b_last_fragment = p_pkt->bd_used ==
  146                                    p_ll2_conn->tx_queue.cur_completing_bd_idx;
  147 
  148         return ECORE_SUCCESS;
  149 }
  150 #endif
  151 
  152 static void ecore_ll2_txq_flush(struct ecore_hwfn *p_hwfn,
  153                                 u8 connection_handle)
  154 {
  155         bool b_last_packet = false, b_last_frag = false;
  156         struct ecore_ll2_tx_packet *p_pkt = OSAL_NULL;
  157         struct ecore_ll2_info *p_ll2_conn;
  158         struct ecore_ll2_tx_queue *p_tx;
  159         unsigned long flags = 0;
  160         dma_addr_t tx_frag;
  161 
  162         p_ll2_conn = ecore_ll2_handle_sanity_inactive(p_hwfn,
  163                                                       connection_handle);
  164         if (p_ll2_conn == OSAL_NULL)
  165                 return;
  166         p_tx = &p_ll2_conn->tx_queue;
  167 
  168         OSAL_SPIN_LOCK_IRQSAVE(&p_tx->lock, flags);
  169         while (!OSAL_LIST_IS_EMPTY(&p_tx->active_descq)) {
  170                 p_pkt = OSAL_LIST_FIRST_ENTRY(&p_tx->active_descq,
  171                                               struct ecore_ll2_tx_packet,
  172                                               list_entry);
  173 
  174                 if (p_pkt == OSAL_NULL)
  175                         break;
  176 
  177 #if defined(_NTDDK_)
  178 #pragma warning(suppress : 6011 28182)
  179 #endif
  180                 OSAL_LIST_REMOVE_ENTRY(&p_pkt->list_entry,
  181                                        &p_tx->active_descq);
  182                 b_last_packet = OSAL_LIST_IS_EMPTY(&p_tx->active_descq);
  183                 OSAL_LIST_PUSH_TAIL(&p_pkt->list_entry,
  184                                     &p_tx->free_descq);
  185                 OSAL_SPIN_UNLOCK_IRQSAVE(&p_tx->lock, flags);
  186                 if (p_ll2_conn->input.conn_type == ECORE_LL2_TYPE_OOO) {
  187                         struct ecore_ooo_buffer *p_buffer;
  188 
  189                         p_buffer = (struct ecore_ooo_buffer *)p_pkt->cookie;
  190                         ecore_ooo_put_free_buffer(p_hwfn->p_ooo_info, p_buffer);
  191                 } else {
  192                         p_tx->cur_completing_packet = *p_pkt;
  193                         p_tx->cur_completing_bd_idx = 1;
  194                         b_last_frag = p_tx->cur_completing_bd_idx ==
  195                                       p_pkt->bd_used;
  196 
  197                         tx_frag = p_pkt->bds_set[0].tx_frag;
  198                         p_ll2_conn->cbs.tx_release_cb(p_ll2_conn->cbs.cookie,
  199                                                       p_ll2_conn->my_id,
  200                                                       p_pkt->cookie,
  201                                                       tx_frag,
  202                                                       b_last_frag,
  203                                                       b_last_packet);
  204                 }
  205                 OSAL_SPIN_LOCK_IRQSAVE(&p_tx->lock, flags);
  206         }
  207         OSAL_SPIN_UNLOCK_IRQSAVE(&p_tx->lock, flags);
  208 }
  209 
  210 static enum _ecore_status_t
  211 ecore_ll2_txq_completion(struct ecore_hwfn *p_hwfn,
  212                          void *p_cookie)
  213 {
  214         struct ecore_ll2_info *p_ll2_conn = (struct ecore_ll2_info*)p_cookie;
  215         struct ecore_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
  216         u16 new_idx = 0, num_bds = 0, num_bds_in_packet = 0;
  217         struct ecore_ll2_tx_packet *p_pkt;
  218         bool b_last_frag = false;
  219         unsigned long flags;
  220         enum _ecore_status_t rc = ECORE_INVAL;
  221 
  222         OSAL_SPIN_LOCK_IRQSAVE(&p_tx->lock, flags);
  223         if (p_tx->b_completing_packet) {
  224                 /* TODO - this looks completely unnecessary to me - the only
  225                  * way we can re-enter is by the DPC calling us again, but this
  226                  * would only happen AFTER we return, and we unset this at end
  227                  * of the function.
  228                  */
  229                 rc = ECORE_BUSY;
  230                 goto out;
  231         }
  232 
  233         new_idx = OSAL_LE16_TO_CPU(*p_tx->p_fw_cons);
  234         num_bds = ((s16)new_idx - (s16)p_tx->bds_idx);
  235         while (num_bds) {
  236                 if (OSAL_LIST_IS_EMPTY(&p_tx->active_descq))
  237                         goto out;
  238 
  239                 p_pkt = OSAL_LIST_FIRST_ENTRY(&p_tx->active_descq,
  240                                               struct ecore_ll2_tx_packet,
  241                                               list_entry);
  242                 if (!p_pkt)
  243                         goto out;
  244 
  245                 p_tx->b_completing_packet = true;
  246                 p_tx->cur_completing_packet = *p_pkt;
  247                 num_bds_in_packet = p_pkt->bd_used;
  248 #if defined(_NTDDK_)
  249 #pragma warning(suppress : 6011 28182)
  250 #endif
  251                 OSAL_LIST_REMOVE_ENTRY(&p_pkt->list_entry,
  252                                        &p_tx->active_descq);
  253 
  254                 if (num_bds < num_bds_in_packet) {
  255                         DP_NOTICE(p_hwfn, true,
  256                                   "Rest of BDs does not cover whole packet\n");
  257                         goto out;
  258                 }
  259 
  260                 num_bds -= num_bds_in_packet;
  261                 p_tx->bds_idx += num_bds_in_packet;
  262                 while (num_bds_in_packet--)
  263                         ecore_chain_consume(&p_tx->txq_chain);
  264 
  265                 p_tx->cur_completing_bd_idx = 1;
  266                 b_last_frag = p_tx->cur_completing_bd_idx ==
  267                               p_pkt->bd_used;
  268                 OSAL_LIST_PUSH_TAIL(&p_pkt->list_entry,
  269                                     &p_tx->free_descq);
  270 
  271                 OSAL_SPIN_UNLOCK_IRQSAVE(&p_tx->lock, flags);
  272 
  273                 p_ll2_conn->cbs.tx_comp_cb(p_ll2_conn->cbs.cookie,
  274                                            p_ll2_conn->my_id,
  275                                            p_pkt->cookie,
  276                                            p_pkt->bds_set[0].tx_frag,
  277                                            b_last_frag,
  278                                            !num_bds);
  279 
  280                 OSAL_SPIN_LOCK_IRQSAVE(&p_tx->lock, flags);
  281         }
  282 
  283         p_tx->b_completing_packet = false;
  284         rc = ECORE_SUCCESS;
  285 out:
  286         OSAL_SPIN_UNLOCK_IRQSAVE(&p_tx->lock, flags);
  287         return rc;
  288 }
  289 
  290 static void ecore_ll2_rxq_parse_gsi(union core_rx_cqe_union *p_cqe,
  291                                     struct ecore_ll2_comp_rx_data *data)
  292 {
  293         data->parse_flags =
  294                 OSAL_LE16_TO_CPU(p_cqe->rx_cqe_gsi.parse_flags.flags);
  295         data->length.data_length =
  296                 OSAL_LE16_TO_CPU(p_cqe->rx_cqe_gsi.data_length);
  297         data->vlan =
  298                 OSAL_LE16_TO_CPU(p_cqe->rx_cqe_gsi.vlan);
  299         data->opaque_data_0 =
  300                 OSAL_LE32_TO_CPU(p_cqe->rx_cqe_gsi.src_mac_addrhi);
  301         data->opaque_data_1 =
  302                 OSAL_LE16_TO_CPU(p_cqe->rx_cqe_gsi.src_mac_addrlo);
  303         data->u.data_length_error =
  304                 p_cqe->rx_cqe_gsi.data_length_error;
  305         data->qp_id = OSAL_LE16_TO_CPU(p_cqe->rx_cqe_gsi.qp_id);
  306 
  307         data->src_qp = OSAL_LE32_TO_CPU(p_cqe->rx_cqe_gsi.src_qp);
  308 }
  309 
  310 static void ecore_ll2_rxq_parse_reg(union core_rx_cqe_union *p_cqe,
  311                                     struct ecore_ll2_comp_rx_data *data)
  312 {
  313         data->parse_flags =
  314                 OSAL_LE16_TO_CPU(p_cqe->rx_cqe_fp.parse_flags.flags);
  315         data->err_flags =
  316                 OSAL_LE16_TO_CPU(p_cqe->rx_cqe_fp.err_flags.flags);
  317         data->length.packet_length =
  318                 OSAL_LE16_TO_CPU(p_cqe->rx_cqe_fp.packet_length);
  319         data->vlan =
  320                 OSAL_LE16_TO_CPU(p_cqe->rx_cqe_fp.vlan);
  321         data->opaque_data_0 =
  322                 OSAL_LE32_TO_CPU(p_cqe->rx_cqe_fp.opaque_data.data[0]);
  323         data->opaque_data_1 =
  324                 OSAL_LE32_TO_CPU(p_cqe->rx_cqe_fp.opaque_data.data[1]);
  325         data->u.placement_offset =
  326                 p_cqe->rx_cqe_fp.placement_offset;
  327 }
  328 
  329 #if defined(_NTDDK_)
  330 #pragma warning(suppress : 28167 26110)
  331 #endif
  332 static enum _ecore_status_t
  333 ecore_ll2_handle_slowpath(struct ecore_hwfn *p_hwfn,
  334                           struct ecore_ll2_info *p_ll2_conn,
  335                           union core_rx_cqe_union *p_cqe,
  336                           unsigned long *p_lock_flags)
  337 {
  338         struct ecore_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue;
  339         struct core_rx_slow_path_cqe *sp_cqe;
  340 
  341         sp_cqe = &p_cqe->rx_cqe_sp;
  342         if (sp_cqe->ramrod_cmd_id != CORE_RAMROD_RX_QUEUE_FLUSH) {
  343                 DP_NOTICE(p_hwfn, true,
  344                           "LL2 - unexpected Rx CQE slowpath ramrod_cmd_id:%d\n",
  345                           sp_cqe->ramrod_cmd_id);
  346                 return ECORE_INVAL;
  347         }
  348 
  349         if (p_ll2_conn->cbs.slowpath_cb == OSAL_NULL) {
  350                 DP_NOTICE(p_hwfn, true,
  351                           "LL2 - received RX_QUEUE_FLUSH but no callback was provided\n");
  352                 return ECORE_INVAL;
  353         }
  354 
  355         OSAL_SPIN_UNLOCK_IRQSAVE(&p_rx->lock, *p_lock_flags);
  356 
  357         p_ll2_conn->cbs.slowpath_cb(p_ll2_conn->cbs.cookie,
  358                                     p_ll2_conn->my_id,
  359                                     OSAL_LE32_TO_CPU(sp_cqe->opaque_data.data[0]),
  360                                     OSAL_LE32_TO_CPU(sp_cqe->opaque_data.data[1]));
  361 
  362         OSAL_SPIN_LOCK_IRQSAVE(&p_rx->lock, *p_lock_flags);
  363 
  364         return ECORE_SUCCESS;
  365 }
  366 
  367 static enum _ecore_status_t
  368 ecore_ll2_rxq_handle_completion(struct ecore_hwfn *p_hwfn,
  369                                 struct ecore_ll2_info *p_ll2_conn,
  370                                 union core_rx_cqe_union *p_cqe,
  371                                 unsigned long *p_lock_flags,
  372                                 bool b_last_cqe)
  373 {
  374         struct ecore_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue;
  375         struct ecore_ll2_rx_packet *p_pkt = OSAL_NULL;
  376         struct ecore_ll2_comp_rx_data data;
  377 
  378         if (!OSAL_LIST_IS_EMPTY(&p_rx->active_descq))
  379                 p_pkt = OSAL_LIST_FIRST_ENTRY(&p_rx->active_descq,
  380                                               struct ecore_ll2_rx_packet,
  381                                               list_entry);
  382         if (!p_pkt) {
  383                 DP_NOTICE(p_hwfn, false,
  384                           "[%d] LL2 Rx completion but active_descq is empty\n",
  385                           p_ll2_conn->input.conn_type);
  386 
  387                 return ECORE_IO;
  388         }
  389 
  390         OSAL_LIST_REMOVE_ENTRY(&p_pkt->list_entry, &p_rx->active_descq);
  391 
  392         if (p_cqe->rx_cqe_sp.type == CORE_RX_CQE_TYPE_REGULAR)
  393                 ecore_ll2_rxq_parse_reg(p_cqe, &data);
  394         else
  395                 ecore_ll2_rxq_parse_gsi(p_cqe, &data);
  396 
  397         if (ecore_chain_consume(&p_rx->rxq_chain) != p_pkt->rxq_bd) {
  398                 DP_NOTICE(p_hwfn, false,
  399                           "Mismatch between active_descq and the LL2 Rx chain\n");
  400                 /* TODO - didn't return error value since this wasn't handled
  401                  * before, but this is obviously lacking.
  402                  */
  403         }
  404 
  405         OSAL_LIST_PUSH_TAIL(&p_pkt->list_entry, &p_rx->free_descq);
  406 
  407         data.connection_handle = p_ll2_conn->my_id;
  408         data.cookie = p_pkt->cookie;
  409         data.rx_buf_addr = p_pkt->rx_buf_addr;
  410         data.b_last_packet = b_last_cqe;
  411 
  412         OSAL_SPIN_UNLOCK_IRQSAVE(&p_rx->lock, *p_lock_flags);
  413         p_ll2_conn->cbs.rx_comp_cb(p_ll2_conn->cbs.cookie,
  414                                    &data);
  415 
  416         OSAL_SPIN_LOCK_IRQSAVE(&p_rx->lock, *p_lock_flags);
  417 
  418         return ECORE_SUCCESS;
  419 }
  420 
  421 static enum _ecore_status_t ecore_ll2_rxq_completion(struct ecore_hwfn *p_hwfn,
  422                                                      void *cookie)
  423 {
  424         struct ecore_ll2_info *p_ll2_conn = (struct ecore_ll2_info*)cookie;
  425         struct ecore_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue;
  426         union core_rx_cqe_union *cqe = OSAL_NULL;
  427         u16 cq_new_idx = 0, cq_old_idx = 0;
  428         unsigned long flags = 0;
  429         enum _ecore_status_t rc = ECORE_SUCCESS;
  430 
  431         OSAL_SPIN_LOCK_IRQSAVE(&p_rx->lock, flags);
  432         cq_new_idx = OSAL_LE16_TO_CPU(*p_rx->p_fw_cons);
  433         cq_old_idx = ecore_chain_get_cons_idx(&p_rx->rcq_chain);
  434 
  435         while (cq_new_idx != cq_old_idx) {
  436                 bool b_last_cqe = (cq_new_idx == cq_old_idx);
  437 
  438                 cqe = (union core_rx_cqe_union *)ecore_chain_consume(&p_rx->rcq_chain);
  439                 cq_old_idx = ecore_chain_get_cons_idx(&p_rx->rcq_chain);
  440 
  441                 DP_VERBOSE(p_hwfn, ECORE_MSG_LL2,
  442                            "LL2 [sw. cons %04x, fw. at %04x] - Got Packet of type %02x\n",
  443                            cq_old_idx, cq_new_idx, cqe->rx_cqe_sp.type);
  444 
  445                 switch (cqe->rx_cqe_sp.type) {
  446                 case CORE_RX_CQE_TYPE_SLOW_PATH:
  447                         rc = ecore_ll2_handle_slowpath(p_hwfn, p_ll2_conn,
  448                                                        cqe, &flags);
  449                         break;
  450                 case CORE_RX_CQE_TYPE_GSI_OFFLOAD:
  451                 case CORE_RX_CQE_TYPE_REGULAR:
  452                         rc = ecore_ll2_rxq_handle_completion(p_hwfn, p_ll2_conn,
  453                                                              cqe, &flags,
  454                                                              b_last_cqe);
  455                         break;
  456                 default:
  457                         rc = ECORE_IO;
  458                 }
  459         }
  460 
  461         OSAL_SPIN_UNLOCK_IRQSAVE(&p_rx->lock, flags);
  462         return rc;
  463 }
  464 
  465 static void ecore_ll2_rxq_flush(struct ecore_hwfn *p_hwfn,
  466                          u8 connection_handle)
  467 {
  468         struct ecore_ll2_info *p_ll2_conn = OSAL_NULL;
  469         struct ecore_ll2_rx_packet *p_pkt = OSAL_NULL;
  470         struct ecore_ll2_rx_queue *p_rx;
  471         unsigned long flags = 0;
  472 
  473         p_ll2_conn = ecore_ll2_handle_sanity_inactive(p_hwfn,
  474                                                       connection_handle);
  475         if (p_ll2_conn == OSAL_NULL)
  476                 return;
  477         p_rx = &p_ll2_conn->rx_queue;
  478 
  479         OSAL_SPIN_LOCK_IRQSAVE(&p_rx->lock, flags);
  480         while (!OSAL_LIST_IS_EMPTY(&p_rx->active_descq)) {
  481                 bool b_last;
  482                 p_pkt = OSAL_LIST_FIRST_ENTRY(&p_rx->active_descq,
  483                                               struct ecore_ll2_rx_packet,
  484                                               list_entry);
  485                 if (p_pkt == OSAL_NULL)
  486                         break;
  487 #if defined(_NTDDK_)
  488 #pragma warning(suppress : 6011 28182)
  489 #endif
  490                 OSAL_LIST_REMOVE_ENTRY(&p_pkt->list_entry,
  491                                        &p_rx->active_descq);
  492                 OSAL_LIST_PUSH_TAIL(&p_pkt->list_entry,
  493                                     &p_rx->free_descq);
  494                 b_last = OSAL_LIST_IS_EMPTY(&p_rx->active_descq);
  495                 OSAL_SPIN_UNLOCK_IRQSAVE(&p_rx->lock, flags);
  496 
  497                 if (p_ll2_conn->input.conn_type == ECORE_LL2_TYPE_OOO) {
  498                         struct ecore_ooo_buffer *p_buffer;
  499 
  500                         p_buffer = (struct ecore_ooo_buffer *)p_pkt->cookie;
  501                         ecore_ooo_put_free_buffer(p_hwfn->p_ooo_info, p_buffer);
  502                 } else {
  503                         dma_addr_t rx_buf_addr = p_pkt->rx_buf_addr;
  504                         void *cookie  = p_pkt->cookie;
  505 
  506                         p_ll2_conn->cbs.rx_release_cb(p_ll2_conn->cbs.cookie,
  507                                                       p_ll2_conn->my_id,
  508                                                       cookie,
  509                                                       rx_buf_addr,
  510                                                       b_last);
  511                 }
  512                 OSAL_SPIN_LOCK_IRQSAVE(&p_rx->lock, flags);
  513         }
  514         OSAL_SPIN_UNLOCK_IRQSAVE(&p_rx->lock, flags);
  515 }
  516 
  517 static bool
  518 ecore_ll2_lb_rxq_handler_slowpath(struct ecore_hwfn *p_hwfn,
  519                                   struct core_rx_slow_path_cqe *p_cqe)
  520 {
  521         struct ooo_opaque *iscsi_ooo;
  522         u32 cid;
  523 
  524         if (p_cqe->ramrod_cmd_id != CORE_RAMROD_RX_QUEUE_FLUSH)
  525                 return false;
  526 
  527         iscsi_ooo = (struct ooo_opaque *)&p_cqe->opaque_data;
  528         if (iscsi_ooo->ooo_opcode != TCP_EVENT_DELETE_ISLES)
  529                 return false;
  530 
  531         /* Need to make a flush */
  532         cid = OSAL_LE32_TO_CPU(iscsi_ooo->cid);
  533         ecore_ooo_release_connection_isles(p_hwfn->p_ooo_info, cid);
  534 
  535         return true;
  536 }
  537 
  538 static enum _ecore_status_t
  539 ecore_ll2_lb_rxq_handler(struct ecore_hwfn *p_hwfn,
  540                          struct ecore_ll2_info *p_ll2_conn)
  541 {
  542         struct ecore_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue;
  543         u16 packet_length = 0, parse_flags = 0, vlan = 0;
  544         struct ecore_ll2_rx_packet *p_pkt = OSAL_NULL;
  545         u32 num_ooo_add_to_peninsula = 0, cid;
  546         union core_rx_cqe_union *cqe = OSAL_NULL;
  547         u16 cq_new_idx = 0, cq_old_idx = 0;
  548         struct ecore_ooo_buffer *p_buffer;
  549         struct ooo_opaque *iscsi_ooo;
  550         u8 placement_offset = 0;
  551         u8 cqe_type;
  552 
  553         cq_new_idx = OSAL_LE16_TO_CPU(*p_rx->p_fw_cons);
  554         cq_old_idx = ecore_chain_get_cons_idx(&p_rx->rcq_chain);
  555         if (cq_new_idx == cq_old_idx)
  556                 return ECORE_SUCCESS;
  557 
  558         while (cq_new_idx != cq_old_idx) {
  559                 struct core_rx_fast_path_cqe *p_cqe_fp;
  560 
  561                 cqe = (union core_rx_cqe_union *)ecore_chain_consume(&p_rx->rcq_chain);
  562                 cq_old_idx = ecore_chain_get_cons_idx(&p_rx->rcq_chain);
  563                 cqe_type = cqe->rx_cqe_sp.type;
  564 
  565                 if (cqe_type == CORE_RX_CQE_TYPE_SLOW_PATH)
  566                         if (ecore_ll2_lb_rxq_handler_slowpath(p_hwfn,
  567                                                               &cqe->rx_cqe_sp))
  568                                 continue;
  569 
  570                 if (cqe_type != CORE_RX_CQE_TYPE_REGULAR) {
  571                         DP_NOTICE(p_hwfn, true,
  572                                   "Got a non-regular LB LL2 completion [type 0x%02x]\n",
  573                                   cqe_type);
  574                         return ECORE_INVAL;
  575                 }
  576                 p_cqe_fp = &cqe->rx_cqe_fp;
  577 
  578                 placement_offset = p_cqe_fp->placement_offset;
  579                 parse_flags = OSAL_LE16_TO_CPU(p_cqe_fp->parse_flags.flags);
  580                 packet_length = OSAL_LE16_TO_CPU(p_cqe_fp->packet_length);
  581                 vlan = OSAL_LE16_TO_CPU(p_cqe_fp->vlan);
  582                 iscsi_ooo = (struct ooo_opaque *)&p_cqe_fp->opaque_data;
  583                 ecore_ooo_save_history_entry(p_hwfn->p_ooo_info, iscsi_ooo);
  584                 cid = OSAL_LE32_TO_CPU(iscsi_ooo->cid);
  585 
  586                 /* Process delete isle first*/
  587                 if (iscsi_ooo->drop_size)
  588                         ecore_ooo_delete_isles(p_hwfn, p_hwfn->p_ooo_info, cid,
  589                                                iscsi_ooo->drop_isle,
  590                                                iscsi_ooo->drop_size);
  591 
  592                 if (iscsi_ooo->ooo_opcode == TCP_EVENT_NOP)
  593                         continue;
  594 
  595                 /* Now process create/add/join isles */
  596                 if (OSAL_LIST_IS_EMPTY(&p_rx->active_descq)) {
  597                         DP_NOTICE(p_hwfn, true,
  598                                   "LL2 OOO RX chain has no submitted buffers\n");
  599                         return ECORE_IO;
  600                 }
  601 
  602                 p_pkt = OSAL_LIST_FIRST_ENTRY(&p_rx->active_descq,
  603                                               struct ecore_ll2_rx_packet,
  604                                               list_entry);
  605 
  606                 if ((iscsi_ooo->ooo_opcode == TCP_EVENT_ADD_NEW_ISLE) ||
  607                     (iscsi_ooo->ooo_opcode == TCP_EVENT_ADD_ISLE_RIGHT) ||
  608                     (iscsi_ooo->ooo_opcode == TCP_EVENT_ADD_ISLE_LEFT) ||
  609                     (iscsi_ooo->ooo_opcode == TCP_EVENT_ADD_PEN) ||
  610                     (iscsi_ooo->ooo_opcode == TCP_EVENT_JOIN)) {
  611                         if (!p_pkt) {
  612                                 DP_NOTICE(p_hwfn, true,
  613                                           "LL2 OOO RX packet is not valid\n");
  614                                 return ECORE_IO;
  615                         }
  616 #if defined(_NTDDK_)
  617 #pragma warning(suppress : 6011 28182)
  618 #endif
  619                         OSAL_LIST_REMOVE_ENTRY(&p_pkt->list_entry,
  620                                                &p_rx->active_descq);
  621                         p_buffer = (struct ecore_ooo_buffer *)p_pkt->cookie;
  622                         p_buffer->packet_length = packet_length;
  623                         p_buffer->parse_flags = parse_flags;
  624                         p_buffer->vlan = vlan;
  625                         p_buffer->placement_offset = placement_offset;
  626                         if (ecore_chain_consume(&p_rx->rxq_chain) !=
  627                             p_pkt->rxq_bd) {
  628                                 /**/
  629                         }
  630                         ecore_ooo_dump_rx_event(p_hwfn, iscsi_ooo, p_buffer);
  631                         OSAL_LIST_PUSH_TAIL(&p_pkt->list_entry,
  632                                             &p_rx->free_descq);
  633 
  634                         switch (iscsi_ooo->ooo_opcode) {
  635                         case TCP_EVENT_ADD_NEW_ISLE:
  636                                 ecore_ooo_add_new_isle(p_hwfn,
  637                                                        p_hwfn->p_ooo_info,
  638                                                        cid,
  639                                                        iscsi_ooo->ooo_isle,
  640                                                        p_buffer);
  641                                 break;
  642                         case TCP_EVENT_ADD_ISLE_RIGHT:
  643                                 ecore_ooo_add_new_buffer(p_hwfn,
  644                                                          p_hwfn->p_ooo_info,
  645                                                          cid,
  646                                                          iscsi_ooo->ooo_isle,
  647                                                          p_buffer,
  648                                                          ECORE_OOO_RIGHT_BUF);
  649                                 break;
  650                         case TCP_EVENT_ADD_ISLE_LEFT:
  651                                 ecore_ooo_add_new_buffer(p_hwfn,
  652                                                          p_hwfn->p_ooo_info,
  653                                                          cid,
  654                                                          iscsi_ooo->ooo_isle,
  655                                                          p_buffer,
  656                                                          ECORE_OOO_LEFT_BUF);
  657                                 break;
  658                         case TCP_EVENT_JOIN:
  659                                 ecore_ooo_add_new_buffer(p_hwfn,
  660                                                          p_hwfn->p_ooo_info,
  661                                                          cid,
  662                                                          iscsi_ooo->ooo_isle +
  663                                                          1,
  664                                                          p_buffer,
  665                                                          ECORE_OOO_LEFT_BUF);
  666                                 ecore_ooo_join_isles(p_hwfn,
  667                                                      p_hwfn->p_ooo_info,
  668                                                      cid,
  669                                                      iscsi_ooo->ooo_isle);
  670                                 break;
  671                         case TCP_EVENT_ADD_PEN:
  672                                 num_ooo_add_to_peninsula++;
  673                                 ecore_ooo_put_ready_buffer(p_hwfn->p_ooo_info,
  674                                                            p_buffer, true);
  675                                 break;
  676                         }
  677                 } else {
  678                         DP_NOTICE(p_hwfn, true,
  679                                   "Unexpected event (%d) TX OOO completion\n",
  680                                   iscsi_ooo->ooo_opcode);
  681                 }
  682         }
  683 
  684         return ECORE_SUCCESS;
  685 }
  686 
  687 static void
  688 ecore_ooo_submit_tx_buffers(struct ecore_hwfn *p_hwfn,
  689                             struct ecore_ll2_info *p_ll2_conn)
  690 {
  691         struct ecore_ll2_tx_pkt_info tx_pkt;
  692         struct ecore_ooo_buffer *p_buffer;
  693         dma_addr_t first_frag;
  694         u16 l4_hdr_offset_w;
  695         u8 bd_flags;
  696         enum _ecore_status_t rc;
  697 
  698         /* Submit Tx buffers here */
  699         while ((p_buffer = ecore_ooo_get_ready_buffer(p_hwfn->p_ooo_info))) {
  700                 l4_hdr_offset_w = 0;
  701                 bd_flags = 0;
  702 
  703                 first_frag = p_buffer->rx_buffer_phys_addr +
  704                              p_buffer->placement_offset;
  705                 SET_FIELD(bd_flags, CORE_TX_BD_DATA_FORCE_VLAN_MODE, 1);
  706                 SET_FIELD(bd_flags, CORE_TX_BD_DATA_L4_PROTOCOL, 1);
  707 
  708                 OSAL_MEM_ZERO(&tx_pkt, sizeof(tx_pkt));
  709                 tx_pkt.num_of_bds = 1;
  710                 tx_pkt.vlan = p_buffer->vlan;
  711                 tx_pkt.bd_flags = bd_flags;
  712                 tx_pkt.l4_hdr_offset_w = l4_hdr_offset_w;
  713                 tx_pkt.tx_dest = (enum ecore_ll2_tx_dest)p_ll2_conn->tx_dest;
  714                 tx_pkt.first_frag = first_frag;
  715                 tx_pkt.first_frag_len = p_buffer->packet_length;
  716                 tx_pkt.cookie = p_buffer;
  717 
  718                 rc = ecore_ll2_prepare_tx_packet(p_hwfn, p_ll2_conn->my_id,
  719                                                  &tx_pkt, true);
  720                 if (rc != ECORE_SUCCESS) {
  721                         ecore_ooo_put_ready_buffer(p_hwfn->p_ooo_info,
  722                                                    p_buffer, false);
  723                         break;
  724                 }
  725         }
  726 }
  727 
  728 static void
  729 ecore_ooo_submit_rx_buffers(struct ecore_hwfn *p_hwfn,
  730                             struct ecore_ll2_info *p_ll2_conn)
  731 {
  732         struct ecore_ooo_buffer *p_buffer;
  733         enum _ecore_status_t rc;
  734 
  735         while ((p_buffer = ecore_ooo_get_free_buffer(p_hwfn->p_ooo_info))) {
  736                 rc = ecore_ll2_post_rx_buffer(p_hwfn,
  737                                             p_ll2_conn->my_id,
  738                                             p_buffer->rx_buffer_phys_addr,
  739                                             0, p_buffer, true);
  740                 if (rc != ECORE_SUCCESS) {
  741                         ecore_ooo_put_free_buffer(p_hwfn->p_ooo_info, p_buffer);
  742                         break;
  743                 }
  744         }
  745 }
  746 
  747 static enum _ecore_status_t
  748 ecore_ll2_lb_rxq_completion(struct ecore_hwfn *p_hwfn,
  749                             void *p_cookie)
  750 {
  751         struct ecore_ll2_info *p_ll2_conn = (struct ecore_ll2_info *)p_cookie;
  752         enum _ecore_status_t rc;
  753 
  754         rc = ecore_ll2_lb_rxq_handler(p_hwfn, p_ll2_conn);
  755         if (rc != ECORE_SUCCESS)
  756                 return rc;
  757 
  758         ecore_ooo_submit_rx_buffers(p_hwfn, p_ll2_conn);
  759         ecore_ooo_submit_tx_buffers(p_hwfn, p_ll2_conn);
  760 
  761         return 0;
  762 }
  763 
  764 static enum _ecore_status_t
  765 ecore_ll2_lb_txq_completion(struct ecore_hwfn *p_hwfn,
  766                             void *p_cookie)
  767 {
  768         struct ecore_ll2_info *p_ll2_conn = (struct ecore_ll2_info *)p_cookie;
  769         struct ecore_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
  770         struct ecore_ll2_tx_packet *p_pkt = OSAL_NULL;
  771         struct ecore_ooo_buffer *p_buffer;
  772         bool b_dont_submit_rx = false;
  773         u16 new_idx = 0, num_bds = 0;
  774         enum _ecore_status_t rc;
  775 
  776         new_idx = OSAL_LE16_TO_CPU(*p_tx->p_fw_cons);
  777         num_bds = ((s16)new_idx - (s16)p_tx->bds_idx);
  778 
  779         if (!num_bds)
  780                 return ECORE_SUCCESS;
  781 
  782         while (num_bds) {
  783                 if (OSAL_LIST_IS_EMPTY(&p_tx->active_descq))
  784                         return ECORE_INVAL;
  785 
  786                 p_pkt = OSAL_LIST_FIRST_ENTRY(&p_tx->active_descq,
  787                                               struct ecore_ll2_tx_packet,
  788                                               list_entry);
  789                 if (!p_pkt)
  790                         return ECORE_INVAL;
  791 
  792                 if (p_pkt->bd_used != 1) {
  793                         DP_NOTICE(p_hwfn, true,
  794                                   "Unexpectedly many BDs(%d) in TX OOO completion\n",
  795                                   p_pkt->bd_used);
  796                         return ECORE_INVAL;
  797                 }
  798 
  799                 OSAL_LIST_REMOVE_ENTRY(&p_pkt->list_entry,
  800                                        &p_tx->active_descq);
  801 
  802                 num_bds--;
  803                 p_tx->bds_idx++;
  804                 ecore_chain_consume(&p_tx->txq_chain);
  805 
  806                 p_buffer = (struct ecore_ooo_buffer *)p_pkt->cookie;
  807                 OSAL_LIST_PUSH_TAIL(&p_pkt->list_entry,
  808                                     &p_tx->free_descq);
  809 
  810                 if (b_dont_submit_rx) {
  811                         ecore_ooo_put_free_buffer(p_hwfn->p_ooo_info, p_buffer);
  812                         continue;
  813                 }
  814 
  815                 rc = ecore_ll2_post_rx_buffer(p_hwfn, p_ll2_conn->my_id,
  816                                               p_buffer->rx_buffer_phys_addr, 0,
  817                                               p_buffer, true);
  818                 if (rc != ECORE_SUCCESS) {
  819                         ecore_ooo_put_free_buffer(p_hwfn->p_ooo_info, p_buffer);
  820                         b_dont_submit_rx = true;
  821                 }
  822         }
  823 
  824         ecore_ooo_submit_tx_buffers(p_hwfn, p_ll2_conn);
  825 
  826         return ECORE_SUCCESS;
  827 }
  828 
  829 static enum _ecore_status_t ecore_sp_ll2_rx_queue_start(struct ecore_hwfn *p_hwfn,
  830                                                         struct ecore_ll2_info *p_ll2_conn,
  831                                                         u8 action_on_error)
  832 {
  833         enum ecore_ll2_conn_type conn_type = p_ll2_conn->input.conn_type;
  834         struct ecore_ll2_rx_queue *p_rx = &p_ll2_conn->rx_queue;
  835         struct core_rx_start_ramrod_data *p_ramrod = OSAL_NULL;
  836         struct ecore_spq_entry *p_ent = OSAL_NULL;
  837         struct ecore_sp_init_data init_data;
  838         u16 cqe_pbl_size;
  839         enum _ecore_status_t rc = ECORE_SUCCESS;
  840 
  841         /* Get SPQ entry */
  842         OSAL_MEMSET(&init_data, 0, sizeof(init_data));
  843         init_data.cid = p_ll2_conn->cid;
  844         init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
  845         init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
  846 
  847         rc = ecore_sp_init_request(p_hwfn, &p_ent,
  848                                    CORE_RAMROD_RX_QUEUE_START,
  849                                    PROTOCOLID_CORE, &init_data);
  850         if (rc != ECORE_SUCCESS)
  851                 return rc;
  852 
  853         p_ramrod = &p_ent->ramrod.core_rx_queue_start;
  854 
  855         p_ramrod->sb_id = OSAL_CPU_TO_LE16(ecore_int_get_sp_sb_id(p_hwfn));
  856         p_ramrod->sb_index = p_rx->rx_sb_index;
  857         p_ramrod->complete_event_flg = 1;
  858 
  859         p_ramrod->mtu = OSAL_CPU_TO_LE16(p_ll2_conn->input.mtu);
  860         DMA_REGPAIR_LE(p_ramrod->bd_base,
  861                        p_rx->rxq_chain.p_phys_addr);
  862         cqe_pbl_size = (u16)ecore_chain_get_page_cnt(&p_rx->rcq_chain);
  863         p_ramrod->num_of_pbl_pages = OSAL_CPU_TO_LE16(cqe_pbl_size);
  864         DMA_REGPAIR_LE(p_ramrod->cqe_pbl_addr,
  865                        ecore_chain_get_pbl_phys(&p_rx->rcq_chain));
  866 
  867         p_ramrod->drop_ttl0_flg = p_ll2_conn->input.rx_drop_ttl0_flg;
  868         p_ramrod->inner_vlan_stripping_en =
  869                 p_ll2_conn->input.rx_vlan_removal_en;
  870 
  871         if (OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC, &p_hwfn->p_dev->mf_bits) &&
  872             (p_ll2_conn->input.conn_type == ECORE_LL2_TYPE_FCOE))
  873                 p_ramrod->report_outer_vlan = 1;
  874         p_ramrod->queue_id = p_ll2_conn->queue_id;
  875         p_ramrod->main_func_queue = p_ll2_conn->main_func_queue;
  876 
  877         if (OSAL_TEST_BIT(ECORE_MF_LL2_NON_UNICAST,
  878                           &p_hwfn->p_dev->mf_bits) &&
  879             p_ramrod->main_func_queue &&
  880             ((conn_type != ECORE_LL2_TYPE_ROCE) &&
  881              (conn_type != ECORE_LL2_TYPE_IWARP))) {
  882                 p_ramrod->mf_si_bcast_accept_all = 1;
  883                 p_ramrod->mf_si_mcast_accept_all = 1;
  884         } else {
  885                 p_ramrod->mf_si_bcast_accept_all = 0;
  886                 p_ramrod->mf_si_mcast_accept_all = 0;
  887         }
  888 
  889         p_ramrod->action_on_error.error_type = action_on_error;
  890         p_ramrod->gsi_offload_flag = p_ll2_conn->input.gsi_enable;
  891         return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
  892 }
  893 
  894 static enum _ecore_status_t ecore_sp_ll2_tx_queue_start(struct ecore_hwfn *p_hwfn,
  895                                                         struct ecore_ll2_info *p_ll2_conn)
  896 {
  897         enum ecore_ll2_conn_type conn_type = p_ll2_conn->input.conn_type;
  898         struct ecore_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
  899         struct core_tx_start_ramrod_data *p_ramrod = OSAL_NULL;
  900         struct ecore_spq_entry *p_ent = OSAL_NULL;
  901         struct ecore_sp_init_data init_data;
  902         u16 pq_id = 0, pbl_size;
  903         enum _ecore_status_t rc = ECORE_NOTIMPL;
  904 
  905         if (!ECORE_LL2_TX_REGISTERED(p_ll2_conn))
  906                 return ECORE_SUCCESS;
  907 
  908         if (p_ll2_conn->input.conn_type == ECORE_LL2_TYPE_OOO)
  909                 p_ll2_conn->tx_stats_en = 0;
  910         else
  911                 p_ll2_conn->tx_stats_en = 1;
  912 
  913         /* Get SPQ entry */
  914         OSAL_MEMSET(&init_data, 0, sizeof(init_data));
  915         init_data.cid = p_ll2_conn->cid;
  916         init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
  917         init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
  918 
  919         rc = ecore_sp_init_request(p_hwfn, &p_ent,
  920                                    CORE_RAMROD_TX_QUEUE_START,
  921                                    PROTOCOLID_CORE, &init_data);
  922         if (rc != ECORE_SUCCESS)
  923                 return rc;
  924 
  925         p_ramrod = &p_ent->ramrod.core_tx_queue_start;
  926 
  927         p_ramrod->sb_id = OSAL_CPU_TO_LE16(ecore_int_get_sp_sb_id(p_hwfn));
  928         p_ramrod->sb_index = p_tx->tx_sb_index;
  929         p_ramrod->mtu = OSAL_CPU_TO_LE16(p_ll2_conn->input.mtu);
  930         p_ramrod->stats_en = p_ll2_conn->tx_stats_en;
  931         p_ramrod->stats_id = p_ll2_conn->tx_stats_id;
  932 
  933         DMA_REGPAIR_LE(p_ramrod->pbl_base_addr,
  934                        ecore_chain_get_pbl_phys(&p_tx->txq_chain));
  935         pbl_size = (u16)ecore_chain_get_page_cnt(&p_tx->txq_chain);
  936         p_ramrod->pbl_size = OSAL_CPU_TO_LE16(pbl_size);
  937 
  938         /* TODO RESC_ALLOC pq for ll2 */
  939         switch (p_ll2_conn->input.tx_tc) {
  940         case PURE_LB_TC:
  941                 pq_id = ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_LB);
  942                 break;
  943         case PKT_LB_TC:
  944                 pq_id = ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_OOO);
  945                 break;
  946         default:
  947                 pq_id = ecore_get_cm_pq_idx(p_hwfn, PQ_FLAGS_OFLD);
  948         }
  949 
  950         p_ramrod->qm_pq_id = OSAL_CPU_TO_LE16(pq_id);
  951 
  952         switch (conn_type) {
  953         case ECORE_LL2_TYPE_FCOE:
  954                 p_ramrod->conn_type = PROTOCOLID_FCOE;
  955                 break;
  956         case ECORE_LL2_TYPE_ISCSI:
  957                 p_ramrod->conn_type = PROTOCOLID_ISCSI;
  958                 break;
  959         case ECORE_LL2_TYPE_ROCE:
  960                 p_ramrod->conn_type = PROTOCOLID_ROCE;
  961                 break;
  962         case ECORE_LL2_TYPE_IWARP:
  963                 p_ramrod->conn_type = PROTOCOLID_IWARP;
  964                 break;
  965         case ECORE_LL2_TYPE_OOO:
  966                 if (p_hwfn->hw_info.personality == ECORE_PCI_ISCSI) {
  967                         p_ramrod->conn_type = PROTOCOLID_ISCSI;
  968                 } else {
  969                         p_ramrod->conn_type = PROTOCOLID_IWARP;
  970                 }
  971                 break;
  972         default:
  973                 p_ramrod->conn_type = PROTOCOLID_ETH;
  974                 DP_NOTICE(p_hwfn, false, "Unknown connection type: %d\n",
  975                           conn_type);
  976         }
  977 
  978         p_ramrod->gsi_offload_flag = p_ll2_conn->input.gsi_enable;
  979 
  980         rc = ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
  981         if (rc != ECORE_SUCCESS)
  982                 return rc;
  983 
  984         rc = ecore_db_recovery_add(p_hwfn->p_dev, p_tx->doorbell_addr,
  985                                    &p_tx->db_msg, DB_REC_WIDTH_32B,
  986                                    DB_REC_KERNEL);
  987         return rc;
  988 }
  989 
  990 static enum _ecore_status_t ecore_sp_ll2_rx_queue_stop(struct ecore_hwfn *p_hwfn,
  991                                                        struct ecore_ll2_info *p_ll2_conn)
  992 {
  993         struct core_rx_stop_ramrod_data *p_ramrod = OSAL_NULL;
  994         struct ecore_spq_entry *p_ent = OSAL_NULL;
  995         struct ecore_sp_init_data init_data;
  996         enum _ecore_status_t rc = ECORE_NOTIMPL;
  997 
  998         /* Get SPQ entry */
  999         OSAL_MEMSET(&init_data, 0, sizeof(init_data));
 1000         init_data.cid = p_ll2_conn->cid;
 1001         init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
 1002         init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
 1003 
 1004         rc = ecore_sp_init_request(p_hwfn, &p_ent,
 1005                                    CORE_RAMROD_RX_QUEUE_STOP,
 1006                                    PROTOCOLID_CORE, &init_data);
 1007         if (rc != ECORE_SUCCESS)
 1008                 return rc;
 1009 
 1010         p_ramrod = &p_ent->ramrod.core_rx_queue_stop;
 1011 
 1012         p_ramrod->complete_event_flg = 1;
 1013         p_ramrod->queue_id = p_ll2_conn->queue_id;
 1014 
 1015         return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
 1016 }
 1017 
 1018 static enum _ecore_status_t ecore_sp_ll2_tx_queue_stop(struct ecore_hwfn *p_hwfn,
 1019                                                        struct ecore_ll2_info *p_ll2_conn)
 1020 {
 1021         struct ecore_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
 1022         struct ecore_spq_entry *p_ent = OSAL_NULL;
 1023         struct ecore_sp_init_data init_data;
 1024         enum _ecore_status_t rc = ECORE_NOTIMPL;
 1025 
 1026         ecore_db_recovery_del(p_hwfn->p_dev, p_tx->doorbell_addr,
 1027                               &p_tx->db_msg);
 1028 
 1029         /* Get SPQ entry */
 1030         OSAL_MEMSET(&init_data, 0, sizeof(init_data));
 1031         init_data.cid = p_ll2_conn->cid;
 1032         init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
 1033         init_data.comp_mode = ECORE_SPQ_MODE_EBLOCK;
 1034 
 1035         rc = ecore_sp_init_request(p_hwfn, &p_ent,
 1036                                    CORE_RAMROD_TX_QUEUE_STOP,
 1037                                    PROTOCOLID_CORE, &init_data);
 1038         if (rc != ECORE_SUCCESS)
 1039                 return rc;
 1040 
 1041         return ecore_spq_post(p_hwfn, p_ent, OSAL_NULL);
 1042 }
 1043 
 1044 static enum _ecore_status_t
 1045 ecore_ll2_acquire_connection_rx(struct ecore_hwfn *p_hwfn,
 1046                                 struct ecore_ll2_info *p_ll2_info)
 1047 {
 1048         struct ecore_ll2_rx_packet *p_descq;
 1049         u32 capacity;
 1050         enum _ecore_status_t rc = ECORE_SUCCESS;
 1051 
 1052         if (!p_ll2_info->input.rx_num_desc)
 1053                 goto out;
 1054 
 1055         rc = ecore_chain_alloc(p_hwfn->p_dev,
 1056                                ECORE_CHAIN_USE_TO_CONSUME_PRODUCE,
 1057                                ECORE_CHAIN_MODE_NEXT_PTR,
 1058                                ECORE_CHAIN_CNT_TYPE_U16,
 1059                                p_ll2_info->input.rx_num_desc,
 1060                                sizeof(struct core_rx_bd),
 1061                                &p_ll2_info->rx_queue.rxq_chain, OSAL_NULL);
 1062         if (rc) {
 1063                 DP_NOTICE(p_hwfn, false,
 1064                           "Failed to allocate ll2 rxq chain\n");
 1065                 goto out;
 1066         }
 1067 
 1068         capacity = ecore_chain_get_capacity(&p_ll2_info->rx_queue.rxq_chain);
 1069         p_descq = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
 1070                               capacity * sizeof(struct ecore_ll2_rx_packet));
 1071         if (!p_descq) {
 1072                 rc = ECORE_NOMEM;
 1073                 DP_NOTICE(p_hwfn, false,
 1074                           "Failed to allocate ll2 Rx desc\n");
 1075                 goto out;
 1076         }
 1077         p_ll2_info->rx_queue.descq_array = p_descq;
 1078 
 1079         rc = ecore_chain_alloc(p_hwfn->p_dev,
 1080                                ECORE_CHAIN_USE_TO_CONSUME_PRODUCE,
 1081                                ECORE_CHAIN_MODE_PBL,
 1082                                ECORE_CHAIN_CNT_TYPE_U16,
 1083                                p_ll2_info->input.rx_num_desc,
 1084                                sizeof(struct core_rx_fast_path_cqe),
 1085                                &p_ll2_info->rx_queue.rcq_chain, OSAL_NULL);
 1086         if (rc != ECORE_SUCCESS) {
 1087                 DP_NOTICE(p_hwfn, false,
 1088                           "Failed to allocate ll2 rcq chain\n");
 1089                 goto out;
 1090         }
 1091 
 1092         DP_VERBOSE(p_hwfn, ECORE_MSG_LL2,
 1093                    "Allocated LL2 Rxq [Type %08x] with 0x%08x buffers\n",
 1094                    p_ll2_info->input.conn_type,
 1095                    p_ll2_info->input.rx_num_desc);
 1096 
 1097 out:
 1098         return rc;
 1099 }
 1100 
 1101 static enum _ecore_status_t
 1102 ecore_ll2_acquire_connection_tx(struct ecore_hwfn *p_hwfn,
 1103                                 struct ecore_ll2_info *p_ll2_info)
 1104 {
 1105         struct ecore_ll2_tx_packet *p_descq;
 1106         u32 capacity;
 1107         enum _ecore_status_t rc = ECORE_SUCCESS;
 1108         u32 desc_size;
 1109 
 1110         if (!p_ll2_info->input.tx_num_desc)
 1111                 goto out;
 1112 
 1113         rc = ecore_chain_alloc(p_hwfn->p_dev,
 1114                                ECORE_CHAIN_USE_TO_CONSUME_PRODUCE,
 1115                                ECORE_CHAIN_MODE_PBL,
 1116                                ECORE_CHAIN_CNT_TYPE_U16,
 1117                                p_ll2_info->input.tx_num_desc,
 1118                                sizeof(struct core_tx_bd),
 1119                                &p_ll2_info->tx_queue.txq_chain, OSAL_NULL);
 1120         if (rc != ECORE_SUCCESS)
 1121                 goto out;
 1122 
 1123         capacity = ecore_chain_get_capacity(&p_ll2_info->tx_queue.txq_chain);
 1124         desc_size = (sizeof(*p_descq) +
 1125                      (p_ll2_info->input.tx_max_bds_per_packet - 1) *
 1126                      sizeof(p_descq->bds_set));
 1127 
 1128         p_descq = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
 1129                               capacity * desc_size);
 1130         if (!p_descq) {
 1131                 rc = ECORE_NOMEM;
 1132                 goto out;
 1133         }
 1134         p_ll2_info->tx_queue.descq_array = p_descq;
 1135 
 1136         DP_VERBOSE(p_hwfn, ECORE_MSG_LL2,
 1137                    "Allocated LL2 Txq [Type %08x] with 0x%08x buffers\n",
 1138                    p_ll2_info->input.conn_type,
 1139                    p_ll2_info->input.tx_num_desc);
 1140 
 1141 out:
 1142         if (rc != ECORE_SUCCESS)
 1143                 DP_NOTICE(p_hwfn, false,
 1144                           "Can't allocate memory for Tx LL2 with 0x%08x buffers\n",
 1145                           p_ll2_info->input.tx_num_desc);
 1146         return rc;
 1147 }
 1148 
 1149 static enum _ecore_status_t
 1150 ecore_ll2_acquire_connection_ooo(struct ecore_hwfn *p_hwfn,
 1151                                  struct ecore_ll2_info *p_ll2_info, u16 mtu)
 1152 {
 1153         struct ecore_ooo_buffer *p_buf = OSAL_NULL;
 1154         u32 rx_buffer_size = 0;
 1155         void *p_virt;
 1156         u16 buf_idx;
 1157         enum _ecore_status_t rc = ECORE_SUCCESS;
 1158 
 1159         if (p_ll2_info->input.conn_type != ECORE_LL2_TYPE_OOO)
 1160                 return rc;
 1161 
 1162         /* Correct number of requested OOO buffers if needed */
 1163         if (!p_ll2_info->input.rx_num_ooo_buffers) {
 1164                 u16 num_desc = p_ll2_info->input.rx_num_desc;
 1165 
 1166                 if (!num_desc)
 1167                         return ECORE_INVAL;
 1168                 p_ll2_info->input.rx_num_ooo_buffers = num_desc * 2;
 1169         }
 1170 
 1171         /* TODO - use some defines for buffer size */
 1172         rx_buffer_size = mtu + 14 + 4 + 8 + ETH_CACHE_LINE_SIZE;
 1173         rx_buffer_size = (rx_buffer_size + ETH_CACHE_LINE_SIZE - 1) &
 1174                          ~(ETH_CACHE_LINE_SIZE - 1);
 1175 
 1176         for (buf_idx = 0; buf_idx < p_ll2_info->input.rx_num_ooo_buffers;
 1177              buf_idx++) {
 1178                 p_buf = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, sizeof(*p_buf));
 1179                 if (!p_buf) {
 1180                         DP_NOTICE(p_hwfn, false,
 1181                                   "Failed to allocate ooo descriptor\n");
 1182                         rc = ECORE_NOMEM;
 1183                         goto out;
 1184                 }
 1185 
 1186                 p_buf->rx_buffer_size = rx_buffer_size;
 1187                 p_virt = OSAL_DMA_ALLOC_COHERENT(p_hwfn->p_dev,
 1188                                                  &p_buf->rx_buffer_phys_addr,
 1189                                                  p_buf->rx_buffer_size);
 1190                 if (!p_virt) {
 1191                         DP_NOTICE(p_hwfn, false,
 1192                                   "Failed to allocate ooo buffer\n");
 1193                         OSAL_FREE(p_hwfn->p_dev, p_buf);
 1194                         rc = ECORE_NOMEM;
 1195                         goto out;
 1196                 }
 1197                 p_buf->rx_buffer_virt_addr = p_virt;
 1198                 ecore_ooo_put_free_buffer(p_hwfn->p_ooo_info, p_buf);
 1199         }
 1200 
 1201         DP_VERBOSE(p_hwfn, ECORE_MSG_LL2,
 1202                    "Allocated [%04x] LL2 OOO buffers [each of size 0x%08x]\n",
 1203                    p_ll2_info->input.rx_num_ooo_buffers, rx_buffer_size);
 1204 
 1205 out:
 1206         return rc;
 1207 }
 1208 
 1209 static enum _ecore_status_t
 1210 ecore_ll2_set_cbs(struct ecore_ll2_info *p_ll2_info,
 1211                     const struct ecore_ll2_cbs *cbs)
 1212 {
 1213         if (!cbs || (!cbs->rx_comp_cb ||
 1214                      !cbs->rx_release_cb ||
 1215                      !cbs->tx_comp_cb ||
 1216                      !cbs->tx_release_cb ||
 1217                      !cbs->cookie))
 1218                 return ECORE_INVAL;
 1219 
 1220         p_ll2_info->cbs.rx_comp_cb = cbs->rx_comp_cb;
 1221         p_ll2_info->cbs.rx_release_cb = cbs->rx_release_cb;
 1222         p_ll2_info->cbs.tx_comp_cb = cbs->tx_comp_cb;
 1223         p_ll2_info->cbs.tx_release_cb = cbs->tx_release_cb;
 1224         p_ll2_info->cbs.slowpath_cb = cbs->slowpath_cb;
 1225         p_ll2_info->cbs.cookie = cbs->cookie;
 1226 
 1227         return ECORE_SUCCESS;
 1228 }
 1229 
 1230 static enum core_error_handle
 1231 ecore_ll2_get_error_choice(enum ecore_ll2_error_handle err)
 1232 {
 1233         switch (err) {
 1234         case ECORE_LL2_DROP_PACKET:
 1235                 return LL2_DROP_PACKET;
 1236         case ECORE_LL2_DO_NOTHING:
 1237                 return LL2_DO_NOTHING;
 1238         case ECORE_LL2_ASSERT:
 1239                 return LL2_ASSERT;
 1240         default:
 1241                 return LL2_DO_NOTHING;
 1242         }
 1243 }
 1244 
 1245 enum _ecore_status_t
 1246 ecore_ll2_acquire_connection(void *cxt,
 1247                              struct ecore_ll2_acquire_data *data)
 1248 {
 1249         struct ecore_hwfn *p_hwfn = (struct ecore_hwfn *)cxt;
 1250         ecore_int_comp_cb_t comp_rx_cb, comp_tx_cb;
 1251         struct ecore_ll2_info *p_ll2_info = OSAL_NULL;
 1252         enum _ecore_status_t rc;
 1253         u8 i, *p_tx_max;
 1254 
 1255         if (!data->p_connection_handle || !p_hwfn->p_ll2_info) {
 1256                 DP_NOTICE(p_hwfn, false, "Invalid connection handle, ll2_info not allocated\n");
 1257                 return ECORE_INVAL;
 1258         }
 1259 
 1260         /* Find a free connection to be used */
 1261         for (i = 0; (i < ECORE_MAX_NUM_OF_LL2_CONNECTIONS); i++) {
 1262                 OSAL_MUTEX_ACQUIRE(&p_hwfn->p_ll2_info[i].mutex);
 1263                 if (p_hwfn->p_ll2_info[i].b_active) {
 1264                         OSAL_MUTEX_RELEASE(&p_hwfn->p_ll2_info[i].mutex);
 1265                         continue;
 1266                 }
 1267 
 1268                 p_hwfn->p_ll2_info[i].b_active = true;
 1269                 p_ll2_info = &p_hwfn->p_ll2_info[i];
 1270                 OSAL_MUTEX_RELEASE(&p_hwfn->p_ll2_info[i].mutex);
 1271                 break;
 1272         }
 1273         if (p_ll2_info == OSAL_NULL) {
 1274                 DP_NOTICE(p_hwfn, false, "No available ll2 connection\n");
 1275                 return ECORE_BUSY;
 1276         }
 1277 
 1278         OSAL_MEMCPY(&p_ll2_info->input, &data->input,
 1279                     sizeof(p_ll2_info->input));
 1280 
 1281         switch (data->input.tx_dest) {
 1282         case ECORE_LL2_TX_DEST_NW:
 1283                 p_ll2_info->tx_dest = CORE_TX_DEST_NW;
 1284                 break;
 1285         case ECORE_LL2_TX_DEST_LB:
 1286                 p_ll2_info->tx_dest = CORE_TX_DEST_LB;
 1287                 break;
 1288         case ECORE_LL2_TX_DEST_DROP:
 1289                 p_ll2_info->tx_dest = CORE_TX_DEST_DROP;
 1290                 break;
 1291         default:
 1292                 return ECORE_INVAL;
 1293         }
 1294 
 1295         if ((data->input.conn_type == ECORE_LL2_TYPE_OOO) ||
 1296             data->input.secondary_queue)
 1297                 p_ll2_info->main_func_queue = false;
 1298         else
 1299                 p_ll2_info->main_func_queue = true;
 1300 
 1301         /* Correct maximum number of Tx BDs */
 1302         p_tx_max = &p_ll2_info->input.tx_max_bds_per_packet;
 1303         if (*p_tx_max == 0)
 1304                 *p_tx_max = CORE_LL2_TX_MAX_BDS_PER_PACKET;
 1305         else
 1306                 *p_tx_max = OSAL_MIN_T(u8, *p_tx_max,
 1307                                        CORE_LL2_TX_MAX_BDS_PER_PACKET);
 1308 
 1309         rc = ecore_ll2_set_cbs(p_ll2_info, data->cbs);
 1310         if (rc) {
 1311                 DP_NOTICE(p_hwfn, false, "Invalid callback functions\n");
 1312                 goto q_allocate_fail;
 1313         }
 1314 
 1315         rc = ecore_ll2_acquire_connection_rx(p_hwfn, p_ll2_info);
 1316         if (rc != ECORE_SUCCESS) {
 1317                 DP_NOTICE(p_hwfn, false, "ll2 acquire rx connection failed\n");
 1318                 goto q_allocate_fail;
 1319         }
 1320 
 1321         rc = ecore_ll2_acquire_connection_tx(p_hwfn, p_ll2_info);
 1322         if (rc != ECORE_SUCCESS) {
 1323                 DP_NOTICE(p_hwfn, false, "ll2 acquire tx connection failed\n");
 1324                 goto q_allocate_fail;
 1325         }
 1326 
 1327         rc = ecore_ll2_acquire_connection_ooo(p_hwfn, p_ll2_info,
 1328                                               data->input.mtu);
 1329         if (rc != ECORE_SUCCESS) {
 1330                 DP_NOTICE(p_hwfn, false, "ll2 acquire ooo connection failed\n");
 1331                 goto q_allocate_fail;
 1332         }
 1333 
 1334         /* Register callbacks for the Rx/Tx queues */
 1335         if (data->input.conn_type == ECORE_LL2_TYPE_OOO) {
 1336                 comp_rx_cb = ecore_ll2_lb_rxq_completion;
 1337                 comp_tx_cb = ecore_ll2_lb_txq_completion;
 1338 
 1339         } else {
 1340                 comp_rx_cb = ecore_ll2_rxq_completion;
 1341                 comp_tx_cb = ecore_ll2_txq_completion;
 1342         }
 1343 
 1344         if (data->input.rx_num_desc) {
 1345                 ecore_int_register_cb(p_hwfn, comp_rx_cb,
 1346                                       &p_hwfn->p_ll2_info[i],
 1347                                       &p_ll2_info->rx_queue.rx_sb_index,
 1348                                       &p_ll2_info->rx_queue.p_fw_cons);
 1349                 p_ll2_info->rx_queue.b_cb_registred   = true;
 1350         }
 1351 
 1352         if (data->input.tx_num_desc) {
 1353                 ecore_int_register_cb(p_hwfn,
 1354                                       comp_tx_cb,
 1355                                       &p_hwfn->p_ll2_info[i],
 1356                                       &p_ll2_info->tx_queue.tx_sb_index,
 1357                                       &p_ll2_info->tx_queue.p_fw_cons);
 1358                 p_ll2_info->tx_queue.b_cb_registred   = true;
 1359         }
 1360 
 1361         *(data->p_connection_handle) = i;
 1362         return rc;
 1363 
 1364 q_allocate_fail:
 1365         ecore_ll2_release_connection(p_hwfn, i);
 1366         return ECORE_NOMEM;
 1367 }
 1368 
 1369 static enum _ecore_status_t ecore_ll2_establish_connection_rx(struct ecore_hwfn *p_hwfn,
 1370                                                               struct ecore_ll2_info *p_ll2_conn)
 1371 {
 1372         enum ecore_ll2_error_handle error_input;
 1373         enum core_error_handle error_mode;
 1374         u8 action_on_error = 0;
 1375 
 1376         if (!ECORE_LL2_RX_REGISTERED(p_ll2_conn))
 1377                 return ECORE_SUCCESS;
 1378 
 1379         DIRECT_REG_WR(p_hwfn, p_ll2_conn->rx_queue.set_prod_addr, 0x0);
 1380         error_input = p_ll2_conn->input.ai_err_packet_too_big;
 1381         error_mode = ecore_ll2_get_error_choice(error_input);
 1382         SET_FIELD(action_on_error,
 1383                   CORE_RX_ACTION_ON_ERROR_PACKET_TOO_BIG, error_mode);
 1384         error_input = p_ll2_conn->input.ai_err_no_buf;
 1385         error_mode = ecore_ll2_get_error_choice(error_input);
 1386         SET_FIELD(action_on_error,
 1387                   CORE_RX_ACTION_ON_ERROR_NO_BUFF, error_mode);
 1388 
 1389         return ecore_sp_ll2_rx_queue_start(p_hwfn, p_ll2_conn, action_on_error);
 1390 }
 1391 
 1392 static void
 1393 ecore_ll2_establish_connection_ooo(struct ecore_hwfn *p_hwfn,
 1394                                    struct ecore_ll2_info *p_ll2_conn)
 1395 {
 1396         if (p_ll2_conn->input.conn_type != ECORE_LL2_TYPE_OOO)
 1397                 return;
 1398 
 1399         ecore_ooo_release_all_isles(p_hwfn->p_ooo_info);
 1400         ecore_ooo_submit_rx_buffers(p_hwfn, p_ll2_conn);
 1401 }
 1402 
 1403 enum _ecore_status_t ecore_ll2_establish_connection(void *cxt,
 1404                                                     u8 connection_handle)
 1405 {
 1406         struct ecore_hwfn *p_hwfn = (struct ecore_hwfn *)cxt;
 1407         struct e4_core_conn_context *p_cxt;
 1408         struct ecore_ll2_info *p_ll2_conn;
 1409         struct ecore_cxt_info cxt_info;
 1410         struct ecore_ll2_rx_queue *p_rx;
 1411         struct ecore_ll2_tx_queue *p_tx;
 1412         struct ecore_ll2_tx_packet *p_pkt;
 1413         struct ecore_ptt *p_ptt;
 1414         enum _ecore_status_t rc = ECORE_NOTIMPL;
 1415         u32 i, capacity;
 1416         u32 desc_size;
 1417         u8 qid;
 1418 
 1419         p_ptt = ecore_ptt_acquire(p_hwfn);
 1420         if (!p_ptt)
 1421                 return ECORE_AGAIN;
 1422 
 1423         p_ll2_conn = ecore_ll2_handle_sanity_lock(p_hwfn, connection_handle);
 1424         if (p_ll2_conn == OSAL_NULL) {
 1425                 rc = ECORE_INVAL;
 1426                 goto out;
 1427         }
 1428 
 1429         p_rx = &p_ll2_conn->rx_queue;
 1430         p_tx = &p_ll2_conn->tx_queue;
 1431 
 1432         ecore_chain_reset(&p_rx->rxq_chain);
 1433         ecore_chain_reset(&p_rx->rcq_chain);
 1434         OSAL_LIST_INIT(&p_rx->active_descq);
 1435         OSAL_LIST_INIT(&p_rx->free_descq);
 1436         OSAL_LIST_INIT(&p_rx->posting_descq);
 1437         OSAL_SPIN_LOCK_INIT(&p_rx->lock);
 1438         capacity = ecore_chain_get_capacity(&p_rx->rxq_chain);
 1439         for (i = 0; i < capacity; i++)
 1440                 OSAL_LIST_PUSH_TAIL(&p_rx->descq_array[i].list_entry,
 1441                                     &p_rx->free_descq);
 1442         *p_rx->p_fw_cons = 0;
 1443 
 1444         ecore_chain_reset(&p_tx->txq_chain);
 1445         OSAL_LIST_INIT(&p_tx->active_descq);
 1446         OSAL_LIST_INIT(&p_tx->free_descq);
 1447         OSAL_LIST_INIT(&p_tx->sending_descq);
 1448         OSAL_SPIN_LOCK_INIT(&p_tx->lock);
 1449         capacity = ecore_chain_get_capacity(&p_tx->txq_chain);
 1450         /* The size of the element in descq_array is flexible */
 1451         desc_size = (sizeof(*p_pkt) +
 1452                      (p_ll2_conn->input.tx_max_bds_per_packet - 1) *
 1453                      sizeof(p_pkt->bds_set));
 1454 
 1455         for (i = 0; i < capacity; i++) {
 1456                 p_pkt = (struct ecore_ll2_tx_packet *)((u8 *)p_tx->descq_array +
 1457                                                        desc_size*i);
 1458                 OSAL_LIST_PUSH_TAIL(&p_pkt->list_entry,
 1459                                     &p_tx->free_descq);
 1460         }
 1461         p_tx->cur_completing_bd_idx = 0;
 1462         p_tx->bds_idx = 0;
 1463         p_tx->b_completing_packet = false;
 1464         p_tx->cur_send_packet = OSAL_NULL;
 1465         p_tx->cur_send_frag_num = 0;
 1466         p_tx->cur_completing_frag_num = 0;
 1467         *p_tx->p_fw_cons = 0;
 1468 
 1469         rc = ecore_cxt_acquire_cid(p_hwfn, PROTOCOLID_CORE, &p_ll2_conn->cid);
 1470         if (rc)
 1471                 goto out;
 1472         cxt_info.iid = p_ll2_conn->cid;
 1473         rc = ecore_cxt_get_cid_info(p_hwfn, &cxt_info);
 1474         if (rc) {
 1475                 DP_NOTICE(p_hwfn, true, "Cannot find context info for cid=%d\n",
 1476                           p_ll2_conn->cid);
 1477                 goto out;
 1478         }
 1479 
 1480         p_cxt = cxt_info.p_cxt;
 1481 
 1482         /* @@@TBD we zero the context until we have ilt_reset implemented. */
 1483         OSAL_MEM_ZERO(p_cxt, sizeof(*p_cxt));
 1484 
 1485         qid = ecore_ll2_handle_to_queue_id(p_hwfn, connection_handle);
 1486         p_ll2_conn->queue_id = qid;
 1487         p_ll2_conn->tx_stats_id = qid;
 1488         p_rx->set_prod_addr = (u8 OSAL_IOMEM*)p_hwfn->regview +
 1489                                               GTT_BAR0_MAP_REG_TSDM_RAM +
 1490                                               TSTORM_LL2_RX_PRODS_OFFSET(qid);
 1491         p_tx->doorbell_addr = (u8 OSAL_IOMEM*)p_hwfn->doorbells +
 1492                                               DB_ADDR(p_ll2_conn->cid,
 1493                                                       DQ_DEMS_LEGACY);
 1494 
 1495         /* prepare db data */
 1496         SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_DEST, DB_DEST_XCM);
 1497         SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_AGG_CMD,
 1498                   DB_AGG_CMD_SET);
 1499         SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_AGG_VAL_SEL,
 1500                   DQ_XCM_CORE_TX_BD_PROD_CMD);
 1501         p_tx->db_msg.agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
 1502 
 1503         rc = ecore_ll2_establish_connection_rx(p_hwfn, p_ll2_conn);
 1504         if (rc)
 1505                 goto out;
 1506 
 1507         rc = ecore_sp_ll2_tx_queue_start(p_hwfn, p_ll2_conn);
 1508         if (rc)
 1509                 goto out;
 1510 
 1511         if (!ECORE_IS_RDMA_PERSONALITY(p_hwfn))
 1512                 ecore_wr(p_hwfn, p_ptt, PRS_REG_USE_LIGHT_L2, 1);
 1513 
 1514         ecore_ll2_establish_connection_ooo(p_hwfn, p_ll2_conn);
 1515 
 1516         if (p_ll2_conn->input.conn_type == ECORE_LL2_TYPE_FCOE) {
 1517                 if (!OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC,
 1518                                    &p_hwfn->p_dev->mf_bits))
 1519                         ecore_llh_add_protocol_filter(p_hwfn->p_dev, 0,
 1520                                                       ECORE_LLH_FILTER_ETHERTYPE,
 1521                                                       0x8906, 0);
 1522                 ecore_llh_add_protocol_filter(p_hwfn->p_dev, 0,
 1523                                               ECORE_LLH_FILTER_ETHERTYPE,
 1524                                               0x8914, 0);
 1525         }
 1526 
 1527 out:
 1528         ecore_ptt_release(p_hwfn, p_ptt);
 1529 
 1530         return rc;
 1531 }
 1532 
 1533 static void ecore_ll2_post_rx_buffer_notify_fw(struct ecore_hwfn *p_hwfn,
 1534                                                struct ecore_ll2_rx_queue *p_rx,
 1535                                                struct ecore_ll2_rx_packet *p_curp)
 1536 {
 1537         struct ecore_ll2_rx_packet *p_posting_packet = OSAL_NULL;
 1538         struct core_ll2_rx_prod rx_prod = {0, 0, 0};
 1539         bool b_notify_fw = false;
 1540         u16 bd_prod, cq_prod;
 1541 
 1542         /* This handles the flushing of already posted buffers */
 1543         while (!OSAL_LIST_IS_EMPTY(&p_rx->posting_descq)) {
 1544                 p_posting_packet = OSAL_LIST_FIRST_ENTRY(&p_rx->posting_descq,
 1545                                                          struct ecore_ll2_rx_packet,
 1546                                                          list_entry);
 1547 #if defined(_NTDDK_)
 1548 #pragma warning(suppress : 6011 28182)
 1549 #endif
 1550                 OSAL_LIST_REMOVE_ENTRY(&p_posting_packet->list_entry, &p_rx->posting_descq);
 1551                 OSAL_LIST_PUSH_TAIL(&p_posting_packet->list_entry, &p_rx->active_descq);
 1552                 b_notify_fw = true;
 1553         }
 1554 
 1555         /* This handles the supplied packet [if there is one] */
 1556         if (p_curp) {
 1557                 OSAL_LIST_PUSH_TAIL(&p_curp->list_entry,
 1558                                     &p_rx->active_descq);
 1559                 b_notify_fw = true;
 1560         }
 1561 
 1562         if (!b_notify_fw)
 1563                 return;
 1564 
 1565         bd_prod = ecore_chain_get_prod_idx(&p_rx->rxq_chain);
 1566         cq_prod = ecore_chain_get_prod_idx(&p_rx->rcq_chain);
 1567         rx_prod.bd_prod = OSAL_CPU_TO_LE16(bd_prod);
 1568         rx_prod.cqe_prod = OSAL_CPU_TO_LE16(cq_prod);
 1569         DIRECT_REG_WR(p_hwfn, p_rx->set_prod_addr, *((u32 *)&rx_prod));
 1570 }
 1571 
 1572 enum _ecore_status_t ecore_ll2_post_rx_buffer(void *cxt,
 1573                                               u8 connection_handle,
 1574                                               dma_addr_t addr,
 1575                                               u16 buf_len,
 1576                                               void *cookie,
 1577                                               u8 notify_fw)
 1578 {
 1579         struct ecore_hwfn *p_hwfn = (struct ecore_hwfn *)cxt;
 1580         struct core_rx_bd_with_buff_len *p_curb = OSAL_NULL;
 1581         struct ecore_ll2_rx_packet *p_curp = OSAL_NULL;
 1582         struct ecore_ll2_info *p_ll2_conn;
 1583         struct ecore_ll2_rx_queue *p_rx;
 1584         unsigned long flags;
 1585         void *p_data;
 1586         enum _ecore_status_t rc = ECORE_SUCCESS;
 1587 
 1588         p_ll2_conn = ecore_ll2_handle_sanity(p_hwfn, connection_handle);
 1589         if (p_ll2_conn == OSAL_NULL)
 1590                 return ECORE_INVAL;
 1591         p_rx = &p_ll2_conn->rx_queue;
 1592         if (p_rx->set_prod_addr == OSAL_NULL)
 1593                 return ECORE_IO;
 1594 
 1595         OSAL_SPIN_LOCK_IRQSAVE(&p_rx->lock, flags);
 1596         if (!OSAL_LIST_IS_EMPTY(&p_rx->free_descq))
 1597                 p_curp = OSAL_LIST_FIRST_ENTRY(&p_rx->free_descq,
 1598                                                struct ecore_ll2_rx_packet,
 1599                                                list_entry);
 1600         if (p_curp) {
 1601                 if (ecore_chain_get_elem_left(&p_rx->rxq_chain) &&
 1602                     ecore_chain_get_elem_left(&p_rx->rcq_chain)) {
 1603                         p_data = ecore_chain_produce(&p_rx->rxq_chain);
 1604                         p_curb = (struct core_rx_bd_with_buff_len *)p_data;
 1605                         ecore_chain_produce(&p_rx->rcq_chain);
 1606                 }
 1607         }
 1608 
 1609         /* If we're lacking entires, let's try to flush buffers to FW */
 1610         if (!p_curp || !p_curb) {
 1611                 rc =  ECORE_BUSY;
 1612                 p_curp = OSAL_NULL;
 1613                 goto out_notify;
 1614         }
 1615 
 1616         /* We have an Rx packet we can fill */
 1617         DMA_REGPAIR_LE(p_curb->addr, addr);
 1618         p_curb->buff_length = OSAL_CPU_TO_LE16(buf_len);
 1619         p_curp->rx_buf_addr = addr;
 1620         p_curp->cookie = cookie;
 1621         p_curp->rxq_bd = p_curb;
 1622         p_curp->buf_length = buf_len;
 1623         OSAL_LIST_REMOVE_ENTRY(&p_curp->list_entry,
 1624                                &p_rx->free_descq);
 1625 
 1626         /* Check if we only want to enqueue this packet without informing FW */
 1627         if (!notify_fw) {
 1628                 OSAL_LIST_PUSH_TAIL(&p_curp->list_entry,
 1629                                     &p_rx->posting_descq);
 1630                 goto out;
 1631         }
 1632 
 1633 out_notify:
 1634         ecore_ll2_post_rx_buffer_notify_fw(p_hwfn, p_rx, p_curp);
 1635 out:
 1636         OSAL_SPIN_UNLOCK_IRQSAVE(&p_rx->lock, flags);
 1637         return rc;
 1638 }
 1639 
 1640 static void ecore_ll2_prepare_tx_packet_set(struct ecore_ll2_tx_queue *p_tx,
 1641                                             struct ecore_ll2_tx_packet *p_curp,
 1642                                             struct ecore_ll2_tx_pkt_info *pkt,
 1643                                             u8 notify_fw)
 1644 {
 1645         OSAL_LIST_REMOVE_ENTRY(&p_curp->list_entry,
 1646                                &p_tx->free_descq);
 1647         p_curp->cookie = pkt->cookie;
 1648         p_curp->bd_used = pkt->num_of_bds;
 1649         p_curp->notify_fw = notify_fw;
 1650         p_tx->cur_send_packet = p_curp;
 1651         p_tx->cur_send_frag_num = 0;
 1652 
 1653         p_curp->bds_set[p_tx->cur_send_frag_num].tx_frag = pkt->first_frag;
 1654         p_curp->bds_set[p_tx->cur_send_frag_num].frag_len = pkt->first_frag_len;
 1655         p_tx->cur_send_frag_num++;
 1656 }
 1657 
 1658 static void ecore_ll2_prepare_tx_packet_set_bd(
 1659                 struct ecore_hwfn *p_hwfn,
 1660                 struct ecore_ll2_info *p_ll2,
 1661                 struct ecore_ll2_tx_packet *p_curp,
 1662                 struct ecore_ll2_tx_pkt_info *pkt)
 1663 {
 1664         struct ecore_chain *p_tx_chain = &p_ll2->tx_queue.txq_chain;
 1665         u16 prod_idx = ecore_chain_get_prod_idx(p_tx_chain);
 1666         struct core_tx_bd *start_bd = OSAL_NULL;
 1667         enum core_roce_flavor_type roce_flavor;
 1668         enum core_tx_dest tx_dest;
 1669         u16 bd_data = 0, frag_idx;
 1670 
 1671         roce_flavor = (pkt->ecore_roce_flavor == ECORE_LL2_ROCE) ?
 1672                 CORE_ROCE : CORE_RROCE;
 1673 
 1674         switch (pkt->tx_dest) {
 1675         case ECORE_LL2_TX_DEST_NW:
 1676                 tx_dest = CORE_TX_DEST_NW;
 1677                 break;
 1678         case ECORE_LL2_TX_DEST_LB:
 1679                 tx_dest = CORE_TX_DEST_LB;
 1680                 break;
 1681         case ECORE_LL2_TX_DEST_DROP:
 1682                 tx_dest = CORE_TX_DEST_DROP;
 1683                 break;
 1684         default:
 1685                 tx_dest = CORE_TX_DEST_LB;
 1686                 break;
 1687         }
 1688 
 1689         start_bd = (struct core_tx_bd*)ecore_chain_produce(p_tx_chain);
 1690 
 1691         if (ECORE_IS_IWARP_PERSONALITY(p_hwfn) &&
 1692             (p_ll2->input.conn_type == ECORE_LL2_TYPE_OOO)) {
 1693                 start_bd->nw_vlan_or_lb_echo =
 1694                         OSAL_CPU_TO_LE16(IWARP_LL2_IN_ORDER_TX_QUEUE);
 1695         } else {
 1696                 start_bd->nw_vlan_or_lb_echo = OSAL_CPU_TO_LE16(pkt->vlan);
 1697                 if (OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC, &p_hwfn->p_dev->mf_bits) &&
 1698                     (p_ll2->input.conn_type == ECORE_LL2_TYPE_FCOE))
 1699                         pkt->remove_stag = true;
 1700         }
 1701 
 1702         SET_FIELD(start_bd->bitfield1, CORE_TX_BD_L4_HDR_OFFSET_W,
 1703                   OSAL_CPU_TO_LE16(pkt->l4_hdr_offset_w));
 1704         SET_FIELD(start_bd->bitfield1, CORE_TX_BD_TX_DST, tx_dest);
 1705         bd_data |= pkt->bd_flags;
 1706         SET_FIELD(bd_data, CORE_TX_BD_DATA_START_BD, 0x1);
 1707         SET_FIELD(bd_data, CORE_TX_BD_DATA_NBDS, pkt->num_of_bds);
 1708         SET_FIELD(bd_data, CORE_TX_BD_DATA_ROCE_FLAV, roce_flavor);
 1709         SET_FIELD(bd_data, CORE_TX_BD_DATA_IP_CSUM, !!(pkt->enable_ip_cksum));
 1710         SET_FIELD(bd_data, CORE_TX_BD_DATA_L4_CSUM, !!(pkt->enable_l4_cksum));
 1711         SET_FIELD(bd_data, CORE_TX_BD_DATA_IP_LEN, !!(pkt->calc_ip_len));
 1712         SET_FIELD(bd_data, CORE_TX_BD_DATA_DISABLE_STAG_INSERTION,
 1713                   !!(pkt->remove_stag));
 1714 
 1715         start_bd->bd_data.as_bitfield = OSAL_CPU_TO_LE16(bd_data);
 1716         DMA_REGPAIR_LE(start_bd->addr, pkt->first_frag);
 1717         start_bd->nbytes = OSAL_CPU_TO_LE16(pkt->first_frag_len);
 1718 
 1719         DP_VERBOSE(p_hwfn, (ECORE_MSG_TX_QUEUED | ECORE_MSG_LL2),
 1720                    "LL2 [q 0x%02x cid 0x%08x type 0x%08x] Tx Producer at [0x%04x] - set with a %04x bytes %02x BDs buffer at %08x:%08x\n",
 1721                    p_ll2->queue_id, p_ll2->cid, p_ll2->input.conn_type,
 1722                    prod_idx, pkt->first_frag_len, pkt->num_of_bds,
 1723                    OSAL_LE32_TO_CPU(start_bd->addr.hi),
 1724                    OSAL_LE32_TO_CPU(start_bd->addr.lo));
 1725 
 1726         if (p_ll2->tx_queue.cur_send_frag_num == pkt->num_of_bds)
 1727                 return;
 1728 
 1729         /* Need to provide the packet with additional BDs for frags */
 1730         for (frag_idx = p_ll2->tx_queue.cur_send_frag_num;
 1731              frag_idx < pkt->num_of_bds; frag_idx++) {
 1732                 struct core_tx_bd **p_bd = &p_curp->bds_set[frag_idx].txq_bd;
 1733 
 1734                 *p_bd = (struct core_tx_bd *)ecore_chain_produce(p_tx_chain);
 1735                 (*p_bd)->bd_data.as_bitfield = 0;
 1736                 (*p_bd)->bitfield1 = 0;
 1737                 p_curp->bds_set[frag_idx].tx_frag = 0;
 1738                 p_curp->bds_set[frag_idx].frag_len = 0;
 1739         }
 1740 }
 1741 
 1742 /* This should be called while the Txq spinlock is being held */
 1743 static void ecore_ll2_tx_packet_notify(struct ecore_hwfn *p_hwfn,
 1744                                        struct ecore_ll2_info *p_ll2_conn)
 1745 {
 1746         bool b_notify = p_ll2_conn->tx_queue.cur_send_packet->notify_fw;
 1747         struct ecore_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
 1748         struct ecore_ll2_tx_packet *p_pkt = OSAL_NULL;
 1749         u16 bd_prod;
 1750 
 1751         /* If there are missing BDs, don't do anything now */
 1752         if (p_ll2_conn->tx_queue.cur_send_frag_num !=
 1753             p_ll2_conn->tx_queue.cur_send_packet->bd_used)
 1754                 return;
 1755 
 1756         /* Push the current packet to the list and clean after it */
 1757         OSAL_LIST_PUSH_TAIL(&p_ll2_conn->tx_queue.cur_send_packet->list_entry,
 1758                             &p_ll2_conn->tx_queue.sending_descq);
 1759         p_ll2_conn->tx_queue.cur_send_packet = OSAL_NULL;
 1760         p_ll2_conn->tx_queue.cur_send_frag_num = 0;
 1761 
 1762         /* Notify FW of packet only if requested to */
 1763         if (!b_notify)
 1764                 return;
 1765 
 1766         bd_prod = ecore_chain_get_prod_idx(&p_ll2_conn->tx_queue.txq_chain);
 1767 
 1768         while (!OSAL_LIST_IS_EMPTY(&p_tx->sending_descq)) {
 1769                 p_pkt = OSAL_LIST_FIRST_ENTRY(&p_tx->sending_descq,
 1770                                               struct ecore_ll2_tx_packet,
 1771                                               list_entry);
 1772                 if (p_pkt == OSAL_NULL)
 1773                         break;
 1774 #if defined(_NTDDK_)
 1775 #pragma warning(suppress : 6011 28182)
 1776 #endif
 1777                 OSAL_LIST_REMOVE_ENTRY(&p_pkt->list_entry,
 1778                                        &p_tx->sending_descq);
 1779                 OSAL_LIST_PUSH_TAIL(&p_pkt->list_entry, &p_tx->active_descq);
 1780         }
 1781 
 1782         p_tx->db_msg.spq_prod = OSAL_CPU_TO_LE16(bd_prod);
 1783 
 1784         /* Make sure the BDs data is updated before ringing the doorbell */
 1785         OSAL_WMB(p_hwfn->p_dev);
 1786 
 1787         //DIRECT_REG_WR(p_hwfn, p_tx->doorbell_addr, *((u32 *)&p_tx->db_msg));
 1788         DIRECT_REG_WR_DB(p_hwfn, p_tx->doorbell_addr, *((u32 *)&p_tx->db_msg));
 1789 
 1790         DP_VERBOSE(p_hwfn, (ECORE_MSG_TX_QUEUED | ECORE_MSG_LL2),
 1791                    "LL2 [q 0x%02x cid 0x%08x type 0x%08x] Doorbelled [producer 0x%04x]\n",
 1792                    p_ll2_conn->queue_id, p_ll2_conn->cid,
 1793                    p_ll2_conn->input.conn_type,
 1794                    p_tx->db_msg.spq_prod);
 1795 }
 1796 
 1797 enum _ecore_status_t ecore_ll2_prepare_tx_packet(
 1798                 void *cxt,
 1799                 u8 connection_handle,
 1800                 struct ecore_ll2_tx_pkt_info *pkt,
 1801                 bool notify_fw)
 1802 {
 1803         struct ecore_hwfn *p_hwfn = (struct ecore_hwfn *)cxt;
 1804         struct ecore_ll2_tx_packet *p_curp = OSAL_NULL;
 1805         struct ecore_ll2_info *p_ll2_conn = OSAL_NULL;
 1806         struct ecore_ll2_tx_queue *p_tx;
 1807         struct ecore_chain *p_tx_chain;
 1808         unsigned long flags;
 1809         enum _ecore_status_t rc = ECORE_SUCCESS;
 1810 
 1811         p_ll2_conn = ecore_ll2_handle_sanity(p_hwfn, connection_handle);
 1812         if (p_ll2_conn == OSAL_NULL)
 1813                 return ECORE_INVAL;
 1814         p_tx = &p_ll2_conn->tx_queue;
 1815         p_tx_chain = &p_tx->txq_chain;
 1816 
 1817         if (pkt->num_of_bds > p_ll2_conn->input.tx_max_bds_per_packet)
 1818                 return ECORE_IO; /* coalescing is requireed */
 1819 
 1820         OSAL_SPIN_LOCK_IRQSAVE(&p_tx->lock, flags);
 1821         if (p_tx->cur_send_packet) {
 1822                 rc = ECORE_EXISTS;
 1823                 goto out;
 1824         }
 1825 
 1826         /* Get entry, but only if we have tx elements for it */
 1827         if (!OSAL_LIST_IS_EMPTY(&p_tx->free_descq))
 1828                 p_curp = OSAL_LIST_FIRST_ENTRY(&p_tx->free_descq,
 1829                                                struct ecore_ll2_tx_packet,
 1830                                                list_entry);
 1831         if (p_curp && ecore_chain_get_elem_left(p_tx_chain) < pkt->num_of_bds)
 1832                 p_curp = OSAL_NULL;
 1833 
 1834         if (!p_curp) {
 1835                 rc = ECORE_BUSY;
 1836                 goto out;
 1837         }
 1838 
 1839         /* Prepare packet and BD, and perhaps send a doorbell to FW */
 1840         ecore_ll2_prepare_tx_packet_set(p_tx, p_curp, pkt, notify_fw);
 1841 
 1842         ecore_ll2_prepare_tx_packet_set_bd(p_hwfn, p_ll2_conn, p_curp,
 1843                                            pkt);
 1844 
 1845         ecore_ll2_tx_packet_notify(p_hwfn, p_ll2_conn);
 1846 
 1847 out:
 1848         OSAL_SPIN_UNLOCK_IRQSAVE(&p_tx->lock, flags);
 1849         return rc;
 1850 }
 1851 
 1852 enum _ecore_status_t ecore_ll2_set_fragment_of_tx_packet(void *cxt,
 1853                                                          u8 connection_handle,
 1854                                                          dma_addr_t addr,
 1855                                                          u16 nbytes)
 1856 {
 1857         struct ecore_ll2_tx_packet *p_cur_send_packet = OSAL_NULL;
 1858         struct ecore_hwfn *p_hwfn = (struct ecore_hwfn *)cxt;
 1859         struct ecore_ll2_info *p_ll2_conn = OSAL_NULL;
 1860         u16 cur_send_frag_num = 0;
 1861         struct core_tx_bd *p_bd;
 1862         unsigned long flags;
 1863 
 1864         p_ll2_conn = ecore_ll2_handle_sanity(p_hwfn, connection_handle);
 1865         if (p_ll2_conn == OSAL_NULL)
 1866                 return ECORE_INVAL;
 1867 
 1868         if (!p_ll2_conn->tx_queue.cur_send_packet)
 1869                 return ECORE_INVAL;
 1870 
 1871         p_cur_send_packet = p_ll2_conn->tx_queue.cur_send_packet;
 1872         cur_send_frag_num = p_ll2_conn->tx_queue.cur_send_frag_num;
 1873 
 1874         if (cur_send_frag_num >= p_cur_send_packet->bd_used)
 1875                 return ECORE_INVAL;
 1876 
 1877         /* Fill the BD information, and possibly notify FW */
 1878         p_bd = p_cur_send_packet->bds_set[cur_send_frag_num].txq_bd;
 1879         DMA_REGPAIR_LE(p_bd->addr, addr);
 1880         p_bd->nbytes = OSAL_CPU_TO_LE16(nbytes);
 1881         p_cur_send_packet->bds_set[cur_send_frag_num].tx_frag = addr;
 1882         p_cur_send_packet->bds_set[cur_send_frag_num].frag_len = nbytes;
 1883 
 1884         p_ll2_conn->tx_queue.cur_send_frag_num++;
 1885 
 1886         OSAL_SPIN_LOCK_IRQSAVE(&p_ll2_conn->tx_queue.lock, flags);
 1887         ecore_ll2_tx_packet_notify(p_hwfn, p_ll2_conn);
 1888         OSAL_SPIN_UNLOCK_IRQSAVE(&p_ll2_conn->tx_queue.lock, flags);
 1889 
 1890         return ECORE_SUCCESS;
 1891 }
 1892 
 1893 enum _ecore_status_t ecore_ll2_terminate_connection(void *cxt,
 1894                                                     u8 connection_handle)
 1895 {
 1896         struct ecore_hwfn *p_hwfn = (struct ecore_hwfn *)cxt;
 1897         struct ecore_ll2_info *p_ll2_conn = OSAL_NULL;
 1898         enum _ecore_status_t rc = ECORE_NOTIMPL;
 1899         struct ecore_ptt *p_ptt;
 1900 
 1901         p_ptt = ecore_ptt_acquire(p_hwfn);
 1902         if (!p_ptt)
 1903                 return ECORE_AGAIN;
 1904 
 1905         p_ll2_conn = ecore_ll2_handle_sanity_lock(p_hwfn, connection_handle);
 1906         if (p_ll2_conn == OSAL_NULL) {
 1907                 rc = ECORE_INVAL;
 1908                 goto out;
 1909         }
 1910 
 1911         /* Stop Tx & Rx of connection, if needed */
 1912         if (ECORE_LL2_TX_REGISTERED(p_ll2_conn)) {
 1913                 rc = ecore_sp_ll2_tx_queue_stop(p_hwfn, p_ll2_conn);
 1914                 if (rc != ECORE_SUCCESS)
 1915                         goto out;
 1916                 ecore_ll2_txq_flush(p_hwfn, connection_handle);
 1917         }
 1918 
 1919         if (ECORE_LL2_RX_REGISTERED(p_ll2_conn)) {
 1920                 rc = ecore_sp_ll2_rx_queue_stop(p_hwfn, p_ll2_conn);
 1921                 if (rc)
 1922                         goto out;
 1923                 ecore_ll2_rxq_flush(p_hwfn, connection_handle);
 1924         }
 1925 
 1926         if (p_ll2_conn->input.conn_type == ECORE_LL2_TYPE_OOO)
 1927                 ecore_ooo_release_all_isles(p_hwfn->p_ooo_info);
 1928 
 1929         if (p_ll2_conn->input.conn_type == ECORE_LL2_TYPE_FCOE) {
 1930                 if (!OSAL_TEST_BIT(ECORE_MF_UFP_SPECIFIC,
 1931                                    &p_hwfn->p_dev->mf_bits))
 1932                         ecore_llh_remove_protocol_filter(p_hwfn->p_dev, 0,
 1933                                                          ECORE_LLH_FILTER_ETHERTYPE,
 1934                                                          0x8906, 0);
 1935                 ecore_llh_remove_protocol_filter(p_hwfn->p_dev, 0,
 1936                                                  ECORE_LLH_FILTER_ETHERTYPE,
 1937                                                  0x8914, 0);
 1938         }
 1939 
 1940 out:
 1941         ecore_ptt_release(p_hwfn, p_ptt);
 1942 
 1943         return rc;
 1944 }
 1945 
 1946 static void ecore_ll2_release_connection_ooo(struct ecore_hwfn *p_hwfn,
 1947                                              struct ecore_ll2_info *p_ll2_conn)
 1948 {
 1949         struct ecore_ooo_buffer *p_buffer;
 1950 
 1951         if (p_ll2_conn->input.conn_type != ECORE_LL2_TYPE_OOO)
 1952                 return;
 1953 
 1954         ecore_ooo_release_all_isles(p_hwfn->p_ooo_info);
 1955         while ((p_buffer = ecore_ooo_get_free_buffer(p_hwfn->p_ooo_info))) {
 1956                 OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev,
 1957                                        p_buffer->rx_buffer_virt_addr,
 1958                                        p_buffer->rx_buffer_phys_addr,
 1959                                        p_buffer->rx_buffer_size);
 1960                 OSAL_FREE(p_hwfn->p_dev, p_buffer);
 1961         }
 1962 }
 1963 
 1964 void ecore_ll2_release_connection(void *cxt,
 1965                                   u8 connection_handle)
 1966 {
 1967         struct ecore_hwfn *p_hwfn = (struct ecore_hwfn *)cxt;
 1968         struct ecore_ll2_info *p_ll2_conn = OSAL_NULL;
 1969 
 1970         p_ll2_conn = ecore_ll2_handle_sanity(p_hwfn, connection_handle);
 1971         if (p_ll2_conn == OSAL_NULL)
 1972                 return;
 1973 
 1974         if (ECORE_LL2_RX_REGISTERED(p_ll2_conn)) {
 1975                 p_ll2_conn->rx_queue.b_cb_registred = false;
 1976                 ecore_int_unregister_cb(p_hwfn,
 1977                                         p_ll2_conn->rx_queue.rx_sb_index);
 1978         }
 1979 
 1980         if (ECORE_LL2_TX_REGISTERED(p_ll2_conn)) {
 1981                 p_ll2_conn->tx_queue.b_cb_registred = false;
 1982                 ecore_int_unregister_cb(p_hwfn,
 1983                                         p_ll2_conn->tx_queue.tx_sb_index);
 1984         }
 1985 
 1986         OSAL_FREE(p_hwfn->p_dev, p_ll2_conn->tx_queue.descq_array);
 1987         ecore_chain_free(p_hwfn->p_dev, &p_ll2_conn->tx_queue.txq_chain);
 1988 
 1989         OSAL_FREE(p_hwfn->p_dev, p_ll2_conn->rx_queue.descq_array);
 1990         ecore_chain_free(p_hwfn->p_dev, &p_ll2_conn->rx_queue.rxq_chain);
 1991         ecore_chain_free(p_hwfn->p_dev, &p_ll2_conn->rx_queue.rcq_chain);
 1992 
 1993         ecore_cxt_release_cid(p_hwfn, p_ll2_conn->cid);
 1994 
 1995         ecore_ll2_release_connection_ooo(p_hwfn, p_ll2_conn);
 1996 
 1997         OSAL_MUTEX_ACQUIRE(&p_ll2_conn->mutex);
 1998         p_ll2_conn->b_active = false;
 1999         OSAL_MUTEX_RELEASE(&p_ll2_conn->mutex);
 2000 }
 2001 
 2002 /* ECORE LL2: internal functions */
 2003 
 2004 enum _ecore_status_t ecore_ll2_alloc(struct ecore_hwfn *p_hwfn)
 2005 {
 2006         struct ecore_ll2_info *p_ll2_info;
 2007         u8 i;
 2008 
 2009         /* Allocate LL2's set struct */
 2010         p_ll2_info = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
 2011                                  sizeof(struct ecore_ll2_info) *
 2012                                  ECORE_MAX_NUM_OF_LL2_CONNECTIONS);
 2013         if (!p_ll2_info) {
 2014                 DP_NOTICE(p_hwfn, false,
 2015                           "Failed to allocate `struct ecore_ll2'\n");
 2016                 return ECORE_NOMEM;
 2017         }
 2018 
 2019         p_hwfn->p_ll2_info = p_ll2_info;
 2020 
 2021         for (i = 0; i < ECORE_MAX_NUM_OF_LL2_CONNECTIONS; i++) {
 2022 #ifdef CONFIG_ECORE_LOCK_ALLOC
 2023                 if (OSAL_MUTEX_ALLOC(p_hwfn, &p_ll2_info[i].mutex))
 2024                         goto handle_err;
 2025                 if (OSAL_SPIN_LOCK_ALLOC(p_hwfn, &p_ll2_info[i].rx_queue.lock))
 2026                         goto handle_err;
 2027                 if (OSAL_SPIN_LOCK_ALLOC(p_hwfn, &p_ll2_info[i].tx_queue.lock))
 2028                         goto handle_err;
 2029 #endif
 2030                 p_ll2_info[i].my_id = i;
 2031         }
 2032 
 2033         return ECORE_SUCCESS;
 2034 #ifdef CONFIG_ECORE_LOCK_ALLOC
 2035 handle_err:
 2036         ecore_ll2_free(p_hwfn);
 2037         return ECORE_NOMEM;
 2038 #endif
 2039 }
 2040 
 2041 void ecore_ll2_setup(struct ecore_hwfn *p_hwfn)
 2042 {
 2043         int  i;
 2044 
 2045         for (i = 0; i < ECORE_MAX_NUM_OF_LL2_CONNECTIONS; i++)
 2046                 OSAL_MUTEX_INIT(&p_hwfn->p_ll2_info[i].mutex);
 2047 }
 2048 
 2049 void ecore_ll2_free(struct ecore_hwfn *p_hwfn)
 2050 {
 2051 #ifdef CONFIG_ECORE_LOCK_ALLOC
 2052         int i;
 2053 #endif
 2054         if (!p_hwfn->p_ll2_info)
 2055                 return;
 2056 
 2057 #ifdef CONFIG_ECORE_LOCK_ALLOC
 2058         for (i = 0; i < ECORE_MAX_NUM_OF_LL2_CONNECTIONS; i++) {
 2059                 OSAL_SPIN_LOCK_DEALLOC(&p_hwfn->p_ll2_info[i].rx_queue.lock);
 2060                 OSAL_SPIN_LOCK_DEALLOC(&p_hwfn->p_ll2_info[i].tx_queue.lock);
 2061                 OSAL_MUTEX_DEALLOC(&p_hwfn->p_ll2_info[i].mutex);
 2062         }
 2063 #endif
 2064         OSAL_FREE(p_hwfn->p_dev, p_hwfn->p_ll2_info);
 2065         p_hwfn->p_ll2_info = OSAL_NULL;
 2066 }
 2067 
 2068 static void _ecore_ll2_get_port_stats(struct ecore_hwfn *p_hwfn,
 2069                                       struct ecore_ptt *p_ptt,
 2070                                       struct ecore_ll2_stats *p_stats)
 2071 {
 2072         struct core_ll2_port_stats port_stats;
 2073 
 2074         OSAL_MEMSET(&port_stats, 0, sizeof(port_stats));
 2075         ecore_memcpy_from(p_hwfn, p_ptt, &port_stats,
 2076                           BAR0_MAP_REG_TSDM_RAM +
 2077                           TSTORM_LL2_PORT_STAT_OFFSET(MFW_PORT(p_hwfn)),
 2078                           sizeof(port_stats));
 2079 
 2080         p_stats->gsi_invalid_hdr +=
 2081                 HILO_64_REGPAIR(port_stats.gsi_invalid_hdr);
 2082         p_stats->gsi_invalid_pkt_length +=
 2083                 HILO_64_REGPAIR(port_stats.gsi_invalid_pkt_length);
 2084         p_stats->gsi_unsupported_pkt_typ +=
 2085                 HILO_64_REGPAIR(port_stats.gsi_unsupported_pkt_typ);
 2086         p_stats->gsi_crcchksm_error +=
 2087                 HILO_64_REGPAIR(port_stats.gsi_crcchksm_error);
 2088 }
 2089 
 2090 static void _ecore_ll2_get_tstats(struct ecore_hwfn *p_hwfn,
 2091                                   struct ecore_ptt *p_ptt,
 2092                                   struct ecore_ll2_info *p_ll2_conn,
 2093                                   struct ecore_ll2_stats *p_stats)
 2094 {
 2095         struct core_ll2_tstorm_per_queue_stat tstats;
 2096         u8 qid = p_ll2_conn->queue_id;
 2097         u32 tstats_addr;
 2098 
 2099         OSAL_MEMSET(&tstats, 0, sizeof(tstats));
 2100         tstats_addr = BAR0_MAP_REG_TSDM_RAM +
 2101                       CORE_LL2_TSTORM_PER_QUEUE_STAT_OFFSET(qid);
 2102         ecore_memcpy_from(p_hwfn, p_ptt, &tstats,
 2103                           tstats_addr,
 2104                           sizeof(tstats));
 2105 
 2106         p_stats->packet_too_big_discard +=
 2107                 HILO_64_REGPAIR(tstats.packet_too_big_discard);
 2108         p_stats->no_buff_discard +=
 2109                 HILO_64_REGPAIR(tstats.no_buff_discard);
 2110 }
 2111 
 2112 static void _ecore_ll2_get_ustats(struct ecore_hwfn *p_hwfn,
 2113                                   struct ecore_ptt *p_ptt,
 2114                                   struct ecore_ll2_info *p_ll2_conn,
 2115                                   struct ecore_ll2_stats *p_stats)
 2116 {
 2117         struct core_ll2_ustorm_per_queue_stat ustats;
 2118         u8 qid = p_ll2_conn->queue_id;
 2119         u32 ustats_addr;
 2120 
 2121         OSAL_MEMSET(&ustats, 0, sizeof(ustats));
 2122         ustats_addr = BAR0_MAP_REG_USDM_RAM +
 2123                       CORE_LL2_USTORM_PER_QUEUE_STAT_OFFSET(qid);
 2124         ecore_memcpy_from(p_hwfn, p_ptt, &ustats,
 2125                           ustats_addr,
 2126                           sizeof(ustats));
 2127 
 2128         p_stats->rcv_ucast_bytes += HILO_64_REGPAIR(ustats.rcv_ucast_bytes);
 2129         p_stats->rcv_mcast_bytes += HILO_64_REGPAIR(ustats.rcv_mcast_bytes);
 2130         p_stats->rcv_bcast_bytes += HILO_64_REGPAIR(ustats.rcv_bcast_bytes);
 2131         p_stats->rcv_ucast_pkts += HILO_64_REGPAIR(ustats.rcv_ucast_pkts);
 2132         p_stats->rcv_mcast_pkts += HILO_64_REGPAIR(ustats.rcv_mcast_pkts);
 2133         p_stats->rcv_bcast_pkts += HILO_64_REGPAIR(ustats.rcv_bcast_pkts);
 2134 }
 2135 
 2136 static void _ecore_ll2_get_pstats(struct ecore_hwfn *p_hwfn,
 2137                                   struct ecore_ptt *p_ptt,
 2138                                   struct ecore_ll2_info *p_ll2_conn,
 2139                                   struct ecore_ll2_stats *p_stats)
 2140 {
 2141         struct core_ll2_pstorm_per_queue_stat pstats;
 2142         u8 stats_id = p_ll2_conn->tx_stats_id;
 2143         u32 pstats_addr;
 2144 
 2145         OSAL_MEMSET(&pstats, 0, sizeof(pstats));
 2146         pstats_addr = BAR0_MAP_REG_PSDM_RAM +
 2147                       CORE_LL2_PSTORM_PER_QUEUE_STAT_OFFSET(stats_id);
 2148         ecore_memcpy_from(p_hwfn, p_ptt, &pstats,
 2149                           pstats_addr,
 2150                           sizeof(pstats));
 2151 
 2152         p_stats->sent_ucast_bytes += HILO_64_REGPAIR(pstats.sent_ucast_bytes);
 2153         p_stats->sent_mcast_bytes += HILO_64_REGPAIR(pstats.sent_mcast_bytes);
 2154         p_stats->sent_bcast_bytes += HILO_64_REGPAIR(pstats.sent_bcast_bytes);
 2155         p_stats->sent_ucast_pkts += HILO_64_REGPAIR(pstats.sent_ucast_pkts);
 2156         p_stats->sent_mcast_pkts += HILO_64_REGPAIR(pstats.sent_mcast_pkts);
 2157         p_stats->sent_bcast_pkts += HILO_64_REGPAIR(pstats.sent_bcast_pkts);
 2158 }
 2159 
 2160 enum _ecore_status_t __ecore_ll2_get_stats(void *cxt,
 2161                                            u8 connection_handle,
 2162                                            struct ecore_ll2_stats *p_stats)
 2163 {
 2164         struct ecore_hwfn *p_hwfn = (struct ecore_hwfn *)cxt;
 2165         struct ecore_ll2_info *p_ll2_conn = OSAL_NULL;
 2166         struct ecore_ptt *p_ptt;
 2167 
 2168         if ((connection_handle >= ECORE_MAX_NUM_OF_LL2_CONNECTIONS) ||
 2169             !p_hwfn->p_ll2_info) {
 2170                 return ECORE_INVAL;
 2171         }
 2172 
 2173         p_ll2_conn = &p_hwfn->p_ll2_info[connection_handle];
 2174 
 2175         p_ptt = ecore_ptt_acquire(p_hwfn);
 2176         if (!p_ptt) {
 2177                 DP_ERR(p_hwfn, "Failed to acquire ptt\n");
 2178                 return ECORE_INVAL;
 2179         }
 2180 
 2181         if (p_ll2_conn->input.gsi_enable)
 2182                 _ecore_ll2_get_port_stats(p_hwfn, p_ptt, p_stats);
 2183 
 2184         _ecore_ll2_get_tstats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
 2185 
 2186         _ecore_ll2_get_ustats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
 2187 
 2188         if (p_ll2_conn->tx_stats_en)
 2189                 _ecore_ll2_get_pstats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
 2190 
 2191         ecore_ptt_release(p_hwfn, p_ptt);
 2192 
 2193         return ECORE_SUCCESS;
 2194 }
 2195 
 2196 enum _ecore_status_t ecore_ll2_get_stats(void *cxt,
 2197                                          u8 connection_handle,
 2198                                          struct ecore_ll2_stats *p_stats)
 2199 {
 2200         OSAL_MEMSET(p_stats, 0, sizeof(*p_stats));
 2201 
 2202         return __ecore_ll2_get_stats(cxt, connection_handle, p_stats);
 2203 }
 2204 
 2205 /**/
 2206 
 2207 #ifdef _NTDDK_
 2208 #pragma warning(pop)
 2209 #endif

Cache object: 80c968c48c909a1645ef0dd23e8e79a4


[ 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.