aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2018-01-17 21:51:03 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-19 15:44:18 -0500
commit527d7d1b9949e04a36fed971adc790641f13c927 (patch)
tree7b9f9f2d42a5ba0996eff8c76fe33d5b234cb890
parentce991ab6662a1d11923ba17d482a77686f2a4b74 (diff)
nfp: read mailbox address from TLV caps
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>
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_common.c20
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.c11
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h25
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)
293 */ 293 */
294static int nfp_net_reconfig_mbox(struct nfp_net *nn, u32 mbox_cmd) 294static int nfp_net_reconfig_mbox(struct nfp_net *nn, u32 mbox_cmd)
295{ 295{
296 u32 mbox = nn->tlv_caps.mbox_off;
296 int ret; 297 int ret;
297 298
298 nn_writeq(nn, NFP_NET_CFG_MBOX_CMD, mbox_cmd); 299 if (!nfp_net_has_mbox(&nn->tlv_caps)) {
300 nn_err(nn, "no mailbox present, command: %u\n", mbox_cmd);
301 return -EIO;
302 }
303
304 nn_writeq(nn, mbox + NFP_NET_CFG_MBOX_SIMPLE_CMD, mbox_cmd);
299 305
300 ret = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_MBOX); 306 ret = nfp_net_reconfig(nn, NFP_NET_CFG_UPDATE_MBOX);
301 if (ret) { 307 if (ret) {
@@ -303,7 +309,7 @@ static int nfp_net_reconfig_mbox(struct nfp_net *nn, u32 mbox_cmd)
303 return ret; 309 return ret;
304 } 310 }
305 311
306 return -nn_readl(nn, NFP_NET_CFG_MBOX_RET); 312 return -nn_readl(nn, mbox + NFP_NET_CFG_MBOX_SIMPLE_RET);
307} 313}
308 314
309/* Interrupt configuration and handling 315/* Interrupt configuration and handling
@@ -3084,8 +3090,9 @@ nfp_net_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
3084 if (!vid) 3090 if (!vid)
3085 return 0; 3091 return 0;
3086 3092
3087 nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_VID, vid); 3093 nn_writew(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_VLAN_FILTER_VID, vid);
3088 nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_PROTO, ETH_P_8021Q); 3094 nn_writew(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_VLAN_FILTER_PROTO,
3095 ETH_P_8021Q);
3089 3096
3090 return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_ADD); 3097 return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_ADD);
3091} 3098}
@@ -3101,8 +3108,9 @@ nfp_net_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
3101 if (!vid) 3108 if (!vid)
3102 return 0; 3109 return 0;
3103 3110
3104 nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_VID, vid); 3111 nn_writew(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_VLAN_FILTER_VID, vid);
3105 nn_writew(nn, NFP_NET_CFG_VLAN_FILTER_PROTO, ETH_P_8021Q); 3112 nn_writew(nn, nn->tlv_caps.mbox_off + NFP_NET_CFG_VLAN_FILTER_PROTO,
3113 ETH_P_8021Q);
3106 3114
3107 return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL); 3115 return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL);
3108} 3116}
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)
43{ 43{
44 memset(caps, 0, sizeof(*caps)); 44 memset(caps, 0, sizeof(*caps));
45 caps->me_freq_mhz = 1200; 45 caps->me_freq_mhz = 1200;
46 caps->mbox_off = NFP_NET_CFG_MBOX_BASE;
47 caps->mbox_len = NFP_NET_CFG_MBOX_VAL_MAX_SZ;
46} 48}
47 49
48int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem, 50int 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,
102 104
103 caps->me_freq_mhz = readl(data); 105 caps->me_freq_mhz = readl(data);
104 break; 106 break;
107 case NFP_NET_CFG_TLV_TYPE_MBOX:
108 if (!length) {
109 caps->mbox_off = 0;
110 caps->mbox_len = 0;
111 } else {
112 caps->mbox_off = data - ctrl_mem;
113 caps->mbox_len = length;
114 }
115 break;
105 default: 116 default:
106 if (!FIELD_GET(NFP_NET_CFG_TLV_HEADER_REQUIRED, hdr)) 117 if (!FIELD_GET(NFP_NET_CFG_TLV_HEADER_REQUIRED, hdr))
107 break; 118 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 @@
413 * 4B used for update command and 4B return code 413 * 4B used for update command and 4B return code
414 * followed by a max of 504B of variable length value 414 * followed by a max of 504B of variable length value
415 */ 415 */
416#define NFP_NET_CFG_MBOX_CMD 0x1800 416#define NFP_NET_CFG_MBOX_BASE 0x1800
417#define NFP_NET_CFG_MBOX_RET 0x1804
418#define NFP_NET_CFG_MBOX_VAL 0x1808
419#define NFP_NET_CFG_MBOX_VAL_MAX_SZ 0x1F8 417#define NFP_NET_CFG_MBOX_VAL_MAX_SZ 0x1F8
420 418
419#define NFP_NET_CFG_MBOX_SIMPLE_CMD 0x0
420#define NFP_NET_CFG_MBOX_SIMPLE_RET 0x4
421#define NFP_NET_CFG_MBOX_SIMPLE_VAL 0x8
422#define NFP_NET_CFG_MBOX_SIMPLE_LEN 0x12
423
421#define NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_ADD 1 424#define NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_ADD 1
422#define NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL 2 425#define NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL 2
423 426
@@ -428,7 +431,7 @@
428 * %NFP_NET_CFG_VLAN_FILTER_PROTO: VLAN proto to filter 431 * %NFP_NET_CFG_VLAN_FILTER_PROTO: VLAN proto to filter
429 * %NFP_NET_CFG_VXLAN_SZ: Size of the VLAN filter mailbox in bytes 432 * %NFP_NET_CFG_VXLAN_SZ: Size of the VLAN filter mailbox in bytes
430 */ 433 */
431#define NFP_NET_CFG_VLAN_FILTER NFP_NET_CFG_MBOX_VAL 434#define NFP_NET_CFG_VLAN_FILTER NFP_NET_CFG_MBOX_SIMPLE_VAL
432#define NFP_NET_CFG_VLAN_FILTER_VID NFP_NET_CFG_VLAN_FILTER 435#define NFP_NET_CFG_VLAN_FILTER_VID NFP_NET_CFG_VLAN_FILTER
433#define NFP_NET_CFG_VLAN_FILTER_PROTO (NFP_NET_CFG_VLAN_FILTER + 2) 436#define NFP_NET_CFG_VLAN_FILTER_PROTO (NFP_NET_CFG_VLAN_FILTER + 2)
434#define NFP_NET_CFG_VLAN_FILTER_SZ 0x0004 437#define NFP_NET_CFG_VLAN_FILTER_SZ 0x0004
@@ -478,23 +481,37 @@
478 * %NFP_NET_CFG_TLV_TYPE_ME_FREQ: 481 * %NFP_NET_CFG_TLV_TYPE_ME_FREQ:
479 * Single word, ME frequency in MHz as used in calculation for 482 * Single word, ME frequency in MHz as used in calculation for
480 * %NFP_NET_CFG_RXR_IRQ_MOD and %NFP_NET_CFG_TXR_IRQ_MOD. 483 * %NFP_NET_CFG_RXR_IRQ_MOD and %NFP_NET_CFG_TXR_IRQ_MOD.
484 *
485 * %NFP_NET_CFG_TLV_TYPE_MBOX:
486 * Variable, mailbox area. Overwrites the default location which is
487 * %NFP_NET_CFG_MBOX_BASE and length %NFP_NET_CFG_MBOX_VAL_MAX_SZ.
481 */ 488 */
482#define NFP_NET_CFG_TLV_TYPE_UNKNOWN 0 489#define NFP_NET_CFG_TLV_TYPE_UNKNOWN 0
483#define NFP_NET_CFG_TLV_TYPE_RESERVED 1 490#define NFP_NET_CFG_TLV_TYPE_RESERVED 1
484#define NFP_NET_CFG_TLV_TYPE_END 2 491#define NFP_NET_CFG_TLV_TYPE_END 2
485#define NFP_NET_CFG_TLV_TYPE_ME_FREQ 3 492#define NFP_NET_CFG_TLV_TYPE_ME_FREQ 3
493#define NFP_NET_CFG_TLV_TYPE_MBOX 4
486 494
487struct device; 495struct device;
488 496
489/** 497/**
490 * struct nfp_net_tlv_caps - parsed control BAR TLV capabilities 498 * struct nfp_net_tlv_caps - parsed control BAR TLV capabilities
491 * @me_freq_mhz: ME clock_freq (MHz) 499 * @me_freq_mhz: ME clock_freq (MHz)
500 * @mbox_off: vNIC mailbox area offset
501 * @mbox_len: vNIC mailbox area length
492 */ 502 */
493struct nfp_net_tlv_caps { 503struct nfp_net_tlv_caps {
494 u32 me_freq_mhz; 504 u32 me_freq_mhz;
505 unsigned int mbox_off;
506 unsigned int mbox_len;
495}; 507};
496 508
497int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem, 509int nfp_net_tlv_caps_parse(struct device *dev, u8 __iomem *ctrl_mem,
498 struct nfp_net_tlv_caps *caps); 510 struct nfp_net_tlv_caps *caps);
499 511
512static inline bool nfp_net_has_mbox(struct nfp_net_tlv_caps *caps)
513{
514 return caps->mbox_len >= NFP_NET_CFG_MBOX_SIMPLE_LEN;
515}
516
500#endif /* _NFP_NET_CTRL_H_ */ 517#endif /* _NFP_NET_CTRL_H_ */