nfp: send control message when MAC representors are created
authorSimon Horman <simon.horman@netronome.com>
Fri, 11 Aug 2017 08:25:44 +0000 (10:25 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 11 Aug 2017 21:51:17 +0000 (14:51 -0700)
The firmware expects a MAC_REPR control message when a MAC representor
is created. The driver should expect a PORTMOD message to follow which
will provide the link states of the physical port associated with the MAC
representor.

Signed-off-by: Simon Horman <simon.horman@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/flower/cmsg.c
drivers/net/ethernet/netronome/nfp/flower/cmsg.h
drivers/net/ethernet/netronome/nfp/flower/main.c

index dd7fa9cf225ff3c9e60d6f62e3f7f17317f2ea52..a69d68ba3d0cb49a8f30f24641e7f274a06c915e 100644 (file)
@@ -75,6 +75,39 @@ nfp_flower_cmsg_alloc(struct nfp_app *app, unsigned int size,
        return skb;
 }
 
+struct sk_buff *
+nfp_flower_cmsg_mac_repr_start(struct nfp_app *app, unsigned int num_ports)
+{
+       struct nfp_flower_cmsg_mac_repr *msg;
+       struct sk_buff *skb;
+       unsigned int size;
+
+       size = sizeof(*msg) + num_ports * sizeof(msg->ports[0]);
+       skb = nfp_flower_cmsg_alloc(app, size, NFP_FLOWER_CMSG_TYPE_MAC_REPR);
+       if (!skb)
+               return NULL;
+
+       msg = nfp_flower_cmsg_get_data(skb);
+       memset(msg->reserved, 0, sizeof(msg->reserved));
+       msg->num_ports = num_ports;
+
+       return skb;
+}
+
+void
+nfp_flower_cmsg_mac_repr_add(struct sk_buff *skb, unsigned int idx,
+                            unsigned int nbi, unsigned int nbi_port,
+                            unsigned int phys_port)
+{
+       struct nfp_flower_cmsg_mac_repr *msg;
+
+       msg = nfp_flower_cmsg_get_data(skb);
+       msg->ports[idx].idx = idx;
+       msg->ports[idx].info = nbi & NFP_FLOWER_CMSG_MAC_REPR_NBI;
+       msg->ports[idx].nbi_port = nbi_port;
+       msg->ports[idx].phys_port = phys_port;
+}
+
 int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok)
 {
        struct nfp_flower_cmsg_portmod *msg;
index cf738de170ab6d11309223571ea85cfcc2aadf60..aa92a8711a02d5f3ea53e6cdd7585db62d6caa3a 100644 (file)
@@ -247,12 +247,27 @@ struct nfp_flower_cmsg_hdr {
 enum nfp_flower_cmsg_type_port {
        NFP_FLOWER_CMSG_TYPE_FLOW_ADD =         0,
        NFP_FLOWER_CMSG_TYPE_FLOW_DEL =         2,
+       NFP_FLOWER_CMSG_TYPE_MAC_REPR =         7,
        NFP_FLOWER_CMSG_TYPE_PORT_MOD =         8,
        NFP_FLOWER_CMSG_TYPE_FLOW_STATS =       15,
        NFP_FLOWER_CMSG_TYPE_PORT_ECHO =        16,
        NFP_FLOWER_CMSG_TYPE_MAX =              32,
 };
 
+/* NFP_FLOWER_CMSG_TYPE_MAC_REPR */
+struct nfp_flower_cmsg_mac_repr {
+       u8 reserved[3];
+       u8 num_ports;
+       struct {
+               u8 idx;
+               u8 info;
+               u8 nbi_port;
+               u8 phys_port;
+       } ports[0];
+};
+
+#define NFP_FLOWER_CMSG_MAC_REPR_NBI           GENMASK(1, 0)
+
 /* NFP_FLOWER_CMSG_TYPE_PORT_MOD */
 struct nfp_flower_cmsg_portmod {
        __be32 portnum;
@@ -308,6 +323,12 @@ static inline void *nfp_flower_cmsg_get_data(struct sk_buff *skb)
        return (unsigned char *)skb->data + NFP_FLOWER_CMSG_HLEN;
 }
 
+struct sk_buff *
+nfp_flower_cmsg_mac_repr_start(struct nfp_app *app, unsigned int num_ports);
+void
+nfp_flower_cmsg_mac_repr_add(struct sk_buff *skb, unsigned int idx,
+                            unsigned int nbi, unsigned int nbi_port,
+                            unsigned int phys_port);
 int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok);
 void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb);
 struct sk_buff *
index 6a65c8b33807ccb6b7f9394c6f60e0222e2ae396..b905454b30ca1b93e57dbeca3078b0c799b73114 100644 (file)
@@ -214,15 +214,22 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
 {
        struct nfp_eth_table *eth_tbl = app->pf->eth_tbl;
        struct nfp_reprs *reprs, *old_reprs;
+       struct sk_buff *ctrl_skb;
        unsigned int i;
        int err;
 
-       reprs = nfp_reprs_alloc(eth_tbl->max_index + 1);
-       if (!reprs)
+       ctrl_skb = nfp_flower_cmsg_mac_repr_start(app, eth_tbl->count);
+       if (!ctrl_skb)
                return -ENOMEM;
 
+       reprs = nfp_reprs_alloc(eth_tbl->max_index + 1);
+       if (!reprs) {
+               err = -ENOMEM;
+               goto err_free_ctrl_skb;
+       }
+
        for (i = 0; i < eth_tbl->count; i++) {
-               int phys_port = eth_tbl->ports[i].index;
+               unsigned int phys_port = eth_tbl->ports[i].index;
                struct nfp_port *port;
                u32 cmsg_port_id;
 
@@ -255,6 +262,11 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
                        goto err_reprs_clean;
                }
 
+               nfp_flower_cmsg_mac_repr_add(ctrl_skb, i,
+                                            eth_tbl->ports[i].nbi,
+                                            eth_tbl->ports[i].base,
+                                            phys_port);
+
                nfp_info(app->cpp, "Phys Port %d Representor(%s) created\n",
                         phys_port, reprs->reprs[phys_port]->name);
        }
@@ -265,9 +277,20 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
                goto err_reprs_clean;
        }
 
+       /* The MAC_REPR control message should be sent after the MAC
+        * representors are registered using nfp_app_reprs_set().  This is
+        * because the firmware may respond with control messages for the
+        * MAC representors, f.e. to provide the driver with information
+        * about their state, and without registration the driver will drop
+        * any such messages.
+        */
+       nfp_ctrl_tx(app->ctrl, ctrl_skb);
+
        return 0;
 err_reprs_clean:
        nfp_reprs_clean_and_free(reprs);
+err_free_ctrl_skb:
+       kfree_skb(ctrl_skb);
        return err;
 }