diff mbox series

[v2,2/3] net/ncsi: add NCSI Intel OEM command to keep PHY up

Message ID 20210708122754.555846-3-i.mikhaylov@yadro.com
State New
Headers show
Series net/ncsi: Add NCSI Intel OEM command to keep PHY link up | expand

Commit Message

Ivan Mikhaylov July 8, 2021, 12:27 p.m. UTC
This allows to keep PHY link up and prevents any channel resets during
the host load.

It is KEEP_PHY_LINK_UP option(Veto bit) in i210 datasheet which
block PHY reset and power state changes.

Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com>
---
 net/ncsi/Kconfig       |  6 ++++++
 net/ncsi/internal.h    |  5 +++++
 net/ncsi/ncsi-manage.c | 45 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

Comments

Joel Stanley July 12, 2021, 10:01 a.m. UTC | #1
On Thu, 8 Jul 2021 at 12:27, Ivan Mikhaylov <i.mikhaylov@yadro.com> wrote:
>

> This allows to keep PHY link up and prevents any channel resets during

> the host load.

>

> It is KEEP_PHY_LINK_UP option(Veto bit) in i210 datasheet which

> block PHY reset and power state changes.


How about using runtime configuration over using kconfig for this, so
the same kernel config can be used on different machines. Something
device tree based?

Another option is to use the netlink handler to send the OEM command
from userspace. Eddie has worked on this for an IBM machine, and I've
asked him to post those changes. I would prefer the kernel option
though.


>

> Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com>

> ---

>  net/ncsi/Kconfig       |  6 ++++++

>  net/ncsi/internal.h    |  5 +++++

>  net/ncsi/ncsi-manage.c | 45 ++++++++++++++++++++++++++++++++++++++++++

>  3 files changed, 56 insertions(+)

>

> diff --git a/net/ncsi/Kconfig b/net/ncsi/Kconfig

> index 93309081f5a4..ea1dd32b6b1f 100644

> --- a/net/ncsi/Kconfig

> +++ b/net/ncsi/Kconfig

> @@ -17,3 +17,9 @@ config NCSI_OEM_CMD_GET_MAC

>         help

>           This allows to get MAC address from NCSI firmware and set them back to

>                 controller.

> +config NCSI_OEM_CMD_KEEP_PHY

> +       bool "Keep PHY Link up"

> +       depends on NET_NCSI

> +       help

> +         This allows to keep PHY link up and prevents any channel resets during

> +         the host load.

> diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h

> index cbbb0de4750a..0b6cfd3b31e0 100644

> --- a/net/ncsi/internal.h

> +++ b/net/ncsi/internal.h

> @@ -78,6 +78,9 @@ enum {

>  /* OEM Vendor Manufacture ID */

>  #define NCSI_OEM_MFR_MLX_ID             0x8119

>  #define NCSI_OEM_MFR_BCM_ID             0x113d

> +#define NCSI_OEM_MFR_INTEL_ID           0x157

> +/* Intel specific OEM command */

> +#define NCSI_OEM_INTEL_CMD_KEEP_PHY     0x20   /* CMD ID for Keep PHY up */

>  /* Broadcom specific OEM Command */

>  #define NCSI_OEM_BCM_CMD_GMA            0x01   /* CMD ID for Get MAC */

>  /* Mellanox specific OEM Command */

> @@ -86,6 +89,7 @@ enum {

>  #define NCSI_OEM_MLX_CMD_SMAF           0x01   /* CMD ID for Set MC Affinity */

>  #define NCSI_OEM_MLX_CMD_SMAF_PARAM     0x07   /* Parameter for SMAF         */

>  /* OEM Command payload lengths*/

> +#define NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN 7

>  #define NCSI_OEM_BCM_CMD_GMA_LEN        12

>  #define NCSI_OEM_MLX_CMD_GMA_LEN        8

>  #define NCSI_OEM_MLX_CMD_SMAF_LEN        60

> @@ -271,6 +275,7 @@ enum {

>         ncsi_dev_state_probe_mlx_gma,

>         ncsi_dev_state_probe_mlx_smaf,

>         ncsi_dev_state_probe_cis,

> +       ncsi_dev_state_probe_keep_phy,

>         ncsi_dev_state_probe_gvi,

>         ncsi_dev_state_probe_gc,

>         ncsi_dev_state_probe_gls,

> diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c

> index 42b54a3da2e6..89c7742cd72e 100644

> --- a/net/ncsi/ncsi-manage.c

> +++ b/net/ncsi/ncsi-manage.c

> @@ -689,6 +689,35 @@ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,

>         return 0;

>  }

>

> +#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)

> +

> +static int ncsi_oem_keep_phy_intel(struct ncsi_cmd_arg *nca)

> +{

> +       unsigned char data[NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN];

> +       int ret = 0;

> +

> +       nca->payload = NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN;

> +

> +       memset(data, 0, NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN);

> +       *(unsigned int *)data = ntohl((__force __be32)NCSI_OEM_MFR_INTEL_ID);

> +

> +       data[4] = NCSI_OEM_INTEL_CMD_KEEP_PHY;

> +

> +       /* PHY Link up attribute */

> +       data[6] = 0x1;

> +

> +       nca->data = data;

> +

> +       ret = ncsi_xmit_cmd(nca);

> +       if (ret)

> +               netdev_err(nca->ndp->ndev.dev,

> +                          "NCSI: Failed to transmit cmd 0x%x during configure\n",

> +                          nca->type);

> +       return ret;

> +}

> +

> +#endif

> +

>  #if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)

>

>  /* NCSI OEM Command APIs */

> @@ -1391,8 +1420,24 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)

>                                 goto error;

>                 }

