1 // SPDX-License-Identifier: GPL-2.0 2 /* Huawei HiNIC PCI Express Linux driver 3 * Copyright(c) 2017 Huawei Technologies Co., Ltd 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * for more details. 13 * 14 */ 15 16 #include <linux/kernel.h> 17 #include <linux/pci.h> 18 #include <linux/device.h> 19 #include <linux/module.h> 20 #include <linux/types.h> 21 #include <linux/errno.h> 22 #include <linux/interrupt.h> 23 #include <linux/etherdevice.h> 24 #include <linux/netdevice.h> 25 #include <linux/if_vlan.h> 26 #include <linux/ethtool.h> 27 #include <linux/vmalloc.h> 28 29 #include "hinic_hw_qp.h" 30 #include "hinic_hw_dev.h" 31 #include "hinic_port.h" 32 #include "hinic_tx.h" 33 #include "hinic_rx.h" 34 #include "hinic_dev.h" 35 36 static void set_link_speed(struct ethtool_link_ksettings *link_ksettings, 37 enum hinic_speed speed) 38 { 39 switch (speed) { 40 case HINIC_SPEED_10MB_LINK: 41 link_ksettings->base.speed = SPEED_10; 42 break; 43 44 case HINIC_SPEED_100MB_LINK: 45 link_ksettings->base.speed = SPEED_100; 46 break; 47 48 case HINIC_SPEED_1000MB_LINK: 49 link_ksettings->base.speed = SPEED_1000; 50 break; 51 52 case HINIC_SPEED_10GB_LINK: 53 link_ksettings->base.speed = SPEED_10000; 54 break; 55 56 case HINIC_SPEED_25GB_LINK: 57 link_ksettings->base.speed = SPEED_25000; 58 break; 59 60 case HINIC_SPEED_40GB_LINK: 61 link_ksettings->base.speed = SPEED_40000; 62 break; 63 64 case HINIC_SPEED_100GB_LINK: 65 link_ksettings->base.speed = SPEED_100000; 66 break; 67 68 default: 69 link_ksettings->base.speed = SPEED_UNKNOWN; 70 break; 71 } 72 } 73 74 static int hinic_get_link_ksettings(struct net_device *netdev, 75 struct ethtool_link_ksettings 76 *link_ksettings) 77 { 78 struct hinic_dev *nic_dev = netdev_priv(netdev); 79 enum hinic_port_link_state link_state; 80 struct hinic_port_cap port_cap; 81 int err; 82 83 ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising); 84 ethtool_link_ksettings_add_link_mode(link_ksettings, supported, 85 Autoneg); 86 87 link_ksettings->base.speed = SPEED_UNKNOWN; 88 link_ksettings->base.autoneg = AUTONEG_DISABLE; 89 link_ksettings->base.duplex = DUPLEX_UNKNOWN; 90 91 err = hinic_port_get_cap(nic_dev, &port_cap); 92 if (err) 93 return err; 94 95 err = hinic_port_link_state(nic_dev, &link_state); 96 if (err) 97 return err; 98 99 if (link_state != HINIC_LINK_STATE_UP) 100 return err; 101 102 set_link_speed(link_ksettings, port_cap.speed); 103 104 if (!!(port_cap.autoneg_cap & HINIC_AUTONEG_SUPPORTED)) 105 ethtool_link_ksettings_add_link_mode(link_ksettings, 106 advertising, Autoneg); 107 108 if (port_cap.autoneg_state == HINIC_AUTONEG_ACTIVE) 109 link_ksettings->base.autoneg = AUTONEG_ENABLE; 110 111 link_ksettings->base.duplex = (port_cap.duplex == HINIC_DUPLEX_FULL) ? 112 DUPLEX_FULL : DUPLEX_HALF; 113 return 0; 114 } 115 116 static void hinic_get_drvinfo(struct net_device *netdev, 117 struct ethtool_drvinfo *info) 118 { 119 struct hinic_dev *nic_dev = netdev_priv(netdev); 120 struct hinic_hwdev *hwdev = nic_dev->hwdev; 121 struct hinic_hwif *hwif = hwdev->hwif; 122 123 strlcpy(info->driver, HINIC_DRV_NAME, sizeof(info->driver)); 124 strlcpy(info->bus_info, pci_name(hwif->pdev), sizeof(info->bus_info)); 125 } 126 127 static void hinic_get_ringparam(struct net_device *netdev, 128 struct ethtool_ringparam *ring) 129 { 130 ring->rx_max_pending = HINIC_RQ_DEPTH; 131 ring->tx_max_pending = HINIC_SQ_DEPTH; 132 ring->rx_pending = HINIC_RQ_DEPTH; 133 ring->tx_pending = HINIC_SQ_DEPTH; 134 } 135 136 static void hinic_get_channels(struct net_device *netdev, 137 struct ethtool_channels *channels) 138 { 139 struct hinic_dev *nic_dev = netdev_priv(netdev); 140 struct hinic_hwdev *hwdev = nic_dev->hwdev; 141 142 channels->max_rx = hwdev->nic_cap.max_qps; 143 channels->max_tx = hwdev->nic_cap.max_qps; 144 channels->max_other = 0; 145 channels->max_combined = 0; 146 channels->rx_count = hinic_hwdev_num_qps(hwdev); 147 channels->tx_count = hinic_hwdev_num_qps(hwdev); 148 channels->other_count = 0; 149 channels->combined_count = 0; 150 } 151 152 static int hinic_get_rss_hash_opts(struct hinic_dev *nic_dev, 153 struct ethtool_rxnfc *cmd) 154 { 155 struct hinic_rss_type rss_type = { 0 }; 156 int err; 157 158 cmd->data = 0; 159 160 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 161 return 0; 162 163 err = hinic_get_rss_type(nic_dev, nic_dev->rss_tmpl_idx, 164 &rss_type); 165 if (err) 166 return err; 167 168 cmd->data = RXH_IP_SRC | RXH_IP_DST; 169 switch (cmd->flow_type) { 170 case TCP_V4_FLOW: 171 if (rss_type.tcp_ipv4) 172 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 173 break; 174 case TCP_V6_FLOW: 175 if (rss_type.tcp_ipv6) 176 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 177 break; 178 case UDP_V4_FLOW: 179 if (rss_type.udp_ipv4) 180 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 181 break; 182 case UDP_V6_FLOW: 183 if (rss_type.udp_ipv6) 184 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 185 break; 186 case IPV4_FLOW: 187 case IPV6_FLOW: 188 break; 189 default: 190 cmd->data = 0; 191 return -EINVAL; 192 } 193 194 return 0; 195 } 196 197 static int set_l4_rss_hash_ops(struct ethtool_rxnfc *cmd, 198 struct hinic_rss_type *rss_type) 199 { 200 u8 rss_l4_en = 0; 201 202 switch (cmd->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 203 case 0: 204 rss_l4_en = 0; 205 break; 206 case (RXH_L4_B_0_1 | RXH_L4_B_2_3): 207 rss_l4_en = 1; 208 break; 209 default: 210 return -EINVAL; 211 } 212 213 switch (cmd->flow_type) { 214 case TCP_V4_FLOW: 215 rss_type->tcp_ipv4 = rss_l4_en; 216 break; 217 case TCP_V6_FLOW: 218 rss_type->tcp_ipv6 = rss_l4_en; 219 break; 220 case UDP_V4_FLOW: 221 rss_type->udp_ipv4 = rss_l4_en; 222 break; 223 case UDP_V6_FLOW: 224 rss_type->udp_ipv6 = rss_l4_en; 225 break; 226 default: 227 return -EINVAL; 228 } 229 230 return 0; 231 } 232 233 static int hinic_set_rss_hash_opts(struct hinic_dev *nic_dev, 234 struct ethtool_rxnfc *cmd) 235 { 236 struct hinic_rss_type *rss_type = &nic_dev->rss_type; 237 int err; 238 239 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) { 240 cmd->data = 0; 241 return -EOPNOTSUPP; 242 } 243 244 /* RSS does not support anything other than hashing 245 * to queues on src and dst IPs and ports 246 */ 247 if (cmd->data & ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | 248 RXH_L4_B_2_3)) 249 return -EINVAL; 250 251 /* We need at least the IP SRC and DEST fields for hashing */ 252 if (!(cmd->data & RXH_IP_SRC) || !(cmd->data & RXH_IP_DST)) 253 return -EINVAL; 254 255 err = hinic_get_rss_type(nic_dev, 256 nic_dev->rss_tmpl_idx, rss_type); 257 if (err) 258 return -EFAULT; 259 260 switch (cmd->flow_type) { 261 case TCP_V4_FLOW: 262 case TCP_V6_FLOW: 263 case UDP_V4_FLOW: 264 case UDP_V6_FLOW: 265 err = set_l4_rss_hash_ops(cmd, rss_type); 266 if (err) 267 return err; 268 break; 269 case IPV4_FLOW: 270 rss_type->ipv4 = 1; 271 break; 272 case IPV6_FLOW: 273 rss_type->ipv6 = 1; 274 break; 275 default: 276 return -EINVAL; 277 } 278 279 err = hinic_set_rss_type(nic_dev, nic_dev->rss_tmpl_idx, 280 *rss_type); 281 if (err) 282 return -EFAULT; 283 284 return 0; 285 } 286 287 static int __set_rss_rxfh(struct net_device *netdev, 288 const u32 *indir, const u8 *key) 289 { 290 struct hinic_dev *nic_dev = netdev_priv(netdev); 291 int err; 292 293 if (indir) { 294 if (!nic_dev->rss_indir_user) { 295 nic_dev->rss_indir_user = 296 kzalloc(sizeof(u32) * HINIC_RSS_INDIR_SIZE, 297 GFP_KERNEL); 298 if (!nic_dev->rss_indir_user) 299 return -ENOMEM; 300 } 301 302 memcpy(nic_dev->rss_indir_user, indir, 303 sizeof(u32) * HINIC_RSS_INDIR_SIZE); 304 305 err = hinic_rss_set_indir_tbl(nic_dev, 306 nic_dev->rss_tmpl_idx, indir); 307 if (err) 308 return -EFAULT; 309 } 310 311 if (key) { 312 if (!nic_dev->rss_hkey_user) { 313 nic_dev->rss_hkey_user = 314 kzalloc(HINIC_RSS_KEY_SIZE * 2, GFP_KERNEL); 315 316 if (!nic_dev->rss_hkey_user) 317 return -ENOMEM; 318 } 319 320 memcpy(nic_dev->rss_hkey_user, key, HINIC_RSS_KEY_SIZE); 321 322 err = hinic_rss_set_template_tbl(nic_dev, 323 nic_dev->rss_tmpl_idx, key); 324 if (err) 325 return -EFAULT; 326 } 327 328 return 0; 329 } 330 331 static int hinic_get_rxnfc(struct net_device *netdev, 332 struct ethtool_rxnfc *cmd, u32 *rule_locs) 333 { 334 struct hinic_dev *nic_dev = netdev_priv(netdev); 335 int err = 0; 336 337 switch (cmd->cmd) { 338 case ETHTOOL_GRXRINGS: 339 cmd->data = nic_dev->num_qps; 340 break; 341 case ETHTOOL_GRXFH: 342 err = hinic_get_rss_hash_opts(nic_dev, cmd); 343 break; 344 default: 345 err = -EOPNOTSUPP; 346 break; 347 } 348 349 return err; 350 } 351 352 static int hinic_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd) 353 { 354 struct hinic_dev *nic_dev = netdev_priv(netdev); 355 int err = 0; 356 357 switch (cmd->cmd) { 358 case ETHTOOL_SRXFH: 359 err = hinic_set_rss_hash_opts(nic_dev, cmd); 360 break; 361 default: 362 err = -EOPNOTSUPP; 363 break; 364 } 365 366 return err; 367 } 368 369 static int hinic_get_rxfh(struct net_device *netdev, 370 u32 *indir, u8 *key, u8 *hfunc) 371 { 372 struct hinic_dev *nic_dev = netdev_priv(netdev); 373 u8 hash_engine_type = 0; 374 int err = 0; 375 376 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 377 return -EOPNOTSUPP; 378 379 if (hfunc) { 380 err = hinic_rss_get_hash_engine(nic_dev, 381 nic_dev->rss_tmpl_idx, 382 &hash_engine_type); 383 if (err) 384 return -EFAULT; 385 386 *hfunc = hash_engine_type ? ETH_RSS_HASH_TOP : ETH_RSS_HASH_XOR; 387 } 388 389 if (indir) { 390 err = hinic_rss_get_indir_tbl(nic_dev, 391 nic_dev->rss_tmpl_idx, indir); 392 if (err) 393 return -EFAULT; 394 } 395 396 if (key) 397 err = hinic_rss_get_template_tbl(nic_dev, 398 nic_dev->rss_tmpl_idx, key); 399 400 return err; 401 } 402 403 static int hinic_set_rxfh(struct net_device *netdev, const u32 *indir, 404 const u8 *key, const u8 hfunc) 405 { 406 struct hinic_dev *nic_dev = netdev_priv(netdev); 407 int err = 0; 408 409 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 410 return -EOPNOTSUPP; 411 412 if (hfunc != ETH_RSS_HASH_NO_CHANGE) { 413 if (hfunc != ETH_RSS_HASH_TOP && hfunc != ETH_RSS_HASH_XOR) 414 return -EOPNOTSUPP; 415 416 nic_dev->rss_hash_engine = (hfunc == ETH_RSS_HASH_XOR) ? 417 HINIC_RSS_HASH_ENGINE_TYPE_XOR : 418 HINIC_RSS_HASH_ENGINE_TYPE_TOEP; 419 err = hinic_rss_set_hash_engine 420 (nic_dev, nic_dev->rss_tmpl_idx, 421 nic_dev->rss_hash_engine); 422 if (err) 423 return -EFAULT; 424 } 425 426 err = __set_rss_rxfh(netdev, indir, key); 427 428 return err; 429 } 430 431 static u32 hinic_get_rxfh_key_size(struct net_device *netdev) 432 { 433 return HINIC_RSS_KEY_SIZE; 434 } 435 436 static u32 hinic_get_rxfh_indir_size(struct net_device *netdev) 437 { 438 return HINIC_RSS_INDIR_SIZE; 439 } 440 441 static const struct ethtool_ops hinic_ethtool_ops = { 442 .get_link_ksettings = hinic_get_link_ksettings, 443 .get_drvinfo = hinic_get_drvinfo, 444 .get_link = ethtool_op_get_link, 445 .get_ringparam = hinic_get_ringparam, 446 .get_channels = hinic_get_channels, 447 .get_rxnfc = hinic_get_rxnfc, 448 .set_rxnfc = hinic_set_rxnfc, 449 .get_rxfh_key_size = hinic_get_rxfh_key_size, 450 .get_rxfh_indir_size = hinic_get_rxfh_indir_size, 451 .get_rxfh = hinic_get_rxfh, 452 .set_rxfh = hinic_set_rxfh, 453 }; 454 455 void hinic_set_ethtool_ops(struct net_device *netdev) 456 { 457 netdev->ethtool_ops = &hinic_ethtool_ops; 458 } 459