Skip to content

Commit

Permalink
nfp: read mailbox address from TLV caps
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jakub Kicinski authored and David S. Miller committed Jan 19, 2018
1 parent ce991ab commit 527d7d1
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
20 changes: 14 additions & 6 deletions drivers/net/ethernet/netronome/nfp/nfp_net_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,17 +293,23 @@ 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) {
nn_err(nn, "Mailbox update error\n");
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
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down
11 changes: 11 additions & 0 deletions drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down
25 changes: 21 additions & 4 deletions drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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_ */

0 comments on commit 527d7d1

Please sign in to comment.