1 /* 2 * Copyright (C) 2015 Cavium, Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License 6 * as published by the Free Software Foundation. 7 */ 8 9 /* ETHTOOL Support for VNIC_VF Device*/ 10 11 #include <linux/pci.h> 12 13 #include "nic_reg.h" 14 #include "nic.h" 15 #include "nicvf_queues.h" 16 #include "q_struct.h" 17 #include "thunder_bgx.h" 18 19 #define DRV_NAME "thunder-nicvf" 20 #define DRV_VERSION "1.0" 21 22 struct nicvf_stat { 23 char name[ETH_GSTRING_LEN]; 24 unsigned int index; 25 }; 26 27 #define NICVF_HW_STAT(stat) { \ 28 .name = #stat, \ 29 .index = offsetof(struct nicvf_hw_stats, stat) / sizeof(u64), \ 30 } 31 32 #define NICVF_DRV_STAT(stat) { \ 33 .name = #stat, \ 34 .index = offsetof(struct nicvf_drv_stats, stat) / sizeof(u64), \ 35 } 36 37 static const struct nicvf_stat nicvf_hw_stats[] = { 38 NICVF_HW_STAT(rx_bytes), 39 NICVF_HW_STAT(rx_ucast_frames), 40 NICVF_HW_STAT(rx_bcast_frames), 41 NICVF_HW_STAT(rx_mcast_frames), 42 NICVF_HW_STAT(rx_fcs_errors), 43 NICVF_HW_STAT(rx_l2_errors), 44 NICVF_HW_STAT(rx_drop_red), 45 NICVF_HW_STAT(rx_drop_red_bytes), 46 NICVF_HW_STAT(rx_drop_overrun), 47 NICVF_HW_STAT(rx_drop_overrun_bytes), 48 NICVF_HW_STAT(rx_drop_bcast), 49 NICVF_HW_STAT(rx_drop_mcast), 50 NICVF_HW_STAT(rx_drop_l3_bcast), 51 NICVF_HW_STAT(rx_drop_l3_mcast), 52 NICVF_HW_STAT(rx_bgx_truncated_pkts), 53 NICVF_HW_STAT(rx_jabber_errs), 54 NICVF_HW_STAT(rx_fcs_errs), 55 NICVF_HW_STAT(rx_bgx_errs), 56 NICVF_HW_STAT(rx_prel2_errs), 57 NICVF_HW_STAT(rx_l2_hdr_malformed), 58 NICVF_HW_STAT(rx_oversize), 59 NICVF_HW_STAT(rx_undersize), 60 NICVF_HW_STAT(rx_l2_len_mismatch), 61 NICVF_HW_STAT(rx_l2_pclp), 62 NICVF_HW_STAT(rx_ip_ver_errs), 63 NICVF_HW_STAT(rx_ip_csum_errs), 64 NICVF_HW_STAT(rx_ip_hdr_malformed), 65 NICVF_HW_STAT(rx_ip_payload_malformed), 66 NICVF_HW_STAT(rx_ip_ttl_errs), 67 NICVF_HW_STAT(rx_l3_pclp), 68 NICVF_HW_STAT(rx_l4_malformed), 69 NICVF_HW_STAT(rx_l4_csum_errs), 70 NICVF_HW_STAT(rx_udp_len_errs), 71 NICVF_HW_STAT(rx_l4_port_errs), 72 NICVF_HW_STAT(rx_tcp_flag_errs), 73 NICVF_HW_STAT(rx_tcp_offset_errs), 74 NICVF_HW_STAT(rx_l4_pclp), 75 NICVF_HW_STAT(rx_truncated_pkts), 76 NICVF_HW_STAT(tx_bytes_ok), 77 NICVF_HW_STAT(tx_ucast_frames_ok), 78 NICVF_HW_STAT(tx_bcast_frames_ok), 79 NICVF_HW_STAT(tx_mcast_frames_ok), 80 }; 81 82 static const struct nicvf_stat nicvf_drv_stats[] = { 83 NICVF_DRV_STAT(rx_frames_ok), 84 NICVF_DRV_STAT(rx_frames_64), 85 NICVF_DRV_STAT(rx_frames_127), 86 NICVF_DRV_STAT(rx_frames_255), 87 NICVF_DRV_STAT(rx_frames_511), 88 NICVF_DRV_STAT(rx_frames_1023), 89 NICVF_DRV_STAT(rx_frames_1518), 90 NICVF_DRV_STAT(rx_frames_jumbo), 91 NICVF_DRV_STAT(rx_drops), 92 NICVF_DRV_STAT(tx_frames_ok), 93 NICVF_DRV_STAT(tx_tso), 94 NICVF_DRV_STAT(tx_drops), 95 NICVF_DRV_STAT(txq_stop), 96 NICVF_DRV_STAT(txq_wake), 97 }; 98 99 static const struct nicvf_stat nicvf_queue_stats[] = { 100 { "bytes", 0 }, 101 { "frames", 1 }, 102 }; 103 104 static const unsigned int nicvf_n_hw_stats = ARRAY_SIZE(nicvf_hw_stats); 105 static const unsigned int nicvf_n_drv_stats = ARRAY_SIZE(nicvf_drv_stats); 106 static const unsigned int nicvf_n_queue_stats = ARRAY_SIZE(nicvf_queue_stats); 107 108 static int nicvf_get_settings(struct net_device *netdev, 109 struct ethtool_cmd *cmd) 110 { 111 struct nicvf *nic = netdev_priv(netdev); 112 113 cmd->supported = 0; 114 cmd->transceiver = XCVR_EXTERNAL; 115 if (nic->speed <= 1000) { 116 cmd->port = PORT_MII; 117 cmd->autoneg = AUTONEG_ENABLE; 118 } else { 119 cmd->port = PORT_FIBRE; 120 cmd->autoneg = AUTONEG_DISABLE; 121 } 122 cmd->duplex = nic->duplex; 123 ethtool_cmd_speed_set(cmd, nic->speed); 124 125 return 0; 126 } 127 128 static void nicvf_get_drvinfo(struct net_device *netdev, 129 struct ethtool_drvinfo *info) 130 { 131 struct nicvf *nic = netdev_priv(netdev); 132 133 strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); 134 strlcpy(info->version, DRV_VERSION, sizeof(info->version)); 135 strlcpy(info->bus_info, pci_name(nic->pdev), sizeof(info->bus_info)); 136 } 137 138 static u32 nicvf_get_msglevel(struct net_device *netdev) 139 { 140 struct nicvf *nic = netdev_priv(netdev); 141 142 return nic->msg_enable; 143 } 144 145 static void nicvf_set_msglevel(struct net_device *netdev, u32 lvl) 146 { 147 struct nicvf *nic = netdev_priv(netdev); 148 149 nic->msg_enable = lvl; 150 } 151 152 static void nicvf_get_qset_strings(struct nicvf *nic, u8 **data, int qset) 153 { 154 int stats, qidx; 155 int start_qidx = qset * MAX_RCV_QUEUES_PER_QS; 156 157 for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) { 158 for (stats = 0; stats < nicvf_n_queue_stats; stats++) { 159 sprintf(*data, "rxq%d: %s", qidx + start_qidx, 160 nicvf_queue_stats[stats].name); 161 *data += ETH_GSTRING_LEN; 162 } 163 } 164 165 for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) { 166 for (stats = 0; stats < nicvf_n_queue_stats; stats++) { 167 sprintf(*data, "txq%d: %s", qidx + start_qidx, 168 nicvf_queue_stats[stats].name); 169 *data += ETH_GSTRING_LEN; 170 } 171 } 172 } 173 174 static void nicvf_get_strings(struct net_device *netdev, u32 sset, u8 *data) 175 { 176 struct nicvf *nic = netdev_priv(netdev); 177 int stats; 178 int sqs; 179 180 if (sset != ETH_SS_STATS) 181 return; 182 183 for (stats = 0; stats < nicvf_n_hw_stats; stats++) { 184 memcpy(data, nicvf_hw_stats[stats].name, ETH_GSTRING_LEN); 185 data += ETH_GSTRING_LEN; 186 } 187 188 for (stats = 0; stats < nicvf_n_drv_stats; stats++) { 189 memcpy(data, nicvf_drv_stats[stats].name, ETH_GSTRING_LEN); 190 data += ETH_GSTRING_LEN; 191 } 192 193 nicvf_get_qset_strings(nic, &data, 0); 194 195 for (sqs = 0; sqs < nic->sqs_count; sqs++) { 196 if (!nic->snicvf[sqs]) 197 continue; 198 nicvf_get_qset_strings(nic->snicvf[sqs], &data, sqs + 1); 199 } 200 201 for (stats = 0; stats < BGX_RX_STATS_COUNT; stats++) { 202 sprintf(data, "bgx_rxstat%d: ", stats); 203 data += ETH_GSTRING_LEN; 204 } 205 206 for (stats = 0; stats < BGX_TX_STATS_COUNT; stats++) { 207 sprintf(data, "bgx_txstat%d: ", stats); 208 data += ETH_GSTRING_LEN; 209 } 210 } 211 212 static int nicvf_get_sset_count(struct net_device *netdev, int sset) 213 { 214 struct nicvf *nic = netdev_priv(netdev); 215 int qstats_count; 216 int sqs; 217 218 if (sset != ETH_SS_STATS) 219 return -EINVAL; 220 221 qstats_count = nicvf_n_queue_stats * 222 (nic->qs->rq_cnt + nic->qs->sq_cnt); 223 for (sqs = 0; sqs < nic->sqs_count; sqs++) { 224 struct nicvf *snic; 225 226 snic = nic->snicvf[sqs]; 227 if (!snic) 228 continue; 229 qstats_count += nicvf_n_queue_stats * 230 (snic->qs->rq_cnt + snic->qs->sq_cnt); 231 } 232 233 return nicvf_n_hw_stats + nicvf_n_drv_stats + 234 qstats_count + 235 BGX_RX_STATS_COUNT + BGX_TX_STATS_COUNT; 236 } 237 238 static void nicvf_get_qset_stats(struct nicvf *nic, 239 struct ethtool_stats *stats, u64 **data) 240 { 241 int stat, qidx; 242 243 if (!nic) 244 return; 245 246 for (qidx = 0; qidx < nic->qs->rq_cnt; qidx++) { 247 nicvf_update_rq_stats(nic, qidx); 248 for (stat = 0; stat < nicvf_n_queue_stats; stat++) 249 *((*data)++) = ((u64 *)&nic->qs->rq[qidx].stats) 250 [nicvf_queue_stats[stat].index]; 251 } 252 253 for (qidx = 0; qidx < nic->qs->sq_cnt; qidx++) { 254 nicvf_update_sq_stats(nic, qidx); 255 for (stat = 0; stat < nicvf_n_queue_stats; stat++) 256 *((*data)++) = ((u64 *)&nic->qs->sq[qidx].stats) 257 [nicvf_queue_stats[stat].index]; 258 } 259 } 260 261 static void nicvf_get_ethtool_stats(struct net_device *netdev, 262 struct ethtool_stats *stats, u64 *data) 263 { 264 struct nicvf *nic = netdev_priv(netdev); 265 int stat; 266 int sqs; 267 268 nicvf_update_stats(nic); 269 270 /* Update LMAC stats */ 271 nicvf_update_lmac_stats(nic); 272 273 for (stat = 0; stat < nicvf_n_hw_stats; stat++) 274 *(data++) = ((u64 *)&nic->hw_stats) 275 [nicvf_hw_stats[stat].index]; 276 for (stat = 0; stat < nicvf_n_drv_stats; stat++) 277 *(data++) = ((u64 *)&nic->drv_stats) 278 [nicvf_drv_stats[stat].index]; 279 280 nicvf_get_qset_stats(nic, stats, &data); 281 282 for (sqs = 0; sqs < nic->sqs_count; sqs++) { 283 if (!nic->snicvf[sqs]) 284 continue; 285 nicvf_get_qset_stats(nic->snicvf[sqs], stats, &data); 286 } 287 288 for (stat = 0; stat < BGX_RX_STATS_COUNT; stat++) 289 *(data++) = nic->bgx_stats.rx_stats[stat]; 290 for (stat = 0; stat < BGX_TX_STATS_COUNT; stat++) 291 *(data++) = nic->bgx_stats.tx_stats[stat]; 292 } 293 294 static int nicvf_get_regs_len(struct net_device *dev) 295 { 296 return sizeof(u64) * NIC_VF_REG_COUNT; 297 } 298 299 static void nicvf_get_regs(struct net_device *dev, 300 struct ethtool_regs *regs, void *reg) 301 { 302 struct nicvf *nic = netdev_priv(dev); 303 u64 *p = (u64 *)reg; 304 u64 reg_offset; 305 int mbox, key, stat, q; 306 int i = 0; 307 308 regs->version = 0; 309 memset(p, 0, NIC_VF_REG_COUNT); 310 311 p[i++] = nicvf_reg_read(nic, NIC_VNIC_CFG); 312 /* Mailbox registers */ 313 for (mbox = 0; mbox < NIC_PF_VF_MAILBOX_SIZE; mbox++) 314 p[i++] = nicvf_reg_read(nic, 315 NIC_VF_PF_MAILBOX_0_1 | (mbox << 3)); 316 317 p[i++] = nicvf_reg_read(nic, NIC_VF_INT); 318 p[i++] = nicvf_reg_read(nic, NIC_VF_INT_W1S); 319 p[i++] = nicvf_reg_read(nic, NIC_VF_ENA_W1C); 320 p[i++] = nicvf_reg_read(nic, NIC_VF_ENA_W1S); 321 p[i++] = nicvf_reg_read(nic, NIC_VNIC_RSS_CFG); 322 323 for (key = 0; key < RSS_HASH_KEY_SIZE; key++) 324 p[i++] = nicvf_reg_read(nic, NIC_VNIC_RSS_KEY_0_4 | (key << 3)); 325 326 /* Tx/Rx statistics */ 327 for (stat = 0; stat < TX_STATS_ENUM_LAST; stat++) 328 p[i++] = nicvf_reg_read(nic, 329 NIC_VNIC_TX_STAT_0_4 | (stat << 3)); 330 331 for (i = 0; i < RX_STATS_ENUM_LAST; i++) 332 p[i++] = nicvf_reg_read(nic, 333 NIC_VNIC_RX_STAT_0_13 | (stat << 3)); 334 335 p[i++] = nicvf_reg_read(nic, NIC_QSET_RQ_GEN_CFG); 336 337 /* All completion queue's registers */ 338 for (q = 0; q < MAX_CMP_QUEUES_PER_QS; q++) { 339 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_CFG, q); 340 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_CFG2, q); 341 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_THRESH, q); 342 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_BASE, q); 343 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_HEAD, q); 344 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_TAIL, q); 345 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_DOOR, q); 346 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_STATUS, q); 347 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_STATUS2, q); 348 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_DEBUG, q); 349 } 350 351 /* All receive queue's registers */ 352 for (q = 0; q < MAX_RCV_QUEUES_PER_QS; q++) { 353 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RQ_0_7_CFG, q); 354 p[i++] = nicvf_queue_reg_read(nic, 355 NIC_QSET_RQ_0_7_STAT_0_1, q); 356 reg_offset = NIC_QSET_RQ_0_7_STAT_0_1 | (1 << 3); 357 p[i++] = nicvf_queue_reg_read(nic, reg_offset, q); 358 } 359 360 for (q = 0; q < MAX_SND_QUEUES_PER_QS; q++) { 361 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_CFG, q); 362 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_THRESH, q); 363 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_BASE, q); 364 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_HEAD, q); 365 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_TAIL, q); 366 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DOOR, q); 367 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STATUS, q); 368 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_DEBUG, q); 369 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_CNM_CHG, q); 370 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_STAT_0_1, q); 371 reg_offset = NIC_QSET_SQ_0_7_STAT_0_1 | (1 << 3); 372 p[i++] = nicvf_queue_reg_read(nic, reg_offset, q); 373 } 374 375 for (q = 0; q < MAX_RCV_BUF_DESC_RINGS_PER_QS; q++) { 376 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_CFG, q); 377 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_THRESH, q); 378 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_BASE, q); 379 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_HEAD, q); 380 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_TAIL, q); 381 p[i++] = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_DOOR, q); 382 p[i++] = nicvf_queue_reg_read(nic, 383 NIC_QSET_RBDR_0_1_STATUS0, q); 384 p[i++] = nicvf_queue_reg_read(nic, 385 NIC_QSET_RBDR_0_1_STATUS1, q); 386 reg_offset = NIC_QSET_RBDR_0_1_PREFETCH_STATUS; 387 p[i++] = nicvf_queue_reg_read(nic, reg_offset, q); 388 } 389 } 390 391 static int nicvf_get_coalesce(struct net_device *netdev, 392 struct ethtool_coalesce *cmd) 393 { 394 struct nicvf *nic = netdev_priv(netdev); 395 396 cmd->rx_coalesce_usecs = nic->cq_coalesce_usecs; 397 return 0; 398 } 399 400 static void nicvf_get_ringparam(struct net_device *netdev, 401 struct ethtool_ringparam *ring) 402 { 403 struct nicvf *nic = netdev_priv(netdev); 404 struct queue_set *qs = nic->qs; 405 406 ring->rx_max_pending = MAX_RCV_BUF_COUNT; 407 ring->rx_pending = qs->rbdr_len; 408 ring->tx_max_pending = MAX_SND_QUEUE_LEN; 409 ring->tx_pending = qs->sq_len; 410 } 411 412 static int nicvf_get_rss_hash_opts(struct nicvf *nic, 413 struct ethtool_rxnfc *info) 414 { 415 info->data = 0; 416 417 switch (info->flow_type) { 418 case TCP_V4_FLOW: 419 case TCP_V6_FLOW: 420 case UDP_V4_FLOW: 421 case UDP_V6_FLOW: 422 case SCTP_V4_FLOW: 423 case SCTP_V6_FLOW: 424 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 425 case IPV4_FLOW: 426 case IPV6_FLOW: 427 info->data |= RXH_IP_SRC | RXH_IP_DST; 428 break; 429 default: 430 return -EINVAL; 431 } 432 433 return 0; 434 } 435 436 static int nicvf_get_rxnfc(struct net_device *dev, 437 struct ethtool_rxnfc *info, u32 *rules) 438 { 439 struct nicvf *nic = netdev_priv(dev); 440 int ret = -EOPNOTSUPP; 441 442 switch (info->cmd) { 443 case ETHTOOL_GRXRINGS: 444 info->data = nic->rx_queues; 445 ret = 0; 446 break; 447 case ETHTOOL_GRXFH: 448 return nicvf_get_rss_hash_opts(nic, info); 449 default: 450 break; 451 } 452 return ret; 453 } 454 455 static int nicvf_set_rss_hash_opts(struct nicvf *nic, 456 struct ethtool_rxnfc *info) 457 { 458 struct nicvf_rss_info *rss = &nic->rss_info; 459 u64 rss_cfg = nicvf_reg_read(nic, NIC_VNIC_RSS_CFG); 460 461 if (!rss->enable) 462 netdev_err(nic->netdev, 463 "RSS is disabled, hash cannot be set\n"); 464 465 netdev_info(nic->netdev, "Set RSS flow type = %d, data = %lld\n", 466 info->flow_type, info->data); 467 468 if (!(info->data & RXH_IP_SRC) || !(info->data & RXH_IP_DST)) 469 return -EINVAL; 470 471 switch (info->flow_type) { 472 case TCP_V4_FLOW: 473 case TCP_V6_FLOW: 474 switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 475 case 0: 476 rss_cfg &= ~(1ULL << RSS_HASH_TCP); 477 break; 478 case (RXH_L4_B_0_1 | RXH_L4_B_2_3): 479 rss_cfg |= (1ULL << RSS_HASH_TCP); 480 break; 481 default: 482 return -EINVAL; 483 } 484 break; 485 case UDP_V4_FLOW: 486 case UDP_V6_FLOW: 487 switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 488 case 0: 489 rss_cfg &= ~(1ULL << RSS_HASH_UDP); 490 break; 491 case (RXH_L4_B_0_1 | RXH_L4_B_2_3): 492 rss_cfg |= (1ULL << RSS_HASH_UDP); 493 break; 494 default: 495 return -EINVAL; 496 } 497 break; 498 case SCTP_V4_FLOW: 499 case SCTP_V6_FLOW: 500 switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 501 case 0: 502 rss_cfg &= ~(1ULL << RSS_HASH_L4ETC); 503 break; 504 case (RXH_L4_B_0_1 | RXH_L4_B_2_3): 505 rss_cfg |= (1ULL << RSS_HASH_L4ETC); 506 break; 507 default: 508 return -EINVAL; 509 } 510 break; 511 case IPV4_FLOW: 512 case IPV6_FLOW: 513 rss_cfg = RSS_HASH_IP; 514 break; 515 default: 516 return -EINVAL; 517 } 518 519 nicvf_reg_write(nic, NIC_VNIC_RSS_CFG, rss_cfg); 520 return 0; 521 } 522 523 static int nicvf_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info) 524 { 525 struct nicvf *nic = netdev_priv(dev); 526 527 switch (info->cmd) { 528 case ETHTOOL_SRXFH: 529 return nicvf_set_rss_hash_opts(nic, info); 530 default: 531 break; 532 } 533 return -EOPNOTSUPP; 534 } 535 536 static u32 nicvf_get_rxfh_key_size(struct net_device *netdev) 537 { 538 return RSS_HASH_KEY_SIZE * sizeof(u64); 539 } 540 541 static u32 nicvf_get_rxfh_indir_size(struct net_device *dev) 542 { 543 struct nicvf *nic = netdev_priv(dev); 544 545 return nic->rss_info.rss_size; 546 } 547 548 static int nicvf_get_rxfh(struct net_device *dev, u32 *indir, u8 *hkey, 549 u8 *hfunc) 550 { 551 struct nicvf *nic = netdev_priv(dev); 552 struct nicvf_rss_info *rss = &nic->rss_info; 553 int idx; 554 555 if (indir) { 556 for (idx = 0; idx < rss->rss_size; idx++) 557 indir[idx] = rss->ind_tbl[idx]; 558 } 559 560 if (hkey) 561 memcpy(hkey, rss->key, RSS_HASH_KEY_SIZE * sizeof(u64)); 562 563 if (hfunc) 564 *hfunc = ETH_RSS_HASH_TOP; 565 566 return 0; 567 } 568 569 static int nicvf_set_rxfh(struct net_device *dev, const u32 *indir, 570 const u8 *hkey, u8 hfunc) 571 { 572 struct nicvf *nic = netdev_priv(dev); 573 struct nicvf_rss_info *rss = &nic->rss_info; 574 int idx; 575 576 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) 577 return -EOPNOTSUPP; 578 579 if (!rss->enable) { 580 netdev_err(nic->netdev, 581 "RSS is disabled, cannot change settings\n"); 582 return -EIO; 583 } 584 585 if (indir) { 586 for (idx = 0; idx < rss->rss_size; idx++) 587 rss->ind_tbl[idx] = indir[idx]; 588 } 589 590 if (hkey) { 591 memcpy(rss->key, hkey, RSS_HASH_KEY_SIZE * sizeof(u64)); 592 nicvf_set_rss_key(nic); 593 } 594 595 nicvf_config_rss(nic); 596 return 0; 597 } 598 599 /* Get no of queues device supports and current queue count */ 600 static void nicvf_get_channels(struct net_device *dev, 601 struct ethtool_channels *channel) 602 { 603 struct nicvf *nic = netdev_priv(dev); 604 605 memset(channel, 0, sizeof(*channel)); 606 607 channel->max_rx = nic->max_queues; 608 channel->max_tx = nic->max_queues; 609 610 channel->rx_count = nic->rx_queues; 611 channel->tx_count = nic->tx_queues; 612 } 613 614 /* Set no of Tx, Rx queues to be used */ 615 static int nicvf_set_channels(struct net_device *dev, 616 struct ethtool_channels *channel) 617 { 618 struct nicvf *nic = netdev_priv(dev); 619 int err = 0; 620 bool if_up = netif_running(dev); 621 int cqcount; 622 623 if (!channel->rx_count || !channel->tx_count) 624 return -EINVAL; 625 if (channel->rx_count > nic->max_queues) 626 return -EINVAL; 627 if (channel->tx_count > nic->max_queues) 628 return -EINVAL; 629 630 if (if_up) 631 nicvf_stop(dev); 632 633 cqcount = max(channel->rx_count, channel->tx_count); 634 635 if (cqcount > MAX_CMP_QUEUES_PER_QS) { 636 nic->sqs_count = roundup(cqcount, MAX_CMP_QUEUES_PER_QS); 637 nic->sqs_count = (nic->sqs_count / MAX_CMP_QUEUES_PER_QS) - 1; 638 } else { 639 nic->sqs_count = 0; 640 } 641 642 nic->qs->rq_cnt = min_t(u32, channel->rx_count, MAX_RCV_QUEUES_PER_QS); 643 nic->qs->sq_cnt = min_t(u32, channel->tx_count, MAX_SND_QUEUES_PER_QS); 644 nic->qs->cq_cnt = max(nic->qs->rq_cnt, nic->qs->sq_cnt); 645 646 nic->rx_queues = channel->rx_count; 647 nic->tx_queues = channel->tx_count; 648 err = nicvf_set_real_num_queues(dev, nic->tx_queues, nic->rx_queues); 649 if (err) 650 return err; 651 652 if (if_up) 653 nicvf_open(dev); 654 655 netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n", 656 nic->tx_queues, nic->rx_queues); 657 658 return err; 659 } 660 661 static const struct ethtool_ops nicvf_ethtool_ops = { 662 .get_settings = nicvf_get_settings, 663 .get_link = ethtool_op_get_link, 664 .get_drvinfo = nicvf_get_drvinfo, 665 .get_msglevel = nicvf_get_msglevel, 666 .set_msglevel = nicvf_set_msglevel, 667 .get_strings = nicvf_get_strings, 668 .get_sset_count = nicvf_get_sset_count, 669 .get_ethtool_stats = nicvf_get_ethtool_stats, 670 .get_regs_len = nicvf_get_regs_len, 671 .get_regs = nicvf_get_regs, 672 .get_coalesce = nicvf_get_coalesce, 673 .get_ringparam = nicvf_get_ringparam, 674 .get_rxnfc = nicvf_get_rxnfc, 675 .set_rxnfc = nicvf_set_rxnfc, 676 .get_rxfh_key_size = nicvf_get_rxfh_key_size, 677 .get_rxfh_indir_size = nicvf_get_rxfh_indir_size, 678 .get_rxfh = nicvf_get_rxfh, 679 .set_rxfh = nicvf_set_rxfh, 680 .get_channels = nicvf_get_channels, 681 .set_channels = nicvf_set_channels, 682 .get_ts_info = ethtool_op_get_ts_info, 683 }; 684 685 void nicvf_set_ethtool_ops(struct net_device *netdev) 686 { 687 netdev->ethtool_ops = &nicvf_ethtool_ops; 688 } 689