blob: fb29a64b9e51826e8250159663f5bf23f01499bd [file] [log] [blame]
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001/**********************************************************************
2* Author: Cavium, Inc.
3*
4* Contact: support@cavium.com
5* Please include "LiquidIO" in the subject.
6*
7* Copyright (c) 2003-2015 Cavium, Inc.
8*
9* This file is free software; you can redistribute it and/or modify
10* it under the terms of the GNU General Public License, Version 2, as
11* published by the Free Software Foundation.
12*
13* This file is distributed in the hope that it will be useful, but
14* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16* NONINFRINGEMENT. See the GNU General Public License for more
17* details.
18*
19* This file may also be available under a different license from Cavium.
20* Contact Cavium, Inc. for more information
21**********************************************************************/
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -070022#include <linux/netdevice.h>
23#include <linux/net_tstamp.h>
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -070024#include <linux/pci.h>
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -070025#include "liquidio_common.h"
26#include "octeon_droq.h"
27#include "octeon_iq.h"
28#include "response_manager.h"
29#include "octeon_device.h"
30#include "octeon_nic.h"
31#include "octeon_main.h"
32#include "octeon_network.h"
33#include "cn66xx_regs.h"
34#include "cn66xx_device.h"
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -070035#include "cn23xx_pf_device.h"
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -070036
Raghu Vatsavayi1f164712016-06-21 22:53:11 -070037static int octnet_get_link_stats(struct net_device *netdev);
38
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -070039struct oct_mdio_cmd_context {
40 int octeon_id;
41 wait_queue_head_t wc;
42 int cond;
43};
44
45struct oct_mdio_cmd_resp {
46 u64 rh;
47 struct oct_mdio_cmd resp;
48 u64 status;
49};
50
51#define OCT_MDIO45_RESP_SIZE (sizeof(struct oct_mdio_cmd_resp))
52
53/* Octeon's interface mode of operation */
54enum {
55 INTERFACE_MODE_DISABLED,
56 INTERFACE_MODE_RGMII,
57 INTERFACE_MODE_GMII,
58 INTERFACE_MODE_SPI,
59 INTERFACE_MODE_PCIE,
60 INTERFACE_MODE_XAUI,
61 INTERFACE_MODE_SGMII,
62 INTERFACE_MODE_PICMG,
63 INTERFACE_MODE_NPI,
64 INTERFACE_MODE_LOOP,
65 INTERFACE_MODE_SRIO,
66 INTERFACE_MODE_ILK,
67 INTERFACE_MODE_RXAUI,
68 INTERFACE_MODE_QSGMII,
69 INTERFACE_MODE_AGL,
Raghu Vatsavayi9eb60842016-06-21 22:53:12 -070070 INTERFACE_MODE_XLAUI,
71 INTERFACE_MODE_XFI,
72 INTERFACE_MODE_10G_KR,
73 INTERFACE_MODE_40G_KR4,
74 INTERFACE_MODE_MIXED,
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -070075};
76
77#define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
78#define OCT_ETHTOOL_REGDUMP_LEN 4096
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -070079#define OCT_ETHTOOL_REGDUMP_LEN_23XX (4096 * 11)
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -070080#define OCT_ETHTOOL_REGSVER 1
81
Raghu Vatsavayi1f164712016-06-21 22:53:11 -070082/* statistics of PF */
83static const char oct_stats_strings[][ETH_GSTRING_LEN] = {
84 "rx_packets",
85 "tx_packets",
86 "rx_bytes",
87 "tx_bytes",
88 "rx_errors", /*jabber_err+l2_err+frame_err */
89 "tx_errors", /*fw_err_pko+fw_err_link+fw_err_drop */
90 "rx_dropped", /*st->fromwire.total_rcvd - st->fromwire.fw_total_rcvd
91 *+st->fromwire.dmac_drop + st->fromwire.fw_err_drop
92 */
93 "tx_dropped",
94
95 "tx_total_sent",
96 "tx_total_fwd",
97 "tx_err_pko",
98 "tx_err_link",
99 "tx_err_drop",
100
101 "tx_tso",
102 "tx_tso_packets",
103 "tx_tso_err",
Raghu Vatsavayi01fb2372016-07-03 13:56:47 -0700104 "tx_vxlan",
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700105
106 "mac_tx_total_pkts",
107 "mac_tx_total_bytes",
108 "mac_tx_mcast_pkts",
109 "mac_tx_bcast_pkts",
110 "mac_tx_ctl_packets", /*oct->link_stats.fromhost.ctl_sent */
111 "mac_tx_total_collisions",
112 "mac_tx_one_collision",
113 "mac_tx_multi_collison",
114 "mac_tx_max_collision_fail",
115 "mac_tx_max_deferal_fail",
116 "mac_tx_fifo_err",
117 "mac_tx_runts",
118
119 "rx_total_rcvd",
120 "rx_total_fwd",
121 "rx_jabber_err",
122 "rx_l2_err",
123 "rx_frame_err",
124 "rx_err_pko",
125 "rx_err_link",
126 "rx_err_drop",
127
Raghu Vatsavayi01fb2372016-07-03 13:56:47 -0700128 "rx_vxlan",
129 "rx_vxlan_err",
130
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700131 "rx_lro_pkts",
132 "rx_lro_bytes",
133 "rx_total_lro",
134
135 "rx_lro_aborts",
136 "rx_lro_aborts_port",
137 "rx_lro_aborts_seq",
138 "rx_lro_aborts_tsval",
139 "rx_lro_aborts_timer",
140 "rx_fwd_rate",
141
142 "mac_rx_total_rcvd",
143 "mac_rx_bytes",
144 "mac_rx_total_bcst",
145 "mac_rx_total_mcst",
146 "mac_rx_runts",
147 "mac_rx_ctl_packets",
148 "mac_rx_fifo_err",
149 "mac_rx_dma_drop",
150 "mac_rx_fcs_err",
151
152 "link_state_changes",
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700153};
154
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700155/* statistics of host tx queue */
156static const char oct_iq_stats_strings[][ETH_GSTRING_LEN] = {
157 "packets", /*oct->instr_queue[iq_no]->stats.tx_done*/
158 "bytes", /*oct->instr_queue[iq_no]->stats.tx_tot_bytes*/
159 "dropped",
160 "iq_busy",
161 "sgentry_sent",
162
163 "fw_instr_posted",
164 "fw_instr_processed",
165 "fw_instr_dropped",
166 "fw_bytes_sent",
167
168 "tso",
Raghu Vatsavayi01fb2372016-07-03 13:56:47 -0700169 "vxlan",
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700170 "txq_restart",
171};
172
173/* statistics of host rx queue */
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700174static const char oct_droq_stats_strings[][ETH_GSTRING_LEN] = {
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700175 "packets", /*oct->droq[oq_no]->stats.rx_pkts_received */
176 "bytes", /*oct->droq[oq_no]->stats.rx_bytes_received */
177 "dropped", /*oct->droq[oq_no]->stats.rx_dropped+
178 *oct->droq[oq_no]->stats.dropped_nodispatch+
179 *oct->droq[oq_no]->stats.dropped_toomany+
180 *oct->droq[oq_no]->stats.dropped_nomem
181 */
182 "dropped_nomem",
183 "dropped_toomany",
184 "fw_dropped",
185 "fw_pkts_received",
186 "fw_bytes_received",
187 "fw_dropped_nodispatch",
188
Raghu Vatsavayi01fb2372016-07-03 13:56:47 -0700189 "vxlan",
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700190 "buffer_alloc_failure",
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700191};
192
193#define OCTNIC_NCMD_AUTONEG_ON 0x1
194#define OCTNIC_NCMD_PHY_ON 0x2
195
196static int lio_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
197{
198 struct lio *lio = GET_LIO(netdev);
199 struct octeon_device *oct = lio->oct_dev;
200 struct oct_link_info *linfo;
201
202 linfo = &lio->linfo;
203
Raghu Vatsavayi9eb60842016-06-21 22:53:12 -0700204 if (linfo->link.s.if_mode == INTERFACE_MODE_XAUI ||
205 linfo->link.s.if_mode == INTERFACE_MODE_RXAUI ||
206 linfo->link.s.if_mode == INTERFACE_MODE_XFI) {
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700207 ecmd->port = PORT_FIBRE;
208 ecmd->supported =
209 (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE |
210 SUPPORTED_Pause);
211 ecmd->advertising =
212 (ADVERTISED_10000baseT_Full | ADVERTISED_Pause);
213 ecmd->transceiver = XCVR_EXTERNAL;
214 ecmd->autoneg = AUTONEG_DISABLE;
215
216 } else {
Raghu Vatsavayi9eb60842016-06-21 22:53:12 -0700217 dev_err(&oct->pci_dev->dev, "Unknown link interface reported %d\n",
218 linfo->link.s.if_mode);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700219 }
220
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -0700221 if (linfo->link.s.link_up) {
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700222 ethtool_cmd_speed_set(ecmd, linfo->link.s.speed);
223 ecmd->duplex = linfo->link.s.duplex;
224 } else {
225 ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
226 ecmd->duplex = DUPLEX_UNKNOWN;
227 }
228
229 return 0;
230}
231
232static void
233lio_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
234{
235 struct lio *lio;
236 struct octeon_device *oct;
237
238 lio = GET_LIO(netdev);
239 oct = lio->oct_dev;
240
241 memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
242 strcpy(drvinfo->driver, "liquidio");
243 strcpy(drvinfo->version, LIQUIDIO_VERSION);
244 strncpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version,
245 ETHTOOL_FWVERS_LEN);
246 strncpy(drvinfo->bus_info, pci_name(oct->pci_dev), 32);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700247}
248
249static void
250lio_ethtool_get_channels(struct net_device *dev,
251 struct ethtool_channels *channel)
252{
253 struct lio *lio = GET_LIO(dev);
254 struct octeon_device *oct = lio->oct_dev;
255 u32 max_rx = 0, max_tx = 0, tx_count = 0, rx_count = 0;
256
257 if (OCTEON_CN6XXX(oct)) {
258 struct octeon_config *conf6x = CHIP_FIELD(oct, cn6xxx, conf);
259
260 max_rx = CFG_GET_OQ_MAX_Q(conf6x);
261 max_tx = CFG_GET_IQ_MAX_Q(conf6x);
262 rx_count = CFG_GET_NUM_RXQS_NIC_IF(conf6x, lio->ifidx);
263 tx_count = CFG_GET_NUM_TXQS_NIC_IF(conf6x, lio->ifidx);
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -0700264 } else if (OCTEON_CN23XX_PF(oct)) {
265 struct octeon_config *conf23 = CHIP_FIELD(oct, cn23xx_pf, conf);
266
267 max_rx = CFG_GET_OQ_MAX_Q(conf23);
268 max_tx = CFG_GET_IQ_MAX_Q(conf23);
269 rx_count = CFG_GET_NUM_RXQS_NIC_IF(conf23, lio->ifidx);
270 tx_count = CFG_GET_NUM_TXQS_NIC_IF(conf23, lio->ifidx);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700271 }
272
273 channel->max_rx = max_rx;
274 channel->max_tx = max_tx;
275 channel->rx_count = rx_count;
276 channel->tx_count = tx_count;
277}
278
279static int lio_get_eeprom_len(struct net_device *netdev)
280{
281 u8 buf[128];
282 struct lio *lio = GET_LIO(netdev);
283 struct octeon_device *oct_dev = lio->oct_dev;
284 struct octeon_board_info *board_info;
285 int len;
286
287 board_info = (struct octeon_board_info *)(&oct_dev->boardinfo);
288 len = sprintf(buf, "boardname:%s serialnum:%s maj:%lld min:%lld\n",
289 board_info->name, board_info->serial_number,
290 board_info->major, board_info->minor);
291
292 return len;
293}
294
295static int
296lio_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
297 u8 *bytes)
298{
299 struct lio *lio = GET_LIO(netdev);
300 struct octeon_device *oct_dev = lio->oct_dev;
301 struct octeon_board_info *board_info;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700302
Raghu Vatsavayi32581242016-08-31 11:03:20 -0700303 if (eeprom->offset)
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700304 return -EINVAL;
305
306 eeprom->magic = oct_dev->pci_dev->vendor;
307 board_info = (struct octeon_board_info *)(&oct_dev->boardinfo);
Raghu Vatsavayi32581242016-08-31 11:03:20 -0700308 sprintf((char *)bytes,
309 "boardname:%s serialnum:%s maj:%lld min:%lld\n",
310 board_info->name, board_info->serial_number,
311 board_info->major, board_info->minor);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700312
313 return 0;
314}
315
316static int octnet_gpio_access(struct net_device *netdev, int addr, int val)
317{
318 struct lio *lio = GET_LIO(netdev);
319 struct octeon_device *oct = lio->oct_dev;
320 struct octnic_ctrl_pkt nctrl;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700321 int ret = 0;
322
323 memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
324
325 nctrl.ncmd.u64 = 0;
326 nctrl.ncmd.s.cmd = OCTNET_CMD_GPIO_ACCESS;
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -0700327 nctrl.ncmd.s.param1 = addr;
328 nctrl.ncmd.s.param2 = val;
329 nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700330 nctrl.wait_time = 100;
331 nctrl.netpndev = (u64)netdev;
332 nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
333
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -0700334 ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700335 if (ret < 0) {
336 dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n");
337 return -EINVAL;
338 }
339
340 return 0;
341}
342
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -0700343static int octnet_id_active(struct net_device *netdev, int val)
344{
345 struct lio *lio = GET_LIO(netdev);
346 struct octeon_device *oct = lio->oct_dev;
347 struct octnic_ctrl_pkt nctrl;
348 int ret = 0;
349
350 memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
351
352 nctrl.ncmd.u64 = 0;
353 nctrl.ncmd.s.cmd = OCTNET_CMD_ID_ACTIVE;
354 nctrl.ncmd.s.param1 = val;
355 nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
356 nctrl.wait_time = 100;
357 nctrl.netpndev = (u64)netdev;
358 nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
359
360 ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
361 if (ret < 0) {
362 dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n");
363 return -EINVAL;
364 }
365
366 return 0;
367}
368
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700369/* Callback for when mdio command response arrives
370 */
371static void octnet_mdio_resp_callback(struct octeon_device *oct,
372 u32 status,
373 void *buf)
374{
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700375 struct oct_mdio_cmd_context *mdio_cmd_ctx;
376 struct octeon_soft_command *sc = (struct octeon_soft_command *)buf;
377
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700378 mdio_cmd_ctx = (struct oct_mdio_cmd_context *)sc->ctxptr;
379
380 oct = lio_get_device(mdio_cmd_ctx->octeon_id);
381 if (status) {
382 dev_err(&oct->pci_dev->dev, "MIDO instruction failed. Status: %llx\n",
383 CVM_CAST64(status));
Raghu Vatsavayia7d5a3d2016-07-03 13:56:48 -0700384 WRITE_ONCE(mdio_cmd_ctx->cond, -1);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700385 } else {
Raghu Vatsavayia7d5a3d2016-07-03 13:56:48 -0700386 WRITE_ONCE(mdio_cmd_ctx->cond, 1);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700387 }
388 wake_up_interruptible(&mdio_cmd_ctx->wc);
389}
390
391/* This routine provides PHY access routines for
392 * mdio clause45 .
393 */
394static int
395octnet_mdio45_access(struct lio *lio, int op, int loc, int *value)
396{
397 struct octeon_device *oct_dev = lio->oct_dev;
398 struct octeon_soft_command *sc;
399 struct oct_mdio_cmd_resp *mdio_cmd_rsp;
400 struct oct_mdio_cmd_context *mdio_cmd_ctx;
401 struct oct_mdio_cmd *mdio_cmd;
402 int retval = 0;
403
404 sc = (struct octeon_soft_command *)
405 octeon_alloc_soft_command(oct_dev,
406 sizeof(struct oct_mdio_cmd),
407 sizeof(struct oct_mdio_cmd_resp),
408 sizeof(struct oct_mdio_cmd_context));
409
410 if (!sc)
411 return -ENOMEM;
412
413 mdio_cmd_ctx = (struct oct_mdio_cmd_context *)sc->ctxptr;
414 mdio_cmd_rsp = (struct oct_mdio_cmd_resp *)sc->virtrptr;
415 mdio_cmd = (struct oct_mdio_cmd *)sc->virtdptr;
416
Raghu Vatsavayia7d5a3d2016-07-03 13:56:48 -0700417 WRITE_ONCE(mdio_cmd_ctx->cond, 0);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700418 mdio_cmd_ctx->octeon_id = lio_get_device_id(oct_dev);
419 mdio_cmd->op = op;
420 mdio_cmd->mdio_addr = loc;
421 if (op)
422 mdio_cmd->value1 = *value;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700423 octeon_swap_8B_data((u64 *)mdio_cmd, sizeof(struct oct_mdio_cmd) / 8);
424
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -0700425 sc->iq_no = lio->linfo.txpciq[0].s.q_no;
426
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700427 octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, OPCODE_NIC_MDIO45,
428 0, 0, 0);
429
430 sc->wait_time = 1000;
431 sc->callback = octnet_mdio_resp_callback;
432 sc->callback_arg = sc;
433
434 init_waitqueue_head(&mdio_cmd_ctx->wc);
435
436 retval = octeon_send_soft_command(oct_dev, sc);
437
Raghu Vatsavayiddc173a2016-06-14 16:54:43 -0700438 if (retval == IQ_SEND_FAILED) {
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700439 dev_err(&oct_dev->pci_dev->dev,
440 "octnet_mdio45_access instruction failed status: %x\n",
441 retval);
Raghu Vatsavayi32581242016-08-31 11:03:20 -0700442 retval = -EBUSY;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700443 } else {
444 /* Sleep on a wait queue till the cond flag indicates that the
445 * response arrived
446 */
447 sleep_cond(&mdio_cmd_ctx->wc, &mdio_cmd_ctx->cond);
448 retval = mdio_cmd_rsp->status;
449 if (retval) {
450 dev_err(&oct_dev->pci_dev->dev, "octnet mdio45 access failed\n");
451 retval = -EBUSY;
452 } else {
453 octeon_swap_8B_data((u64 *)(&mdio_cmd_rsp->resp),
454 sizeof(struct oct_mdio_cmd) / 8);
455
Raghu Vatsavayia7d5a3d2016-07-03 13:56:48 -0700456 if (READ_ONCE(mdio_cmd_ctx->cond) == 1) {
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700457 if (!op)
458 *value = mdio_cmd_rsp->resp.value1;
459 } else {
460 retval = -EINVAL;
461 }
462 }
463 }
464
465 octeon_free_soft_command(oct_dev, sc);
466
467 return retval;
468}
469
470static int lio_set_phys_id(struct net_device *netdev,
471 enum ethtool_phys_id_state state)
472{
473 struct lio *lio = GET_LIO(netdev);
474 struct octeon_device *oct = lio->oct_dev;
475 int value, ret;
476
477 switch (state) {
478 case ETHTOOL_ID_ACTIVE:
479 if (oct->chip_id == OCTEON_CN66XX) {
480 octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
481 VITESSE_PHY_GPIO_DRIVEON);
482 return 2;
483
484 } else if (oct->chip_id == OCTEON_CN68XX) {
485 /* Save the current LED settings */
486 ret = octnet_mdio45_access(lio, 0,
487 LIO68XX_LED_BEACON_ADDR,
488 &lio->phy_beacon_val);
489 if (ret)
490 return ret;
491
492 ret = octnet_mdio45_access(lio, 0,
493 LIO68XX_LED_CTRL_ADDR,
494 &lio->led_ctrl_val);
495 if (ret)
496 return ret;
497
498 /* Configure Beacon values */
499 value = LIO68XX_LED_BEACON_CFGON;
Raghu Vatsavayia2c64b62016-07-03 13:56:55 -0700500 ret = octnet_mdio45_access(lio, 1,
501 LIO68XX_LED_BEACON_ADDR,
502 &value);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700503 if (ret)
504 return ret;
505
506 value = LIO68XX_LED_CTRL_CFGON;
Raghu Vatsavayia2c64b62016-07-03 13:56:55 -0700507 ret = octnet_mdio45_access(lio, 1,
508 LIO68XX_LED_CTRL_ADDR,
509 &value);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700510 if (ret)
511 return ret;
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -0700512 } else if (oct->chip_id == OCTEON_CN23XX_PF_VID) {
513 octnet_id_active(netdev, LED_IDENTIFICATION_ON);
514
515 /* returns 0 since updates are asynchronous */
516 return 0;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700517 } else {
518 return -EINVAL;
519 }
520 break;
521
522 case ETHTOOL_ID_ON:
523 if (oct->chip_id == OCTEON_CN66XX) {
524 octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
525 VITESSE_PHY_GPIO_HIGH);
526
527 } else if (oct->chip_id == OCTEON_CN68XX) {
528 return -EINVAL;
529 } else {
530 return -EINVAL;
531 }
532 break;
533
534 case ETHTOOL_ID_OFF:
535 if (oct->chip_id == OCTEON_CN66XX)
536 octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
537 VITESSE_PHY_GPIO_LOW);
538 else if (oct->chip_id == OCTEON_CN68XX)
539 return -EINVAL;
540 else
541 return -EINVAL;
542
543 break;
544
545 case ETHTOOL_ID_INACTIVE:
546 if (oct->chip_id == OCTEON_CN66XX) {
547 octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
548 VITESSE_PHY_GPIO_DRIVEOFF);
549 } else if (oct->chip_id == OCTEON_CN68XX) {
550 /* Restore LED settings */
551 ret = octnet_mdio45_access(lio, 1,
552 LIO68XX_LED_CTRL_ADDR,
553 &lio->led_ctrl_val);
554 if (ret)
555 return ret;
556
Dan Carpentercbdb9772015-06-24 17:47:02 +0300557 ret = octnet_mdio45_access(lio, 1,
558 LIO68XX_LED_BEACON_ADDR,
559 &lio->phy_beacon_val);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700560 if (ret)
561 return ret;
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -0700562 } else if (oct->chip_id == OCTEON_CN23XX_PF_VID) {
563 octnet_id_active(netdev, LED_IDENTIFICATION_OFF);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700564
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -0700565 return 0;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700566 } else {
567 return -EINVAL;
568 }
569 break;
570
571 default:
572 return -EINVAL;
573 }
574
575 return 0;
576}
577
578static void
579lio_ethtool_get_ringparam(struct net_device *netdev,
580 struct ethtool_ringparam *ering)
581{
582 struct lio *lio = GET_LIO(netdev);
583 struct octeon_device *oct = lio->oct_dev;
584 u32 tx_max_pending = 0, rx_max_pending = 0, tx_pending = 0,
585 rx_pending = 0;
586
587 if (OCTEON_CN6XXX(oct)) {
588 struct octeon_config *conf6x = CHIP_FIELD(oct, cn6xxx, conf);
589
590 tx_max_pending = CN6XXX_MAX_IQ_DESCRIPTORS;
591 rx_max_pending = CN6XXX_MAX_OQ_DESCRIPTORS;
592 rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf6x, lio->ifidx);
593 tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf6x, lio->ifidx);
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -0700594 } else if (OCTEON_CN23XX_PF(oct)) {
595 struct octeon_config *conf23 = CHIP_FIELD(oct, cn23xx_pf, conf);
596
597 tx_max_pending = CN23XX_MAX_IQ_DESCRIPTORS;
598 rx_max_pending = CN23XX_MAX_OQ_DESCRIPTORS;
599 rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf23, lio->ifidx);
600 tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf23, lio->ifidx);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700601 }
602
Raghu Vatsavayi4c2743f2016-07-03 13:56:53 -0700603 if (lio->mtu > OCTNET_DEFAULT_FRM_SIZE - OCTNET_FRM_HEADER_SIZE) {
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700604 ering->rx_pending = 0;
605 ering->rx_max_pending = 0;
606 ering->rx_mini_pending = 0;
607 ering->rx_jumbo_pending = rx_pending;
608 ering->rx_mini_max_pending = 0;
609 ering->rx_jumbo_max_pending = rx_max_pending;
610 } else {
611 ering->rx_pending = rx_pending;
612 ering->rx_max_pending = rx_max_pending;
613 ering->rx_mini_pending = 0;
614 ering->rx_jumbo_pending = 0;
615 ering->rx_mini_max_pending = 0;
616 ering->rx_jumbo_max_pending = 0;
617 }
618
619 ering->tx_pending = tx_pending;
620 ering->tx_max_pending = tx_max_pending;
621}
622
623static u32 lio_get_msglevel(struct net_device *netdev)
624{
625 struct lio *lio = GET_LIO(netdev);
626
627 return lio->msg_enable;
628}
629
630static void lio_set_msglevel(struct net_device *netdev, u32 msglvl)
631{
632 struct lio *lio = GET_LIO(netdev);
633
634 if ((msglvl ^ lio->msg_enable) & NETIF_MSG_HW) {
635 if (msglvl & NETIF_MSG_HW)
636 liquidio_set_feature(netdev,
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -0700637 OCTNET_CMD_VERBOSE_ENABLE, 0);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700638 else
639 liquidio_set_feature(netdev,
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -0700640 OCTNET_CMD_VERBOSE_DISABLE, 0);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700641 }
642
643 lio->msg_enable = msglvl;
644}
645
646static void
647lio_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
648{
649 /* Notes: Not supporting any auto negotiation in these
650 * drivers. Just report pause frame support.
651 */
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700652 struct lio *lio = GET_LIO(netdev);
653 struct octeon_device *oct = lio->oct_dev;
654
655 pause->autoneg = 0;
656
657 pause->tx_pause = oct->tx_pause;
658 pause->rx_pause = oct->rx_pause;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700659}
660
661static void
662lio_get_ethtool_stats(struct net_device *netdev,
Raghu Vatsavayia7d5a3d2016-07-03 13:56:48 -0700663 struct ethtool_stats *stats __attribute__((unused)),
664 u64 *data)
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700665{
666 struct lio *lio = GET_LIO(netdev);
667 struct octeon_device *oct_dev = lio->oct_dev;
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700668 struct net_device_stats *netstats = &netdev->stats;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700669 int i = 0, j;
670
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700671 netdev->netdev_ops->ndo_get_stats(netdev);
672 octnet_get_link_stats(netdev);
673
674 /*sum of oct->droq[oq_no]->stats->rx_pkts_received */
675 data[i++] = CVM_CAST64(netstats->rx_packets);
676 /*sum of oct->instr_queue[iq_no]->stats.tx_done */
677 data[i++] = CVM_CAST64(netstats->tx_packets);
678 /*sum of oct->droq[oq_no]->stats->rx_bytes_received */
679 data[i++] = CVM_CAST64(netstats->rx_bytes);
680 /*sum of oct->instr_queue[iq_no]->stats.tx_tot_bytes */
681 data[i++] = CVM_CAST64(netstats->tx_bytes);
682 data[i++] = CVM_CAST64(netstats->rx_errors);
683 data[i++] = CVM_CAST64(netstats->tx_errors);
684 /*sum of oct->droq[oq_no]->stats->rx_dropped +
685 *oct->droq[oq_no]->stats->dropped_nodispatch +
686 *oct->droq[oq_no]->stats->dropped_toomany +
687 *oct->droq[oq_no]->stats->dropped_nomem
688 */
689 data[i++] = CVM_CAST64(netstats->rx_dropped);
690 /*sum of oct->instr_queue[iq_no]->stats.tx_dropped */
691 data[i++] = CVM_CAST64(netstats->tx_dropped);
692
693 /*data[i++] = CVM_CAST64(stats->multicast); */
694 /*data[i++] = CVM_CAST64(stats->collisions); */
695
696 /* firmware tx stats */
697 /*per_core_stats[cvmx_get_core_num()].link_stats[mdata->from_ifidx].
698 *fromhost.fw_total_sent
699 */
700 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_total_sent);
701 /*per_core_stats[i].link_stats[port].fromwire.fw_total_fwd */
702 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_total_fwd);
703 /*per_core_stats[j].link_stats[i].fromhost.fw_err_pko */
704 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_pko);
705 /*per_core_stats[j].link_stats[i].fromhost.fw_err_link */
706 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_link);
707 /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.
708 *fw_err_drop
709 */
710 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_drop);
711
712 /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.fw_tso */
713 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tso);
714 /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.
715 *fw_tso_fwd
716 */
717 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tso_fwd);
718 /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.
719 *fw_err_tso
720 */
721 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_tso);
Raghu Vatsavayi01fb2372016-07-03 13:56:47 -0700722 /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.
723 *fw_tx_vxlan
724 */
725 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tx_vxlan);
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700726
727 /* mac tx statistics */
728 /*CVMX_BGXX_CMRX_TX_STAT5 */
729 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_pkts_sent);
730 /*CVMX_BGXX_CMRX_TX_STAT4 */
731 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_bytes_sent);
732 /*CVMX_BGXX_CMRX_TX_STAT15 */
733 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.mcast_pkts_sent);
734 /*CVMX_BGXX_CMRX_TX_STAT14 */
735 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.bcast_pkts_sent);
736 /*CVMX_BGXX_CMRX_TX_STAT17 */
737 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.ctl_sent);
738 /*CVMX_BGXX_CMRX_TX_STAT0 */
739 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_collisions);
740 /*CVMX_BGXX_CMRX_TX_STAT3 */
741 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.one_collision_sent);
742 /*CVMX_BGXX_CMRX_TX_STAT2 */
743 data[i++] =
744 CVM_CAST64(oct_dev->link_stats.fromhost.multi_collision_sent);
745 /*CVMX_BGXX_CMRX_TX_STAT0 */
746 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.max_collision_fail);
747 /*CVMX_BGXX_CMRX_TX_STAT1 */
748 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.max_deferral_fail);
749 /*CVMX_BGXX_CMRX_TX_STAT16 */
750 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fifo_err);
751 /*CVMX_BGXX_CMRX_TX_STAT6 */
752 data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.runts);
753
754 /* RX firmware stats */
755 /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
756 *fw_total_rcvd
757 */
758 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_rcvd);
759 /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
760 *fw_total_fwd
761 */
762 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_fwd);
763 /*per_core_stats[core_id].link_stats[ifidx].fromwire.jabber_err */
764 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.jabber_err);
765 /*per_core_stats[core_id].link_stats[ifidx].fromwire.l2_err */
766 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.l2_err);
767 /*per_core_stats[core_id].link_stats[ifidx].fromwire.frame_err */
768 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.frame_err);
769 /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
770 *fw_err_pko
771 */
772 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_pko);
773 /*per_core_stats[j].link_stats[i].fromwire.fw_err_link */
774 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_link);
775 /*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx].
776 *fromwire.fw_err_drop
777 */
778 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_drop);
779
Raghu Vatsavayi01fb2372016-07-03 13:56:47 -0700780 /*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx].
781 *fromwire.fw_rx_vxlan
782 */
783 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_rx_vxlan);
784 /*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx].
785 *fromwire.fw_rx_vxlan_err
786 */
787 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_rx_vxlan_err);
788
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700789 /* LRO */
790 /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
791 *fw_lro_pkts
792 */
793 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_pkts);
794 /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
795 *fw_lro_octs
796 */
797 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_octs);
798 /*per_core_stats[j].link_stats[i].fromwire.fw_total_lro */
799 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_lro);
800 /*per_core_stats[j].link_stats[i].fromwire.fw_lro_aborts */
801 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts);
802 /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
803 *fw_lro_aborts_port
804 */
805 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_port);
806 /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
807 *fw_lro_aborts_seq
808 */
809 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_seq);
810 /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
811 *fw_lro_aborts_tsval
812 */
813 data[i++] =
814 CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_tsval);
815 /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire.
816 *fw_lro_aborts_timer
817 */
818 /* intrmod: packet forward rate */
819 data[i++] =
820 CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_timer);
821 /*per_core_stats[j].link_stats[i].fromwire.fw_lro_aborts */
822 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fwd_rate);
823
824 /* mac: link-level stats */
825 /*CVMX_BGXX_CMRX_RX_STAT0 */
826 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_rcvd);
827 /*CVMX_BGXX_CMRX_RX_STAT1 */
828 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.bytes_rcvd);
829 /*CVMX_PKI_STATX_STAT5 */
830 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_bcst);
831 /*CVMX_PKI_STATX_STAT5 */
832 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_mcst);
833 /*wqe->word2.err_code or wqe->word2.err_level */
834 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.runts);
835 /*CVMX_BGXX_CMRX_RX_STAT2 */
836 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.ctl_rcvd);
837 /*CVMX_BGXX_CMRX_RX_STAT6 */
838 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fifo_err);
839 /*CVMX_BGXX_CMRX_RX_STAT4 */
840 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.dmac_drop);
841 /*wqe->word2.err_code or wqe->word2.err_level */
842 data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fcs_err);
843 /*lio->link_changes*/
844 data[i++] = CVM_CAST64(lio->link_changes);
845
846 /* TX -- lio_update_stats(lio); */
847 for (j = 0; j < MAX_OCTEON_INSTR_QUEUES(oct_dev); j++) {
Raghu Vatsavayi63da8402016-06-21 22:53:03 -0700848 if (!(oct_dev->io_qmask.iq & (1ULL << j)))
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700849 continue;
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700850 /*packets to network port*/
851 /*# of packets tx to network */
852 data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_done);
853 /*# of bytes tx to network */
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700854 data[i++] =
855 CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_tot_bytes);
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700856 /*# of packets dropped */
857 data[i++] =
858 CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_dropped);
859 /*# of tx fails due to queue full */
860 data[i++] =
861 CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_iq_busy);
862 /*XXX gather entries sent */
863 data[i++] =
864 CVM_CAST64(oct_dev->instr_queue[j]->stats.sgentry_sent);
865
866 /*instruction to firmware: data and control */
867 /*# of instructions to the queue */
868 data[i++] =
869 CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_posted);
870 /*# of instructions processed */
871 data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->
872 stats.instr_processed);
873 /*# of instructions could not be processed */
874 data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->
875 stats.instr_dropped);
876 /*bytes sent through the queue */
877 data[i++] =
878 CVM_CAST64(oct_dev->instr_queue[j]->stats.bytes_sent);
879
880 /*tso request*/
881 data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_gso);
Raghu Vatsavayi01fb2372016-07-03 13:56:47 -0700882 /*vxlan request*/
883 data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_vxlan);
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700884 /*txq restart*/
885 data[i++] =
886 CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_restart);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700887 }
888
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700889 /* RX */
890 /* for (j = 0; j < oct_dev->num_oqs; j++) { */
891 for (j = 0; j < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); j++) {
Raghu Vatsavayi63da8402016-06-21 22:53:03 -0700892 if (!(oct_dev->io_qmask.oq & (1ULL << j)))
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700893 continue;
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700894
895 /*packets send to TCP/IP network stack */
896 /*# of packets to network stack */
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700897 data[i++] =
898 CVM_CAST64(oct_dev->droq[j]->stats.rx_pkts_received);
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700899 /*# of bytes to network stack */
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700900 data[i++] =
901 CVM_CAST64(oct_dev->droq[j]->stats.rx_bytes_received);
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700902 /*# of packets dropped */
903 data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem +
904 oct_dev->droq[j]->stats.dropped_toomany +
905 oct_dev->droq[j]->stats.rx_dropped);
906 data[i++] =
907 CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem);
908 data[i++] =
909 CVM_CAST64(oct_dev->droq[j]->stats.dropped_toomany);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700910 data[i++] =
911 CVM_CAST64(oct_dev->droq[j]->stats.rx_dropped);
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700912
913 /*control and data path*/
914 data[i++] =
915 CVM_CAST64(oct_dev->droq[j]->stats.pkts_received);
916 data[i++] =
917 CVM_CAST64(oct_dev->droq[j]->stats.bytes_received);
918 data[i++] =
919 CVM_CAST64(oct_dev->droq[j]->stats.dropped_nodispatch);
Raghu Vatsavayi01fb2372016-07-03 13:56:47 -0700920
921 data[i++] =
922 CVM_CAST64(oct_dev->droq[j]->stats.rx_vxlan);
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700923 data[i++] =
924 CVM_CAST64(oct_dev->droq[j]->stats.rx_alloc_failure);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700925 }
926}
927
928static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
929{
930 struct lio *lio = GET_LIO(netdev);
931 struct octeon_device *oct_dev = lio->oct_dev;
932 int num_iq_stats, num_oq_stats, i, j;
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700933 int num_stats;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700934
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700935 switch (stringset) {
936 case ETH_SS_STATS:
937 num_stats = ARRAY_SIZE(oct_stats_strings);
938 for (j = 0; j < num_stats; j++) {
939 sprintf(data, "%s", oct_stats_strings[j]);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700940 data += ETH_GSTRING_LEN;
941 }
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700942
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700943 num_iq_stats = ARRAY_SIZE(oct_iq_stats_strings);
944 for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct_dev); i++) {
945 if (!(oct_dev->io_qmask.iq & (1ULL << i)))
946 continue;
947 for (j = 0; j < num_iq_stats; j++) {
948 sprintf(data, "tx-%d-%s", i,
949 oct_iq_stats_strings[j]);
950 data += ETH_GSTRING_LEN;
951 }
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700952 }
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700953
954 num_oq_stats = ARRAY_SIZE(oct_droq_stats_strings);
955 /* for (i = 0; i < oct_dev->num_oqs; i++) { */
956 for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); i++) {
957 if (!(oct_dev->io_qmask.oq & (1ULL << i)))
958 continue;
959 for (j = 0; j < num_oq_stats; j++) {
960 sprintf(data, "rx-%d-%s", i,
961 oct_droq_stats_strings[j]);
962 data += ETH_GSTRING_LEN;
963 }
964 }
965 break;
966
967 default:
968 netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n");
969 break;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700970 }
971}
972
973static int lio_get_sset_count(struct net_device *netdev, int sset)
974{
975 struct lio *lio = GET_LIO(netdev);
976 struct octeon_device *oct_dev = lio->oct_dev;
977
Raghu Vatsavayi1f164712016-06-21 22:53:11 -0700978 switch (sset) {
979 case ETH_SS_STATS:
980 return (ARRAY_SIZE(oct_stats_strings) +
981 ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs +
982 ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs);
983 default:
984 return -EOPNOTSUPP;
985 }
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700986}
987
988static int lio_get_intr_coalesce(struct net_device *netdev,
989 struct ethtool_coalesce *intr_coal)
990{
991 struct lio *lio = GET_LIO(netdev);
992 struct octeon_device *oct = lio->oct_dev;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -0700993 struct octeon_instr_queue *iq;
994 struct oct_intrmod_cfg *intrmod_cfg;
995
996 intrmod_cfg = &oct->intrmod;
997
998 switch (oct->chip_id) {
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -0700999 case OCTEON_CN23XX_PF_VID:
1000 if (!intrmod_cfg->rx_enable) {
1001 intr_coal->rx_coalesce_usecs = intrmod_cfg->rx_usecs;
1002 intr_coal->rx_max_coalesced_frames =
1003 intrmod_cfg->rx_frames;
1004 }
1005 if (!intrmod_cfg->tx_enable)
1006 intr_coal->tx_max_coalesced_frames =
1007 intrmod_cfg->tx_frames;
1008 break;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001009 case OCTEON_CN68XX:
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001010 case OCTEON_CN66XX: {
1011 struct octeon_cn6xxx *cn6xxx =
1012 (struct octeon_cn6xxx *)oct->chip;
1013
1014 if (!intrmod_cfg->rx_enable) {
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001015 intr_coal->rx_coalesce_usecs =
1016 CFG_GET_OQ_INTR_TIME(cn6xxx->conf);
1017 intr_coal->rx_max_coalesced_frames =
1018 CFG_GET_OQ_INTR_PKT(cn6xxx->conf);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001019 }
Raghu Vatsavayi26236fa2016-06-14 16:54:44 -07001020 iq = oct->instr_queue[lio->linfo.txpciq[0].s.q_no];
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001021 intr_coal->tx_max_coalesced_frames = iq->fill_threshold;
1022 break;
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001023 }
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001024 default:
1025 netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n");
1026 return -EINVAL;
1027 }
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001028 if (intrmod_cfg->rx_enable) {
1029 intr_coal->use_adaptive_rx_coalesce =
1030 intrmod_cfg->rx_enable;
1031 intr_coal->rate_sample_interval =
1032 intrmod_cfg->check_intrvl;
1033 intr_coal->pkt_rate_high =
1034 intrmod_cfg->maxpkt_ratethr;
1035 intr_coal->pkt_rate_low =
1036 intrmod_cfg->minpkt_ratethr;
1037 intr_coal->rx_max_coalesced_frames_high =
1038 intrmod_cfg->rx_maxcnt_trigger;
1039 intr_coal->rx_coalesce_usecs_high =
1040 intrmod_cfg->rx_maxtmr_trigger;
1041 intr_coal->rx_coalesce_usecs_low =
1042 intrmod_cfg->rx_mintmr_trigger;
1043 intr_coal->rx_max_coalesced_frames_low =
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -07001044 intrmod_cfg->rx_mincnt_trigger;
1045 }
1046 if (OCTEON_CN23XX_PF(oct) &&
1047 (intrmod_cfg->tx_enable)) {
1048 intr_coal->use_adaptive_tx_coalesce = intrmod_cfg->tx_enable;
1049 intr_coal->tx_max_coalesced_frames_high =
1050 intrmod_cfg->tx_maxcnt_trigger;
1051 intr_coal->tx_max_coalesced_frames_low =
1052 intrmod_cfg->tx_mincnt_trigger;
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001053 }
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001054 return 0;
1055}
1056
1057/* Callback function for intrmod */
1058static void octnet_intrmod_callback(struct octeon_device *oct_dev,
1059 u32 status,
1060 void *ptr)
1061{
1062 struct oct_intrmod_cmd *cmd = ptr;
1063 struct octeon_soft_command *sc = cmd->sc;
1064
1065 oct_dev = cmd->oct_dev;
1066
1067 if (status)
1068 dev_err(&oct_dev->pci_dev->dev, "intrmod config failed. Status: %llx\n",
1069 CVM_CAST64(status));
1070 else
1071 dev_info(&oct_dev->pci_dev->dev,
1072 "Rx-Adaptive Interrupt moderation enabled:%llx\n",
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001073 oct_dev->intrmod.rx_enable);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001074
1075 octeon_free_soft_command(oct_dev, sc);
1076}
1077
1078/* Configure interrupt moderation parameters */
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001079static int octnet_set_intrmod_cfg(struct lio *lio,
1080 struct oct_intrmod_cfg *intr_cfg)
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001081{
1082 struct octeon_soft_command *sc;
1083 struct oct_intrmod_cmd *cmd;
1084 struct oct_intrmod_cfg *cfg;
1085 int retval;
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001086 struct octeon_device *oct_dev = lio->oct_dev;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001087
1088 /* Alloc soft command */
1089 sc = (struct octeon_soft_command *)
1090 octeon_alloc_soft_command(oct_dev,
1091 sizeof(struct oct_intrmod_cfg),
1092 0,
1093 sizeof(struct oct_intrmod_cmd));
1094
1095 if (!sc)
1096 return -ENOMEM;
1097
1098 cmd = (struct oct_intrmod_cmd *)sc->ctxptr;
1099 cfg = (struct oct_intrmod_cfg *)sc->virtdptr;
1100
1101 memcpy(cfg, intr_cfg, sizeof(struct oct_intrmod_cfg));
1102 octeon_swap_8B_data((u64 *)cfg, (sizeof(struct oct_intrmod_cfg)) / 8);
1103 cmd->sc = sc;
1104 cmd->cfg = cfg;
1105 cmd->oct_dev = oct_dev;
1106
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001107 sc->iq_no = lio->linfo.txpciq[0].s.q_no;
1108
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001109 octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC,
1110 OPCODE_NIC_INTRMOD_CFG, 0, 0, 0);
1111
1112 sc->callback = octnet_intrmod_callback;
1113 sc->callback_arg = cmd;
1114 sc->wait_time = 1000;
1115
1116 retval = octeon_send_soft_command(oct_dev, sc);
Raghu Vatsavayiddc173a2016-06-14 16:54:43 -07001117 if (retval == IQ_SEND_FAILED) {
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001118 octeon_free_soft_command(oct_dev, sc);
1119 return -EINVAL;
1120 }
1121
1122 return 0;
1123}
1124
Raghu Vatsavayia7d5a3d2016-07-03 13:56:48 -07001125static void
Raghu Vatsavayi1f164712016-06-21 22:53:11 -07001126octnet_nic_stats_callback(struct octeon_device *oct_dev,
1127 u32 status, void *ptr)
1128{
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -07001129 struct octeon_soft_command *sc = (struct octeon_soft_command *)ptr;
1130 struct oct_nic_stats_resp *resp =
1131 (struct oct_nic_stats_resp *)sc->virtrptr;
1132 struct oct_nic_stats_ctrl *ctrl =
1133 (struct oct_nic_stats_ctrl *)sc->ctxptr;
Raghu Vatsavayi1f164712016-06-21 22:53:11 -07001134 struct nic_rx_stats *rsp_rstats = &resp->stats.fromwire;
1135 struct nic_tx_stats *rsp_tstats = &resp->stats.fromhost;
1136
1137 struct nic_rx_stats *rstats = &oct_dev->link_stats.fromwire;
1138 struct nic_tx_stats *tstats = &oct_dev->link_stats.fromhost;
1139
1140 if ((status != OCTEON_REQUEST_TIMEOUT) && !resp->status) {
1141 octeon_swap_8B_data((u64 *)&resp->stats,
1142 (sizeof(struct oct_link_stats)) >> 3);
1143
1144 /* RX link-level stats */
1145 rstats->total_rcvd = rsp_rstats->total_rcvd;
1146 rstats->bytes_rcvd = rsp_rstats->bytes_rcvd;
1147 rstats->total_bcst = rsp_rstats->total_bcst;
1148 rstats->total_mcst = rsp_rstats->total_mcst;
1149 rstats->runts = rsp_rstats->runts;
1150 rstats->ctl_rcvd = rsp_rstats->ctl_rcvd;
1151 /* Accounts for over/under-run of buffers */
1152 rstats->fifo_err = rsp_rstats->fifo_err;
1153 rstats->dmac_drop = rsp_rstats->dmac_drop;
1154 rstats->fcs_err = rsp_rstats->fcs_err;
1155 rstats->jabber_err = rsp_rstats->jabber_err;
1156 rstats->l2_err = rsp_rstats->l2_err;
1157 rstats->frame_err = rsp_rstats->frame_err;
1158
1159 /* RX firmware stats */
1160 rstats->fw_total_rcvd = rsp_rstats->fw_total_rcvd;
1161 rstats->fw_total_fwd = rsp_rstats->fw_total_fwd;
1162 rstats->fw_err_pko = rsp_rstats->fw_err_pko;
1163 rstats->fw_err_link = rsp_rstats->fw_err_link;
1164 rstats->fw_err_drop = rsp_rstats->fw_err_drop;
Raghu Vatsavayi01fb2372016-07-03 13:56:47 -07001165 rstats->fw_rx_vxlan = rsp_rstats->fw_rx_vxlan;
1166 rstats->fw_rx_vxlan_err = rsp_rstats->fw_rx_vxlan_err;
1167
Raghu Vatsavayi1f164712016-06-21 22:53:11 -07001168 /* Number of packets that are LROed */
1169 rstats->fw_lro_pkts = rsp_rstats->fw_lro_pkts;
1170 /* Number of octets that are LROed */
1171 rstats->fw_lro_octs = rsp_rstats->fw_lro_octs;
1172 /* Number of LRO packets formed */
1173 rstats->fw_total_lro = rsp_rstats->fw_total_lro;
1174 /* Number of times lRO of packet aborted */
1175 rstats->fw_lro_aborts = rsp_rstats->fw_lro_aborts;
1176 rstats->fw_lro_aborts_port = rsp_rstats->fw_lro_aborts_port;
1177 rstats->fw_lro_aborts_seq = rsp_rstats->fw_lro_aborts_seq;
1178 rstats->fw_lro_aborts_tsval = rsp_rstats->fw_lro_aborts_tsval;
1179 rstats->fw_lro_aborts_timer = rsp_rstats->fw_lro_aborts_timer;
1180 /* intrmod: packet forward rate */
1181 rstats->fwd_rate = rsp_rstats->fwd_rate;
1182
1183 /* TX link-level stats */
1184 tstats->total_pkts_sent = rsp_tstats->total_pkts_sent;
1185 tstats->total_bytes_sent = rsp_tstats->total_bytes_sent;
1186 tstats->mcast_pkts_sent = rsp_tstats->mcast_pkts_sent;
1187 tstats->bcast_pkts_sent = rsp_tstats->bcast_pkts_sent;
1188 tstats->ctl_sent = rsp_tstats->ctl_sent;
1189 /* Packets sent after one collision*/
1190 tstats->one_collision_sent = rsp_tstats->one_collision_sent;
1191 /* Packets sent after multiple collision*/
1192 tstats->multi_collision_sent = rsp_tstats->multi_collision_sent;
1193 /* Packets not sent due to max collisions */
1194 tstats->max_collision_fail = rsp_tstats->max_collision_fail;
1195 /* Packets not sent due to max deferrals */
1196 tstats->max_deferral_fail = rsp_tstats->max_deferral_fail;
1197 /* Accounts for over/under-run of buffers */
1198 tstats->fifo_err = rsp_tstats->fifo_err;
1199 tstats->runts = rsp_tstats->runts;
1200 /* Total number of collisions detected */
1201 tstats->total_collisions = rsp_tstats->total_collisions;
1202
1203 /* firmware stats */
1204 tstats->fw_total_sent = rsp_tstats->fw_total_sent;
1205 tstats->fw_total_fwd = rsp_tstats->fw_total_fwd;
1206 tstats->fw_err_pko = rsp_tstats->fw_err_pko;
1207 tstats->fw_err_link = rsp_tstats->fw_err_link;
1208 tstats->fw_err_drop = rsp_tstats->fw_err_drop;
1209 tstats->fw_tso = rsp_tstats->fw_tso;
1210 tstats->fw_tso_fwd = rsp_tstats->fw_tso_fwd;
1211 tstats->fw_err_tso = rsp_tstats->fw_err_tso;
Raghu Vatsavayi01fb2372016-07-03 13:56:47 -07001212 tstats->fw_tx_vxlan = rsp_tstats->fw_tx_vxlan;
1213
Raghu Vatsavayi1f164712016-06-21 22:53:11 -07001214 resp->status = 1;
1215 } else {
1216 resp->status = -1;
1217 }
1218 complete(&ctrl->complete);
1219}
1220
1221/* Configure interrupt moderation parameters */
1222static int octnet_get_link_stats(struct net_device *netdev)
1223{
1224 struct lio *lio = GET_LIO(netdev);
1225 struct octeon_device *oct_dev = lio->oct_dev;
1226
1227 struct octeon_soft_command *sc;
1228 struct oct_nic_stats_ctrl *ctrl;
1229 struct oct_nic_stats_resp *resp;
1230
1231 int retval;
1232
1233 /* Alloc soft command */
1234 sc = (struct octeon_soft_command *)
1235 octeon_alloc_soft_command(oct_dev,
1236 0,
1237 sizeof(struct oct_nic_stats_resp),
1238 sizeof(struct octnic_ctrl_pkt));
1239
1240 if (!sc)
1241 return -ENOMEM;
1242
1243 resp = (struct oct_nic_stats_resp *)sc->virtrptr;
1244 memset(resp, 0, sizeof(struct oct_nic_stats_resp));
1245
1246 ctrl = (struct oct_nic_stats_ctrl *)sc->ctxptr;
1247 memset(ctrl, 0, sizeof(struct oct_nic_stats_ctrl));
1248 ctrl->netdev = netdev;
1249 init_completion(&ctrl->complete);
1250
1251 sc->iq_no = lio->linfo.txpciq[0].s.q_no;
1252
1253 octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC,
1254 OPCODE_NIC_PORT_STATS, 0, 0, 0);
1255
1256 sc->callback = octnet_nic_stats_callback;
1257 sc->callback_arg = sc;
1258 sc->wait_time = 500; /*in milli seconds*/
1259
1260 retval = octeon_send_soft_command(oct_dev, sc);
1261 if (retval == IQ_SEND_FAILED) {
1262 octeon_free_soft_command(oct_dev, sc);
1263 return -EINVAL;
1264 }
1265
1266 wait_for_completion_timeout(&ctrl->complete, msecs_to_jiffies(1000));
1267
1268 if (resp->status != 1) {
1269 octeon_free_soft_command(oct_dev, sc);
1270
1271 return -EINVAL;
1272 }
1273
1274 octeon_free_soft_command(oct_dev, sc);
1275
1276 return 0;
1277}
1278
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001279/* Enable/Disable auto interrupt Moderation */
1280static int oct_cfg_adaptive_intr(struct lio *lio, struct ethtool_coalesce
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001281 *intr_coal)
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001282{
1283 int ret = 0;
1284 struct octeon_device *oct = lio->oct_dev;
1285 struct oct_intrmod_cfg *intrmod_cfg;
1286
1287 intrmod_cfg = &oct->intrmod;
1288
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001289 if (oct->intrmod.rx_enable || oct->intrmod.tx_enable) {
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001290 if (intr_coal->rate_sample_interval)
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001291 intrmod_cfg->check_intrvl =
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001292 intr_coal->rate_sample_interval;
1293 else
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001294 intrmod_cfg->check_intrvl =
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001295 LIO_INTRMOD_CHECK_INTERVAL;
1296
1297 if (intr_coal->pkt_rate_high)
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001298 intrmod_cfg->maxpkt_ratethr =
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001299 intr_coal->pkt_rate_high;
1300 else
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001301 intrmod_cfg->maxpkt_ratethr =
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001302 LIO_INTRMOD_MAXPKT_RATETHR;
1303
1304 if (intr_coal->pkt_rate_low)
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001305 intrmod_cfg->minpkt_ratethr =
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001306 intr_coal->pkt_rate_low;
1307 else
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001308 intrmod_cfg->minpkt_ratethr =
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001309 LIO_INTRMOD_MINPKT_RATETHR;
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001310 }
1311 if (oct->intrmod.rx_enable) {
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001312 if (intr_coal->rx_max_coalesced_frames_high)
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001313 intrmod_cfg->rx_maxcnt_trigger =
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001314 intr_coal->rx_max_coalesced_frames_high;
1315 else
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001316 intrmod_cfg->rx_maxcnt_trigger =
1317 LIO_INTRMOD_RXMAXCNT_TRIGGER;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001318
1319 if (intr_coal->rx_coalesce_usecs_high)
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001320 intrmod_cfg->rx_maxtmr_trigger =
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001321 intr_coal->rx_coalesce_usecs_high;
1322 else
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001323 intrmod_cfg->rx_maxtmr_trigger =
1324 LIO_INTRMOD_RXMAXTMR_TRIGGER;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001325
1326 if (intr_coal->rx_coalesce_usecs_low)
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001327 intrmod_cfg->rx_mintmr_trigger =
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001328 intr_coal->rx_coalesce_usecs_low;
1329 else
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001330 intrmod_cfg->rx_mintmr_trigger =
1331 LIO_INTRMOD_RXMINTMR_TRIGGER;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001332
1333 if (intr_coal->rx_max_coalesced_frames_low)
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001334 intrmod_cfg->rx_mincnt_trigger =
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001335 intr_coal->rx_max_coalesced_frames_low;
1336 else
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001337 intrmod_cfg->rx_mincnt_trigger =
1338 LIO_INTRMOD_RXMINCNT_TRIGGER;
1339 }
1340 if (oct->intrmod.tx_enable) {
1341 if (intr_coal->tx_max_coalesced_frames_high)
1342 intrmod_cfg->tx_maxcnt_trigger =
1343 intr_coal->tx_max_coalesced_frames_high;
1344 else
1345 intrmod_cfg->tx_maxcnt_trigger =
1346 LIO_INTRMOD_TXMAXCNT_TRIGGER;
1347 if (intr_coal->tx_max_coalesced_frames_low)
1348 intrmod_cfg->tx_mincnt_trigger =
1349 intr_coal->tx_max_coalesced_frames_low;
1350 else
1351 intrmod_cfg->tx_mincnt_trigger =
1352 LIO_INTRMOD_TXMINCNT_TRIGGER;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001353 }
1354
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001355 ret = octnet_set_intrmod_cfg(lio, intrmod_cfg);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001356
1357 return ret;
1358}
1359
1360static int
1361oct_cfg_rx_intrcnt(struct lio *lio, struct ethtool_coalesce *intr_coal)
1362{
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001363 struct octeon_device *oct = lio->oct_dev;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001364 u32 rx_max_coalesced_frames;
1365
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001366 /* Config Cnt based interrupt values */
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001367 switch (oct->chip_id) {
1368 case OCTEON_CN68XX:
1369 case OCTEON_CN66XX: {
1370 struct octeon_cn6xxx *cn6xxx =
1371 (struct octeon_cn6xxx *)oct->chip;
1372
1373 if (!intr_coal->rx_max_coalesced_frames)
1374 rx_max_coalesced_frames = CN6XXX_OQ_INTR_PKT;
1375 else
1376 rx_max_coalesced_frames =
1377 intr_coal->rx_max_coalesced_frames;
1378 octeon_write_csr(oct, CN6XXX_SLI_OQ_INT_LEVEL_PKTS,
1379 rx_max_coalesced_frames);
1380 CFG_SET_OQ_INTR_PKT(cn6xxx->conf, rx_max_coalesced_frames);
1381 break;
1382 }
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -07001383 case OCTEON_CN23XX_PF_VID: {
1384 int q_no;
1385
1386 if (!intr_coal->rx_max_coalesced_frames)
1387 rx_max_coalesced_frames = oct->intrmod.rx_frames;
1388 else
1389 rx_max_coalesced_frames =
1390 intr_coal->rx_max_coalesced_frames;
1391 for (q_no = 0; q_no < oct->num_oqs; q_no++) {
1392 q_no += oct->sriov_info.pf_srn;
1393 octeon_write_csr64(
1394 oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no),
1395 (octeon_read_csr64(
1396 oct, CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no)) &
1397 (0x3fffff00000000UL)) |
1398 rx_max_coalesced_frames);
1399 /*consider setting resend bit*/
1400 }
1401 oct->intrmod.rx_frames = rx_max_coalesced_frames;
1402 break;
1403 }
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001404 default:
1405 return -EINVAL;
1406 }
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001407 return 0;
1408}
1409
Raghu Vatsavayi32581242016-08-31 11:03:20 -07001410static int oct_cfg_rx_intrtime(struct lio *lio,
1411 struct ethtool_coalesce *intr_coal)
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001412{
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001413 struct octeon_device *oct = lio->oct_dev;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001414 u32 time_threshold, rx_coalesce_usecs;
1415
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001416 /* Config Time based interrupt values */
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001417 switch (oct->chip_id) {
1418 case OCTEON_CN68XX:
1419 case OCTEON_CN66XX: {
1420 struct octeon_cn6xxx *cn6xxx =
1421 (struct octeon_cn6xxx *)oct->chip;
1422 if (!intr_coal->rx_coalesce_usecs)
1423 rx_coalesce_usecs = CN6XXX_OQ_INTR_TIME;
1424 else
1425 rx_coalesce_usecs = intr_coal->rx_coalesce_usecs;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001426
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001427 time_threshold = lio_cn6xxx_get_oq_ticks(oct,
1428 rx_coalesce_usecs);
1429 octeon_write_csr(oct,
1430 CN6XXX_SLI_OQ_INT_LEVEL_TIME,
1431 time_threshold);
1432
1433 CFG_SET_OQ_INTR_TIME(cn6xxx->conf, rx_coalesce_usecs);
1434 break;
1435 }
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -07001436 case OCTEON_CN23XX_PF_VID: {
1437 u64 time_threshold;
1438 int q_no;
1439
1440 if (!intr_coal->rx_coalesce_usecs)
1441 rx_coalesce_usecs = oct->intrmod.rx_usecs;
1442 else
1443 rx_coalesce_usecs = intr_coal->rx_coalesce_usecs;
1444 time_threshold =
1445 cn23xx_pf_get_oq_ticks(oct, (u32)rx_coalesce_usecs);
1446 for (q_no = 0; q_no < oct->num_oqs; q_no++) {
1447 q_no += oct->sriov_info.pf_srn;
1448 octeon_write_csr64(oct,
1449 CN23XX_SLI_OQ_PKT_INT_LEVELS(q_no),
1450 (oct->intrmod.rx_frames |
1451 (time_threshold << 32)));
1452 /*consider writing to resend bit here*/
1453 }
1454 oct->intrmod.rx_usecs = rx_coalesce_usecs;
1455 break;
1456 }
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001457 default:
1458 return -EINVAL;
1459 }
1460
1461 return 0;
1462}
1463
1464static int
1465oct_cfg_tx_intrcnt(struct lio *lio, struct ethtool_coalesce *intr_coal
1466 __attribute__((unused)))
1467{
1468 struct octeon_device *oct = lio->oct_dev;
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -07001469 u32 iq_intr_pkt;
1470 void __iomem *inst_cnt_reg;
1471 u64 val;
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001472
1473 /* Config Cnt based interrupt values */
1474 switch (oct->chip_id) {
1475 case OCTEON_CN68XX:
1476 case OCTEON_CN66XX:
1477 break;
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -07001478 case OCTEON_CN23XX_PF_VID: {
1479 int q_no;
1480
1481 if (!intr_coal->tx_max_coalesced_frames)
1482 iq_intr_pkt = CN23XX_DEF_IQ_INTR_THRESHOLD &
1483 CN23XX_PKT_IN_DONE_WMARK_MASK;
1484 else
1485 iq_intr_pkt = intr_coal->tx_max_coalesced_frames &
1486 CN23XX_PKT_IN_DONE_WMARK_MASK;
1487 for (q_no = 0; q_no < oct->num_iqs; q_no++) {
1488 inst_cnt_reg = (oct->instr_queue[q_no])->inst_cnt_reg;
1489 val = readq(inst_cnt_reg);
1490 /*clear wmark and count.dont want to write count back*/
1491 val = (val & 0xFFFF000000000000ULL) |
1492 ((u64)iq_intr_pkt
1493 << CN23XX_PKT_IN_DONE_WMARK_BIT_POS);
1494 writeq(val, inst_cnt_reg);
1495 /*consider setting resend bit*/
1496 }
1497 oct->intrmod.tx_frames = iq_intr_pkt;
1498 break;
1499 }
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001500 default:
1501 return -EINVAL;
1502 }
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001503 return 0;
1504}
1505
1506static int lio_set_intr_coalesce(struct net_device *netdev,
1507 struct ethtool_coalesce *intr_coal)
1508{
1509 struct lio *lio = GET_LIO(netdev);
1510 int ret;
1511 struct octeon_device *oct = lio->oct_dev;
1512 u32 j, q_no;
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001513 int db_max, db_min;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001514
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001515 switch (oct->chip_id) {
1516 case OCTEON_CN68XX:
1517 case OCTEON_CN66XX:
1518 db_min = CN6XXX_DB_MIN;
1519 db_max = CN6XXX_DB_MAX;
1520 if ((intr_coal->tx_max_coalesced_frames >= db_min) &&
1521 (intr_coal->tx_max_coalesced_frames <= db_max)) {
1522 for (j = 0; j < lio->linfo.num_txpciq; j++) {
1523 q_no = lio->linfo.txpciq[j].s.q_no;
1524 oct->instr_queue[q_no]->fill_threshold =
1525 intr_coal->tx_max_coalesced_frames;
1526 }
1527 } else {
1528 dev_err(&oct->pci_dev->dev,
1529 "LIQUIDIO: Invalid tx-frames:%d. Range is min:%d max:%d\n",
1530 intr_coal->tx_max_coalesced_frames, db_min,
1531 db_max);
1532 return -EINVAL;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001533 }
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001534 break;
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -07001535 case OCTEON_CN23XX_PF_VID:
1536 break;
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001537 default:
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001538 return -EINVAL;
1539 }
1540
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001541 oct->intrmod.rx_enable = intr_coal->use_adaptive_rx_coalesce ? 1 : 0;
1542 oct->intrmod.tx_enable = intr_coal->use_adaptive_tx_coalesce ? 1 : 0;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001543
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001544 ret = oct_cfg_adaptive_intr(lio, intr_coal);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001545
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001546 if (!intr_coal->use_adaptive_rx_coalesce) {
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001547 ret = oct_cfg_rx_intrtime(lio, intr_coal);
1548 if (ret)
1549 goto ret_intrmod;
1550
1551 ret = oct_cfg_rx_intrcnt(lio, intr_coal);
1552 if (ret)
1553 goto ret_intrmod;
1554 }
Raghu Vatsavayi78e6a9b2016-06-21 22:53:10 -07001555 if (!intr_coal->use_adaptive_tx_coalesce) {
1556 ret = oct_cfg_tx_intrcnt(lio, intr_coal);
1557 if (ret)
1558 goto ret_intrmod;
1559 }
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001560
1561 return 0;
1562ret_intrmod:
1563 return ret;
1564}
1565
1566static int lio_get_ts_info(struct net_device *netdev,
1567 struct ethtool_ts_info *info)
1568{
1569 struct lio *lio = GET_LIO(netdev);
1570
1571 info->so_timestamping =
Raghu Vatsavayi178cc102016-06-21 22:53:13 -07001572#ifdef PTP_HARDWARE_TIMESTAMPING
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001573 SOF_TIMESTAMPING_TX_HARDWARE |
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001574 SOF_TIMESTAMPING_RX_HARDWARE |
Raghu Vatsavayi178cc102016-06-21 22:53:13 -07001575 SOF_TIMESTAMPING_RAW_HARDWARE |
1576 SOF_TIMESTAMPING_TX_SOFTWARE |
1577#endif
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001578 SOF_TIMESTAMPING_RX_SOFTWARE |
Raghu Vatsavayi178cc102016-06-21 22:53:13 -07001579 SOF_TIMESTAMPING_SOFTWARE;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001580
1581 if (lio->ptp_clock)
1582 info->phc_index = ptp_clock_index(lio->ptp_clock);
1583 else
1584 info->phc_index = -1;
1585
Raghu Vatsavayi178cc102016-06-21 22:53:13 -07001586#ifdef PTP_HARDWARE_TIMESTAMPING
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001587 info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
1588
1589 info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
1590 (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
1591 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
1592 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
Raghu Vatsavayi178cc102016-06-21 22:53:13 -07001593#endif
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001594
1595 return 0;
1596}
1597
1598static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
1599{
1600 struct lio *lio = GET_LIO(netdev);
1601 struct octeon_device *oct = lio->oct_dev;
1602 struct oct_link_info *linfo;
1603 struct octnic_ctrl_pkt nctrl;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001604 int ret = 0;
1605
1606 /* get the link info */
1607 linfo = &lio->linfo;
1608
1609 if (ecmd->autoneg != AUTONEG_ENABLE && ecmd->autoneg != AUTONEG_DISABLE)
1610 return -EINVAL;
1611
1612 if (ecmd->autoneg == AUTONEG_DISABLE && ((ecmd->speed != SPEED_100 &&
1613 ecmd->speed != SPEED_10) ||
1614 (ecmd->duplex != DUPLEX_HALF &&
1615 ecmd->duplex != DUPLEX_FULL)))
1616 return -EINVAL;
1617
Raghu Vatsavayi9eb60842016-06-21 22:53:12 -07001618 /* Ethtool Support is not provided for XAUI, RXAUI, and XFI Interfaces
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001619 * as they operate at fixed Speed and Duplex settings
1620 */
Raghu Vatsavayi9eb60842016-06-21 22:53:12 -07001621 if (linfo->link.s.if_mode == INTERFACE_MODE_XAUI ||
1622 linfo->link.s.if_mode == INTERFACE_MODE_RXAUI ||
1623 linfo->link.s.if_mode == INTERFACE_MODE_XFI) {
1624 dev_info(&oct->pci_dev->dev,
1625 "Autonegotiation, duplex and speed settings cannot be modified.\n");
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001626 return -EINVAL;
1627 }
1628
1629 memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
1630
1631 nctrl.ncmd.u64 = 0;
1632 nctrl.ncmd.s.cmd = OCTNET_CMD_SET_SETTINGS;
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -07001633 nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001634 nctrl.wait_time = 1000;
1635 nctrl.netpndev = (u64)netdev;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001636 nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
1637
1638 /* Passing the parameters sent by ethtool like Speed, Autoneg & Duplex
1639 * to SE core application using ncmd.s.more & ncmd.s.param
1640 */
1641 if (ecmd->autoneg == AUTONEG_ENABLE) {
1642 /* Autoneg ON */
1643 nctrl.ncmd.s.more = OCTNIC_NCMD_PHY_ON |
1644 OCTNIC_NCMD_AUTONEG_ON;
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -07001645 nctrl.ncmd.s.param1 = ecmd->advertising;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001646 } else {
1647 /* Autoneg OFF */
1648 nctrl.ncmd.s.more = OCTNIC_NCMD_PHY_ON;
1649
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -07001650 nctrl.ncmd.s.param2 = ecmd->duplex;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001651
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -07001652 nctrl.ncmd.s.param1 = ecmd->speed;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001653 }
1654
Raghu Vatsavayi0cece6c2016-06-14 16:54:50 -07001655 ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001656 if (ret < 0) {
1657 dev_err(&oct->pci_dev->dev, "Failed to set settings\n");
1658 return -1;
1659 }
1660
1661 return 0;
1662}
1663
1664static int lio_nway_reset(struct net_device *netdev)
1665{
1666 if (netif_running(netdev)) {
1667 struct ethtool_cmd ecmd;
1668
1669 memset(&ecmd, 0, sizeof(struct ethtool_cmd));
1670 ecmd.autoneg = 0;
1671 ecmd.speed = 0;
1672 ecmd.duplex = 0;
1673 lio_set_settings(netdev, &ecmd);
1674 }
1675 return 0;
1676}
1677
1678/* Return register dump len. */
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -07001679static int lio_get_regs_len(struct net_device *dev)
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001680{
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -07001681 struct lio *lio = GET_LIO(dev);
1682 struct octeon_device *oct = lio->oct_dev;
1683
1684 switch (oct->chip_id) {
1685 case OCTEON_CN23XX_PF_VID:
1686 return OCT_ETHTOOL_REGDUMP_LEN_23XX;
1687 default:
1688 return OCT_ETHTOOL_REGDUMP_LEN;
1689 }
1690}
1691
1692static int cn23xx_read_csr_reg(char *s, struct octeon_device *oct)
1693{
1694 u32 reg;
1695 u8 pf_num = oct->pf_num;
1696 int len = 0;
1697 int i;
1698
1699 /* PCI Window Registers */
1700
1701 len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n");
1702
1703 /*0x29030 or 0x29040*/
1704 reg = CN23XX_SLI_PKT_MAC_RINFO64(oct->pcie_port, oct->pf_num);
1705 len += sprintf(s + len,
1706 "\n[%08x] (SLI_PKT_MAC%d_PF%d_RINFO): %016llx\n",
1707 reg, oct->pcie_port, oct->pf_num,
1708 (u64)octeon_read_csr64(oct, reg));
1709
1710 /*0x27080 or 0x27090*/
1711 reg = CN23XX_SLI_MAC_PF_INT_ENB64(oct->pcie_port, oct->pf_num);
1712 len +=
1713 sprintf(s + len, "\n[%08x] (SLI_MAC%d_PF%d_INT_ENB): %016llx\n",
1714 reg, oct->pcie_port, oct->pf_num,
1715 (u64)octeon_read_csr64(oct, reg));
1716
1717 /*0x27000 or 0x27010*/
1718 reg = CN23XX_SLI_MAC_PF_INT_SUM64(oct->pcie_port, oct->pf_num);
1719 len +=
1720 sprintf(s + len, "\n[%08x] (SLI_MAC%d_PF%d_INT_SUM): %016llx\n",
1721 reg, oct->pcie_port, oct->pf_num,
1722 (u64)octeon_read_csr64(oct, reg));
1723
1724 /*0x29120*/
1725 reg = 0x29120;
1726 len += sprintf(s + len, "\n[%08x] (SLI_PKT_MEM_CTL): %016llx\n", reg,
1727 (u64)octeon_read_csr64(oct, reg));
1728
1729 /*0x27300*/
1730 reg = 0x27300 + oct->pcie_port * CN23XX_MAC_INT_OFFSET +
1731 (oct->pf_num) * CN23XX_PF_INT_OFFSET;
1732 len += sprintf(
1733 s + len, "\n[%08x] (SLI_MAC%d_PF%d_PKT_VF_INT): %016llx\n", reg,
1734 oct->pcie_port, oct->pf_num, (u64)octeon_read_csr64(oct, reg));
1735
1736 /*0x27200*/
1737 reg = 0x27200 + oct->pcie_port * CN23XX_MAC_INT_OFFSET +
1738 (oct->pf_num) * CN23XX_PF_INT_OFFSET;
1739 len += sprintf(s + len,
1740 "\n[%08x] (SLI_MAC%d_PF%d_PP_VF_INT): %016llx\n",
1741 reg, oct->pcie_port, oct->pf_num,
1742 (u64)octeon_read_csr64(oct, reg));
1743
1744 /*29130*/
1745 reg = CN23XX_SLI_PKT_CNT_INT;
1746 len += sprintf(s + len, "\n[%08x] (SLI_PKT_CNT_INT): %016llx\n", reg,
1747 (u64)octeon_read_csr64(oct, reg));
1748
1749 /*0x29140*/
1750 reg = CN23XX_SLI_PKT_TIME_INT;
1751 len += sprintf(s + len, "\n[%08x] (SLI_PKT_TIME_INT): %016llx\n", reg,
1752 (u64)octeon_read_csr64(oct, reg));
1753
1754 /*0x29160*/
1755 reg = 0x29160;
1756 len += sprintf(s + len, "\n[%08x] (SLI_PKT_INT): %016llx\n", reg,
1757 (u64)octeon_read_csr64(oct, reg));
1758
1759 /*0x29180*/
1760 reg = CN23XX_SLI_OQ_WMARK;
1761 len += sprintf(s + len, "\n[%08x] (SLI_PKT_OUTPUT_WMARK): %016llx\n",
1762 reg, (u64)octeon_read_csr64(oct, reg));
1763
1764 /*0x291E0*/
1765 reg = CN23XX_SLI_PKT_IOQ_RING_RST;
1766 len += sprintf(s + len, "\n[%08x] (SLI_PKT_RING_RST): %016llx\n", reg,
1767 (u64)octeon_read_csr64(oct, reg));
1768
1769 /*0x29210*/
1770 reg = CN23XX_SLI_GBL_CONTROL;
1771 len += sprintf(s + len,
1772 "\n[%08x] (SLI_PKT_GBL_CONTROL): %016llx\n", reg,
1773 (u64)octeon_read_csr64(oct, reg));
1774
1775 /*0x29220*/
1776 reg = 0x29220;
1777 len += sprintf(s + len, "\n[%08x] (SLI_PKT_BIST_STATUS): %016llx\n",
1778 reg, (u64)octeon_read_csr64(oct, reg));
1779
1780 /*PF only*/
1781 if (pf_num == 0) {
1782 /*0x29260*/
1783 reg = CN23XX_SLI_OUT_BP_EN_W1S;
1784 len += sprintf(s + len,
1785 "\n[%08x] (SLI_PKT_OUT_BP_EN_W1S): %016llx\n",
1786 reg, (u64)octeon_read_csr64(oct, reg));
1787 } else if (pf_num == 1) {
1788 /*0x29270*/
1789 reg = CN23XX_SLI_OUT_BP_EN2_W1S;
1790 len += sprintf(s + len,
1791 "\n[%08x] (SLI_PKT_OUT_BP_EN2_W1S): %016llx\n",
1792 reg, (u64)octeon_read_csr64(oct, reg));
1793 }
1794
1795 for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
1796 reg = CN23XX_SLI_OQ_BUFF_INFO_SIZE(i);
1797 len +=
1798 sprintf(s + len, "\n[%08x] (SLI_PKT%d_OUT_SIZE): %016llx\n",
1799 reg, i, (u64)octeon_read_csr64(oct, reg));
1800 }
1801
1802 /*0x10040*/
1803 for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
1804 reg = CN23XX_SLI_IQ_INSTR_COUNT64(i);
1805 len += sprintf(s + len,
1806 "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",
1807 reg, i, (u64)octeon_read_csr64(oct, reg));
1808 }
1809
1810 /*0x10080*/
1811 for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
1812 reg = CN23XX_SLI_OQ_PKTS_CREDIT(i);
1813 len += sprintf(s + len,
1814 "\n[%08x] (SLI_PKT%d_SLIST_BAOFF_DBELL): %016llx\n",
1815 reg, i, (u64)octeon_read_csr64(oct, reg));
1816 }
1817
1818 /*0x10090*/
1819 for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
1820 reg = CN23XX_SLI_OQ_SIZE(i);
1821 len += sprintf(
1822 s + len, "\n[%08x] (SLI_PKT%d_SLIST_FIFO_RSIZE): %016llx\n",
1823 reg, i, (u64)octeon_read_csr64(oct, reg));
1824 }
1825
1826 /*0x10050*/
1827 for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
1828 reg = CN23XX_SLI_OQ_PKT_CONTROL(i);
1829 len += sprintf(
1830 s + len,
1831 "\n[%08x] (SLI_PKT%d__OUTPUT_CONTROL): %016llx\n",
1832 reg, i, (u64)octeon_read_csr64(oct, reg));
1833 }
1834
1835 /*0x10070*/
1836 for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
1837 reg = CN23XX_SLI_OQ_BASE_ADDR64(i);
1838 len += sprintf(s + len,
1839 "\n[%08x] (SLI_PKT%d_SLIST_BADDR): %016llx\n",
1840 reg, i, (u64)octeon_read_csr64(oct, reg));
1841 }
1842
1843 /*0x100a0*/
1844 for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
1845 reg = CN23XX_SLI_OQ_PKT_INT_LEVELS(i);
1846 len += sprintf(s + len,
1847 "\n[%08x] (SLI_PKT%d_INT_LEVELS): %016llx\n",
1848 reg, i, (u64)octeon_read_csr64(oct, reg));
1849 }
1850
1851 /*0x100b0*/
1852 for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
1853 reg = CN23XX_SLI_OQ_PKTS_SENT(i);
1854 len += sprintf(s + len, "\n[%08x] (SLI_PKT%d_CNTS): %016llx\n",
1855 reg, i, (u64)octeon_read_csr64(oct, reg));
1856 }
1857
1858 /*0x100c0*/
1859 for (i = 0; i < CN23XX_MAX_OUTPUT_QUEUES; i++) {
1860 reg = 0x100c0 + i * CN23XX_OQ_OFFSET;
1861 len += sprintf(s + len,
1862 "\n[%08x] (SLI_PKT%d_ERROR_INFO): %016llx\n",
1863 reg, i, (u64)octeon_read_csr64(oct, reg));
1864
1865 /*0x10000*/
1866 for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
1867 reg = CN23XX_SLI_IQ_PKT_CONTROL64(i);
1868 len += sprintf(
1869 s + len,
1870 "\n[%08x] (SLI_PKT%d_INPUT_CONTROL): %016llx\n",
1871 reg, i, (u64)octeon_read_csr64(oct, reg));
1872 }
1873
1874 /*0x10010*/
1875 for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
1876 reg = CN23XX_SLI_IQ_BASE_ADDR64(i);
1877 len += sprintf(
1878 s + len,
1879 "\n[%08x] (SLI_PKT%d_INSTR_BADDR): %016llx\n", reg,
1880 i, (u64)octeon_read_csr64(oct, reg));
1881 }
1882
1883 /*0x10020*/
1884 for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
1885 reg = CN23XX_SLI_IQ_DOORBELL(i);
1886 len += sprintf(
1887 s + len,
1888 "\n[%08x] (SLI_PKT%d_INSTR_BAOFF_DBELL): %016llx\n",
1889 reg, i, (u64)octeon_read_csr64(oct, reg));
1890 }
1891
1892 /*0x10030*/
1893 for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++) {
1894 reg = CN23XX_SLI_IQ_SIZE(i);
1895 len += sprintf(
1896 s + len,
1897 "\n[%08x] (SLI_PKT%d_INSTR_FIFO_RSIZE): %016llx\n",
1898 reg, i, (u64)octeon_read_csr64(oct, reg));
1899 }
1900
1901 /*0x10040*/
1902 for (i = 0; i < CN23XX_MAX_INPUT_QUEUES; i++)
1903 reg = CN23XX_SLI_IQ_INSTR_COUNT64(i);
1904 len += sprintf(s + len,
1905 "\n[%08x] (SLI_PKT_IN_DONE%d_CNTS): %016llx\n",
1906 reg, i, (u64)octeon_read_csr64(oct, reg));
1907 }
1908
1909 return len;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07001910}
1911
1912static int cn6xxx_read_csr_reg(char *s, struct octeon_device *oct)
1913{
1914 u32 reg;
1915 int i, len = 0;
1916
1917 /* PCI Window Registers */
1918
1919 len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n");
1920 reg = CN6XXX_WIN_WR_ADDR_LO;
1921 len += sprintf(s + len, "\n[%02x] (WIN_WR_ADDR_LO): %08x\n",
1922 CN6XXX_WIN_WR_ADDR_LO, octeon_read_csr(oct, reg));
1923 reg = CN6XXX_WIN_WR_ADDR_HI;
1924 len += sprintf(s + len, "[%02x] (WIN_WR_ADDR_HI): %08x\n",
1925 CN6XXX_WIN_WR_ADDR_HI, octeon_read_csr(oct, reg));
1926 reg = CN6XXX_WIN_RD_ADDR_LO;
1927 len += sprintf(s + len, "[%02x] (WIN_RD_ADDR_LO): %08x\n",
1928 CN6XXX_WIN_RD_ADDR_LO, octeon_read_csr(oct, reg));
1929 reg = CN6XXX_WIN_RD_ADDR_HI;
1930 len += sprintf(s + len, "[%02x] (WIN_RD_ADDR_HI): %08x\n",
1931 CN6XXX_WIN_RD_ADDR_HI, octeon_read_csr(oct, reg));
1932 reg = CN6XXX_WIN_WR_DATA_LO;
1933 len += sprintf(s + len, "[%02x] (WIN_WR_DATA_LO): %08x\n",
1934 CN6XXX_WIN_WR_DATA_LO, octeon_read_csr(oct, reg));
1935 reg = CN6XXX_WIN_WR_DATA_HI;
1936 len += sprintf(s + len, "[%02x] (WIN_WR_DATA_HI): %08x\n",
1937 CN6XXX_WIN_WR_DATA_HI, octeon_read_csr(oct, reg));
1938 len += sprintf(s + len, "[%02x] (WIN_WR_MASK_REG): %08x\n",
1939 CN6XXX_WIN_WR_MASK_REG,
1940 octeon_read_csr(oct, CN6XXX_WIN_WR_MASK_REG));
1941
1942 /* PCI Interrupt Register */
1943 len += sprintf(s + len, "\n[%x] (INT_ENABLE PORT 0): %08x\n",
1944 CN6XXX_SLI_INT_ENB64_PORT0, octeon_read_csr(oct,
1945 CN6XXX_SLI_INT_ENB64_PORT0));
1946 len += sprintf(s + len, "\n[%x] (INT_ENABLE PORT 1): %08x\n",
1947 CN6XXX_SLI_INT_ENB64_PORT1,
1948 octeon_read_csr(oct, CN6XXX_SLI_INT_ENB64_PORT1));
1949 len += sprintf(s + len, "[%x] (INT_SUM): %08x\n", CN6XXX_SLI_INT_SUM64,
1950 octeon_read_csr(oct, CN6XXX_SLI_INT_SUM64));
1951
1952 /* PCI Output queue registers */
1953 for (i = 0; i < oct->num_oqs; i++) {
1954 reg = CN6XXX_SLI_OQ_PKTS_SENT(i);
1955 len += sprintf(s + len, "\n[%x] (PKTS_SENT_%d): %08x\n",
1956 reg, i, octeon_read_csr(oct, reg));
1957 reg = CN6XXX_SLI_OQ_PKTS_CREDIT(i);
1958 len += sprintf(s + len, "[%x] (PKT_CREDITS_%d): %08x\n",
1959 reg, i, octeon_read_csr(oct, reg));
1960 }
1961 reg = CN6XXX_SLI_OQ_INT_LEVEL_PKTS;
1962 len += sprintf(s + len, "\n[%x] (PKTS_SENT_INT_LEVEL): %08x\n",
1963 reg, octeon_read_csr(oct, reg));
1964 reg = CN6XXX_SLI_OQ_INT_LEVEL_TIME;
1965 len += sprintf(s + len, "[%x] (PKTS_SENT_TIME): %08x\n",
1966 reg, octeon_read_csr(oct, reg));
1967
1968 /* PCI Input queue registers */
1969 for (i = 0; i <= 3; i++) {
1970 u32 reg;
1971
1972 reg = CN6XXX_SLI_IQ_DOORBELL(i);
1973 len += sprintf(s + len, "\n[%x] (INSTR_DOORBELL_%d): %08x\n",
1974 reg, i, octeon_read_csr(oct, reg));
1975 reg = CN6XXX_SLI_IQ_INSTR_COUNT(i);
1976 len += sprintf(s + len, "[%x] (INSTR_COUNT_%d): %08x\n",
1977 reg, i, octeon_read_csr(oct, reg));
1978 }
1979
1980 /* PCI DMA registers */
1981
1982 len += sprintf(s + len, "\n[%x] (DMA_CNT_0): %08x\n",
1983 CN6XXX_DMA_CNT(0),
1984 octeon_read_csr(oct, CN6XXX_DMA_CNT(0)));
1985 reg = CN6XXX_DMA_PKT_INT_LEVEL(0);
1986 len += sprintf(s + len, "[%x] (DMA_INT_LEV_0): %08x\n",
1987 CN6XXX_DMA_PKT_INT_LEVEL(0), octeon_read_csr(oct, reg));
1988 reg = CN6XXX_DMA_TIME_INT_LEVEL(0);
1989 len += sprintf(s + len, "[%x] (DMA_TIME_0): %08x\n",
1990 CN6XXX_DMA_TIME_INT_LEVEL(0),
1991 octeon_read_csr(oct, reg));
1992
1993 len += sprintf(s + len, "\n[%x] (DMA_CNT_1): %08x\n",
1994 CN6XXX_DMA_CNT(1),
1995 octeon_read_csr(oct, CN6XXX_DMA_CNT(1)));
1996 reg = CN6XXX_DMA_PKT_INT_LEVEL(1);
1997 len += sprintf(s + len, "[%x] (DMA_INT_LEV_1): %08x\n",
1998 CN6XXX_DMA_PKT_INT_LEVEL(1),
1999 octeon_read_csr(oct, reg));
2000 reg = CN6XXX_DMA_PKT_INT_LEVEL(1);
2001 len += sprintf(s + len, "[%x] (DMA_TIME_1): %08x\n",
2002 CN6XXX_DMA_TIME_INT_LEVEL(1),
2003 octeon_read_csr(oct, reg));
2004
2005 /* PCI Index registers */
2006
2007 len += sprintf(s + len, "\n");
2008
2009 for (i = 0; i < 16; i++) {
2010 reg = lio_pci_readq(oct, CN6XXX_BAR1_REG(i, oct->pcie_port));
2011 len += sprintf(s + len, "[%llx] (BAR1_INDEX_%02d): %08x\n",
2012 CN6XXX_BAR1_REG(i, oct->pcie_port), i, reg);
2013 }
2014
2015 return len;
2016}
2017
2018static int cn6xxx_read_config_reg(char *s, struct octeon_device *oct)
2019{
2020 u32 val;
2021 int i, len = 0;
2022
2023 /* PCI CONFIG Registers */
2024
2025 len += sprintf(s + len,
2026 "\n\t Octeon Config space Registers\n\n");
2027
2028 for (i = 0; i <= 13; i++) {
2029 pci_read_config_dword(oct->pci_dev, (i * 4), &val);
2030 len += sprintf(s + len, "[0x%x] (Config[%d]): 0x%08x\n",
2031 (i * 4), i, val);
2032 }
2033
2034 for (i = 30; i <= 34; i++) {
2035 pci_read_config_dword(oct->pci_dev, (i * 4), &val);
2036 len += sprintf(s + len, "[0x%x] (Config[%d]): 0x%08x\n",
2037 (i * 4), i, val);
2038 }
2039
2040 return len;
2041}
2042
2043/* Return register dump user app. */
2044static void lio_get_regs(struct net_device *dev,
2045 struct ethtool_regs *regs, void *regbuf)
2046{
2047 struct lio *lio = GET_LIO(dev);
2048 int len = 0;
2049 struct octeon_device *oct = lio->oct_dev;
2050
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07002051 regs->version = OCT_ETHTOOL_REGSVER;
2052
2053 switch (oct->chip_id) {
Raghu Vatsavayidc3abcb2016-09-01 11:16:08 -07002054 case OCTEON_CN23XX_PF_VID:
2055 memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN_23XX);
2056 len += cn23xx_read_csr_reg(regbuf + len, oct);
2057 break;
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07002058 case OCTEON_CN68XX:
2059 case OCTEON_CN66XX:
Raghu Vatsavayia2c64b62016-07-03 13:56:55 -07002060 memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN);
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07002061 len += cn6xxx_read_csr_reg(regbuf + len, oct);
2062 len += cn6xxx_read_config_reg(regbuf + len, oct);
2063 break;
2064 default:
2065 dev_err(&oct->pci_dev->dev, "%s Unknown chipid: %d\n",
2066 __func__, oct->chip_id);
2067 }
2068}
2069
Raghu Vatsavayif5a20472016-06-21 22:53:14 -07002070static u32 lio_get_priv_flags(struct net_device *netdev)
2071{
2072 struct lio *lio = GET_LIO(netdev);
2073
2074 return lio->oct_dev->priv_flags;
2075}
2076
2077static int lio_set_priv_flags(struct net_device *netdev, u32 flags)
2078{
2079 struct lio *lio = GET_LIO(netdev);
2080 bool intr_by_tx_bytes = !!(flags & (0x1 << OCT_PRIV_FLAG_TX_BYTES));
2081
2082 lio_set_priv_flag(lio->oct_dev, OCT_PRIV_FLAG_TX_BYTES,
2083 intr_by_tx_bytes);
2084 return 0;
2085}
2086
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07002087static const struct ethtool_ops lio_ethtool_ops = {
2088 .get_settings = lio_get_settings,
2089 .get_link = ethtool_op_get_link,
2090 .get_drvinfo = lio_get_drvinfo,
2091 .get_ringparam = lio_ethtool_get_ringparam,
2092 .get_channels = lio_ethtool_get_channels,
2093 .set_phys_id = lio_set_phys_id,
2094 .get_eeprom_len = lio_get_eeprom_len,
2095 .get_eeprom = lio_get_eeprom,
2096 .get_strings = lio_get_strings,
2097 .get_ethtool_stats = lio_get_ethtool_stats,
2098 .get_pauseparam = lio_get_pauseparam,
2099 .get_regs_len = lio_get_regs_len,
2100 .get_regs = lio_get_regs,
2101 .get_msglevel = lio_get_msglevel,
2102 .set_msglevel = lio_set_msglevel,
2103 .get_sset_count = lio_get_sset_count,
2104 .nway_reset = lio_nway_reset,
2105 .set_settings = lio_set_settings,
2106 .get_coalesce = lio_get_intr_coalesce,
2107 .set_coalesce = lio_set_intr_coalesce,
Raghu Vatsavayif5a20472016-06-21 22:53:14 -07002108 .get_priv_flags = lio_get_priv_flags,
2109 .set_priv_flags = lio_set_priv_flags,
Raghu Vatsavayif21fb3e2015-06-09 18:15:23 -07002110 .get_ts_info = lio_get_ts_info,
2111};
2112
2113void liquidio_set_ethtool_ops(struct net_device *netdev)
2114{
2115 netdev->ethtool_ops = &lio_ethtool_ops;
2116}