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 */ 61 void 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 */ 84 void 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 */ 125 void 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 */ 161 void 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 */ 195 void 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 */ 229 void 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 */ 276 void 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 */ 314 void 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 */ 346 void 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 } 391