nfp: report port type in ethtool
authorJakub Kicinski <jakub.kicinski@netronome.com>
Tue, 4 Apr 2017 23:12:29 +0000 (16:12 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 5 Apr 2017 17:49:12 +0000 (10:49 -0700)
Service process firmware provides us with information about media
and interface (SFP module) plugged in, translate that to Linux's
PORT_* defines and report via ethtool.

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

index 563ced3c99e1bba6e6ede92b858492c5e2abf83f..3b2a09821a59d64ea44109460ec951e2673db2ba 100644 (file)
@@ -215,6 +215,7 @@ nfp_net_get_link_ksettings(struct net_device *netdev,
                nfp_net_refresh_port_config(nn);
        /* Separate if - on FW error the port could've disappeared from table */
        if (nn->eth_port) {
+               cmd->base.port = nn->eth_port->port_type;
                cmd->base.speed = nn->eth_port->speed;
                cmd->base.duplex = DUPLEX_FULL;
                return 0;
index dcb1bc81e5541e0a8f67f481894e1ce0a740dd68..07b4ded0151459541e113a3b48c2134d1bbbf26e 100644 (file)
@@ -62,6 +62,8 @@
 #define NSP_ETH_STATE_TX_ENABLED       BIT_ULL(2)
 #define NSP_ETH_STATE_RX_ENABLED       BIT_ULL(3)
 #define NSP_ETH_STATE_RATE             GENMASK_ULL(11, 8)
+#define NSP_ETH_STATE_INTERFACE                GENMASK_ULL(19, 12)
+#define NSP_ETH_STATE_MEDIA            GENMASK_ULL(21, 20)
 #define NSP_ETH_STATE_OVRD_CHNG                BIT_ULL(22)
 #define NSP_ETH_STATE_ANEG             GENMASK_ULL(25, 23)
 
@@ -134,6 +136,9 @@ nfp_eth_port_translate(struct nfp_nsp *nsp, const struct eth_table_entry *src,
        rate = nfp_eth_rate(FIELD_GET(NSP_ETH_STATE_RATE, state));
        dst->speed = dst->lanes * rate;
 
+       dst->interface = FIELD_GET(NSP_ETH_STATE_INTERFACE, state);
+       dst->media = FIELD_GET(NSP_ETH_STATE_MEDIA, state);
+
        nfp_eth_copy_mac_reverse(dst->mac_addr, src->mac_addr);
 
        dst->label_port = FIELD_GET(NSP_ETH_PORT_PHYLABEL, port);
@@ -170,6 +175,20 @@ nfp_eth_mark_split_ports(struct nfp_cpp *cpp, struct nfp_eth_table *table)
                }
 }
 
+static void
+nfp_eth_calc_port_type(struct nfp_cpp *cpp, struct nfp_eth_table_port *entry)
+{
+       if (entry->interface == NFP_INTERFACE_NONE) {
+               entry->port_type = PORT_NONE;
+               return;
+       }
+
+       if (entry->media == NFP_MEDIA_FIBRE)
+               entry->port_type = PORT_FIBRE;
+       else
+               entry->port_type = PORT_DA;
+}
+
 /**
  * nfp_eth_read_ports() - retrieve port information
  * @cpp:       NFP CPP handle
@@ -237,6 +256,8 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp)
                                               &table->ports[j++]);
 
        nfp_eth_mark_split_ports(cpp, table);
+       for (i = 0; i < table->count; i++)
+               nfp_eth_calc_port_type(cpp, &table->ports[i]);
 
        kfree(entries);
 
index 6b3e954e70b3422db05ade88745d688da8fe9dbf..57eb3cfa6a0ab76f6fda5b2a8656d975511ad4ad 100644 (file)
 #include <linux/types.h>
 #include <linux/if_ether.h>
 
+enum nfp_eth_interface {
+       NFP_INTERFACE_NONE      = 0,
+       NFP_INTERFACE_SFP       = 1,
+       NFP_INTERFACE_SFPP      = 10,
+       NFP_INTERFACE_SFP28     = 28,
+       NFP_INTERFACE_QSFP      = 40,
+       NFP_INTERFACE_CXP       = 100,
+       NFP_INTERFACE_QSFP28    = 112,
+};
+
+enum nfp_eth_media {
+       NFP_MEDIA_DAC_PASSIVE = 0,
+       NFP_MEDIA_DAC_ACTIVE,
+       NFP_MEDIA_FIBRE,
+};
+
 enum nfp_eth_aneg {
        NFP_ANEG_AUTO = 0,
        NFP_ANEG_SEARCH,
@@ -56,6 +72,8 @@ enum nfp_eth_aneg {
  * @base:      first channel index (within NBI)
  * @lanes:     number of channels
  * @speed:     interface speed (in Mbps)
+ * @interface: interface (module) plugged in
+ * @media:     media type of the @interface
  * @aneg:      auto negotiation mode
  * @mac_addr:  interface MAC address
  * @label_port:        port id
@@ -65,6 +83,7 @@ enum nfp_eth_aneg {
  * @rx_enabled:        is RX enabled?
  * @override_changed: is media reconfig pending?
  *
+ * @port_type: one of %PORT_* defines for ethtool
  * @is_split:  is interface part of a split port
  */
 struct nfp_eth_table {
@@ -77,6 +96,9 @@ struct nfp_eth_table {
                unsigned int lanes;
                unsigned int speed;
 
+               unsigned int interface;
+               enum nfp_eth_media media;
+
                enum nfp_eth_aneg aneg;
 
                u8 mac_addr[ETH_ALEN];
@@ -91,6 +113,8 @@ struct nfp_eth_table {
                bool override_changed;
 
                /* Computed fields */
+               u8 port_type;
+
                bool is_split;
        } ports[0];
 };