[PATCH 02/10] net/ncsi: NCSI command packet handler
Joel Stanley
joel at jms.id.au
Fri Jul 1 00:05:07 AEST 2016
On Thu, Jun 30, 2016 at 7:57 PM, Gavin Shan <gwshan at linux.vnet.ibm.com> wrote:
> The NCSI command packets are sent from MC (Management Controller)
> to remote end. They are used for multiple purposes: probe existing
> NCSI package/channel, retrieve NCSI channel's capability, configure
> NCSI channel etc.
>
> This defines struct to represent NCSI command packets and introduces
> function ncsi_xmit_cmd(), which will be used to transmit NCSI command
> packet according to the request. The request is represented by struct
> ncsi_cmd_arg.
>
> Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
> ---
> include/uapi/linux/if_ether.h | 1 +
> net/ncsi/Makefile | 2 +-
> net/ncsi/internal.h | 18 ++
> net/ncsi/ncsi-cmd.c | 372 ++++++++++++++++++++++++++++++++++++++++++
> net/ncsi/ncsi-pkt.h | 168 +++++++++++++++++++
> 5 files changed, 560 insertions(+), 1 deletion(-)
> create mode 100644 net/ncsi/ncsi-cmd.c
> create mode 100644 net/ncsi/ncsi-pkt.h
>
> diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
> index cec849a..7300b2d 100644
> --- a/include/uapi/linux/if_ether.h
> +++ b/include/uapi/linux/if_ether.h
> @@ -87,6 +87,7 @@
> #define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
> #define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */
> #define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
> +#define ETH_P_NCSI 0x88F8 /* NCSI protocol */
> #define ETH_P_PRP 0x88FB /* IEC 62439-3 PRP/HSRv0 */
> #define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
> #define ETH_P_TDLS 0x890D /* TDLS */
> diff --git a/net/ncsi/Makefile b/net/ncsi/Makefile
> index 07b5625..abc4046 100644
> --- a/net/ncsi/Makefile
> +++ b/net/ncsi/Makefile
> @@ -1,4 +1,4 @@
> #
> # Makefile for NCSI API
> #
> -obj-$(CONFIG_NET_NCSI) += ncsi-manage.o
> +obj-$(CONFIG_NET_NCSI) += ncsi-cmd.o ncsi-manage.o
> diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h
> index 4a8bd76..0c51c89 100644
> --- a/net/ncsi/internal.h
> +++ b/net/ncsi/internal.h
> @@ -217,6 +217,21 @@ struct ncsi_dev_priv {
> struct list_head ndp_node;
> };
>
> +struct ncsi_cmd_arg {
> + struct ncsi_dev_priv *nca_ndp;
> + unsigned char nca_type;
> + unsigned char nca_id;
> + unsigned char nca_package;
> + unsigned char nca_channel;
> + unsigned short nca_payload;
> + unsigned int nca_portid;
> + union {
> + unsigned char nca_bytes[16];
> + unsigned short nca_words[8];
> + unsigned int nca_dwords[4];
> + };
> +};
> +
> extern struct list_head ncsi_dev_list;
> extern spinlock_t ncsi_dev_lock;
>
> @@ -250,4 +265,7 @@ struct ncsi_req *ncsi_alloc_req(struct ncsi_dev_priv *ndp);
> void ncsi_free_req(struct ncsi_req *nr, bool check, bool timeout);
> struct ncsi_dev *ncsi_find_dev(struct net_device *dev);
>
> +/* Packet handlers */
> +int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca);
> +
> #endif /* __NCSI_INTERNAL_H__ */
> diff --git a/net/ncsi/ncsi-cmd.c b/net/ncsi/ncsi-cmd.c
> new file mode 100644
> index 0000000..c64c437
> --- /dev/null
> +++ b/net/ncsi/ncsi-cmd.c
> @@ -0,0 +1,372 @@
> +/*
> + * Copyright Gavin Shan, IBM Corporation 2016.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/netdevice.h>
> +#include <linux/skbuff.h>
> +
> +#include <net/ncsi.h>
> +#include <net/net_namespace.h>
> +#include <net/sock.h>
> +
> +#include "internal.h"
> +#include "ncsi-pkt.h"
> +
> +/* This function should be called after the data area has been
> + * populated completely.
> + */
> +static int ncsi_cmd_build_header(struct ncsi_pkt_hdr *h,
> + struct ncsi_cmd_arg *nca)
> +{
> + __be32 csum, *checksum;
> + __be32 low, high;
> + unsigned char *stream;
> + int i;
> +
> + h->mc_id = 0;
> + h->revision = NCSI_PKT_REVISION;
> + h->reserved = 0;
> + h->id = nca->nca_id;
> + h->type = nca->nca_type;
> + h->channel = NCSI_TO_CHANNEL(nca->nca_package,
> + nca->nca_channel);
> + h->length = htons(nca->nca_payload);
> + h->reserved1[0] = 0;
> + h->reserved1[1] = 0;
> +
> + /* Calculate the checksum */
> + csum = 0;
> + stream = (unsigned char *)h;
> + for (i = 0; i < sizeof(*h) + nca->nca_payload; i += 2) {
> + high = stream[i];
> + low = stream[i + 1];
You're assigning a uchar to a u32 here, and then arranging them into a
u16 in the next line. Perhaps just do
csum += (stream[i + 1] | stream[i]);
Or make stream be a pointer to u16s that you iterate over and add to csum?
> + csum += ((high << 8) | low);
> + }
> +
> + /* Fill with the calculated checksum */
> + checksum = (__be32 *)((void *)(h + 1) + nca->nca_payload);
Whoa. So we're pointing past the end of the ncsi_pkt_hdr, plus
nca_payload bytes? Is there a better way to describe this?
> + csum = (~csum + 1);
> + *checksum = htonl(csum);
> +
> + return 0;
We always return 0. Can we drop the return type?
> +}
> +
> +static int ncsi_cmd_handler_default(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_pkt *cmd;
> +
> + if (!nca)
> + return 0;
> +
> + cmd = (struct ncsi_cmd_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_sp(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_sp_pkt *cmd;
> +
> + if (!nca)
> + return 4;
4?
https://xkcd.com/221/ ?
> +
> + cmd = (struct ncsi_cmd_sp_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + cmd->hw_arbitration = nca->nca_bytes[0];
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_dc(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_dc_pkt *cmd;
> +
> + if (!nca)
> + return 4;
> +
> + cmd = (struct ncsi_cmd_dc_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + cmd->ald = nca->nca_bytes[0];
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_rc(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_rc_pkt *cmd;
> +
> + if (!nca)
> + return 4;
> +
> + cmd = (struct ncsi_cmd_rc_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_ae(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_ae_pkt *cmd;
> +
> + if (!nca)
> + return 8;
> +
> + cmd = (struct ncsi_cmd_ae_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + cmd->mc_id = nca->nca_bytes[0];
> + cmd->mode = htonl(nca->nca_dwords[1]);
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_sl(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_sl_pkt *cmd;
> +
> + if (!nca)
> + return 8;
> +
> + cmd = (struct ncsi_cmd_sl_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + cmd->mode = htonl(nca->nca_dwords[0]);
> + cmd->oem_mode = htonl(nca->nca_dwords[1]);
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_svf(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_svf_pkt *cmd;
> +
> + if (!nca)
> + return 4;
> +
> + cmd = (struct ncsi_cmd_svf_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + cmd->vlan = htons(nca->nca_words[0]);
> + cmd->index = nca->nca_bytes[2];
> + cmd->enable = nca->nca_bytes[3];
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_ev(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_ev_pkt *cmd;
> +
> + if (!nca)
> + return 4;
> +
> + cmd = (struct ncsi_cmd_ev_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + cmd->mode = nca->nca_bytes[0];
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_sma(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_sma_pkt *cmd;
> + int i;
> +
> + if (!nca)
> + return 8;
> +
> + cmd = (struct ncsi_cmd_sma_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + for (i = 0; i < 6; i++)
> + cmd->mac[i] = nca->nca_bytes[i];
> + cmd->index = nca->nca_bytes[6];
> + cmd->at_e = nca->nca_bytes[7];
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_ebf(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_ebf_pkt *cmd;
> +
> + if (!nca)
> + return 4;
> +
> + cmd = (struct ncsi_cmd_ebf_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + cmd->mode = htonl(nca->nca_dwords[0]);
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_egmf(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_egmf_pkt *cmd;
> +
> + if (!nca)
> + return 4;
> +
> + cmd = (struct ncsi_cmd_egmf_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + cmd->mode = htonl(nca->nca_dwords[0]);
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static int ncsi_cmd_handler_snfc(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_cmd_snfc_pkt *cmd;
> +
> + if (!nca)
> + return 4;
> +
> + cmd = (struct ncsi_cmd_snfc_pkt *)skb_put(skb, sizeof(*cmd));
> + memset(cmd, 0, sizeof(*cmd));
> + cmd->mode = nca->nca_bytes[0];
> + return ncsi_cmd_build_header(&cmd->cmd.common, nca);
> +}
> +
> +static struct ncsi_cmd_handler {
> + unsigned char nch_type;
> + int (*nch_handler)(struct sk_buff *skb,
> + struct ncsi_cmd_arg *nca);
> +} ncsi_cmd_handlers[] = {
> + { NCSI_PKT_CMD_CIS, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_SP, ncsi_cmd_handler_sp },
> + { NCSI_PKT_CMD_DP, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_EC, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_DC, ncsi_cmd_handler_dc },
> + { NCSI_PKT_CMD_RC, ncsi_cmd_handler_rc },
> + { NCSI_PKT_CMD_ECNT, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_DCNT, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_AE, ncsi_cmd_handler_ae },
> + { NCSI_PKT_CMD_SL, ncsi_cmd_handler_sl },
> + { NCSI_PKT_CMD_GLS, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_SVF, ncsi_cmd_handler_svf },
> + { NCSI_PKT_CMD_EV, ncsi_cmd_handler_ev },
> + { NCSI_PKT_CMD_DV, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_SMA, ncsi_cmd_handler_sma },
> + { NCSI_PKT_CMD_EBF, ncsi_cmd_handler_ebf },
> + { NCSI_PKT_CMD_DBF, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_EGMF, ncsi_cmd_handler_egmf },
> + { NCSI_PKT_CMD_DGMF, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_SNFC, ncsi_cmd_handler_snfc },
> + { NCSI_PKT_CMD_GVI, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_GC, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_GP, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_GCPS, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_GNS, ncsi_cmd_handler_default },
> + { NCSI_PKT_CMD_GNPTS, ncsi_cmd_handler_default },
> + { 0, NULL }
> +};
> +
> +static struct ncsi_req *ncsi_alloc_cmd_req(struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_dev_priv *ndp = nca->nca_ndp;
> + struct ncsi_dev *nd = &ndp->ndp_ndev;
> + struct net_device *dev = nd->nd_dev;
> + int hlen = LL_RESERVED_SPACE(dev);
> + int tlen = dev->needed_tailroom;
> + int len = hlen + tlen;
> + struct sk_buff *skb;
> + struct ncsi_req *nr;
> +
> + nr = ncsi_alloc_req(ndp);
> + if (!nr)
> + return NULL;
> +
> + /* NCSI command packet has 16-bytes header, payload,
> + * 4-bytes checksum and optional padding.
> + */
> + len += sizeof(struct ncsi_cmd_pkt_hdr);
> + len += 4;
> + if (nca->nca_payload < 26)
> + len += 26;
4 is the checksum I assume. What is 26? Can we sizeof() any structures
so these aren't just magic numbers?
> + else
> + len += nca->nca_payload;
> +
> + /* Allocate skb */
> + skb = alloc_skb(len, GFP_ATOMIC);
> + if (!skb) {
> + ncsi_free_req(nr, false, false);
> + return NULL;
> + }
> +
> + nr->nr_cmd = skb;
> + skb_reserve(skb, hlen);
> + skb_reset_network_header(skb);
> +
> + skb->dev = dev;
> + skb->protocol = htons(ETH_P_NCSI);
> +
> + return nr;
> +}
> +
> +int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca)
> +{
> + struct ncsi_req *nr;
> + struct ethhdr *eh;
> + struct ncsi_cmd_handler *nch;
> + int i, ret;
> +
> + /* Search for the handler */
> + nch = ncsi_cmd_handlers;
> + while (nch->nch_handler) {
> + if (nch->nch_type == nca->nca_type)
> + break;
> + nch++;
> + }
> +
> + if (!nch->nch_handler) {
> + pr_info("%s: Cannot send packet with type 0x%x\n",
> + __func__, nca->nca_type);
> + return -ENOENT;
> + }
> +
> + /* Get packet payload length and allocate the request */
> + nca->nca_payload = nch->nch_handler(NULL, NULL);
> + nr = ncsi_alloc_cmd_req(nca);
> + if (!nr)
> + return -ENOMEM;
> +
> + /* Prepare the packet */
> + nca->nca_id = nr->nr_id;
> + ret = nch->nch_handler(nr->nr_cmd, nca);
> + if (ret) {
> + ncsi_free_req(nr, true, false);
> + return ret;
> + }
> +
> + /* Fill the ethernet header */
> + eh = (struct ethhdr *)skb_push(nr->nr_cmd, sizeof(*eh));
> + eh->h_proto = htons(ETH_P_NCSI);
> + for (i = 0; i < ETH_ALEN; i++) {
> + eh->h_dest[i] = 0xff;
> + eh->h_source[i] = 0xff;
> + }
These two could be eth_broadcast_addr().
> +
> + /* Start the timer for the request that might not have
> + * corresponding response. I'm not sure 1 second delay
> + * here is enough. Anyway, NCSI is internal network, so
> + * the responsiveness should be as fast as enough.
> + */
Could this message be updated now that we are confident it works on hardware?
/*
* Start the timer for the request that might not have
* corresponding response. Given NCSI is an internal
* connection a 1 second delay should be sufficient.
*/
> + nr->nr_timer_enabled = true;
> + mod_timer(&nr->nr_timer, jiffies + 1 * HZ);
> +
> + /* Send NCSI packet */
> + skb_get(nr->nr_cmd);
> + ret = dev_queue_xmit(nr->nr_cmd);
> + if (ret < 0) {
> + ncsi_free_req(nr, true, false);
> + return ret;
> + }
> +
> + return 0;
> +}
> diff --git a/net/ncsi/ncsi-pkt.h b/net/ncsi/ncsi-pkt.h
> new file mode 100644
> index 0000000..7f030b5
> --- /dev/null
> +++ b/net/ncsi/ncsi-pkt.h
> @@ -0,0 +1,168 @@
> +/*
> + * Copyright Gavin Shan, IBM Corporation 2016.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#ifndef __NCSI_PKT_H__
> +#define __NCSI_PKT_H__
> +
> +struct ncsi_pkt_hdr {
> + unsigned char mc_id; /* Management controller ID */
> + unsigned char revision; /* NCSI version - 0x01 */
> + unsigned char reserved; /* Reserved */
> + unsigned char id; /* Packet sequence number */
> + unsigned char type; /* Packet type */
> + unsigned char channel; /* Network controller ID */
> + __be16 length; /* Payload length */
> + __be32 reserved1[2]; /* Reserved */
> +};
> +
> +struct ncsi_cmd_pkt_hdr {
> + struct ncsi_pkt_hdr common; /* Common NCSI packet header */
> +};
> +
> +/* NCSI common command packet */
> +struct ncsi_cmd_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[26];
> +};
> +
> +/* Select Package */
> +struct ncsi_cmd_sp_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + unsigned char reserved[3]; /* Reserved */
> + unsigned char hw_arbitration; /* HW arbitration */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[22];
> +};
> +
> +/* Disable Channel */
> +struct ncsi_cmd_dc_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + unsigned char reserved[3]; /* Reserved */
> + unsigned char ald; /* Allow link down */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[22];
> +};
> +
> +/* Reset Channel */
> +struct ncsi_cmd_rc_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + __be32 reserved; /* Reserved */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[22];
> +};
> +
> +/* AEN Enable */
> +struct ncsi_cmd_ae_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + unsigned char reserved[3]; /* Reserved */
> + unsigned char mc_id; /* MC ID */
> + __be32 mode; /* AEN working mode */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[18];
> +};
> +
> +/* Set Link */
> +struct ncsi_cmd_sl_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + __be32 mode; /* Link working mode */
> + __be32 oem_mode; /* OEM link mode */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[18];
> +};
> +
> +/* Set VLAN Filter */
> +struct ncsi_cmd_svf_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + __be16 reserved; /* Reserved */
> + __be16 vlan; /* VLAN ID */
> + __be16 reserved1; /* Reserved */
> + unsigned char index; /* VLAN table index */
> + unsigned char enable; /* Enable or disable */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[14];
> +};
> +
> +/* Enable VLAN */
> +struct ncsi_cmd_ev_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + unsigned char reserved[3]; /* Reserved */
> + unsigned char mode; /* VLAN filter mode */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[22];
> +};
> +
> +/* Set MAC Address */
> +struct ncsi_cmd_sma_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + unsigned char mac[6]; /* MAC address */
> + unsigned char index; /* MAC table index */
> + unsigned char at_e; /* Addr type and operation */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[18];
> +};
> +
> +/* Enable Broadcast Filter */
> +struct ncsi_cmd_ebf_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + __be32 mode; /* Filter mode */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[22];
> +};
> +
> +/* Enable Global Multicast Filter */
> +struct ncsi_cmd_egmf_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + __be32 mode; /* Global MC mode */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[22];
> +};
> +
> +/* Set NCSI Flow Control */
> +struct ncsi_cmd_snfc_pkt {
> + struct ncsi_cmd_pkt_hdr cmd; /* Command header */
> + unsigned char reserved[3]; /* Reserved */
> + unsigned char mode; /* Flow control mode */
> + __be32 checksum; /* Checksum */
> + unsigned char pad[22];
> +};
> +
> +/* NCSI packet revision */
> +#define NCSI_PKT_REVISION 0x01
> +
> +/* NCSI packet commands */
> +#define NCSI_PKT_CMD_CIS 0x00 /* Clear Initial State */
> +#define NCSI_PKT_CMD_SP 0x01 /* Select Package */
> +#define NCSI_PKT_CMD_DP 0x02 /* Deselect Package */
> +#define NCSI_PKT_CMD_EC 0x03 /* Enable Channel */
> +#define NCSI_PKT_CMD_DC 0x04 /* Disable Channel */
> +#define NCSI_PKT_CMD_RC 0x05 /* Reset Channel */
> +#define NCSI_PKT_CMD_ECNT 0x06 /* Enable Channel Network Tx */
> +#define NCSI_PKT_CMD_DCNT 0x07 /* Disable Channel Network Tx */
> +#define NCSI_PKT_CMD_AE 0x08 /* AEN Enable */
> +#define NCSI_PKT_CMD_SL 0x09 /* Set Link */
> +#define NCSI_PKT_CMD_GLS 0x0a /* Get Link */
> +#define NCSI_PKT_CMD_SVF 0x0b /* Set VLAN Filter */
> +#define NCSI_PKT_CMD_EV 0x0c /* Enable VLAN */
> +#define NCSI_PKT_CMD_DV 0x0d /* Disable VLAN */
> +#define NCSI_PKT_CMD_SMA 0x0e /* Set MAC address */
> +#define NCSI_PKT_CMD_EBF 0x10 /* Enable Broadcast Filter */
> +#define NCSI_PKT_CMD_DBF 0x11 /* Disable Broadcast Filter */
> +#define NCSI_PKT_CMD_EGMF 0x12 /* Enable Global Multicast Filter */
> +#define NCSI_PKT_CMD_DGMF 0x13 /* Disable Global Multicast Filter */
> +#define NCSI_PKT_CMD_SNFC 0x14 /* Set NCSI Flow Control */
> +#define NCSI_PKT_CMD_GVI 0x15 /* Get Version ID */
> +#define NCSI_PKT_CMD_GC 0x16 /* Get Capabilities */
> +#define NCSI_PKT_CMD_GP 0x17 /* Get Parameters */
> +#define NCSI_PKT_CMD_GCPS 0x18 /* Get Controller Packet Statistics */
> +#define NCSI_PKT_CMD_GNS 0x19 /* Get NCSI Statistics */
> +#define NCSI_PKT_CMD_GNPTS 0x1a /* Get NCSI Pass-throu Statistics */
> +#define NCSI_PKT_CMD_OEM 0x50 /* OEM */
> +
> +#endif /* __NCSI_PKT_H__ */
> --
> 2.1.0
>
More information about the openbmc
mailing list