blob: 427e043a033f961a256047228bff7e808a59ee83 [file] [log] [blame]
Sudarsana Kalluru133fac02015-10-26 11:02:34 +02001/* QLogic qede NIC Driver
2* Copyright (c) 2015 QLogic Corporation
3*
4* This software is available under the terms of the GNU General Public License
5* (GPL) Version 2, available from the file COPYING in the main directory of
6* this source tree.
7*/
8
9#include <linux/version.h>
10#include <linux/types.h>
11#include <linux/netdevice.h>
Sudarsana Reddy Kalluru16f46bf2016-04-28 20:20:54 -040012#include <linux/etherdevice.h>
Sudarsana Kalluru133fac02015-10-26 11:02:34 +020013#include <linux/ethtool.h>
14#include <linux/string.h>
15#include <linux/pci.h>
16#include <linux/capability.h>
17#include "qede.h"
18
19#define QEDE_STAT_OFFSET(stat_name) (offsetof(struct qede_stats, stat_name))
20#define QEDE_STAT_STRING(stat_name) (#stat_name)
21#define _QEDE_STAT(stat_name, pf_only) \
22 {QEDE_STAT_OFFSET(stat_name), QEDE_STAT_STRING(stat_name), pf_only}
23#define QEDE_PF_STAT(stat_name) _QEDE_STAT(stat_name, true)
24#define QEDE_STAT(stat_name) _QEDE_STAT(stat_name, false)
25
26#define QEDE_RQSTAT_OFFSET(stat_name) \
27 (offsetof(struct qede_rx_queue, stat_name))
28#define QEDE_RQSTAT_STRING(stat_name) (#stat_name)
29#define QEDE_RQSTAT(stat_name) \
30 {QEDE_RQSTAT_OFFSET(stat_name), QEDE_RQSTAT_STRING(stat_name)}
Sudarsana Reddy Kalluru16f46bf2016-04-28 20:20:54 -040031
32#define QEDE_SELFTEST_POLL_COUNT 100
33
Sudarsana Kalluru133fac02015-10-26 11:02:34 +020034static const struct {
35 u64 offset;
36 char string[ETH_GSTRING_LEN];
37} qede_rqstats_arr[] = {
38 QEDE_RQSTAT(rx_hw_errors),
39 QEDE_RQSTAT(rx_alloc_errors),
Manish Choprac72a6122016-06-30 02:35:18 -040040 QEDE_RQSTAT(rx_ip_frags),
Sudarsana Kalluru133fac02015-10-26 11:02:34 +020041};
42
43#define QEDE_NUM_RQSTATS ARRAY_SIZE(qede_rqstats_arr)
44#define QEDE_RQSTATS_DATA(dev, sindex, rqindex) \
45 (*((u64 *)(((char *)(dev->fp_array[(rqindex)].rxq)) +\
46 qede_rqstats_arr[(sindex)].offset)))
47static const struct {
48 u64 offset;
49 char string[ETH_GSTRING_LEN];
50 bool pf_only;
51} qede_stats_arr[] = {
52 QEDE_STAT(rx_ucast_bytes),
53 QEDE_STAT(rx_mcast_bytes),
54 QEDE_STAT(rx_bcast_bytes),
55 QEDE_STAT(rx_ucast_pkts),
56 QEDE_STAT(rx_mcast_pkts),
57 QEDE_STAT(rx_bcast_pkts),
58
59 QEDE_STAT(tx_ucast_bytes),
60 QEDE_STAT(tx_mcast_bytes),
61 QEDE_STAT(tx_bcast_bytes),
62 QEDE_STAT(tx_ucast_pkts),
63 QEDE_STAT(tx_mcast_pkts),
64 QEDE_STAT(tx_bcast_pkts),
65
66 QEDE_PF_STAT(rx_64_byte_packets),
Yuval Mintzd4967cf2016-04-22 08:41:01 +030067 QEDE_PF_STAT(rx_65_to_127_byte_packets),
68 QEDE_PF_STAT(rx_128_to_255_byte_packets),
69 QEDE_PF_STAT(rx_256_to_511_byte_packets),
70 QEDE_PF_STAT(rx_512_to_1023_byte_packets),
71 QEDE_PF_STAT(rx_1024_to_1518_byte_packets),
72 QEDE_PF_STAT(rx_1519_to_1522_byte_packets),
73 QEDE_PF_STAT(rx_1519_to_2047_byte_packets),
74 QEDE_PF_STAT(rx_2048_to_4095_byte_packets),
75 QEDE_PF_STAT(rx_4096_to_9216_byte_packets),
76 QEDE_PF_STAT(rx_9217_to_16383_byte_packets),
Sudarsana Kalluru133fac02015-10-26 11:02:34 +020077 QEDE_PF_STAT(tx_64_byte_packets),
78 QEDE_PF_STAT(tx_65_to_127_byte_packets),
79 QEDE_PF_STAT(tx_128_to_255_byte_packets),
80 QEDE_PF_STAT(tx_256_to_511_byte_packets),
81 QEDE_PF_STAT(tx_512_to_1023_byte_packets),
82 QEDE_PF_STAT(tx_1024_to_1518_byte_packets),
83 QEDE_PF_STAT(tx_1519_to_2047_byte_packets),
84 QEDE_PF_STAT(tx_2048_to_4095_byte_packets),
85 QEDE_PF_STAT(tx_4096_to_9216_byte_packets),
86 QEDE_PF_STAT(tx_9217_to_16383_byte_packets),
87
88 QEDE_PF_STAT(rx_mac_crtl_frames),
89 QEDE_PF_STAT(tx_mac_ctrl_frames),
90 QEDE_PF_STAT(rx_pause_frames),
91 QEDE_PF_STAT(tx_pause_frames),
92 QEDE_PF_STAT(rx_pfc_frames),
93 QEDE_PF_STAT(tx_pfc_frames),
94
95 QEDE_PF_STAT(rx_crc_errors),
96 QEDE_PF_STAT(rx_align_errors),
97 QEDE_PF_STAT(rx_carrier_errors),
98 QEDE_PF_STAT(rx_oversize_packets),
99 QEDE_PF_STAT(rx_jabbers),
100 QEDE_PF_STAT(rx_undersize_packets),
101 QEDE_PF_STAT(rx_fragments),
102 QEDE_PF_STAT(tx_lpi_entry_count),
103 QEDE_PF_STAT(tx_total_collisions),
104 QEDE_PF_STAT(brb_truncates),
105 QEDE_PF_STAT(brb_discards),
106 QEDE_STAT(no_buff_discards),
107 QEDE_PF_STAT(mftag_filter_discards),
108 QEDE_PF_STAT(mac_filter_discards),
109 QEDE_STAT(tx_err_drop_pkts),
110
111 QEDE_STAT(coalesced_pkts),
112 QEDE_STAT(coalesced_events),
113 QEDE_STAT(coalesced_aborts_num),
114 QEDE_STAT(non_coalesced_pkts),
115 QEDE_STAT(coalesced_bytes),
116};
117
118#define QEDE_STATS_DATA(dev, index) \
119 (*((u64 *)(((char *)(dev)) + offsetof(struct qede_dev, stats) \
120 + qede_stats_arr[(index)].offset)))
121
122#define QEDE_NUM_STATS ARRAY_SIZE(qede_stats_arr)
123
Yuval Mintzf3e72102016-04-22 08:41:02 +0300124enum {
125 QEDE_PRI_FLAG_CMT,
126 QEDE_PRI_FLAG_LEN,
127};
128
129static const char qede_private_arr[QEDE_PRI_FLAG_LEN][ETH_GSTRING_LEN] = {
130 "Coupled-Function",
131};
132
Sudarsana Reddy Kalluru3044a022016-04-28 20:20:53 -0400133enum qede_ethtool_tests {
Sudarsana Reddy Kalluru16f46bf2016-04-28 20:20:54 -0400134 QEDE_ETHTOOL_INT_LOOPBACK,
Sudarsana Reddy Kalluru3044a022016-04-28 20:20:53 -0400135 QEDE_ETHTOOL_INTERRUPT_TEST,
136 QEDE_ETHTOOL_MEMORY_TEST,
137 QEDE_ETHTOOL_REGISTER_TEST,
138 QEDE_ETHTOOL_CLOCK_TEST,
139 QEDE_ETHTOOL_TEST_MAX
140};
141
142static const char qede_tests_str_arr[QEDE_ETHTOOL_TEST_MAX][ETH_GSTRING_LEN] = {
Sudarsana Reddy Kalluru16f46bf2016-04-28 20:20:54 -0400143 "Internal loopback (offline)",
Sudarsana Reddy Kalluru3044a022016-04-28 20:20:53 -0400144 "Interrupt (online)\t",
145 "Memory (online)\t\t",
146 "Register (online)\t",
147 "Clock (online)\t\t",
148};
149
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200150static void qede_get_strings_stats(struct qede_dev *edev, u8 *buf)
151{
152 int i, j, k;
153
154 for (i = 0, j = 0; i < QEDE_NUM_STATS; i++) {
Yuval Mintzfefb0202016-05-11 16:36:19 +0300155 if (IS_VF(edev) && qede_stats_arr[i].pf_only)
156 continue;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200157 strcpy(buf + j * ETH_GSTRING_LEN,
158 qede_stats_arr[i].string);
159 j++;
160 }
161
162 for (k = 0; k < QEDE_NUM_RQSTATS; k++, j++)
163 strcpy(buf + j * ETH_GSTRING_LEN,
164 qede_rqstats_arr[k].string);
165}
166
167static void qede_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
168{
169 struct qede_dev *edev = netdev_priv(dev);
170
171 switch (stringset) {
172 case ETH_SS_STATS:
173 qede_get_strings_stats(edev, buf);
174 break;
Yuval Mintzf3e72102016-04-22 08:41:02 +0300175 case ETH_SS_PRIV_FLAGS:
176 memcpy(buf, qede_private_arr,
177 ETH_GSTRING_LEN * QEDE_PRI_FLAG_LEN);
178 break;
Sudarsana Reddy Kalluru3044a022016-04-28 20:20:53 -0400179 case ETH_SS_TEST:
180 memcpy(buf, qede_tests_str_arr,
181 ETH_GSTRING_LEN * QEDE_ETHTOOL_TEST_MAX);
182 break;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200183 default:
184 DP_VERBOSE(edev, QED_MSG_DEBUG,
185 "Unsupported stringset 0x%08x\n", stringset);
186 }
187}
188
189static void qede_get_ethtool_stats(struct net_device *dev,
190 struct ethtool_stats *stats, u64 *buf)
191{
192 struct qede_dev *edev = netdev_priv(dev);
193 int sidx, cnt = 0;
194 int qid;
195
196 qede_fill_by_demand_stats(edev);
197
198 mutex_lock(&edev->qede_lock);
199
Yuval Mintzfefb0202016-05-11 16:36:19 +0300200 for (sidx = 0; sidx < QEDE_NUM_STATS; sidx++) {
201 if (IS_VF(edev) && qede_stats_arr[sidx].pf_only)
202 continue;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200203 buf[cnt++] = QEDE_STATS_DATA(edev, sidx);
Yuval Mintzfefb0202016-05-11 16:36:19 +0300204 }
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200205
206 for (sidx = 0; sidx < QEDE_NUM_RQSTATS; sidx++) {
207 buf[cnt] = 0;
208 for (qid = 0; qid < edev->num_rss; qid++)
209 buf[cnt] += QEDE_RQSTATS_DATA(edev, sidx, qid);
210 cnt++;
211 }
212
213 mutex_unlock(&edev->qede_lock);
214}
215
216static int qede_get_sset_count(struct net_device *dev, int stringset)
217{
218 struct qede_dev *edev = netdev_priv(dev);
219 int num_stats = QEDE_NUM_STATS;
220
221 switch (stringset) {
222 case ETH_SS_STATS:
Yuval Mintzfefb0202016-05-11 16:36:19 +0300223 if (IS_VF(edev)) {
224 int i;
225
226 for (i = 0; i < QEDE_NUM_STATS; i++)
227 if (qede_stats_arr[i].pf_only)
228 num_stats--;
229 }
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200230 return num_stats + QEDE_NUM_RQSTATS;
Yuval Mintzf3e72102016-04-22 08:41:02 +0300231 case ETH_SS_PRIV_FLAGS:
232 return QEDE_PRI_FLAG_LEN;
Sudarsana Reddy Kalluru3044a022016-04-28 20:20:53 -0400233 case ETH_SS_TEST:
Yuval Mintz6ecb0a02016-05-26 11:01:19 +0300234 if (!IS_VF(edev))
235 return QEDE_ETHTOOL_TEST_MAX;
236 else
237 return 0;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200238 default:
239 DP_VERBOSE(edev, QED_MSG_DEBUG,
240 "Unsupported stringset 0x%08x\n", stringset);
241 return -EINVAL;
242 }
243}
244
Yuval Mintzf3e72102016-04-22 08:41:02 +0300245static u32 qede_get_priv_flags(struct net_device *dev)
246{
247 struct qede_dev *edev = netdev_priv(dev);
248
249 return (!!(edev->dev_info.common.num_hwfns > 1)) << QEDE_PRI_FLAG_CMT;
250}
251
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400252struct qede_link_mode_mapping {
253 u32 qed_link_mode;
254 u32 ethtool_link_mode;
255};
256
257static const struct qede_link_mode_mapping qed_lm_map[] = {
258 {QED_LM_FIBRE_BIT, ETHTOOL_LINK_MODE_FIBRE_BIT},
259 {QED_LM_Autoneg_BIT, ETHTOOL_LINK_MODE_Autoneg_BIT},
260 {QED_LM_Asym_Pause_BIT, ETHTOOL_LINK_MODE_Asym_Pause_BIT},
261 {QED_LM_Pause_BIT, ETHTOOL_LINK_MODE_Pause_BIT},
262 {QED_LM_1000baseT_Half_BIT, ETHTOOL_LINK_MODE_1000baseT_Half_BIT},
263 {QED_LM_1000baseT_Full_BIT, ETHTOOL_LINK_MODE_1000baseT_Full_BIT},
264 {QED_LM_10000baseKR_Full_BIT, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT},
265 {QED_LM_25000baseKR_Full_BIT, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT},
266 {QED_LM_40000baseLR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT},
267 {QED_LM_50000baseKR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT},
268 {QED_LM_100000baseKR4_Full_BIT,
269 ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT},
270};
271
272#define QEDE_DRV_TO_ETHTOOL_CAPS(caps, lk_ksettings, name) \
273{ \
274 int i; \
275 \
276 for (i = 0; i < QED_LM_COUNT; i++) { \
277 if ((caps) & (qed_lm_map[i].qed_link_mode)) \
278 __set_bit(qed_lm_map[i].ethtool_link_mode,\
279 lk_ksettings->link_modes.name); \
280 } \
281}
282
283#define QEDE_ETHTOOL_TO_DRV_CAPS(caps, lk_ksettings, name) \
284{ \
285 int i; \
286 \
287 for (i = 0; i < QED_LM_COUNT; i++) { \
288 if (test_bit(qed_lm_map[i].ethtool_link_mode, \
289 lk_ksettings->link_modes.name)) \
290 caps |= qed_lm_map[i].qed_link_mode; \
291 } \
292}
293
294static int qede_get_link_ksettings(struct net_device *dev,
295 struct ethtool_link_ksettings *cmd)
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200296{
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400297 struct ethtool_link_settings *base = &cmd->base;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200298 struct qede_dev *edev = netdev_priv(dev);
299 struct qed_link_output current_link;
300
301 memset(&current_link, 0, sizeof(current_link));
302 edev->ops->common->get_link(edev->cdev, &current_link);
303
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400304 ethtool_link_ksettings_zero_link_mode(cmd, supported);
305 QEDE_DRV_TO_ETHTOOL_CAPS(current_link.supported_caps, cmd, supported)
306
307 ethtool_link_ksettings_zero_link_mode(cmd, advertising);
308 QEDE_DRV_TO_ETHTOOL_CAPS(current_link.advertised_caps, cmd, advertising)
309
310 ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising);
311 QEDE_DRV_TO_ETHTOOL_CAPS(current_link.lp_caps, cmd, lp_advertising)
312
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200313 if ((edev->state == QEDE_STATE_OPEN) && (current_link.link_up)) {
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400314 base->speed = current_link.speed;
315 base->duplex = current_link.duplex;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200316 } else {
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400317 base->speed = SPEED_UNKNOWN;
318 base->duplex = DUPLEX_UNKNOWN;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200319 }
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400320 base->port = current_link.port;
321 base->autoneg = (current_link.autoneg) ? AUTONEG_ENABLE :
322 AUTONEG_DISABLE;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200323
324 return 0;
325}
326
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400327static int qede_set_link_ksettings(struct net_device *dev,
328 const struct ethtool_link_ksettings *cmd)
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200329{
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400330 const struct ethtool_link_settings *base = &cmd->base;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200331 struct qede_dev *edev = netdev_priv(dev);
332 struct qed_link_output current_link;
333 struct qed_link_params params;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200334
Yuval Mintzfe7cd2b2016-04-22 08:41:03 +0300335 if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400336 DP_INFO(edev, "Link settings are not allowed to be changed\n");
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200337 return -EOPNOTSUPP;
338 }
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200339 memset(&current_link, 0, sizeof(current_link));
340 memset(&params, 0, sizeof(params));
341 edev->ops->common->get_link(edev->cdev, &current_link);
342
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200343 params.override_flags |= QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS;
344 params.override_flags |= QED_LINK_OVERRIDE_SPEED_AUTONEG;
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400345 if (base->autoneg == AUTONEG_ENABLE) {
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200346 params.autoneg = true;
347 params.forced_speed = 0;
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400348 QEDE_ETHTOOL_TO_DRV_CAPS(params.adv_speeds, cmd, advertising)
349 } else { /* forced speed */
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200350 params.override_flags |= QED_LINK_OVERRIDE_SPEED_FORCED_SPEED;
351 params.autoneg = false;
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400352 params.forced_speed = base->speed;
353 switch (base->speed) {
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200354 case SPEED_10000:
355 if (!(current_link.supported_caps &
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400356 QED_LM_10000baseKR_Full_BIT)) {
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200357 DP_INFO(edev, "10G speed not supported\n");
358 return -EINVAL;
359 }
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400360 params.adv_speeds = QED_LM_10000baseKR_Full_BIT;
361 break;
362 case SPEED_25000:
363 if (!(current_link.supported_caps &
364 QED_LM_25000baseKR_Full_BIT)) {
365 DP_INFO(edev, "25G speed not supported\n");
366 return -EINVAL;
367 }
368 params.adv_speeds = QED_LM_25000baseKR_Full_BIT;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200369 break;
370 case SPEED_40000:
371 if (!(current_link.supported_caps &
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400372 QED_LM_40000baseLR4_Full_BIT)) {
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200373 DP_INFO(edev, "40G speed not supported\n");
374 return -EINVAL;
375 }
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400376 params.adv_speeds = QED_LM_40000baseLR4_Full_BIT;
377 break;
378 case 0xdead:
379 if (!(current_link.supported_caps &
380 QED_LM_50000baseKR2_Full_BIT)) {
381 DP_INFO(edev, "50G speed not supported\n");
382 return -EINVAL;
383 }
384 params.adv_speeds = QED_LM_50000baseKR2_Full_BIT;
385 break;
386 case 0xbeef:
387 if (!(current_link.supported_caps &
388 QED_LM_100000baseKR4_Full_BIT)) {
389 DP_INFO(edev, "100G speed not supported\n");
390 return -EINVAL;
391 }
392 params.adv_speeds = QED_LM_100000baseKR4_Full_BIT;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200393 break;
394 default:
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -0400395 DP_INFO(edev, "Unsupported speed %u\n", base->speed);
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200396 return -EINVAL;
397 }
398 }
399
400 params.link_up = true;
401 edev->ops->common->set_link(edev->cdev, &params);
402
403 return 0;
404}
405
406static void qede_get_drvinfo(struct net_device *ndev,
407 struct ethtool_drvinfo *info)
408{
409 char mfw[ETHTOOL_FWVERS_LEN], storm[ETHTOOL_FWVERS_LEN];
410 struct qede_dev *edev = netdev_priv(ndev);
411
412 strlcpy(info->driver, "qede", sizeof(info->driver));
413 strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
414
415 snprintf(storm, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d",
416 edev->dev_info.common.fw_major,
417 edev->dev_info.common.fw_minor,
418 edev->dev_info.common.fw_rev,
419 edev->dev_info.common.fw_eng);
420
421 snprintf(mfw, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d",
422 (edev->dev_info.common.mfw_rev >> 24) & 0xFF,
423 (edev->dev_info.common.mfw_rev >> 16) & 0xFF,
424 (edev->dev_info.common.mfw_rev >> 8) & 0xFF,
425 edev->dev_info.common.mfw_rev & 0xFF);
426
427 if ((strlen(storm) + strlen(mfw) + strlen("mfw storm ")) <
428 sizeof(info->fw_version)) {
429 snprintf(info->fw_version, sizeof(info->fw_version),
430 "mfw %s storm %s", mfw, storm);
431 } else {
432 snprintf(info->fw_version, sizeof(info->fw_version),
433 "%s %s", mfw, storm);
434 }
435
436 strlcpy(info->bus_info, pci_name(edev->pdev), sizeof(info->bus_info));
437}
438
439static u32 qede_get_msglevel(struct net_device *ndev)
440{
441 struct qede_dev *edev = netdev_priv(ndev);
442
Yuval Mintz1a635e42016-08-15 10:42:43 +0300443 return ((u32)edev->dp_level << QED_LOG_LEVEL_SHIFT) | edev->dp_module;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200444}
445
446static void qede_set_msglevel(struct net_device *ndev, u32 level)
447{
448 struct qede_dev *edev = netdev_priv(ndev);
449 u32 dp_module = 0;
450 u8 dp_level = 0;
451
452 qede_config_debug(level, &dp_module, &dp_level);
453
454 edev->dp_level = dp_level;
455 edev->dp_module = dp_module;
456 edev->ops->common->update_msglvl(edev->cdev,
457 dp_module, dp_level);
458}
459
Sudarsana Kalluru32a7a572015-11-30 12:25:05 +0200460static int qede_nway_reset(struct net_device *dev)
461{
462 struct qede_dev *edev = netdev_priv(dev);
463 struct qed_link_output current_link;
464 struct qed_link_params link_params;
465
Yuval Mintzfe7cd2b2016-04-22 08:41:03 +0300466 if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
Yuval Mintz1a635e42016-08-15 10:42:43 +0300467 DP_INFO(edev, "Link settings are not allowed to be changed\n");
Yuval Mintzfe7cd2b2016-04-22 08:41:03 +0300468 return -EOPNOTSUPP;
469 }
470
Sudarsana Kalluru32a7a572015-11-30 12:25:05 +0200471 if (!netif_running(dev))
472 return 0;
473
474 memset(&current_link, 0, sizeof(current_link));
475 edev->ops->common->get_link(edev->cdev, &current_link);
476 if (!current_link.link_up)
477 return 0;
478
479 /* Toggle the link */
480 memset(&link_params, 0, sizeof(link_params));
481 link_params.link_up = false;
482 edev->ops->common->set_link(edev->cdev, &link_params);
483 link_params.link_up = true;
484 edev->ops->common->set_link(edev->cdev, &link_params);
485
486 return 0;
487}
488
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200489static u32 qede_get_link(struct net_device *dev)
490{
491 struct qede_dev *edev = netdev_priv(dev);
492 struct qed_link_output current_link;
493
494 memset(&current_link, 0, sizeof(current_link));
495 edev->ops->common->get_link(edev->cdev, &current_link);
496
497 return current_link.link_up;
498}
499
Sudarsana Reddy Kallurud552fa82016-06-21 09:36:22 -0400500static int qede_get_coalesce(struct net_device *dev,
501 struct ethtool_coalesce *coal)
502{
503 struct qede_dev *edev = netdev_priv(dev);
Sudarsana Reddy Kallurud2890de2016-06-28 02:10:59 -0400504 u16 rxc, txc;
Sudarsana Reddy Kallurud552fa82016-06-21 09:36:22 -0400505
506 memset(coal, 0, sizeof(struct ethtool_coalesce));
Sudarsana Reddy Kallurud2890de2016-06-28 02:10:59 -0400507 edev->ops->common->get_coalesce(edev->cdev, &rxc, &txc);
508
509 coal->rx_coalesce_usecs = rxc;
510 coal->tx_coalesce_usecs = txc;
Sudarsana Reddy Kallurud552fa82016-06-21 09:36:22 -0400511
512 return 0;
513}
514
515static int qede_set_coalesce(struct net_device *dev,
516 struct ethtool_coalesce *coal)
517{
518 struct qede_dev *edev = netdev_priv(dev);
519 int i, rc = 0;
520 u16 rxc, txc;
521 u8 sb_id;
522
523 if (!netif_running(dev)) {
524 DP_INFO(edev, "Interface is down\n");
525 return -EINVAL;
526 }
527
528 if (coal->rx_coalesce_usecs > QED_COALESCE_MAX ||
529 coal->tx_coalesce_usecs > QED_COALESCE_MAX) {
530 DP_INFO(edev,
531 "Can't support requested %s coalesce value [max supported value %d]\n",
532 coal->rx_coalesce_usecs > QED_COALESCE_MAX ? "rx"
533 : "tx",
534 QED_COALESCE_MAX);
535 return -EINVAL;
536 }
537
538 rxc = (u16)coal->rx_coalesce_usecs;
539 txc = (u16)coal->tx_coalesce_usecs;
540 for_each_rss(i) {
541 sb_id = edev->fp_array[i].sb_info->igu_sb_id;
542 rc = edev->ops->common->set_coalesce(edev->cdev, rxc, txc,
543 (u8)i, sb_id);
544 if (rc) {
545 DP_INFO(edev, "Set coalesce error, rc = %d\n", rc);
546 return rc;
547 }
548 }
549
550 return rc;
551}
552
Sudarsana Kalluru01ef7e02015-11-30 12:25:02 +0200553static void qede_get_ringparam(struct net_device *dev,
554 struct ethtool_ringparam *ering)
555{
556 struct qede_dev *edev = netdev_priv(dev);
557
558 ering->rx_max_pending = NUM_RX_BDS_MAX;
559 ering->rx_pending = edev->q_num_rx_buffers;
560 ering->tx_max_pending = NUM_TX_BDS_MAX;
561 ering->tx_pending = edev->q_num_tx_buffers;
562}
563
564static int qede_set_ringparam(struct net_device *dev,
565 struct ethtool_ringparam *ering)
566{
567 struct qede_dev *edev = netdev_priv(dev);
568
569 DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
570 "Set ring params command parameters: rx_pending = %d, tx_pending = %d\n",
571 ering->rx_pending, ering->tx_pending);
572
573 /* Validate legality of configuration */
574 if (ering->rx_pending > NUM_RX_BDS_MAX ||
575 ering->rx_pending < NUM_RX_BDS_MIN ||
576 ering->tx_pending > NUM_TX_BDS_MAX ||
577 ering->tx_pending < NUM_TX_BDS_MIN) {
578 DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
579 "Can only support Rx Buffer size [0%08x,...,0x%08x] and Tx Buffer size [0x%08x,...,0x%08x]\n",
580 NUM_RX_BDS_MIN, NUM_RX_BDS_MAX,
581 NUM_TX_BDS_MIN, NUM_TX_BDS_MAX);
582 return -EINVAL;
583 }
584
585 /* Change ring size and re-load */
586 edev->q_num_rx_buffers = ering->rx_pending;
587 edev->q_num_tx_buffers = ering->tx_pending;
588
589 if (netif_running(edev->ndev))
590 qede_reload(edev, NULL, NULL);
591
592 return 0;
593}
594
Sudarsana Kalluru0f7db142015-11-30 12:25:06 +0200595static void qede_get_pauseparam(struct net_device *dev,
596 struct ethtool_pauseparam *epause)
597{
598 struct qede_dev *edev = netdev_priv(dev);
599 struct qed_link_output current_link;
600
601 memset(&current_link, 0, sizeof(current_link));
602 edev->ops->common->get_link(edev->cdev, &current_link);
603
604 if (current_link.pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE)
605 epause->autoneg = true;
606 if (current_link.pause_config & QED_LINK_PAUSE_RX_ENABLE)
607 epause->rx_pause = true;
608 if (current_link.pause_config & QED_LINK_PAUSE_TX_ENABLE)
609 epause->tx_pause = true;
610
611 DP_VERBOSE(edev, QED_MSG_DEBUG,
612 "ethtool_pauseparam: cmd %d autoneg %d rx_pause %d tx_pause %d\n",
613 epause->cmd, epause->autoneg, epause->rx_pause,
614 epause->tx_pause);
615}
616
617static int qede_set_pauseparam(struct net_device *dev,
618 struct ethtool_pauseparam *epause)
619{
620 struct qede_dev *edev = netdev_priv(dev);
621 struct qed_link_params params;
622 struct qed_link_output current_link;
623
Yuval Mintzfe7cd2b2016-04-22 08:41:03 +0300624 if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
Sudarsana Kalluru0f7db142015-11-30 12:25:06 +0200625 DP_INFO(edev,
Yuval Mintzfe7cd2b2016-04-22 08:41:03 +0300626 "Pause settings are not allowed to be changed\n");
Sudarsana Kalluru0f7db142015-11-30 12:25:06 +0200627 return -EOPNOTSUPP;
628 }
629
630 memset(&current_link, 0, sizeof(current_link));
631 edev->ops->common->get_link(edev->cdev, &current_link);
632
633 memset(&params, 0, sizeof(params));
634 params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG;
635 if (epause->autoneg) {
636 if (!(current_link.supported_caps & SUPPORTED_Autoneg)) {
637 DP_INFO(edev, "autoneg not supported\n");
638 return -EINVAL;
639 }
640 params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE;
641 }
642 if (epause->rx_pause)
643 params.pause_config |= QED_LINK_PAUSE_RX_ENABLE;
644 if (epause->tx_pause)
645 params.pause_config |= QED_LINK_PAUSE_TX_ENABLE;
646
647 params.link_up = true;
648 edev->ops->common->set_link(edev->cdev, &params);
649
650 return 0;
651}
652
Sudarsana Kalluru133fac02015-10-26 11:02:34 +0200653static void qede_update_mtu(struct qede_dev *edev, union qede_reload_args *args)
654{
655 edev->ndev->mtu = args->mtu;
656}
657
658/* Netdevice NDOs */
659#define ETH_MAX_JUMBO_PACKET_SIZE 9600
660#define ETH_MIN_PACKET_SIZE 60
661int qede_change_mtu(struct net_device *ndev, int new_mtu)
662{
663 struct qede_dev *edev = netdev_priv(ndev);
664 union qede_reload_args args;
665
666 if ((new_mtu > ETH_MAX_JUMBO_PACKET_SIZE) ||
667 ((new_mtu + ETH_HLEN) < ETH_MIN_PACKET_SIZE)) {
668 DP_ERR(edev, "Can't support requested MTU size\n");
669 return -EINVAL;
670 }
671
672 DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
673 "Configuring MTU size of %d\n", new_mtu);
674
675 /* Set the mtu field and re-start the interface if needed*/
676 args.mtu = new_mtu;
677
678 if (netif_running(edev->ndev))
679 qede_reload(edev, &qede_update_mtu, &args);
680
681 qede_update_mtu(edev, &args);
682
683 return 0;
684}
685
Sudarsana Kalluru8edf0492015-11-30 12:25:01 +0200686static void qede_get_channels(struct net_device *dev,
687 struct ethtool_channels *channels)
688{
689 struct qede_dev *edev = netdev_priv(dev);
690
691 channels->max_combined = QEDE_MAX_RSS_CNT(edev);
692 channels->combined_count = QEDE_RSS_CNT(edev);
693}
694
695static int qede_set_channels(struct net_device *dev,
696 struct ethtool_channels *channels)
697{
698 struct qede_dev *edev = netdev_priv(dev);
699
700 DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
701 "set-channels command parameters: rx = %d, tx = %d, other = %d, combined = %d\n",
702 channels->rx_count, channels->tx_count,
703 channels->other_count, channels->combined_count);
704
705 /* We don't support separate rx / tx, nor `other' channels. */
706 if (channels->rx_count || channels->tx_count ||
707 channels->other_count || (channels->combined_count == 0) ||
708 (channels->combined_count > QEDE_MAX_RSS_CNT(edev))) {
709 DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
710 "command parameters not supported\n");
711 return -EINVAL;
712 }
713
714 /* Check if there was a change in the active parameters */
715 if (channels->combined_count == QEDE_RSS_CNT(edev)) {
716 DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
717 "No change in active parameters\n");
718 return 0;
719 }
720
721 /* We need the number of queues to be divisible between the hwfns */
722 if (channels->combined_count % edev->dev_info.common.num_hwfns) {
723 DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN),
724 "Number of channels must be divisable by %04x\n",
725 edev->dev_info.common.num_hwfns);
726 return -EINVAL;
727 }
728
729 /* Set number of queues and reload if necessary */
730 edev->req_rss = channels->combined_count;
731 if (netif_running(dev))
732 qede_reload(edev, NULL, NULL);
733
734 return 0;
735}
736
Sudarsana Kalluru3d971cb2015-11-30 12:25:04 +0200737static int qede_set_phys_id(struct net_device *dev,
738 enum ethtool_phys_id_state state)
739{
740 struct qede_dev *edev = netdev_priv(dev);
741 u8 led_state = 0;
742
743 switch (state) {
744 case ETHTOOL_ID_ACTIVE:
745 return 1; /* cycle on/off once per second */
746
747 case ETHTOOL_ID_ON:
748 led_state = QED_LED_MODE_ON;
749 break;
750
751 case ETHTOOL_ID_OFF:
752 led_state = QED_LED_MODE_OFF;
753 break;
754
755 case ETHTOOL_ID_INACTIVE:
756 led_state = QED_LED_MODE_RESTORE;
757 break;
758 }
759
760 edev->ops->common->set_led(edev->cdev, led_state);
761
762 return 0;
763}
764
Sudarsana Reddy Kalluru961acde2016-04-10 12:43:01 +0300765static int qede_get_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
766{
767 info->data = RXH_IP_SRC | RXH_IP_DST;
768
769 switch (info->flow_type) {
770 case TCP_V4_FLOW:
771 case TCP_V6_FLOW:
772 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
773 break;
774 case UDP_V4_FLOW:
775 if (edev->rss_params.rss_caps & QED_RSS_IPV4_UDP)
776 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
777 break;
778 case UDP_V6_FLOW:
779 if (edev->rss_params.rss_caps & QED_RSS_IPV6_UDP)
780 info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
781 break;
782 case IPV4_FLOW:
783 case IPV6_FLOW:
784 break;
785 default:
786 info->data = 0;
787 break;
788 }
789
790 return 0;
791}
792
793static int qede_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
794 u32 *rules __always_unused)
795{
796 struct qede_dev *edev = netdev_priv(dev);
797
798 switch (info->cmd) {
799 case ETHTOOL_GRXRINGS:
800 info->data = edev->num_rss;
801 return 0;
802 case ETHTOOL_GRXFH:
803 return qede_get_rss_flags(edev, info);
804 default:
805 DP_ERR(edev, "Command parameters not supported\n");
806 return -EOPNOTSUPP;
807 }
808}
809
810static int qede_set_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
811{
812 struct qed_update_vport_params vport_update_params;
813 u8 set_caps = 0, clr_caps = 0;
814
815 DP_VERBOSE(edev, QED_MSG_DEBUG,
816 "Set rss flags command parameters: flow type = %d, data = %llu\n",
817 info->flow_type, info->data);
818
819 switch (info->flow_type) {
820 case TCP_V4_FLOW:
821 case TCP_V6_FLOW:
822 /* For TCP only 4-tuple hash is supported */
823 if (info->data ^ (RXH_IP_SRC | RXH_IP_DST |
824 RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
825 DP_INFO(edev, "Command parameters not supported\n");
826 return -EINVAL;
827 }
828 return 0;
829 case UDP_V4_FLOW:
830 /* For UDP either 2-tuple hash or 4-tuple hash is supported */
831 if (info->data == (RXH_IP_SRC | RXH_IP_DST |
832 RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
833 set_caps = QED_RSS_IPV4_UDP;
834 DP_VERBOSE(edev, QED_MSG_DEBUG,
835 "UDP 4-tuple enabled\n");
836 } else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
837 clr_caps = QED_RSS_IPV4_UDP;
838 DP_VERBOSE(edev, QED_MSG_DEBUG,
839 "UDP 4-tuple disabled\n");
840 } else {
841 return -EINVAL;
842 }
843 break;
844 case UDP_V6_FLOW:
845 /* For UDP either 2-tuple hash or 4-tuple hash is supported */
846 if (info->data == (RXH_IP_SRC | RXH_IP_DST |
847 RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
848 set_caps = QED_RSS_IPV6_UDP;
849 DP_VERBOSE(edev, QED_MSG_DEBUG,
850 "UDP 4-tuple enabled\n");
851 } else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
852 clr_caps = QED_RSS_IPV6_UDP;
853 DP_VERBOSE(edev, QED_MSG_DEBUG,
854 "UDP 4-tuple disabled\n");
855 } else {
856 return -EINVAL;
857 }
858 break;
859 case IPV4_FLOW:
860 case IPV6_FLOW:
861 /* For IP only 2-tuple hash is supported */
862 if (info->data ^ (RXH_IP_SRC | RXH_IP_DST)) {
863 DP_INFO(edev, "Command parameters not supported\n");
864 return -EINVAL;
865 }
866 return 0;
867 case SCTP_V4_FLOW:
868 case AH_ESP_V4_FLOW:
869 case AH_V4_FLOW:
870 case ESP_V4_FLOW:
871 case SCTP_V6_FLOW:
872 case AH_ESP_V6_FLOW:
873 case AH_V6_FLOW:
874 case ESP_V6_FLOW:
875 case IP_USER_FLOW:
876 case ETHER_FLOW:
877 /* RSS is not supported for these protocols */
878 if (info->data) {
879 DP_INFO(edev, "Command parameters not supported\n");
880 return -EINVAL;
881 }
882 return 0;
883 default:
884 return -EINVAL;
885 }
886
887 /* No action is needed if there is no change in the rss capability */
888 if (edev->rss_params.rss_caps == ((edev->rss_params.rss_caps &
889 ~clr_caps) | set_caps))
890 return 0;
891
892 /* Update internal configuration */
893 edev->rss_params.rss_caps = (edev->rss_params.rss_caps & ~clr_caps) |
894 set_caps;
895 edev->rss_params_inited |= QEDE_RSS_CAPS_INITED;
896
897 /* Re-configure if possible */
898 if (netif_running(edev->ndev)) {
899 memset(&vport_update_params, 0, sizeof(vport_update_params));
900 vport_update_params.update_rss_flg = 1;
901 vport_update_params.vport_id = 0;
902 memcpy(&vport_update_params.rss_params, &edev->rss_params,
903 sizeof(vport_update_params.rss_params));
904 return edev->ops->vport_update(edev->cdev,
905 &vport_update_params);
906 }
907
908 return 0;
909}
910
911static int qede_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
912{
913 struct qede_dev *edev = netdev_priv(dev);
914
915 switch (info->cmd) {
916 case ETHTOOL_SRXFH:
917 return qede_set_rss_flags(edev, info);
918 default:
919 DP_INFO(edev, "Command parameters not supported\n");
920 return -EOPNOTSUPP;
921 }
922}
923
924static u32 qede_get_rxfh_indir_size(struct net_device *dev)
925{
926 return QED_RSS_IND_TABLE_SIZE;
927}
928
929static u32 qede_get_rxfh_key_size(struct net_device *dev)
930{
931 struct qede_dev *edev = netdev_priv(dev);
932
933 return sizeof(edev->rss_params.rss_key);
934}
935
936static int qede_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc)
937{
938 struct qede_dev *edev = netdev_priv(dev);
939 int i;
940
941 if (hfunc)
942 *hfunc = ETH_RSS_HASH_TOP;
943
944 if (!indir)
945 return 0;
946
947 for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++)
948 indir[i] = edev->rss_params.rss_ind_table[i];
949
950 if (key)
951 memcpy(key, edev->rss_params.rss_key,
952 qede_get_rxfh_key_size(dev));
953
954 return 0;
955}
956
957static int qede_set_rxfh(struct net_device *dev, const u32 *indir,
958 const u8 *key, const u8 hfunc)
959{
960 struct qed_update_vport_params vport_update_params;
961 struct qede_dev *edev = netdev_priv(dev);
962 int i;
963
964 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
965 return -EOPNOTSUPP;
966
967 if (!indir && !key)
968 return 0;
969
970 if (indir) {
971 for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++)
972 edev->rss_params.rss_ind_table[i] = indir[i];
973 edev->rss_params_inited |= QEDE_RSS_INDIR_INITED;
974 }
975
976 if (key) {
977 memcpy(&edev->rss_params.rss_key, key,
978 qede_get_rxfh_key_size(dev));
979 edev->rss_params_inited |= QEDE_RSS_KEY_INITED;
980 }
981
982 if (netif_running(edev->ndev)) {
983 memset(&vport_update_params, 0, sizeof(vport_update_params));
984 vport_update_params.update_rss_flg = 1;
985 vport_update_params.vport_id = 0;
986 memcpy(&vport_update_params.rss_params, &edev->rss_params,
987 sizeof(vport_update_params.rss_params));
988 return edev->ops->vport_update(edev->cdev,
989 &vport_update_params);
990 }
991
992 return 0;
993}
994
Sudarsana Reddy Kalluru16f46bf2016-04-28 20:20:54 -0400995/* This function enables the interrupt generation and the NAPI on the device */
996static void qede_netif_start(struct qede_dev *edev)
997{
998 int i;
999
1000 if (!netif_running(edev->ndev))
1001 return;
1002
1003 for_each_rss(i) {
1004 /* Update and reenable interrupts */
1005 qed_sb_ack(edev->fp_array[i].sb_info, IGU_INT_ENABLE, 1);
1006 napi_enable(&edev->fp_array[i].napi);
1007 }
1008}
1009
1010/* This function disables the NAPI and the interrupt generation on the device */
1011static void qede_netif_stop(struct qede_dev *edev)
1012{
1013 int i;
1014
1015 for_each_rss(i) {
1016 napi_disable(&edev->fp_array[i].napi);
1017 /* Disable interrupts */
1018 qed_sb_ack(edev->fp_array[i].sb_info, IGU_INT_DISABLE, 0);
1019 }
1020}
1021
1022static int qede_selftest_transmit_traffic(struct qede_dev *edev,
1023 struct sk_buff *skb)
1024{
1025 struct qede_tx_queue *txq = &edev->fp_array[0].txqs[0];
1026 struct eth_tx_1st_bd *first_bd;
1027 dma_addr_t mapping;
1028 int i, idx, val;
1029
1030 /* Fill the entry in the SW ring and the BDs in the FW ring */
1031 idx = txq->sw_tx_prod & NUM_TX_BDS_MAX;
1032 txq->sw_tx_ring[idx].skb = skb;
1033 first_bd = qed_chain_produce(&txq->tx_pbl);
1034 memset(first_bd, 0, sizeof(*first_bd));
1035 val = 1 << ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT;
1036 first_bd->data.bd_flags.bitfields = val;
Yuval Mintz351a4ded2016-06-02 10:23:29 +03001037 val = skb->len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK;
1038 first_bd->data.bitfields |= (val << ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT);
Sudarsana Reddy Kalluru16f46bf2016-04-28 20:20:54 -04001039
1040 /* Map skb linear data for DMA and set in the first BD */
1041 mapping = dma_map_single(&edev->pdev->dev, skb->data,
1042 skb_headlen(skb), DMA_TO_DEVICE);
1043 if (unlikely(dma_mapping_error(&edev->pdev->dev, mapping))) {
1044 DP_NOTICE(edev, "SKB mapping failed\n");
1045 return -ENOMEM;
1046 }
1047 BD_SET_UNMAP_ADDR_LEN(first_bd, mapping, skb_headlen(skb));
1048
1049 /* update the first BD with the actual num BDs */
1050 first_bd->data.nbds = 1;
1051 txq->sw_tx_prod++;
1052 /* 'next page' entries are counted in the producer value */
1053 val = cpu_to_le16(qed_chain_get_prod_idx(&txq->tx_pbl));
1054 txq->tx_db.data.bd_prod = val;
1055
1056 /* wmb makes sure that the BDs data is updated before updating the
1057 * producer, otherwise FW may read old data from the BDs.
1058 */
1059 wmb();
1060 barrier();
1061 writel(txq->tx_db.raw, txq->doorbell_addr);
1062
1063 /* mmiowb is needed to synchronize doorbell writes from more than one
1064 * processor. It guarantees that the write arrives to the device before
1065 * the queue lock is released and another start_xmit is called (possibly
1066 * on another CPU). Without this barrier, the next doorbell can bypass
1067 * this doorbell. This is applicable to IA64/Altix systems.
1068 */
1069 mmiowb();
1070
1071 for (i = 0; i < QEDE_SELFTEST_POLL_COUNT; i++) {
1072 if (qede_txq_has_work(txq))
1073 break;
1074 usleep_range(100, 200);
1075 }
1076
1077 if (!qede_txq_has_work(txq)) {
1078 DP_NOTICE(edev, "Tx completion didn't happen\n");
1079 return -1;
1080 }
1081
1082 first_bd = (struct eth_tx_1st_bd *)qed_chain_consume(&txq->tx_pbl);
1083 dma_unmap_page(&edev->pdev->dev, BD_UNMAP_ADDR(first_bd),
1084 BD_UNMAP_LEN(first_bd), DMA_TO_DEVICE);
1085 txq->sw_tx_cons++;
1086 txq->sw_tx_ring[idx].skb = NULL;
1087
1088 return 0;
1089}
1090
1091static int qede_selftest_receive_traffic(struct qede_dev *edev)
1092{
1093 struct qede_rx_queue *rxq = edev->fp_array[0].rxq;
1094 u16 hw_comp_cons, sw_comp_cons, sw_rx_index, len;
1095 struct eth_fast_path_rx_reg_cqe *fp_cqe;
1096 struct sw_rx_data *sw_rx_data;
1097 union eth_rx_cqe *cqe;
1098 u8 *data_ptr;
1099 int i;
1100
1101 /* The packet is expected to receive on rx-queue 0 even though RSS is
1102 * enabled. This is because the queue 0 is configured as the default
1103 * queue and that the loopback traffic is not IP.
1104 */
1105 for (i = 0; i < QEDE_SELFTEST_POLL_COUNT; i++) {
1106 if (qede_has_rx_work(rxq))
1107 break;
1108 usleep_range(100, 200);
1109 }
1110
1111 if (!qede_has_rx_work(rxq)) {
1112 DP_NOTICE(edev, "Failed to receive the traffic\n");
1113 return -1;
1114 }
1115
1116 hw_comp_cons = le16_to_cpu(*rxq->hw_cons_ptr);
1117 sw_comp_cons = qed_chain_get_cons_idx(&rxq->rx_comp_ring);
1118
1119 /* Memory barrier to prevent the CPU from doing speculative reads of CQE
1120 * / BD before reading hw_comp_cons. If the CQE is read before it is
1121 * written by FW, then FW writes CQE and SB, and then the CPU reads the
1122 * hw_comp_cons, it will use an old CQE.
1123 */
1124 rmb();
1125
1126 /* Get the CQE from the completion ring */
1127 cqe = (union eth_rx_cqe *)qed_chain_consume(&rxq->rx_comp_ring);
1128
1129 /* Get the data from the SW ring */
1130 sw_rx_index = rxq->sw_rx_cons & NUM_RX_BDS_MAX;
1131 sw_rx_data = &rxq->sw_rx_ring[sw_rx_index];
1132 fp_cqe = &cqe->fast_path_regular;
1133 len = le16_to_cpu(fp_cqe->len_on_first_bd);
1134 data_ptr = (u8 *)(page_address(sw_rx_data->data) +
1135 fp_cqe->placement_offset + sw_rx_data->page_offset);
1136 for (i = ETH_HLEN; i < len; i++)
1137 if (data_ptr[i] != (unsigned char)(i & 0xff)) {
1138 DP_NOTICE(edev, "Loopback test failed\n");
1139 qede_recycle_rx_bd_ring(rxq, edev, 1);
1140 return -1;
1141 }
1142
1143 qede_recycle_rx_bd_ring(rxq, edev, 1);
1144
1145 return 0;
1146}
1147
1148static int qede_selftest_run_loopback(struct qede_dev *edev, u32 loopback_mode)
1149{
1150 struct qed_link_params link_params;
1151 struct sk_buff *skb = NULL;
1152 int rc = 0, i;
1153 u32 pkt_size;
1154 u8 *packet;
1155
1156 if (!netif_running(edev->ndev)) {
1157 DP_NOTICE(edev, "Interface is down\n");
1158 return -EINVAL;
1159 }
1160
1161 qede_netif_stop(edev);
1162
1163 /* Bring up the link in Loopback mode */
1164 memset(&link_params, 0, sizeof(link_params));
1165 link_params.link_up = true;
1166 link_params.override_flags = QED_LINK_OVERRIDE_LOOPBACK_MODE;
1167 link_params.loopback_mode = loopback_mode;
1168 edev->ops->common->set_link(edev->cdev, &link_params);
1169
1170 /* Wait for loopback configuration to apply */
1171 msleep_interruptible(500);
1172
1173 /* prepare the loopback packet */
1174 pkt_size = edev->ndev->mtu + ETH_HLEN;
1175
1176 skb = netdev_alloc_skb(edev->ndev, pkt_size);
1177 if (!skb) {
1178 DP_INFO(edev, "Can't allocate skb\n");
1179 rc = -ENOMEM;
1180 goto test_loopback_exit;
1181 }
1182 packet = skb_put(skb, pkt_size);
1183 ether_addr_copy(packet, edev->ndev->dev_addr);
1184 ether_addr_copy(packet + ETH_ALEN, edev->ndev->dev_addr);
1185 memset(packet + (2 * ETH_ALEN), 0x77, (ETH_HLEN - (2 * ETH_ALEN)));
1186 for (i = ETH_HLEN; i < pkt_size; i++)
1187 packet[i] = (unsigned char)(i & 0xff);
1188
1189 rc = qede_selftest_transmit_traffic(edev, skb);
1190 if (rc)
1191 goto test_loopback_exit;
1192
1193 rc = qede_selftest_receive_traffic(edev);
1194 if (rc)
1195 goto test_loopback_exit;
1196
1197 DP_VERBOSE(edev, NETIF_MSG_RX_STATUS, "Loopback test successful\n");
1198
1199test_loopback_exit:
1200 dev_kfree_skb(skb);
1201
1202 /* Bring up the link in Normal mode */
1203 memset(&link_params, 0, sizeof(link_params));
1204 link_params.link_up = true;
1205 link_params.override_flags = QED_LINK_OVERRIDE_LOOPBACK_MODE;
1206 link_params.loopback_mode = QED_LINK_LOOPBACK_NONE;
1207 edev->ops->common->set_link(edev->cdev, &link_params);
1208
1209 /* Wait for loopback configuration to apply */
1210 msleep_interruptible(500);
1211
1212 qede_netif_start(edev);
1213
1214 return rc;
1215}
1216
Sudarsana Reddy Kalluru3044a022016-04-28 20:20:53 -04001217static void qede_self_test(struct net_device *dev,
1218 struct ethtool_test *etest, u64 *buf)
1219{
1220 struct qede_dev *edev = netdev_priv(dev);
1221
1222 DP_VERBOSE(edev, QED_MSG_DEBUG,
1223 "Self-test command parameters: offline = %d, external_lb = %d\n",
1224 (etest->flags & ETH_TEST_FL_OFFLINE),
1225 (etest->flags & ETH_TEST_FL_EXTERNAL_LB) >> 2);
1226
1227 memset(buf, 0, sizeof(u64) * QEDE_ETHTOOL_TEST_MAX);
1228
Sudarsana Reddy Kalluru16f46bf2016-04-28 20:20:54 -04001229 if (etest->flags & ETH_TEST_FL_OFFLINE) {
1230 if (qede_selftest_run_loopback(edev,
1231 QED_LINK_LOOPBACK_INT_PHY)) {
1232 buf[QEDE_ETHTOOL_INT_LOOPBACK] = 1;
1233 etest->flags |= ETH_TEST_FL_FAILED;
1234 }
1235 }
1236
Sudarsana Reddy Kalluru3044a022016-04-28 20:20:53 -04001237 if (edev->ops->common->selftest->selftest_interrupt(edev->cdev)) {
1238 buf[QEDE_ETHTOOL_INTERRUPT_TEST] = 1;
1239 etest->flags |= ETH_TEST_FL_FAILED;
1240 }
1241
1242 if (edev->ops->common->selftest->selftest_memory(edev->cdev)) {
1243 buf[QEDE_ETHTOOL_MEMORY_TEST] = 1;
1244 etest->flags |= ETH_TEST_FL_FAILED;
1245 }
1246
1247 if (edev->ops->common->selftest->selftest_register(edev->cdev)) {
1248 buf[QEDE_ETHTOOL_REGISTER_TEST] = 1;
1249 etest->flags |= ETH_TEST_FL_FAILED;
1250 }
1251
1252 if (edev->ops->common->selftest->selftest_clock(edev->cdev)) {
1253 buf[QEDE_ETHTOOL_CLOCK_TEST] = 1;
1254 etest->flags |= ETH_TEST_FL_FAILED;
1255 }
1256}
1257
Manish Chopra3d789992016-06-30 02:35:21 -04001258static int qede_set_tunable(struct net_device *dev,
1259 const struct ethtool_tunable *tuna,
1260 const void *data)
1261{
1262 struct qede_dev *edev = netdev_priv(dev);
1263 u32 val;
1264
1265 switch (tuna->id) {
1266 case ETHTOOL_RX_COPYBREAK:
1267 val = *(u32 *)data;
1268 if (val < QEDE_MIN_PKT_LEN || val > QEDE_RX_HDR_SIZE) {
1269 DP_VERBOSE(edev, QED_MSG_DEBUG,
1270 "Invalid rx copy break value, range is [%u, %u]",
1271 QEDE_MIN_PKT_LEN, QEDE_RX_HDR_SIZE);
1272 return -EINVAL;
1273 }
1274
1275 edev->rx_copybreak = *(u32 *)data;
1276 break;
1277 default:
1278 return -EOPNOTSUPP;
1279 }
1280
1281 return 0;
1282}
1283
1284static int qede_get_tunable(struct net_device *dev,
1285 const struct ethtool_tunable *tuna, void *data)
1286{
1287 struct qede_dev *edev = netdev_priv(dev);
1288
1289 switch (tuna->id) {
1290 case ETHTOOL_RX_COPYBREAK:
1291 *(u32 *)data = edev->rx_copybreak;
1292 break;
1293 default:
1294 return -EOPNOTSUPP;
1295 }
1296
1297 return 0;
1298}
1299
Sudarsana Kalluru133fac02015-10-26 11:02:34 +02001300static const struct ethtool_ops qede_ethtool_ops = {
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -04001301 .get_link_ksettings = qede_get_link_ksettings,
1302 .set_link_ksettings = qede_set_link_ksettings,
Sudarsana Kalluru133fac02015-10-26 11:02:34 +02001303 .get_drvinfo = qede_get_drvinfo,
1304 .get_msglevel = qede_get_msglevel,
1305 .set_msglevel = qede_set_msglevel,
Sudarsana Kalluru32a7a572015-11-30 12:25:05 +02001306 .nway_reset = qede_nway_reset,
Sudarsana Kalluru133fac02015-10-26 11:02:34 +02001307 .get_link = qede_get_link,
Sudarsana Reddy Kallurud552fa82016-06-21 09:36:22 -04001308 .get_coalesce = qede_get_coalesce,
1309 .set_coalesce = qede_set_coalesce,
Sudarsana Kalluru01ef7e02015-11-30 12:25:02 +02001310 .get_ringparam = qede_get_ringparam,
1311 .set_ringparam = qede_set_ringparam,
Sudarsana Kalluru0f7db142015-11-30 12:25:06 +02001312 .get_pauseparam = qede_get_pauseparam,
1313 .set_pauseparam = qede_set_pauseparam,
Sudarsana Kalluru133fac02015-10-26 11:02:34 +02001314 .get_strings = qede_get_strings,
Sudarsana Kalluru3d971cb2015-11-30 12:25:04 +02001315 .set_phys_id = qede_set_phys_id,
Sudarsana Kalluru133fac02015-10-26 11:02:34 +02001316 .get_ethtool_stats = qede_get_ethtool_stats,
Yuval Mintzf3e72102016-04-22 08:41:02 +03001317 .get_priv_flags = qede_get_priv_flags,
Sudarsana Kalluru133fac02015-10-26 11:02:34 +02001318 .get_sset_count = qede_get_sset_count,
Sudarsana Reddy Kalluru961acde2016-04-10 12:43:01 +03001319 .get_rxnfc = qede_get_rxnfc,
1320 .set_rxnfc = qede_set_rxnfc,
1321 .get_rxfh_indir_size = qede_get_rxfh_indir_size,
1322 .get_rxfh_key_size = qede_get_rxfh_key_size,
1323 .get_rxfh = qede_get_rxfh,
1324 .set_rxfh = qede_set_rxfh,
Sudarsana Kalluru8edf0492015-11-30 12:25:01 +02001325 .get_channels = qede_get_channels,
1326 .set_channels = qede_set_channels,
Sudarsana Reddy Kalluru3044a022016-04-28 20:20:53 -04001327 .self_test = qede_self_test,
Manish Chopra3d789992016-06-30 02:35:21 -04001328 .get_tunable = qede_get_tunable,
1329 .set_tunable = qede_set_tunable,
Sudarsana Kalluru133fac02015-10-26 11:02:34 +02001330};
1331
Yuval Mintzfefb0202016-05-11 16:36:19 +03001332static const struct ethtool_ops qede_vf_ethtool_ops = {
Sudarsana Reddy Kalluru054c67d2016-08-09 03:51:23 -04001333 .get_link_ksettings = qede_get_link_ksettings,
Yuval Mintzfefb0202016-05-11 16:36:19 +03001334 .get_drvinfo = qede_get_drvinfo,
1335 .get_msglevel = qede_get_msglevel,
1336 .set_msglevel = qede_set_msglevel,
1337 .get_link = qede_get_link,
1338 .get_ringparam = qede_get_ringparam,
1339 .set_ringparam = qede_set_ringparam,
1340 .get_strings = qede_get_strings,
1341 .get_ethtool_stats = qede_get_ethtool_stats,
1342 .get_priv_flags = qede_get_priv_flags,
1343 .get_sset_count = qede_get_sset_count,
1344 .get_rxnfc = qede_get_rxnfc,
1345 .set_rxnfc = qede_set_rxnfc,
1346 .get_rxfh_indir_size = qede_get_rxfh_indir_size,
1347 .get_rxfh_key_size = qede_get_rxfh_key_size,
1348 .get_rxfh = qede_get_rxfh,
1349 .set_rxfh = qede_set_rxfh,
1350 .get_channels = qede_get_channels,
1351 .set_channels = qede_set_channels,
Manish Chopra3d789992016-06-30 02:35:21 -04001352 .get_tunable = qede_get_tunable,
1353 .set_tunable = qede_set_tunable,
Yuval Mintzfefb0202016-05-11 16:36:19 +03001354};
1355
Sudarsana Kalluru133fac02015-10-26 11:02:34 +02001356void qede_set_ethtool_ops(struct net_device *dev)
1357{
Yuval Mintzfefb0202016-05-11 16:36:19 +03001358 struct qede_dev *edev = netdev_priv(dev);
1359
1360 if (IS_VF(edev))
1361 dev->ethtool_ops = &qede_vf_ethtool_ops;
1362 else
1363 dev->ethtool_ops = &qede_ethtool_ops;
Sudarsana Kalluru133fac02015-10-26 11:02:34 +02001364}