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.kicin...@netronome.com>
Reviewed-by: Dirk van der Merwe <dirk.vanderme...@netronome.com>
---
 .../net/ethernet/netronome/nfp/nfp_net_common.c    | 20 +++++++++++------
 drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c  | 11 ++++++++++
 drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h  | 25 ++++++++++++++++++----
 3 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index 4218a8660d46..15c2fec4f520 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -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);
 }
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c 
b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c
index 72da1b352418..ffb402746ad4 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c
@@ -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;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h 
b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
index 4c288cdd0e18..eeecef2caac6 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
@@ -413,11 +413,14 @@
  * 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
 
@@ -428,7 +431,7 @@
  * %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
@@ -478,23 +481,37 @@
  * %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_ */
-- 
2.15.1

Reply via email to