]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/ethernet/cavium/liquidio/lio_ethtool.c
Merge remote-tracking branch 'input-current/for-linus'
[karo-tx-linux.git] / drivers / net / ethernet / cavium / liquidio / lio_ethtool.c
1 /**********************************************************************
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 **********************************************************************/
22 #include <linux/version.h>
23 #include <linux/netdevice.h>
24 #include <linux/net_tstamp.h>
25 #include <linux/ethtool.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/pci.h>
28 #include "octeon_config.h"
29 #include "liquidio_common.h"
30 #include "octeon_droq.h"
31 #include "octeon_iq.h"
32 #include "response_manager.h"
33 #include "octeon_device.h"
34 #include "octeon_nic.h"
35 #include "octeon_main.h"
36 #include "octeon_network.h"
37 #include "cn66xx_regs.h"
38 #include "cn66xx_device.h"
39 #include "cn68xx_regs.h"
40 #include "cn68xx_device.h"
41 #include "liquidio_image.h"
42
43 struct oct_mdio_cmd_context {
44         int octeon_id;
45         wait_queue_head_t wc;
46         int cond;
47 };
48
49 struct oct_mdio_cmd_resp {
50         u64 rh;
51         struct oct_mdio_cmd resp;
52         u64 status;
53 };
54
55 #define OCT_MDIO45_RESP_SIZE   (sizeof(struct oct_mdio_cmd_resp))
56
57 /* Octeon's interface mode of operation */
58 enum {
59         INTERFACE_MODE_DISABLED,
60         INTERFACE_MODE_RGMII,
61         INTERFACE_MODE_GMII,
62         INTERFACE_MODE_SPI,
63         INTERFACE_MODE_PCIE,
64         INTERFACE_MODE_XAUI,
65         INTERFACE_MODE_SGMII,
66         INTERFACE_MODE_PICMG,
67         INTERFACE_MODE_NPI,
68         INTERFACE_MODE_LOOP,
69         INTERFACE_MODE_SRIO,
70         INTERFACE_MODE_ILK,
71         INTERFACE_MODE_RXAUI,
72         INTERFACE_MODE_QSGMII,
73         INTERFACE_MODE_AGL,
74 };
75
76 #define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
77 #define OCT_ETHTOOL_REGDUMP_LEN  4096
78 #define OCT_ETHTOOL_REGSVER  1
79
80 static const char oct_iq_stats_strings[][ETH_GSTRING_LEN] = {
81         "Instr posted",
82         "Instr processed",
83         "Instr dropped",
84         "Bytes Sent",
85         "Sgentry_sent",
86         "Inst cntreg",
87         "Tx done",
88         "Tx Iq busy",
89         "Tx dropped",
90         "Tx bytes",
91 };
92
93 static const char oct_droq_stats_strings[][ETH_GSTRING_LEN] = {
94         "OQ Pkts Received",
95         "OQ Bytes Received",
96         "Dropped no dispatch",
97         "Dropped nomem",
98         "Dropped toomany",
99         "Stack RX cnt",
100         "Stack RX Bytes",
101         "RX dropped",
102 };
103
104 #define OCTNIC_NCMD_AUTONEG_ON  0x1
105 #define OCTNIC_NCMD_PHY_ON      0x2
106
107 static int lio_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
108 {
109         struct lio *lio = GET_LIO(netdev);
110         struct octeon_device *oct = lio->oct_dev;
111         struct oct_link_info *linfo;
112
113         linfo = &lio->linfo;
114
115         if (linfo->link.s.interface == INTERFACE_MODE_XAUI ||
116             linfo->link.s.interface == INTERFACE_MODE_RXAUI) {
117                 ecmd->port = PORT_FIBRE;
118                 ecmd->supported =
119                         (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE |
120                          SUPPORTED_Pause);
121                 ecmd->advertising =
122                         (ADVERTISED_10000baseT_Full | ADVERTISED_Pause);
123                 ecmd->transceiver = XCVR_EXTERNAL;
124                 ecmd->autoneg = AUTONEG_DISABLE;
125
126         } else {
127                 dev_err(&oct->pci_dev->dev, "Unknown link interface reported\n");
128         }
129
130         if (linfo->link.s.status) {
131                 ethtool_cmd_speed_set(ecmd, linfo->link.s.speed);
132                 ecmd->duplex = linfo->link.s.duplex;
133         } else {
134                 ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
135                 ecmd->duplex = DUPLEX_UNKNOWN;
136         }
137
138         return 0;
139 }
140
141 static void
142 lio_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
143 {
144         struct lio *lio;
145         struct octeon_device *oct;
146
147         lio = GET_LIO(netdev);
148         oct = lio->oct_dev;
149
150         memset(drvinfo, 0, sizeof(struct ethtool_drvinfo));
151         strcpy(drvinfo->driver, "liquidio");
152         strcpy(drvinfo->version, LIQUIDIO_VERSION);
153         strncpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version,
154                 ETHTOOL_FWVERS_LEN);
155         strncpy(drvinfo->bus_info, pci_name(oct->pci_dev), 32);
156 }
157
158 static void
159 lio_ethtool_get_channels(struct net_device *dev,
160                          struct ethtool_channels *channel)
161 {
162         struct lio *lio = GET_LIO(dev);
163         struct octeon_device *oct = lio->oct_dev;
164         u32 max_rx = 0, max_tx = 0, tx_count = 0, rx_count = 0;
165
166         if (OCTEON_CN6XXX(oct)) {
167                 struct octeon_config *conf6x = CHIP_FIELD(oct, cn6xxx, conf);
168
169                 max_rx = CFG_GET_OQ_MAX_Q(conf6x);
170                 max_tx = CFG_GET_IQ_MAX_Q(conf6x);
171                 rx_count = CFG_GET_NUM_RXQS_NIC_IF(conf6x, lio->ifidx);
172                 tx_count = CFG_GET_NUM_TXQS_NIC_IF(conf6x, lio->ifidx);
173         }
174
175         channel->max_rx = max_rx;
176         channel->max_tx = max_tx;
177         channel->rx_count = rx_count;
178         channel->tx_count = tx_count;
179 }
180
181 static int lio_get_eeprom_len(struct net_device *netdev)
182 {
183         u8 buf[128];
184         struct lio *lio = GET_LIO(netdev);
185         struct octeon_device *oct_dev = lio->oct_dev;
186         struct octeon_board_info *board_info;
187         int len;
188
189         board_info = (struct octeon_board_info *)(&oct_dev->boardinfo);
190         len = sprintf(buf, "boardname:%s serialnum:%s maj:%lld min:%lld\n",
191                       board_info->name, board_info->serial_number,
192                       board_info->major, board_info->minor);
193
194         return len;
195 }
196
197 static int
198 lio_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom,
199                u8 *bytes)
200 {
201         struct lio *lio = GET_LIO(netdev);
202         struct octeon_device *oct_dev = lio->oct_dev;
203         struct octeon_board_info *board_info;
204         int len;
205
206         if (eeprom->offset != 0)
207                 return -EINVAL;
208
209         eeprom->magic = oct_dev->pci_dev->vendor;
210         board_info = (struct octeon_board_info *)(&oct_dev->boardinfo);
211         len =
212                 sprintf((char *)bytes,
213                         "boardname:%s serialnum:%s maj:%lld min:%lld\n",
214                         board_info->name, board_info->serial_number,
215                         board_info->major, board_info->minor);
216
217         return 0;
218 }
219
220 static int octnet_gpio_access(struct net_device *netdev, int addr, int val)
221 {
222         struct lio *lio = GET_LIO(netdev);
223         struct octeon_device *oct = lio->oct_dev;
224         struct octnic_ctrl_pkt nctrl;
225         struct octnic_ctrl_params nparams;
226         int ret = 0;
227
228         memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
229
230         nctrl.ncmd.u64 = 0;
231         nctrl.ncmd.s.cmd = OCTNET_CMD_GPIO_ACCESS;
232         nctrl.ncmd.s.param1 = lio->linfo.ifidx;
233         nctrl.ncmd.s.param2 = addr;
234         nctrl.ncmd.s.param3 = val;
235         nctrl.wait_time = 100;
236         nctrl.netpndev = (u64)netdev;
237         nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
238
239         nparams.resp_order = OCTEON_RESP_ORDERED;
240
241         ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
242         if (ret < 0) {
243                 dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n");
244                 return -EINVAL;
245         }
246
247         return 0;
248 }
249
250 /* Callback for when mdio command response arrives
251  */
252 static void octnet_mdio_resp_callback(struct octeon_device *oct,
253                                       u32 status,
254                                       void *buf)
255 {
256         struct oct_mdio_cmd_resp *mdio_cmd_rsp;
257         struct oct_mdio_cmd_context *mdio_cmd_ctx;
258         struct octeon_soft_command *sc = (struct octeon_soft_command *)buf;
259
260         mdio_cmd_rsp = (struct oct_mdio_cmd_resp *)sc->virtrptr;
261         mdio_cmd_ctx = (struct oct_mdio_cmd_context *)sc->ctxptr;
262
263         oct = lio_get_device(mdio_cmd_ctx->octeon_id);
264         if (status) {
265                 dev_err(&oct->pci_dev->dev, "MIDO instruction failed. Status: %llx\n",
266                         CVM_CAST64(status));
267                 ACCESS_ONCE(mdio_cmd_ctx->cond) = -1;
268         } else {
269                 ACCESS_ONCE(mdio_cmd_ctx->cond) = 1;
270         }
271         wake_up_interruptible(&mdio_cmd_ctx->wc);
272 }
273
274 /* This routine provides PHY access routines for
275  * mdio  clause45 .
276  */
277 static int
278 octnet_mdio45_access(struct lio *lio, int op, int loc, int *value)
279 {
280         struct octeon_device *oct_dev = lio->oct_dev;
281         struct octeon_soft_command *sc;
282         struct oct_mdio_cmd_resp *mdio_cmd_rsp;
283         struct oct_mdio_cmd_context *mdio_cmd_ctx;
284         struct oct_mdio_cmd *mdio_cmd;
285         int retval = 0;
286
287         sc = (struct octeon_soft_command *)
288                 octeon_alloc_soft_command(oct_dev,
289                                           sizeof(struct oct_mdio_cmd),
290                                           sizeof(struct oct_mdio_cmd_resp),
291                                           sizeof(struct oct_mdio_cmd_context));
292
293         if (!sc)
294                 return -ENOMEM;
295
296         mdio_cmd_ctx = (struct oct_mdio_cmd_context *)sc->ctxptr;
297         mdio_cmd_rsp = (struct oct_mdio_cmd_resp *)sc->virtrptr;
298         mdio_cmd = (struct oct_mdio_cmd *)sc->virtdptr;
299
300         ACCESS_ONCE(mdio_cmd_ctx->cond) = 0;
301         mdio_cmd_ctx->octeon_id = lio_get_device_id(oct_dev);
302         mdio_cmd->op = op;
303         mdio_cmd->mdio_addr = loc;
304         if (op)
305                 mdio_cmd->value1 = *value;
306         mdio_cmd->value2 = lio->linfo.ifidx;
307         octeon_swap_8B_data((u64 *)mdio_cmd, sizeof(struct oct_mdio_cmd) / 8);
308
309         octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, OPCODE_NIC_MDIO45,
310                                     0, 0, 0);
311
312         sc->wait_time = 1000;
313         sc->callback = octnet_mdio_resp_callback;
314         sc->callback_arg = sc;
315
316         init_waitqueue_head(&mdio_cmd_ctx->wc);
317
318         retval = octeon_send_soft_command(oct_dev, sc);
319
320         if (retval) {
321                 dev_err(&oct_dev->pci_dev->dev,
322                         "octnet_mdio45_access instruction failed status: %x\n",
323                         retval);
324                 retval =  -EBUSY;
325         } else {
326                 /* Sleep on a wait queue till the cond flag indicates that the
327                  * response arrived
328                  */
329                 sleep_cond(&mdio_cmd_ctx->wc, &mdio_cmd_ctx->cond);
330                 retval = mdio_cmd_rsp->status;
331                 if (retval) {
332                         dev_err(&oct_dev->pci_dev->dev, "octnet mdio45 access failed\n");
333                         retval = -EBUSY;
334                 } else {
335                         octeon_swap_8B_data((u64 *)(&mdio_cmd_rsp->resp),
336                                             sizeof(struct oct_mdio_cmd) / 8);
337
338                         if (ACCESS_ONCE(mdio_cmd_ctx->cond) == 1) {
339                                 if (!op)
340                                         *value = mdio_cmd_rsp->resp.value1;
341                         } else {
342                                 retval = -EINVAL;
343                         }
344                 }
345         }
346
347         octeon_free_soft_command(oct_dev, sc);
348
349         return retval;
350 }
351
352 static int lio_set_phys_id(struct net_device *netdev,
353                            enum ethtool_phys_id_state state)
354 {
355         struct lio *lio = GET_LIO(netdev);
356         struct octeon_device *oct = lio->oct_dev;
357         int value, ret;
358
359         switch (state) {
360         case ETHTOOL_ID_ACTIVE:
361                 if (oct->chip_id == OCTEON_CN66XX) {
362                         octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
363                                            VITESSE_PHY_GPIO_DRIVEON);
364                         return 2;
365
366                 } else if (oct->chip_id == OCTEON_CN68XX) {
367                         /* Save the current LED settings */
368                         ret = octnet_mdio45_access(lio, 0,
369                                                    LIO68XX_LED_BEACON_ADDR,
370                                                    &lio->phy_beacon_val);
371                         if (ret)
372                                 return ret;
373
374                         ret = octnet_mdio45_access(lio, 0,
375                                                    LIO68XX_LED_CTRL_ADDR,
376                                                    &lio->led_ctrl_val);
377                         if (ret)
378                                 return ret;
379
380                         /* Configure Beacon values */
381                         value = LIO68XX_LED_BEACON_CFGON;
382                         ret =
383                                 octnet_mdio45_access(lio, 1,
384                                                      LIO68XX_LED_BEACON_ADDR,
385                                                      &value);
386                         if (ret)
387                                 return ret;
388
389                         value = LIO68XX_LED_CTRL_CFGON;
390                         ret =
391                                 octnet_mdio45_access(lio, 1,
392                                                      LIO68XX_LED_CTRL_ADDR,
393                                                      &value);
394                         if (ret)
395                                 return ret;
396                 } else {
397                         return -EINVAL;
398                 }
399                 break;
400
401         case ETHTOOL_ID_ON:
402                 if (oct->chip_id == OCTEON_CN66XX) {
403                         octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
404                                            VITESSE_PHY_GPIO_HIGH);
405
406                 } else if (oct->chip_id == OCTEON_CN68XX) {
407                         return -EINVAL;
408                 } else {
409                         return -EINVAL;
410                 }
411                 break;
412
413         case ETHTOOL_ID_OFF:
414                 if (oct->chip_id == OCTEON_CN66XX)
415                         octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
416                                            VITESSE_PHY_GPIO_LOW);
417                 else if (oct->chip_id == OCTEON_CN68XX)
418                         return -EINVAL;
419                 else
420                         return -EINVAL;
421
422                 break;
423
424         case ETHTOOL_ID_INACTIVE:
425                 if (oct->chip_id == OCTEON_CN66XX) {
426                         octnet_gpio_access(netdev, VITESSE_PHY_GPIO_CFG,
427                                            VITESSE_PHY_GPIO_DRIVEOFF);
428                 } else if (oct->chip_id == OCTEON_CN68XX) {
429                         /* Restore LED settings */
430                         ret = octnet_mdio45_access(lio, 1,
431                                                    LIO68XX_LED_CTRL_ADDR,
432                                                    &lio->led_ctrl_val);
433                         if (ret)
434                                 return ret;
435
436                         ret = octnet_mdio45_access(lio, 1,
437                                                    LIO68XX_LED_BEACON_ADDR,
438                                                    &lio->phy_beacon_val);
439                         if (ret)
440                                 return ret;
441
442                 } else {
443                         return -EINVAL;
444                 }
445                 break;
446
447         default:
448                 return -EINVAL;
449         }
450
451         return 0;
452 }
453
454 static void
455 lio_ethtool_get_ringparam(struct net_device *netdev,
456                           struct ethtool_ringparam *ering)
457 {
458         struct lio *lio = GET_LIO(netdev);
459         struct octeon_device *oct = lio->oct_dev;
460         u32 tx_max_pending = 0, rx_max_pending = 0, tx_pending = 0,
461             rx_pending = 0;
462
463         if (OCTEON_CN6XXX(oct)) {
464                 struct octeon_config *conf6x = CHIP_FIELD(oct, cn6xxx, conf);
465
466                 tx_max_pending = CN6XXX_MAX_IQ_DESCRIPTORS;
467                 rx_max_pending = CN6XXX_MAX_OQ_DESCRIPTORS;
468                 rx_pending = CFG_GET_NUM_RX_DESCS_NIC_IF(conf6x, lio->ifidx);
469                 tx_pending = CFG_GET_NUM_TX_DESCS_NIC_IF(conf6x, lio->ifidx);
470         }
471
472         if (lio->mtu > OCTNET_DEFAULT_FRM_SIZE) {
473                 ering->rx_pending = 0;
474                 ering->rx_max_pending = 0;
475                 ering->rx_mini_pending = 0;
476                 ering->rx_jumbo_pending = rx_pending;
477                 ering->rx_mini_max_pending = 0;
478                 ering->rx_jumbo_max_pending = rx_max_pending;
479         } else {
480                 ering->rx_pending = rx_pending;
481                 ering->rx_max_pending = rx_max_pending;
482                 ering->rx_mini_pending = 0;
483                 ering->rx_jumbo_pending = 0;
484                 ering->rx_mini_max_pending = 0;
485                 ering->rx_jumbo_max_pending = 0;
486         }
487
488         ering->tx_pending = tx_pending;
489         ering->tx_max_pending = tx_max_pending;
490 }
491
492 static u32 lio_get_msglevel(struct net_device *netdev)
493 {
494         struct lio *lio = GET_LIO(netdev);
495
496         return lio->msg_enable;
497 }
498
499 static void lio_set_msglevel(struct net_device *netdev, u32 msglvl)
500 {
501         struct lio *lio = GET_LIO(netdev);
502
503         if ((msglvl ^ lio->msg_enable) & NETIF_MSG_HW) {
504                 if (msglvl & NETIF_MSG_HW)
505                         liquidio_set_feature(netdev,
506                                              OCTNET_CMD_VERBOSE_ENABLE);
507                 else
508                         liquidio_set_feature(netdev,
509                                              OCTNET_CMD_VERBOSE_DISABLE);
510         }
511
512         lio->msg_enable = msglvl;
513 }
514
515 static void
516 lio_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause)
517 {
518         /* Notes: Not supporting any auto negotiation in these
519          * drivers. Just report pause frame support.
520          */
521         pause->tx_pause = 1;
522         pause->rx_pause = 1;    /* TODO: Need to support RX pause frame!!. */
523 }
524
525 static void
526 lio_get_ethtool_stats(struct net_device *netdev,
527                       struct ethtool_stats *stats, u64 *data)
528 {
529         struct lio *lio = GET_LIO(netdev);
530         struct octeon_device *oct_dev = lio->oct_dev;
531         int i = 0, j;
532
533         for (j = 0; j < MAX_OCTEON_INSTR_QUEUES; j++) {
534                 if (!(oct_dev->io_qmask.iq & (1UL << j)))
535                         continue;
536                 data[i++] =
537                         CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_posted);
538                 data[i++] =
539                         CVM_CAST64(
540                                 oct_dev->instr_queue[j]->stats.instr_processed);
541                 data[i++] =
542                         CVM_CAST64(
543                                 oct_dev->instr_queue[j]->stats.instr_dropped);
544                 data[i++] =
545                         CVM_CAST64(oct_dev->instr_queue[j]->stats.bytes_sent);
546                 data[i++] =
547                         CVM_CAST64(oct_dev->instr_queue[j]->stats.sgentry_sent);
548                 data[i++] =
549                         readl(oct_dev->instr_queue[j]->inst_cnt_reg);
550                 data[i++] =
551                         CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_done);
552                 data[i++] =
553                         CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_iq_busy);
554                 data[i++] =
555                         CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_dropped);
556                 data[i++] =
557                         CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_tot_bytes);
558         }
559
560         /* for (j = 0; j < oct_dev->num_oqs; j++){ */
561         for (j = 0; j < MAX_OCTEON_OUTPUT_QUEUES; j++) {
562                 if (!(oct_dev->io_qmask.oq & (1UL << j)))
563                         continue;
564                 data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.pkts_received);
565                 data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.bytes_received);
566                 data[i++] =
567                         CVM_CAST64(oct_dev->droq[j]->stats.dropped_nodispatch);
568                 data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem);
569                 data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_toomany);
570                 data[i++] =
571                         CVM_CAST64(oct_dev->droq[j]->stats.rx_pkts_received);
572                 data[i++] =
573                         CVM_CAST64(oct_dev->droq[j]->stats.rx_bytes_received);
574                 data[i++] =
575                         CVM_CAST64(oct_dev->droq[j]->stats.rx_dropped);
576         }
577 }
578
579 static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
580 {
581         struct lio *lio = GET_LIO(netdev);
582         struct octeon_device *oct_dev = lio->oct_dev;
583         int num_iq_stats, num_oq_stats, i, j;
584
585         num_iq_stats = ARRAY_SIZE(oct_iq_stats_strings);
586         for (i = 0; i < MAX_OCTEON_INSTR_QUEUES; i++) {
587                 if (!(oct_dev->io_qmask.iq & (1UL << i)))
588                         continue;
589                 for (j = 0; j < num_iq_stats; j++) {
590                         sprintf(data, "IQ%d %s", i, oct_iq_stats_strings[j]);
591                         data += ETH_GSTRING_LEN;
592                 }
593         }
594
595         num_oq_stats = ARRAY_SIZE(oct_droq_stats_strings);
596         /* for (i = 0; i < oct_dev->num_oqs; i++) { */
597         for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES; i++) {
598                 if (!(oct_dev->io_qmask.oq & (1UL << i)))
599                         continue;
600                 for (j = 0; j < num_oq_stats; j++) {
601                         sprintf(data, "OQ%d %s", i, oct_droq_stats_strings[j]);
602                         data += ETH_GSTRING_LEN;
603                 }
604         }
605 }
606
607 static int lio_get_sset_count(struct net_device *netdev, int sset)
608 {
609         struct lio *lio = GET_LIO(netdev);
610         struct octeon_device *oct_dev = lio->oct_dev;
611
612         return (ARRAY_SIZE(oct_iq_stats_strings) * oct_dev->num_iqs) +
613                (ARRAY_SIZE(oct_droq_stats_strings) * oct_dev->num_oqs);
614 }
615
616 static int lio_get_intr_coalesce(struct net_device *netdev,
617                                  struct ethtool_coalesce *intr_coal)
618 {
619         struct lio *lio = GET_LIO(netdev);
620         struct octeon_device *oct = lio->oct_dev;
621         struct octeon_cn6xxx *cn6xxx = (struct octeon_cn6xxx *)oct->chip;
622         struct octeon_instr_queue *iq;
623         struct oct_intrmod_cfg *intrmod_cfg;
624
625         intrmod_cfg = &oct->intrmod;
626
627         switch (oct->chip_id) {
628         /* case OCTEON_CN73XX: Todo */
629         /*      break; */
630         case OCTEON_CN68XX:
631         case OCTEON_CN66XX:
632                 if (!intrmod_cfg->intrmod_enable) {
633                         intr_coal->rx_coalesce_usecs =
634                                 CFG_GET_OQ_INTR_TIME(cn6xxx->conf);
635                         intr_coal->rx_max_coalesced_frames =
636                                 CFG_GET_OQ_INTR_PKT(cn6xxx->conf);
637                 } else {
638                         intr_coal->use_adaptive_rx_coalesce =
639                                 intrmod_cfg->intrmod_enable;
640                         intr_coal->rate_sample_interval =
641                                 intrmod_cfg->intrmod_check_intrvl;
642                         intr_coal->pkt_rate_high =
643                                 intrmod_cfg->intrmod_maxpkt_ratethr;
644                         intr_coal->pkt_rate_low =
645                                 intrmod_cfg->intrmod_minpkt_ratethr;
646                         intr_coal->rx_max_coalesced_frames_high =
647                                 intrmod_cfg->intrmod_maxcnt_trigger;
648                         intr_coal->rx_coalesce_usecs_high =
649                                 intrmod_cfg->intrmod_maxtmr_trigger;
650                         intr_coal->rx_coalesce_usecs_low =
651                                 intrmod_cfg->intrmod_mintmr_trigger;
652                         intr_coal->rx_max_coalesced_frames_low =
653                                 intrmod_cfg->intrmod_mincnt_trigger;
654                 }
655
656                 iq = oct->instr_queue[lio->linfo.txpciq[0]];
657                 intr_coal->tx_max_coalesced_frames = iq->fill_threshold;
658                 break;
659
660         default:
661                 netif_info(lio, drv, lio->netdev, "Unknown Chip !!\n");
662                 return -EINVAL;
663         }
664
665         return 0;
666 }
667
668 /* Callback function for intrmod */
669 static void octnet_intrmod_callback(struct octeon_device *oct_dev,
670                                     u32 status,
671                                     void *ptr)
672 {
673         struct oct_intrmod_cmd *cmd = ptr;
674         struct octeon_soft_command *sc = cmd->sc;
675
676         oct_dev = cmd->oct_dev;
677
678         if (status)
679                 dev_err(&oct_dev->pci_dev->dev, "intrmod config failed. Status: %llx\n",
680                         CVM_CAST64(status));
681         else
682                 dev_info(&oct_dev->pci_dev->dev,
683                          "Rx-Adaptive Interrupt moderation enabled:%llx\n",
684                          oct_dev->intrmod.intrmod_enable);
685
686         octeon_free_soft_command(oct_dev, sc);
687 }
688
689 /*  Configure interrupt moderation parameters */
690 static int octnet_set_intrmod_cfg(void *oct, struct oct_intrmod_cfg *intr_cfg)
691 {
692         struct octeon_soft_command *sc;
693         struct oct_intrmod_cmd *cmd;
694         struct oct_intrmod_cfg *cfg;
695         int retval;
696         struct octeon_device *oct_dev = (struct octeon_device *)oct;
697
698         /* Alloc soft command */
699         sc = (struct octeon_soft_command *)
700                 octeon_alloc_soft_command(oct_dev,
701                                           sizeof(struct oct_intrmod_cfg),
702                                           0,
703                                           sizeof(struct oct_intrmod_cmd));
704
705         if (!sc)
706                 return -ENOMEM;
707
708         cmd = (struct oct_intrmod_cmd *)sc->ctxptr;
709         cfg = (struct oct_intrmod_cfg *)sc->virtdptr;
710
711         memcpy(cfg, intr_cfg, sizeof(struct oct_intrmod_cfg));
712         octeon_swap_8B_data((u64 *)cfg, (sizeof(struct oct_intrmod_cfg)) / 8);
713         cmd->sc = sc;
714         cmd->cfg = cfg;
715         cmd->oct_dev = oct_dev;
716
717         octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC,
718                                     OPCODE_NIC_INTRMOD_CFG, 0, 0, 0);
719
720         sc->callback = octnet_intrmod_callback;
721         sc->callback_arg = cmd;
722         sc->wait_time = 1000;
723
724         retval = octeon_send_soft_command(oct_dev, sc);
725         if (retval) {
726                 octeon_free_soft_command(oct_dev, sc);
727                 return -EINVAL;
728         }
729
730         return 0;
731 }
732
733 /* Enable/Disable auto interrupt Moderation */
734 static int oct_cfg_adaptive_intr(struct lio *lio, struct ethtool_coalesce
735                                  *intr_coal, int adaptive)
736 {
737         int ret = 0;
738         struct octeon_device *oct = lio->oct_dev;
739         struct oct_intrmod_cfg *intrmod_cfg;
740
741         intrmod_cfg = &oct->intrmod;
742
743         if (adaptive) {
744                 if (intr_coal->rate_sample_interval)
745                         intrmod_cfg->intrmod_check_intrvl =
746                                 intr_coal->rate_sample_interval;
747                 else
748                         intrmod_cfg->intrmod_check_intrvl =
749                                 LIO_INTRMOD_CHECK_INTERVAL;
750
751                 if (intr_coal->pkt_rate_high)
752                         intrmod_cfg->intrmod_maxpkt_ratethr =
753                                 intr_coal->pkt_rate_high;
754                 else
755                         intrmod_cfg->intrmod_maxpkt_ratethr =
756                                 LIO_INTRMOD_MAXPKT_RATETHR;
757
758                 if (intr_coal->pkt_rate_low)
759                         intrmod_cfg->intrmod_minpkt_ratethr =
760                                 intr_coal->pkt_rate_low;
761                 else
762                         intrmod_cfg->intrmod_minpkt_ratethr =
763                                 LIO_INTRMOD_MINPKT_RATETHR;
764
765                 if (intr_coal->rx_max_coalesced_frames_high)
766                         intrmod_cfg->intrmod_maxcnt_trigger =
767                                 intr_coal->rx_max_coalesced_frames_high;
768                 else
769                         intrmod_cfg->intrmod_maxcnt_trigger =
770                                 LIO_INTRMOD_MAXCNT_TRIGGER;
771
772                 if (intr_coal->rx_coalesce_usecs_high)
773                         intrmod_cfg->intrmod_maxtmr_trigger =
774                                 intr_coal->rx_coalesce_usecs_high;
775                 else
776                         intrmod_cfg->intrmod_maxtmr_trigger =
777                                 LIO_INTRMOD_MAXTMR_TRIGGER;
778
779                 if (intr_coal->rx_coalesce_usecs_low)
780                         intrmod_cfg->intrmod_mintmr_trigger =
781                                 intr_coal->rx_coalesce_usecs_low;
782                 else
783                         intrmod_cfg->intrmod_mintmr_trigger =
784                                 LIO_INTRMOD_MINTMR_TRIGGER;
785
786                 if (intr_coal->rx_max_coalesced_frames_low)
787                         intrmod_cfg->intrmod_mincnt_trigger =
788                                 intr_coal->rx_max_coalesced_frames_low;
789                 else
790                         intrmod_cfg->intrmod_mincnt_trigger =
791                                 LIO_INTRMOD_MINCNT_TRIGGER;
792         }
793
794         intrmod_cfg->intrmod_enable = adaptive;
795         ret = octnet_set_intrmod_cfg(oct, intrmod_cfg);
796
797         return ret;
798 }
799
800 static int
801 oct_cfg_rx_intrcnt(struct lio *lio, struct ethtool_coalesce *intr_coal)
802 {
803         int ret;
804         struct octeon_device *oct = lio->oct_dev;
805         struct octeon_cn6xxx *cn6xxx = (struct octeon_cn6xxx *)oct->chip;
806         u32 rx_max_coalesced_frames;
807
808         if (!intr_coal->rx_max_coalesced_frames)
809                 rx_max_coalesced_frames = CN6XXX_OQ_INTR_PKT;
810         else
811                 rx_max_coalesced_frames = intr_coal->rx_max_coalesced_frames;
812
813         /* Disable adaptive interrupt modulation */
814         ret = oct_cfg_adaptive_intr(lio, intr_coal, 0);
815         if (ret)
816                 return ret;
817
818         /* Config Cnt based interrupt values */
819         octeon_write_csr(oct, CN6XXX_SLI_OQ_INT_LEVEL_PKTS,
820                          rx_max_coalesced_frames);
821         CFG_SET_OQ_INTR_PKT(cn6xxx->conf, rx_max_coalesced_frames);
822         return 0;
823 }
824
825 static int oct_cfg_rx_intrtime(struct lio *lio, struct ethtool_coalesce
826                                *intr_coal)
827 {
828         int ret;
829         struct octeon_device *oct = lio->oct_dev;
830         struct octeon_cn6xxx *cn6xxx = (struct octeon_cn6xxx *)oct->chip;
831         u32 time_threshold, rx_coalesce_usecs;
832
833         if (!intr_coal->rx_coalesce_usecs)
834                 rx_coalesce_usecs = CN6XXX_OQ_INTR_TIME;
835         else
836                 rx_coalesce_usecs = intr_coal->rx_coalesce_usecs;
837
838         /* Disable adaptive interrupt modulation */
839         ret = oct_cfg_adaptive_intr(lio, intr_coal, 0);
840         if (ret)
841                 return ret;
842
843         /* Config Time based interrupt values */
844         time_threshold = lio_cn6xxx_get_oq_ticks(oct, rx_coalesce_usecs);
845         octeon_write_csr(oct, CN6XXX_SLI_OQ_INT_LEVEL_TIME, time_threshold);
846         CFG_SET_OQ_INTR_TIME(cn6xxx->conf, rx_coalesce_usecs);
847
848         return 0;
849 }
850
851 static int lio_set_intr_coalesce(struct net_device *netdev,
852                                  struct ethtool_coalesce *intr_coal)
853 {
854         struct lio *lio = GET_LIO(netdev);
855         int ret;
856         struct octeon_device *oct = lio->oct_dev;
857         u32 j, q_no;
858
859         if ((intr_coal->tx_max_coalesced_frames >= CN6XXX_DB_MIN) &&
860             (intr_coal->tx_max_coalesced_frames <= CN6XXX_DB_MAX)) {
861                 for (j = 0; j < lio->linfo.num_txpciq; j++) {
862                         q_no = lio->linfo.txpciq[j];
863                         oct->instr_queue[q_no]->fill_threshold =
864                                 intr_coal->tx_max_coalesced_frames;
865                 }
866         } else {
867                 dev_err(&oct->pci_dev->dev,
868                         "LIQUIDIO: Invalid tx-frames:%d. Range is min:%d max:%d\n",
869                         intr_coal->tx_max_coalesced_frames, CN6XXX_DB_MIN,
870                         CN6XXX_DB_MAX);
871                 return -EINVAL;
872         }
873
874         /* User requested adaptive-rx on */
875         if (intr_coal->use_adaptive_rx_coalesce) {
876                 ret = oct_cfg_adaptive_intr(lio, intr_coal, 1);
877                 if (ret)
878                         goto ret_intrmod;
879         }
880
881         /* User requested adaptive-rx off and rx coalesce */
882         if ((intr_coal->rx_coalesce_usecs) &&
883             (!intr_coal->use_adaptive_rx_coalesce)) {
884                 ret = oct_cfg_rx_intrtime(lio, intr_coal);
885                 if (ret)
886                         goto ret_intrmod;
887         }
888
889         /* User requested adaptive-rx off and rx coalesce */
890         if ((intr_coal->rx_max_coalesced_frames) &&
891             (!intr_coal->use_adaptive_rx_coalesce)) {
892                 ret = oct_cfg_rx_intrcnt(lio, intr_coal);
893                 if (ret)
894                         goto ret_intrmod;
895         }
896
897         /* User requested adaptive-rx off, so use default coalesce params */
898         if ((!intr_coal->rx_max_coalesced_frames) &&
899             (!intr_coal->use_adaptive_rx_coalesce) &&
900             (!intr_coal->rx_coalesce_usecs)) {
901                 dev_info(&oct->pci_dev->dev,
902                          "Turning off adaptive-rx interrupt moderation\n");
903                 dev_info(&oct->pci_dev->dev,
904                          "Using RX Coalesce Default values rx_coalesce_usecs:%d rx_max_coalesced_frames:%d\n",
905                          CN6XXX_OQ_INTR_TIME, CN6XXX_OQ_INTR_PKT);
906                 ret = oct_cfg_rx_intrtime(lio, intr_coal);
907                 if (ret)
908                         goto ret_intrmod;
909
910                 ret = oct_cfg_rx_intrcnt(lio, intr_coal);
911                 if (ret)
912                         goto ret_intrmod;
913         }
914
915         return 0;
916 ret_intrmod:
917         return ret;
918 }
919
920 static int lio_get_ts_info(struct net_device *netdev,
921                            struct ethtool_ts_info *info)
922 {
923         struct lio *lio = GET_LIO(netdev);
924
925         info->so_timestamping =
926                 SOF_TIMESTAMPING_TX_HARDWARE |
927                 SOF_TIMESTAMPING_TX_SOFTWARE |
928                 SOF_TIMESTAMPING_RX_HARDWARE |
929                 SOF_TIMESTAMPING_RX_SOFTWARE |
930                 SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_RAW_HARDWARE;
931
932         if (lio->ptp_clock)
933                 info->phc_index = ptp_clock_index(lio->ptp_clock);
934         else
935                 info->phc_index = -1;
936
937         info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
938
939         info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
940                            (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
941                            (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
942                            (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT);
943
944         return 0;
945 }
946
947 static int lio_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
948 {
949         struct lio *lio = GET_LIO(netdev);
950         struct octeon_device *oct = lio->oct_dev;
951         struct oct_link_info *linfo;
952         struct octnic_ctrl_pkt nctrl;
953         struct octnic_ctrl_params nparams;
954         int ret = 0;
955
956         /* get the link info */
957         linfo = &lio->linfo;
958
959         if (ecmd->autoneg != AUTONEG_ENABLE && ecmd->autoneg != AUTONEG_DISABLE)
960                 return -EINVAL;
961
962         if (ecmd->autoneg == AUTONEG_DISABLE && ((ecmd->speed != SPEED_100 &&
963                                                   ecmd->speed != SPEED_10) ||
964                                                  (ecmd->duplex != DUPLEX_HALF &&
965                                                   ecmd->duplex != DUPLEX_FULL)))
966                 return -EINVAL;
967
968         /* Ethtool Support is not provided for XAUI and RXAUI Interfaces
969          * as they operate at fixed Speed and Duplex settings
970          */
971         if (linfo->link.s.interface == INTERFACE_MODE_XAUI ||
972             linfo->link.s.interface == INTERFACE_MODE_RXAUI) {
973                 dev_info(&oct->pci_dev->dev, "XAUI IFs settings cannot be modified.\n");
974                 return -EINVAL;
975         }
976
977         memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
978
979         nctrl.ncmd.u64 = 0;
980         nctrl.ncmd.s.cmd = OCTNET_CMD_SET_SETTINGS;
981         nctrl.wait_time = 1000;
982         nctrl.netpndev = (u64)netdev;
983         nctrl.ncmd.s.param1 = lio->linfo.ifidx;
984         nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
985
986         /* Passing the parameters sent by ethtool like Speed, Autoneg & Duplex
987          * to SE core application using ncmd.s.more & ncmd.s.param
988          */
989         if (ecmd->autoneg == AUTONEG_ENABLE) {
990                 /* Autoneg ON */
991                 nctrl.ncmd.s.more = OCTNIC_NCMD_PHY_ON |
992                                      OCTNIC_NCMD_AUTONEG_ON;
993                 nctrl.ncmd.s.param2 = ecmd->advertising;
994         } else {
995                 /* Autoneg OFF */
996                 nctrl.ncmd.s.more = OCTNIC_NCMD_PHY_ON;
997
998                 nctrl.ncmd.s.param3 = ecmd->duplex;
999
1000                 nctrl.ncmd.s.param2 = ecmd->speed;
1001         }
1002
1003         nparams.resp_order = OCTEON_RESP_ORDERED;
1004
1005         ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl, nparams);
1006         if (ret < 0) {
1007                 dev_err(&oct->pci_dev->dev, "Failed to set settings\n");
1008                 return -1;
1009         }
1010
1011         return 0;
1012 }
1013
1014 static int lio_nway_reset(struct net_device *netdev)
1015 {
1016         if (netif_running(netdev)) {
1017                 struct ethtool_cmd ecmd;
1018
1019                 memset(&ecmd, 0, sizeof(struct ethtool_cmd));
1020                 ecmd.autoneg = 0;
1021                 ecmd.speed = 0;
1022                 ecmd.duplex = 0;
1023                 lio_set_settings(netdev, &ecmd);
1024         }
1025         return 0;
1026 }
1027
1028 /* Return register dump len. */
1029 static int lio_get_regs_len(struct net_device *dev)
1030 {
1031         return OCT_ETHTOOL_REGDUMP_LEN;
1032 }
1033
1034 static int cn6xxx_read_csr_reg(char *s, struct octeon_device *oct)
1035 {
1036         u32 reg;
1037         int i, len = 0;
1038
1039         /* PCI  Window Registers */
1040
1041         len += sprintf(s + len, "\n\t Octeon CSR Registers\n\n");
1042         reg = CN6XXX_WIN_WR_ADDR_LO;
1043         len += sprintf(s + len, "\n[%02x] (WIN_WR_ADDR_LO): %08x\n",
1044                        CN6XXX_WIN_WR_ADDR_LO, octeon_read_csr(oct, reg));
1045         reg = CN6XXX_WIN_WR_ADDR_HI;
1046         len += sprintf(s + len, "[%02x] (WIN_WR_ADDR_HI): %08x\n",
1047                        CN6XXX_WIN_WR_ADDR_HI, octeon_read_csr(oct, reg));
1048         reg = CN6XXX_WIN_RD_ADDR_LO;
1049         len += sprintf(s + len, "[%02x] (WIN_RD_ADDR_LO): %08x\n",
1050                        CN6XXX_WIN_RD_ADDR_LO, octeon_read_csr(oct, reg));
1051         reg = CN6XXX_WIN_RD_ADDR_HI;
1052         len += sprintf(s + len, "[%02x] (WIN_RD_ADDR_HI): %08x\n",
1053                        CN6XXX_WIN_RD_ADDR_HI, octeon_read_csr(oct, reg));
1054         reg = CN6XXX_WIN_WR_DATA_LO;
1055         len += sprintf(s + len, "[%02x] (WIN_WR_DATA_LO): %08x\n",
1056                        CN6XXX_WIN_WR_DATA_LO, octeon_read_csr(oct, reg));
1057         reg = CN6XXX_WIN_WR_DATA_HI;
1058         len += sprintf(s + len, "[%02x] (WIN_WR_DATA_HI): %08x\n",
1059                        CN6XXX_WIN_WR_DATA_HI, octeon_read_csr(oct, reg));
1060         len += sprintf(s + len, "[%02x] (WIN_WR_MASK_REG): %08x\n",
1061                        CN6XXX_WIN_WR_MASK_REG,
1062                        octeon_read_csr(oct, CN6XXX_WIN_WR_MASK_REG));
1063
1064         /* PCI  Interrupt Register */
1065         len += sprintf(s + len, "\n[%x] (INT_ENABLE PORT 0): %08x\n",
1066                        CN6XXX_SLI_INT_ENB64_PORT0, octeon_read_csr(oct,
1067                                                 CN6XXX_SLI_INT_ENB64_PORT0));
1068         len += sprintf(s + len, "\n[%x] (INT_ENABLE PORT 1): %08x\n",
1069                        CN6XXX_SLI_INT_ENB64_PORT1,
1070                        octeon_read_csr(oct, CN6XXX_SLI_INT_ENB64_PORT1));
1071         len += sprintf(s + len, "[%x] (INT_SUM): %08x\n", CN6XXX_SLI_INT_SUM64,
1072                        octeon_read_csr(oct, CN6XXX_SLI_INT_SUM64));
1073
1074         /* PCI  Output queue registers */
1075         for (i = 0; i < oct->num_oqs; i++) {
1076                 reg = CN6XXX_SLI_OQ_PKTS_SENT(i);
1077                 len += sprintf(s + len, "\n[%x] (PKTS_SENT_%d): %08x\n",
1078                                reg, i, octeon_read_csr(oct, reg));
1079                 reg = CN6XXX_SLI_OQ_PKTS_CREDIT(i);
1080                 len += sprintf(s + len, "[%x] (PKT_CREDITS_%d): %08x\n",
1081                                reg, i, octeon_read_csr(oct, reg));
1082         }
1083         reg = CN6XXX_SLI_OQ_INT_LEVEL_PKTS;
1084         len += sprintf(s + len, "\n[%x] (PKTS_SENT_INT_LEVEL): %08x\n",
1085                        reg, octeon_read_csr(oct, reg));
1086         reg = CN6XXX_SLI_OQ_INT_LEVEL_TIME;
1087         len += sprintf(s + len, "[%x] (PKTS_SENT_TIME): %08x\n",
1088                        reg, octeon_read_csr(oct, reg));
1089
1090         /* PCI  Input queue registers */
1091         for (i = 0; i <= 3; i++) {
1092                 u32 reg;
1093
1094                 reg = CN6XXX_SLI_IQ_DOORBELL(i);
1095                 len += sprintf(s + len, "\n[%x] (INSTR_DOORBELL_%d): %08x\n",
1096                                reg, i, octeon_read_csr(oct, reg));
1097                 reg = CN6XXX_SLI_IQ_INSTR_COUNT(i);
1098                 len += sprintf(s + len, "[%x] (INSTR_COUNT_%d): %08x\n",
1099                                reg, i, octeon_read_csr(oct, reg));
1100         }
1101
1102         /* PCI  DMA registers */
1103
1104         len += sprintf(s + len, "\n[%x] (DMA_CNT_0): %08x\n",
1105                        CN6XXX_DMA_CNT(0),
1106                        octeon_read_csr(oct, CN6XXX_DMA_CNT(0)));
1107         reg = CN6XXX_DMA_PKT_INT_LEVEL(0);
1108         len += sprintf(s + len, "[%x] (DMA_INT_LEV_0): %08x\n",
1109                        CN6XXX_DMA_PKT_INT_LEVEL(0), octeon_read_csr(oct, reg));
1110         reg = CN6XXX_DMA_TIME_INT_LEVEL(0);
1111         len += sprintf(s + len, "[%x] (DMA_TIME_0): %08x\n",
1112                        CN6XXX_DMA_TIME_INT_LEVEL(0),
1113                        octeon_read_csr(oct, reg));
1114
1115         len += sprintf(s + len, "\n[%x] (DMA_CNT_1): %08x\n",
1116                        CN6XXX_DMA_CNT(1),
1117                        octeon_read_csr(oct, CN6XXX_DMA_CNT(1)));
1118         reg = CN6XXX_DMA_PKT_INT_LEVEL(1);
1119         len += sprintf(s + len, "[%x] (DMA_INT_LEV_1): %08x\n",
1120                        CN6XXX_DMA_PKT_INT_LEVEL(1),
1121                        octeon_read_csr(oct, reg));
1122         reg = CN6XXX_DMA_PKT_INT_LEVEL(1);
1123         len += sprintf(s + len, "[%x] (DMA_TIME_1): %08x\n",
1124                        CN6XXX_DMA_TIME_INT_LEVEL(1),
1125                        octeon_read_csr(oct, reg));
1126
1127         /* PCI  Index registers */
1128
1129         len += sprintf(s + len, "\n");
1130
1131         for (i = 0; i < 16; i++) {
1132                 reg = lio_pci_readq(oct, CN6XXX_BAR1_REG(i, oct->pcie_port));
1133                 len += sprintf(s + len, "[%llx] (BAR1_INDEX_%02d): %08x\n",
1134                                CN6XXX_BAR1_REG(i, oct->pcie_port), i, reg);
1135         }
1136
1137         return len;
1138 }
1139
1140 static int cn6xxx_read_config_reg(char *s, struct octeon_device *oct)
1141 {
1142         u32 val;
1143         int i, len = 0;
1144
1145         /* PCI CONFIG Registers */
1146
1147         len += sprintf(s + len,
1148                        "\n\t Octeon Config space Registers\n\n");
1149
1150         for (i = 0; i <= 13; i++) {
1151                 pci_read_config_dword(oct->pci_dev, (i * 4), &val);
1152                 len += sprintf(s + len, "[0x%x] (Config[%d]): 0x%08x\n",
1153                                (i * 4), i, val);
1154         }
1155
1156         for (i = 30; i <= 34; i++) {
1157                 pci_read_config_dword(oct->pci_dev, (i * 4), &val);
1158                 len += sprintf(s + len, "[0x%x] (Config[%d]): 0x%08x\n",
1159                                (i * 4), i, val);
1160         }
1161
1162         return len;
1163 }
1164
1165 /*  Return register dump user app.  */
1166 static void lio_get_regs(struct net_device *dev,
1167                          struct ethtool_regs *regs, void *regbuf)
1168 {
1169         struct lio *lio = GET_LIO(dev);
1170         int len = 0;
1171         struct octeon_device *oct = lio->oct_dev;
1172
1173         memset(regbuf, 0, OCT_ETHTOOL_REGDUMP_LEN);
1174         regs->version = OCT_ETHTOOL_REGSVER;
1175
1176         switch (oct->chip_id) {
1177         /* case OCTEON_CN73XX: Todo */
1178         case OCTEON_CN68XX:
1179         case OCTEON_CN66XX:
1180                 len += cn6xxx_read_csr_reg(regbuf + len, oct);
1181                 len += cn6xxx_read_config_reg(regbuf + len, oct);
1182                 break;
1183         default:
1184                 dev_err(&oct->pci_dev->dev, "%s Unknown chipid: %d\n",
1185                         __func__, oct->chip_id);
1186         }
1187 }
1188
1189 static const struct ethtool_ops lio_ethtool_ops = {
1190         .get_settings           = lio_get_settings,
1191         .get_link               = ethtool_op_get_link,
1192         .get_drvinfo            = lio_get_drvinfo,
1193         .get_ringparam          = lio_ethtool_get_ringparam,
1194         .get_channels           = lio_ethtool_get_channels,
1195         .set_phys_id            = lio_set_phys_id,
1196         .get_eeprom_len         = lio_get_eeprom_len,
1197         .get_eeprom             = lio_get_eeprom,
1198         .get_strings            = lio_get_strings,
1199         .get_ethtool_stats      = lio_get_ethtool_stats,
1200         .get_pauseparam         = lio_get_pauseparam,
1201         .get_regs_len           = lio_get_regs_len,
1202         .get_regs               = lio_get_regs,
1203         .get_msglevel           = lio_get_msglevel,
1204         .set_msglevel           = lio_set_msglevel,
1205         .get_sset_count         = lio_get_sset_count,
1206         .nway_reset             = lio_nway_reset,
1207         .set_settings           = lio_set_settings,
1208         .get_coalesce           = lio_get_intr_coalesce,
1209         .set_coalesce           = lio_set_intr_coalesce,
1210         .get_ts_info            = lio_get_ts_info,
1211 };
1212
1213 void liquidio_set_ethtool_ops(struct net_device *netdev)
1214 {
1215         netdev->ethtool_ops = &lio_ethtool_ops;
1216 }