nfp: read mailbox address from TLV caps
authorJakub Kicinski <jakub.kicinski@netronome.com>
Thu, 18 Jan 2018 02:51:03 +0000 (18:51 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 19 Jan 2018 20:44:18 +0000 (15:44 -0500)
Allow specifying alternative vNIC mailbox location in TLV caps.
This way we can size the mailbox to the needs and not necessarily
waste 512B of ctrl memory space.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c
drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h

index 4218a8660d46bf2768f8c9ac88b9f6b6b1132f35..15c2fec4f520652d8f5fcfe1a38b597d41d41bb0 100644 (file)
@@ -293,9 +293,15 @@ int nfp_net_reconfig(struct nfp_net *nn, u32 update)
  */
 static int nfp_net_reconfig_mbox(struct nfp_net *nn, u32 mbox_cmd)
 {
+       u32 mbox = nn->tlv_caps.mbox_off;
        int ret;
 
-       nn_writeq(nn, NFP_NET_CFG_MBOX_CMD, mbox_cmd);
+       if (!nfp_net_has_mbox(&nn->tlv_caps)) {
+               nn_err(nn, "no mailbox present, command: %u\n", mbox_cmd);
+               return -EIO;
+       }
+
+       nn_writeq(nn, mbox + NFP_NET_CFG_MBOX_SIMPLE_CMD, mbox_cmd);
 
        ret = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_MBOX);
        if (ret) {
@@ -303,7 +309,7 @@ static int nfp_net_reconfig_mbox(struct nfp_net *nn, u32 mbox_cmd)
                return ret;
        }
 
-       return -nn_readl(nn, NFP_NET_CFG_MBOX_RET);
+       return -nn_readl(nn, mbox + NFP_NET_CFG_MBOX_SIMPLE_RET);
 }
 
 /* Interrupt configuration and handling
@@ -3084,8 +3090,9 @@ nfp_net_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
        if (!vid)
                return 0;
 
-       nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_VID, vid);
-       nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_PROTO, ETH_P_8021Q);
+       nn_writew(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_VLAN_FILTER_VID, vid);
+       nn_writew(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_VLAN_FILTER_PROTO,
+                 ETH_P_8021Q);
 
        return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_ADD);
 }
@@ -3101,8 +3108,9 @@ nfp_net_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
        if (!vid)
                return 0;
 
-       nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_VID, vid);
-       nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_PROTO, ETH_P_8021Q);
+       nn_writew(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_VLAN_FILTER_VID, vid);
+       nn_writew(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_VLAN_FILTER_PROTO,
+                 ETH_P_8021Q);
 
        return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL);
 }
index 72da1b35241832246a937d3996a69908a42eeb3c..ffb402746ad4211d6690fe76dff59437068d7d10 100644 (file)
@@ -43,6 +43,8 @@ static void nfp_net_tlv_caps_reset(struct nfp_net_tlv_caps *caps)
 {
        memset(caps, 0, sizeof(*caps));
        caps->me_freq_mhz = 1200;
+       caps->mbox_off = NFP_NET_CFG_MBOX_BASE;
+       caps->mbox_len = NFP_NET_CFG_MBOX_VAL_MAX_SZ;
 }
 
 int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem,
@@ -102,6 +104,15 @@ int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem,
 
                        caps->me_freq_mhz = readl(data);
                        break;
+               case NFP_NET_CFG_TLV_TYPE_MBOX:
+                       if (!length) {
+                               caps->mbox_off = 0;
+                               caps->mbox_len = 0;
+                       } else {
+                               caps->mbox_off = data - ctrl_mem;
+                               caps->mbox_len = length;
+                       }
+                       break;
                default:
                        if (!FIELD_GET(NFP_NET_CFG_TLV_HEADER_REQUIRED, hdr))
                                break;
index 4c288cdd0e188cfca35d3a74843b4a0addf5173a..eeecef2caac6f8f352756161a894a3286f00b40f 100644 (file)
  * 4B used for update command and 4B return code
  * followed by a max of 504B of variable length value
  */
-#define NFP_NET_CFG_MBOX_CMD           0x1800
-#define NFP_NET_CFG_MBOX_RET           0x1804
-#define NFP_NET_CFG_MBOX_VAL           0x1808
+#define NFP_NET_CFG_MBOX_BASE          0x1800
 #define NFP_NET_CFG_MBOX_VAL_MAX_SZ    0x1F8
 
+#define NFP_NET_CFG_MBOX_SIMPLE_CMD    0x0
+#define NFP_NET_CFG_MBOX_SIMPLE_RET    0x4
+#define NFP_NET_CFG_MBOX_SIMPLE_VAL    0x8
+#define NFP_NET_CFG_MBOX_SIMPLE_LEN    0x12
+
 #define NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_ADD 1
 #define NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL 2
 
  * %NFP_NET_CFG_VLAN_FILTER_PROTO:     VLAN proto to filter
  * %NFP_NET_CFG_VXLAN_SZ:              Size of the VLAN filter mailbox in bytes
  */
-#define NFP_NET_CFG_VLAN_FILTER                NFP_NET_CFG_MBOX_VAL
+#define NFP_NET_CFG_VLAN_FILTER                NFP_NET_CFG_MBOX_SIMPLE_VAL
 #define  NFP_NET_CFG_VLAN_FILTER_VID   NFP_NET_CFG_VLAN_FILTER
 #define  NFP_NET_CFG_VLAN_FILTER_PROTO  (NFP_NET_CFG_VLAN_FILTER + 2)
 #define NFP_NET_CFG_VLAN_FILTER_SZ      0x0004
  * %NFP_NET_CFG_TLV_TYPE_ME_FREQ:
  * Single word, ME frequency in MHz as used in calculation for
  * %NFP_NET_CFG_RXR_IRQ_MOD and %NFP_NET_CFG_TXR_IRQ_MOD.
+ *
+ * %NFP_NET_CFG_TLV_TYPE_MBOX:
+ * Variable, mailbox area.  Overwrites the default location which is
+ * %NFP_NET_CFG_MBOX_BASE and length %NFP_NET_CFG_MBOX_VAL_MAX_SZ.
  */
 #define NFP_NET_CFG_TLV_TYPE_UNKNOWN           0
 #define NFP_NET_CFG_TLV_TYPE_RESERVED          1
 #define NFP_NET_CFG_TLV_TYPE_END               2
 #define NFP_NET_CFG_TLV_TYPE_ME_FREQ           3
+#define NFP_NET_CFG_TLV_TYPE_MBOX              4
 
 struct device;
 
 /**
  * struct nfp_net_tlv_caps - parsed control BAR TLV capabilities
  * @me_freq_mhz:       ME clock_freq (MHz)
+ * @mbox_off:          vNIC mailbox area offset
+ * @mbox_len:          vNIC mailbox area length
  */
 struct nfp_net_tlv_caps {
        u32 me_freq_mhz;
+       unsigned int mbox_off;
+       unsigned int mbox_len;
 };
 
 int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem,
                           struct nfp_net_tlv_caps *caps);
 
+static inline bool nfp_net_has_mbox(struct nfp_net_tlv_caps *caps)
+{
+       return caps->mbox_len >= NFP_NET_CFG_MBOX_SIMPLE_LEN;
+}
+
 #endif /* _NFP_NET_CTRL_H_ */