Re: [PATCH net-next] liquidio: Add the features to show FEC settings and set FEC settings

2018-09-17 Thread David Miller
From: Felix Manlunas 
Date: Sun, 16 Sep 2018 22:43:32 -0700

> From: Weilin Chang 
> 
> 1. Add functions for get_fecparam and set_fecparam.
> 2. Modify lio_get_link_ksettings to display FEC setting.
> 
> Signed-off-by: Weilin Chang 
> Acked-by: Derek Chickles 
> Signed-off-by: Felix Manlunas 

Applied.


[PATCH net-next] liquidio: Add the features to show FEC settings and set FEC settings

2018-09-16 Thread Felix Manlunas
From: Weilin Chang 

1. Add functions for get_fecparam and set_fecparam.
2. Modify lio_get_link_ksettings to display FEC setting.

Signed-off-by: Weilin Chang 
Acked-by: Derek Chickles 
Signed-off-by: Felix Manlunas 
---
 drivers/net/ethernet/cavium/liquidio/lio_core.c| 148 +
 drivers/net/ethernet/cavium/liquidio/lio_ethtool.c |  76 ++-
 drivers/net/ethernet/cavium/liquidio/lio_main.c|   8 ++
 .../net/ethernet/cavium/liquidio/liquidio_common.h |   5 +
 .../net/ethernet/cavium/liquidio/octeon_device.h   |   2 +
 .../net/ethernet/cavium/liquidio/octeon_network.h  |   7 +-
 6 files changed, 243 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cavium/liquidio/lio_core.c 
b/drivers/net/ethernet/cavium/liquidio/lio_core.c
index 52b32b8..eb96b06 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_core.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_core.c
@@ -1654,3 +1654,151 @@ int liquidio_get_speed(struct lio *lio)
 
return retval;
 }
+
+int liquidio_set_fec(struct lio *lio, int on_off)
+{
+   struct oct_nic_seapi_resp *resp;
+   struct octeon_soft_command *sc;
+   struct octeon_device *oct;
+   union octnet_cmd *ncmd;
+   int retval;
+   u32 var;
+
+   oct = lio->oct_dev;
+
+   if (oct->props[lio->ifidx].fec == on_off)
+   return 0;
+
+   if (!OCTEON_CN23XX_PF(oct)) {
+   dev_err(>pci_dev->dev, "%s: SET FEC only for PF\n",
+   __func__);
+   return -1;
+   }
+
+   if (oct->speed_boot != 25)  {
+   dev_err(>pci_dev->dev,
+   "Set FEC only when link speed is 25G during insmod\n");
+   return -1;
+   }
+
+   sc = octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE,
+  sizeof(struct oct_nic_seapi_resp), 0);
+
+   ncmd = sc->virtdptr;
+   resp = sc->virtrptr;
+   memset(resp, 0, sizeof(struct oct_nic_seapi_resp));
+
+   init_completion(>complete);
+   sc->sc_status = OCTEON_REQUEST_PENDING;
+
+   ncmd->u64 = 0;
+   ncmd->s.cmd = SEAPI_CMD_FEC_SET;
+   ncmd->s.param1 = on_off;
+   /* SEAPI_CMD_FEC_DISABLE(0) or SEAPI_CMD_FEC_RS(1) */
+
+   octeon_swap_8B_data((u64 *)ncmd, (OCTNET_CMD_SIZE >> 3));
+
+   sc->iq_no = lio->linfo.txpciq[0].s.q_no;
+
+   octeon_prepare_soft_command(oct, sc, OPCODE_NIC,
+   OPCODE_NIC_UBOOT_CTL, 0, 0, 0);
+
+   retval = octeon_send_soft_command(oct, sc);
+   if (retval == IQ_SEND_FAILED) {
+   dev_info(>pci_dev->dev, "Failed to send soft command\n");
+   octeon_free_soft_command(oct, sc);
+   return -EIO;
+   }
+
+   retval = wait_for_sc_completion_timeout(oct, sc, 0);
+   if (retval)
+   return (-EIO);
+
+   var = be32_to_cpu(resp->fec_setting);
+   resp->fec_setting = var;
+   if (var != on_off) {
+   dev_err(>pci_dev->dev,
+   "Setting failed fec= %x, expect %x\n",
+   var, on_off);
+   oct->props[lio->ifidx].fec = var;
+   if (resp->fec_setting == SEAPI_CMD_FEC_SET_RS)
+   oct->props[lio->ifidx].fec = 1;
+   else
+   oct->props[lio->ifidx].fec = 0;
+   }
+
+   WRITE_ONCE(sc->caller_is_done, true);
+
+   if (oct->props[lio->ifidx].fec !=
+   oct->props[lio->ifidx].fec_boot) {
+   dev_dbg(>pci_dev->dev,
+   "Reloade driver to chang fec to %s\n",
+   oct->props[lio->ifidx].fec ? "on" : "off");
+   }
+
+   return retval;
+}
+
+int liquidio_get_fec(struct lio *lio)
+{
+   struct oct_nic_seapi_resp *resp;
+   struct octeon_soft_command *sc;
+   struct octeon_device *oct;
+   union octnet_cmd *ncmd;
+   int retval;
+   u32 var;
+
+   oct = lio->oct_dev;
+
+   sc = octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE,
+  sizeof(struct oct_nic_seapi_resp), 0);
+   if (!sc)
+   return -ENOMEM;
+
+   ncmd = sc->virtdptr;
+   resp = sc->virtrptr;
+   memset(resp, 0, sizeof(struct oct_nic_seapi_resp));
+
+   init_completion(>complete);
+   sc->sc_status = OCTEON_REQUEST_PENDING;
+
+   ncmd->u64 = 0;
+   ncmd->s.cmd = SEAPI_CMD_FEC_GET;
+
+   octeon_swap_8B_data((u64 *)ncmd, (OCTNET_CMD_SIZE >> 3));
+
+   sc->iq_no = lio->linfo.txpciq[0].s.q_no;
+
+   octeon_prepare_soft_command(oct, sc, OPCODE_NIC,
+   OPCODE_NIC_UBOOT_CTL, 0, 0, 0);
+
+   retval = octeon_send_soft_command(oct, sc);
+   if (retval == IQ_SEND_FAILED) {
+   dev_info(>pci_dev->dev,
+"%s: Failed to send soft command\n", __func__);
+   octeon_free_soft_command(oct, sc);
+   return -EIO;
+   }
+
+   retval =