2 * Copyright(c) 2017 Intel Corporation.
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.
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.
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.
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
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
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.
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.
49 * This file contains OPA VNIC EMA Interface functions.
52 #include "opa_vnic_internal.h"
55 * opa_vnic_vema_report_event - sent trap to report the specified event
56 * @adapter: vnic port adapter
57 * @event: event to be reported
59 * This function calls vema api to sent a trap for the given event.
61 void opa_vnic_vema_report_event(struct opa_vnic_adapter
*adapter
, u8 event
)
63 struct __opa_veswport_info
*info
= &adapter
->info
;
64 struct __opa_veswport_trap trap_data
;
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
;
73 opa_vnic_vema_send_trap(adapter
, &trap_data
, info
->vport
.encap_slid
);
77 * opa_vnic_get_summary_counters - get summary counters
78 * @adapter: vnic port adapter
79 * @cntrs: pointer to destination summary counters structure
81 * This function populates the summary counters that is maintained by the
82 * given adapter to destination address provided.
84 void opa_vnic_get_summary_counters(struct opa_vnic_adapter
*adapter
,
85 struct opa_veswport_summary_counters
*cntrs
)
87 struct opa_vnic_stats vstats
;
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
);
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
);
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
);
108 * This loop depends on layout of
109 * opa_veswport_summary_counters opa_vnic_stats structures.
111 for (dst
= &cntrs
->tx_unicast
, src
= &vstats
.tx_grp
.unicast
;
112 dst
< &cntrs
->reserved
[0]; dst
++, src
++) {
113 *dst
= cpu_to_be64(*src
);
118 * opa_vnic_get_error_counters - get error counters
119 * @adapter: vnic port adapter
120 * @cntrs: pointer to destination error counters structure
122 * This function populates the error counters that is maintained by the
123 * given adapter to destination address provided.
125 void opa_vnic_get_error_counters(struct opa_vnic_adapter
*adapter
,
126 struct opa_veswport_error_counters
*cntrs
)
128 struct opa_vnic_stats vstats
;
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
);
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
);
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
);
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
);
154 * opa_vnic_get_vesw_info -- Get the vesw information
155 * @adapter: vnic port adapter
156 * @info: pointer to destination vesw info structure
158 * This function copies the vesw info that is maintained by the
159 * given adapter to destination address provided.
161 void opa_vnic_get_vesw_info(struct opa_vnic_adapter
*adapter
,
162 struct opa_vesw_info
*info
)
164 struct __opa_vesw_info
*src
= &adapter
->info
.vesw
;
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
);
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
]);
179 info
->rc
= cpu_to_be32(src
->rc
);
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
));
187 * opa_vnic_set_vesw_info -- Set the vesw information
188 * @adapter: vnic port adapter
189 * @info: pointer to vesw info structure
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.
195 void opa_vnic_set_vesw_info(struct opa_vnic_adapter
*adapter
,
196 struct opa_vesw_info
*info
)
198 struct __opa_vesw_info
*dst
= &adapter
->info
.vesw
;
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
);
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
]);
213 dst
->rc
= be32_to_cpu(info
->rc
);
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
));
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
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.
229 void opa_vnic_get_per_veswport_info(struct opa_vnic_adapter
*adapter
,
230 struct opa_per_veswport_info
*info
)
232 struct __opa_per_veswport_info
*src
= &adapter
->info
.vport
;
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
));
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
));
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
));
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
));
268 * opa_vnic_set_per_veswport_info -- Set vesw per port information
269 * @adapter: vnic port adapter
270 * @info: pointer to vport info structure
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.
276 void opa_vnic_set_per_veswport_info(struct opa_vnic_adapter
*adapter
,
277 struct opa_per_veswport_info
*info
)
279 struct __opa_per_veswport_info
*dst
= &adapter
->info
.vport
;
281 dst
->port_num
= be32_to_cpu(info
->port_num
);
282 memcpy(dst
->rsvd0
, info
->rsvd0
, ARRAY_SIZE(info
->rsvd0
));
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
));
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
));
307 * opa_vnic_query_mcast_macs - query multicast mac list
308 * @adapter: vnic port adapter
309 * @macs: pointer mac list
311 * This function populates the provided mac list with the configured
312 * multicast addresses in the adapter.
314 void opa_vnic_query_mcast_macs(struct opa_vnic_adapter
*adapter
,
315 struct opa_veswport_iface_macs
*macs
)
317 u16 start_idx
, num_macs
, idx
= 0, count
= 0;
318 struct netdev_hw_addr
*ha
;
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
];
325 if (start_idx
> idx
++)
327 else if (num_macs
== count
)
329 memcpy(entry
, ha
->addr
, sizeof(*entry
));
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
);
339 * opa_vnic_query_ucast_macs - query unicast mac list
340 * @adapter: vnic port adapter
341 * @macs: pointer mac list
343 * This function populates the provided mac list with the configured
344 * unicast addresses in the adapter.
346 void opa_vnic_query_ucast_macs(struct opa_vnic_adapter
*adapter
,
347 struct opa_veswport_iface_macs
*macs
)
349 u16 start_idx
, tot_macs
, num_macs
, idx
= 0, count
= 0, em_macs
= 0;
350 struct netdev_hw_addr
*ha
;
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
];
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
))) {
365 if (start_idx
> idx
++)
367 else if (num_macs
== count
)
369 memcpy(entry
, ha
->addr
, sizeof(*entry
));
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
];
377 if (start_idx
> idx
++)
379 else if (num_macs
== count
)
381 memcpy(entry
, ha
->addr
, sizeof(*entry
));
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
);