| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) |
|---|
| 1 | 2 | /* QLogic qede NIC Driver |
|---|
| 2 | 3 | * Copyright (c) 2015-2017 QLogic Corporation |
|---|
| 3 | | - * |
|---|
| 4 | | - * This software is available to you under a choice of one of two |
|---|
| 5 | | - * licenses. You may choose to be licensed under the terms of the GNU |
|---|
| 6 | | - * General Public License (GPL) Version 2, available from the file |
|---|
| 7 | | - * COPYING in the main directory of this source tree, or the |
|---|
| 8 | | - * OpenIB.org BSD license below: |
|---|
| 9 | | - * |
|---|
| 10 | | - * Redistribution and use in source and binary forms, with or |
|---|
| 11 | | - * without modification, are permitted provided that the following |
|---|
| 12 | | - * conditions are met: |
|---|
| 13 | | - * |
|---|
| 14 | | - * - Redistributions of source code must retain the above |
|---|
| 15 | | - * copyright notice, this list of conditions and the following |
|---|
| 16 | | - * disclaimer. |
|---|
| 17 | | - * |
|---|
| 18 | | - * - Redistributions in binary form must reproduce the above |
|---|
| 19 | | - * copyright notice, this list of conditions and the following |
|---|
| 20 | | - * disclaimer in the documentation and /or other materials |
|---|
| 21 | | - * provided with the distribution. |
|---|
| 22 | | - * |
|---|
| 23 | | - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|---|
| 24 | | - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|---|
| 25 | | - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|---|
| 26 | | - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
|---|
| 27 | | - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|---|
| 28 | | - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|---|
| 29 | | - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|---|
| 30 | | - * SOFTWARE. |
|---|
| 4 | + * Copyright (c) 2019-2020 Marvell International Ltd. |
|---|
| 31 | 5 | */ |
|---|
| 6 | + |
|---|
| 32 | 7 | #include <linux/version.h> |
|---|
| 33 | 8 | #include <linux/types.h> |
|---|
| 34 | 9 | #include <linux/netdevice.h> |
|---|
| .. | .. |
|---|
| 38 | 13 | #include <linux/pci.h> |
|---|
| 39 | 14 | #include <linux/capability.h> |
|---|
| 40 | 15 | #include <linux/vmalloc.h> |
|---|
| 16 | +#include <linux/phylink.h> |
|---|
| 17 | + |
|---|
| 41 | 18 | #include "qede.h" |
|---|
| 42 | 19 | #include "qede_ptp.h" |
|---|
| 43 | 20 | |
|---|
| .. | .. |
|---|
| 48 | 25 | {QEDE_RQSTAT_OFFSET(stat_name), QEDE_RQSTAT_STRING(stat_name)} |
|---|
| 49 | 26 | |
|---|
| 50 | 27 | #define QEDE_SELFTEST_POLL_COUNT 100 |
|---|
| 28 | +#define QEDE_DUMP_VERSION 0x1 |
|---|
| 29 | +#define QEDE_DUMP_NVM_ARG_COUNT 2 |
|---|
| 51 | 30 | |
|---|
| 52 | 31 | static const struct { |
|---|
| 53 | 32 | u64 offset; |
|---|
| .. | .. |
|---|
| 73 | 52 | } qede_tqstats_arr[] = { |
|---|
| 74 | 53 | QEDE_TQSTAT(xmit_pkts), |
|---|
| 75 | 54 | QEDE_TQSTAT(stopped_cnt), |
|---|
| 55 | + QEDE_TQSTAT(tx_mem_alloc_err), |
|---|
| 76 | 56 | }; |
|---|
| 77 | 57 | |
|---|
| 78 | 58 | #define QEDE_STAT_OFFSET(stat_name, type, base) \ |
|---|
| .. | .. |
|---|
| 173 | 153 | QEDE_STAT(coalesced_bytes), |
|---|
| 174 | 154 | |
|---|
| 175 | 155 | QEDE_STAT(link_change_count), |
|---|
| 156 | + QEDE_STAT(ptp_skip_txts), |
|---|
| 176 | 157 | }; |
|---|
| 177 | 158 | |
|---|
| 178 | 159 | #define QEDE_NUM_STATS ARRAY_SIZE(qede_stats_arr) |
|---|
| .. | .. |
|---|
| 185 | 166 | |
|---|
| 186 | 167 | enum { |
|---|
| 187 | 168 | QEDE_PRI_FLAG_CMT, |
|---|
| 169 | + QEDE_PRI_FLAG_SMART_AN_SUPPORT, /* MFW supports SmartAN */ |
|---|
| 170 | + QEDE_PRI_FLAG_RECOVER_ON_ERROR, |
|---|
| 188 | 171 | QEDE_PRI_FLAG_LEN, |
|---|
| 189 | 172 | }; |
|---|
| 190 | 173 | |
|---|
| 191 | 174 | static const char qede_private_arr[QEDE_PRI_FLAG_LEN][ETH_GSTRING_LEN] = { |
|---|
| 192 | 175 | "Coupled-Function", |
|---|
| 176 | + "SmartAN capable", |
|---|
| 177 | + "Recover on error", |
|---|
| 193 | 178 | }; |
|---|
| 194 | 179 | |
|---|
| 195 | 180 | enum qede_ethtool_tests { |
|---|
| .. | .. |
|---|
| 210 | 195 | "Clock (online)\t\t", |
|---|
| 211 | 196 | "Nvram (online)\t\t", |
|---|
| 212 | 197 | }; |
|---|
| 198 | + |
|---|
| 199 | +/* Forced speed capabilities maps */ |
|---|
| 200 | + |
|---|
| 201 | +struct qede_forced_speed_map { |
|---|
| 202 | + u32 speed; |
|---|
| 203 | + __ETHTOOL_DECLARE_LINK_MODE_MASK(caps); |
|---|
| 204 | + |
|---|
| 205 | + const u32 *cap_arr; |
|---|
| 206 | + u32 arr_size; |
|---|
| 207 | +}; |
|---|
| 208 | + |
|---|
| 209 | +#define QEDE_FORCED_SPEED_MAP(value) \ |
|---|
| 210 | +{ \ |
|---|
| 211 | + .speed = SPEED_##value, \ |
|---|
| 212 | + .cap_arr = qede_forced_speed_##value, \ |
|---|
| 213 | + .arr_size = ARRAY_SIZE(qede_forced_speed_##value), \ |
|---|
| 214 | +} |
|---|
| 215 | + |
|---|
| 216 | +static const u32 qede_forced_speed_1000[] __initconst = { |
|---|
| 217 | + ETHTOOL_LINK_MODE_1000baseT_Full_BIT, |
|---|
| 218 | + ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, |
|---|
| 219 | + ETHTOOL_LINK_MODE_1000baseX_Full_BIT, |
|---|
| 220 | +}; |
|---|
| 221 | + |
|---|
| 222 | +static const u32 qede_forced_speed_10000[] __initconst = { |
|---|
| 223 | + ETHTOOL_LINK_MODE_10000baseT_Full_BIT, |
|---|
| 224 | + ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, |
|---|
| 225 | + ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, |
|---|
| 226 | + ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, |
|---|
| 227 | + ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, |
|---|
| 228 | + ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, |
|---|
| 229 | + ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, |
|---|
| 230 | + ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, |
|---|
| 231 | +}; |
|---|
| 232 | + |
|---|
| 233 | +static const u32 qede_forced_speed_20000[] __initconst = { |
|---|
| 234 | + ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT, |
|---|
| 235 | +}; |
|---|
| 236 | + |
|---|
| 237 | +static const u32 qede_forced_speed_25000[] __initconst = { |
|---|
| 238 | + ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, |
|---|
| 239 | + ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, |
|---|
| 240 | + ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, |
|---|
| 241 | +}; |
|---|
| 242 | + |
|---|
| 243 | +static const u32 qede_forced_speed_40000[] __initconst = { |
|---|
| 244 | + ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, |
|---|
| 245 | + ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, |
|---|
| 246 | + ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, |
|---|
| 247 | + ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, |
|---|
| 248 | +}; |
|---|
| 249 | + |
|---|
| 250 | +static const u32 qede_forced_speed_50000[] __initconst = { |
|---|
| 251 | + ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, |
|---|
| 252 | + ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, |
|---|
| 253 | + ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, |
|---|
| 254 | +}; |
|---|
| 255 | + |
|---|
| 256 | +static const u32 qede_forced_speed_100000[] __initconst = { |
|---|
| 257 | + ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, |
|---|
| 258 | + ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, |
|---|
| 259 | + ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, |
|---|
| 260 | + ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, |
|---|
| 261 | +}; |
|---|
| 262 | + |
|---|
| 263 | +static struct qede_forced_speed_map qede_forced_speed_maps[] __ro_after_init = { |
|---|
| 264 | + QEDE_FORCED_SPEED_MAP(1000), |
|---|
| 265 | + QEDE_FORCED_SPEED_MAP(10000), |
|---|
| 266 | + QEDE_FORCED_SPEED_MAP(20000), |
|---|
| 267 | + QEDE_FORCED_SPEED_MAP(25000), |
|---|
| 268 | + QEDE_FORCED_SPEED_MAP(40000), |
|---|
| 269 | + QEDE_FORCED_SPEED_MAP(50000), |
|---|
| 270 | + QEDE_FORCED_SPEED_MAP(100000), |
|---|
| 271 | +}; |
|---|
| 272 | + |
|---|
| 273 | +void __init qede_forced_speed_maps_init(void) |
|---|
| 274 | +{ |
|---|
| 275 | + struct qede_forced_speed_map *map; |
|---|
| 276 | + u32 i; |
|---|
| 277 | + |
|---|
| 278 | + for (i = 0; i < ARRAY_SIZE(qede_forced_speed_maps); i++) { |
|---|
| 279 | + map = qede_forced_speed_maps + i; |
|---|
| 280 | + |
|---|
| 281 | + linkmode_set_bit_array(map->cap_arr, map->arr_size, map->caps); |
|---|
| 282 | + map->cap_arr = NULL; |
|---|
| 283 | + map->arr_size = 0; |
|---|
| 284 | + } |
|---|
| 285 | +} |
|---|
| 286 | + |
|---|
| 287 | +/* Ethtool callbacks */ |
|---|
| 213 | 288 | |
|---|
| 214 | 289 | static void qede_get_strings_stats_txq(struct qede_dev *edev, |
|---|
| 215 | 290 | struct qede_tx_queue *txq, u8 **buf) |
|---|
| .. | .. |
|---|
| 403 | 478 | static u32 qede_get_priv_flags(struct net_device *dev) |
|---|
| 404 | 479 | { |
|---|
| 405 | 480 | struct qede_dev *edev = netdev_priv(dev); |
|---|
| 481 | + u32 flags = 0; |
|---|
| 406 | 482 | |
|---|
| 407 | | - return (!!(edev->dev_info.common.num_hwfns > 1)) << QEDE_PRI_FLAG_CMT; |
|---|
| 483 | + if (edev->dev_info.common.num_hwfns > 1) |
|---|
| 484 | + flags |= BIT(QEDE_PRI_FLAG_CMT); |
|---|
| 485 | + |
|---|
| 486 | + if (edev->dev_info.common.smart_an) |
|---|
| 487 | + flags |= BIT(QEDE_PRI_FLAG_SMART_AN_SUPPORT); |
|---|
| 488 | + |
|---|
| 489 | + if (edev->err_flags & BIT(QEDE_ERR_IS_RECOVERABLE)) |
|---|
| 490 | + flags |= BIT(QEDE_PRI_FLAG_RECOVER_ON_ERROR); |
|---|
| 491 | + |
|---|
| 492 | + return flags; |
|---|
| 408 | 493 | } |
|---|
| 409 | 494 | |
|---|
| 410 | | -struct qede_link_mode_mapping { |
|---|
| 411 | | - u32 qed_link_mode; |
|---|
| 412 | | - u32 ethtool_link_mode; |
|---|
| 413 | | -}; |
|---|
| 495 | +static int qede_set_priv_flags(struct net_device *dev, u32 flags) |
|---|
| 496 | +{ |
|---|
| 497 | + struct qede_dev *edev = netdev_priv(dev); |
|---|
| 498 | + u32 cflags = qede_get_priv_flags(dev); |
|---|
| 499 | + u32 dflags = flags ^ cflags; |
|---|
| 414 | 500 | |
|---|
| 415 | | -static const struct qede_link_mode_mapping qed_lm_map[] = { |
|---|
| 416 | | - {QED_LM_FIBRE_BIT, ETHTOOL_LINK_MODE_FIBRE_BIT}, |
|---|
| 417 | | - {QED_LM_Autoneg_BIT, ETHTOOL_LINK_MODE_Autoneg_BIT}, |
|---|
| 418 | | - {QED_LM_Asym_Pause_BIT, ETHTOOL_LINK_MODE_Asym_Pause_BIT}, |
|---|
| 419 | | - {QED_LM_Pause_BIT, ETHTOOL_LINK_MODE_Pause_BIT}, |
|---|
| 420 | | - {QED_LM_1000baseT_Half_BIT, ETHTOOL_LINK_MODE_1000baseT_Half_BIT}, |
|---|
| 421 | | - {QED_LM_1000baseT_Full_BIT, ETHTOOL_LINK_MODE_1000baseT_Full_BIT}, |
|---|
| 422 | | - {QED_LM_10000baseKR_Full_BIT, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT}, |
|---|
| 423 | | - {QED_LM_25000baseKR_Full_BIT, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT}, |
|---|
| 424 | | - {QED_LM_40000baseLR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT}, |
|---|
| 425 | | - {QED_LM_50000baseKR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT}, |
|---|
| 426 | | - {QED_LM_100000baseKR4_Full_BIT, |
|---|
| 427 | | - ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT}, |
|---|
| 428 | | -}; |
|---|
| 501 | + /* can only change RECOVER_ON_ERROR flag */ |
|---|
| 502 | + if (dflags & ~BIT(QEDE_PRI_FLAG_RECOVER_ON_ERROR)) |
|---|
| 503 | + return -EINVAL; |
|---|
| 429 | 504 | |
|---|
| 430 | | -#define QEDE_DRV_TO_ETHTOOL_CAPS(caps, lk_ksettings, name) \ |
|---|
| 431 | | -{ \ |
|---|
| 432 | | - int i; \ |
|---|
| 433 | | - \ |
|---|
| 434 | | - for (i = 0; i < ARRAY_SIZE(qed_lm_map); i++) { \ |
|---|
| 435 | | - if ((caps) & (qed_lm_map[i].qed_link_mode)) \ |
|---|
| 436 | | - __set_bit(qed_lm_map[i].ethtool_link_mode,\ |
|---|
| 437 | | - lk_ksettings->link_modes.name); \ |
|---|
| 438 | | - } \ |
|---|
| 439 | | -} |
|---|
| 505 | + if (flags & BIT(QEDE_PRI_FLAG_RECOVER_ON_ERROR)) |
|---|
| 506 | + set_bit(QEDE_ERR_IS_RECOVERABLE, &edev->err_flags); |
|---|
| 507 | + else |
|---|
| 508 | + clear_bit(QEDE_ERR_IS_RECOVERABLE, &edev->err_flags); |
|---|
| 440 | 509 | |
|---|
| 441 | | -#define QEDE_ETHTOOL_TO_DRV_CAPS(caps, lk_ksettings, name) \ |
|---|
| 442 | | -{ \ |
|---|
| 443 | | - int i; \ |
|---|
| 444 | | - \ |
|---|
| 445 | | - for (i = 0; i < ARRAY_SIZE(qed_lm_map); i++) { \ |
|---|
| 446 | | - if (test_bit(qed_lm_map[i].ethtool_link_mode, \ |
|---|
| 447 | | - lk_ksettings->link_modes.name)) \ |
|---|
| 448 | | - caps |= qed_lm_map[i].qed_link_mode; \ |
|---|
| 449 | | - } \ |
|---|
| 510 | + return 0; |
|---|
| 450 | 511 | } |
|---|
| 451 | 512 | |
|---|
| 452 | 513 | static int qede_get_link_ksettings(struct net_device *dev, |
|---|
| 453 | 514 | struct ethtool_link_ksettings *cmd) |
|---|
| 454 | 515 | { |
|---|
| 516 | + typeof(cmd->link_modes) *link_modes = &cmd->link_modes; |
|---|
| 455 | 517 | struct ethtool_link_settings *base = &cmd->base; |
|---|
| 456 | 518 | struct qede_dev *edev = netdev_priv(dev); |
|---|
| 457 | 519 | struct qed_link_output current_link; |
|---|
| .. | .. |
|---|
| 461 | 523 | memset(¤t_link, 0, sizeof(current_link)); |
|---|
| 462 | 524 | edev->ops->common->get_link(edev->cdev, ¤t_link); |
|---|
| 463 | 525 | |
|---|
| 464 | | - ethtool_link_ksettings_zero_link_mode(cmd, supported); |
|---|
| 465 | | - QEDE_DRV_TO_ETHTOOL_CAPS(current_link.supported_caps, cmd, supported) |
|---|
| 466 | | - |
|---|
| 467 | | - ethtool_link_ksettings_zero_link_mode(cmd, advertising); |
|---|
| 468 | | - QEDE_DRV_TO_ETHTOOL_CAPS(current_link.advertised_caps, cmd, advertising) |
|---|
| 469 | | - |
|---|
| 470 | | - ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising); |
|---|
| 471 | | - QEDE_DRV_TO_ETHTOOL_CAPS(current_link.lp_caps, cmd, lp_advertising) |
|---|
| 526 | + linkmode_copy(link_modes->supported, current_link.supported_caps); |
|---|
| 527 | + linkmode_copy(link_modes->advertising, current_link.advertised_caps); |
|---|
| 528 | + linkmode_copy(link_modes->lp_advertising, current_link.lp_caps); |
|---|
| 472 | 529 | |
|---|
| 473 | 530 | if ((edev->state == QEDE_STATE_OPEN) && (current_link.link_up)) { |
|---|
| 474 | 531 | base->speed = current_link.speed; |
|---|
| .. | .. |
|---|
| 492 | 549 | { |
|---|
| 493 | 550 | const struct ethtool_link_settings *base = &cmd->base; |
|---|
| 494 | 551 | struct qede_dev *edev = netdev_priv(dev); |
|---|
| 552 | + const struct qede_forced_speed_map *map; |
|---|
| 495 | 553 | struct qed_link_output current_link; |
|---|
| 496 | 554 | struct qed_link_params params; |
|---|
| 555 | + u32 i; |
|---|
| 497 | 556 | |
|---|
| 498 | 557 | if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) { |
|---|
| 499 | 558 | DP_INFO(edev, "Link settings are not allowed to be changed\n"); |
|---|
| .. | .. |
|---|
| 505 | 564 | |
|---|
| 506 | 565 | params.override_flags |= QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS; |
|---|
| 507 | 566 | params.override_flags |= QED_LINK_OVERRIDE_SPEED_AUTONEG; |
|---|
| 567 | + |
|---|
| 508 | 568 | if (base->autoneg == AUTONEG_ENABLE) { |
|---|
| 509 | | - if (!(current_link.supported_caps & QED_LM_Autoneg_BIT)) { |
|---|
| 569 | + if (!phylink_test(current_link.supported_caps, Autoneg)) { |
|---|
| 510 | 570 | DP_INFO(edev, "Auto negotiation is not supported\n"); |
|---|
| 511 | 571 | return -EOPNOTSUPP; |
|---|
| 512 | 572 | } |
|---|
| 513 | 573 | |
|---|
| 514 | 574 | params.autoneg = true; |
|---|
| 515 | 575 | params.forced_speed = 0; |
|---|
| 516 | | - QEDE_ETHTOOL_TO_DRV_CAPS(params.adv_speeds, cmd, advertising) |
|---|
| 576 | + |
|---|
| 577 | + linkmode_copy(params.adv_speeds, cmd->link_modes.advertising); |
|---|
| 517 | 578 | } else { /* forced speed */ |
|---|
| 518 | 579 | params.override_flags |= QED_LINK_OVERRIDE_SPEED_FORCED_SPEED; |
|---|
| 519 | 580 | params.autoneg = false; |
|---|
| 520 | 581 | params.forced_speed = base->speed; |
|---|
| 521 | | - switch (base->speed) { |
|---|
| 522 | | - case SPEED_1000: |
|---|
| 523 | | - if (!(current_link.supported_caps & |
|---|
| 524 | | - QED_LM_1000baseT_Full_BIT)) { |
|---|
| 525 | | - DP_INFO(edev, "1G speed not supported\n"); |
|---|
| 526 | | - return -EINVAL; |
|---|
| 527 | | - } |
|---|
| 528 | | - params.adv_speeds = QED_LM_1000baseT_Full_BIT; |
|---|
| 529 | | - break; |
|---|
| 530 | | - case SPEED_10000: |
|---|
| 531 | | - if (!(current_link.supported_caps & |
|---|
| 532 | | - QED_LM_10000baseKR_Full_BIT)) { |
|---|
| 533 | | - DP_INFO(edev, "10G speed not supported\n"); |
|---|
| 534 | | - return -EINVAL; |
|---|
| 535 | | - } |
|---|
| 536 | | - params.adv_speeds = QED_LM_10000baseKR_Full_BIT; |
|---|
| 537 | | - break; |
|---|
| 538 | | - case SPEED_25000: |
|---|
| 539 | | - if (!(current_link.supported_caps & |
|---|
| 540 | | - QED_LM_25000baseKR_Full_BIT)) { |
|---|
| 541 | | - DP_INFO(edev, "25G speed not supported\n"); |
|---|
| 542 | | - return -EINVAL; |
|---|
| 543 | | - } |
|---|
| 544 | | - params.adv_speeds = QED_LM_25000baseKR_Full_BIT; |
|---|
| 545 | | - break; |
|---|
| 546 | | - case SPEED_40000: |
|---|
| 547 | | - if (!(current_link.supported_caps & |
|---|
| 548 | | - QED_LM_40000baseLR4_Full_BIT)) { |
|---|
| 549 | | - DP_INFO(edev, "40G speed not supported\n"); |
|---|
| 550 | | - return -EINVAL; |
|---|
| 551 | | - } |
|---|
| 552 | | - params.adv_speeds = QED_LM_40000baseLR4_Full_BIT; |
|---|
| 553 | | - break; |
|---|
| 554 | | - case SPEED_50000: |
|---|
| 555 | | - if (!(current_link.supported_caps & |
|---|
| 556 | | - QED_LM_50000baseKR2_Full_BIT)) { |
|---|
| 557 | | - DP_INFO(edev, "50G speed not supported\n"); |
|---|
| 558 | | - return -EINVAL; |
|---|
| 559 | | - } |
|---|
| 560 | | - params.adv_speeds = QED_LM_50000baseKR2_Full_BIT; |
|---|
| 561 | | - break; |
|---|
| 562 | | - case SPEED_100000: |
|---|
| 563 | | - if (!(current_link.supported_caps & |
|---|
| 564 | | - QED_LM_100000baseKR4_Full_BIT)) { |
|---|
| 565 | | - DP_INFO(edev, "100G speed not supported\n"); |
|---|
| 566 | | - return -EINVAL; |
|---|
| 567 | | - } |
|---|
| 568 | | - params.adv_speeds = QED_LM_100000baseKR4_Full_BIT; |
|---|
| 569 | | - break; |
|---|
| 570 | | - default: |
|---|
| 571 | | - DP_INFO(edev, "Unsupported speed %u\n", base->speed); |
|---|
| 572 | | - return -EINVAL; |
|---|
| 582 | + |
|---|
| 583 | + for (i = 0; i < ARRAY_SIZE(qede_forced_speed_maps); i++) { |
|---|
| 584 | + map = qede_forced_speed_maps + i; |
|---|
| 585 | + |
|---|
| 586 | + if (base->speed != map->speed || |
|---|
| 587 | + !linkmode_intersects(current_link.supported_caps, |
|---|
| 588 | + map->caps)) |
|---|
| 589 | + continue; |
|---|
| 590 | + |
|---|
| 591 | + linkmode_and(params.adv_speeds, |
|---|
| 592 | + current_link.supported_caps, map->caps); |
|---|
| 593 | + goto set_link; |
|---|
| 573 | 594 | } |
|---|
| 595 | + |
|---|
| 596 | + DP_INFO(edev, "Unsupported speed %u\n", base->speed); |
|---|
| 597 | + return -EINVAL; |
|---|
| 574 | 598 | } |
|---|
| 575 | 599 | |
|---|
| 600 | +set_link: |
|---|
| 576 | 601 | params.link_up = true; |
|---|
| 577 | 602 | edev->ops->common->set_link(edev->cdev, ¶ms); |
|---|
| 578 | 603 | |
|---|
| .. | .. |
|---|
| 584 | 609 | { |
|---|
| 585 | 610 | char mfw[ETHTOOL_FWVERS_LEN], storm[ETHTOOL_FWVERS_LEN]; |
|---|
| 586 | 611 | struct qede_dev *edev = netdev_priv(ndev); |
|---|
| 612 | + char mbi[ETHTOOL_FWVERS_LEN]; |
|---|
| 587 | 613 | |
|---|
| 588 | 614 | strlcpy(info->driver, "qede", sizeof(info->driver)); |
|---|
| 589 | | - strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); |
|---|
| 590 | 615 | |
|---|
| 591 | 616 | snprintf(storm, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d", |
|---|
| 592 | 617 | edev->dev_info.common.fw_major, |
|---|
| .. | .. |
|---|
| 600 | 625 | (edev->dev_info.common.mfw_rev >> 8) & 0xFF, |
|---|
| 601 | 626 | edev->dev_info.common.mfw_rev & 0xFF); |
|---|
| 602 | 627 | |
|---|
| 603 | | - if ((strlen(storm) + strlen(mfw) + strlen("mfw storm ")) < |
|---|
| 604 | | - sizeof(info->fw_version)) { |
|---|
| 628 | + if ((strlen(storm) + strlen(DRV_MODULE_VERSION) + strlen("[storm] ")) < |
|---|
| 629 | + sizeof(info->version)) |
|---|
| 630 | + snprintf(info->version, sizeof(info->version), |
|---|
| 631 | + "%s [storm %s]", DRV_MODULE_VERSION, storm); |
|---|
| 632 | + else |
|---|
| 633 | + snprintf(info->version, sizeof(info->version), |
|---|
| 634 | + "%s %s", DRV_MODULE_VERSION, storm); |
|---|
| 635 | + |
|---|
| 636 | + if (edev->dev_info.common.mbi_version) { |
|---|
| 637 | + snprintf(mbi, ETHTOOL_FWVERS_LEN, "%d.%d.%d", |
|---|
| 638 | + (edev->dev_info.common.mbi_version & |
|---|
| 639 | + QED_MBI_VERSION_2_MASK) >> QED_MBI_VERSION_2_OFFSET, |
|---|
| 640 | + (edev->dev_info.common.mbi_version & |
|---|
| 641 | + QED_MBI_VERSION_1_MASK) >> QED_MBI_VERSION_1_OFFSET, |
|---|
| 642 | + (edev->dev_info.common.mbi_version & |
|---|
| 643 | + QED_MBI_VERSION_0_MASK) >> QED_MBI_VERSION_0_OFFSET); |
|---|
| 605 | 644 | snprintf(info->fw_version, sizeof(info->fw_version), |
|---|
| 606 | | - "mfw %s storm %s", mfw, storm); |
|---|
| 645 | + "mbi %s [mfw %s]", mbi, mfw); |
|---|
| 607 | 646 | } else { |
|---|
| 608 | 647 | snprintf(info->fw_version, sizeof(info->fw_version), |
|---|
| 609 | | - "%s %s", mfw, storm); |
|---|
| 648 | + "mfw %s", mfw); |
|---|
| 610 | 649 | } |
|---|
| 611 | 650 | |
|---|
| 612 | 651 | strlcpy(info->bus_info, pci_name(edev->pdev), sizeof(info->bus_info)); |
|---|
| .. | .. |
|---|
| 922 | 961 | |
|---|
| 923 | 962 | memset(¶ms, 0, sizeof(params)); |
|---|
| 924 | 963 | params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG; |
|---|
| 964 | + |
|---|
| 925 | 965 | if (epause->autoneg) { |
|---|
| 926 | | - if (!(current_link.supported_caps & QED_LM_Autoneg_BIT)) { |
|---|
| 966 | + if (!phylink_test(current_link.supported_caps, Autoneg)) { |
|---|
| 927 | 967 | DP_INFO(edev, "autoneg not supported\n"); |
|---|
| 928 | 968 | return -EINVAL; |
|---|
| 929 | 969 | } |
|---|
| 970 | + |
|---|
| 930 | 971 | params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE; |
|---|
| 931 | 972 | } |
|---|
| 973 | + |
|---|
| 932 | 974 | if (epause->rx_pause) |
|---|
| 933 | 975 | params.pause_config |= QED_LINK_PAUSE_RX_ENABLE; |
|---|
| 934 | 976 | if (epause->tx_pause) |
|---|
| .. | .. |
|---|
| 984 | 1026 | args.u.mtu = new_mtu; |
|---|
| 985 | 1027 | args.func = &qede_update_mtu; |
|---|
| 986 | 1028 | qede_reload(edev, &args, false); |
|---|
| 987 | | - |
|---|
| 1029 | +#if IS_ENABLED(CONFIG_QED_RDMA) |
|---|
| 1030 | + qede_rdma_event_change_mtu(edev); |
|---|
| 1031 | +#endif |
|---|
| 988 | 1032 | edev->ops->common->update_mtu(edev->cdev, new_mtu); |
|---|
| 989 | 1033 | |
|---|
| 990 | 1034 | return 0; |
|---|
| .. | .. |
|---|
| 1458 | 1502 | barrier(); |
|---|
| 1459 | 1503 | writel(txq->tx_db.raw, txq->doorbell_addr); |
|---|
| 1460 | 1504 | |
|---|
| 1461 | | - /* mmiowb is needed to synchronize doorbell writes from more than one |
|---|
| 1462 | | - * processor. It guarantees that the write arrives to the device before |
|---|
| 1463 | | - * the queue lock is released and another start_xmit is called (possibly |
|---|
| 1464 | | - * on another CPU). Without this barrier, the next doorbell can bypass |
|---|
| 1465 | | - * this doorbell. This is applicable to IA64/Altix systems. |
|---|
| 1466 | | - */ |
|---|
| 1467 | | - mmiowb(); |
|---|
| 1468 | | - |
|---|
| 1469 | 1505 | for (i = 0; i < QEDE_SELFTEST_POLL_COUNT; i++) { |
|---|
| 1470 | 1506 | if (qede_txq_has_work(txq)) |
|---|
| 1471 | 1507 | break; |
|---|
| .. | .. |
|---|
| 1488 | 1524 | |
|---|
| 1489 | 1525 | static int qede_selftest_receive_traffic(struct qede_dev *edev) |
|---|
| 1490 | 1526 | { |
|---|
| 1491 | | - u16 hw_comp_cons, sw_comp_cons, sw_rx_index, len; |
|---|
| 1527 | + u16 sw_rx_index, len; |
|---|
| 1492 | 1528 | struct eth_fast_path_rx_reg_cqe *fp_cqe; |
|---|
| 1493 | 1529 | struct qede_rx_queue *rxq = NULL; |
|---|
| 1494 | 1530 | struct sw_rx_data *sw_rx_data; |
|---|
| .. | .. |
|---|
| 1517 | 1553 | usleep_range(100, 200); |
|---|
| 1518 | 1554 | continue; |
|---|
| 1519 | 1555 | } |
|---|
| 1520 | | - |
|---|
| 1521 | | - hw_comp_cons = le16_to_cpu(*rxq->hw_cons_ptr); |
|---|
| 1522 | | - sw_comp_cons = qed_chain_get_cons_idx(&rxq->rx_comp_ring); |
|---|
| 1523 | | - |
|---|
| 1524 | | - /* Memory barrier to prevent the CPU from doing speculative |
|---|
| 1525 | | - * reads of CQE/BD before reading hw_comp_cons. If the CQE is |
|---|
| 1526 | | - * read before it is written by FW, then FW writes CQE and SB, |
|---|
| 1527 | | - * and then the CPU reads the hw_comp_cons, it will use an old |
|---|
| 1528 | | - * CQE. |
|---|
| 1529 | | - */ |
|---|
| 1530 | | - rmb(); |
|---|
| 1531 | 1556 | |
|---|
| 1532 | 1557 | /* Get the CQE from the completion ring */ |
|---|
| 1533 | 1558 | cqe = (union eth_rx_cqe *)qed_chain_consume(&rxq->rx_comp_ring); |
|---|
| .. | .. |
|---|
| 1595 | 1620 | /* Wait for loopback configuration to apply */ |
|---|
| 1596 | 1621 | msleep_interruptible(500); |
|---|
| 1597 | 1622 | |
|---|
| 1598 | | - /* prepare the loopback packet */ |
|---|
| 1599 | | - pkt_size = edev->ndev->mtu + ETH_HLEN; |
|---|
| 1623 | + /* Setting max packet size to 1.5K to avoid data being split over |
|---|
| 1624 | + * multiple BDs in cases where MTU > PAGE_SIZE. |
|---|
| 1625 | + */ |
|---|
| 1626 | + pkt_size = (((edev->ndev->mtu < ETH_DATA_LEN) ? |
|---|
| 1627 | + edev->ndev->mtu : ETH_DATA_LEN) + ETH_HLEN); |
|---|
| 1600 | 1628 | |
|---|
| 1601 | 1629 | skb = netdev_alloc_skb(edev->ndev, pkt_size); |
|---|
| 1602 | 1630 | if (!skb) { |
|---|
| .. | .. |
|---|
| 1808 | 1836 | return 0; |
|---|
| 1809 | 1837 | } |
|---|
| 1810 | 1838 | |
|---|
| 1839 | +static u32 qede_link_to_ethtool_fec(u32 link_fec) |
|---|
| 1840 | +{ |
|---|
| 1841 | + u32 eth_fec = 0; |
|---|
| 1842 | + |
|---|
| 1843 | + if (link_fec & QED_FEC_MODE_NONE) |
|---|
| 1844 | + eth_fec |= ETHTOOL_FEC_OFF; |
|---|
| 1845 | + if (link_fec & QED_FEC_MODE_FIRECODE) |
|---|
| 1846 | + eth_fec |= ETHTOOL_FEC_BASER; |
|---|
| 1847 | + if (link_fec & QED_FEC_MODE_RS) |
|---|
| 1848 | + eth_fec |= ETHTOOL_FEC_RS; |
|---|
| 1849 | + if (link_fec & QED_FEC_MODE_AUTO) |
|---|
| 1850 | + eth_fec |= ETHTOOL_FEC_AUTO; |
|---|
| 1851 | + if (link_fec & QED_FEC_MODE_UNSUPPORTED) |
|---|
| 1852 | + eth_fec |= ETHTOOL_FEC_NONE; |
|---|
| 1853 | + |
|---|
| 1854 | + return eth_fec; |
|---|
| 1855 | +} |
|---|
| 1856 | + |
|---|
| 1857 | +static u32 qede_ethtool_to_link_fec(u32 eth_fec) |
|---|
| 1858 | +{ |
|---|
| 1859 | + u32 link_fec = 0; |
|---|
| 1860 | + |
|---|
| 1861 | + if (eth_fec & ETHTOOL_FEC_OFF) |
|---|
| 1862 | + link_fec |= QED_FEC_MODE_NONE; |
|---|
| 1863 | + if (eth_fec & ETHTOOL_FEC_BASER) |
|---|
| 1864 | + link_fec |= QED_FEC_MODE_FIRECODE; |
|---|
| 1865 | + if (eth_fec & ETHTOOL_FEC_RS) |
|---|
| 1866 | + link_fec |= QED_FEC_MODE_RS; |
|---|
| 1867 | + if (eth_fec & ETHTOOL_FEC_AUTO) |
|---|
| 1868 | + link_fec |= QED_FEC_MODE_AUTO; |
|---|
| 1869 | + if (eth_fec & ETHTOOL_FEC_NONE) |
|---|
| 1870 | + link_fec |= QED_FEC_MODE_UNSUPPORTED; |
|---|
| 1871 | + |
|---|
| 1872 | + return link_fec; |
|---|
| 1873 | +} |
|---|
| 1874 | + |
|---|
| 1875 | +static int qede_get_fecparam(struct net_device *dev, |
|---|
| 1876 | + struct ethtool_fecparam *fecparam) |
|---|
| 1877 | +{ |
|---|
| 1878 | + struct qede_dev *edev = netdev_priv(dev); |
|---|
| 1879 | + struct qed_link_output curr_link; |
|---|
| 1880 | + |
|---|
| 1881 | + memset(&curr_link, 0, sizeof(curr_link)); |
|---|
| 1882 | + edev->ops->common->get_link(edev->cdev, &curr_link); |
|---|
| 1883 | + |
|---|
| 1884 | + fecparam->active_fec = qede_link_to_ethtool_fec(curr_link.active_fec); |
|---|
| 1885 | + fecparam->fec = qede_link_to_ethtool_fec(curr_link.sup_fec); |
|---|
| 1886 | + |
|---|
| 1887 | + return 0; |
|---|
| 1888 | +} |
|---|
| 1889 | + |
|---|
| 1890 | +static int qede_set_fecparam(struct net_device *dev, |
|---|
| 1891 | + struct ethtool_fecparam *fecparam) |
|---|
| 1892 | +{ |
|---|
| 1893 | + struct qede_dev *edev = netdev_priv(dev); |
|---|
| 1894 | + struct qed_link_params params; |
|---|
| 1895 | + |
|---|
| 1896 | + if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) { |
|---|
| 1897 | + DP_INFO(edev, "Link settings are not allowed to be changed\n"); |
|---|
| 1898 | + return -EOPNOTSUPP; |
|---|
| 1899 | + } |
|---|
| 1900 | + |
|---|
| 1901 | + memset(¶ms, 0, sizeof(params)); |
|---|
| 1902 | + params.override_flags |= QED_LINK_OVERRIDE_FEC_CONFIG; |
|---|
| 1903 | + params.fec = qede_ethtool_to_link_fec(fecparam->fec); |
|---|
| 1904 | + params.link_up = true; |
|---|
| 1905 | + |
|---|
| 1906 | + edev->ops->common->set_link(edev->cdev, ¶ms); |
|---|
| 1907 | + |
|---|
| 1908 | + return 0; |
|---|
| 1909 | +} |
|---|
| 1910 | + |
|---|
| 1811 | 1911 | static int qede_get_module_info(struct net_device *dev, |
|---|
| 1812 | 1912 | struct ethtool_modinfo *modinfo) |
|---|
| 1813 | 1913 | { |
|---|
| .. | .. |
|---|
| 1894 | 1994 | return rc; |
|---|
| 1895 | 1995 | } |
|---|
| 1896 | 1996 | |
|---|
| 1897 | | -static const struct ethtool_ops qede_ethtool_ops = { |
|---|
| 1898 | | - .get_link_ksettings = qede_get_link_ksettings, |
|---|
| 1899 | | - .set_link_ksettings = qede_set_link_ksettings, |
|---|
| 1900 | | - .get_drvinfo = qede_get_drvinfo, |
|---|
| 1901 | | - .get_regs_len = qede_get_regs_len, |
|---|
| 1902 | | - .get_regs = qede_get_regs, |
|---|
| 1903 | | - .get_wol = qede_get_wol, |
|---|
| 1904 | | - .set_wol = qede_set_wol, |
|---|
| 1905 | | - .get_msglevel = qede_get_msglevel, |
|---|
| 1906 | | - .set_msglevel = qede_set_msglevel, |
|---|
| 1907 | | - .nway_reset = qede_nway_reset, |
|---|
| 1908 | | - .get_link = qede_get_link, |
|---|
| 1909 | | - .get_coalesce = qede_get_coalesce, |
|---|
| 1910 | | - .set_coalesce = qede_set_coalesce, |
|---|
| 1911 | | - .get_ringparam = qede_get_ringparam, |
|---|
| 1912 | | - .set_ringparam = qede_set_ringparam, |
|---|
| 1913 | | - .get_pauseparam = qede_get_pauseparam, |
|---|
| 1914 | | - .set_pauseparam = qede_set_pauseparam, |
|---|
| 1915 | | - .get_strings = qede_get_strings, |
|---|
| 1916 | | - .set_phys_id = qede_set_phys_id, |
|---|
| 1917 | | - .get_ethtool_stats = qede_get_ethtool_stats, |
|---|
| 1918 | | - .get_priv_flags = qede_get_priv_flags, |
|---|
| 1919 | | - .get_sset_count = qede_get_sset_count, |
|---|
| 1920 | | - .get_rxnfc = qede_get_rxnfc, |
|---|
| 1921 | | - .set_rxnfc = qede_set_rxnfc, |
|---|
| 1922 | | - .get_rxfh_indir_size = qede_get_rxfh_indir_size, |
|---|
| 1923 | | - .get_rxfh_key_size = qede_get_rxfh_key_size, |
|---|
| 1924 | | - .get_rxfh = qede_get_rxfh, |
|---|
| 1925 | | - .set_rxfh = qede_set_rxfh, |
|---|
| 1926 | | - .get_ts_info = qede_get_ts_info, |
|---|
| 1927 | | - .get_channels = qede_get_channels, |
|---|
| 1928 | | - .set_channels = qede_set_channels, |
|---|
| 1929 | | - .self_test = qede_self_test, |
|---|
| 1930 | | - .get_module_info = qede_get_module_info, |
|---|
| 1931 | | - .get_module_eeprom = qede_get_module_eeprom, |
|---|
| 1932 | | - .get_eee = qede_get_eee, |
|---|
| 1933 | | - .set_eee = qede_set_eee, |
|---|
| 1997 | +static int qede_set_dump(struct net_device *dev, struct ethtool_dump *val) |
|---|
| 1998 | +{ |
|---|
| 1999 | + struct qede_dev *edev = netdev_priv(dev); |
|---|
| 2000 | + int rc = 0; |
|---|
| 1934 | 2001 | |
|---|
| 1935 | | - .get_tunable = qede_get_tunable, |
|---|
| 1936 | | - .set_tunable = qede_set_tunable, |
|---|
| 1937 | | - .flash_device = qede_flash_device, |
|---|
| 2002 | + if (edev->dump_info.cmd == QEDE_DUMP_CMD_NONE) { |
|---|
| 2003 | + if (val->flag > QEDE_DUMP_CMD_MAX) { |
|---|
| 2004 | + DP_ERR(edev, "Invalid command %d\n", val->flag); |
|---|
| 2005 | + return -EINVAL; |
|---|
| 2006 | + } |
|---|
| 2007 | + edev->dump_info.cmd = val->flag; |
|---|
| 2008 | + edev->dump_info.num_args = 0; |
|---|
| 2009 | + return 0; |
|---|
| 2010 | + } |
|---|
| 2011 | + |
|---|
| 2012 | + if (edev->dump_info.num_args == QEDE_DUMP_MAX_ARGS) { |
|---|
| 2013 | + DP_ERR(edev, "Arg count = %d\n", edev->dump_info.num_args); |
|---|
| 2014 | + return -EINVAL; |
|---|
| 2015 | + } |
|---|
| 2016 | + |
|---|
| 2017 | + switch (edev->dump_info.cmd) { |
|---|
| 2018 | + case QEDE_DUMP_CMD_NVM_CFG: |
|---|
| 2019 | + edev->dump_info.args[edev->dump_info.num_args] = val->flag; |
|---|
| 2020 | + edev->dump_info.num_args++; |
|---|
| 2021 | + break; |
|---|
| 2022 | + case QEDE_DUMP_CMD_GRCDUMP: |
|---|
| 2023 | + rc = edev->ops->common->set_grc_config(edev->cdev, |
|---|
| 2024 | + val->flag, 1); |
|---|
| 2025 | + break; |
|---|
| 2026 | + default: |
|---|
| 2027 | + break; |
|---|
| 2028 | + } |
|---|
| 2029 | + |
|---|
| 2030 | + return rc; |
|---|
| 2031 | +} |
|---|
| 2032 | + |
|---|
| 2033 | +static int qede_get_dump_flag(struct net_device *dev, |
|---|
| 2034 | + struct ethtool_dump *dump) |
|---|
| 2035 | +{ |
|---|
| 2036 | + struct qede_dev *edev = netdev_priv(dev); |
|---|
| 2037 | + |
|---|
| 2038 | + if (!edev->ops || !edev->ops->common) { |
|---|
| 2039 | + DP_ERR(edev, "Edev ops not populated\n"); |
|---|
| 2040 | + return -EINVAL; |
|---|
| 2041 | + } |
|---|
| 2042 | + |
|---|
| 2043 | + dump->version = QEDE_DUMP_VERSION; |
|---|
| 2044 | + switch (edev->dump_info.cmd) { |
|---|
| 2045 | + case QEDE_DUMP_CMD_NVM_CFG: |
|---|
| 2046 | + dump->flag = QEDE_DUMP_CMD_NVM_CFG; |
|---|
| 2047 | + dump->len = edev->ops->common->read_nvm_cfg_len(edev->cdev, |
|---|
| 2048 | + edev->dump_info.args[0]); |
|---|
| 2049 | + break; |
|---|
| 2050 | + case QEDE_DUMP_CMD_GRCDUMP: |
|---|
| 2051 | + dump->flag = QEDE_DUMP_CMD_GRCDUMP; |
|---|
| 2052 | + dump->len = edev->ops->common->dbg_all_data_size(edev->cdev); |
|---|
| 2053 | + break; |
|---|
| 2054 | + default: |
|---|
| 2055 | + DP_ERR(edev, "Invalid cmd = %d\n", edev->dump_info.cmd); |
|---|
| 2056 | + return -EINVAL; |
|---|
| 2057 | + } |
|---|
| 2058 | + |
|---|
| 2059 | + DP_VERBOSE(edev, QED_MSG_DEBUG, |
|---|
| 2060 | + "dump->version = 0x%x dump->flag = %d dump->len = %d\n", |
|---|
| 2061 | + dump->version, dump->flag, dump->len); |
|---|
| 2062 | + return 0; |
|---|
| 2063 | +} |
|---|
| 2064 | + |
|---|
| 2065 | +static int qede_get_dump_data(struct net_device *dev, |
|---|
| 2066 | + struct ethtool_dump *dump, void *buf) |
|---|
| 2067 | +{ |
|---|
| 2068 | + struct qede_dev *edev = netdev_priv(dev); |
|---|
| 2069 | + int rc = 0; |
|---|
| 2070 | + |
|---|
| 2071 | + if (!edev->ops || !edev->ops->common) { |
|---|
| 2072 | + DP_ERR(edev, "Edev ops not populated\n"); |
|---|
| 2073 | + rc = -EINVAL; |
|---|
| 2074 | + goto err; |
|---|
| 2075 | + } |
|---|
| 2076 | + |
|---|
| 2077 | + switch (edev->dump_info.cmd) { |
|---|
| 2078 | + case QEDE_DUMP_CMD_NVM_CFG: |
|---|
| 2079 | + if (edev->dump_info.num_args != QEDE_DUMP_NVM_ARG_COUNT) { |
|---|
| 2080 | + DP_ERR(edev, "Arg count = %d required = %d\n", |
|---|
| 2081 | + edev->dump_info.num_args, |
|---|
| 2082 | + QEDE_DUMP_NVM_ARG_COUNT); |
|---|
| 2083 | + rc = -EINVAL; |
|---|
| 2084 | + goto err; |
|---|
| 2085 | + } |
|---|
| 2086 | + rc = edev->ops->common->read_nvm_cfg(edev->cdev, (u8 **)&buf, |
|---|
| 2087 | + edev->dump_info.args[0], |
|---|
| 2088 | + edev->dump_info.args[1]); |
|---|
| 2089 | + break; |
|---|
| 2090 | + case QEDE_DUMP_CMD_GRCDUMP: |
|---|
| 2091 | + memset(buf, 0, dump->len); |
|---|
| 2092 | + rc = edev->ops->common->dbg_all_data(edev->cdev, buf); |
|---|
| 2093 | + break; |
|---|
| 2094 | + default: |
|---|
| 2095 | + DP_ERR(edev, "Invalid cmd = %d\n", edev->dump_info.cmd); |
|---|
| 2096 | + rc = -EINVAL; |
|---|
| 2097 | + break; |
|---|
| 2098 | + } |
|---|
| 2099 | + |
|---|
| 2100 | +err: |
|---|
| 2101 | + edev->dump_info.cmd = QEDE_DUMP_CMD_NONE; |
|---|
| 2102 | + edev->dump_info.num_args = 0; |
|---|
| 2103 | + memset(edev->dump_info.args, 0, sizeof(edev->dump_info.args)); |
|---|
| 2104 | + |
|---|
| 2105 | + return rc; |
|---|
| 2106 | +} |
|---|
| 2107 | + |
|---|
| 2108 | +static const struct ethtool_ops qede_ethtool_ops = { |
|---|
| 2109 | + .supported_coalesce_params = ETHTOOL_COALESCE_USECS, |
|---|
| 2110 | + .get_link_ksettings = qede_get_link_ksettings, |
|---|
| 2111 | + .set_link_ksettings = qede_set_link_ksettings, |
|---|
| 2112 | + .get_drvinfo = qede_get_drvinfo, |
|---|
| 2113 | + .get_regs_len = qede_get_regs_len, |
|---|
| 2114 | + .get_regs = qede_get_regs, |
|---|
| 2115 | + .get_wol = qede_get_wol, |
|---|
| 2116 | + .set_wol = qede_set_wol, |
|---|
| 2117 | + .get_msglevel = qede_get_msglevel, |
|---|
| 2118 | + .set_msglevel = qede_set_msglevel, |
|---|
| 2119 | + .nway_reset = qede_nway_reset, |
|---|
| 2120 | + .get_link = qede_get_link, |
|---|
| 2121 | + .get_coalesce = qede_get_coalesce, |
|---|
| 2122 | + .set_coalesce = qede_set_coalesce, |
|---|
| 2123 | + .get_ringparam = qede_get_ringparam, |
|---|
| 2124 | + .set_ringparam = qede_set_ringparam, |
|---|
| 2125 | + .get_pauseparam = qede_get_pauseparam, |
|---|
| 2126 | + .set_pauseparam = qede_set_pauseparam, |
|---|
| 2127 | + .get_strings = qede_get_strings, |
|---|
| 2128 | + .set_phys_id = qede_set_phys_id, |
|---|
| 2129 | + .get_ethtool_stats = qede_get_ethtool_stats, |
|---|
| 2130 | + .get_priv_flags = qede_get_priv_flags, |
|---|
| 2131 | + .set_priv_flags = qede_set_priv_flags, |
|---|
| 2132 | + .get_sset_count = qede_get_sset_count, |
|---|
| 2133 | + .get_rxnfc = qede_get_rxnfc, |
|---|
| 2134 | + .set_rxnfc = qede_set_rxnfc, |
|---|
| 2135 | + .get_rxfh_indir_size = qede_get_rxfh_indir_size, |
|---|
| 2136 | + .get_rxfh_key_size = qede_get_rxfh_key_size, |
|---|
| 2137 | + .get_rxfh = qede_get_rxfh, |
|---|
| 2138 | + .set_rxfh = qede_set_rxfh, |
|---|
| 2139 | + .get_ts_info = qede_get_ts_info, |
|---|
| 2140 | + .get_channels = qede_get_channels, |
|---|
| 2141 | + .set_channels = qede_set_channels, |
|---|
| 2142 | + .self_test = qede_self_test, |
|---|
| 2143 | + .get_module_info = qede_get_module_info, |
|---|
| 2144 | + .get_module_eeprom = qede_get_module_eeprom, |
|---|
| 2145 | + .get_eee = qede_get_eee, |
|---|
| 2146 | + .set_eee = qede_set_eee, |
|---|
| 2147 | + .get_fecparam = qede_get_fecparam, |
|---|
| 2148 | + .set_fecparam = qede_set_fecparam, |
|---|
| 2149 | + .get_tunable = qede_get_tunable, |
|---|
| 2150 | + .set_tunable = qede_set_tunable, |
|---|
| 2151 | + .flash_device = qede_flash_device, |
|---|
| 2152 | + .get_dump_flag = qede_get_dump_flag, |
|---|
| 2153 | + .get_dump_data = qede_get_dump_data, |
|---|
| 2154 | + .set_dump = qede_set_dump, |
|---|
| 1938 | 2155 | }; |
|---|
| 1939 | 2156 | |
|---|
| 1940 | 2157 | static const struct ethtool_ops qede_vf_ethtool_ops = { |
|---|
| 1941 | | - .get_link_ksettings = qede_get_link_ksettings, |
|---|
| 1942 | | - .get_drvinfo = qede_get_drvinfo, |
|---|
| 1943 | | - .get_msglevel = qede_get_msglevel, |
|---|
| 1944 | | - .set_msglevel = qede_set_msglevel, |
|---|
| 1945 | | - .get_link = qede_get_link, |
|---|
| 1946 | | - .get_coalesce = qede_get_coalesce, |
|---|
| 1947 | | - .set_coalesce = qede_set_coalesce, |
|---|
| 1948 | | - .get_ringparam = qede_get_ringparam, |
|---|
| 1949 | | - .set_ringparam = qede_set_ringparam, |
|---|
| 1950 | | - .get_strings = qede_get_strings, |
|---|
| 1951 | | - .get_ethtool_stats = qede_get_ethtool_stats, |
|---|
| 1952 | | - .get_priv_flags = qede_get_priv_flags, |
|---|
| 1953 | | - .get_sset_count = qede_get_sset_count, |
|---|
| 1954 | | - .get_rxnfc = qede_get_rxnfc, |
|---|
| 1955 | | - .set_rxnfc = qede_set_rxnfc, |
|---|
| 1956 | | - .get_rxfh_indir_size = qede_get_rxfh_indir_size, |
|---|
| 1957 | | - .get_rxfh_key_size = qede_get_rxfh_key_size, |
|---|
| 1958 | | - .get_rxfh = qede_get_rxfh, |
|---|
| 1959 | | - .set_rxfh = qede_set_rxfh, |
|---|
| 1960 | | - .get_channels = qede_get_channels, |
|---|
| 1961 | | - .set_channels = qede_set_channels, |
|---|
| 1962 | | - .get_tunable = qede_get_tunable, |
|---|
| 1963 | | - .set_tunable = qede_set_tunable, |
|---|
| 2158 | + .supported_coalesce_params = ETHTOOL_COALESCE_USECS, |
|---|
| 2159 | + .get_link_ksettings = qede_get_link_ksettings, |
|---|
| 2160 | + .get_drvinfo = qede_get_drvinfo, |
|---|
| 2161 | + .get_msglevel = qede_get_msglevel, |
|---|
| 2162 | + .set_msglevel = qede_set_msglevel, |
|---|
| 2163 | + .get_link = qede_get_link, |
|---|
| 2164 | + .get_coalesce = qede_get_coalesce, |
|---|
| 2165 | + .set_coalesce = qede_set_coalesce, |
|---|
| 2166 | + .get_ringparam = qede_get_ringparam, |
|---|
| 2167 | + .set_ringparam = qede_set_ringparam, |
|---|
| 2168 | + .get_strings = qede_get_strings, |
|---|
| 2169 | + .get_ethtool_stats = qede_get_ethtool_stats, |
|---|
| 2170 | + .get_priv_flags = qede_get_priv_flags, |
|---|
| 2171 | + .get_sset_count = qede_get_sset_count, |
|---|
| 2172 | + .get_rxnfc = qede_get_rxnfc, |
|---|
| 2173 | + .set_rxnfc = qede_set_rxnfc, |
|---|
| 2174 | + .get_rxfh_indir_size = qede_get_rxfh_indir_size, |
|---|
| 2175 | + .get_rxfh_key_size = qede_get_rxfh_key_size, |
|---|
| 2176 | + .get_rxfh = qede_get_rxfh, |
|---|
| 2177 | + .set_rxfh = qede_set_rxfh, |
|---|
| 2178 | + .get_channels = qede_get_channels, |
|---|
| 2179 | + .set_channels = qede_set_channels, |
|---|
| 2180 | + .get_tunable = qede_get_tunable, |
|---|
| 2181 | + .set_tunable = qede_set_tunable, |
|---|
| 1964 | 2182 | }; |
|---|
| 1965 | 2183 | |
|---|
| 1966 | 2184 | void qede_set_ethtool_ops(struct net_device *dev) |
|---|