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/irdma/irdma_uda.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  * SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB
    3  *
    4  * Copyright (c) 2016 - 2021 Intel Corporation
    5  *
    6  * This software is available to you under a choice of one of two
    7  * licenses.  You may choose to be licensed under the terms of the GNU
    8  * General Public License (GPL) Version 2, available from the file
    9  * COPYING in the main directory of this source tree, or the
   10  * OpenFabrics.org BSD license below:
   11  *
   12  *   Redistribution and use in source and binary forms, with or
   13  *   without modification, are permitted provided that the following
   14  *   conditions are met:
   15  *
   16  *    - Redistributions of source code must retain the above
   17  *      copyright notice, this list of conditions and the following
   18  *      disclaimer.
   19  *
   20  *    - Redistributions in binary form must reproduce the above
   21  *      copyright notice, this list of conditions and the following
   22  *      disclaimer in the documentation and/or other materials
   23  *      provided with the distribution.
   24  *
   25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
   29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
   30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   32  * SOFTWARE.
   33  */
   34 /*$FreeBSD$*/
   35 
   36 #include "osdep.h"
   37 #include "irdma_hmc.h"
   38 #include "irdma_defs.h"
   39 #include "irdma_type.h"
   40 #include "irdma_protos.h"
   41 #include "irdma_uda.h"
   42 #include "irdma_uda_d.h"
   43 
   44 /**
   45  * irdma_sc_access_ah() - Create, modify or delete AH
   46  * @cqp: struct for cqp hw
   47  * @info: ah information
   48  * @op: Operation
   49  * @scratch: u64 saved to be used during cqp completion
   50  */
   51 int
   52 irdma_sc_access_ah(struct irdma_sc_cqp *cqp, struct irdma_ah_info *info,
   53                    u32 op, u64 scratch)
   54 {
   55         __le64 *wqe;
   56         u64 qw1, qw2;
   57 
   58         wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
   59         if (!wqe)
   60                 return -ENOSPC;
   61 
   62         set_64bit_val(wqe, IRDMA_BYTE_0, LS_64_1(info->mac_addr[5], 16) |
   63                       LS_64_1(info->mac_addr[4], 24) |
   64                       LS_64_1(info->mac_addr[3], 32) |
   65                       LS_64_1(info->mac_addr[2], 40) |
   66                       LS_64_1(info->mac_addr[1], 48) |
   67                       LS_64_1(info->mac_addr[0], 56));
   68 
   69         qw1 = FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_PDINDEXLO, info->pd_idx) |
   70             FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_TC, info->tc_tos) |
   71             FIELD_PREP(IRDMA_UDAQPC_VLANTAG, info->vlan_tag);
   72 
   73         qw2 = FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ARPINDEX, info->dst_arpindex) |
   74             FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_FLOWLABEL, info->flow_label) |
   75             FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_HOPLIMIT, info->hop_ttl) |
   76             FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_PDINDEXHI, info->pd_idx >> 16);
   77 
   78         if (!info->ipv4_valid) {
   79                 set_64bit_val(wqe, IRDMA_BYTE_40,
   80                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR0, info->dest_ip_addr[0]) |
   81                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR1, info->dest_ip_addr[1]));
   82                 set_64bit_val(wqe, IRDMA_BYTE_32,
   83                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR2, info->dest_ip_addr[2]) |
   84                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[3]));
   85 
   86                 set_64bit_val(wqe, IRDMA_BYTE_56,
   87                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR0, info->src_ip_addr[0]) |
   88                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR1, info->src_ip_addr[1]));
   89                 set_64bit_val(wqe, IRDMA_BYTE_48,
   90                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR2, info->src_ip_addr[2]) |
   91                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->src_ip_addr[3]));
   92         } else {
   93                 set_64bit_val(wqe, IRDMA_BYTE_32,
   94                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[0]));
   95 
   96                 set_64bit_val(wqe, IRDMA_BYTE_48,
   97                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->src_ip_addr[0]));
   98         }
   99 
  100         set_64bit_val(wqe, IRDMA_BYTE_8, qw1);
  101         set_64bit_val(wqe, IRDMA_BYTE_16, qw2);
  102 
  103         irdma_wmb();            /* need write block before writing WQE header */
  104 
  105         set_64bit_val(
  106                       wqe, IRDMA_BYTE_24,
  107                       FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_WQEVALID, cqp->polarity) |
  108                       FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_OPCODE, op) |
  109                       FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_DOLOOPBACKK, info->do_lpbk) |
  110                       FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_IPV4VALID, info->ipv4_valid) |
  111                       FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_AVIDX, info->ah_idx) |
  112                       FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_INSERTVLANTAG, info->insert_vlan_tag));
  113 
  114         irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MANAGE_AH WQE", wqe,
  115                         IRDMA_CQP_WQE_SIZE * 8);
  116         irdma_sc_cqp_post_sq(cqp);
  117 
  118         return 0;
  119 }
  120 
  121 /**
  122  * irdma_create_mg_ctx() - create a mcg context
  123  * @info: multicast group context info
  124  */
  125 static int
  126 irdma_create_mg_ctx(struct irdma_mcast_grp_info *info)
  127 {
  128         struct irdma_mcast_grp_ctx_entry_info *entry_info = NULL;
  129         u8 idx = 0;             /* index in the array */
  130         u8 ctx_idx = 0;         /* index in the MG context */
  131 
  132         memset(info->dma_mem_mc.va, 0, IRDMA_MAX_MGS_PER_CTX * sizeof(u64));
  133 
  134         for (idx = 0; idx < IRDMA_MAX_MGS_PER_CTX; idx++) {
  135                 entry_info = &info->mg_ctx_info[idx];
  136                 if (entry_info->valid_entry) {
  137                         set_64bit_val((__le64 *) info->dma_mem_mc.va,
  138                                       ctx_idx * sizeof(u64),
  139                                       FIELD_PREP(IRDMA_UDA_MGCTX_DESTPORT, entry_info->dest_port) |
  140                                       FIELD_PREP(IRDMA_UDA_MGCTX_VALIDENT, entry_info->valid_entry) |
  141                                       FIELD_PREP(IRDMA_UDA_MGCTX_QPID, entry_info->qp_id));
  142                         ctx_idx++;
  143                 }
  144         }
  145 
  146         return 0;
  147 }
  148 
  149 /**
  150  * irdma_access_mcast_grp() - Access mcast group based on op
  151  * @cqp: Control QP
  152  * @info: multicast group context info
  153  * @op: operation to perform
  154  * @scratch: u64 saved to be used during cqp completion
  155  */
  156 int
  157 irdma_access_mcast_grp(struct irdma_sc_cqp *cqp,
  158                        struct irdma_mcast_grp_info *info, u32 op,
  159                        u64 scratch)
  160 {
  161         __le64 *wqe;
  162         int ret_code = 0;
  163 
  164         if (info->mg_id >= IRDMA_UDA_MAX_FSI_MGS) {
  165                 irdma_debug(cqp->dev, IRDMA_DEBUG_WQE, "mg_id out of range\n");
  166                 return -EINVAL;
  167         }
  168 
  169         wqe = irdma_sc_cqp_get_next_send_wqe(cqp, scratch);
  170         if (!wqe) {
  171                 irdma_debug(cqp->dev, IRDMA_DEBUG_WQE, "ring full\n");
  172                 return -ENOSPC;
  173         }
  174 
  175         ret_code = irdma_create_mg_ctx(info);
  176         if (ret_code)
  177                 return ret_code;
  178 
  179         set_64bit_val(wqe, IRDMA_BYTE_32, info->dma_mem_mc.pa);
  180         set_64bit_val(wqe, IRDMA_BYTE_16,
  181                       FIELD_PREP(IRDMA_UDA_CQPSQ_MG_VLANID, info->vlan_id) |
  182                       FIELD_PREP(IRDMA_UDA_CQPSQ_QS_HANDLE, info->qs_handle));
  183         set_64bit_val(wqe, IRDMA_BYTE_0, LS_64_1(info->dest_mac_addr[5], 0) |
  184                       LS_64_1(info->dest_mac_addr[4], 8) |
  185                       LS_64_1(info->dest_mac_addr[3], 16) |
  186                       LS_64_1(info->dest_mac_addr[2], 24) |
  187                       LS_64_1(info->dest_mac_addr[1], 32) |
  188                       LS_64_1(info->dest_mac_addr[0], 40));
  189         set_64bit_val(wqe, IRDMA_BYTE_8,
  190                       FIELD_PREP(IRDMA_UDA_CQPSQ_MG_HMC_FCN_ID, info->hmc_fcn_id));
  191 
  192         if (!info->ipv4_valid) {
  193                 set_64bit_val(wqe, IRDMA_BYTE_56,
  194                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR0, info->dest_ip_addr[0]) |
  195                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR1, info->dest_ip_addr[1]));
  196                 set_64bit_val(wqe, IRDMA_BYTE_48,
  197                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR2, info->dest_ip_addr[2]) |
  198                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[3]));
  199         } else {
  200                 set_64bit_val(wqe, IRDMA_BYTE_48,
  201                               FIELD_PREP(IRDMA_UDA_CQPSQ_MAV_ADDR3, info->dest_ip_addr[0]));
  202         }
  203 
  204         irdma_wmb();            /* need write memory block before writing the WQE header. */
  205 
  206         set_64bit_val(wqe, IRDMA_BYTE_24,
  207                       FIELD_PREP(IRDMA_UDA_CQPSQ_MG_WQEVALID, cqp->polarity) |
  208                       FIELD_PREP(IRDMA_UDA_CQPSQ_MG_OPCODE, op) |
  209                       FIELD_PREP(IRDMA_UDA_CQPSQ_MG_MGIDX, info->mg_id) |
  210                       FIELD_PREP(IRDMA_UDA_CQPSQ_MG_VLANVALID, info->vlan_valid) |
  211                       FIELD_PREP(IRDMA_UDA_CQPSQ_MG_IPV4VALID, info->ipv4_valid));
  212 
  213         irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MANAGE_MCG WQE", wqe,
  214                         IRDMA_CQP_WQE_SIZE * 8);
  215         irdma_debug_buf(cqp->dev, IRDMA_DEBUG_WQE, "MCG_HOST CTX WQE",
  216                         info->dma_mem_mc.va, IRDMA_MAX_MGS_PER_CTX * 8);
  217         irdma_sc_cqp_post_sq(cqp);
  218 
  219         return 0;
  220 }
  221 
  222 /**
  223  * irdma_compare_mgs - Compares two multicast group structures
  224  * @entry1: Multcast group info
  225  * @entry2: Multcast group info in context
  226  */
  227 static bool
  228 irdma_compare_mgs(struct irdma_mcast_grp_ctx_entry_info *entry1,
  229                   struct irdma_mcast_grp_ctx_entry_info *entry2)
  230 {
  231         if (entry1->dest_port == entry2->dest_port &&
  232             entry1->qp_id == entry2->qp_id)
  233                 return true;
  234 
  235         return false;
  236 }
  237 
  238 /**
  239  * irdma_sc_add_mcast_grp - Allocates mcast group entry in ctx
  240  * @ctx: Multcast group context
  241  * @mg: Multcast group info
  242  */
  243 int
  244 irdma_sc_add_mcast_grp(struct irdma_mcast_grp_info *ctx,
  245                        struct irdma_mcast_grp_ctx_entry_info *mg)
  246 {
  247         u32 idx;
  248         bool free_entry_found = false;
  249         u32 free_entry_idx = 0;
  250 
  251         /* find either an identical or a free entry for a multicast group */
  252         for (idx = 0; idx < IRDMA_MAX_MGS_PER_CTX; idx++) {
  253                 if (ctx->mg_ctx_info[idx].valid_entry) {
  254                         if (irdma_compare_mgs(&ctx->mg_ctx_info[idx], mg)) {
  255                                 ctx->mg_ctx_info[idx].use_cnt++;
  256                                 return 0;
  257                         }
  258                         continue;
  259                 }
  260                 if (!free_entry_found) {
  261                         free_entry_found = true;
  262                         free_entry_idx = idx;
  263                 }
  264         }
  265 
  266         if (free_entry_found) {
  267                 ctx->mg_ctx_info[free_entry_idx] = *mg;
  268                 ctx->mg_ctx_info[free_entry_idx].valid_entry = true;
  269                 ctx->mg_ctx_info[free_entry_idx].use_cnt = 1;
  270                 ctx->no_of_mgs++;
  271                 return 0;
  272         }
  273 
  274         return -ENOMEM;
  275 }
  276 
  277 /**
  278  * irdma_sc_del_mcast_grp - Delete mcast group
  279  * @ctx: Multcast group context
  280  * @mg: Multcast group info
  281  *
  282  * Finds and removes a specific mulicast group from context, all
  283  * parameters must match to remove a multicast group.
  284  */
  285 int
  286 irdma_sc_del_mcast_grp(struct irdma_mcast_grp_info *ctx,
  287                        struct irdma_mcast_grp_ctx_entry_info *mg)
  288 {
  289         u32 idx;
  290 
  291         /* find an entry in multicast group context */
  292         for (idx = 0; idx < IRDMA_MAX_MGS_PER_CTX; idx++) {
  293                 if (!ctx->mg_ctx_info[idx].valid_entry)
  294                         continue;
  295 
  296                 if (irdma_compare_mgs(mg, &ctx->mg_ctx_info[idx])) {
  297                         ctx->mg_ctx_info[idx].use_cnt--;
  298 
  299                         if (!ctx->mg_ctx_info[idx].use_cnt) {
  300                                 ctx->mg_ctx_info[idx].valid_entry = false;
  301                                 ctx->no_of_mgs--;
  302                                 /* Remove gap if element was not the last */
  303                                 if (idx != ctx->no_of_mgs &&
  304                                     ctx->no_of_mgs > 0) {
  305                                         irdma_memcpy(&ctx->mg_ctx_info[idx],
  306                                                      &ctx->mg_ctx_info[ctx->no_of_mgs - 1],
  307                                                      sizeof(ctx->mg_ctx_info[idx]));
  308                                         ctx->mg_ctx_info[ctx->no_of_mgs - 1].valid_entry = false;
  309                                 }
  310                         }
  311 
  312                         return 0;
  313                 }
  314         }
  315 
  316         return -EINVAL;
  317 }

Cache object: 808cf0b916283ba93ec8cee66c66cfb2


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