linux/drivers/infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c
<<
>>
Prefs
   1/*
   2 * Copyright(c) 2017 Intel Corporation.
   3 *
   4 * This file is provided under a dual BSD/GPLv2 license.  When using or
   5 * redistributing this file, you may do so under either license.
   6 *
   7 * GPL LICENSE SUMMARY
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of version 2 of the GNU General Public License as
  11 * published by the Free Software Foundation.
  12 *
  13 * This program is distributed in the hope that it will be useful, but
  14 * WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16 * General Public License for more details.
  17 *
  18 * BSD LICENSE
  19 *
  20 * Redistribution and use in source and binary forms, with or without
  21 * modification, are permitted provided that the following conditions
  22 * are met:
  23 *
  24 *  - Redistributions of source code must retain the above copyright
  25 *    notice, this list of conditions and the following disclaimer.
  26 *  - Redistributions in binary form must reproduce the above copyright
  27 *    notice, this list of conditions and the following disclaimer in
  28 *    the documentation and/or other materials provided with the
  29 *    distribution.
  30 *  - Neither the name of Intel Corporation nor the names of its
  31 *    contributors may be used to endorse or promote products derived
  32 *    from this software without specific prior written permission.
  33 *
  34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  35 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  36 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  37 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  38 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  45 *
  46 */
  47
  48/*
  49 * This file contains OPA VNIC EMA Interface functions.
  50 */
  51
  52#include "opa_vnic_internal.h"
  53
  54/**
  55 * opa_vnic_vema_report_event - sent trap to report the specified event
  56 * @adapter: vnic port adapter
  57 * @event: event to be reported
  58 *
  59 * This function calls vema api to sent a trap for the given event.
  60 */
  61void opa_vnic_vema_report_event(struct opa_vnic_adapter *adapter, u8 event)
  62{
  63        struct __opa_veswport_info *info = &adapter->info;
  64        struct __opa_veswport_trap trap_data;
  65
  66        trap_data.fabric_id = info->vesw.fabric_id;
  67        trap_data.veswid = info->vesw.vesw_id;
  68        trap_data.veswportnum = info->vport.port_num;
  69        trap_data.opaportnum = adapter->port_num;
  70        trap_data.veswportindex = adapter->vport_num;
  71        trap_data.opcode = event;
  72
  73        opa_vnic_vema_send_trap(adapter, &trap_data, info->vport.encap_slid);
  74}
  75
  76/**
  77 * opa_vnic_get_error_counters - get summary counters
  78 * @adapter: vnic port adapter
  79 * @cntrs: pointer to destination summary counters structure
  80 *
  81 * This function populates the summary counters that is maintained by the
  82 * given adapter to destination address provided.
  83 */
  84void opa_vnic_get_summary_counters(struct opa_vnic_adapter *adapter,
  85                                   struct opa_veswport_summary_counters *cntrs)
  86{
  87        struct opa_vnic_stats vstats;
  88        __be64 *dst;
  89        u64 *src;
  90
  91        memset(&vstats, 0, sizeof(vstats));
  92        spin_lock(&adapter->stats_lock);
  93        adapter->rn_ops->ndo_get_stats64(adapter->netdev, &vstats.netstats);
  94        spin_unlock(&adapter->stats_lock);
  95
  96        cntrs->vp_instance = cpu_to_be16(adapter->vport_num);
  97        cntrs->vesw_id = cpu_to_be16(adapter->info.vesw.vesw_id);
  98        cntrs->veswport_num = cpu_to_be32(adapter->port_num);
  99
 100        cntrs->tx_errors = cpu_to_be64(vstats.netstats.tx_errors);
 101        cntrs->rx_errors = cpu_to_be64(vstats.netstats.rx_errors);
 102        cntrs->tx_packets = cpu_to_be64(vstats.netstats.tx_packets);
 103        cntrs->rx_packets = cpu_to_be64(vstats.netstats.rx_packets);
 104        cntrs->tx_bytes = cpu_to_be64(vstats.netstats.tx_bytes);
 105        cntrs->rx_bytes = cpu_to_be64(vstats.netstats.rx_bytes);
 106
 107        /*
 108         * This loop depends on layout of
 109         * opa_veswport_summary_counters opa_vnic_stats structures.
 110         */
 111        for (dst = &cntrs->tx_unicast, src = &vstats.tx_grp.unicast;
 112             dst < &cntrs->reserved[0]; dst++, src++) {
 113                *dst = cpu_to_be64(*src);
 114        }
 115}
 116
 117/**
 118 * opa_vnic_get_error_counters - get error counters
 119 * @adapter: vnic port adapter
 120 * @cntrs: pointer to destination error counters structure
 121 *
 122 * This function populates the error counters that is maintained by the
 123 * given adapter to destination address provided.
 124 */
 125void opa_vnic_get_error_counters(struct opa_vnic_adapter *adapter,
 126                                 struct opa_veswport_error_counters *cntrs)
 127{
 128        struct opa_vnic_stats vstats;
 129
 130        memset(&vstats, 0, sizeof(vstats));
 131        spin_lock(&adapter->stats_lock);
 132        adapter->rn_ops->ndo_get_stats64(adapter->netdev, &vstats.netstats);
 133        spin_unlock(&adapter->stats_lock);
 134
 135        cntrs->vp_instance = cpu_to_be16(adapter->vport_num);
 136        cntrs->vesw_id = cpu_to_be16(adapter->info.vesw.vesw_id);
 137        cntrs->veswport_num = cpu_to_be32(adapter->port_num);
 138
 139        cntrs->tx_errors = cpu_to_be64(vstats.netstats.tx_errors);
 140        cntrs->rx_errors = cpu_to_be64(vstats.netstats.rx_errors);
 141        cntrs->tx_dlid_zero = cpu_to_be64(vstats.tx_dlid_zero);
 142        cntrs->tx_drop_state = cpu_to_be64(vstats.tx_drop_state);
 143        cntrs->tx_logic = cpu_to_be64(vstats.netstats.tx_fifo_errors +
 144                                      vstats.netstats.tx_carrier_errors);
 145
 146        cntrs->rx_bad_veswid = cpu_to_be64(vstats.netstats.rx_nohandler);
 147        cntrs->rx_runt = cpu_to_be64(vstats.rx_runt);
 148        cntrs->rx_oversize = cpu_to_be64(vstats.rx_oversize);
 149        cntrs->rx_drop_state = cpu_to_be64(vstats.rx_drop_state);
 150        cntrs->rx_logic = cpu_to_be64(vstats.netstats.rx_fifo_errors);
 151}
 152
 153/**
 154 * opa_vnic_get_vesw_info -- Get the vesw information
 155 * @adapter: vnic port adapter
 156 * @info: pointer to destination vesw info structure
 157 *
 158 * This function copies the vesw info that is maintained by the
 159 * given adapter to destination address provided.
 160 */
 161void opa_vnic_get_vesw_info(struct opa_vnic_adapter *adapter,
 162                            struct opa_vesw_info *info)
 163{
 164        struct __opa_vesw_info *src = &adapter->info.vesw;
 165        int i;
 166
 167        info->fabric_id = cpu_to_be16(src->fabric_id);
 168        info->vesw_id = cpu_to_be16(src->vesw_id);
 169        memcpy(info->rsvd0, src->rsvd0, ARRAY_SIZE(src->rsvd0));
 170        info->def_port_mask = cpu_to_be16(src->def_port_mask);
 171        memcpy(info->rsvd1, src->rsvd1, ARRAY_SIZE(src->rsvd1));
 172        info->pkey = cpu_to_be16(src->pkey);
 173
 174        memcpy(info->rsvd2, src->rsvd2, ARRAY_SIZE(src->rsvd2));
 175        info->u_mcast_dlid = cpu_to_be32(src->u_mcast_dlid);
 176        for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++)
 177                info->u_ucast_dlid[i] = cpu_to_be32(src->u_ucast_dlid[i]);
 178
 179        memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3));
 180        for (i = 0; i < OPA_VNIC_MAX_NUM_PCP; i++)
 181                info->eth_mtu[i] = cpu_to_be16(src->eth_mtu[i]);
 182
 183        info->eth_mtu_non_vlan = cpu_to_be16(src->eth_mtu_non_vlan);
 184        memcpy(info->rsvd4, src->rsvd4, ARRAY_SIZE(src->rsvd4));
 185}
 186
 187/**
 188 * opa_vnic_set_vesw_info -- Set the vesw information
 189 * @adapter: vnic port adapter
 190 * @info: pointer to vesw info structure
 191 *
 192 * This function updates the vesw info that is maintained by the
 193 * given adapter with vesw info provided. Reserved fields are stored
 194 * and returned back to EM as is.
 195 */
 196void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter,
 197                            struct opa_vesw_info *info)
 198{
 199        struct __opa_vesw_info *dst = &adapter->info.vesw;
 200        int i;
 201
 202        dst->fabric_id = be16_to_cpu(info->fabric_id);
 203        dst->vesw_id = be16_to_cpu(info->vesw_id);
 204        memcpy(dst->rsvd0, info->rsvd0, ARRAY_SIZE(info->rsvd0));
 205        dst->def_port_mask = be16_to_cpu(info->def_port_mask);
 206        memcpy(dst->rsvd1, info->rsvd1, ARRAY_SIZE(info->rsvd1));
 207        dst->pkey = be16_to_cpu(info->pkey);
 208
 209        memcpy(dst->rsvd2, info->rsvd2, ARRAY_SIZE(info->rsvd2));
 210        dst->u_mcast_dlid = be32_to_cpu(info->u_mcast_dlid);
 211        for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++)
 212                dst->u_ucast_dlid[i] = be32_to_cpu(info->u_ucast_dlid[i]);
 213
 214        memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3));
 215        for (i = 0; i < OPA_VNIC_MAX_NUM_PCP; i++)
 216                dst->eth_mtu[i] = be16_to_cpu(info->eth_mtu[i]);
 217
 218        dst->eth_mtu_non_vlan = be16_to_cpu(info->eth_mtu_non_vlan);
 219        memcpy(dst->rsvd4, info->rsvd4, ARRAY_SIZE(info->rsvd4));
 220}
 221
 222/**
 223 * opa_vnic_get_per_veswport_info -- Get the vesw per port information
 224 * @adapter: vnic port adapter
 225 * @info: pointer to destination vport info structure
 226 *
 227 * This function copies the vesw per port info that is maintained by the
 228 * given adapter to destination address provided.
 229 * Note that the read only fields are not copied.
 230 */
 231void opa_vnic_get_per_veswport_info(struct opa_vnic_adapter *adapter,
 232                                    struct opa_per_veswport_info *info)
 233{
 234        struct __opa_per_veswport_info *src = &adapter->info.vport;
 235
 236        info->port_num = cpu_to_be32(src->port_num);
 237        info->eth_link_status = src->eth_link_status;
 238        memcpy(info->rsvd0, src->rsvd0, ARRAY_SIZE(src->rsvd0));
 239
 240        memcpy(info->base_mac_addr, src->base_mac_addr,
 241               ARRAY_SIZE(info->base_mac_addr));
 242        info->config_state = src->config_state;
 243        info->oper_state = src->oper_state;
 244        info->max_mac_tbl_ent = cpu_to_be16(src->max_mac_tbl_ent);
 245        info->max_smac_ent = cpu_to_be16(src->max_smac_ent);
 246        info->mac_tbl_digest = cpu_to_be32(src->mac_tbl_digest);
 247        memcpy(info->rsvd1, src->rsvd1, ARRAY_SIZE(src->rsvd1));
 248
 249        info->encap_slid = cpu_to_be32(src->encap_slid);
 250        memcpy(info->pcp_to_sc_uc, src->pcp_to_sc_uc,
 251               ARRAY_SIZE(info->pcp_to_sc_uc));
 252        memcpy(info->pcp_to_vl_uc, src->pcp_to_vl_uc,
 253               ARRAY_SIZE(info->pcp_to_vl_uc));
 254        memcpy(info->pcp_to_sc_mc, src->pcp_to_sc_mc,
 255               ARRAY_SIZE(info->pcp_to_sc_mc));
 256        memcpy(info->pcp_to_vl_mc, src->pcp_to_vl_mc,
 257               ARRAY_SIZE(info->pcp_to_vl_mc));
 258        info->non_vlan_sc_uc = src->non_vlan_sc_uc;
 259        info->non_vlan_vl_uc = src->non_vlan_vl_uc;
 260        info->non_vlan_sc_mc = src->non_vlan_sc_mc;
 261        info->non_vlan_vl_mc = src->non_vlan_vl_mc;
 262        memcpy(info->rsvd2, src->rsvd2, ARRAY_SIZE(src->rsvd2));
 263
 264        info->uc_macs_gen_count = cpu_to_be16(src->uc_macs_gen_count);
 265        info->mc_macs_gen_count = cpu_to_be16(src->mc_macs_gen_count);
 266        memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3));
 267}
 268
 269/**
 270 * opa_vnic_set_per_veswport_info -- Set vesw per port information
 271 * @adapter: vnic port adapter
 272 * @info: pointer to vport info structure
 273 *
 274 * This function updates the vesw per port info that is maintained by the
 275 * given adapter with vesw per port info provided. Reserved fields are
 276 * stored and returned back to EM as is.
 277 */
 278void opa_vnic_set_per_veswport_info(struct opa_vnic_adapter *adapter,
 279                                    struct opa_per_veswport_info *info)
 280{
 281        struct __opa_per_veswport_info *dst = &adapter->info.vport;
 282
 283        dst->port_num = be32_to_cpu(info->port_num);
 284        memcpy(dst->rsvd0, info->rsvd0, ARRAY_SIZE(info->rsvd0));
 285
 286        memcpy(dst->base_mac_addr, info->base_mac_addr,
 287               ARRAY_SIZE(dst->base_mac_addr));
 288        dst->config_state = info->config_state;
 289        memcpy(dst->rsvd1, info->rsvd1, ARRAY_SIZE(info->rsvd1));
 290
 291        dst->encap_slid = be32_to_cpu(info->encap_slid);
 292        memcpy(dst->pcp_to_sc_uc, info->pcp_to_sc_uc,
 293               ARRAY_SIZE(dst->pcp_to_sc_uc));
 294        memcpy(dst->pcp_to_vl_uc, info->pcp_to_vl_uc,
 295               ARRAY_SIZE(dst->pcp_to_vl_uc));
 296        memcpy(dst->pcp_to_sc_mc, info->pcp_to_sc_mc,
 297               ARRAY_SIZE(dst->pcp_to_sc_mc));
 298        memcpy(dst->pcp_to_vl_mc, info->pcp_to_vl_mc,
 299               ARRAY_SIZE(dst->pcp_to_vl_mc));
 300        dst->non_vlan_sc_uc = info->non_vlan_sc_uc;
 301        dst->non_vlan_vl_uc = info->non_vlan_vl_uc;
 302        dst->non_vlan_sc_mc = info->non_vlan_sc_mc;
 303        dst->non_vlan_vl_mc = info->non_vlan_vl_mc;
 304        memcpy(dst->rsvd2, info->rsvd2, ARRAY_SIZE(info->rsvd2));
 305        memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3));
 306}
 307
 308/**
 309 * opa_vnic_query_mcast_macs - query multicast mac list
 310 * @adapter: vnic port adapter
 311 * @macs: pointer mac list
 312 *
 313 * This function populates the provided mac list with the configured
 314 * multicast addresses in the adapter.
 315 */
 316void opa_vnic_query_mcast_macs(struct opa_vnic_adapter *adapter,
 317                               struct opa_veswport_iface_macs *macs)
 318{
 319        u16 start_idx, num_macs, idx = 0, count = 0;
 320        struct netdev_hw_addr *ha;
 321
 322        start_idx = be16_to_cpu(macs->start_idx);
 323        num_macs = be16_to_cpu(macs->num_macs_in_msg);
 324        netdev_for_each_mc_addr(ha, adapter->netdev) {
 325                struct opa_vnic_iface_mac_entry *entry = &macs->entry[count];
 326
 327                if (start_idx > idx++)
 328                        continue;
 329                else if (num_macs == count)
 330                        break;
 331                memcpy(entry, ha->addr, sizeof(*entry));
 332                count++;
 333        }
 334
 335        macs->tot_macs_in_lst = cpu_to_be16(netdev_mc_count(adapter->netdev));
 336        macs->num_macs_in_msg = cpu_to_be16(count);
 337        macs->gen_count = cpu_to_be16(adapter->info.vport.mc_macs_gen_count);
 338}
 339
 340/**
 341 * opa_vnic_query_ucast_macs - query unicast mac list
 342 * @adapter: vnic port adapter
 343 * @macs: pointer mac list
 344 *
 345 * This function populates the provided mac list with the configured
 346 * unicast addresses in the adapter.
 347 */
 348void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter,
 349                               struct opa_veswport_iface_macs *macs)
 350{
 351        u16 start_idx, tot_macs, num_macs, idx = 0, count = 0;
 352        struct netdev_hw_addr *ha;
 353
 354        start_idx = be16_to_cpu(macs->start_idx);
 355        num_macs = be16_to_cpu(macs->num_macs_in_msg);
 356        /* loop through dev_addrs list first */
 357        for_each_dev_addr(adapter->netdev, ha) {
 358                struct opa_vnic_iface_mac_entry *entry = &macs->entry[count];
 359
 360                /* Do not include EM specified MAC address */
 361                if (!memcmp(adapter->info.vport.base_mac_addr, ha->addr,
 362                            ARRAY_SIZE(adapter->info.vport.base_mac_addr)))
 363                        continue;
 364
 365                if (start_idx > idx++)
 366                        continue;
 367                else if (num_macs == count)
 368                        break;
 369                memcpy(entry, ha->addr, sizeof(*entry));
 370                count++;
 371        }
 372
 373        /* loop through uc list */
 374        netdev_for_each_uc_addr(ha, adapter->netdev) {
 375                struct opa_vnic_iface_mac_entry *entry = &macs->entry[count];
 376
 377                if (start_idx > idx++)
 378                        continue;
 379                else if (num_macs == count)
 380                        break;
 381                memcpy(entry, ha->addr, sizeof(*entry));
 382                count++;
 383        }
 384
 385        tot_macs = netdev_hw_addr_list_count(&adapter->netdev->dev_addrs) +
 386                   netdev_uc_count(adapter->netdev);
 387        macs->tot_macs_in_lst = cpu_to_be16(tot_macs);
 388        macs->num_macs_in_msg = cpu_to_be16(count);
 389        macs->gen_count = cpu_to_be16(adapter->info.vport.uc_macs_gen_count);
 390}
 391