File Index
Files and directories
Sign in
FILE

opa_vnic_vema_iface.c

File preview with syntax highlighting.

linux-6.19.14/drivers/infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c C
  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}
~/ Read-only file preview.