cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

opa_vnic_vema_iface.c (14113B)


      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_summary_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	info->rc = cpu_to_be32(src->rc);
    180
    181	memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3));
    182	info->eth_mtu = cpu_to_be16(src->eth_mtu);
    183	memcpy(info->rsvd4, src->rsvd4, ARRAY_SIZE(src->rsvd4));
    184}
    185
    186/**
    187 * opa_vnic_set_vesw_info -- Set the vesw information
    188 * @adapter: vnic port adapter
    189 * @info: pointer to vesw info structure
    190 *
    191 * This function updates the vesw info that is maintained by the
    192 * given adapter with vesw info provided. Reserved fields are stored
    193 * and returned back to EM as is.
    194 */
    195void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter,
    196			    struct opa_vesw_info *info)
    197{
    198	struct __opa_vesw_info *dst = &adapter->info.vesw;
    199	int i;
    200
    201	dst->fabric_id = be16_to_cpu(info->fabric_id);
    202	dst->vesw_id = be16_to_cpu(info->vesw_id);
    203	memcpy(dst->rsvd0, info->rsvd0, ARRAY_SIZE(info->rsvd0));
    204	dst->def_port_mask = be16_to_cpu(info->def_port_mask);
    205	memcpy(dst->rsvd1, info->rsvd1, ARRAY_SIZE(info->rsvd1));
    206	dst->pkey = be16_to_cpu(info->pkey);
    207
    208	memcpy(dst->rsvd2, info->rsvd2, ARRAY_SIZE(info->rsvd2));
    209	dst->u_mcast_dlid = be32_to_cpu(info->u_mcast_dlid);
    210	for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++)
    211		dst->u_ucast_dlid[i] = be32_to_cpu(info->u_ucast_dlid[i]);
    212
    213	dst->rc = be32_to_cpu(info->rc);
    214
    215	memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3));
    216	dst->eth_mtu = be16_to_cpu(info->eth_mtu);
    217	memcpy(dst->rsvd4, info->rsvd4, ARRAY_SIZE(info->rsvd4));
    218}
    219
    220/**
    221 * opa_vnic_get_per_veswport_info -- Get the vesw per port information
    222 * @adapter: vnic port adapter
    223 * @info: pointer to destination vport info structure
    224 *
    225 * This function copies the vesw per port info that is maintained by the
    226 * given adapter to destination address provided.
    227 * Note that the read only fields are not copied.
    228 */
    229void opa_vnic_get_per_veswport_info(struct opa_vnic_adapter *adapter,
    230				    struct opa_per_veswport_info *info)
    231{
    232	struct __opa_per_veswport_info *src = &adapter->info.vport;
    233
    234	info->port_num = cpu_to_be32(src->port_num);
    235	info->eth_link_status = src->eth_link_status;
    236	memcpy(info->rsvd0, src->rsvd0, ARRAY_SIZE(src->rsvd0));
    237
    238	memcpy(info->base_mac_addr, src->base_mac_addr,
    239	       ARRAY_SIZE(info->base_mac_addr));
    240	info->config_state = src->config_state;
    241	info->oper_state = src->oper_state;
    242	info->max_mac_tbl_ent = cpu_to_be16(src->max_mac_tbl_ent);
    243	info->max_smac_ent = cpu_to_be16(src->max_smac_ent);
    244	info->mac_tbl_digest = cpu_to_be32(src->mac_tbl_digest);
    245	memcpy(info->rsvd1, src->rsvd1, ARRAY_SIZE(src->rsvd1));
    246
    247	info->encap_slid = cpu_to_be32(src->encap_slid);
    248	memcpy(info->pcp_to_sc_uc, src->pcp_to_sc_uc,
    249	       ARRAY_SIZE(info->pcp_to_sc_uc));
    250	memcpy(info->pcp_to_vl_uc, src->pcp_to_vl_uc,
    251	       ARRAY_SIZE(info->pcp_to_vl_uc));
    252	memcpy(info->pcp_to_sc_mc, src->pcp_to_sc_mc,
    253	       ARRAY_SIZE(info->pcp_to_sc_mc));
    254	memcpy(info->pcp_to_vl_mc, src->pcp_to_vl_mc,
    255	       ARRAY_SIZE(info->pcp_to_vl_mc));
    256	info->non_vlan_sc_uc = src->non_vlan_sc_uc;
    257	info->non_vlan_vl_uc = src->non_vlan_vl_uc;
    258	info->non_vlan_sc_mc = src->non_vlan_sc_mc;
    259	info->non_vlan_vl_mc = src->non_vlan_vl_mc;
    260	memcpy(info->rsvd2, src->rsvd2, ARRAY_SIZE(src->rsvd2));
    261
    262	info->uc_macs_gen_count = cpu_to_be16(src->uc_macs_gen_count);
    263	info->mc_macs_gen_count = cpu_to_be16(src->mc_macs_gen_count);
    264	memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3));
    265}
    266
    267/**
    268 * opa_vnic_set_per_veswport_info -- Set vesw per port information
    269 * @adapter: vnic port adapter
    270 * @info: pointer to vport info structure
    271 *
    272 * This function updates the vesw per port info that is maintained by the
    273 * given adapter with vesw per port info provided. Reserved fields are
    274 * stored and returned back to EM as is.
    275 */
    276void opa_vnic_set_per_veswport_info(struct opa_vnic_adapter *adapter,
    277				    struct opa_per_veswport_info *info)
    278{
    279	struct __opa_per_veswport_info *dst = &adapter->info.vport;
    280
    281	dst->port_num = be32_to_cpu(info->port_num);
    282	memcpy(dst->rsvd0, info->rsvd0, ARRAY_SIZE(info->rsvd0));
    283
    284	memcpy(dst->base_mac_addr, info->base_mac_addr,
    285	       ARRAY_SIZE(dst->base_mac_addr));
    286	dst->config_state = info->config_state;
    287	memcpy(dst->rsvd1, info->rsvd1, ARRAY_SIZE(info->rsvd1));
    288
    289	dst->encap_slid = be32_to_cpu(info->encap_slid);
    290	memcpy(dst->pcp_to_sc_uc, info->pcp_to_sc_uc,
    291	       ARRAY_SIZE(dst->pcp_to_sc_uc));
    292	memcpy(dst->pcp_to_vl_uc, info->pcp_to_vl_uc,
    293	       ARRAY_SIZE(dst->pcp_to_vl_uc));
    294	memcpy(dst->pcp_to_sc_mc, info->pcp_to_sc_mc,
    295	       ARRAY_SIZE(dst->pcp_to_sc_mc));
    296	memcpy(dst->pcp_to_vl_mc, info->pcp_to_vl_mc,
    297	       ARRAY_SIZE(dst->pcp_to_vl_mc));
    298	dst->non_vlan_sc_uc = info->non_vlan_sc_uc;
    299	dst->non_vlan_vl_uc = info->non_vlan_vl_uc;
    300	dst->non_vlan_sc_mc = info->non_vlan_sc_mc;
    301	dst->non_vlan_vl_mc = info->non_vlan_vl_mc;
    302	memcpy(dst->rsvd2, info->rsvd2, ARRAY_SIZE(info->rsvd2));
    303	memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3));
    304}
    305
    306/**
    307 * opa_vnic_query_mcast_macs - query multicast mac list
    308 * @adapter: vnic port adapter
    309 * @macs: pointer mac list
    310 *
    311 * This function populates the provided mac list with the configured
    312 * multicast addresses in the adapter.
    313 */
    314void opa_vnic_query_mcast_macs(struct opa_vnic_adapter *adapter,
    315			       struct opa_veswport_iface_macs *macs)
    316{
    317	u16 start_idx, num_macs, idx = 0, count = 0;
    318	struct netdev_hw_addr *ha;
    319
    320	start_idx = be16_to_cpu(macs->start_idx);
    321	num_macs = be16_to_cpu(macs->num_macs_in_msg);
    322	netdev_for_each_mc_addr(ha, adapter->netdev) {
    323		struct opa_vnic_iface_mac_entry *entry = &macs->entry[count];
    324
    325		if (start_idx > idx++)
    326			continue;
    327		else if (num_macs == count)
    328			break;
    329		memcpy(entry, ha->addr, sizeof(*entry));
    330		count++;
    331	}
    332
    333	macs->tot_macs_in_lst = cpu_to_be16(netdev_mc_count(adapter->netdev));
    334	macs->num_macs_in_msg = cpu_to_be16(count);
    335	macs->gen_count = cpu_to_be16(adapter->info.vport.mc_macs_gen_count);
    336}
    337
    338/**
    339 * opa_vnic_query_ucast_macs - query unicast mac list
    340 * @adapter: vnic port adapter
    341 * @macs: pointer mac list
    342 *
    343 * This function populates the provided mac list with the configured
    344 * unicast addresses in the adapter.
    345 */
    346void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter,
    347			       struct opa_veswport_iface_macs *macs)
    348{
    349	u16 start_idx, tot_macs, num_macs, idx = 0, count = 0, em_macs = 0;
    350	struct netdev_hw_addr *ha;
    351
    352	start_idx = be16_to_cpu(macs->start_idx);
    353	num_macs = be16_to_cpu(macs->num_macs_in_msg);
    354	/* loop through dev_addrs list first */
    355	for_each_dev_addr(adapter->netdev, ha) {
    356		struct opa_vnic_iface_mac_entry *entry = &macs->entry[count];
    357
    358		/* Do not include EM specified MAC address */
    359		if (!memcmp(adapter->info.vport.base_mac_addr, ha->addr,
    360			    ARRAY_SIZE(adapter->info.vport.base_mac_addr))) {
    361			em_macs++;
    362			continue;
    363		}
    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) - em_macs;
    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}