1133fac0eSSudarsana Kalluru /* QLogic qede NIC Driver 2e8f1cb50SMintz, Yuval * Copyright (c) 2015-2017 QLogic Corporation 3133fac0eSSudarsana Kalluru * 4e8f1cb50SMintz, Yuval * This software is available to you under a choice of one of two 5e8f1cb50SMintz, Yuval * licenses. You may choose to be licensed under the terms of the GNU 6e8f1cb50SMintz, Yuval * General Public License (GPL) Version 2, available from the file 7e8f1cb50SMintz, Yuval * COPYING in the main directory of this source tree, or the 8e8f1cb50SMintz, Yuval * OpenIB.org BSD license below: 9e8f1cb50SMintz, Yuval * 10e8f1cb50SMintz, Yuval * Redistribution and use in source and binary forms, with or 11e8f1cb50SMintz, Yuval * without modification, are permitted provided that the following 12e8f1cb50SMintz, Yuval * conditions are met: 13e8f1cb50SMintz, Yuval * 14e8f1cb50SMintz, Yuval * - Redistributions of source code must retain the above 15e8f1cb50SMintz, Yuval * copyright notice, this list of conditions and the following 16e8f1cb50SMintz, Yuval * disclaimer. 17e8f1cb50SMintz, Yuval * 18e8f1cb50SMintz, Yuval * - Redistributions in binary form must reproduce the above 19e8f1cb50SMintz, Yuval * copyright notice, this list of conditions and the following 20e8f1cb50SMintz, Yuval * disclaimer in the documentation and /or other materials 21e8f1cb50SMintz, Yuval * provided with the distribution. 22e8f1cb50SMintz, Yuval * 23e8f1cb50SMintz, Yuval * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24e8f1cb50SMintz, Yuval * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25e8f1cb50SMintz, Yuval * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26e8f1cb50SMintz, Yuval * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27e8f1cb50SMintz, Yuval * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28e8f1cb50SMintz, Yuval * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29e8f1cb50SMintz, Yuval * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30e8f1cb50SMintz, Yuval * SOFTWARE. 31133fac0eSSudarsana Kalluru */ 32133fac0eSSudarsana Kalluru #include <linux/version.h> 33133fac0eSSudarsana Kalluru #include <linux/types.h> 34133fac0eSSudarsana Kalluru #include <linux/netdevice.h> 3516f46bf0SSudarsana Reddy Kalluru #include <linux/etherdevice.h> 36133fac0eSSudarsana Kalluru #include <linux/ethtool.h> 37133fac0eSSudarsana Kalluru #include <linux/string.h> 38133fac0eSSudarsana Kalluru #include <linux/pci.h> 39133fac0eSSudarsana Kalluru #include <linux/capability.h> 40f29ffdb6SMintz, Yuval #include <linux/vmalloc.h> 41133fac0eSSudarsana Kalluru #include "qede.h" 424c55215cSSudarsana Reddy Kalluru #include "qede_ptp.h" 43133fac0eSSudarsana Kalluru 44133fac0eSSudarsana Kalluru #define QEDE_RQSTAT_OFFSET(stat_name) \ 45133fac0eSSudarsana Kalluru (offsetof(struct qede_rx_queue, stat_name)) 46133fac0eSSudarsana Kalluru #define QEDE_RQSTAT_STRING(stat_name) (#stat_name) 47133fac0eSSudarsana Kalluru #define QEDE_RQSTAT(stat_name) \ 48133fac0eSSudarsana Kalluru {QEDE_RQSTAT_OFFSET(stat_name), QEDE_RQSTAT_STRING(stat_name)} 4916f46bf0SSudarsana Reddy Kalluru 5016f46bf0SSudarsana Reddy Kalluru #define QEDE_SELFTEST_POLL_COUNT 100 5116f46bf0SSudarsana Reddy Kalluru 52133fac0eSSudarsana Kalluru static const struct { 53133fac0eSSudarsana Kalluru u64 offset; 54133fac0eSSudarsana Kalluru char string[ETH_GSTRING_LEN]; 55133fac0eSSudarsana Kalluru } qede_rqstats_arr[] = { 5668db9ec2SSudarsana Reddy Kalluru QEDE_RQSTAT(rcv_pkts), 57133fac0eSSudarsana Kalluru QEDE_RQSTAT(rx_hw_errors), 58133fac0eSSudarsana Kalluru QEDE_RQSTAT(rx_alloc_errors), 59c72a6125SManish Chopra QEDE_RQSTAT(rx_ip_frags), 60496e0517SMintz, Yuval QEDE_RQSTAT(xdp_no_pass), 61133fac0eSSudarsana Kalluru }; 62133fac0eSSudarsana Kalluru 63133fac0eSSudarsana Kalluru #define QEDE_NUM_RQSTATS ARRAY_SIZE(qede_rqstats_arr) 6468db9ec2SSudarsana Reddy Kalluru #define QEDE_TQSTAT_OFFSET(stat_name) \ 6568db9ec2SSudarsana Reddy Kalluru (offsetof(struct qede_tx_queue, stat_name)) 6668db9ec2SSudarsana Reddy Kalluru #define QEDE_TQSTAT_STRING(stat_name) (#stat_name) 6768db9ec2SSudarsana Reddy Kalluru #define QEDE_TQSTAT(stat_name) \ 6868db9ec2SSudarsana Reddy Kalluru {QEDE_TQSTAT_OFFSET(stat_name), QEDE_TQSTAT_STRING(stat_name)} 6968db9ec2SSudarsana Reddy Kalluru #define QEDE_NUM_TQSTATS ARRAY_SIZE(qede_tqstats_arr) 7068db9ec2SSudarsana Reddy Kalluru static const struct { 7168db9ec2SSudarsana Reddy Kalluru u64 offset; 7268db9ec2SSudarsana Reddy Kalluru char string[ETH_GSTRING_LEN]; 7368db9ec2SSudarsana Reddy Kalluru } qede_tqstats_arr[] = { 7468db9ec2SSudarsana Reddy Kalluru QEDE_TQSTAT(xmit_pkts), 7568db9ec2SSudarsana Reddy Kalluru QEDE_TQSTAT(stopped_cnt), 7668db9ec2SSudarsana Reddy Kalluru }; 7768db9ec2SSudarsana Reddy Kalluru 789c79ddaaSMintz, Yuval #define QEDE_STAT_OFFSET(stat_name, type, base) \ 799c79ddaaSMintz, Yuval (offsetof(type, stat_name) + (base)) 804dbcd640SMintz, Yuval #define QEDE_STAT_STRING(stat_name) (#stat_name) 819c79ddaaSMintz, Yuval #define _QEDE_STAT(stat_name, type, base, attr) \ 829c79ddaaSMintz, Yuval {QEDE_STAT_OFFSET(stat_name, type, base), \ 839c79ddaaSMintz, Yuval QEDE_STAT_STRING(stat_name), \ 849c79ddaaSMintz, Yuval attr} 859c79ddaaSMintz, Yuval #define QEDE_STAT(stat_name) \ 869c79ddaaSMintz, Yuval _QEDE_STAT(stat_name, struct qede_stats_common, 0, 0x0) 879c79ddaaSMintz, Yuval #define QEDE_PF_STAT(stat_name) \ 889c79ddaaSMintz, Yuval _QEDE_STAT(stat_name, struct qede_stats_common, 0, \ 899c79ddaaSMintz, Yuval BIT(QEDE_STAT_PF_ONLY)) 909c79ddaaSMintz, Yuval #define QEDE_PF_BB_STAT(stat_name) \ 919c79ddaaSMintz, Yuval _QEDE_STAT(stat_name, struct qede_stats_bb, \ 929c79ddaaSMintz, Yuval offsetof(struct qede_stats, bb), \ 939c79ddaaSMintz, Yuval BIT(QEDE_STAT_PF_ONLY) | BIT(QEDE_STAT_BB_ONLY)) 949c79ddaaSMintz, Yuval #define QEDE_PF_AH_STAT(stat_name) \ 959c79ddaaSMintz, Yuval _QEDE_STAT(stat_name, struct qede_stats_ah, \ 969c79ddaaSMintz, Yuval offsetof(struct qede_stats, ah), \ 979c79ddaaSMintz, Yuval BIT(QEDE_STAT_PF_ONLY) | BIT(QEDE_STAT_AH_ONLY)) 98133fac0eSSudarsana Kalluru static const struct { 99133fac0eSSudarsana Kalluru u64 offset; 100133fac0eSSudarsana Kalluru char string[ETH_GSTRING_LEN]; 1019c79ddaaSMintz, Yuval unsigned long attr; 1029c79ddaaSMintz, Yuval #define QEDE_STAT_PF_ONLY 0 1039c79ddaaSMintz, Yuval #define QEDE_STAT_BB_ONLY 1 1049c79ddaaSMintz, Yuval #define QEDE_STAT_AH_ONLY 2 105133fac0eSSudarsana Kalluru } qede_stats_arr[] = { 106133fac0eSSudarsana Kalluru QEDE_STAT(rx_ucast_bytes), 107133fac0eSSudarsana Kalluru QEDE_STAT(rx_mcast_bytes), 108133fac0eSSudarsana Kalluru QEDE_STAT(rx_bcast_bytes), 109133fac0eSSudarsana Kalluru QEDE_STAT(rx_ucast_pkts), 110133fac0eSSudarsana Kalluru QEDE_STAT(rx_mcast_pkts), 111133fac0eSSudarsana Kalluru QEDE_STAT(rx_bcast_pkts), 112133fac0eSSudarsana Kalluru 113133fac0eSSudarsana Kalluru QEDE_STAT(tx_ucast_bytes), 114133fac0eSSudarsana Kalluru QEDE_STAT(tx_mcast_bytes), 115133fac0eSSudarsana Kalluru QEDE_STAT(tx_bcast_bytes), 116133fac0eSSudarsana Kalluru QEDE_STAT(tx_ucast_pkts), 117133fac0eSSudarsana Kalluru QEDE_STAT(tx_mcast_pkts), 118133fac0eSSudarsana Kalluru QEDE_STAT(tx_bcast_pkts), 119133fac0eSSudarsana Kalluru 120133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_64_byte_packets), 121d4967cf3SYuval Mintz QEDE_PF_STAT(rx_65_to_127_byte_packets), 122d4967cf3SYuval Mintz QEDE_PF_STAT(rx_128_to_255_byte_packets), 123d4967cf3SYuval Mintz QEDE_PF_STAT(rx_256_to_511_byte_packets), 124d4967cf3SYuval Mintz QEDE_PF_STAT(rx_512_to_1023_byte_packets), 125d4967cf3SYuval Mintz QEDE_PF_STAT(rx_1024_to_1518_byte_packets), 1269c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(rx_1519_to_1522_byte_packets), 1279c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(rx_1519_to_2047_byte_packets), 1289c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(rx_2048_to_4095_byte_packets), 1299c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(rx_4096_to_9216_byte_packets), 1309c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(rx_9217_to_16383_byte_packets), 1319c79ddaaSMintz, Yuval QEDE_PF_AH_STAT(rx_1519_to_max_byte_packets), 132133fac0eSSudarsana Kalluru QEDE_PF_STAT(tx_64_byte_packets), 133133fac0eSSudarsana Kalluru QEDE_PF_STAT(tx_65_to_127_byte_packets), 134133fac0eSSudarsana Kalluru QEDE_PF_STAT(tx_128_to_255_byte_packets), 135133fac0eSSudarsana Kalluru QEDE_PF_STAT(tx_256_to_511_byte_packets), 136133fac0eSSudarsana Kalluru QEDE_PF_STAT(tx_512_to_1023_byte_packets), 137133fac0eSSudarsana Kalluru QEDE_PF_STAT(tx_1024_to_1518_byte_packets), 1389c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(tx_1519_to_2047_byte_packets), 1399c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(tx_2048_to_4095_byte_packets), 1409c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(tx_4096_to_9216_byte_packets), 1419c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(tx_9217_to_16383_byte_packets), 1429c79ddaaSMintz, Yuval QEDE_PF_AH_STAT(tx_1519_to_max_byte_packets), 143133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_mac_crtl_frames), 144133fac0eSSudarsana Kalluru QEDE_PF_STAT(tx_mac_ctrl_frames), 145133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_pause_frames), 146133fac0eSSudarsana Kalluru QEDE_PF_STAT(tx_pause_frames), 147133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_pfc_frames), 148133fac0eSSudarsana Kalluru QEDE_PF_STAT(tx_pfc_frames), 149133fac0eSSudarsana Kalluru 150133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_crc_errors), 151133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_align_errors), 152133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_carrier_errors), 153133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_oversize_packets), 154133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_jabbers), 155133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_undersize_packets), 156133fac0eSSudarsana Kalluru QEDE_PF_STAT(rx_fragments), 1579c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(tx_lpi_entry_count), 1589c79ddaaSMintz, Yuval QEDE_PF_BB_STAT(tx_total_collisions), 159133fac0eSSudarsana Kalluru QEDE_PF_STAT(brb_truncates), 160133fac0eSSudarsana Kalluru QEDE_PF_STAT(brb_discards), 161133fac0eSSudarsana Kalluru QEDE_STAT(no_buff_discards), 162133fac0eSSudarsana Kalluru QEDE_PF_STAT(mftag_filter_discards), 163133fac0eSSudarsana Kalluru QEDE_PF_STAT(mac_filter_discards), 164133fac0eSSudarsana Kalluru QEDE_STAT(tx_err_drop_pkts), 1651a5a366fSSudarsana Reddy Kalluru QEDE_STAT(ttl0_discard), 1661a5a366fSSudarsana Reddy Kalluru QEDE_STAT(packet_too_big_discard), 167133fac0eSSudarsana Kalluru 168133fac0eSSudarsana Kalluru QEDE_STAT(coalesced_pkts), 169133fac0eSSudarsana Kalluru QEDE_STAT(coalesced_events), 170133fac0eSSudarsana Kalluru QEDE_STAT(coalesced_aborts_num), 171133fac0eSSudarsana Kalluru QEDE_STAT(non_coalesced_pkts), 172133fac0eSSudarsana Kalluru QEDE_STAT(coalesced_bytes), 173133fac0eSSudarsana Kalluru }; 174133fac0eSSudarsana Kalluru 175133fac0eSSudarsana Kalluru #define QEDE_NUM_STATS ARRAY_SIZE(qede_stats_arr) 1769c79ddaaSMintz, Yuval #define QEDE_STAT_IS_PF_ONLY(i) \ 1779c79ddaaSMintz, Yuval test_bit(QEDE_STAT_PF_ONLY, &qede_stats_arr[i].attr) 1789c79ddaaSMintz, Yuval #define QEDE_STAT_IS_BB_ONLY(i) \ 1799c79ddaaSMintz, Yuval test_bit(QEDE_STAT_BB_ONLY, &qede_stats_arr[i].attr) 1809c79ddaaSMintz, Yuval #define QEDE_STAT_IS_AH_ONLY(i) \ 1819c79ddaaSMintz, Yuval test_bit(QEDE_STAT_AH_ONLY, &qede_stats_arr[i].attr) 182133fac0eSSudarsana Kalluru 183f3e72109SYuval Mintz enum { 184f3e72109SYuval Mintz QEDE_PRI_FLAG_CMT, 185f3e72109SYuval Mintz QEDE_PRI_FLAG_LEN, 186f3e72109SYuval Mintz }; 187f3e72109SYuval Mintz 188f3e72109SYuval Mintz static const char qede_private_arr[QEDE_PRI_FLAG_LEN][ETH_GSTRING_LEN] = { 189f3e72109SYuval Mintz "Coupled-Function", 190f3e72109SYuval Mintz }; 191f3e72109SYuval Mintz 1923044a02eSSudarsana Reddy Kalluru enum qede_ethtool_tests { 19316f46bf0SSudarsana Reddy Kalluru QEDE_ETHTOOL_INT_LOOPBACK, 1943044a02eSSudarsana Reddy Kalluru QEDE_ETHTOOL_INTERRUPT_TEST, 1953044a02eSSudarsana Reddy Kalluru QEDE_ETHTOOL_MEMORY_TEST, 1963044a02eSSudarsana Reddy Kalluru QEDE_ETHTOOL_REGISTER_TEST, 1973044a02eSSudarsana Reddy Kalluru QEDE_ETHTOOL_CLOCK_TEST, 1987a4b21b7SMintz, Yuval QEDE_ETHTOOL_NVRAM_TEST, 1993044a02eSSudarsana Reddy Kalluru QEDE_ETHTOOL_TEST_MAX 2003044a02eSSudarsana Reddy Kalluru }; 2013044a02eSSudarsana Reddy Kalluru 2023044a02eSSudarsana Reddy Kalluru static const char qede_tests_str_arr[QEDE_ETHTOOL_TEST_MAX][ETH_GSTRING_LEN] = { 20316f46bf0SSudarsana Reddy Kalluru "Internal loopback (offline)", 2043044a02eSSudarsana Reddy Kalluru "Interrupt (online)\t", 2053044a02eSSudarsana Reddy Kalluru "Memory (online)\t\t", 2063044a02eSSudarsana Reddy Kalluru "Register (online)\t", 2073044a02eSSudarsana Reddy Kalluru "Clock (online)\t\t", 2087a4b21b7SMintz, Yuval "Nvram (online)\t\t", 2093044a02eSSudarsana Reddy Kalluru }; 2103044a02eSSudarsana Reddy Kalluru 2114dbcd640SMintz, Yuval static void qede_get_strings_stats_txq(struct qede_dev *edev, 2124dbcd640SMintz, Yuval struct qede_tx_queue *txq, u8 **buf) 2134dbcd640SMintz, Yuval { 2144dbcd640SMintz, Yuval int i; 2154dbcd640SMintz, Yuval 2164dbcd640SMintz, Yuval for (i = 0; i < QEDE_NUM_TQSTATS; i++) { 217cb6aeb07SMintz, Yuval if (txq->is_xdp) 218cb6aeb07SMintz, Yuval sprintf(*buf, "%d [XDP]: %s", 219cb6aeb07SMintz, Yuval QEDE_TXQ_XDP_TO_IDX(edev, txq), 220cb6aeb07SMintz, Yuval qede_tqstats_arr[i].string); 221cb6aeb07SMintz, Yuval else 2224dbcd640SMintz, Yuval sprintf(*buf, "%d: %s", txq->index, 2234dbcd640SMintz, Yuval qede_tqstats_arr[i].string); 2244dbcd640SMintz, Yuval *buf += ETH_GSTRING_LEN; 2254dbcd640SMintz, Yuval } 2264dbcd640SMintz, Yuval } 2274dbcd640SMintz, Yuval 2284dbcd640SMintz, Yuval static void qede_get_strings_stats_rxq(struct qede_dev *edev, 2294dbcd640SMintz, Yuval struct qede_rx_queue *rxq, u8 **buf) 2304dbcd640SMintz, Yuval { 2314dbcd640SMintz, Yuval int i; 2324dbcd640SMintz, Yuval 2334dbcd640SMintz, Yuval for (i = 0; i < QEDE_NUM_RQSTATS; i++) { 2344dbcd640SMintz, Yuval sprintf(*buf, "%d: %s", rxq->rxq_id, 2354dbcd640SMintz, Yuval qede_rqstats_arr[i].string); 2364dbcd640SMintz, Yuval *buf += ETH_GSTRING_LEN; 2374dbcd640SMintz, Yuval } 2384dbcd640SMintz, Yuval } 2394dbcd640SMintz, Yuval 2409c79ddaaSMintz, Yuval static bool qede_is_irrelevant_stat(struct qede_dev *edev, int stat_index) 2419c79ddaaSMintz, Yuval { 2429c79ddaaSMintz, Yuval return (IS_VF(edev) && QEDE_STAT_IS_PF_ONLY(stat_index)) || 2439c79ddaaSMintz, Yuval (QEDE_IS_BB(edev) && QEDE_STAT_IS_AH_ONLY(stat_index)) || 2449c79ddaaSMintz, Yuval (QEDE_IS_AH(edev) && QEDE_STAT_IS_BB_ONLY(stat_index)); 2459c79ddaaSMintz, Yuval } 2469c79ddaaSMintz, Yuval 247133fac0eSSudarsana Kalluru static void qede_get_strings_stats(struct qede_dev *edev, u8 *buf) 248133fac0eSSudarsana Kalluru { 2494dbcd640SMintz, Yuval struct qede_fastpath *fp; 2504dbcd640SMintz, Yuval int i; 251133fac0eSSudarsana Kalluru 2524dbcd640SMintz, Yuval /* Account for queue statistics */ 2534dbcd640SMintz, Yuval for (i = 0; i < QEDE_QUEUE_CNT(edev); i++) { 2544dbcd640SMintz, Yuval fp = &edev->fp_array[i]; 25568db9ec2SSudarsana Reddy Kalluru 2564dbcd640SMintz, Yuval if (fp->type & QEDE_FASTPATH_RX) 2574dbcd640SMintz, Yuval qede_get_strings_stats_rxq(edev, fp->rxq, &buf); 2584dbcd640SMintz, Yuval 259cb6aeb07SMintz, Yuval if (fp->type & QEDE_FASTPATH_XDP) 260cb6aeb07SMintz, Yuval qede_get_strings_stats_txq(edev, fp->xdp_tx, &buf); 261cb6aeb07SMintz, Yuval 2624dbcd640SMintz, Yuval if (fp->type & QEDE_FASTPATH_TX) 2634dbcd640SMintz, Yuval qede_get_strings_stats_txq(edev, fp->txq, &buf); 264cbbf049aSMintz, Yuval } 265cbbf049aSMintz, Yuval 2664dbcd640SMintz, Yuval /* Account for non-queue statistics */ 2674dbcd640SMintz, Yuval for (i = 0; i < QEDE_NUM_STATS; i++) { 2689c79ddaaSMintz, Yuval if (qede_is_irrelevant_stat(edev, i)) 269fefb0202SYuval Mintz continue; 2704dbcd640SMintz, Yuval strcpy(buf, qede_stats_arr[i].string); 2714dbcd640SMintz, Yuval buf += ETH_GSTRING_LEN; 272133fac0eSSudarsana Kalluru } 273133fac0eSSudarsana Kalluru } 274133fac0eSSudarsana Kalluru 275133fac0eSSudarsana Kalluru static void qede_get_strings(struct net_device *dev, u32 stringset, u8 *buf) 276133fac0eSSudarsana Kalluru { 277133fac0eSSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 278133fac0eSSudarsana Kalluru 279133fac0eSSudarsana Kalluru switch (stringset) { 280133fac0eSSudarsana Kalluru case ETH_SS_STATS: 281133fac0eSSudarsana Kalluru qede_get_strings_stats(edev, buf); 282133fac0eSSudarsana Kalluru break; 283f3e72109SYuval Mintz case ETH_SS_PRIV_FLAGS: 284f3e72109SYuval Mintz memcpy(buf, qede_private_arr, 285f3e72109SYuval Mintz ETH_GSTRING_LEN * QEDE_PRI_FLAG_LEN); 286f3e72109SYuval Mintz break; 2873044a02eSSudarsana Reddy Kalluru case ETH_SS_TEST: 2883044a02eSSudarsana Reddy Kalluru memcpy(buf, qede_tests_str_arr, 2893044a02eSSudarsana Reddy Kalluru ETH_GSTRING_LEN * QEDE_ETHTOOL_TEST_MAX); 2903044a02eSSudarsana Reddy Kalluru break; 291133fac0eSSudarsana Kalluru default: 292133fac0eSSudarsana Kalluru DP_VERBOSE(edev, QED_MSG_DEBUG, 293133fac0eSSudarsana Kalluru "Unsupported stringset 0x%08x\n", stringset); 294133fac0eSSudarsana Kalluru } 295133fac0eSSudarsana Kalluru } 296133fac0eSSudarsana Kalluru 2974dbcd640SMintz, Yuval static void qede_get_ethtool_stats_txq(struct qede_tx_queue *txq, u64 **buf) 2984dbcd640SMintz, Yuval { 2994dbcd640SMintz, Yuval int i; 3004dbcd640SMintz, Yuval 3014dbcd640SMintz, Yuval for (i = 0; i < QEDE_NUM_TQSTATS; i++) { 3024dbcd640SMintz, Yuval **buf = *((u64 *)(((void *)txq) + qede_tqstats_arr[i].offset)); 3034dbcd640SMintz, Yuval (*buf)++; 3044dbcd640SMintz, Yuval } 3054dbcd640SMintz, Yuval } 3064dbcd640SMintz, Yuval 3074dbcd640SMintz, Yuval static void qede_get_ethtool_stats_rxq(struct qede_rx_queue *rxq, u64 **buf) 3084dbcd640SMintz, Yuval { 3094dbcd640SMintz, Yuval int i; 3104dbcd640SMintz, Yuval 3114dbcd640SMintz, Yuval for (i = 0; i < QEDE_NUM_RQSTATS; i++) { 3124dbcd640SMintz, Yuval **buf = *((u64 *)(((void *)rxq) + qede_rqstats_arr[i].offset)); 3134dbcd640SMintz, Yuval (*buf)++; 3144dbcd640SMintz, Yuval } 3154dbcd640SMintz, Yuval } 3164dbcd640SMintz, Yuval 317133fac0eSSudarsana Kalluru static void qede_get_ethtool_stats(struct net_device *dev, 318133fac0eSSudarsana Kalluru struct ethtool_stats *stats, u64 *buf) 319133fac0eSSudarsana Kalluru { 320133fac0eSSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 3214dbcd640SMintz, Yuval struct qede_fastpath *fp; 3224dbcd640SMintz, Yuval int i; 323133fac0eSSudarsana Kalluru 324133fac0eSSudarsana Kalluru qede_fill_by_demand_stats(edev); 325133fac0eSSudarsana Kalluru 326567b3c12SMintz, Yuval /* Need to protect the access to the fastpath array */ 327567b3c12SMintz, Yuval __qede_lock(edev); 328567b3c12SMintz, Yuval 3294dbcd640SMintz, Yuval for (i = 0; i < QEDE_QUEUE_CNT(edev); i++) { 3304dbcd640SMintz, Yuval fp = &edev->fp_array[i]; 331133fac0eSSudarsana Kalluru 3324dbcd640SMintz, Yuval if (fp->type & QEDE_FASTPATH_RX) 3334dbcd640SMintz, Yuval qede_get_ethtool_stats_rxq(fp->rxq, &buf); 33468db9ec2SSudarsana Reddy Kalluru 335cb6aeb07SMintz, Yuval if (fp->type & QEDE_FASTPATH_XDP) 336cb6aeb07SMintz, Yuval qede_get_ethtool_stats_txq(fp->xdp_tx, &buf); 337cb6aeb07SMintz, Yuval 3384dbcd640SMintz, Yuval if (fp->type & QEDE_FASTPATH_TX) 3394dbcd640SMintz, Yuval qede_get_ethtool_stats_txq(fp->txq, &buf); 34068db9ec2SSudarsana Reddy Kalluru } 34168db9ec2SSudarsana Reddy Kalluru 3424dbcd640SMintz, Yuval for (i = 0; i < QEDE_NUM_STATS; i++) { 3439c79ddaaSMintz, Yuval if (qede_is_irrelevant_stat(edev, i)) 344fefb0202SYuval Mintz continue; 3454dbcd640SMintz, Yuval *buf = *((u64 *)(((void *)&edev->stats) + 3464dbcd640SMintz, Yuval qede_stats_arr[i].offset)); 3474dbcd640SMintz, Yuval 3484dbcd640SMintz, Yuval buf++; 349fefb0202SYuval Mintz } 350133fac0eSSudarsana Kalluru 351567b3c12SMintz, Yuval __qede_unlock(edev); 352133fac0eSSudarsana Kalluru } 353133fac0eSSudarsana Kalluru 354133fac0eSSudarsana Kalluru static int qede_get_sset_count(struct net_device *dev, int stringset) 355133fac0eSSudarsana Kalluru { 356133fac0eSSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 3579c79ddaaSMintz, Yuval int num_stats = QEDE_NUM_STATS, i; 358133fac0eSSudarsana Kalluru 359133fac0eSSudarsana Kalluru switch (stringset) { 360133fac0eSSudarsana Kalluru case ETH_SS_STATS: 361fefb0202SYuval Mintz for (i = 0; i < QEDE_NUM_STATS; i++) 3629c79ddaaSMintz, Yuval if (qede_is_irrelevant_stat(edev, i)) 363fefb0202SYuval Mintz num_stats--; 3644dbcd640SMintz, Yuval 3654dbcd640SMintz, Yuval /* Account for the Regular Tx statistics */ 3664dbcd640SMintz, Yuval num_stats += QEDE_TSS_COUNT(edev) * QEDE_NUM_TQSTATS; 3674dbcd640SMintz, Yuval 3684dbcd640SMintz, Yuval /* Account for the Regular Rx statistics */ 3694dbcd640SMintz, Yuval num_stats += QEDE_RSS_COUNT(edev) * QEDE_NUM_RQSTATS; 3704dbcd640SMintz, Yuval 371cb6aeb07SMintz, Yuval /* Account for XDP statistics [if needed] */ 372cb6aeb07SMintz, Yuval if (edev->xdp_prog) 373cb6aeb07SMintz, Yuval num_stats += QEDE_RSS_COUNT(edev) * QEDE_NUM_TQSTATS; 3744dbcd640SMintz, Yuval return num_stats; 3754dbcd640SMintz, Yuval 376f3e72109SYuval Mintz case ETH_SS_PRIV_FLAGS: 377f3e72109SYuval Mintz return QEDE_PRI_FLAG_LEN; 3783044a02eSSudarsana Reddy Kalluru case ETH_SS_TEST: 3796ecb0a0cSYuval Mintz if (!IS_VF(edev)) 3803044a02eSSudarsana Reddy Kalluru return QEDE_ETHTOOL_TEST_MAX; 3816ecb0a0cSYuval Mintz else 3826ecb0a0cSYuval Mintz return 0; 383133fac0eSSudarsana Kalluru default: 384133fac0eSSudarsana Kalluru DP_VERBOSE(edev, QED_MSG_DEBUG, 385133fac0eSSudarsana Kalluru "Unsupported stringset 0x%08x\n", stringset); 386133fac0eSSudarsana Kalluru return -EINVAL; 387133fac0eSSudarsana Kalluru } 388133fac0eSSudarsana Kalluru } 389133fac0eSSudarsana Kalluru 390f3e72109SYuval Mintz static u32 qede_get_priv_flags(struct net_device *dev) 391f3e72109SYuval Mintz { 392f3e72109SYuval Mintz struct qede_dev *edev = netdev_priv(dev); 393f3e72109SYuval Mintz 394f3e72109SYuval Mintz return (!!(edev->dev_info.common.num_hwfns > 1)) << QEDE_PRI_FLAG_CMT; 395f3e72109SYuval Mintz } 396f3e72109SYuval Mintz 397054c67d1SSudarsana Reddy Kalluru struct qede_link_mode_mapping { 398054c67d1SSudarsana Reddy Kalluru u32 qed_link_mode; 399054c67d1SSudarsana Reddy Kalluru u32 ethtool_link_mode; 400054c67d1SSudarsana Reddy Kalluru }; 401054c67d1SSudarsana Reddy Kalluru 402054c67d1SSudarsana Reddy Kalluru static const struct qede_link_mode_mapping qed_lm_map[] = { 403054c67d1SSudarsana Reddy Kalluru {QED_LM_FIBRE_BIT, ETHTOOL_LINK_MODE_FIBRE_BIT}, 404054c67d1SSudarsana Reddy Kalluru {QED_LM_Autoneg_BIT, ETHTOOL_LINK_MODE_Autoneg_BIT}, 405054c67d1SSudarsana Reddy Kalluru {QED_LM_Asym_Pause_BIT, ETHTOOL_LINK_MODE_Asym_Pause_BIT}, 406054c67d1SSudarsana Reddy Kalluru {QED_LM_Pause_BIT, ETHTOOL_LINK_MODE_Pause_BIT}, 407054c67d1SSudarsana Reddy Kalluru {QED_LM_1000baseT_Half_BIT, ETHTOOL_LINK_MODE_1000baseT_Half_BIT}, 408054c67d1SSudarsana Reddy Kalluru {QED_LM_1000baseT_Full_BIT, ETHTOOL_LINK_MODE_1000baseT_Full_BIT}, 409054c67d1SSudarsana Reddy Kalluru {QED_LM_10000baseKR_Full_BIT, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT}, 410054c67d1SSudarsana Reddy Kalluru {QED_LM_25000baseKR_Full_BIT, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT}, 411054c67d1SSudarsana Reddy Kalluru {QED_LM_40000baseLR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT}, 412054c67d1SSudarsana Reddy Kalluru {QED_LM_50000baseKR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT}, 413054c67d1SSudarsana Reddy Kalluru {QED_LM_100000baseKR4_Full_BIT, 414054c67d1SSudarsana Reddy Kalluru ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT}, 415054c67d1SSudarsana Reddy Kalluru }; 416054c67d1SSudarsana Reddy Kalluru 417054c67d1SSudarsana Reddy Kalluru #define QEDE_DRV_TO_ETHTOOL_CAPS(caps, lk_ksettings, name) \ 418054c67d1SSudarsana Reddy Kalluru { \ 419054c67d1SSudarsana Reddy Kalluru int i; \ 420054c67d1SSudarsana Reddy Kalluru \ 421d7455f6eSMintz, Yuval for (i = 0; i < ARRAY_SIZE(qed_lm_map); i++) { \ 422054c67d1SSudarsana Reddy Kalluru if ((caps) & (qed_lm_map[i].qed_link_mode)) \ 423054c67d1SSudarsana Reddy Kalluru __set_bit(qed_lm_map[i].ethtool_link_mode,\ 424054c67d1SSudarsana Reddy Kalluru lk_ksettings->link_modes.name); \ 425054c67d1SSudarsana Reddy Kalluru } \ 426054c67d1SSudarsana Reddy Kalluru } 427054c67d1SSudarsana Reddy Kalluru 428054c67d1SSudarsana Reddy Kalluru #define QEDE_ETHTOOL_TO_DRV_CAPS(caps, lk_ksettings, name) \ 429054c67d1SSudarsana Reddy Kalluru { \ 430054c67d1SSudarsana Reddy Kalluru int i; \ 431054c67d1SSudarsana Reddy Kalluru \ 432d7455f6eSMintz, Yuval for (i = 0; i < ARRAY_SIZE(qed_lm_map); i++) { \ 433054c67d1SSudarsana Reddy Kalluru if (test_bit(qed_lm_map[i].ethtool_link_mode, \ 434054c67d1SSudarsana Reddy Kalluru lk_ksettings->link_modes.name)) \ 435054c67d1SSudarsana Reddy Kalluru caps |= qed_lm_map[i].qed_link_mode; \ 436054c67d1SSudarsana Reddy Kalluru } \ 437054c67d1SSudarsana Reddy Kalluru } 438054c67d1SSudarsana Reddy Kalluru 439054c67d1SSudarsana Reddy Kalluru static int qede_get_link_ksettings(struct net_device *dev, 440054c67d1SSudarsana Reddy Kalluru struct ethtool_link_ksettings *cmd) 441133fac0eSSudarsana Kalluru { 442054c67d1SSudarsana Reddy Kalluru struct ethtool_link_settings *base = &cmd->base; 443133fac0eSSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 444133fac0eSSudarsana Kalluru struct qed_link_output current_link; 445133fac0eSSudarsana Kalluru 446567b3c12SMintz, Yuval __qede_lock(edev); 447567b3c12SMintz, Yuval 448133fac0eSSudarsana Kalluru memset(¤t_link, 0, sizeof(current_link)); 449133fac0eSSudarsana Kalluru edev->ops->common->get_link(edev->cdev, ¤t_link); 450133fac0eSSudarsana Kalluru 451054c67d1SSudarsana Reddy Kalluru ethtool_link_ksettings_zero_link_mode(cmd, supported); 452054c67d1SSudarsana Reddy Kalluru QEDE_DRV_TO_ETHTOOL_CAPS(current_link.supported_caps, cmd, supported) 453054c67d1SSudarsana Reddy Kalluru 454054c67d1SSudarsana Reddy Kalluru ethtool_link_ksettings_zero_link_mode(cmd, advertising); 455054c67d1SSudarsana Reddy Kalluru QEDE_DRV_TO_ETHTOOL_CAPS(current_link.advertised_caps, cmd, advertising) 456054c67d1SSudarsana Reddy Kalluru 457054c67d1SSudarsana Reddy Kalluru ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising); 458054c67d1SSudarsana Reddy Kalluru QEDE_DRV_TO_ETHTOOL_CAPS(current_link.lp_caps, cmd, lp_advertising) 459054c67d1SSudarsana Reddy Kalluru 460133fac0eSSudarsana Kalluru if ((edev->state == QEDE_STATE_OPEN) && (current_link.link_up)) { 461054c67d1SSudarsana Reddy Kalluru base->speed = current_link.speed; 462054c67d1SSudarsana Reddy Kalluru base->duplex = current_link.duplex; 463133fac0eSSudarsana Kalluru } else { 464054c67d1SSudarsana Reddy Kalluru base->speed = SPEED_UNKNOWN; 465054c67d1SSudarsana Reddy Kalluru base->duplex = DUPLEX_UNKNOWN; 466133fac0eSSudarsana Kalluru } 467567b3c12SMintz, Yuval 468567b3c12SMintz, Yuval __qede_unlock(edev); 469567b3c12SMintz, Yuval 470054c67d1SSudarsana Reddy Kalluru base->port = current_link.port; 471054c67d1SSudarsana Reddy Kalluru base->autoneg = (current_link.autoneg) ? AUTONEG_ENABLE : 472133fac0eSSudarsana Kalluru AUTONEG_DISABLE; 473133fac0eSSudarsana Kalluru 474133fac0eSSudarsana Kalluru return 0; 475133fac0eSSudarsana Kalluru } 476133fac0eSSudarsana Kalluru 477054c67d1SSudarsana Reddy Kalluru static int qede_set_link_ksettings(struct net_device *dev, 478054c67d1SSudarsana Reddy Kalluru const struct ethtool_link_ksettings *cmd) 479133fac0eSSudarsana Kalluru { 480054c67d1SSudarsana Reddy Kalluru const struct ethtool_link_settings *base = &cmd->base; 481133fac0eSSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 482133fac0eSSudarsana Kalluru struct qed_link_output current_link; 483133fac0eSSudarsana Kalluru struct qed_link_params params; 484133fac0eSSudarsana Kalluru 485fe7cd2bfSYuval Mintz if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) { 486054c67d1SSudarsana Reddy Kalluru DP_INFO(edev, "Link settings are not allowed to be changed\n"); 487133fac0eSSudarsana Kalluru return -EOPNOTSUPP; 488133fac0eSSudarsana Kalluru } 489133fac0eSSudarsana Kalluru memset(¤t_link, 0, sizeof(current_link)); 490133fac0eSSudarsana Kalluru memset(¶ms, 0, sizeof(params)); 491133fac0eSSudarsana Kalluru edev->ops->common->get_link(edev->cdev, ¤t_link); 492133fac0eSSudarsana Kalluru 493133fac0eSSudarsana Kalluru params.override_flags |= QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS; 494133fac0eSSudarsana Kalluru params.override_flags |= QED_LINK_OVERRIDE_SPEED_AUTONEG; 495054c67d1SSudarsana Reddy Kalluru if (base->autoneg == AUTONEG_ENABLE) { 496161adb04Ssudarsana.kalluru@cavium.com if (!(current_link.supported_caps & QED_LM_Autoneg_BIT)) { 497161adb04Ssudarsana.kalluru@cavium.com DP_INFO(edev, "Auto negotiation is not supported\n"); 498161adb04Ssudarsana.kalluru@cavium.com return -EOPNOTSUPP; 499161adb04Ssudarsana.kalluru@cavium.com } 500161adb04Ssudarsana.kalluru@cavium.com 501133fac0eSSudarsana Kalluru params.autoneg = true; 502133fac0eSSudarsana Kalluru params.forced_speed = 0; 503054c67d1SSudarsana Reddy Kalluru QEDE_ETHTOOL_TO_DRV_CAPS(params.adv_speeds, cmd, advertising) 504133fac0eSSudarsana Kalluru } else { /* forced speed */ 505133fac0eSSudarsana Kalluru params.override_flags |= QED_LINK_OVERRIDE_SPEED_FORCED_SPEED; 506133fac0eSSudarsana Kalluru params.autoneg = false; 507054c67d1SSudarsana Reddy Kalluru params.forced_speed = base->speed; 508054c67d1SSudarsana Reddy Kalluru switch (base->speed) { 5099ac4c546SSudarsana Reddy Kalluru case SPEED_1000: 5109ac4c546SSudarsana Reddy Kalluru if (!(current_link.supported_caps & 5119ac4c546SSudarsana Reddy Kalluru QED_LM_1000baseT_Full_BIT)) { 5129ac4c546SSudarsana Reddy Kalluru DP_INFO(edev, "1G speed not supported\n"); 5139ac4c546SSudarsana Reddy Kalluru return -EINVAL; 5149ac4c546SSudarsana Reddy Kalluru } 5159ac4c546SSudarsana Reddy Kalluru params.adv_speeds = QED_LM_1000baseT_Full_BIT; 5169ac4c546SSudarsana Reddy Kalluru break; 517133fac0eSSudarsana Kalluru case SPEED_10000: 518133fac0eSSudarsana Kalluru if (!(current_link.supported_caps & 519054c67d1SSudarsana Reddy Kalluru QED_LM_10000baseKR_Full_BIT)) { 520133fac0eSSudarsana Kalluru DP_INFO(edev, "10G speed not supported\n"); 521133fac0eSSudarsana Kalluru return -EINVAL; 522133fac0eSSudarsana Kalluru } 523054c67d1SSudarsana Reddy Kalluru params.adv_speeds = QED_LM_10000baseKR_Full_BIT; 524054c67d1SSudarsana Reddy Kalluru break; 525054c67d1SSudarsana Reddy Kalluru case SPEED_25000: 526054c67d1SSudarsana Reddy Kalluru if (!(current_link.supported_caps & 527054c67d1SSudarsana Reddy Kalluru QED_LM_25000baseKR_Full_BIT)) { 528054c67d1SSudarsana Reddy Kalluru DP_INFO(edev, "25G speed not supported\n"); 529054c67d1SSudarsana Reddy Kalluru return -EINVAL; 530054c67d1SSudarsana Reddy Kalluru } 531054c67d1SSudarsana Reddy Kalluru params.adv_speeds = QED_LM_25000baseKR_Full_BIT; 532133fac0eSSudarsana Kalluru break; 533133fac0eSSudarsana Kalluru case SPEED_40000: 534133fac0eSSudarsana Kalluru if (!(current_link.supported_caps & 535054c67d1SSudarsana Reddy Kalluru QED_LM_40000baseLR4_Full_BIT)) { 536133fac0eSSudarsana Kalluru DP_INFO(edev, "40G speed not supported\n"); 537133fac0eSSudarsana Kalluru return -EINVAL; 538133fac0eSSudarsana Kalluru } 539054c67d1SSudarsana Reddy Kalluru params.adv_speeds = QED_LM_40000baseLR4_Full_BIT; 540054c67d1SSudarsana Reddy Kalluru break; 54116d5946aSYuval Mintz case SPEED_50000: 542054c67d1SSudarsana Reddy Kalluru if (!(current_link.supported_caps & 543054c67d1SSudarsana Reddy Kalluru QED_LM_50000baseKR2_Full_BIT)) { 544054c67d1SSudarsana Reddy Kalluru DP_INFO(edev, "50G speed not supported\n"); 545054c67d1SSudarsana Reddy Kalluru return -EINVAL; 546054c67d1SSudarsana Reddy Kalluru } 547054c67d1SSudarsana Reddy Kalluru params.adv_speeds = QED_LM_50000baseKR2_Full_BIT; 548054c67d1SSudarsana Reddy Kalluru break; 54916d5946aSYuval Mintz case SPEED_100000: 550054c67d1SSudarsana Reddy Kalluru if (!(current_link.supported_caps & 551054c67d1SSudarsana Reddy Kalluru QED_LM_100000baseKR4_Full_BIT)) { 552054c67d1SSudarsana Reddy Kalluru DP_INFO(edev, "100G speed not supported\n"); 553054c67d1SSudarsana Reddy Kalluru return -EINVAL; 554054c67d1SSudarsana Reddy Kalluru } 555054c67d1SSudarsana Reddy Kalluru params.adv_speeds = QED_LM_100000baseKR4_Full_BIT; 556133fac0eSSudarsana Kalluru break; 557133fac0eSSudarsana Kalluru default: 558054c67d1SSudarsana Reddy Kalluru DP_INFO(edev, "Unsupported speed %u\n", base->speed); 559133fac0eSSudarsana Kalluru return -EINVAL; 560133fac0eSSudarsana Kalluru } 561133fac0eSSudarsana Kalluru } 562133fac0eSSudarsana Kalluru 563133fac0eSSudarsana Kalluru params.link_up = true; 564133fac0eSSudarsana Kalluru edev->ops->common->set_link(edev->cdev, ¶ms); 565133fac0eSSudarsana Kalluru 566133fac0eSSudarsana Kalluru return 0; 567133fac0eSSudarsana Kalluru } 568133fac0eSSudarsana Kalluru 569133fac0eSSudarsana Kalluru static void qede_get_drvinfo(struct net_device *ndev, 570133fac0eSSudarsana Kalluru struct ethtool_drvinfo *info) 571133fac0eSSudarsana Kalluru { 572133fac0eSSudarsana Kalluru char mfw[ETHTOOL_FWVERS_LEN], storm[ETHTOOL_FWVERS_LEN]; 573133fac0eSSudarsana Kalluru struct qede_dev *edev = netdev_priv(ndev); 574133fac0eSSudarsana Kalluru 575133fac0eSSudarsana Kalluru strlcpy(info->driver, "qede", sizeof(info->driver)); 576133fac0eSSudarsana Kalluru strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); 577133fac0eSSudarsana Kalluru 578133fac0eSSudarsana Kalluru snprintf(storm, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d", 579133fac0eSSudarsana Kalluru edev->dev_info.common.fw_major, 580133fac0eSSudarsana Kalluru edev->dev_info.common.fw_minor, 581133fac0eSSudarsana Kalluru edev->dev_info.common.fw_rev, 582133fac0eSSudarsana Kalluru edev->dev_info.common.fw_eng); 583133fac0eSSudarsana Kalluru 584133fac0eSSudarsana Kalluru snprintf(mfw, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d", 585133fac0eSSudarsana Kalluru (edev->dev_info.common.mfw_rev >> 24) & 0xFF, 586133fac0eSSudarsana Kalluru (edev->dev_info.common.mfw_rev >> 16) & 0xFF, 587133fac0eSSudarsana Kalluru (edev->dev_info.common.mfw_rev >> 8) & 0xFF, 588133fac0eSSudarsana Kalluru edev->dev_info.common.mfw_rev & 0xFF); 589133fac0eSSudarsana Kalluru 590133fac0eSSudarsana Kalluru if ((strlen(storm) + strlen(mfw) + strlen("mfw storm ")) < 591133fac0eSSudarsana Kalluru sizeof(info->fw_version)) { 592133fac0eSSudarsana Kalluru snprintf(info->fw_version, sizeof(info->fw_version), 593133fac0eSSudarsana Kalluru "mfw %s storm %s", mfw, storm); 594133fac0eSSudarsana Kalluru } else { 595133fac0eSSudarsana Kalluru snprintf(info->fw_version, sizeof(info->fw_version), 596133fac0eSSudarsana Kalluru "%s %s", mfw, storm); 597133fac0eSSudarsana Kalluru } 598133fac0eSSudarsana Kalluru 599133fac0eSSudarsana Kalluru strlcpy(info->bus_info, pci_name(edev->pdev), sizeof(info->bus_info)); 600133fac0eSSudarsana Kalluru } 601133fac0eSSudarsana Kalluru 60214d39648SMintz, Yuval static void qede_get_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) 60314d39648SMintz, Yuval { 60414d39648SMintz, Yuval struct qede_dev *edev = netdev_priv(ndev); 60514d39648SMintz, Yuval 60614d39648SMintz, Yuval if (edev->dev_info.common.wol_support) { 60714d39648SMintz, Yuval wol->supported = WAKE_MAGIC; 60814d39648SMintz, Yuval wol->wolopts = edev->wol_enabled ? WAKE_MAGIC : 0; 60914d39648SMintz, Yuval } 61014d39648SMintz, Yuval } 61114d39648SMintz, Yuval 61214d39648SMintz, Yuval static int qede_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) 61314d39648SMintz, Yuval { 61414d39648SMintz, Yuval struct qede_dev *edev = netdev_priv(ndev); 61514d39648SMintz, Yuval bool wol_requested; 61614d39648SMintz, Yuval int rc; 61714d39648SMintz, Yuval 61814d39648SMintz, Yuval if (wol->wolopts & ~WAKE_MAGIC) { 61914d39648SMintz, Yuval DP_INFO(edev, 62014d39648SMintz, Yuval "Can't support WoL options other than magic-packet\n"); 62114d39648SMintz, Yuval return -EINVAL; 62214d39648SMintz, Yuval } 62314d39648SMintz, Yuval 62414d39648SMintz, Yuval wol_requested = !!(wol->wolopts & WAKE_MAGIC); 62514d39648SMintz, Yuval if (wol_requested == edev->wol_enabled) 62614d39648SMintz, Yuval return 0; 62714d39648SMintz, Yuval 62814d39648SMintz, Yuval /* Need to actually change configuration */ 62914d39648SMintz, Yuval if (!edev->dev_info.common.wol_support) { 63014d39648SMintz, Yuval DP_INFO(edev, "Device doesn't support WoL\n"); 63114d39648SMintz, Yuval return -EINVAL; 63214d39648SMintz, Yuval } 63314d39648SMintz, Yuval 63414d39648SMintz, Yuval rc = edev->ops->common->update_wol(edev->cdev, wol_requested); 63514d39648SMintz, Yuval if (!rc) 63614d39648SMintz, Yuval edev->wol_enabled = wol_requested; 63714d39648SMintz, Yuval 63814d39648SMintz, Yuval return rc; 63914d39648SMintz, Yuval } 64014d39648SMintz, Yuval 641133fac0eSSudarsana Kalluru static u32 qede_get_msglevel(struct net_device *ndev) 642133fac0eSSudarsana Kalluru { 643133fac0eSSudarsana Kalluru struct qede_dev *edev = netdev_priv(ndev); 644133fac0eSSudarsana Kalluru 6451a635e48SYuval Mintz return ((u32)edev->dp_level << QED_LOG_LEVEL_SHIFT) | edev->dp_module; 646133fac0eSSudarsana Kalluru } 647133fac0eSSudarsana Kalluru 648133fac0eSSudarsana Kalluru static void qede_set_msglevel(struct net_device *ndev, u32 level) 649133fac0eSSudarsana Kalluru { 650133fac0eSSudarsana Kalluru struct qede_dev *edev = netdev_priv(ndev); 651133fac0eSSudarsana Kalluru u32 dp_module = 0; 652133fac0eSSudarsana Kalluru u8 dp_level = 0; 653133fac0eSSudarsana Kalluru 654133fac0eSSudarsana Kalluru qede_config_debug(level, &dp_module, &dp_level); 655133fac0eSSudarsana Kalluru 656133fac0eSSudarsana Kalluru edev->dp_level = dp_level; 657133fac0eSSudarsana Kalluru edev->dp_module = dp_module; 658133fac0eSSudarsana Kalluru edev->ops->common->update_msglvl(edev->cdev, 659133fac0eSSudarsana Kalluru dp_module, dp_level); 660133fac0eSSudarsana Kalluru } 661133fac0eSSudarsana Kalluru 66232a7a570SSudarsana Kalluru static int qede_nway_reset(struct net_device *dev) 66332a7a570SSudarsana Kalluru { 66432a7a570SSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 66532a7a570SSudarsana Kalluru struct qed_link_output current_link; 66632a7a570SSudarsana Kalluru struct qed_link_params link_params; 66732a7a570SSudarsana Kalluru 668fe7cd2bfSYuval Mintz if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) { 6691a635e48SYuval Mintz DP_INFO(edev, "Link settings are not allowed to be changed\n"); 670fe7cd2bfSYuval Mintz return -EOPNOTSUPP; 671fe7cd2bfSYuval Mintz } 672fe7cd2bfSYuval Mintz 67332a7a570SSudarsana Kalluru if (!netif_running(dev)) 67432a7a570SSudarsana Kalluru return 0; 67532a7a570SSudarsana Kalluru 67632a7a570SSudarsana Kalluru memset(¤t_link, 0, sizeof(current_link)); 67732a7a570SSudarsana Kalluru edev->ops->common->get_link(edev->cdev, ¤t_link); 67832a7a570SSudarsana Kalluru if (!current_link.link_up) 67932a7a570SSudarsana Kalluru return 0; 68032a7a570SSudarsana Kalluru 68132a7a570SSudarsana Kalluru /* Toggle the link */ 68232a7a570SSudarsana Kalluru memset(&link_params, 0, sizeof(link_params)); 68332a7a570SSudarsana Kalluru link_params.link_up = false; 68432a7a570SSudarsana Kalluru edev->ops->common->set_link(edev->cdev, &link_params); 68532a7a570SSudarsana Kalluru link_params.link_up = true; 68632a7a570SSudarsana Kalluru edev->ops->common->set_link(edev->cdev, &link_params); 68732a7a570SSudarsana Kalluru 68832a7a570SSudarsana Kalluru return 0; 68932a7a570SSudarsana Kalluru } 69032a7a570SSudarsana Kalluru 691133fac0eSSudarsana Kalluru static u32 qede_get_link(struct net_device *dev) 692133fac0eSSudarsana Kalluru { 693133fac0eSSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 694133fac0eSSudarsana Kalluru struct qed_link_output current_link; 695133fac0eSSudarsana Kalluru 696133fac0eSSudarsana Kalluru memset(¤t_link, 0, sizeof(current_link)); 697133fac0eSSudarsana Kalluru edev->ops->common->get_link(edev->cdev, ¤t_link); 698133fac0eSSudarsana Kalluru 699133fac0eSSudarsana Kalluru return current_link.link_up; 700133fac0eSSudarsana Kalluru } 701133fac0eSSudarsana Kalluru 702d552fa84SSudarsana Reddy Kalluru static int qede_get_coalesce(struct net_device *dev, 703d552fa84SSudarsana Reddy Kalluru struct ethtool_coalesce *coal) 704d552fa84SSudarsana Reddy Kalluru { 705d552fa84SSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 706d2890deaSSudarsana Reddy Kalluru u16 rxc, txc; 707d552fa84SSudarsana Reddy Kalluru 708d552fa84SSudarsana Reddy Kalluru memset(coal, 0, sizeof(struct ethtool_coalesce)); 709d2890deaSSudarsana Reddy Kalluru edev->ops->common->get_coalesce(edev->cdev, &rxc, &txc); 710d2890deaSSudarsana Reddy Kalluru 711d2890deaSSudarsana Reddy Kalluru coal->rx_coalesce_usecs = rxc; 712d2890deaSSudarsana Reddy Kalluru coal->tx_coalesce_usecs = txc; 713d552fa84SSudarsana Reddy Kalluru 714d552fa84SSudarsana Reddy Kalluru return 0; 715d552fa84SSudarsana Reddy Kalluru } 716d552fa84SSudarsana Reddy Kalluru 717d552fa84SSudarsana Reddy Kalluru static int qede_set_coalesce(struct net_device *dev, 718d552fa84SSudarsana Reddy Kalluru struct ethtool_coalesce *coal) 719d552fa84SSudarsana Reddy Kalluru { 720d552fa84SSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 721477f2d14SRahul Verma struct qede_fastpath *fp; 722d552fa84SSudarsana Reddy Kalluru int i, rc = 0; 723477f2d14SRahul Verma u16 rxc, txc; 724d552fa84SSudarsana Reddy Kalluru 725d552fa84SSudarsana Reddy Kalluru if (!netif_running(dev)) { 726d552fa84SSudarsana Reddy Kalluru DP_INFO(edev, "Interface is down\n"); 727d552fa84SSudarsana Reddy Kalluru return -EINVAL; 728d552fa84SSudarsana Reddy Kalluru } 729d552fa84SSudarsana Reddy Kalluru 730d552fa84SSudarsana Reddy Kalluru if (coal->rx_coalesce_usecs > QED_COALESCE_MAX || 731d552fa84SSudarsana Reddy Kalluru coal->tx_coalesce_usecs > QED_COALESCE_MAX) { 732d552fa84SSudarsana Reddy Kalluru DP_INFO(edev, 733d552fa84SSudarsana Reddy Kalluru "Can't support requested %s coalesce value [max supported value %d]\n", 734477f2d14SRahul Verma coal->rx_coalesce_usecs > QED_COALESCE_MAX ? "rx" : 735477f2d14SRahul Verma "tx", QED_COALESCE_MAX); 736d552fa84SSudarsana Reddy Kalluru return -EINVAL; 737d552fa84SSudarsana Reddy Kalluru } 738d552fa84SSudarsana Reddy Kalluru 739d552fa84SSudarsana Reddy Kalluru rxc = (u16)coal->rx_coalesce_usecs; 740d552fa84SSudarsana Reddy Kalluru txc = (u16)coal->tx_coalesce_usecs; 7419a4d7e86SSudarsana Reddy Kalluru for_each_queue(i) { 742477f2d14SRahul Verma fp = &edev->fp_array[i]; 743477f2d14SRahul Verma 744477f2d14SRahul Verma if (edev->fp_array[i].type & QEDE_FASTPATH_RX) { 745477f2d14SRahul Verma rc = edev->ops->common->set_coalesce(edev->cdev, 746477f2d14SRahul Verma rxc, 0, 747477f2d14SRahul Verma fp->rxq->handle); 748d552fa84SSudarsana Reddy Kalluru if (rc) { 749477f2d14SRahul Verma DP_INFO(edev, 750477f2d14SRahul Verma "Set RX coalesce error, rc = %d\n", rc); 751d552fa84SSudarsana Reddy Kalluru return rc; 752d552fa84SSudarsana Reddy Kalluru } 753d552fa84SSudarsana Reddy Kalluru } 754d552fa84SSudarsana Reddy Kalluru 755477f2d14SRahul Verma if (edev->fp_array[i].type & QEDE_FASTPATH_TX) { 756477f2d14SRahul Verma rc = edev->ops->common->set_coalesce(edev->cdev, 757477f2d14SRahul Verma 0, txc, 758477f2d14SRahul Verma fp->txq->handle); 759477f2d14SRahul Verma if (rc) { 760477f2d14SRahul Verma DP_INFO(edev, 761477f2d14SRahul Verma "Set TX coalesce error, rc = %d\n", rc); 762477f2d14SRahul Verma return rc; 763477f2d14SRahul Verma } 764477f2d14SRahul Verma } 765477f2d14SRahul Verma } 766477f2d14SRahul Verma 767d552fa84SSudarsana Reddy Kalluru return rc; 768d552fa84SSudarsana Reddy Kalluru } 769d552fa84SSudarsana Reddy Kalluru 77001ef7e05SSudarsana Kalluru static void qede_get_ringparam(struct net_device *dev, 77101ef7e05SSudarsana Kalluru struct ethtool_ringparam *ering) 77201ef7e05SSudarsana Kalluru { 77301ef7e05SSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 77401ef7e05SSudarsana Kalluru 77501ef7e05SSudarsana Kalluru ering->rx_max_pending = NUM_RX_BDS_MAX; 77601ef7e05SSudarsana Kalluru ering->rx_pending = edev->q_num_rx_buffers; 77701ef7e05SSudarsana Kalluru ering->tx_max_pending = NUM_TX_BDS_MAX; 77801ef7e05SSudarsana Kalluru ering->tx_pending = edev->q_num_tx_buffers; 77901ef7e05SSudarsana Kalluru } 78001ef7e05SSudarsana Kalluru 78101ef7e05SSudarsana Kalluru static int qede_set_ringparam(struct net_device *dev, 78201ef7e05SSudarsana Kalluru struct ethtool_ringparam *ering) 78301ef7e05SSudarsana Kalluru { 78401ef7e05SSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 78501ef7e05SSudarsana Kalluru 78601ef7e05SSudarsana Kalluru DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), 78701ef7e05SSudarsana Kalluru "Set ring params command parameters: rx_pending = %d, tx_pending = %d\n", 78801ef7e05SSudarsana Kalluru ering->rx_pending, ering->tx_pending); 78901ef7e05SSudarsana Kalluru 79001ef7e05SSudarsana Kalluru /* Validate legality of configuration */ 79101ef7e05SSudarsana Kalluru if (ering->rx_pending > NUM_RX_BDS_MAX || 79201ef7e05SSudarsana Kalluru ering->rx_pending < NUM_RX_BDS_MIN || 79301ef7e05SSudarsana Kalluru ering->tx_pending > NUM_TX_BDS_MAX || 79401ef7e05SSudarsana Kalluru ering->tx_pending < NUM_TX_BDS_MIN) { 79501ef7e05SSudarsana Kalluru DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), 79601ef7e05SSudarsana Kalluru "Can only support Rx Buffer size [0%08x,...,0x%08x] and Tx Buffer size [0x%08x,...,0x%08x]\n", 79701ef7e05SSudarsana Kalluru NUM_RX_BDS_MIN, NUM_RX_BDS_MAX, 79801ef7e05SSudarsana Kalluru NUM_TX_BDS_MIN, NUM_TX_BDS_MAX); 79901ef7e05SSudarsana Kalluru return -EINVAL; 80001ef7e05SSudarsana Kalluru } 80101ef7e05SSudarsana Kalluru 80201ef7e05SSudarsana Kalluru /* Change ring size and re-load */ 80301ef7e05SSudarsana Kalluru edev->q_num_rx_buffers = ering->rx_pending; 80401ef7e05SSudarsana Kalluru edev->q_num_tx_buffers = ering->tx_pending; 80501ef7e05SSudarsana Kalluru 806567b3c12SMintz, Yuval qede_reload(edev, NULL, false); 80701ef7e05SSudarsana Kalluru 80801ef7e05SSudarsana Kalluru return 0; 80901ef7e05SSudarsana Kalluru } 81001ef7e05SSudarsana Kalluru 8110f7db144SSudarsana Kalluru static void qede_get_pauseparam(struct net_device *dev, 8120f7db144SSudarsana Kalluru struct ethtool_pauseparam *epause) 8130f7db144SSudarsana Kalluru { 8140f7db144SSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 8150f7db144SSudarsana Kalluru struct qed_link_output current_link; 8160f7db144SSudarsana Kalluru 8170f7db144SSudarsana Kalluru memset(¤t_link, 0, sizeof(current_link)); 8180f7db144SSudarsana Kalluru edev->ops->common->get_link(edev->cdev, ¤t_link); 8190f7db144SSudarsana Kalluru 8200f7db144SSudarsana Kalluru if (current_link.pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE) 8210f7db144SSudarsana Kalluru epause->autoneg = true; 8220f7db144SSudarsana Kalluru if (current_link.pause_config & QED_LINK_PAUSE_RX_ENABLE) 8230f7db144SSudarsana Kalluru epause->rx_pause = true; 8240f7db144SSudarsana Kalluru if (current_link.pause_config & QED_LINK_PAUSE_TX_ENABLE) 8250f7db144SSudarsana Kalluru epause->tx_pause = true; 8260f7db144SSudarsana Kalluru 8270f7db144SSudarsana Kalluru DP_VERBOSE(edev, QED_MSG_DEBUG, 8280f7db144SSudarsana Kalluru "ethtool_pauseparam: cmd %d autoneg %d rx_pause %d tx_pause %d\n", 8290f7db144SSudarsana Kalluru epause->cmd, epause->autoneg, epause->rx_pause, 8300f7db144SSudarsana Kalluru epause->tx_pause); 8310f7db144SSudarsana Kalluru } 8320f7db144SSudarsana Kalluru 8330f7db144SSudarsana Kalluru static int qede_set_pauseparam(struct net_device *dev, 8340f7db144SSudarsana Kalluru struct ethtool_pauseparam *epause) 8350f7db144SSudarsana Kalluru { 8360f7db144SSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 8370f7db144SSudarsana Kalluru struct qed_link_params params; 8380f7db144SSudarsana Kalluru struct qed_link_output current_link; 8390f7db144SSudarsana Kalluru 840fe7cd2bfSYuval Mintz if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) { 8410f7db144SSudarsana Kalluru DP_INFO(edev, 842fe7cd2bfSYuval Mintz "Pause settings are not allowed to be changed\n"); 8430f7db144SSudarsana Kalluru return -EOPNOTSUPP; 8440f7db144SSudarsana Kalluru } 8450f7db144SSudarsana Kalluru 8460f7db144SSudarsana Kalluru memset(¤t_link, 0, sizeof(current_link)); 8470f7db144SSudarsana Kalluru edev->ops->common->get_link(edev->cdev, ¤t_link); 8480f7db144SSudarsana Kalluru 8490f7db144SSudarsana Kalluru memset(¶ms, 0, sizeof(params)); 8500f7db144SSudarsana Kalluru params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG; 8510f7db144SSudarsana Kalluru if (epause->autoneg) { 852d194fd26SYuval Mintz if (!(current_link.supported_caps & QED_LM_Autoneg_BIT)) { 8530f7db144SSudarsana Kalluru DP_INFO(edev, "autoneg not supported\n"); 8540f7db144SSudarsana Kalluru return -EINVAL; 8550f7db144SSudarsana Kalluru } 8560f7db144SSudarsana Kalluru params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE; 8570f7db144SSudarsana Kalluru } 8580f7db144SSudarsana Kalluru if (epause->rx_pause) 8590f7db144SSudarsana Kalluru params.pause_config |= QED_LINK_PAUSE_RX_ENABLE; 8600f7db144SSudarsana Kalluru if (epause->tx_pause) 8610f7db144SSudarsana Kalluru params.pause_config |= QED_LINK_PAUSE_TX_ENABLE; 8620f7db144SSudarsana Kalluru 8630f7db144SSudarsana Kalluru params.link_up = true; 8640f7db144SSudarsana Kalluru edev->ops->common->set_link(edev->cdev, ¶ms); 8650f7db144SSudarsana Kalluru 8660f7db144SSudarsana Kalluru return 0; 8670f7db144SSudarsana Kalluru } 8680f7db144SSudarsana Kalluru 869e0971c83STomer Tayar static void qede_get_regs(struct net_device *ndev, 870e0971c83STomer Tayar struct ethtool_regs *regs, void *buffer) 871e0971c83STomer Tayar { 872e0971c83STomer Tayar struct qede_dev *edev = netdev_priv(ndev); 873e0971c83STomer Tayar 874e0971c83STomer Tayar regs->version = 0; 875e0971c83STomer Tayar memset(buffer, 0, regs->len); 876e0971c83STomer Tayar 877e0971c83STomer Tayar if (edev->ops && edev->ops->common) 878e0971c83STomer Tayar edev->ops->common->dbg_all_data(edev->cdev, buffer); 879e0971c83STomer Tayar } 880e0971c83STomer Tayar 881e0971c83STomer Tayar static int qede_get_regs_len(struct net_device *ndev) 882e0971c83STomer Tayar { 883e0971c83STomer Tayar struct qede_dev *edev = netdev_priv(ndev); 884e0971c83STomer Tayar 885e0971c83STomer Tayar if (edev->ops && edev->ops->common) 886e0971c83STomer Tayar return edev->ops->common->dbg_all_data_size(edev->cdev); 887e0971c83STomer Tayar else 888e0971c83STomer Tayar return -EINVAL; 889e0971c83STomer Tayar } 890e0971c83STomer Tayar 891567b3c12SMintz, Yuval static void qede_update_mtu(struct qede_dev *edev, 892567b3c12SMintz, Yuval struct qede_reload_args *args) 893133fac0eSSudarsana Kalluru { 894567b3c12SMintz, Yuval edev->ndev->mtu = args->u.mtu; 895133fac0eSSudarsana Kalluru } 896133fac0eSSudarsana Kalluru 897133fac0eSSudarsana Kalluru /* Netdevice NDOs */ 898133fac0eSSudarsana Kalluru int qede_change_mtu(struct net_device *ndev, int new_mtu) 899133fac0eSSudarsana Kalluru { 900133fac0eSSudarsana Kalluru struct qede_dev *edev = netdev_priv(ndev); 901567b3c12SMintz, Yuval struct qede_reload_args args; 902133fac0eSSudarsana Kalluru 903133fac0eSSudarsana Kalluru DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), 904133fac0eSSudarsana Kalluru "Configuring MTU size of %d\n", new_mtu); 905133fac0eSSudarsana Kalluru 906133fac0eSSudarsana Kalluru /* Set the mtu field and re-start the interface if needed */ 907567b3c12SMintz, Yuval args.u.mtu = new_mtu; 908567b3c12SMintz, Yuval args.func = &qede_update_mtu; 909567b3c12SMintz, Yuval qede_reload(edev, &args, false); 910133fac0eSSudarsana Kalluru 911567b3c12SMintz, Yuval edev->ops->common->update_mtu(edev->cdev, new_mtu); 9120fefbfbaSSudarsana Kalluru 913133fac0eSSudarsana Kalluru return 0; 914133fac0eSSudarsana Kalluru } 915133fac0eSSudarsana Kalluru 9168edf049dSSudarsana Kalluru static void qede_get_channels(struct net_device *dev, 9178edf049dSSudarsana Kalluru struct ethtool_channels *channels) 9188edf049dSSudarsana Kalluru { 9198edf049dSSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 9208edf049dSSudarsana Kalluru 9218edf049dSSudarsana Kalluru channels->max_combined = QEDE_MAX_RSS_CNT(edev); 922bdc8cbd3SSudarsana Reddy Kalluru channels->max_rx = QEDE_MAX_RSS_CNT(edev); 923bdc8cbd3SSudarsana Reddy Kalluru channels->max_tx = QEDE_MAX_RSS_CNT(edev); 9249a4d7e86SSudarsana Reddy Kalluru channels->combined_count = QEDE_QUEUE_CNT(edev) - edev->fp_num_tx - 9259a4d7e86SSudarsana Reddy Kalluru edev->fp_num_rx; 9269a4d7e86SSudarsana Reddy Kalluru channels->tx_count = edev->fp_num_tx; 9279a4d7e86SSudarsana Reddy Kalluru channels->rx_count = edev->fp_num_rx; 9288edf049dSSudarsana Kalluru } 9298edf049dSSudarsana Kalluru 9308edf049dSSudarsana Kalluru static int qede_set_channels(struct net_device *dev, 9318edf049dSSudarsana Kalluru struct ethtool_channels *channels) 9328edf049dSSudarsana Kalluru { 9338edf049dSSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 9349a4d7e86SSudarsana Reddy Kalluru u32 count; 9358edf049dSSudarsana Kalluru 9368edf049dSSudarsana Kalluru DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), 9378edf049dSSudarsana Kalluru "set-channels command parameters: rx = %d, tx = %d, other = %d, combined = %d\n", 9388edf049dSSudarsana Kalluru channels->rx_count, channels->tx_count, 9398edf049dSSudarsana Kalluru channels->other_count, channels->combined_count); 9408edf049dSSudarsana Kalluru 9419a4d7e86SSudarsana Reddy Kalluru count = channels->rx_count + channels->tx_count + 9429a4d7e86SSudarsana Reddy Kalluru channels->combined_count; 9439a4d7e86SSudarsana Reddy Kalluru 9449a4d7e86SSudarsana Reddy Kalluru /* We don't support `other' channels */ 9459a4d7e86SSudarsana Reddy Kalluru if (channels->other_count) { 9468edf049dSSudarsana Kalluru DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), 9478edf049dSSudarsana Kalluru "command parameters not supported\n"); 9488edf049dSSudarsana Kalluru return -EINVAL; 9498edf049dSSudarsana Kalluru } 9508edf049dSSudarsana Kalluru 9519a4d7e86SSudarsana Reddy Kalluru if (!(channels->combined_count || (channels->rx_count && 9529a4d7e86SSudarsana Reddy Kalluru channels->tx_count))) { 9539a4d7e86SSudarsana Reddy Kalluru DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), 9549a4d7e86SSudarsana Reddy Kalluru "need to request at least one transmit and one receive channel\n"); 9559a4d7e86SSudarsana Reddy Kalluru return -EINVAL; 9569a4d7e86SSudarsana Reddy Kalluru } 9579a4d7e86SSudarsana Reddy Kalluru 9589a4d7e86SSudarsana Reddy Kalluru if (count > QEDE_MAX_RSS_CNT(edev)) { 9599a4d7e86SSudarsana Reddy Kalluru DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), 9609a4d7e86SSudarsana Reddy Kalluru "requested channels = %d max supported channels = %d\n", 9619a4d7e86SSudarsana Reddy Kalluru count, QEDE_MAX_RSS_CNT(edev)); 9629a4d7e86SSudarsana Reddy Kalluru return -EINVAL; 9639a4d7e86SSudarsana Reddy Kalluru } 9649a4d7e86SSudarsana Reddy Kalluru 9658edf049dSSudarsana Kalluru /* Check if there was a change in the active parameters */ 9669a4d7e86SSudarsana Reddy Kalluru if ((count == QEDE_QUEUE_CNT(edev)) && 9679a4d7e86SSudarsana Reddy Kalluru (channels->tx_count == edev->fp_num_tx) && 9689a4d7e86SSudarsana Reddy Kalluru (channels->rx_count == edev->fp_num_rx)) { 9698edf049dSSudarsana Kalluru DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), 9708edf049dSSudarsana Kalluru "No change in active parameters\n"); 9718edf049dSSudarsana Kalluru return 0; 9728edf049dSSudarsana Kalluru } 9738edf049dSSudarsana Kalluru 9748edf049dSSudarsana Kalluru /* We need the number of queues to be divisible between the hwfns */ 9759a4d7e86SSudarsana Reddy Kalluru if ((count % edev->dev_info.common.num_hwfns) || 9769a4d7e86SSudarsana Reddy Kalluru (channels->tx_count % edev->dev_info.common.num_hwfns) || 9779a4d7e86SSudarsana Reddy Kalluru (channels->rx_count % edev->dev_info.common.num_hwfns)) { 9788edf049dSSudarsana Kalluru DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), 9799a4d7e86SSudarsana Reddy Kalluru "Number of channels must be divisible by %04x\n", 9808edf049dSSudarsana Kalluru edev->dev_info.common.num_hwfns); 9818edf049dSSudarsana Kalluru return -EINVAL; 9828edf049dSSudarsana Kalluru } 9838edf049dSSudarsana Kalluru 9848edf049dSSudarsana Kalluru /* Set number of queues and reload if necessary */ 9859a4d7e86SSudarsana Reddy Kalluru edev->req_queues = count; 9869a4d7e86SSudarsana Reddy Kalluru edev->req_num_tx = channels->tx_count; 9879a4d7e86SSudarsana Reddy Kalluru edev->req_num_rx = channels->rx_count; 988ed0dd915SSudarsana Reddy Kalluru /* Reset the indirection table if rx queue count is updated */ 989ed0dd915SSudarsana Reddy Kalluru if ((edev->req_queues - edev->req_num_tx) != QEDE_RSS_COUNT(edev)) { 990ed0dd915SSudarsana Reddy Kalluru edev->rss_params_inited &= ~QEDE_RSS_INDIR_INITED; 991f29ffdb6SMintz, Yuval memset(edev->rss_ind_table, 0, sizeof(edev->rss_ind_table)); 992ed0dd915SSudarsana Reddy Kalluru } 993ed0dd915SSudarsana Reddy Kalluru 994567b3c12SMintz, Yuval qede_reload(edev, NULL, false); 9958edf049dSSudarsana Kalluru 9968edf049dSSudarsana Kalluru return 0; 9978edf049dSSudarsana Kalluru } 9988edf049dSSudarsana Kalluru 9994c55215cSSudarsana Reddy Kalluru static int qede_get_ts_info(struct net_device *dev, 10004c55215cSSudarsana Reddy Kalluru struct ethtool_ts_info *info) 10014c55215cSSudarsana Reddy Kalluru { 10024c55215cSSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 10034c55215cSSudarsana Reddy Kalluru 10044c55215cSSudarsana Reddy Kalluru return qede_ptp_get_ts_info(edev, info); 10054c55215cSSudarsana Reddy Kalluru } 10064c55215cSSudarsana Reddy Kalluru 10073d971cbdSSudarsana Kalluru static int qede_set_phys_id(struct net_device *dev, 10083d971cbdSSudarsana Kalluru enum ethtool_phys_id_state state) 10093d971cbdSSudarsana Kalluru { 10103d971cbdSSudarsana Kalluru struct qede_dev *edev = netdev_priv(dev); 10113d971cbdSSudarsana Kalluru u8 led_state = 0; 10123d971cbdSSudarsana Kalluru 10133d971cbdSSudarsana Kalluru switch (state) { 10143d971cbdSSudarsana Kalluru case ETHTOOL_ID_ACTIVE: 10153d971cbdSSudarsana Kalluru return 1; /* cycle on/off once per second */ 10163d971cbdSSudarsana Kalluru 10173d971cbdSSudarsana Kalluru case ETHTOOL_ID_ON: 10183d971cbdSSudarsana Kalluru led_state = QED_LED_MODE_ON; 10193d971cbdSSudarsana Kalluru break; 10203d971cbdSSudarsana Kalluru 10213d971cbdSSudarsana Kalluru case ETHTOOL_ID_OFF: 10223d971cbdSSudarsana Kalluru led_state = QED_LED_MODE_OFF; 10233d971cbdSSudarsana Kalluru break; 10243d971cbdSSudarsana Kalluru 10253d971cbdSSudarsana Kalluru case ETHTOOL_ID_INACTIVE: 10263d971cbdSSudarsana Kalluru led_state = QED_LED_MODE_RESTORE; 10273d971cbdSSudarsana Kalluru break; 10283d971cbdSSudarsana Kalluru } 10293d971cbdSSudarsana Kalluru 10303d971cbdSSudarsana Kalluru edev->ops->common->set_led(edev->cdev, led_state); 10313d971cbdSSudarsana Kalluru 10323d971cbdSSudarsana Kalluru return 0; 10333d971cbdSSudarsana Kalluru } 10343d971cbdSSudarsana Kalluru 1035961acdeaSSudarsana Reddy Kalluru static int qede_get_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info) 1036961acdeaSSudarsana Reddy Kalluru { 1037961acdeaSSudarsana Reddy Kalluru info->data = RXH_IP_SRC | RXH_IP_DST; 1038961acdeaSSudarsana Reddy Kalluru 1039961acdeaSSudarsana Reddy Kalluru switch (info->flow_type) { 1040961acdeaSSudarsana Reddy Kalluru case TCP_V4_FLOW: 1041961acdeaSSudarsana Reddy Kalluru case TCP_V6_FLOW: 1042961acdeaSSudarsana Reddy Kalluru info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 1043961acdeaSSudarsana Reddy Kalluru break; 1044961acdeaSSudarsana Reddy Kalluru case UDP_V4_FLOW: 1045f29ffdb6SMintz, Yuval if (edev->rss_caps & QED_RSS_IPV4_UDP) 1046961acdeaSSudarsana Reddy Kalluru info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 1047961acdeaSSudarsana Reddy Kalluru break; 1048961acdeaSSudarsana Reddy Kalluru case UDP_V6_FLOW: 1049f29ffdb6SMintz, Yuval if (edev->rss_caps & QED_RSS_IPV6_UDP) 1050961acdeaSSudarsana Reddy Kalluru info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 1051961acdeaSSudarsana Reddy Kalluru break; 1052961acdeaSSudarsana Reddy Kalluru case IPV4_FLOW: 1053961acdeaSSudarsana Reddy Kalluru case IPV6_FLOW: 1054961acdeaSSudarsana Reddy Kalluru break; 1055961acdeaSSudarsana Reddy Kalluru default: 1056961acdeaSSudarsana Reddy Kalluru info->data = 0; 1057961acdeaSSudarsana Reddy Kalluru break; 1058961acdeaSSudarsana Reddy Kalluru } 1059961acdeaSSudarsana Reddy Kalluru 1060961acdeaSSudarsana Reddy Kalluru return 0; 1061961acdeaSSudarsana Reddy Kalluru } 1062961acdeaSSudarsana Reddy Kalluru 1063961acdeaSSudarsana Reddy Kalluru static int qede_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info, 1064ec9b8dbdSChopra, Manish u32 *rule_locs) 1065961acdeaSSudarsana Reddy Kalluru { 1066961acdeaSSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 1067ec9b8dbdSChopra, Manish int rc = 0; 1068961acdeaSSudarsana Reddy Kalluru 1069961acdeaSSudarsana Reddy Kalluru switch (info->cmd) { 1070961acdeaSSudarsana Reddy Kalluru case ETHTOOL_GRXRINGS: 10719a4d7e86SSudarsana Reddy Kalluru info->data = QEDE_RSS_COUNT(edev); 1072ec9b8dbdSChopra, Manish break; 1073961acdeaSSudarsana Reddy Kalluru case ETHTOOL_GRXFH: 1074ec9b8dbdSChopra, Manish rc = qede_get_rss_flags(edev, info); 1075ec9b8dbdSChopra, Manish break; 1076ec9b8dbdSChopra, Manish case ETHTOOL_GRXCLSRLCNT: 1077ec9b8dbdSChopra, Manish info->rule_cnt = qede_get_arfs_filter_count(edev); 1078ec9b8dbdSChopra, Manish info->data = QEDE_RFS_MAX_FLTR; 1079ec9b8dbdSChopra, Manish break; 1080ec9b8dbdSChopra, Manish case ETHTOOL_GRXCLSRULE: 1081ec9b8dbdSChopra, Manish rc = qede_get_cls_rule_entry(edev, info); 1082ec9b8dbdSChopra, Manish break; 1083ec9b8dbdSChopra, Manish case ETHTOOL_GRXCLSRLALL: 1084ec9b8dbdSChopra, Manish rc = qede_get_cls_rule_all(edev, info, rule_locs); 1085ec9b8dbdSChopra, Manish break; 1086961acdeaSSudarsana Reddy Kalluru default: 1087961acdeaSSudarsana Reddy Kalluru DP_ERR(edev, "Command parameters not supported\n"); 1088ec9b8dbdSChopra, Manish rc = -EOPNOTSUPP; 1089961acdeaSSudarsana Reddy Kalluru } 1090ec9b8dbdSChopra, Manish 1091ec9b8dbdSChopra, Manish return rc; 1092961acdeaSSudarsana Reddy Kalluru } 1093961acdeaSSudarsana Reddy Kalluru 1094961acdeaSSudarsana Reddy Kalluru static int qede_set_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info) 1095961acdeaSSudarsana Reddy Kalluru { 1096f29ffdb6SMintz, Yuval struct qed_update_vport_params *vport_update_params; 1097961acdeaSSudarsana Reddy Kalluru u8 set_caps = 0, clr_caps = 0; 1098f29ffdb6SMintz, Yuval int rc = 0; 1099961acdeaSSudarsana Reddy Kalluru 1100961acdeaSSudarsana Reddy Kalluru DP_VERBOSE(edev, QED_MSG_DEBUG, 1101961acdeaSSudarsana Reddy Kalluru "Set rss flags command parameters: flow type = %d, data = %llu\n", 1102961acdeaSSudarsana Reddy Kalluru info->flow_type, info->data); 1103961acdeaSSudarsana Reddy Kalluru 1104961acdeaSSudarsana Reddy Kalluru switch (info->flow_type) { 1105961acdeaSSudarsana Reddy Kalluru case TCP_V4_FLOW: 1106961acdeaSSudarsana Reddy Kalluru case TCP_V6_FLOW: 1107961acdeaSSudarsana Reddy Kalluru /* For TCP only 4-tuple hash is supported */ 1108961acdeaSSudarsana Reddy Kalluru if (info->data ^ (RXH_IP_SRC | RXH_IP_DST | 1109961acdeaSSudarsana Reddy Kalluru RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 1110961acdeaSSudarsana Reddy Kalluru DP_INFO(edev, "Command parameters not supported\n"); 1111961acdeaSSudarsana Reddy Kalluru return -EINVAL; 1112961acdeaSSudarsana Reddy Kalluru } 1113961acdeaSSudarsana Reddy Kalluru return 0; 1114961acdeaSSudarsana Reddy Kalluru case UDP_V4_FLOW: 1115961acdeaSSudarsana Reddy Kalluru /* For UDP either 2-tuple hash or 4-tuple hash is supported */ 1116961acdeaSSudarsana Reddy Kalluru if (info->data == (RXH_IP_SRC | RXH_IP_DST | 1117961acdeaSSudarsana Reddy Kalluru RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 1118961acdeaSSudarsana Reddy Kalluru set_caps = QED_RSS_IPV4_UDP; 1119961acdeaSSudarsana Reddy Kalluru DP_VERBOSE(edev, QED_MSG_DEBUG, 1120961acdeaSSudarsana Reddy Kalluru "UDP 4-tuple enabled\n"); 1121961acdeaSSudarsana Reddy Kalluru } else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) { 1122961acdeaSSudarsana Reddy Kalluru clr_caps = QED_RSS_IPV4_UDP; 1123961acdeaSSudarsana Reddy Kalluru DP_VERBOSE(edev, QED_MSG_DEBUG, 1124961acdeaSSudarsana Reddy Kalluru "UDP 4-tuple disabled\n"); 1125961acdeaSSudarsana Reddy Kalluru } else { 1126961acdeaSSudarsana Reddy Kalluru return -EINVAL; 1127961acdeaSSudarsana Reddy Kalluru } 1128961acdeaSSudarsana Reddy Kalluru break; 1129961acdeaSSudarsana Reddy Kalluru case UDP_V6_FLOW: 1130961acdeaSSudarsana Reddy Kalluru /* For UDP either 2-tuple hash or 4-tuple hash is supported */ 1131961acdeaSSudarsana Reddy Kalluru if (info->data == (RXH_IP_SRC | RXH_IP_DST | 1132961acdeaSSudarsana Reddy Kalluru RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 1133961acdeaSSudarsana Reddy Kalluru set_caps = QED_RSS_IPV6_UDP; 1134961acdeaSSudarsana Reddy Kalluru DP_VERBOSE(edev, QED_MSG_DEBUG, 1135961acdeaSSudarsana Reddy Kalluru "UDP 4-tuple enabled\n"); 1136961acdeaSSudarsana Reddy Kalluru } else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) { 1137961acdeaSSudarsana Reddy Kalluru clr_caps = QED_RSS_IPV6_UDP; 1138961acdeaSSudarsana Reddy Kalluru DP_VERBOSE(edev, QED_MSG_DEBUG, 1139961acdeaSSudarsana Reddy Kalluru "UDP 4-tuple disabled\n"); 1140961acdeaSSudarsana Reddy Kalluru } else { 1141961acdeaSSudarsana Reddy Kalluru return -EINVAL; 1142961acdeaSSudarsana Reddy Kalluru } 1143961acdeaSSudarsana Reddy Kalluru break; 1144961acdeaSSudarsana Reddy Kalluru case IPV4_FLOW: 1145961acdeaSSudarsana Reddy Kalluru case IPV6_FLOW: 1146961acdeaSSudarsana Reddy Kalluru /* For IP only 2-tuple hash is supported */ 1147961acdeaSSudarsana Reddy Kalluru if (info->data ^ (RXH_IP_SRC | RXH_IP_DST)) { 1148961acdeaSSudarsana Reddy Kalluru DP_INFO(edev, "Command parameters not supported\n"); 1149961acdeaSSudarsana Reddy Kalluru return -EINVAL; 1150961acdeaSSudarsana Reddy Kalluru } 1151961acdeaSSudarsana Reddy Kalluru return 0; 1152961acdeaSSudarsana Reddy Kalluru case SCTP_V4_FLOW: 1153961acdeaSSudarsana Reddy Kalluru case AH_ESP_V4_FLOW: 1154961acdeaSSudarsana Reddy Kalluru case AH_V4_FLOW: 1155961acdeaSSudarsana Reddy Kalluru case ESP_V4_FLOW: 1156961acdeaSSudarsana Reddy Kalluru case SCTP_V6_FLOW: 1157961acdeaSSudarsana Reddy Kalluru case AH_ESP_V6_FLOW: 1158961acdeaSSudarsana Reddy Kalluru case AH_V6_FLOW: 1159961acdeaSSudarsana Reddy Kalluru case ESP_V6_FLOW: 1160961acdeaSSudarsana Reddy Kalluru case IP_USER_FLOW: 1161961acdeaSSudarsana Reddy Kalluru case ETHER_FLOW: 1162961acdeaSSudarsana Reddy Kalluru /* RSS is not supported for these protocols */ 1163961acdeaSSudarsana Reddy Kalluru if (info->data) { 1164961acdeaSSudarsana Reddy Kalluru DP_INFO(edev, "Command parameters not supported\n"); 1165961acdeaSSudarsana Reddy Kalluru return -EINVAL; 1166961acdeaSSudarsana Reddy Kalluru } 1167961acdeaSSudarsana Reddy Kalluru return 0; 1168961acdeaSSudarsana Reddy Kalluru default: 1169961acdeaSSudarsana Reddy Kalluru return -EINVAL; 1170961acdeaSSudarsana Reddy Kalluru } 1171961acdeaSSudarsana Reddy Kalluru 1172961acdeaSSudarsana Reddy Kalluru /* No action is needed if there is no change in the rss capability */ 1173f29ffdb6SMintz, Yuval if (edev->rss_caps == ((edev->rss_caps & ~clr_caps) | set_caps)) 1174961acdeaSSudarsana Reddy Kalluru return 0; 1175961acdeaSSudarsana Reddy Kalluru 1176961acdeaSSudarsana Reddy Kalluru /* Update internal configuration */ 1177f29ffdb6SMintz, Yuval edev->rss_caps = ((edev->rss_caps & ~clr_caps) | set_caps); 1178961acdeaSSudarsana Reddy Kalluru edev->rss_params_inited |= QEDE_RSS_CAPS_INITED; 1179961acdeaSSudarsana Reddy Kalluru 1180961acdeaSSudarsana Reddy Kalluru /* Re-configure if possible */ 1181f29ffdb6SMintz, Yuval __qede_lock(edev); 1182f29ffdb6SMintz, Yuval if (edev->state == QEDE_STATE_OPEN) { 1183f29ffdb6SMintz, Yuval vport_update_params = vzalloc(sizeof(*vport_update_params)); 1184f29ffdb6SMintz, Yuval if (!vport_update_params) { 1185f29ffdb6SMintz, Yuval __qede_unlock(edev); 1186f29ffdb6SMintz, Yuval return -ENOMEM; 1187961acdeaSSudarsana Reddy Kalluru } 1188f29ffdb6SMintz, Yuval qede_fill_rss_params(edev, &vport_update_params->rss_params, 1189f29ffdb6SMintz, Yuval &vport_update_params->update_rss_flg); 1190f29ffdb6SMintz, Yuval rc = edev->ops->vport_update(edev->cdev, vport_update_params); 1191f29ffdb6SMintz, Yuval vfree(vport_update_params); 1192f29ffdb6SMintz, Yuval } 1193f29ffdb6SMintz, Yuval __qede_unlock(edev); 1194961acdeaSSudarsana Reddy Kalluru 1195f29ffdb6SMintz, Yuval return rc; 1196961acdeaSSudarsana Reddy Kalluru } 1197961acdeaSSudarsana Reddy Kalluru 1198961acdeaSSudarsana Reddy Kalluru static int qede_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info) 1199961acdeaSSudarsana Reddy Kalluru { 1200961acdeaSSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 12013f2a2b8bSChopra, Manish int rc; 1202961acdeaSSudarsana Reddy Kalluru 1203961acdeaSSudarsana Reddy Kalluru switch (info->cmd) { 1204961acdeaSSudarsana Reddy Kalluru case ETHTOOL_SRXFH: 12053f2a2b8bSChopra, Manish rc = qede_set_rss_flags(edev, info); 12063f2a2b8bSChopra, Manish break; 12073f2a2b8bSChopra, Manish case ETHTOOL_SRXCLSRLINS: 12083f2a2b8bSChopra, Manish rc = qede_add_cls_rule(edev, info); 12093f2a2b8bSChopra, Manish break; 12103f2a2b8bSChopra, Manish case ETHTOOL_SRXCLSRLDEL: 12113f2a2b8bSChopra, Manish rc = qede_del_cls_rule(edev, info); 12123f2a2b8bSChopra, Manish break; 1213961acdeaSSudarsana Reddy Kalluru default: 1214961acdeaSSudarsana Reddy Kalluru DP_INFO(edev, "Command parameters not supported\n"); 12153f2a2b8bSChopra, Manish rc = -EOPNOTSUPP; 1216961acdeaSSudarsana Reddy Kalluru } 12173f2a2b8bSChopra, Manish 12183f2a2b8bSChopra, Manish return rc; 1219961acdeaSSudarsana Reddy Kalluru } 1220961acdeaSSudarsana Reddy Kalluru 1221961acdeaSSudarsana Reddy Kalluru static u32 qede_get_rxfh_indir_size(struct net_device *dev) 1222961acdeaSSudarsana Reddy Kalluru { 1223961acdeaSSudarsana Reddy Kalluru return QED_RSS_IND_TABLE_SIZE; 1224961acdeaSSudarsana Reddy Kalluru } 1225961acdeaSSudarsana Reddy Kalluru 1226961acdeaSSudarsana Reddy Kalluru static u32 qede_get_rxfh_key_size(struct net_device *dev) 1227961acdeaSSudarsana Reddy Kalluru { 1228961acdeaSSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 1229961acdeaSSudarsana Reddy Kalluru 1230f29ffdb6SMintz, Yuval return sizeof(edev->rss_key); 1231961acdeaSSudarsana Reddy Kalluru } 1232961acdeaSSudarsana Reddy Kalluru 1233961acdeaSSudarsana Reddy Kalluru static int qede_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc) 1234961acdeaSSudarsana Reddy Kalluru { 1235961acdeaSSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 1236961acdeaSSudarsana Reddy Kalluru int i; 1237961acdeaSSudarsana Reddy Kalluru 1238961acdeaSSudarsana Reddy Kalluru if (hfunc) 1239961acdeaSSudarsana Reddy Kalluru *hfunc = ETH_RSS_HASH_TOP; 1240961acdeaSSudarsana Reddy Kalluru 1241961acdeaSSudarsana Reddy Kalluru if (!indir) 1242961acdeaSSudarsana Reddy Kalluru return 0; 1243961acdeaSSudarsana Reddy Kalluru 1244961acdeaSSudarsana Reddy Kalluru for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++) 1245f29ffdb6SMintz, Yuval indir[i] = edev->rss_ind_table[i]; 1246961acdeaSSudarsana Reddy Kalluru 1247961acdeaSSudarsana Reddy Kalluru if (key) 1248f29ffdb6SMintz, Yuval memcpy(key, edev->rss_key, qede_get_rxfh_key_size(dev)); 1249961acdeaSSudarsana Reddy Kalluru 1250961acdeaSSudarsana Reddy Kalluru return 0; 1251961acdeaSSudarsana Reddy Kalluru } 1252961acdeaSSudarsana Reddy Kalluru 1253961acdeaSSudarsana Reddy Kalluru static int qede_set_rxfh(struct net_device *dev, const u32 *indir, 1254961acdeaSSudarsana Reddy Kalluru const u8 *key, const u8 hfunc) 1255961acdeaSSudarsana Reddy Kalluru { 1256f29ffdb6SMintz, Yuval struct qed_update_vport_params *vport_update_params; 1257961acdeaSSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 1258f29ffdb6SMintz, Yuval int i, rc = 0; 1259961acdeaSSudarsana Reddy Kalluru 1260ba300ce3SSudarsana Reddy Kalluru if (edev->dev_info.common.num_hwfns > 1) { 1261ba300ce3SSudarsana Reddy Kalluru DP_INFO(edev, 1262ba300ce3SSudarsana Reddy Kalluru "RSS configuration is not supported for 100G devices\n"); 1263ba300ce3SSudarsana Reddy Kalluru return -EOPNOTSUPP; 1264ba300ce3SSudarsana Reddy Kalluru } 1265ba300ce3SSudarsana Reddy Kalluru 1266961acdeaSSudarsana Reddy Kalluru if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) 1267961acdeaSSudarsana Reddy Kalluru return -EOPNOTSUPP; 1268961acdeaSSudarsana Reddy Kalluru 1269961acdeaSSudarsana Reddy Kalluru if (!indir && !key) 1270961acdeaSSudarsana Reddy Kalluru return 0; 1271961acdeaSSudarsana Reddy Kalluru 1272961acdeaSSudarsana Reddy Kalluru if (indir) { 1273961acdeaSSudarsana Reddy Kalluru for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++) 1274f29ffdb6SMintz, Yuval edev->rss_ind_table[i] = indir[i]; 1275961acdeaSSudarsana Reddy Kalluru edev->rss_params_inited |= QEDE_RSS_INDIR_INITED; 1276961acdeaSSudarsana Reddy Kalluru } 1277961acdeaSSudarsana Reddy Kalluru 1278961acdeaSSudarsana Reddy Kalluru if (key) { 1279f29ffdb6SMintz, Yuval memcpy(&edev->rss_key, key, qede_get_rxfh_key_size(dev)); 1280961acdeaSSudarsana Reddy Kalluru edev->rss_params_inited |= QEDE_RSS_KEY_INITED; 1281961acdeaSSudarsana Reddy Kalluru } 1282961acdeaSSudarsana Reddy Kalluru 1283f29ffdb6SMintz, Yuval __qede_lock(edev); 1284f29ffdb6SMintz, Yuval if (edev->state == QEDE_STATE_OPEN) { 1285f29ffdb6SMintz, Yuval vport_update_params = vzalloc(sizeof(*vport_update_params)); 1286f29ffdb6SMintz, Yuval if (!vport_update_params) { 1287f29ffdb6SMintz, Yuval __qede_unlock(edev); 1288f29ffdb6SMintz, Yuval return -ENOMEM; 1289961acdeaSSudarsana Reddy Kalluru } 1290f29ffdb6SMintz, Yuval qede_fill_rss_params(edev, &vport_update_params->rss_params, 1291f29ffdb6SMintz, Yuval &vport_update_params->update_rss_flg); 1292f29ffdb6SMintz, Yuval rc = edev->ops->vport_update(edev->cdev, vport_update_params); 1293f29ffdb6SMintz, Yuval vfree(vport_update_params); 1294f29ffdb6SMintz, Yuval } 1295f29ffdb6SMintz, Yuval __qede_unlock(edev); 1296961acdeaSSudarsana Reddy Kalluru 1297f29ffdb6SMintz, Yuval return rc; 1298961acdeaSSudarsana Reddy Kalluru } 1299961acdeaSSudarsana Reddy Kalluru 130016f46bf0SSudarsana Reddy Kalluru /* This function enables the interrupt generation and the NAPI on the device */ 130116f46bf0SSudarsana Reddy Kalluru static void qede_netif_start(struct qede_dev *edev) 130216f46bf0SSudarsana Reddy Kalluru { 130316f46bf0SSudarsana Reddy Kalluru int i; 130416f46bf0SSudarsana Reddy Kalluru 130516f46bf0SSudarsana Reddy Kalluru if (!netif_running(edev->ndev)) 130616f46bf0SSudarsana Reddy Kalluru return; 130716f46bf0SSudarsana Reddy Kalluru 13089a4d7e86SSudarsana Reddy Kalluru for_each_queue(i) { 130916f46bf0SSudarsana Reddy Kalluru /* Update and reenable interrupts */ 131016f46bf0SSudarsana Reddy Kalluru qed_sb_ack(edev->fp_array[i].sb_info, IGU_INT_ENABLE, 1); 131116f46bf0SSudarsana Reddy Kalluru napi_enable(&edev->fp_array[i].napi); 131216f46bf0SSudarsana Reddy Kalluru } 131316f46bf0SSudarsana Reddy Kalluru } 131416f46bf0SSudarsana Reddy Kalluru 131516f46bf0SSudarsana Reddy Kalluru /* This function disables the NAPI and the interrupt generation on the device */ 131616f46bf0SSudarsana Reddy Kalluru static void qede_netif_stop(struct qede_dev *edev) 131716f46bf0SSudarsana Reddy Kalluru { 131816f46bf0SSudarsana Reddy Kalluru int i; 131916f46bf0SSudarsana Reddy Kalluru 13209a4d7e86SSudarsana Reddy Kalluru for_each_queue(i) { 132116f46bf0SSudarsana Reddy Kalluru napi_disable(&edev->fp_array[i].napi); 132216f46bf0SSudarsana Reddy Kalluru /* Disable interrupts */ 132316f46bf0SSudarsana Reddy Kalluru qed_sb_ack(edev->fp_array[i].sb_info, IGU_INT_DISABLE, 0); 132416f46bf0SSudarsana Reddy Kalluru } 132516f46bf0SSudarsana Reddy Kalluru } 132616f46bf0SSudarsana Reddy Kalluru 132716f46bf0SSudarsana Reddy Kalluru static int qede_selftest_transmit_traffic(struct qede_dev *edev, 132816f46bf0SSudarsana Reddy Kalluru struct sk_buff *skb) 132916f46bf0SSudarsana Reddy Kalluru { 13309a4d7e86SSudarsana Reddy Kalluru struct qede_tx_queue *txq = NULL; 133116f46bf0SSudarsana Reddy Kalluru struct eth_tx_1st_bd *first_bd; 133216f46bf0SSudarsana Reddy Kalluru dma_addr_t mapping; 133348848a06SManish Chopra int i, idx; 133448848a06SManish Chopra u16 val; 133516f46bf0SSudarsana Reddy Kalluru 13369a4d7e86SSudarsana Reddy Kalluru for_each_queue(i) { 13379a4d7e86SSudarsana Reddy Kalluru if (edev->fp_array[i].type & QEDE_FASTPATH_TX) { 133880439a17SMintz, Yuval txq = edev->fp_array[i].txq; 13399a4d7e86SSudarsana Reddy Kalluru break; 13409a4d7e86SSudarsana Reddy Kalluru } 13419a4d7e86SSudarsana Reddy Kalluru } 13429a4d7e86SSudarsana Reddy Kalluru 13439a4d7e86SSudarsana Reddy Kalluru if (!txq) { 13449a4d7e86SSudarsana Reddy Kalluru DP_NOTICE(edev, "Tx path is not available\n"); 13459a4d7e86SSudarsana Reddy Kalluru return -1; 13469a4d7e86SSudarsana Reddy Kalluru } 13479a4d7e86SSudarsana Reddy Kalluru 134816f46bf0SSudarsana Reddy Kalluru /* Fill the entry in the SW ring and the BDs in the FW ring */ 13495a052d62SSudarsana Reddy Kalluru idx = txq->sw_tx_prod; 1350cb6aeb07SMintz, Yuval txq->sw_tx_ring.skbs[idx].skb = skb; 135116f46bf0SSudarsana Reddy Kalluru first_bd = qed_chain_produce(&txq->tx_pbl); 135216f46bf0SSudarsana Reddy Kalluru memset(first_bd, 0, sizeof(*first_bd)); 135316f46bf0SSudarsana Reddy Kalluru val = 1 << ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT; 135416f46bf0SSudarsana Reddy Kalluru first_bd->data.bd_flags.bitfields = val; 1355351a4dedSYuval Mintz val = skb->len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK; 135648848a06SManish Chopra val = val << ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT; 135748848a06SManish Chopra first_bd->data.bitfields |= cpu_to_le16(val); 135816f46bf0SSudarsana Reddy Kalluru 135916f46bf0SSudarsana Reddy Kalluru /* Map skb linear data for DMA and set in the first BD */ 136016f46bf0SSudarsana Reddy Kalluru mapping = dma_map_single(&edev->pdev->dev, skb->data, 136116f46bf0SSudarsana Reddy Kalluru skb_headlen(skb), DMA_TO_DEVICE); 136216f46bf0SSudarsana Reddy Kalluru if (unlikely(dma_mapping_error(&edev->pdev->dev, mapping))) { 136316f46bf0SSudarsana Reddy Kalluru DP_NOTICE(edev, "SKB mapping failed\n"); 136416f46bf0SSudarsana Reddy Kalluru return -ENOMEM; 136516f46bf0SSudarsana Reddy Kalluru } 136616f46bf0SSudarsana Reddy Kalluru BD_SET_UNMAP_ADDR_LEN(first_bd, mapping, skb_headlen(skb)); 136716f46bf0SSudarsana Reddy Kalluru 136816f46bf0SSudarsana Reddy Kalluru /* update the first BD with the actual num BDs */ 136916f46bf0SSudarsana Reddy Kalluru first_bd->data.nbds = 1; 13705a052d62SSudarsana Reddy Kalluru txq->sw_tx_prod = (txq->sw_tx_prod + 1) % txq->num_tx_buffers; 137116f46bf0SSudarsana Reddy Kalluru /* 'next page' entries are counted in the producer value */ 137248848a06SManish Chopra val = qed_chain_get_prod_idx(&txq->tx_pbl); 137348848a06SManish Chopra txq->tx_db.data.bd_prod = cpu_to_le16(val); 137416f46bf0SSudarsana Reddy Kalluru 137516f46bf0SSudarsana Reddy Kalluru /* wmb makes sure that the BDs data is updated before updating the 137616f46bf0SSudarsana Reddy Kalluru * producer, otherwise FW may read old data from the BDs. 137716f46bf0SSudarsana Reddy Kalluru */ 137816f46bf0SSudarsana Reddy Kalluru wmb(); 137916f46bf0SSudarsana Reddy Kalluru barrier(); 138016f46bf0SSudarsana Reddy Kalluru writel(txq->tx_db.raw, txq->doorbell_addr); 138116f46bf0SSudarsana Reddy Kalluru 138216f46bf0SSudarsana Reddy Kalluru /* mmiowb is needed to synchronize doorbell writes from more than one 138316f46bf0SSudarsana Reddy Kalluru * processor. It guarantees that the write arrives to the device before 138416f46bf0SSudarsana Reddy Kalluru * the queue lock is released and another start_xmit is called (possibly 138516f46bf0SSudarsana Reddy Kalluru * on another CPU). Without this barrier, the next doorbell can bypass 138616f46bf0SSudarsana Reddy Kalluru * this doorbell. This is applicable to IA64/Altix systems. 138716f46bf0SSudarsana Reddy Kalluru */ 138816f46bf0SSudarsana Reddy Kalluru mmiowb(); 138916f46bf0SSudarsana Reddy Kalluru 139016f46bf0SSudarsana Reddy Kalluru for (i = 0; i < QEDE_SELFTEST_POLL_COUNT; i++) { 139116f46bf0SSudarsana Reddy Kalluru if (qede_txq_has_work(txq)) 139216f46bf0SSudarsana Reddy Kalluru break; 139316f46bf0SSudarsana Reddy Kalluru usleep_range(100, 200); 139416f46bf0SSudarsana Reddy Kalluru } 139516f46bf0SSudarsana Reddy Kalluru 139616f46bf0SSudarsana Reddy Kalluru if (!qede_txq_has_work(txq)) { 139716f46bf0SSudarsana Reddy Kalluru DP_NOTICE(edev, "Tx completion didn't happen\n"); 139816f46bf0SSudarsana Reddy Kalluru return -1; 139916f46bf0SSudarsana Reddy Kalluru } 140016f46bf0SSudarsana Reddy Kalluru 140116f46bf0SSudarsana Reddy Kalluru first_bd = (struct eth_tx_1st_bd *)qed_chain_consume(&txq->tx_pbl); 1402fabd545cSManish Chopra dma_unmap_single(&edev->pdev->dev, BD_UNMAP_ADDR(first_bd), 140316f46bf0SSudarsana Reddy Kalluru BD_UNMAP_LEN(first_bd), DMA_TO_DEVICE); 14045a052d62SSudarsana Reddy Kalluru txq->sw_tx_cons = (txq->sw_tx_cons + 1) % txq->num_tx_buffers; 1405cb6aeb07SMintz, Yuval txq->sw_tx_ring.skbs[idx].skb = NULL; 140616f46bf0SSudarsana Reddy Kalluru 140716f46bf0SSudarsana Reddy Kalluru return 0; 140816f46bf0SSudarsana Reddy Kalluru } 140916f46bf0SSudarsana Reddy Kalluru 141016f46bf0SSudarsana Reddy Kalluru static int qede_selftest_receive_traffic(struct qede_dev *edev) 141116f46bf0SSudarsana Reddy Kalluru { 141216f46bf0SSudarsana Reddy Kalluru u16 hw_comp_cons, sw_comp_cons, sw_rx_index, len; 141316f46bf0SSudarsana Reddy Kalluru struct eth_fast_path_rx_reg_cqe *fp_cqe; 14149a4d7e86SSudarsana Reddy Kalluru struct qede_rx_queue *rxq = NULL; 141516f46bf0SSudarsana Reddy Kalluru struct sw_rx_data *sw_rx_data; 141616f46bf0SSudarsana Reddy Kalluru union eth_rx_cqe *cqe; 1417afe981d6SSudarsana Reddy Kalluru int i, iter, rc = 0; 141816f46bf0SSudarsana Reddy Kalluru u8 *data_ptr; 141916f46bf0SSudarsana Reddy Kalluru 14209a4d7e86SSudarsana Reddy Kalluru for_each_queue(i) { 14219a4d7e86SSudarsana Reddy Kalluru if (edev->fp_array[i].type & QEDE_FASTPATH_RX) { 14229a4d7e86SSudarsana Reddy Kalluru rxq = edev->fp_array[i].rxq; 14239a4d7e86SSudarsana Reddy Kalluru break; 14249a4d7e86SSudarsana Reddy Kalluru } 14259a4d7e86SSudarsana Reddy Kalluru } 14269a4d7e86SSudarsana Reddy Kalluru 14279a4d7e86SSudarsana Reddy Kalluru if (!rxq) { 14289a4d7e86SSudarsana Reddy Kalluru DP_NOTICE(edev, "Rx path is not available\n"); 14299a4d7e86SSudarsana Reddy Kalluru return -1; 14309a4d7e86SSudarsana Reddy Kalluru } 14319a4d7e86SSudarsana Reddy Kalluru 143216f46bf0SSudarsana Reddy Kalluru /* The packet is expected to receive on rx-queue 0 even though RSS is 143316f46bf0SSudarsana Reddy Kalluru * enabled. This is because the queue 0 is configured as the default 143416f46bf0SSudarsana Reddy Kalluru * queue and that the loopback traffic is not IP. 143516f46bf0SSudarsana Reddy Kalluru */ 1436afe981d6SSudarsana Reddy Kalluru for (iter = 0; iter < QEDE_SELFTEST_POLL_COUNT; iter++) { 143716f46bf0SSudarsana Reddy Kalluru if (!qede_has_rx_work(rxq)) { 1438837d4eb6SSudarsana Reddy Kalluru usleep_range(100, 200); 1439837d4eb6SSudarsana Reddy Kalluru continue; 144016f46bf0SSudarsana Reddy Kalluru } 144116f46bf0SSudarsana Reddy Kalluru 144216f46bf0SSudarsana Reddy Kalluru hw_comp_cons = le16_to_cpu(*rxq->hw_cons_ptr); 144316f46bf0SSudarsana Reddy Kalluru sw_comp_cons = qed_chain_get_cons_idx(&rxq->rx_comp_ring); 144416f46bf0SSudarsana Reddy Kalluru 1445837d4eb6SSudarsana Reddy Kalluru /* Memory barrier to prevent the CPU from doing speculative 1446837d4eb6SSudarsana Reddy Kalluru * reads of CQE/BD before reading hw_comp_cons. If the CQE is 1447837d4eb6SSudarsana Reddy Kalluru * read before it is written by FW, then FW writes CQE and SB, 1448837d4eb6SSudarsana Reddy Kalluru * and then the CPU reads the hw_comp_cons, it will use an old 1449837d4eb6SSudarsana Reddy Kalluru * CQE. 145016f46bf0SSudarsana Reddy Kalluru */ 145116f46bf0SSudarsana Reddy Kalluru rmb(); 145216f46bf0SSudarsana Reddy Kalluru 145316f46bf0SSudarsana Reddy Kalluru /* Get the CQE from the completion ring */ 145416f46bf0SSudarsana Reddy Kalluru cqe = (union eth_rx_cqe *)qed_chain_consume(&rxq->rx_comp_ring); 145516f46bf0SSudarsana Reddy Kalluru 145616f46bf0SSudarsana Reddy Kalluru /* Get the data from the SW ring */ 145716f46bf0SSudarsana Reddy Kalluru sw_rx_index = rxq->sw_rx_cons & NUM_RX_BDS_MAX; 145816f46bf0SSudarsana Reddy Kalluru sw_rx_data = &rxq->sw_rx_ring[sw_rx_index]; 145916f46bf0SSudarsana Reddy Kalluru fp_cqe = &cqe->fast_path_regular; 146016f46bf0SSudarsana Reddy Kalluru len = le16_to_cpu(fp_cqe->len_on_first_bd); 146116f46bf0SSudarsana Reddy Kalluru data_ptr = (u8 *)(page_address(sw_rx_data->data) + 1462837d4eb6SSudarsana Reddy Kalluru fp_cqe->placement_offset + 1463837d4eb6SSudarsana Reddy Kalluru sw_rx_data->page_offset); 1464837d4eb6SSudarsana Reddy Kalluru if (ether_addr_equal(data_ptr, edev->ndev->dev_addr) && 1465837d4eb6SSudarsana Reddy Kalluru ether_addr_equal(data_ptr + ETH_ALEN, 1466837d4eb6SSudarsana Reddy Kalluru edev->ndev->dev_addr)) { 146716f46bf0SSudarsana Reddy Kalluru for (i = ETH_HLEN; i < len; i++) 146816f46bf0SSudarsana Reddy Kalluru if (data_ptr[i] != (unsigned char)(i & 0xff)) { 1469837d4eb6SSudarsana Reddy Kalluru rc = -1; 1470837d4eb6SSudarsana Reddy Kalluru break; 147116f46bf0SSudarsana Reddy Kalluru } 147216f46bf0SSudarsana Reddy Kalluru 14739eb22357SMintz, Yuval qede_recycle_rx_bd_ring(rxq, 1); 1474837d4eb6SSudarsana Reddy Kalluru qed_chain_recycle_consumed(&rxq->rx_comp_ring); 1475837d4eb6SSudarsana Reddy Kalluru break; 1476837d4eb6SSudarsana Reddy Kalluru } 147716f46bf0SSudarsana Reddy Kalluru 1478837d4eb6SSudarsana Reddy Kalluru DP_INFO(edev, "Not the transmitted packet\n"); 14799eb22357SMintz, Yuval qede_recycle_rx_bd_ring(rxq, 1); 1480837d4eb6SSudarsana Reddy Kalluru qed_chain_recycle_consumed(&rxq->rx_comp_ring); 1481837d4eb6SSudarsana Reddy Kalluru } 1482837d4eb6SSudarsana Reddy Kalluru 1483afe981d6SSudarsana Reddy Kalluru if (iter == QEDE_SELFTEST_POLL_COUNT) { 1484837d4eb6SSudarsana Reddy Kalluru DP_NOTICE(edev, "Failed to receive the traffic\n"); 1485837d4eb6SSudarsana Reddy Kalluru return -1; 1486837d4eb6SSudarsana Reddy Kalluru } 1487837d4eb6SSudarsana Reddy Kalluru 1488837d4eb6SSudarsana Reddy Kalluru qede_update_rx_prod(edev, rxq); 1489837d4eb6SSudarsana Reddy Kalluru 1490837d4eb6SSudarsana Reddy Kalluru return rc; 149116f46bf0SSudarsana Reddy Kalluru } 149216f46bf0SSudarsana Reddy Kalluru 149316f46bf0SSudarsana Reddy Kalluru static int qede_selftest_run_loopback(struct qede_dev *edev, u32 loopback_mode) 149416f46bf0SSudarsana Reddy Kalluru { 149516f46bf0SSudarsana Reddy Kalluru struct qed_link_params link_params; 149616f46bf0SSudarsana Reddy Kalluru struct sk_buff *skb = NULL; 149716f46bf0SSudarsana Reddy Kalluru int rc = 0, i; 149816f46bf0SSudarsana Reddy Kalluru u32 pkt_size; 149916f46bf0SSudarsana Reddy Kalluru u8 *packet; 150016f46bf0SSudarsana Reddy Kalluru 150116f46bf0SSudarsana Reddy Kalluru if (!netif_running(edev->ndev)) { 150216f46bf0SSudarsana Reddy Kalluru DP_NOTICE(edev, "Interface is down\n"); 150316f46bf0SSudarsana Reddy Kalluru return -EINVAL; 150416f46bf0SSudarsana Reddy Kalluru } 150516f46bf0SSudarsana Reddy Kalluru 150616f46bf0SSudarsana Reddy Kalluru qede_netif_stop(edev); 150716f46bf0SSudarsana Reddy Kalluru 150816f46bf0SSudarsana Reddy Kalluru /* Bring up the link in Loopback mode */ 150916f46bf0SSudarsana Reddy Kalluru memset(&link_params, 0, sizeof(link_params)); 151016f46bf0SSudarsana Reddy Kalluru link_params.link_up = true; 151116f46bf0SSudarsana Reddy Kalluru link_params.override_flags = QED_LINK_OVERRIDE_LOOPBACK_MODE; 151216f46bf0SSudarsana Reddy Kalluru link_params.loopback_mode = loopback_mode; 151316f46bf0SSudarsana Reddy Kalluru edev->ops->common->set_link(edev->cdev, &link_params); 151416f46bf0SSudarsana Reddy Kalluru 151516f46bf0SSudarsana Reddy Kalluru /* Wait for loopback configuration to apply */ 151616f46bf0SSudarsana Reddy Kalluru msleep_interruptible(500); 151716f46bf0SSudarsana Reddy Kalluru 151816f46bf0SSudarsana Reddy Kalluru /* prepare the loopback packet */ 151916f46bf0SSudarsana Reddy Kalluru pkt_size = edev->ndev->mtu + ETH_HLEN; 152016f46bf0SSudarsana Reddy Kalluru 152116f46bf0SSudarsana Reddy Kalluru skb = netdev_alloc_skb(edev->ndev, pkt_size); 152216f46bf0SSudarsana Reddy Kalluru if (!skb) { 152316f46bf0SSudarsana Reddy Kalluru DP_INFO(edev, "Can't allocate skb\n"); 152416f46bf0SSudarsana Reddy Kalluru rc = -ENOMEM; 152516f46bf0SSudarsana Reddy Kalluru goto test_loopback_exit; 152616f46bf0SSudarsana Reddy Kalluru } 152716f46bf0SSudarsana Reddy Kalluru packet = skb_put(skb, pkt_size); 152816f46bf0SSudarsana Reddy Kalluru ether_addr_copy(packet, edev->ndev->dev_addr); 152916f46bf0SSudarsana Reddy Kalluru ether_addr_copy(packet + ETH_ALEN, edev->ndev->dev_addr); 153016f46bf0SSudarsana Reddy Kalluru memset(packet + (2 * ETH_ALEN), 0x77, (ETH_HLEN - (2 * ETH_ALEN))); 153116f46bf0SSudarsana Reddy Kalluru for (i = ETH_HLEN; i < pkt_size; i++) 153216f46bf0SSudarsana Reddy Kalluru packet[i] = (unsigned char)(i & 0xff); 153316f46bf0SSudarsana Reddy Kalluru 153416f46bf0SSudarsana Reddy Kalluru rc = qede_selftest_transmit_traffic(edev, skb); 153516f46bf0SSudarsana Reddy Kalluru if (rc) 153616f46bf0SSudarsana Reddy Kalluru goto test_loopback_exit; 153716f46bf0SSudarsana Reddy Kalluru 153816f46bf0SSudarsana Reddy Kalluru rc = qede_selftest_receive_traffic(edev); 153916f46bf0SSudarsana Reddy Kalluru if (rc) 154016f46bf0SSudarsana Reddy Kalluru goto test_loopback_exit; 154116f46bf0SSudarsana Reddy Kalluru 154216f46bf0SSudarsana Reddy Kalluru DP_VERBOSE(edev, NETIF_MSG_RX_STATUS, "Loopback test successful\n"); 154316f46bf0SSudarsana Reddy Kalluru 154416f46bf0SSudarsana Reddy Kalluru test_loopback_exit: 154516f46bf0SSudarsana Reddy Kalluru dev_kfree_skb(skb); 154616f46bf0SSudarsana Reddy Kalluru 154716f46bf0SSudarsana Reddy Kalluru /* Bring up the link in Normal mode */ 154816f46bf0SSudarsana Reddy Kalluru memset(&link_params, 0, sizeof(link_params)); 154916f46bf0SSudarsana Reddy Kalluru link_params.link_up = true; 155016f46bf0SSudarsana Reddy Kalluru link_params.override_flags = QED_LINK_OVERRIDE_LOOPBACK_MODE; 155116f46bf0SSudarsana Reddy Kalluru link_params.loopback_mode = QED_LINK_LOOPBACK_NONE; 155216f46bf0SSudarsana Reddy Kalluru edev->ops->common->set_link(edev->cdev, &link_params); 155316f46bf0SSudarsana Reddy Kalluru 155416f46bf0SSudarsana Reddy Kalluru /* Wait for loopback configuration to apply */ 155516f46bf0SSudarsana Reddy Kalluru msleep_interruptible(500); 155616f46bf0SSudarsana Reddy Kalluru 155716f46bf0SSudarsana Reddy Kalluru qede_netif_start(edev); 155816f46bf0SSudarsana Reddy Kalluru 155916f46bf0SSudarsana Reddy Kalluru return rc; 156016f46bf0SSudarsana Reddy Kalluru } 156116f46bf0SSudarsana Reddy Kalluru 15623044a02eSSudarsana Reddy Kalluru static void qede_self_test(struct net_device *dev, 15633044a02eSSudarsana Reddy Kalluru struct ethtool_test *etest, u64 *buf) 15643044a02eSSudarsana Reddy Kalluru { 15653044a02eSSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 15663044a02eSSudarsana Reddy Kalluru 15673044a02eSSudarsana Reddy Kalluru DP_VERBOSE(edev, QED_MSG_DEBUG, 15683044a02eSSudarsana Reddy Kalluru "Self-test command parameters: offline = %d, external_lb = %d\n", 15693044a02eSSudarsana Reddy Kalluru (etest->flags & ETH_TEST_FL_OFFLINE), 15703044a02eSSudarsana Reddy Kalluru (etest->flags & ETH_TEST_FL_EXTERNAL_LB) >> 2); 15713044a02eSSudarsana Reddy Kalluru 15723044a02eSSudarsana Reddy Kalluru memset(buf, 0, sizeof(u64) * QEDE_ETHTOOL_TEST_MAX); 15733044a02eSSudarsana Reddy Kalluru 157416f46bf0SSudarsana Reddy Kalluru if (etest->flags & ETH_TEST_FL_OFFLINE) { 157516f46bf0SSudarsana Reddy Kalluru if (qede_selftest_run_loopback(edev, 157616f46bf0SSudarsana Reddy Kalluru QED_LINK_LOOPBACK_INT_PHY)) { 157716f46bf0SSudarsana Reddy Kalluru buf[QEDE_ETHTOOL_INT_LOOPBACK] = 1; 157816f46bf0SSudarsana Reddy Kalluru etest->flags |= ETH_TEST_FL_FAILED; 157916f46bf0SSudarsana Reddy Kalluru } 158016f46bf0SSudarsana Reddy Kalluru } 158116f46bf0SSudarsana Reddy Kalluru 15823044a02eSSudarsana Reddy Kalluru if (edev->ops->common->selftest->selftest_interrupt(edev->cdev)) { 15833044a02eSSudarsana Reddy Kalluru buf[QEDE_ETHTOOL_INTERRUPT_TEST] = 1; 15843044a02eSSudarsana Reddy Kalluru etest->flags |= ETH_TEST_FL_FAILED; 15853044a02eSSudarsana Reddy Kalluru } 15863044a02eSSudarsana Reddy Kalluru 15873044a02eSSudarsana Reddy Kalluru if (edev->ops->common->selftest->selftest_memory(edev->cdev)) { 15883044a02eSSudarsana Reddy Kalluru buf[QEDE_ETHTOOL_MEMORY_TEST] = 1; 15893044a02eSSudarsana Reddy Kalluru etest->flags |= ETH_TEST_FL_FAILED; 15903044a02eSSudarsana Reddy Kalluru } 15913044a02eSSudarsana Reddy Kalluru 15923044a02eSSudarsana Reddy Kalluru if (edev->ops->common->selftest->selftest_register(edev->cdev)) { 15933044a02eSSudarsana Reddy Kalluru buf[QEDE_ETHTOOL_REGISTER_TEST] = 1; 15943044a02eSSudarsana Reddy Kalluru etest->flags |= ETH_TEST_FL_FAILED; 15953044a02eSSudarsana Reddy Kalluru } 15963044a02eSSudarsana Reddy Kalluru 15973044a02eSSudarsana Reddy Kalluru if (edev->ops->common->selftest->selftest_clock(edev->cdev)) { 15983044a02eSSudarsana Reddy Kalluru buf[QEDE_ETHTOOL_CLOCK_TEST] = 1; 15993044a02eSSudarsana Reddy Kalluru etest->flags |= ETH_TEST_FL_FAILED; 16003044a02eSSudarsana Reddy Kalluru } 16017a4b21b7SMintz, Yuval 16027a4b21b7SMintz, Yuval if (edev->ops->common->selftest->selftest_nvram(edev->cdev)) { 16037a4b21b7SMintz, Yuval buf[QEDE_ETHTOOL_NVRAM_TEST] = 1; 16047a4b21b7SMintz, Yuval etest->flags |= ETH_TEST_FL_FAILED; 16057a4b21b7SMintz, Yuval } 16063044a02eSSudarsana Reddy Kalluru } 16073044a02eSSudarsana Reddy Kalluru 16083d789994SManish Chopra static int qede_set_tunable(struct net_device *dev, 16093d789994SManish Chopra const struct ethtool_tunable *tuna, 16103d789994SManish Chopra const void *data) 16113d789994SManish Chopra { 16123d789994SManish Chopra struct qede_dev *edev = netdev_priv(dev); 16133d789994SManish Chopra u32 val; 16143d789994SManish Chopra 16153d789994SManish Chopra switch (tuna->id) { 16163d789994SManish Chopra case ETHTOOL_RX_COPYBREAK: 16173d789994SManish Chopra val = *(u32 *)data; 16183d789994SManish Chopra if (val < QEDE_MIN_PKT_LEN || val > QEDE_RX_HDR_SIZE) { 16193d789994SManish Chopra DP_VERBOSE(edev, QED_MSG_DEBUG, 16203d789994SManish Chopra "Invalid rx copy break value, range is [%u, %u]", 16213d789994SManish Chopra QEDE_MIN_PKT_LEN, QEDE_RX_HDR_SIZE); 16223d789994SManish Chopra return -EINVAL; 16233d789994SManish Chopra } 16243d789994SManish Chopra 16253d789994SManish Chopra edev->rx_copybreak = *(u32 *)data; 16263d789994SManish Chopra break; 16273d789994SManish Chopra default: 16283d789994SManish Chopra return -EOPNOTSUPP; 16293d789994SManish Chopra } 16303d789994SManish Chopra 16313d789994SManish Chopra return 0; 16323d789994SManish Chopra } 16333d789994SManish Chopra 16343d789994SManish Chopra static int qede_get_tunable(struct net_device *dev, 16353d789994SManish Chopra const struct ethtool_tunable *tuna, void *data) 16363d789994SManish Chopra { 16373d789994SManish Chopra struct qede_dev *edev = netdev_priv(dev); 16383d789994SManish Chopra 16393d789994SManish Chopra switch (tuna->id) { 16403d789994SManish Chopra case ETHTOOL_RX_COPYBREAK: 16413d789994SManish Chopra *(u32 *)data = edev->rx_copybreak; 16423d789994SManish Chopra break; 16433d789994SManish Chopra default: 16443d789994SManish Chopra return -EOPNOTSUPP; 16453d789994SManish Chopra } 16463d789994SManish Chopra 16473d789994SManish Chopra return 0; 16483d789994SManish Chopra } 16493d789994SManish Chopra 1650c3dc48f7SSudarsana Reddy Kalluru static int qede_get_eee(struct net_device *dev, struct ethtool_eee *edata) 1651c3dc48f7SSudarsana Reddy Kalluru { 1652c3dc48f7SSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 1653c3dc48f7SSudarsana Reddy Kalluru struct qed_link_output current_link; 1654c3dc48f7SSudarsana Reddy Kalluru 1655c3dc48f7SSudarsana Reddy Kalluru memset(¤t_link, 0, sizeof(current_link)); 1656c3dc48f7SSudarsana Reddy Kalluru edev->ops->common->get_link(edev->cdev, ¤t_link); 1657c3dc48f7SSudarsana Reddy Kalluru 1658c3dc48f7SSudarsana Reddy Kalluru if (!current_link.eee_supported) { 1659c3dc48f7SSudarsana Reddy Kalluru DP_INFO(edev, "EEE is not supported\n"); 1660c3dc48f7SSudarsana Reddy Kalluru return -EOPNOTSUPP; 1661c3dc48f7SSudarsana Reddy Kalluru } 1662c3dc48f7SSudarsana Reddy Kalluru 1663c3dc48f7SSudarsana Reddy Kalluru if (current_link.eee.adv_caps & QED_EEE_1G_ADV) 1664c3dc48f7SSudarsana Reddy Kalluru edata->advertised = ADVERTISED_1000baseT_Full; 1665c3dc48f7SSudarsana Reddy Kalluru if (current_link.eee.adv_caps & QED_EEE_10G_ADV) 1666c3dc48f7SSudarsana Reddy Kalluru edata->advertised |= ADVERTISED_10000baseT_Full; 1667c3dc48f7SSudarsana Reddy Kalluru if (current_link.sup_caps & QED_EEE_1G_ADV) 1668c3dc48f7SSudarsana Reddy Kalluru edata->supported = ADVERTISED_1000baseT_Full; 1669c3dc48f7SSudarsana Reddy Kalluru if (current_link.sup_caps & QED_EEE_10G_ADV) 1670c3dc48f7SSudarsana Reddy Kalluru edata->supported |= ADVERTISED_10000baseT_Full; 1671c3dc48f7SSudarsana Reddy Kalluru if (current_link.eee.lp_adv_caps & QED_EEE_1G_ADV) 1672c3dc48f7SSudarsana Reddy Kalluru edata->lp_advertised = ADVERTISED_1000baseT_Full; 1673c3dc48f7SSudarsana Reddy Kalluru if (current_link.eee.lp_adv_caps & QED_EEE_10G_ADV) 1674c3dc48f7SSudarsana Reddy Kalluru edata->lp_advertised |= ADVERTISED_10000baseT_Full; 1675c3dc48f7SSudarsana Reddy Kalluru 1676c3dc48f7SSudarsana Reddy Kalluru edata->tx_lpi_timer = current_link.eee.tx_lpi_timer; 1677c3dc48f7SSudarsana Reddy Kalluru edata->eee_enabled = current_link.eee.enable; 1678c3dc48f7SSudarsana Reddy Kalluru edata->tx_lpi_enabled = current_link.eee.tx_lpi_enable; 1679c3dc48f7SSudarsana Reddy Kalluru edata->eee_active = current_link.eee_active; 1680c3dc48f7SSudarsana Reddy Kalluru 1681c3dc48f7SSudarsana Reddy Kalluru return 0; 1682c3dc48f7SSudarsana Reddy Kalluru } 1683c3dc48f7SSudarsana Reddy Kalluru 1684c3dc48f7SSudarsana Reddy Kalluru static int qede_set_eee(struct net_device *dev, struct ethtool_eee *edata) 1685c3dc48f7SSudarsana Reddy Kalluru { 1686c3dc48f7SSudarsana Reddy Kalluru struct qede_dev *edev = netdev_priv(dev); 1687c3dc48f7SSudarsana Reddy Kalluru struct qed_link_output current_link; 1688c3dc48f7SSudarsana Reddy Kalluru struct qed_link_params params; 1689c3dc48f7SSudarsana Reddy Kalluru 1690c3dc48f7SSudarsana Reddy Kalluru if (!edev->ops->common->can_link_change(edev->cdev)) { 1691c3dc48f7SSudarsana Reddy Kalluru DP_INFO(edev, "Link settings are not allowed to be changed\n"); 1692c3dc48f7SSudarsana Reddy Kalluru return -EOPNOTSUPP; 1693c3dc48f7SSudarsana Reddy Kalluru } 1694c3dc48f7SSudarsana Reddy Kalluru 1695c3dc48f7SSudarsana Reddy Kalluru memset(¤t_link, 0, sizeof(current_link)); 1696c3dc48f7SSudarsana Reddy Kalluru edev->ops->common->get_link(edev->cdev, ¤t_link); 1697c3dc48f7SSudarsana Reddy Kalluru 1698c3dc48f7SSudarsana Reddy Kalluru if (!current_link.eee_supported) { 1699c3dc48f7SSudarsana Reddy Kalluru DP_INFO(edev, "EEE is not supported\n"); 1700c3dc48f7SSudarsana Reddy Kalluru return -EOPNOTSUPP; 1701c3dc48f7SSudarsana Reddy Kalluru } 1702c3dc48f7SSudarsana Reddy Kalluru 1703c3dc48f7SSudarsana Reddy Kalluru memset(¶ms, 0, sizeof(params)); 1704c3dc48f7SSudarsana Reddy Kalluru params.override_flags |= QED_LINK_OVERRIDE_EEE_CONFIG; 1705c3dc48f7SSudarsana Reddy Kalluru 1706c3dc48f7SSudarsana Reddy Kalluru if (!(edata->advertised & (ADVERTISED_1000baseT_Full | 1707c3dc48f7SSudarsana Reddy Kalluru ADVERTISED_10000baseT_Full)) || 1708c3dc48f7SSudarsana Reddy Kalluru ((edata->advertised & (ADVERTISED_1000baseT_Full | 1709c3dc48f7SSudarsana Reddy Kalluru ADVERTISED_10000baseT_Full)) != 1710c3dc48f7SSudarsana Reddy Kalluru edata->advertised)) { 1711c3dc48f7SSudarsana Reddy Kalluru DP_VERBOSE(edev, QED_MSG_DEBUG, 1712c3dc48f7SSudarsana Reddy Kalluru "Invalid advertised capabilities %d\n", 1713c3dc48f7SSudarsana Reddy Kalluru edata->advertised); 1714c3dc48f7SSudarsana Reddy Kalluru return -EINVAL; 1715c3dc48f7SSudarsana Reddy Kalluru } 1716c3dc48f7SSudarsana Reddy Kalluru 1717c3dc48f7SSudarsana Reddy Kalluru if (edata->advertised & ADVERTISED_1000baseT_Full) 1718c3dc48f7SSudarsana Reddy Kalluru params.eee.adv_caps = QED_EEE_1G_ADV; 1719c3dc48f7SSudarsana Reddy Kalluru if (edata->advertised & ADVERTISED_10000baseT_Full) 1720c3dc48f7SSudarsana Reddy Kalluru params.eee.adv_caps |= QED_EEE_10G_ADV; 1721c3dc48f7SSudarsana Reddy Kalluru params.eee.enable = edata->eee_enabled; 1722c3dc48f7SSudarsana Reddy Kalluru params.eee.tx_lpi_enable = edata->tx_lpi_enabled; 1723c3dc48f7SSudarsana Reddy Kalluru params.eee.tx_lpi_timer = edata->tx_lpi_timer; 1724c3dc48f7SSudarsana Reddy Kalluru 1725c3dc48f7SSudarsana Reddy Kalluru params.link_up = true; 1726c3dc48f7SSudarsana Reddy Kalluru edev->ops->common->set_link(edev->cdev, ¶ms); 1727c3dc48f7SSudarsana Reddy Kalluru 1728c3dc48f7SSudarsana Reddy Kalluru return 0; 1729c3dc48f7SSudarsana Reddy Kalluru } 1730c3dc48f7SSudarsana Reddy Kalluru 1731133fac0eSSudarsana Kalluru static const struct ethtool_ops qede_ethtool_ops = { 1732054c67d1SSudarsana Reddy Kalluru .get_link_ksettings = qede_get_link_ksettings, 1733054c67d1SSudarsana Reddy Kalluru .set_link_ksettings = qede_set_link_ksettings, 1734133fac0eSSudarsana Kalluru .get_drvinfo = qede_get_drvinfo, 1735e0971c83STomer Tayar .get_regs_len = qede_get_regs_len, 1736e0971c83STomer Tayar .get_regs = qede_get_regs, 173714d39648SMintz, Yuval .get_wol = qede_get_wol, 173814d39648SMintz, Yuval .set_wol = qede_set_wol, 1739133fac0eSSudarsana Kalluru .get_msglevel = qede_get_msglevel, 1740133fac0eSSudarsana Kalluru .set_msglevel = qede_set_msglevel, 174132a7a570SSudarsana Kalluru .nway_reset = qede_nway_reset, 1742133fac0eSSudarsana Kalluru .get_link = qede_get_link, 1743d552fa84SSudarsana Reddy Kalluru .get_coalesce = qede_get_coalesce, 1744d552fa84SSudarsana Reddy Kalluru .set_coalesce = qede_set_coalesce, 174501ef7e05SSudarsana Kalluru .get_ringparam = qede_get_ringparam, 174601ef7e05SSudarsana Kalluru .set_ringparam = qede_set_ringparam, 17470f7db144SSudarsana Kalluru .get_pauseparam = qede_get_pauseparam, 17480f7db144SSudarsana Kalluru .set_pauseparam = qede_set_pauseparam, 1749133fac0eSSudarsana Kalluru .get_strings = qede_get_strings, 17503d971cbdSSudarsana Kalluru .set_phys_id = qede_set_phys_id, 1751133fac0eSSudarsana Kalluru .get_ethtool_stats = qede_get_ethtool_stats, 1752f3e72109SYuval Mintz .get_priv_flags = qede_get_priv_flags, 1753133fac0eSSudarsana Kalluru .get_sset_count = qede_get_sset_count, 1754961acdeaSSudarsana Reddy Kalluru .get_rxnfc = qede_get_rxnfc, 1755961acdeaSSudarsana Reddy Kalluru .set_rxnfc = qede_set_rxnfc, 1756961acdeaSSudarsana Reddy Kalluru .get_rxfh_indir_size = qede_get_rxfh_indir_size, 1757961acdeaSSudarsana Reddy Kalluru .get_rxfh_key_size = qede_get_rxfh_key_size, 1758961acdeaSSudarsana Reddy Kalluru .get_rxfh = qede_get_rxfh, 1759961acdeaSSudarsana Reddy Kalluru .set_rxfh = qede_set_rxfh, 17604c55215cSSudarsana Reddy Kalluru .get_ts_info = qede_get_ts_info, 17618edf049dSSudarsana Kalluru .get_channels = qede_get_channels, 17628edf049dSSudarsana Kalluru .set_channels = qede_set_channels, 17633044a02eSSudarsana Reddy Kalluru .self_test = qede_self_test, 1764c3dc48f7SSudarsana Reddy Kalluru .get_eee = qede_get_eee, 1765c3dc48f7SSudarsana Reddy Kalluru .set_eee = qede_set_eee, 1766c3dc48f7SSudarsana Reddy Kalluru 17673d789994SManish Chopra .get_tunable = qede_get_tunable, 17683d789994SManish Chopra .set_tunable = qede_set_tunable, 1769133fac0eSSudarsana Kalluru }; 1770133fac0eSSudarsana Kalluru 1771fefb0202SYuval Mintz static const struct ethtool_ops qede_vf_ethtool_ops = { 1772054c67d1SSudarsana Reddy Kalluru .get_link_ksettings = qede_get_link_ksettings, 1773fefb0202SYuval Mintz .get_drvinfo = qede_get_drvinfo, 1774fefb0202SYuval Mintz .get_msglevel = qede_get_msglevel, 1775fefb0202SYuval Mintz .set_msglevel = qede_set_msglevel, 1776fefb0202SYuval Mintz .get_link = qede_get_link, 1777477f2d14SRahul Verma .get_coalesce = qede_get_coalesce, 1778477f2d14SRahul Verma .set_coalesce = qede_set_coalesce, 1779fefb0202SYuval Mintz .get_ringparam = qede_get_ringparam, 1780fefb0202SYuval Mintz .set_ringparam = qede_set_ringparam, 1781fefb0202SYuval Mintz .get_strings = qede_get_strings, 1782fefb0202SYuval Mintz .get_ethtool_stats = qede_get_ethtool_stats, 1783fefb0202SYuval Mintz .get_priv_flags = qede_get_priv_flags, 1784fefb0202SYuval Mintz .get_sset_count = qede_get_sset_count, 1785fefb0202SYuval Mintz .get_rxnfc = qede_get_rxnfc, 1786fefb0202SYuval Mintz .set_rxnfc = qede_set_rxnfc, 1787fefb0202SYuval Mintz .get_rxfh_indir_size = qede_get_rxfh_indir_size, 1788fefb0202SYuval Mintz .get_rxfh_key_size = qede_get_rxfh_key_size, 1789fefb0202SYuval Mintz .get_rxfh = qede_get_rxfh, 1790fefb0202SYuval Mintz .set_rxfh = qede_set_rxfh, 1791fefb0202SYuval Mintz .get_channels = qede_get_channels, 1792fefb0202SYuval Mintz .set_channels = qede_set_channels, 17933d789994SManish Chopra .get_tunable = qede_get_tunable, 17943d789994SManish Chopra .set_tunable = qede_set_tunable, 1795fefb0202SYuval Mintz }; 1796fefb0202SYuval Mintz 1797133fac0eSSudarsana Kalluru void qede_set_ethtool_ops(struct net_device *dev) 1798133fac0eSSudarsana Kalluru { 1799fefb0202SYuval Mintz struct qede_dev *edev = netdev_priv(dev); 1800fefb0202SYuval Mintz 1801fefb0202SYuval Mintz if (IS_VF(edev)) 1802fefb0202SYuval Mintz dev->ethtool_ops = &qede_vf_ethtool_ops; 1803fefb0202SYuval Mintz else 1804133fac0eSSudarsana Kalluru dev->ethtool_ops = &qede_ethtool_ops; 1805133fac0eSSudarsana Kalluru } 1806