>

> +               nd->state = ncsi_dev_state_probe_gvi;

> +               if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY))

> +                       nd->state = ncsi_dev_state_probe_keep_phy;

> +               break;

> +#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)

> +       case ncsi_dev_state_probe_keep_phy:

> +               ndp->pending_req_num = 1;

> +

> +               nca.type = NCSI_PKT_CMD_OEM;

> +               nca.package = ndp->active_package->id;

> +               nca.channel = 0;

> +               ret = ncsi_oem_keep_phy_intel(&nca);

> +               if (ret)

> +                       goto error;

> +

>                 nd->state = ncsi_dev_state_probe_gvi;

>                 break;

> +#endif /* CONFIG_NCSI_OEM_CMD_KEEP_PHY */

>         case ncsi_dev_state_probe_gvi:

>         case ncsi_dev_state_probe_gc:

>         case ncsi_dev_state_probe_gls:

> --

> 2.31.1

>
Eddie James July 12, 2021, 7:32 p.m. UTC | #2
On Mon, 2021-07-12 at 10:01 +0000, Joel Stanley wrote:
> On Thu, 8 Jul 2021 at 12:27, Ivan Mikhaylov <i.mikhaylov@yadro.com>

> wrote:

> > This allows to keep PHY link up and prevents any channel resets

> > during

> > the host load.

> > 

> > It is KEEP_PHY_LINK_UP option(Veto bit) in i210 datasheet which

> > block PHY reset and power state changes.

> 

> How about using runtime configuration over using kconfig for this, so

> the same kernel config can be used on different machines. Something

> device tree based?

> 

> Another option is to use the netlink handler to send the OEM command

> from userspace. Eddie has worked on this for an IBM machine, and I've

> asked him to post those changes. I would prefer the kernel option

> though.


For reference that is here: 
https://gerrit.openbmc-project.xyz/c/openbmc/phosphor-networkd/+/36592

Thanks,
Eddie

> 

> 

> > Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com>

> > ---

> >  net/ncsi/Kconfig       |  6 ++++++

> >  net/ncsi/internal.h    |  5 +++++

> >  net/ncsi/ncsi-manage.c | 45

> > ++++++++++++++++++++++++++++++++++++++++++

> >  3 files changed, 56 insertions(+)

> > 

> > diff --git a/net/ncsi/Kconfig b/net/ncsi/Kconfig

> > index 93309081f5a4..ea1dd32b6b1f 100644

> > --- a/net/ncsi/Kconfig

> > +++ b/net/ncsi/Kconfig

> > @@ -17,3 +17,9 @@ config NCSI_OEM_CMD_GET_MAC

> >         help

> >           This allows to get MAC address from NCSI firmware and set

> > them back to

> >                 controller.

> > +config NCSI_OEM_CMD_KEEP_PHY

> > +       bool "Keep PHY Link up"

> > +       depends on NET_NCSI

> > +       help

> > +         This allows to keep PHY link up and prevents any channel

> > resets during

> > +         the host load.

> > diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h

> > index cbbb0de4750a..0b6cfd3b31e0 100644

> > --- a/net/ncsi/internal.h

> > +++ b/net/ncsi/internal.h

> > @@ -78,6 +78,9 @@ enum {

> >  /* OEM Vendor Manufacture ID */

> >  #define NCSI_OEM_MFR_MLX_ID             0x8119

> >  #define NCSI_OEM_MFR_BCM_ID             0x113d

> > +#define NCSI_OEM_MFR_INTEL_ID           0x157

> > +/* Intel specific OEM command */

> > +#define NCSI_OEM_INTEL_CMD_KEEP_PHY     0x20   /* CMD ID for Keep

> > PHY up */

> >  /* Broadcom specific OEM Command */

> >  #define NCSI_OEM_BCM_CMD_GMA            0x01   /* CMD ID for Get

> > MAC */

> >  /* Mellanox specific OEM Command */

> > @@ -86,6 +89,7 @@ enum {

> >  #define NCSI_OEM_MLX_CMD_SMAF           0x01   /* CMD ID for Set

> > MC Affinity */

> >  #define NCSI_OEM_MLX_CMD_SMAF_PARAM     0x07   /* Parameter for

> > SMAF         */

> >  /* OEM Command payload lengths*/

> > +#define NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN 7

> >  #define NCSI_OEM_BCM_CMD_GMA_LEN        12

> >  #define NCSI_OEM_MLX_CMD_GMA_LEN        8

> >  #define NCSI_OEM_MLX_CMD_SMAF_LEN        60

> > @@ -271,6 +275,7 @@ enum {

> >         ncsi_dev_state_probe_mlx_gma,

> >         ncsi_dev_state_probe_mlx_smaf,

> >         ncsi_dev_state_probe_cis,

> > +       ncsi_dev_state_probe_keep_phy,

> >         ncsi_dev_state_probe_gvi,

> >         ncsi_dev_state_probe_gc,

> >         ncsi_dev_state_probe_gls,

> > diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c

> > index 42b54a3da2e6..89c7742cd72e 100644

> > --- a/net/ncsi/ncsi-manage.c

> > +++ b/net/ncsi/ncsi-manage.c

> > @@ -689,6 +689,35 @@ static int set_one_vid(struct ncsi_dev_priv

> > *ndp, struct ncsi_channel *nc,

> >         return 0;

> >  }

> > 

> > +#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)

> > +

> > +static int ncsi_oem_keep_phy_intel(struct ncsi_cmd_arg *nca)

> > +{

> > +       unsigned char data[NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN];

> > +       int ret = 0;

> > +

> > +       nca->payload = NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN;

> > +

> > +       memset(data, 0, NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN);

> > +       *(unsigned int *)data = ntohl((__force

> > __be32)NCSI_OEM_MFR_INTEL_ID);

> > +

> > +       data[4] = NCSI_OEM_INTEL_CMD_KEEP_PHY;

> > +

> > +       /* PHY Link up attribute */

> > +       data[6] = 0x1;

> > +

> > +       nca->data = data;

> > +

> > +       ret = ncsi_xmit_cmd(nca);

> > +       if (ret)

> > +               netdev_err(nca->ndp->ndev.dev,

> > +                          "NCSI: Failed to transmit cmd 0x%x

> > during configure\n",

> > +                          nca->type);

> > +       return ret;

> > +}

> > +

> > +#endif

> > +

> >  #if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)

> > 

> >  /* NCSI OEM Command APIs */

> > @@ -1391,8 +1420,24 @@ static void ncsi_probe_channel(struct

> > ncsi_dev_priv *ndp)

> >                                 goto error;

> >                 }

> > 

> > +               nd->state = ncsi_dev_state_probe_gvi;

> > +               if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY))

> > +                       nd->state = ncsi_dev_state_probe_keep_phy;

> > +               break;

> > +#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)

> > +       case ncsi_dev_state_probe_keep_phy:

> > +               ndp->pending_req_num = 1;

> > +

> > +               nca.type = NCSI_PKT_CMD_OEM;

> > +               nca.package = ndp->active_package->id;

> > +               nca.channel = 0;

> > +               ret = ncsi_oem_keep_phy_intel(&nca);

> > +               if (ret)

> > +                       goto error;

> > +

> >                 nd->state = ncsi_dev_state_probe_gvi;

> >                 break;

> > +#endif /* CONFIG_NCSI_OEM_CMD_KEEP_PHY */

> >         case ncsi_dev_state_probe_gvi:

> >         case ncsi_dev_state_probe_gc:

> >         case ncsi_dev_state_probe_gls:

> > --

> > 2.31.1

> >
Ivan Mikhaylov July 13, 2021, 10:16 a.m. UTC | #3
On Mon, 2021-07-12 at 10:01 +0000, Joel Stanley wrote:
> On Thu, 8 Jul 2021 at 12:27, Ivan Mikhaylov <i.mikhaylov@yadro.com> wrote:

> > 

> > This allows to keep PHY link up and prevents any channel resets during

> > the host load.

> > 

> > It is KEEP_PHY_LINK_UP option(Veto bit) in i210 datasheet which

> > block PHY reset and power state changes.

> 

> How about using runtime configuration over using kconfig for this, so

> the same kernel config can be used on different machines. Something

> device tree based?


As I see there is already the way with Kconfig option, with previous
broadcom/mellanox get mac address and set affinity for mellanox commands.
I'm not sure about dts based solution. As I see there is two ways:
1. make everything related OEM into dts based options
2. or this way, with Kconfig

> 

> Another option is to use the netlink handler to send the OEM command

> from userspace. Eddie has worked on this for an IBM machine, and I've

> asked him to post those changes. I would prefer the kernel option

> though.

> 


I like the idea, it may help with debugging.

Thanks.
>
diff mbox series

Patch

diff --git a/net/ncsi/Kconfig b/net/ncsi/Kconfig
index 93309081f5a4..ea1dd32b6b1f 100644
--- a/net/ncsi/Kconfig
+++ b/net/ncsi/Kconfig
@@ -17,3 +17,9 @@  config NCSI_OEM_CMD_GET_MAC
 	help
 	  This allows to get MAC address from NCSI firmware and set them back to
 		controller.
+config NCSI_OEM_CMD_KEEP_PHY
+	bool "Keep PHY Link up"
+	depends on NET_NCSI
+	help
+	  This allows to keep PHY link up and prevents any channel resets during
+	  the host load.
diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
index cbbb0de4750a..0b6cfd3b31e0 100644
--- a/net/ncsi/internal.h
+++ b/net/ncsi/internal.h
@@ -78,6 +78,9 @@  enum {
 /* OEM Vendor Manufacture ID */
 #define NCSI_OEM_MFR_MLX_ID             0x8119
 #define NCSI_OEM_MFR_BCM_ID             0x113d
+#define NCSI_OEM_MFR_INTEL_ID           0x157
+/* Intel specific OEM command */
+#define NCSI_OEM_INTEL_CMD_KEEP_PHY     0x20   /* CMD ID for Keep PHY up */
 /* Broadcom specific OEM Command */
 #define NCSI_OEM_BCM_CMD_GMA            0x01   /* CMD ID for Get MAC */
 /* Mellanox specific OEM Command */
@@ -86,6 +89,7 @@  enum {
 #define NCSI_OEM_MLX_CMD_SMAF           0x01   /* CMD ID for Set MC Affinity */
 #define NCSI_OEM_MLX_CMD_SMAF_PARAM     0x07   /* Parameter for SMAF         */
 /* OEM Command payload lengths*/
+#define NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN 7
 #define NCSI_OEM_BCM_CMD_GMA_LEN        12
 #define NCSI_OEM_MLX_CMD_GMA_LEN        8
 #define NCSI_OEM_MLX_CMD_SMAF_LEN        60
@@ -271,6 +275,7 @@  enum {
 	ncsi_dev_state_probe_mlx_gma,
 	ncsi_dev_state_probe_mlx_smaf,
 	ncsi_dev_state_probe_cis,
+	ncsi_dev_state_probe_keep_phy,
 	ncsi_dev_state_probe_gvi,
 	ncsi_dev_state_probe_gc,
 	ncsi_dev_state_probe_gls,
diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c
index 42b54a3da2e6..89c7742cd72e 100644
--- a/net/ncsi/ncsi-manage.c
+++ b/net/ncsi/ncsi-manage.c
@@ -689,6 +689,35 @@  static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)
+
+static int ncsi_oem_keep_phy_intel(struct ncsi_cmd_arg *nca)
+{
+	unsigned char data[NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN];
+	int ret = 0;
+
+	nca->payload = NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN;
+
+	memset(data, 0, NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN);
+	*(unsigned int *)data = ntohl((__force __be32)NCSI_OEM_MFR_INTEL_ID);
+
+	data[4] = NCSI_OEM_INTEL_CMD_KEEP_PHY;
+
+	/* PHY Link up attribute */
+	data[6] = 0x1;
+
+	nca->data = data;
+
+	ret = ncsi_xmit_cmd(nca);
+	if (ret)
+		netdev_err(nca->ndp->ndev.dev,
+			   "NCSI: Failed to transmit cmd 0x%x during configure\n",
+			   nca->type);
+	return ret;
+}
+
+#endif
+
 #if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)
 
 /* NCSI OEM Command APIs */
@@ -1391,8 +1420,24 @@  static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
 				goto error;
 		}
 
+		nd->state = ncsi_dev_state_probe_gvi;
+		if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY))
+			nd->state = ncsi_dev_state_probe_keep_phy;
+		break;
+#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)
+	case ncsi_dev_state_probe_keep_phy:
+		ndp->pending_req_num = 1;
+
+		nca.type = NCSI_PKT_CMD_OEM;
+		nca.package = ndp->active_package->id;
+		nca.channel = 0;
+		ret = ncsi_oem_keep_phy_intel(&nca);
+		if (ret)
+			goto error;
+
 		nd->state = ncsi_dev_state_probe_gvi;
 		break;
+#endif /* CONFIG_NCSI_OEM_CMD_KEEP_PHY */
 	case ncsi_dev_state_probe_gvi:
 	case ncsi_dev_state_probe_gc:
 	case ncsi_dev_state_probe_gls: