This series of patches add support for parsing switch headers and
configuration support for phy modulation type(NRZ or PAM4).
PHYs that support changing modulation type ,user can configure it
through private flags pam4.
Marvell switches support DSA(distributed switch architecture) with
different switch headers like FDSA and EDSA. This patch series adds
private flags to enable user to configure interface in fdsa/edsa
mode such that flow steering (forwading packets to pf/vf depending on
switch header fields) and packet parsing can be acheived.
Also adds support for HIGIG2 protocol, user can configure interface
in higig mode through higig private flage, such that packet classification
and flow sterring achieved on packets with higig header
Felix Manlunas (2):
octeontx2-af: Add new CGX_CMDs to set and get PHY modulation type
octeontx2-pf: Add ethtool priv flag to control PAM4 on/off
Hariprasad Kelam (6):
octeontx2-af: Support for parsing pkts with switch headers
octeontx2-af: Do not allow VFs to overwrite PKIND config
octeontx2-af: Put CGX LMAC also in Higig2 mode
octeontx2-pf: Support to enable EDSA/Higig2 pkts parsing
octeontx2-af: Add flow steering support for FDSA tag
octeontx2-pf: Add ntuple filter support for FDSA
.../net/ethernet/marvell/octeontx2/af/cgx.c | 177 ++++++++++++-
.../net/ethernet/marvell/octeontx2/af/cgx.h | 19 +-
.../ethernet/marvell/octeontx2/af/cgx_fw_if.h | 6 +
.../net/ethernet/marvell/octeontx2/af/mbox.h | 39 ++-
.../net/ethernet/marvell/octeontx2/af/npc.h | 14 +-
.../net/ethernet/marvell/octeontx2/af/rvu.h | 9 +
.../ethernet/marvell/octeontx2/af/rvu_cgx.c | 103 +++++++-
.../marvell/octeontx2/af/rvu_debugfs.c | 3 +-
.../ethernet/marvell/octeontx2/af/rvu_nix.c | 44 +++-
.../ethernet/marvell/octeontx2/af/rvu_npc.c | 76 ++++++
.../marvell/octeontx2/af/rvu_npc_fs.c | 14 +-
.../marvell/octeontx2/nic/otx2_common.c | 2 +
.../marvell/octeontx2/nic/otx2_common.h | 36 ++-
.../marvell/octeontx2/nic/otx2_ethtool.c | 244 ++++++++++++++++++
.../marvell/octeontx2/nic/otx2_flows.c | 58 ++++-
.../ethernet/marvell/octeontx2/nic/otx2_pf.c | 21 +-
.../marvell/octeontx2/nic/otx2_txrx.c | 1 +
.../ethernet/marvell/octeontx2/nic/otx2_vf.c | 10 +
18 files changed, 832 insertions(+), 44 deletions(-)
--
2.17.1
From: Felix Manlunas <[email protected]>
For PHYs that support changing modulation type (NRZ or PAM4), enable these
commands:
ethtool --set-priv-flags ethX pam4 on
ethtool --set-priv-flags ethX pam4 off # means NRZ modulation
ethtool --show-priv-flags ethX
Signed-off-by: Felix Manlunas <[email protected]>
Signed-off-by: Hariprasad Kelam <[email protected]>
Signed-off-by: Sunil Goutham <[email protected]>
---
.../marvell/octeontx2/nic/otx2_ethtool.c | 62 +++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
index f4962a97a07..552ecae1dbe 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
@@ -22,6 +22,11 @@
#define DRV_NAME "octeontx2-nicpf"
#define DRV_VF_NAME "octeontx2-nicvf"
+static const char otx2_priv_flags_strings[][ETH_GSTRING_LEN] = {
+#define OTX2_PRIV_FLAGS_PAM4 BIT(0)
+ "pam4",
+};
+
struct otx2_stat {
char name[ETH_GSTRING_LEN];
unsigned int index;
@@ -112,6 +117,12 @@ static void otx2_get_strings(struct net_device *netdev, u32 sset, u8 *data)
struct otx2_nic *pfvf = netdev_priv(netdev);
int stats;
+ if (sset == ETH_SS_PRIV_FLAGS) {
+ memcpy(data, otx2_priv_flags_strings,
+ ARRAY_SIZE(otx2_priv_flags_strings) * ETH_GSTRING_LEN);
+ return;
+ }
+
if (sset != ETH_SS_STATS)
return;
@@ -250,6 +261,9 @@ static int otx2_get_sset_count(struct net_device *netdev, int sset)
struct otx2_nic *pfvf = netdev_priv(netdev);
int qstats_count;
+ if (sset == ETH_SS_PRIV_FLAGS)
+ return ARRAY_SIZE(otx2_priv_flags_strings);
+
if (sset != ETH_SS_STATS)
return -EINVAL;
@@ -1219,6 +1233,52 @@ static int otx2_set_link_ksettings(struct net_device *netdev,
return err;
}
+static int otx2_set_priv_flags(struct net_device *netdev, u32 priv_flags)
+{
+ struct otx2_nic *pfvf = netdev_priv(netdev);
+ struct cgx_phy_mod_type *req;
+ struct cgx_fw_data *fwd;
+ int rc = -ENOMEM;
+
+ fwd = otx2_get_fwdata(pfvf);
+ if (IS_ERR(fwd))
+ return PTR_ERR(fwd);
+
+ /* ret here if phy does not support this feature */
+ if (!fwd->fwdata.phy.misc.can_change_mod_type)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&pfvf->mbox.lock);
+ req = otx2_mbox_alloc_msg_cgx_set_phy_mod_type(&pfvf->mbox);
+ if (!req)
+ goto end;
+
+ req->mod = priv_flags & OTX2_PRIV_FLAGS_PAM4;
+ if (!otx2_sync_mbox_msg(&pfvf->mbox))
+ rc = 0;
+
+end:
+ mutex_unlock(&pfvf->mbox.lock);
+ return rc;
+}
+
+static u32 otx2_get_priv_flags(struct net_device *netdev)
+{
+ struct otx2_nic *pfvf = netdev_priv(netdev);
+ struct cgx_fw_data *rsp;
+ u32 priv_flags = 0;
+
+ rsp = otx2_get_fwdata(pfvf);
+
+ if (IS_ERR(rsp))
+ return 0;
+
+ if (rsp->fwdata.phy.misc.mod_type)
+ priv_flags |= OTX2_PRIV_FLAGS_PAM4;
+
+ return priv_flags;
+}
+
static const struct ethtool_ops otx2_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_MAX_FRAMES,
@@ -1250,6 +1310,8 @@ static const struct ethtool_ops otx2_ethtool_ops = {
.set_fecparam = otx2_set_fecparam,
.get_link_ksettings = otx2_get_link_ksettings,
.set_link_ksettings = otx2_set_link_ksettings,
+ .set_priv_flags = otx2_set_priv_flags,
+ .get_priv_flags = otx2_get_priv_flags,
};
void otx2_set_ethtool_ops(struct net_device *netdev)
--
2.17.1
Switch headers are designed to support better flow control and
loadbalancing etc. When switch headers like EDSA, Higig2 etc are
present in ingress or egress pkts default iKPU index (or PKIND)
used by NPC to parse pkts will not work as there are additional
headers appended to the pkt. Hence a separate Pkind is chosen on
Rx and/or Tx sides to tell to KPU to parse the pkts accordingly.
Signed-off-by: Hariprasad Kelam <[email protected]>
Signed-off-by: Geetha sowjanya <[email protected]>
Signed-off-by: Sunil Goutham <[email protected]>
---
.../net/ethernet/marvell/octeontx2/af/mbox.h | 14 +++++
.../net/ethernet/marvell/octeontx2/af/npc.h | 6 ++-
.../net/ethernet/marvell/octeontx2/af/rvu.h | 4 ++
.../ethernet/marvell/octeontx2/af/rvu_cgx.c | 2 +-
.../ethernet/marvell/octeontx2/af/rvu_nix.c | 4 ++
.../ethernet/marvell/octeontx2/af/rvu_npc.c | 54 +++++++++++++++++++
6 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index 66ab320b845..1ce22782260 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -222,6 +222,8 @@ M(NPC_MCAM_READ_BASE_RULE, 0x6011, npc_read_base_steer_rule, \
M(NPC_MCAM_GET_STATS, 0x6012, npc_mcam_entry_stats, \
npc_mcam_get_stats_req, \
npc_mcam_get_stats_rsp) \
+M(NPC_SET_PKIND, 0x6013, npc_set_pkind, \
+ npc_set_pkind, msg_rsp) \
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */ \
M(NIX_LF_ALLOC, 0x8000, nix_lf_alloc, \
nix_lf_alloc_req, nix_lf_alloc_rsp) \
@@ -475,6 +477,18 @@ struct cgx_fw_data {
struct cgx_lmac_fwdata_s fwdata;
};
+struct npc_set_pkind {
+ struct mbox_msghdr hdr;
+#define OTX2_PRIV_FLAGS_DEFAULT BIT_ULL(0)
+#define OTX2_PRIV_FLAGS_EDSA BIT_ULL(1)
+#define OTX2_PRIV_FLAGS_HIGIG BIT_ULL(2)
+#define OTX2_PRIV_FLAGS_CUSTOM BIT_ULL(63)
+ u64 mode;
+#define PKIND_TX BIT_ULL(0)
+#define PKIND_RX BIT_ULL(1)
+ u8 dir;
+ u8 pkind; /* valid only in case custom flag */
+};
struct cgx_set_link_mode_args {
u32 speed;
u8 duplex;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/npc.h
index 1e012e78726..e60f1fa2d55 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/npc.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/npc.h
@@ -146,7 +146,11 @@ enum npc_kpu_lh_ltype {
* Ethernet interfaces, LBK interfaces, etc.
*/
enum npc_pkind_type {
- NPC_TX_DEF_PKIND = 63ULL, /* NIX-TX PKIND */
+ NPC_TX_HIGIG_PKIND = 60ULL,
+ NPC_RX_HIGIG_PKIND,
+ NPC_RX_EDSA_PKIND,
+ NPC_TX_DEF_PKIND,
+
};
/* list of known and supported fields in packet header and
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index baaba01bd8c..2b31ecd3d21 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -616,6 +616,8 @@ void rvu_cgx_enadis_rx_bp(struct rvu *rvu, int pf, bool enable);
int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start);
int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id, int index,
int rxtxflag, u64 *stat);
+bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc);
+
/* NPA APIs */
int rvu_npa_init(struct rvu *rvu);
void rvu_npa_freemem(struct rvu *rvu);
@@ -682,6 +684,8 @@ void npc_read_mcam_entry(struct rvu *rvu, struct npc_mcam *mcam,
u8 *intf, u8 *ena);
bool is_mac_feature_supported(struct rvu *rvu, int pf, int feature);
u32 rvu_cgx_get_fifolen(struct rvu *rvu);
+int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
+ u64 pkind);
int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
int type);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
index b78e48d18f6..992e53e56c3 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
@@ -396,7 +396,7 @@ int rvu_cgx_exit(struct rvu *rvu)
* VF's of mapped PF and other PFs are not allowed. This fn() checks
* whether a PFFUNC is permitted to do the config or not.
*/
-static bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc)
+bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc)
{
if ((pcifunc & RVU_PFVF_FUNC_MASK) ||
!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc)))
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index a8710412134..42cc443e6e8 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -1284,6 +1284,10 @@ int rvu_mbox_handler_nix_lf_free(struct rvu *rvu, struct nix_lf_free_req *req,
return NIX_AF_ERR_LF_RESET;
}
+ /* reset HW config done for Switch headers */
+ rvu_npc_set_parse_mode(rvu, pcifunc, OTX2_PRIV_FLAGS_DEFAULT,
+ (PKIND_TX | PKIND_RX), 0);
+
nix_ctx_free(rvu, pfvf);
return 0;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
index 16d7797b7a1..802668e1f90 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -2845,3 +2845,57 @@ int rvu_mbox_handler_npc_mcam_entry_stats(struct rvu *rvu,
return 0;
}
+
+int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
+ u64 pkind)
+{
+ int pf = rvu_get_pf(pcifunc);
+ int blkaddr, nixlf, rc;
+ u64 rxpkind, txpkind;
+ u8 cgx_id, lmac_id;
+
+ /* use default pkind to disable edsa/higig */
+ rxpkind = rvu_npc_get_pkind(rvu, pf);
+ txpkind = NPC_TX_DEF_PKIND;
+
+ if (mode & OTX2_PRIV_FLAGS_EDSA) {
+ rxpkind = NPC_RX_EDSA_PKIND;
+ } else if (mode & OTX2_PRIV_FLAGS_HIGIG) {
+ rxpkind = NPC_RX_HIGIG_PKIND;
+ txpkind = NPC_TX_HIGIG_PKIND;
+ } else if (mode & OTX2_PRIV_FLAGS_CUSTOM) {
+ rxpkind = pkind;
+ txpkind = pkind;
+ }
+
+ if (dir & PKIND_RX) {
+ /* rx pkind set req valid only for cgx mapped PFs */
+ if (!is_cgx_config_permitted(rvu, pcifunc))
+ return 0;
+ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+
+ rc = cgx_set_pkind(rvu_cgx_pdata(cgx_id, rvu),
+ lmac_id, rxpkind);
+ if (rc)
+ return rc;
+ }
+
+ if (dir & PKIND_TX) {
+ /* Tx pkind set request valid if PCIFUNC has NIXLF attached */
+ rc = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr);
+ if (rc)
+ return rc;
+
+ rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf),
+ txpkind);
+ }
+ return 0;
+}
+
+int rvu_mbox_handler_npc_set_pkind(struct rvu *rvu,
+ struct npc_set_pkind *req,
+ struct msg_rsp *rsp)
+{
+ return rvu_npc_set_parse_mode(rvu, req->hdr.pcifunc, req->mode,
+ req->dir, req->pkind);
+}
--
2.17.1
From: Felix Manlunas <[email protected]>
Implement commands to set and get PHY line-side modulation type
(NRZ or PAM4) from firmware.
Signed-off-by: Felix Manlunas <[email protected]>
Signed-off-by: Hariprasad Kelam <[email protected]>
Signed-off-by: Sunil Goutham <[email protected]>
---
.../net/ethernet/marvell/octeontx2/af/cgx.c | 29 +++++++++++++++++
.../net/ethernet/marvell/octeontx2/af/cgx.h | 2 ++
.../ethernet/marvell/octeontx2/af/cgx_fw_if.h | 6 ++++
.../net/ethernet/marvell/octeontx2/af/mbox.h | 10 +++++-
.../ethernet/marvell/octeontx2/af/rvu_cgx.c | 31 +++++++++++++++++++
5 files changed, 77 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
index 68deae529bc..294e7d12f15 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
@@ -1072,6 +1072,35 @@ int cgx_get_phy_fec_stats(void *cgxd, int lmac_id)
return cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id);
}
+int cgx_set_phy_mod_type(int mod, void *cgxd, int lmac_id)
+{
+ struct cgx *cgx = cgxd;
+ u64 req = 0, resp;
+
+ if (!cgx)
+ return -ENODEV;
+
+ req = FIELD_SET(CMDREG_ID, CGX_CMD_SET_PHY_MOD_TYPE, req);
+ req = FIELD_SET(CMDSETPHYMODTYPE, mod, req);
+ return cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id);
+}
+
+int cgx_get_phy_mod_type(void *cgxd, int lmac_id)
+{
+ struct cgx *cgx = cgxd;
+ u64 req = 0, resp;
+ int err;
+
+ if (!cgx)
+ return -ENODEV;
+
+ req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_PHY_MOD_TYPE, req);
+ err = cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id);
+ if (!err)
+ return FIELD_GET(RESP_GETPHYMODTYPE, resp);
+ return err;
+}
+
static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool enable)
{
u64 req = 0;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
index 12521262164..10b5611a3b4 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
@@ -165,4 +165,6 @@ u8 cgx_get_lmacid(void *cgxd, u8 lmac_index);
unsigned long cgx_get_lmac_bmap(void *cgxd);
void cgx_lmac_write(int cgx_id, int lmac_id, u64 offset, u64 val);
u64 cgx_lmac_read(int cgx_id, int lmac_id, u64 offset);
+int cgx_set_phy_mod_type(int mod, void *cgxd, int lmac_id);
+int cgx_get_phy_mod_type(void *cgxd, int lmac_id);
#endif /* CGX_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
index aa4e42f78f1..6bde02c8e4b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
@@ -264,4 +264,10 @@ struct cgx_lnk_sts {
#define CMDMODECHANGE_PORT GENMASK_ULL(21, 14)
#define CMDMODECHANGE_FLAGS GENMASK_ULL(63, 22)
+/* command argument to be passed for cmd ID - CGX_CMD_SET_PHY_MOD_TYPE */
+#define CMDSETPHYMODTYPE GENMASK_ULL(8, 8)
+
+/* response to cmd ID - RESP_GETPHYMODTYPE */
+#define RESP_GETPHYMODTYPE GENMASK_ULL(9, 9)
+
#endif /* __CGX_FW_INTF_H__ */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index 3af4d0ffcf7..66ab320b845 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -162,7 +162,10 @@ M(CGX_SET_LINK_MODE, 0x214, cgx_set_link_mode, cgx_set_link_mode_req,\
M(CGX_FEATURES_GET, 0x215, cgx_features_get, msg_req, \
cgx_features_info_msg) \
M(RPM_STATS, 0x216, rpm_stats, msg_req, rpm_stats_rsp) \
- /* NPA mbox IDs (range 0x400 - 0x5FF) */ \
+M(CGX_GET_PHY_MOD_TYPE, 0x217, cgx_get_phy_mod_type, msg_req, \
+ cgx_phy_mod_type) \
+M(CGX_SET_PHY_MOD_TYPE, 0x218, cgx_set_phy_mod_type, cgx_phy_mod_type, \
+ msg_rsp) \
/* NPA mbox IDs (range 0x400 - 0x5FF) */ \
M(NPA_LF_ALLOC, 0x400, npa_lf_alloc, \
npa_lf_alloc_req, npa_lf_alloc_rsp) \
@@ -510,6 +513,11 @@ struct rpm_stats_rsp {
u64 tx_stats[RPM_TX_STATS_COUNT];
};
+struct cgx_phy_mod_type {
+ struct mbox_msghdr hdr;
+ int mod;
+};
+
/* NPA mbox message formats */
/* NPA mailbox error codes
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
index e668e482383..b78e48d18f6 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
@@ -939,3 +939,34 @@ int rvu_mbox_handler_cgx_set_link_mode(struct rvu *rvu,
rsp->status = cgx_set_link_mode(cgxd, req->args, cgx_idx, lmac);
return 0;
}
+
+int rvu_mbox_handler_cgx_set_phy_mod_type(struct rvu *rvu,
+ struct cgx_phy_mod_type *req,
+ struct msg_rsp *rsp)
+{
+ int pf = rvu_get_pf(req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_pf_cgxmapped(rvu, pf))
+ return -EPERM;
+
+ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+ return cgx_set_phy_mod_type(req->mod, rvu_cgx_pdata(cgx_id, rvu),
+ lmac_id);
+}
+
+int rvu_mbox_handler_cgx_get_phy_mod_type(struct rvu *rvu, struct msg_req *req,
+ struct cgx_phy_mod_type *rsp)
+{
+ int pf = rvu_get_pf(req->hdr.pcifunc);
+ u8 cgx_id, lmac_id;
+
+ if (!is_pf_cgxmapped(rvu, pf))
+ return -EPERM;
+
+ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+ rsp->mod = cgx_get_phy_mod_type(rvu_cgx_pdata(cgx_id, rvu), lmac_id);
+ if (rsp->mod < 0)
+ return rsp->mod;
+ return 0;
+}
--
2.17.1
When switch headers like EDSA, Higig2 etc are present in ingress
or egress pkts the pkt parsing done by NPC needs to take additional
headers into account. KPU profile handles these using specific PKINDs
(the iKPU index) to start parsing pkts differently.
This patch enables user to configure these PKINDs into hardware for
proper pkt parsing. Patch also handles changes to max frame size due to
additional headers in pkt.
higig2:
ethtool --set-priv-flags eth0 higig2 on/off
edsa:
ethtool --set-priv-flags eth0 edsa on/off
Signed-off-by: Hariprasad Kelam <[email protected]>
Signed-off-by: Sunil Goutham <[email protected]>
---
.../marvell/octeontx2/nic/otx2_common.c | 2 +
.../marvell/octeontx2/nic/otx2_common.h | 22 +++
.../marvell/octeontx2/nic/otx2_ethtool.c | 153 +++++++++++++++++-
.../ethernet/marvell/octeontx2/nic/otx2_pf.c | 8 +
.../marvell/octeontx2/nic/otx2_txrx.c | 1 +
.../ethernet/marvell/octeontx2/nic/otx2_vf.c | 10 ++
6 files changed, 188 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
index cf7875d51d8..b9a5cd35061 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
@@ -230,6 +230,8 @@ int otx2_hw_set_mtu(struct otx2_nic *pfvf, int mtu)
return -ENOMEM;
}
+ /* Add EDSA/HIGIG2 header len to maxlen */
+ pfvf->max_frs = mtu + OTX2_ETH_HLEN + pfvf->addl_mtu;
req->maxlen = pfvf->max_frs;
err = otx2_sync_mbox_msg(&pfvf->mbox);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
index 45730d0d92f..73e927a7843 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
@@ -303,6 +303,7 @@ struct otx2_nic {
struct net_device *netdev;
struct dev_hw_ops *hw_ops;
void *iommu_domain;
+ u16 xtra_hdr;
u16 max_frs;
u16 rbsize; /* Receive buffer size */
@@ -345,6 +346,25 @@ struct otx2_nic {
struct refill_work *refill_wrk;
struct workqueue_struct *otx2_wq;
struct work_struct rx_mode_work;
+
+#define OTX2_PRIV_FLAG_PAM4 BIT(0)
+#define OTX2_PRIV_FLAG_EDSA_HDR BIT(1)
+#define OTX2_PRIV_FLAG_HIGIG2_HDR BIT(2)
+#define OTX2_PRIV_FLAG_DEF_MODE BIT(3)
+#define OTX2_IS_EDSA_ENABLED(flags) ((flags) & \
+ OTX2_PRIV_FLAG_EDSA_HDR)
+#define OTX2_IS_HIGIG2_ENABLED(flags) ((flags) & \
+ OTX2_PRIV_FLAG_HIGIG2_HDR)
+#define OTX2_IS_DEF_MODE_ENABLED(flags) ((flags) & \
+ OTX2_PRIV_FLAG_DEF_MODE)
+ u32 ethtool_flags;
+
+ /* extended DSA and EDSA header lengths are 8/16 bytes
+ * so take max length 16 bytes here
+ */
+#define OTX2_EDSA_HDR_LEN 16
+#define OTX2_HIGIG2_HDR_LEN 16
+ u32 addl_mtu;
struct otx2_mac_table *mac_table;
/* Ethtool stuff */
@@ -796,6 +816,8 @@ int otx2_open(struct net_device *netdev);
int otx2_stop(struct net_device *netdev);
int otx2_set_real_num_queues(struct net_device *netdev,
int tx_queues, int rx_queues);
+int otx2_set_npc_parse_mode(struct otx2_nic *pfvf, bool unbind);
+
/* MCAM filter related APIs */
int otx2_mcam_flow_init(struct otx2_nic *pf);
int otx2_alloc_mcam_entries(struct otx2_nic *pfvf);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
index 552ecae1dbe..c1405611489 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
@@ -23,8 +23,9 @@
#define DRV_VF_NAME "octeontx2-nicvf"
static const char otx2_priv_flags_strings[][ETH_GSTRING_LEN] = {
-#define OTX2_PRIV_FLAGS_PAM4 BIT(0)
"pam4",
+ "edsa",
+ "higig2",
};
struct otx2_stat {
@@ -1233,7 +1234,7 @@ static int otx2_set_link_ksettings(struct net_device *netdev,
return err;
}
-static int otx2_set_priv_flags(struct net_device *netdev, u32 priv_flags)
+static int otx2_set_phy_mod_type(struct net_device *netdev, bool enable)
{
struct otx2_nic *pfvf = netdev_priv(netdev);
struct cgx_phy_mod_type *req;
@@ -1253,7 +1254,7 @@ static int otx2_set_priv_flags(struct net_device *netdev, u32 priv_flags)
if (!req)
goto end;
- req->mod = priv_flags & OTX2_PRIV_FLAGS_PAM4;
+ req->mod = enable;
if (!otx2_sync_mbox_msg(&pfvf->mbox))
rc = 0;
@@ -1262,21 +1263,157 @@ static int otx2_set_priv_flags(struct net_device *netdev, u32 priv_flags)
return rc;
}
+int otx2_set_npc_parse_mode(struct otx2_nic *pfvf, bool unbind)
+{
+ struct npc_set_pkind *req;
+ u32 interface_mode = 0;
+ int rc = -ENOMEM;
+
+ if (OTX2_IS_DEF_MODE_ENABLED(pfvf->ethtool_flags))
+ return 0;
+
+ mutex_lock(&pfvf->mbox.lock);
+ req = otx2_mbox_alloc_msg_npc_set_pkind(&pfvf->mbox);
+ if (!req)
+ goto end;
+
+ if (unbind) {
+ req->mode = OTX2_PRIV_FLAGS_DEFAULT;
+ interface_mode = OTX2_PRIV_FLAG_DEF_MODE;
+ } else if (OTX2_IS_HIGIG2_ENABLED(pfvf->ethtool_flags)) {
+ req->mode = OTX2_PRIV_FLAGS_HIGIG;
+ interface_mode = OTX2_PRIV_FLAG_HIGIG2_HDR;
+ } else if (OTX2_IS_EDSA_ENABLED(pfvf->ethtool_flags)) {
+ req->mode = OTX2_PRIV_FLAGS_EDSA;
+ interface_mode = OTX2_PRIV_FLAG_EDSA_HDR;
+ } else {
+ req->mode = OTX2_PRIV_FLAGS_DEFAULT;
+ interface_mode = OTX2_PRIV_FLAG_DEF_MODE;
+ }
+
+ req->dir = PKIND_RX;
+
+ /* req AF to change pkind on both the dir */
+ if (req->mode == OTX2_PRIV_FLAGS_HIGIG ||
+ req->mode == OTX2_PRIV_FLAGS_DEFAULT)
+ req->dir |= PKIND_TX;
+
+ if (!otx2_sync_mbox_msg(&pfvf->mbox))
+ rc = 0;
+ else
+ pfvf->ethtool_flags &= ~interface_mode;
+end:
+ mutex_unlock(&pfvf->mbox.lock);
+ return rc;
+}
+
static u32 otx2_get_priv_flags(struct net_device *netdev)
{
struct otx2_nic *pfvf = netdev_priv(netdev);
struct cgx_fw_data *rsp;
- u32 priv_flags = 0;
rsp = otx2_get_fwdata(pfvf);
- if (IS_ERR(rsp))
+ if (IS_ERR(rsp)) {
+ pfvf->ethtool_flags &= ~OTX2_PRIV_FLAG_PAM4;
+ } else {
+ if (rsp->fwdata.phy.misc.mod_type)
+ pfvf->ethtool_flags |= OTX2_PRIV_FLAG_PAM4;
+ else
+ pfvf->ethtool_flags &= ~OTX2_PRIV_FLAG_PAM4;
+ }
+ return pfvf->ethtool_flags;
+}
+
+static int otx2_enable_addl_header(struct net_device *netdev, int bitpos,
+ u32 len, bool enable)
+{
+ struct otx2_nic *pfvf = netdev_priv(netdev);
+ bool if_up = netif_running(netdev);
+
+ if (enable) {
+ pfvf->ethtool_flags |= BIT(bitpos);
+ pfvf->ethtool_flags &= ~OTX2_PRIV_FLAG_DEF_MODE;
+ } else {
+ pfvf->ethtool_flags &= ~BIT(bitpos);
+ len = 0;
+ }
+
+ if (if_up)
+ otx2_stop(netdev);
+
+ /* Update max FRS so that additional hdrs are considered */
+ pfvf->addl_mtu = len;
+
+ /* Incase HIGIG2 mode is set packet will have 16 bytes of
+ * extra header at start of packet which stack does not need.
+ */
+ if (OTX2_IS_HIGIG2_ENABLED(pfvf->ethtool_flags))
+ pfvf->xtra_hdr = 16;
+ else
+ pfvf->xtra_hdr = 0;
+
+ /* NPC parse mode will be updated here */
+ if (if_up) {
+ otx2_open(netdev);
+
+ if (!enable)
+ pfvf->ethtool_flags |= OTX2_PRIV_FLAG_DEF_MODE;
+ }
+
+ return 0;
+}
+
+static int otx2_set_priv_flags(struct net_device *netdev, u32 new_flags)
+{
+ struct otx2_nic *pfvf = netdev_priv(netdev);
+ bool enable = false;
+ int bitnr, rc = 0;
+ u32 chg_flags;
+
+ /* Get latest PAM4 settings */
+ otx2_get_priv_flags(netdev);
+
+ chg_flags = new_flags ^ pfvf->ethtool_flags;
+ if (!chg_flags)
return 0;
- if (rsp->fwdata.phy.misc.mod_type)
- priv_flags |= OTX2_PRIV_FLAGS_PAM4;
+ /* Some are mutually exclusive, so allow only change at a time */
+ if (hweight32(chg_flags) != 1)
+ return -EINVAL;
+
+ bitnr = ffs(chg_flags) - 1;
+ if (new_flags & BIT(bitnr))
+ enable = true;
+
+ switch (BIT(bitnr)) {
+ case OTX2_PRIV_FLAG_PAM4:
+ rc = otx2_set_phy_mod_type(netdev, enable);
+ break;
+ case OTX2_PRIV_FLAG_EDSA_HDR:
+ /* HIGIG & EDSA are mutual exclusive */
+ if (enable && OTX2_IS_HIGIG2_ENABLED(pfvf->ethtool_flags))
+ return -EINVAL;
+ return otx2_enable_addl_header(netdev, bitnr,
+ OTX2_EDSA_HDR_LEN, enable);
+ case OTX2_PRIV_FLAG_HIGIG2_HDR:
+ if (enable && OTX2_IS_EDSA_ENABLED(pfvf->ethtool_flags))
+ return -EINVAL;
+ return otx2_enable_addl_header(netdev, bitnr,
+ OTX2_HIGIG2_HDR_LEN, enable);
+ default:
+ break;
+ }
+
+ /* save the change */
+ if (!rc) {
+ if (enable)
+ pfvf->ethtool_flags |= BIT(bitnr);
+ else
+ pfvf->ethtool_flags &= ~BIT(bitnr);
+ }
- return priv_flags;
+ return rc;
}
static const struct ethtool_ops otx2_ethtool_ops = {
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
index 772a29ba850..977da158f1d 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
@@ -1639,6 +1639,9 @@ int otx2_open(struct net_device *netdev)
/* Restore pause frame settings */
otx2_config_pause_frm(pf);
+ /* Set NPC parsing mode */
+ otx2_set_npc_parse_mode(pf, false);
+
err = otx2_rxtx_enable(pf, true);
if (err)
goto err_tx_stop_queues;
@@ -2511,6 +2514,9 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
pf->flags |= OTX2_FLAG_RX_PAUSE_ENABLED;
pf->flags |= OTX2_FLAG_TX_PAUSE_ENABLED;
+ /* Set interface mode as Default */
+ pf->ethtool_flags |= OTX2_PRIV_FLAG_DEF_MODE;
+
return 0;
err_mcam_flow_del:
@@ -2671,6 +2677,8 @@ static void otx2_remove(struct pci_dev *pdev)
if (pf->flags & OTX2_FLAG_RX_TSTAMP_ENABLED)
otx2_config_hw_rx_tstamp(pf, false);
+ otx2_set_npc_parse_mode(pf, true);
+
cancel_work_sync(&pf->reset_task);
/* Disable link notifications */
otx2_cgx_config_linkevents(pf, false);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
index 22ec03a618b..14292e35ace 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
@@ -154,6 +154,7 @@ static void otx2_skb_add_frag(struct otx2_nic *pfvf, struct sk_buff *skb,
otx2_set_rxtstamp(pfvf, skb, va);
off = OTX2_HW_TIMESTAMP_LEN;
}
+ off += pfvf->xtra_hdr;
}
page = virt_to_page(va);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
index 085be90a03e..eb0c009357f 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
@@ -377,6 +377,13 @@ static netdev_tx_t otx2vf_xmit(struct sk_buff *skb, struct net_device *netdev)
struct otx2_snd_queue *sq;
struct netdev_queue *txq;
+ /* Check for minimum and maximum packet length */
+ if (skb->len <= ETH_HLEN ||
+ (!skb_shinfo(skb)->gso_size && skb->len > vf->max_frs)) {
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
sq = &vf->qset.sq[qidx];
txq = netdev_get_tx_queue(netdev, qidx);
@@ -612,6 +619,9 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
vf->flags |= OTX2_FLAG_RX_PAUSE_ENABLED;
vf->flags |= OTX2_FLAG_TX_PAUSE_ENABLED;
+ /* Set interface mode as Default */
+ vf->ethtool_flags |= OTX2_PRIV_FLAG_DEF_MODE;
+
return 0;
err_detach_rsrc:
--
2.17.1
When switch headers like EDSA, Higig2 etc are present in ingress
or egress packets the packet parsing done by NPC needs to take additional
headers into account. KPU profile handles these using specific
PKINDs (the iKPU index) to parse these packets differently.
AF writes these pkinds to HW upon receiving NPC_SET_PKIND mbox request.
But in nix_lf_alloc mbox request from VF, AF writes default RX/TX
pkinds to HW. Since PF and its VFs share same CGX/LMAC pair, earlier
configuration is getting overwritten. Ideally VF should not override PF
configuration. This patch adds proper validation to ensure the same.
Signed-off-by: Hariprasad Kelam <[email protected]>
Signed-off-by: Sunil Goutham <[email protected]>
---
.../net/ethernet/marvell/octeontx2/af/cgx.c | 12 +++++++
.../net/ethernet/marvell/octeontx2/af/cgx.h | 1 +
.../net/ethernet/marvell/octeontx2/af/rvu.h | 1 +
.../ethernet/marvell/octeontx2/af/rvu_cgx.c | 36 +++++++++++++++++++
.../ethernet/marvell/octeontx2/af/rvu_nix.c | 14 +++++---
5 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
index 294e7d12f15..aa86691885d 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
@@ -231,6 +231,18 @@ int cgx_set_pkind(void *cgxd, u8 lmac_id, int pkind)
return 0;
}
+int cgx_get_pkind(void *cgxd, u8 lmac_id, int *pkind)
+{
+ struct cgx *cgx = cgxd;
+
+ if (!is_lmac_valid(cgx, lmac_id))
+ return -ENODEV;
+
+ *pkind = cgx_read(cgx, lmac_id, CGXX_CMRX_RX_ID_MAP);
+ *pkind = *pkind & 0x3F;
+ return 0;
+}
+
static u8 cgx_get_lmac_type(void *cgxd, int lmac_id)
{
struct cgx *cgx = cgxd;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
index 10b5611a3b4..237a91b801e 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
@@ -167,4 +167,5 @@ void cgx_lmac_write(int cgx_id, int lmac_id, u64 offset, u64 val);
u64 cgx_lmac_read(int cgx_id, int lmac_id, u64 offset);
int cgx_set_phy_mod_type(int mod, void *cgxd, int lmac_id);
int cgx_get_phy_mod_type(void *cgxd, int lmac_id);
+int cgx_get_pkind(void *cgxd, u8 lmac_id, int *pkind);
#endif /* CGX_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index 2b31ecd3d21..292351bad5b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -617,6 +617,7 @@ int rvu_cgx_start_stop_io(struct rvu *rvu, u16 pcifunc, bool start);
int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id, int index,
int rxtxflag, u64 *stat);
bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc);
+bool rvu_cgx_is_pkind_config_permitted(struct rvu *rvu, u16 pcifunc);
/* NPA APIs */
int rvu_npa_init(struct rvu *rvu);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
index 992e53e56c3..9c30692070b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
@@ -970,3 +970,39 @@ int rvu_mbox_handler_cgx_get_phy_mod_type(struct rvu *rvu, struct msg_req *req,
return rsp->mod;
return 0;
}
+
+/* Dont allow cgx mapped VFs to overwrite PKIND config
+ * incase of special PKINDs are configured like (HIGIG/EDSA)
+ */
+bool rvu_cgx_is_pkind_config_permitted(struct rvu *rvu, u16 pcifunc)
+{
+ int rc, pf, rxpkind;
+ u8 cgx_id, lmac_id;
+
+ pf = rvu_get_pf(pcifunc);
+
+ /* Ret here for PFs or non cgx interfaces */
+ if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+ return true;
+
+ if (!is_pf_cgxmapped(rvu, pf))
+ return true;
+
+ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+
+ rc = cgx_get_pkind(rvu_cgx_pdata(cgx_id, rvu), lmac_id, &rxpkind);
+ if (rc)
+ return false;
+
+ switch (rxpkind) {
+ /* Add here specific pkinds reserved for pkt parsing */
+ case NPC_RX_HIGIG_PKIND:
+ case NPC_RX_EDSA_PKIND:
+ rc = false;
+ break;
+ default:
+ rc = true;
+ }
+
+ return rc;
+}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index 42cc443e6e8..ed96ebc4022 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -239,8 +239,12 @@ static int nix_interface_init(struct rvu *rvu, u16 pcifunc, int type, int nixlf)
pfvf->tx_chan_base = pfvf->rx_chan_base;
pfvf->rx_chan_cnt = 1;
pfvf->tx_chan_cnt = 1;
- cgx_set_pkind(rvu_cgx_pdata(cgx_id, rvu), lmac_id, pkind);
- rvu_npc_set_pkind(rvu, pkind, pfvf);
+
+ if (rvu_cgx_is_pkind_config_permitted(rvu, pcifunc)) {
+ cgx_set_pkind(rvu_cgx_pdata(cgx_id, rvu), lmac_id,
+ pkind);
+ rvu_npc_set_pkind(rvu, pkind, pfvf);
+ }
mac_ops = get_mac_ops(rvu_cgx_pdata(cgx_id, rvu));
/* By default we enable pause frames */
@@ -1196,8 +1200,10 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
rvu_write64(rvu, blkaddr, NIX_AF_LFX_RX_CFG(nixlf), req->rx_cfg);
/* Configure pkind for TX parse config */
- cfg = NPC_TX_DEF_PKIND;
- rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf), cfg);
+ if (rvu_cgx_is_pkind_config_permitted(rvu, pcifunc)) {
+ cfg = NPC_TX_DEF_PKIND;
+ rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf), cfg);
+ }
intf = is_afvf(pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX;
err = nix_interface_init(rvu, pcifunc, intf, nixlf);
--
2.17.1
Marvell switches support distributed switch architecture (DSA) by
implementing FORWARD(FDSA). Special pkind 62 is reserved to parse
this tag.
This patch adds support to configure pkind and flow steering for
the same. To distribute fdsa packets among PF/VF , one can
specify NPC_FDSA_VAL in mcam features .Rx vtag Type 6 is reserved
to strip FDSA tag.
Signed-off-by: Hariprasad Kelam <[email protected]>
Signed-off-by: Sunil Goutham <[email protected]>
---
drivers/net/ethernet/marvell/octeontx2/af/mbox.h | 1 +
drivers/net/ethernet/marvell/octeontx2/af/npc.h | 8 ++++++++
drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 1 +
.../ethernet/marvell/octeontx2/af/rvu_debugfs.c | 3 ++-
.../net/ethernet/marvell/octeontx2/af/rvu_nix.c | 9 +++++++--
.../net/ethernet/marvell/octeontx2/af/rvu_npc.c | 10 +++++++++-
.../net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c | 14 ++++++++++++--
7 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index a1f71ee9e98..8e0d1e47876 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -482,6 +482,7 @@ struct npc_set_pkind {
#define OTX2_PRIV_FLAGS_DEFAULT BIT_ULL(0)
#define OTX2_PRIV_FLAGS_EDSA BIT_ULL(1)
#define OTX2_PRIV_FLAGS_HIGIG BIT_ULL(2)
+#define OTX2_PRIV_FLAGS_FDSA BIT_ULL(3)
#define OTX2_PRIV_FLAGS_CUSTOM BIT_ULL(63)
u64 mode;
#define PKIND_TX BIT_ULL(0)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/npc.h b/drivers/net/ethernet/marvell/octeontx2/af/npc.h
index e60f1fa2d55..059de54a4dd 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/npc.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/npc.h
@@ -179,6 +179,7 @@ enum key_fields {
NPC_DPORT_UDP,
NPC_SPORT_SCTP,
NPC_DPORT_SCTP,
+ NPC_FDSA_VAL,
NPC_HEADER_FIELDS_MAX,
NPC_CHAN = NPC_HEADER_FIELDS_MAX, /* Valid when Rx */
NPC_PF_FUNC, /* Valid when Tx */
@@ -208,6 +209,13 @@ enum key_fields {
NPC_KEY_FIELDS_MAX,
};
+enum npc_interface_type {
+ NPC_INTF_MODE_DEF,
+ NPC_INTF_MODE_EDSA,
+ NPC_INTF_MODE_HIGIG,
+ NPC_INTF_MODE_FDSA,
+};
+
struct npc_kpu_profile_cam {
u8 state;
u8 state_mask;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index ae51937ee46..f9fd443a34d 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -239,6 +239,7 @@ struct rvu_pfvf {
u8 nix_blkaddr; /* BLKADDR_NIX0/1 assigned to this PF */
u8 nix_rx_intf; /* NIX0_RX/NIX1_RX interface to NPC */
u8 nix_tx_intf; /* NIX0_TX/NIX1_TX interface to NPC */
+ int intf_mode;
};
struct nix_txsch {
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
index 741da112fdf..791eaf5e2ca 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
@@ -2002,7 +2002,8 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s,
seq_printf(s, "mask 0x%x\n", ntohs(rule->mask.etype));
break;
case NPC_OUTER_VID:
- seq_printf(s, "0x%x ", ntohs(rule->packet.vlan_tci));
+ case NPC_FDSA_VAL:
+ seq_printf(s, "%d ", ntohs(rule->packet.vlan_tci));
seq_printf(s, "mask 0x%x\n",
ntohs(rule->mask.vlan_tci));
break;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index 56ade799011..8959f03867f 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -1217,6 +1217,11 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
rvu_write64(rvu, blkaddr,
NIX_AF_LFX_RX_VTAG_TYPEX(nixlf, NIX_AF_LFX_RX_VTAG_TYPE7),
VTAGSIZE_T4 | VTAG_STRIP);
+ /* Configure RX VTAG Type 6 (strip) for fdsa */
+ rvu_write64(rvu, blkaddr,
+ NIX_AF_LFX_RX_VTAG_TYPEX(nixlf, NIX_AF_LFX_RX_VTAG_TYPE6),
+ VTAGSIZE_T4 | VTAG_STRIP | VTAG_CAPTURE);
+
goto exit;
@@ -2016,8 +2021,8 @@ static int nix_rx_vtag_cfg(struct rvu *rvu, int nixlf, int blkaddr,
req->vtag_size > VTAGSIZE_T8)
return -EINVAL;
- /* RX VTAG Type 7 reserved for vf vlan */
- if (req->rx.vtag_type == NIX_AF_LFX_RX_VTAG_TYPE7)
+ /* RX VTAG Type 7,6 are reserved for vf vlan& FDSA tag strip */
+ if (req->rx.vtag_type >= NIX_AF_LFX_RX_VTAG_TYPE6)
return NIX_AF_ERR_RX_VTAG_INUSE;
if (req->rx.capture_vtag)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
index dba57a6b439..70a4243056e 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -2849,18 +2849,24 @@ int rvu_mbox_handler_npc_mcam_entry_stats(struct rvu *rvu,
int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
u64 pkind)
{
+ struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
+ int blkaddr, nixlf, rc, intf_mode;
int pf = rvu_get_pf(pcifunc);
bool enable_higig2 = false;
- int blkaddr, nixlf, rc;
u64 rxpkind, txpkind;
u8 cgx_id, lmac_id;
/* use default pkind to disable edsa/higig */
rxpkind = rvu_npc_get_pkind(rvu, pf);
txpkind = NPC_TX_DEF_PKIND;
+ intf_mode = NPC_INTF_MODE_DEF;
if (mode & OTX2_PRIV_FLAGS_EDSA) {
rxpkind = NPC_RX_EDSA_PKIND;
+ intf_mode = NPC_INTF_MODE_EDSA;
+ } else if (mode & OTX2_PRIV_FLAGS_FDSA) {
+ rxpkind = NPC_RX_EDSA_PKIND;
+ intf_mode = NPC_INTF_MODE_FDSA;
} else if (mode & OTX2_PRIV_FLAGS_HIGIG) {
/* Silicon does not support enabling higig in time stamp mode */
if (rvu_nix_is_ptp_tx_enabled(rvu, pcifunc))
@@ -2872,6 +2878,7 @@ int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
rxpkind = NPC_RX_HIGIG_PKIND;
txpkind = NPC_TX_HIGIG_PKIND;
+ intf_mode = NPC_INTF_MODE_HIGIG;
enable_higig2 = true;
} else if (mode & OTX2_PRIV_FLAGS_CUSTOM) {
rxpkind = pkind;
@@ -2903,6 +2910,7 @@ int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
if (enable_higig2 ^ rvu_cgx_is_higig2_enabled(rvu, pf))
rvu_cgx_enadis_higig2(rvu, pf, enable_higig2);
+ pfvf->intf_mode = intf_mode;
return 0;
}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
index 7f35b62eea1..17097a07ccb 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
@@ -39,6 +39,7 @@ static const char * const npc_flow_names[] = {
[NPC_DPORT_UDP] = "udp destination port",
[NPC_SPORT_SCTP] = "sctp source port",
[NPC_DPORT_SCTP] = "sctp destination port",
+ [NPC_FDSA_VAL] = "FDSA tag value ",
[NPC_UNKNOWN] = "unknown",
};
@@ -445,6 +446,7 @@ do { \
NPC_SCAN_HDR(NPC_ETYPE_TAG2, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 8, 2);
NPC_SCAN_HDR(NPC_VLAN_TAG1, NPC_LID_LB, NPC_LT_LB_CTAG, 2, 2);
NPC_SCAN_HDR(NPC_VLAN_TAG2, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 2, 2);
+ NPC_SCAN_HDR(NPC_FDSA_VAL, NPC_LID_LB, NPC_LT_LB_FDSA, 1, 1);
NPC_SCAN_HDR(NPC_DMAC, NPC_LID_LA, la_ltype, la_start, 6);
NPC_SCAN_HDR(NPC_SMAC, NPC_LID_LA, la_ltype, la_start, 6);
/* PF_FUNC is 2 bytes at 0th byte of NPC_LT_LA_IH_NIX_ETHER */
@@ -492,9 +494,12 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf)
*features |= BIT_ULL(NPC_IPPROTO_ESP);
/* for vlan corresponding layer type should be in the key */
- if (*features & BIT_ULL(NPC_OUTER_VID))
- if (!npc_check_field(rvu, blkaddr, NPC_LB, intf))
+ if (*features & BIT_ULL(NPC_OUTER_VID) ||
+ *features & BIT_ULL(NPC_FDSA_VAL))
+ if (!npc_check_field(rvu, blkaddr, NPC_LB, intf)) {
*features &= ~BIT_ULL(NPC_OUTER_VID);
+ *features &= ~BIT_ULL(NPC_FDSA_VAL);
+ }
}
/* Scan key extraction profile and record how fields of our interest
@@ -786,6 +791,9 @@ static void npc_update_flow(struct rvu *rvu, struct mcam_entry *entry,
npc_update_entry(rvu, NPC_LB, entry,
NPC_LT_LB_STAG_QINQ | NPC_LT_LB_CTAG, 0,
NPC_LT_LB_STAG_QINQ & NPC_LT_LB_CTAG, 0, intf);
+ if (features & BIT_ULL(NPC_FDSA_VAL))
+ npc_update_entry(rvu, NPC_LB, entry, NPC_LT_LB_FDSA,
+ 0, ~0ULL, 0, intf);
/* For AH, LTYPE should be present in entry */
if (features & BIT_ULL(NPC_IPPROTO_AH))
@@ -830,6 +838,8 @@ do { \
NPC_WRITE_FLOW(NPC_OUTER_VID, vlan_tci, ntohs(pkt->vlan_tci), 0,
ntohs(mask->vlan_tci), 0);
+ NPC_WRITE_FLOW(NPC_FDSA_VAL, vlan_tci, ntohs(pkt->vlan_tci), 0,
+ ntohs(mask->vlan_tci), 0);
npc_update_ipv6_flow(rvu, entry, features, pkt, mask, output, intf);
}
--
2.17.1
Currently upon user request to enable Higig2 mode, only NPC packet
parsing related settings are done. This patch adds config to put
CGX LMAC also in Higig2 mode. Actual hardware config is done by firmware,
so send a request to firmware to get the config done.
Adds support for higig2 pause frames such that when user enables
higig2, 802.3 pause frames are disabled and higig2 pause frames
are enabled vice versa.
Other changes
- CGX HW doesn't support timestamping when in Higig2 mode, so
made PTP and Higig2 settings mutually exclusive.
Signed-off-by: Hariprasad Kelam <[email protected]>
Signed-off-by: Sunil Goutham <[email protected]>
---
.../net/ethernet/marvell/octeontx2/af/cgx.c | 136 ++++++++++++++++--
.../net/ethernet/marvell/octeontx2/af/cgx.h | 16 ++-
.../net/ethernet/marvell/octeontx2/af/mbox.h | 14 +-
.../net/ethernet/marvell/octeontx2/af/rvu.h | 3 +
.../ethernet/marvell/octeontx2/af/rvu_cgx.c | 34 +++++
.../ethernet/marvell/octeontx2/af/rvu_nix.c | 17 +++
.../ethernet/marvell/octeontx2/af/rvu_npc.c | 14 ++
7 files changed, 214 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
index aa86691885d..1cbd1ffe039 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
@@ -460,18 +460,32 @@ int cgx_lmac_tx_enable(void *cgxd, int lmac_id, bool enable)
return !!(last & DATA_PKT_TX_EN);
}
-static int cgx_lmac_get_pause_frm_status(void *cgxd, int lmac_id,
- u8 *tx_pause, u8 *rx_pause)
+static int cgx_lmac_get_higig2_pause_frm_status(void *cgxd, int lmac_id,
+ u8 *tx_pause, u8 *rx_pause)
{
struct cgx *cgx = cgxd;
u64 cfg;
- if (is_dev_rpm(cgx))
- return 0;
+ cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_HG2_CONTROL);
+
+ *rx_pause = !!(cfg & CGXX_SMUX_HG2_CONTROL_RX_ENABLE);
+ *tx_pause = !!(cfg & CGXX_SMUX_HG2_CONTROL_TX_ENABLE);
+ return 0;
+}
+
+int cgx_lmac_get_pause_frm_status(void *cgxd, int lmac_id,
+ u8 *tx_pause, u8 *rx_pause)
+{
+ struct cgx *cgx = cgxd;
+ u64 cfg;
if (!is_lmac_valid(cgx, lmac_id))
return -ENODEV;
+ if (is_higig2_enabled(cgxd, lmac_id))
+ return cgx_lmac_get_higig2_pause_frm_status(cgxd, lmac_id,
+ tx_pause, rx_pause);
+
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
*rx_pause = !!(cfg & CGX_SMUX_RX_FRM_CTL_CTL_BCK);
@@ -480,17 +494,51 @@ static int cgx_lmac_get_pause_frm_status(void *cgxd, int lmac_id,
return 0;
}
-static int cgx_lmac_enadis_pause_frm(void *cgxd, int lmac_id,
- u8 tx_pause, u8 rx_pause)
+static int cgx_lmac_enadis_higig2_pause_frm(void *cgxd, int lmac_id,
+ u8 tx_pause, u8 rx_pause)
{
struct cgx *cgx = cgxd;
u64 cfg;
- if (is_dev_rpm(cgx))
- return 0;
+ cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_HG2_CONTROL);
+ cfg &= ~CGXX_SMUX_HG2_CONTROL_RX_ENABLE;
+ cfg |= rx_pause ? CGXX_SMUX_HG2_CONTROL_RX_ENABLE : 0x0;
+ cgx_write(cgx, lmac_id, CGXX_SMUX_HG2_CONTROL, cfg);
- if (!is_lmac_valid(cgx, lmac_id))
- return -ENODEV;
+ /* Forward PAUSE information to TX block */
+ cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
+ cfg &= ~CGX_SMUX_RX_FRM_CTL_CTL_BCK;
+ cfg |= rx_pause ? CGX_SMUX_RX_FRM_CTL_CTL_BCK : 0x0;
+ cgx_write(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL, cfg);
+
+ cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_HG2_CONTROL);
+ cfg &= ~CGXX_SMUX_HG2_CONTROL_TX_ENABLE;
+ cfg |= tx_pause ? CGXX_SMUX_HG2_CONTROL_TX_ENABLE : 0x0;
+ cgx_write(cgx, lmac_id, CGXX_SMUX_HG2_CONTROL, cfg);
+
+ /* allow intra packet hg2 generation */
+ cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_INTERVAL);
+ cfg &= ~CGXX_SMUX_TX_PAUSE_PKT_HG2_INTRA_EN;
+ cfg |= tx_pause ? CGXX_SMUX_TX_PAUSE_PKT_HG2_INTRA_EN : 0x0;
+ cgx_write(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_INTERVAL, cfg);
+
+ cfg = cgx_read(cgx, 0, CGXX_CMR_RX_OVR_BP);
+ if (tx_pause) {
+ cfg &= ~CGX_CMR_RX_OVR_BP_EN(lmac_id);
+ } else {
+ cfg |= CGX_CMR_RX_OVR_BP_EN(lmac_id);
+ cfg &= ~CGX_CMR_RX_OVR_BP_BP(lmac_id);
+ }
+
+ cgx_write(cgx, 0, CGXX_CMR_RX_OVR_BP, cfg);
+ return 0;
+}
+
+static int cgx_lmac_enadis_8023_pause_frm(void *cgxd, int lmac_id,
+ u8 tx_pause, u8 rx_pause)
+{
+ struct cgx *cgx = cgxd;
+ u64 cfg;
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
cfg &= ~CGX_SMUX_RX_FRM_CTL_CTL_BCK;
@@ -513,6 +561,22 @@ static int cgx_lmac_enadis_pause_frm(void *cgxd, int lmac_id,
return 0;
}
+int cgx_lmac_enadis_pause_frm(void *cgxd, int lmac_id,
+ u8 tx_pause, u8 rx_pause)
+{
+ struct cgx *cgx = cgxd;
+
+ if (!is_lmac_valid(cgx, lmac_id))
+ return -ENODEV;
+
+ if (is_higig2_enabled(cgxd, lmac_id))
+ return cgx_lmac_enadis_higig2_pause_frm(cgxd, lmac_id,
+ tx_pause, rx_pause);
+ else
+ return cgx_lmac_enadis_8023_pause_frm(cgxd, lmac_id,
+ tx_pause, rx_pause);
+}
+
static void cgx_lmac_pause_frm_config(void *cgxd, int lmac_id, bool enable)
{
struct cgx *cgx = cgxd;
@@ -520,6 +584,7 @@ static void cgx_lmac_pause_frm_config(void *cgxd, int lmac_id, bool enable)
if (!is_lmac_valid(cgx, lmac_id))
return;
+
if (enable) {
/* Enable receive pause frames */
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
@@ -543,6 +608,12 @@ static void cgx_lmac_pause_frm_config(void *cgxd, int lmac_id, bool enable)
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_INTERVAL,
cfg | (DEFAULT_PAUSE_TIME / 2));
+ cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_INTERVAL);
+ cfg = FIELD_SET(HG2_INTRA_INTERVAL, (DEFAULT_PAUSE_TIME / 2),
+ cfg);
+ cgx_write(cgx, lmac_id, CGXX_SMUX_TX_PAUSE_PKT_INTERVAL,
+ cfg);
+
cgx_write(cgx, lmac_id, CGXX_GMP_GMI_TX_PAUSE_PKT_TIME,
DEFAULT_PAUSE_TIME);
@@ -561,10 +632,18 @@ static void cgx_lmac_pause_frm_config(void *cgxd, int lmac_id, bool enable)
cfg &= ~CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK;
cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg);
+ cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_HG2_CONTROL);
+ cfg &= ~CGXX_SMUX_HG2_CONTROL_RX_ENABLE;
+ cgx_write(cgx, lmac_id, CGXX_SMUX_HG2_CONTROL, cfg);
+
/* Disable pause frames transmission */
cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_CTL);
cfg &= ~CGX_SMUX_TX_CTL_L2P_BP_CONV;
cgx_write(cgx, lmac_id, CGXX_SMUX_TX_CTL, cfg);
+
+ cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_HG2_CONTROL);
+ cfg &= ~CGXX_SMUX_HG2_CONTROL_TX_ENABLE;
+ cgx_write(cgx, lmac_id, CGXX_SMUX_HG2_CONTROL, cfg);
}
}
@@ -1242,6 +1321,37 @@ unsigned long cgx_get_lmac_bmap(void *cgxd)
return cgx->lmac_bmap;
}
+void cgx_lmac_enadis_higig2(void *cgxd, int lmac_id, bool enable)
+{
+ struct cgx *cgx = cgxd;
+ u64 req = 0, resp;
+
+ /* disable 802.3 pause frames before enabling higig2 */
+ if (enable) {
+ cgx_lmac_enadis_8023_pause_frm(cgxd, lmac_id, false, false);
+ cgx_lmac_enadis_higig2_pause_frm(cgxd, lmac_id, true, true);
+ }
+
+ req = FIELD_SET(CMDREG_ID, CGX_CMD_HIGIG, req);
+ req = FIELD_SET(CMDREG_ENABLE, enable, req);
+ cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id);
+
+ /* enable 802.3 pause frames as higig2 disabled */
+ if (!enable) {
+ cgx_lmac_enadis_higig2_pause_frm(cgxd, lmac_id, false, false);
+ cgx_lmac_enadis_8023_pause_frm(cgxd, lmac_id, true, true);
+ }
+}
+
+bool is_higig2_enabled(void *cgxd, int lmac_id)
+{
+ struct cgx *cgx = cgxd;
+ u64 cfg;
+
+ cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_TX_CTL);
+ return (cfg & CGXX_SMUX_TX_CTL_HIGIG_EN);
+}
+
static int cgx_lmac_init(struct cgx *cgx)
{
struct lmac *lmac;
@@ -1328,9 +1438,11 @@ static int cgx_lmac_exit(struct cgx *cgx)
static void cgx_populate_features(struct cgx *cgx)
{
if (is_dev_rpm(cgx))
- cgx->hw_features = (RVU_MAC_RPM | RVU_LMAC_FEAT_FC);
+ cgx->hw_features = (RVU_LMAC_FEAT_DMACF | RVU_MAC_RPM |
+ RVU_LMAC_FEAT_FC);
else
- cgx->hw_features = (RVU_LMAC_FEAT_FC | RVU_LMAC_FEAT_PTP);
+ cgx->hw_features = (RVU_LMAC_FEAT_FC | RVU_LMAC_FEAT_HIGIG2 |
+ RVU_LMAC_FEAT_PTP | RVU_LMAC_FEAT_DMACF);
}
static struct mac_ops cgx_mac_ops = {
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
index 237a91b801e..1547e66fb24 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
@@ -74,14 +74,20 @@
#define CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK BIT_ULL(3)
#define CGX_GMP_GMI_RXX_FRM_CTL_PTP_MODE BIT_ULL(12)
#define CGXX_SMUX_TX_CTL 0x20178
+#define CGXX_SMUX_TX_CTL_HIGIG_EN BIT_ULL(8)
#define CGXX_SMUX_TX_PAUSE_PKT_TIME 0x20110
#define CGXX_SMUX_TX_PAUSE_PKT_INTERVAL 0x20120
+#define CGXX_SMUX_TX_PAUSE_PKT_HG2_INTRA_EN BIT_ULL(32)
+#define HG2_INTRA_INTERVAL GENMASK_ULL(31, 16)
#define CGXX_GMP_GMI_TX_PAUSE_PKT_TIME 0x38230
#define CGXX_GMP_GMI_TX_PAUSE_PKT_INTERVAL 0x38248
#define CGX_SMUX_TX_CTL_L2P_BP_CONV BIT_ULL(7)
#define CGXX_CMR_RX_OVR_BP 0x130
#define CGX_CMR_RX_OVR_BP_EN(X) BIT_ULL(((X) + 8))
#define CGX_CMR_RX_OVR_BP_BP(X) BIT_ULL(((X) + 4))
+#define CGXX_SMUX_HG2_CONTROL 0x20210
+#define CGXX_SMUX_HG2_CONTROL_TX_ENABLE BIT_ULL(18)
+#define CGXX_SMUX_HG2_CONTROL_RX_ENABLE BIT_ULL(17)
#define CGX_COMMAND_REG CGXX_SCRATCH1_REG
#define CGX_EVENT_REG CGXX_SCRATCH0_REG
@@ -147,10 +153,10 @@ int cgx_get_link_info(void *cgxd, int lmac_id,
struct cgx_link_user_info *linfo);
int cgx_lmac_linkup_start(void *cgxd);
int cgx_get_fwdata_base(u64 *base);
-int cgx_lmac_get_pause_frm(void *cgxd, int lmac_id,
- u8 *tx_pause, u8 *rx_pause);
-int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id,
- u8 tx_pause, u8 rx_pause);
+int cgx_lmac_get_pause_frm_status(void *cgxd, int lmac_id,
+ u8 *tx_pause, u8 *rx_pause);
+int cgx_lmac_enadis_pause_frm(void *cgxd, int lmac_id,
+ u8 tx_pause, u8 rx_pause);
void cgx_lmac_ptp_config(void *cgxd, int lmac_id, bool enable);
u8 cgx_lmac_get_p2x(int cgx_id, int lmac_id);
int cgx_set_fec(u64 fec, int cgx_id, int lmac_id);
@@ -168,4 +174,6 @@ u64 cgx_lmac_read(int cgx_id, int lmac_id, u64 offset);
int cgx_set_phy_mod_type(int mod, void *cgxd, int lmac_id);
int cgx_get_phy_mod_type(void *cgxd, int lmac_id);
int cgx_get_pkind(void *cgxd, u8 lmac_id, int *pkind);
+void cgx_lmac_enadis_higig2(void *cgxd, int lmac_id, bool enable);
+bool is_higig2_enabled(void *cgxd, int lmac_id);
#endif /* CGX_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index 1ce22782260..a1f71ee9e98 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -509,10 +509,13 @@ struct cgx_set_link_mode_rsp {
};
#define RVU_LMAC_FEAT_FC BIT_ULL(0) /* pause frames */
-#define RVU_LMAC_FEAT_PTP BIT_ULL(1) /* precison time protocol */
-#define RVU_MAC_VERSION BIT_ULL(2)
-#define RVU_MAC_CGX BIT_ULL(3)
-#define RVU_MAC_RPM BIT_ULL(4)
+#define RVU_LMAC_FEAT_HIGIG2 BIT_ULL(1)
+ /* flow control from physical link higig2 messages */
+#define RVU_LMAC_FEAT_PTP BIT_ULL(2) /* precison time protocol */
+#define RVU_LMAC_FEAT_DMACF BIT_ULL(3) /* DMAC FILTER */
+#define RVU_MAC_VERSION BIT_ULL(4)
+#define RVU_MAC_CGX BIT_ULL(5)
+#define RVU_MAC_RPM BIT_ULL(6)
struct cgx_features_info_msg {
struct mbox_msghdr hdr;
@@ -631,6 +634,7 @@ enum nix_af_status {
NIX_AF_ERR_TX_VTAG_NOSPC = -421,
NIX_AF_ERR_RX_VTAG_INUSE = -422,
NIX_AF_ERR_NPC_KEY_NOT_SUPP = -423,
+ NIX_AF_ERR_PTP_CONFIG_FAIL = -424,
};
/* For NIX RX vtag action */
@@ -1003,6 +1007,8 @@ enum npc_af_status {
NPC_MCAM_ALLOC_DENIED = -702,
NPC_MCAM_ALLOC_FAILED = -703,
NPC_MCAM_PERM_DENIED = -704,
+ NPC_AF_ERR_HIGIG_CONFIG_FAIL = -705,
+ NPC_AF_ERR_HIGIG_NOT_SUPPORTED = -706,
};
struct npc_mcam_alloc_entry_req {
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index 292351bad5b..ae51937ee46 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -618,6 +618,8 @@ int rvu_cgx_nix_cuml_stats(struct rvu *rvu, void *cgxd, int lmac_id, int index,
int rxtxflag, u64 *stat);
bool is_cgx_config_permitted(struct rvu *rvu, u16 pcifunc);
bool rvu_cgx_is_pkind_config_permitted(struct rvu *rvu, u16 pcifunc);
+void rvu_cgx_enadis_higig2(struct rvu *rvu, int pf, bool enable);
+bool rvu_cgx_is_higig2_enabled(struct rvu *rvu, int pf);
/* NPA APIs */
int rvu_npa_init(struct rvu *rvu);
@@ -639,6 +641,7 @@ int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add);
struct nix_hw *get_nix_hw(struct rvu_hwinfo *hw, int blkaddr);
int rvu_get_next_nix_blkaddr(struct rvu *rvu, int blkaddr);
void rvu_nix_reset_mac(struct rvu_pfvf *pfvf, int pcifunc);
+u64 rvu_nix_is_ptp_tx_enabled(struct rvu *rvu, u16 pcifunc);
/* NPC APIs */
int rvu_npc_init(struct rvu *rvu);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
index 9c30692070b..2f35b5f8268 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
@@ -424,6 +424,36 @@ void rvu_cgx_enadis_rx_bp(struct rvu *rvu, int pf, bool enable)
mac_ops->mac_enadis_rx_pause_fwding(cgxd, lmac_id, false);
}
+void rvu_cgx_enadis_higig2(struct rvu *rvu, int pf, bool enable)
+{
+ u8 cgx_id, lmac_id;
+ void *cgxd;
+
+ if (!is_pf_cgxmapped(rvu, pf))
+ return;
+
+ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+ cgxd = rvu_cgx_pdata(cgx_id, rvu);
+ cgx_lmac_enadis_higig2(cgxd, lmac_id, enable);
+}
+
+bool rvu_cgx_is_higig2_enabled(struct rvu *rvu, int pf)
+{
+ u8 cgx_id, lmac_id;
+ void *cgxd;
+
+ if (is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_HIGIG2) == false)
+ return 0;
+
+ if (!is_pf_cgxmapped(rvu, pf))
+ return false;
+
+ rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_id, &lmac_id);
+ cgxd = rvu_cgx_pdata(cgx_id, rvu);
+
+ return is_higig2_enabled(cgxd, lmac_id);
+}
+
int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start)
{
int pf = rvu_get_pf(pcifunc);
@@ -604,6 +634,10 @@ static int rvu_cgx_ptp_rx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
if (!is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_PTP))
return 0;
+ /* Silicon does not support enabling time stamp in higig mode */
+ if (enable && rvu_cgx_is_higig2_enabled(rvu, pf))
+ return NIX_AF_ERR_PTP_CONFIG_FAIL;
+
/* This msg is expected only from PFs that are mapped to CGX LMACs,
* if received from other PF/VF simply ACK, nothing to do.
*/
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index ed96ebc4022..56ade799011 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -3707,6 +3707,10 @@ static int rvu_nix_lf_ptp_tx_cfg(struct rvu *rvu, u16 pcifunc, bool enable)
if (!is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_PTP))
return 0;
+ /* Silicon does not support enabling time stamp in higig mode */
+ if (rvu_cgx_is_higig2_enabled(rvu, rvu_get_pf(pcifunc)))
+ return NIX_AF_ERR_PTP_CONFIG_FAIL;
+
blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
if (blkaddr < 0)
return NIX_AF_ERR_AF_LF_INVALID;
@@ -3799,3 +3803,16 @@ void rvu_nix_reset_mac(struct rvu_pfvf *pfvf, int pcifunc)
if (from_vf)
ether_addr_copy(pfvf->mac_addr, pfvf->default_mac);
}
+
+u64 rvu_nix_is_ptp_tx_enabled(struct rvu *rvu, u16 pcifunc)
+{
+ int blkaddr, nixlf, err;
+ u64 cfg;
+
+ err = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr);
+ if (err)
+ return false;
+
+ cfg = rvu_read64(rvu, blkaddr, NIX_AF_LFX_TX_CFG(nixlf));
+ return (cfg & BIT_ULL(32));
+}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
index 802668e1f90..dba57a6b439 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -2850,6 +2850,7 @@ int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
u64 pkind)
{
int pf = rvu_get_pf(pcifunc);
+ bool enable_higig2 = false;
int blkaddr, nixlf, rc;
u64 rxpkind, txpkind;
u8 cgx_id, lmac_id;
@@ -2861,8 +2862,17 @@ int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
if (mode & OTX2_PRIV_FLAGS_EDSA) {
rxpkind = NPC_RX_EDSA_PKIND;
} else if (mode & OTX2_PRIV_FLAGS_HIGIG) {
+ /* Silicon does not support enabling higig in time stamp mode */
+ if (rvu_nix_is_ptp_tx_enabled(rvu, pcifunc))
+ return NPC_AF_ERR_HIGIG_CONFIG_FAIL;
+
+ if (is_mac_feature_supported(rvu, pf, RVU_LMAC_FEAT_HIGIG2) ==
+ false)
+ return NPC_AF_ERR_HIGIG_NOT_SUPPORTED;
+
rxpkind = NPC_RX_HIGIG_PKIND;
txpkind = NPC_TX_HIGIG_PKIND;
+ enable_higig2 = true;
} else if (mode & OTX2_PRIV_FLAGS_CUSTOM) {
rxpkind = pkind;
txpkind = pkind;
@@ -2889,6 +2899,10 @@ int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir,
rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf),
txpkind);
}
+
+ if (enable_higig2 ^ rvu_cgx_is_higig2_enabled(rvu, pf))
+ rvu_cgx_enadis_higig2(rvu, pf, enable_higig2);
+
return 0;
}
--
2.17.1
Marvell switches support FDSA (Forward DSA). FDSA has
4 bytes length and it contains Src port and vlan field.
KPU profile is updated to parse FDSA packet and extract Src port.
The extracted Src port is placed in vlan field of KEX key.
This patch adds ntuple filter support to FDSA tag.
So that user can send traffic to either PF or VF based on
Src port or Vlan id. All rules installed for FDSA has default
action as RSS. Upon enabling FDSA , vf vlan rules will be disabled.
To enable fdsa tag
ethtool --set-priv-flags eth0 fdsa on
To send traffic with Srcport 30 to PF
ethtool -U eth0 flow-type ether user-def 0x1e
To send traffic with vlan id 30 to PF
ethtool -U eth0 flow-type ether dst xx vlan 30 m 0xf000
To send traffic with Srcport 20 to vf 0
ethtool -U eth0 flow-type ether vf 0 user-def 0x14
Signed-off-by: Hariprasad Kelam <[email protected]>
Signed-off-by: Sunil Goutham <[email protected]>
---
.../marvell/octeontx2/nic/otx2_common.h | 16 ++++-
.../marvell/octeontx2/nic/otx2_ethtool.c | 49 +++++++++++++++-
.../marvell/octeontx2/nic/otx2_flows.c | 58 ++++++++++++++++---
.../ethernet/marvell/octeontx2/nic/otx2_pf.c | 13 ++++-
4 files changed, 121 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
index 73e927a7843..3aa61125f84 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
@@ -223,6 +223,12 @@ struct otx2_hw {
u64 *nix_lmt_base;
};
+struct vfvlan {
+ u16 vlan;
+ __be16 proto;
+ u8 qos;
+};
+
struct otx2_vf_config {
struct otx2_nic *pf;
struct delayed_work link_event_work;
@@ -230,6 +236,7 @@ struct otx2_vf_config {
u8 mac[ETH_ALEN];
u16 vlan;
int tx_vtag_idx;
+ struct vfvlan rule;
};
struct flr_work {
@@ -350,7 +357,9 @@ struct otx2_nic {
#define OTX2_PRIV_FLAG_PAM4 BIT(0)
#define OTX2_PRIV_FLAG_EDSA_HDR BIT(1)
#define OTX2_PRIV_FLAG_HIGIG2_HDR BIT(2)
-#define OTX2_PRIV_FLAG_DEF_MODE BIT(3)
+#define OTX2_PRIV_FLAG_FDSA_HDR BIT(3)
+#define OTX2_INTF_MOD_MASK GENMASK(3, 1)
+#define OTX2_PRIV_FLAG_DEF_MODE BIT(4)
#define OTX2_IS_EDSA_ENABLED(flags) ((flags) & \
OTX2_PRIV_FLAG_EDSA_HDR)
#define OTX2_IS_HIGIG2_ENABLED(flags) ((flags) & \
@@ -364,6 +373,7 @@ struct otx2_nic {
*/
#define OTX2_EDSA_HDR_LEN 16
#define OTX2_HIGIG2_HDR_LEN 16
+#define OTX2_FDSA_HDR_LEN 4
u32 addl_mtu;
struct otx2_mac_table *mac_table;
@@ -831,14 +841,14 @@ int otx2_get_all_flows(struct otx2_nic *pfvf,
int otx2_add_flow(struct otx2_nic *pfvf,
struct ethtool_rxnfc *nfc);
int otx2_remove_flow(struct otx2_nic *pfvf, u32 location);
-int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
- struct npc_install_flow_req *req);
void otx2_rss_ctx_flow_del(struct otx2_nic *pfvf, int ctx_id);
int otx2_del_macfilter(struct net_device *netdev, const u8 *mac);
int otx2_add_macfilter(struct net_device *netdev, const u8 *mac);
int otx2_enable_rxvlan(struct otx2_nic *pf, bool enable);
int otx2_install_rxvlan_offload_flow(struct otx2_nic *pfvf);
u16 otx2_get_max_mtu(struct otx2_nic *pfvf);
+int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos,
+ __be16 proto);
/* tc support */
int otx2_init_tc(struct otx2_nic *nic);
void otx2_shutdown_tc(struct otx2_nic *nic);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
index c1405611489..523bb089b9e 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
@@ -26,6 +26,7 @@ static const char otx2_priv_flags_strings[][ETH_GSTRING_LEN] = {
"pam4",
"edsa",
"higig2",
+ "fdsa",
};
struct otx2_stat {
@@ -1286,6 +1287,9 @@ int otx2_set_npc_parse_mode(struct otx2_nic *pfvf, bool unbind)
} else if (OTX2_IS_EDSA_ENABLED(pfvf->ethtool_flags)) {
req->mode = OTX2_PRIV_FLAGS_EDSA;
interface_mode = OTX2_PRIV_FLAG_EDSA_HDR;
+ } else if (pfvf->ethtool_flags & OTX2_PRIV_FLAG_FDSA_HDR) {
+ req->mode = OTX2_PRIV_FLAGS_FDSA;
+ interface_mode = OTX2_PRIV_FLAG_FDSA_HDR;
} else {
req->mode = OTX2_PRIV_FLAGS_DEFAULT;
interface_mode = OTX2_PRIV_FLAG_DEF_MODE;
@@ -1364,6 +1368,28 @@ static int otx2_enable_addl_header(struct net_device *netdev, int bitpos,
return 0;
}
+/* This function disables vfvlan rules upon enabling
+ * fdsa and vice versa
+ */
+static void otx2_endis_vfvlan_rules(struct otx2_nic *pfvf, bool enable)
+{
+ struct vfvlan *rule;
+ int vf;
+
+ for (vf = 0; vf < pci_num_vf(pfvf->pdev); vf++) {
+ /* pass vlan as 0 to disable rule */
+ if (enable) {
+ otx2_do_set_vf_vlan(pfvf, vf, 0, 0, 0);
+ } else {
+ rule = &pfvf->vf_configs[vf].rule;
+ otx2_do_set_vf_vlan(pfvf, vf, rule->vlan, rule->qos,
+ rule->proto);
+ }
+ }
+}
+
+#define OTX2_IS_INTFMOD_SET(flags) hweight32((flags) & OTX2_INTF_MOD_MASK)
+
static int otx2_set_priv_flags(struct net_device *netdev, u32 new_flags)
{
struct otx2_nic *pfvf = netdev_priv(netdev);
@@ -1392,15 +1418,34 @@ static int otx2_set_priv_flags(struct net_device *netdev, u32 new_flags)
break;
case OTX2_PRIV_FLAG_EDSA_HDR:
/* HIGIG & EDSA are mutual exclusive */
- if (enable && OTX2_IS_HIGIG2_ENABLED(pfvf->ethtool_flags))
+ if (enable && OTX2_IS_INTFMOD_SET(pfvf->ethtool_flags)) {
+ netdev_info(netdev,
+ "Disable mutually exclusive modes higig2/fdsa\n");
return -EINVAL;
+ }
return otx2_enable_addl_header(netdev, bitnr,
OTX2_EDSA_HDR_LEN, enable);
case OTX2_PRIV_FLAG_HIGIG2_HDR:
- if (enable && OTX2_IS_EDSA_ENABLED(pfvf->ethtool_flags))
+ if (enable && OTX2_IS_INTFMOD_SET(pfvf->ethtool_flags)) {
+ netdev_info(netdev,
+ "Disable mutually exclusive modes edsa/fdsa\n");
return -EINVAL;
+ }
return otx2_enable_addl_header(netdev, bitnr,
OTX2_HIGIG2_HDR_LEN, enable);
+ case OTX2_PRIV_FLAG_FDSA_HDR:
+ if (enable && OTX2_IS_INTFMOD_SET(pfvf->ethtool_flags)) {
+ netdev_info(netdev,
+ "Disable mutually exclusive modes edsa/higig2\n");
+ return -EINVAL;
+ }
+ otx2_enable_addl_header(netdev, bitnr,
+ OTX2_FDSA_HDR_LEN, enable);
+ if (enable)
+ netdev_warn(netdev,
+ "Disabling VF VLAN rules as FDSA & VFVLAN are mutual exclusive\n");
+ otx2_endis_vfvlan_rules(pfvf, enable);
+ break;
default:
break;
}
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
index fa7a46aa15e..4e22798ea6c 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
@@ -9,6 +9,8 @@
#include "otx2_common.h"
#define OTX2_DEFAULT_ACTION 0x1
+#define FDSA_MAX_SPORT 32
+#define FDSA_SPORT_MASK 0xf8
struct otx2_flow {
struct ethtool_rx_flow_spec flow_spec;
@@ -556,8 +558,18 @@ static int otx2_prepare_ipv6_flow(struct ethtool_rx_flow_spec *fsp,
return 0;
}
-int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
- struct npc_install_flow_req *req)
+static void otx2_prepare_fdsa_flow_request(struct npc_install_flow_req *req)
+{
+ /* Strip FDSA tag */
+ req->features |= BIT_ULL(NPC_FDSA_VAL);
+ req->vtag0_valid = true;
+ req->vtag0_type = NIX_AF_LFX_RX_VTAG_TYPE6;
+ req->op = NIX_RX_ACTION_DEFAULT;
+}
+
+static int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
+ struct npc_install_flow_req *req,
+ struct otx2_nic *pfvf)
{
struct ethhdr *eth_mask = &fsp->m_u.ether_spec;
struct ethhdr *eth_hdr = &fsp->h_u.ether_spec;
@@ -612,6 +624,9 @@ int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
return -EOPNOTSUPP;
}
if (fsp->flow_type & FLOW_EXT) {
+ int skip_user_def = false;
+ u16 fdsa_sport = 0;
+
if (fsp->m_ext.vlan_etype)
return -EINVAL;
if (fsp->m_ext.vlan_tci) {
@@ -624,13 +639,36 @@ int otx2_prepare_flow_request(struct ethtool_rx_flow_spec *fsp,
sizeof(pkt->vlan_tci));
memcpy(&pmask->vlan_tci, &fsp->m_ext.vlan_tci,
sizeof(pmask->vlan_tci));
- req->features |= BIT_ULL(NPC_OUTER_VID);
+ if (pfvf->ethtool_flags & OTX2_PRIV_FLAG_FDSA_HDR) {
+ otx2_prepare_fdsa_flow_request(req);
+ skip_user_def = true;
+ } else {
+ req->features |= BIT_ULL(NPC_OUTER_VID);
+ }
+ }
+
+ if (fsp->m_ext.data[1] && !skip_user_def) {
+ if (pfvf->ethtool_flags & OTX2_PRIV_FLAG_FDSA_HDR) {
+ if (be32_to_cpu(fsp->h_ext.data[1]) >=
+ FDSA_MAX_SPORT)
+ return -EINVAL;
+ /* FDSA source port is 5 bit value ..starts
+ * from b3..b7. Derive source port value
+ * from h_ext.data.
+ */
+ fdsa_sport = be32_to_cpu(fsp->h_ext.data[1]);
+ pkt->vlan_tci = cpu_to_be16(fdsa_sport << 3);
+ pmask->vlan_tci = cpu_to_be16(FDSA_SPORT_MASK);
+ otx2_prepare_fdsa_flow_request(req);
+ } else if (fsp->h_ext.data[1] ==
+ cpu_to_be32(OTX2_DEFAULT_ACTION)) {
+ /* Not Drop/Direct to queue but use action
+ * in default entry
+ */
+ req->op = NIX_RX_ACTION_DEFAULT;
+ }
}
- /* Not Drop/Direct to queue but use action in default entry */
- if (fsp->m_ext.data[1] &&
- fsp->h_ext.data[1] == cpu_to_be32(OTX2_DEFAULT_ACTION))
- req->op = NIX_RX_ACTION_DEFAULT;
}
if (fsp->flow_type & FLOW_MAC_EXT &&
@@ -659,7 +697,7 @@ static int otx2_add_flow_msg(struct otx2_nic *pfvf, struct otx2_flow *flow)
return -ENOMEM;
}
- err = otx2_prepare_flow_request(&flow->flow_spec, req);
+ err = otx2_prepare_flow_request(&flow->flow_spec, req, pfvf);
if (err) {
/* free the allocated msg above */
otx2_mbox_reset(&pfvf->mbox.mbox, 0);
@@ -949,6 +987,10 @@ int otx2_enable_rxvlan(struct otx2_nic *pf, bool enable)
if (!(pf->flags & OTX2_FLAG_RX_VLAN_SUPPORT))
return -ENOMEM;
+ /* FDSA & RXVLAN are mutually exclusive */
+ if (pf->ethtool_flags & OTX2_PRIV_FLAG_FDSA_HDR)
+ enable = false;
+
if (enable) {
err = otx2_install_rxvlan_offload_flow(pf);
if (err)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
index 977da158f1d..a967710a801 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
@@ -2058,8 +2058,8 @@ static int otx2_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
return ret;
}
-static int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos,
- __be16 proto)
+int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos,
+ __be16 proto)
{
struct otx2_flow_config *flow_cfg = pf->flow_cfg;
struct nix_vtag_config_rsp *vtag_rsp;
@@ -2118,6 +2118,8 @@ static int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos,
flow_cfg->entry[flow_cfg->vf_vlan_offset + idx];
err = otx2_sync_mbox_msg(&pf->mbox);
+ if (!(pf->ethtool_flags & OTX2_PRIV_FLAG_FDSA_HDR))
+ memset(&config->rule, 0, sizeof(config->rule));
goto out;
}
@@ -2191,6 +2193,10 @@ static int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos,
req->set_cntr = 1;
err = otx2_sync_mbox_msg(&pf->mbox);
+ /* Update these values to reinstall the vfvlan rule */
+ config->rule.vlan = vlan;
+ config->rule.proto = proto;
+ config->rule.qos = qos;
out:
config->vlan = vlan;
mutex_unlock(&pf->mbox.lock);
@@ -2219,6 +2225,9 @@ static int otx2_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos,
if (!(pf->flags & OTX2_FLAG_VF_VLAN_SUPPORT))
return -EOPNOTSUPP;
+ if (pf->ethtool_flags & OTX2_PRIV_FLAG_FDSA_HDR)
+ return -EOPNOTSUPP;
+
return otx2_do_set_vf_vlan(pf, vf, vlan, qos, proto);
}
--
2.17.1
On Sun, Mar 21, 2021 at 05:39:50PM +0530, Hariprasad Kelam wrote:
> This series of patches add support for parsing switch headers and
> configuration support for phy modulation type(NRZ or PAM4).
>
> PHYs that support changing modulation type ,user can configure it
> through private flags pam4.
>
> Marvell switches support DSA(distributed switch architecture) with
> different switch headers like FDSA and EDSA. This patch series adds
> private flags to enable user to configure interface in fdsa/edsa
> mode such that flow steering (forwading packets to pf/vf depending on
> switch header fields) and packet parsing can be acheived.
Hi Hariprasad
Private flags sound very wrong here. I would expect to see some
integration between the switchdev/DSA driver and the MAC driver.
Please show how this works in combination with
drivers/net/dsa/mv88e6xxx or drivers/net/ethernet/marvell/prestera.
Andrew
On Sun, Mar 21, 2021 at 05:39:52PM +0530, Hariprasad Kelam wrote:
> From: Felix Manlunas <[email protected]>
>
> For PHYs that support changing modulation type (NRZ or PAM4), enable these
> commands:
>
> ethtool --set-priv-flags ethX pam4 on
> ethtool --set-priv-flags ethX pam4 off # means NRZ modulation
> ethtool --show-priv-flags ethX
Why is this not derived from the link mode? How do other Vendors
support this in their high speed MAC/PHY combinations.
Please stop using priv flags like this. This is not a Marvell specific
problem. Any high speed MAC/PHY combination is going to need some way
to configure this. So please think about the best generic solution.
This combined with your DSA changes give me a bad feeling. It seems
like you are just trying to dump your SDK features into the kernel,
without properly integrating the features in a vendor neutral way.
Andrew
Hi Andrew ,
Please see inline,
> -----Original Message-----
> From: Andrew Lunn <[email protected]>
> Sent: Sunday, March 21, 2021 7:45 PM
> To: Hariprasad Kelam <[email protected]>
> Cc: [email protected]; [email protected]; [email protected];
> [email protected]; Sunil Kovvuri Goutham <[email protected]>;
> Linu Cherian <[email protected]>; Geethasowjanya Akula
> <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>;
> Subbaraya Sundeep Bhatta <[email protected]>
> Subject: [EXT] Re: [net-next PATCH 0/8] configuration support for switch
> headers & phy
>
> On Sun, Mar 21, 2021 at 05:39:50PM +0530, Hariprasad Kelam wrote:
> > This series of patches add support for parsing switch headers and
> > configuration support for phy modulation type(NRZ or PAM4).
> >
> > PHYs that support changing modulation type ,user can configure it
> > through private flags pam4.
> >
> > Marvell switches support DSA(distributed switch architecture) with
> > different switch headers like FDSA and EDSA. This patch series adds
> > private flags to enable user to configure interface in fdsa/edsa mode
> > such that flow steering (forwading packets to pf/vf depending on
> > switch header fields) and packet parsing can be acheived.
>
> Hi Hariprasad
>
> Private flags sound very wrong here. I would expect to see some integration
> between the switchdev/DSA driver and the MAC driver.
> Please show how this works in combination with drivers/net/dsa/mv88e6xxx
> or drivers/net/ethernet/marvell/prestera.
>
Octeontx2 silicon supports NPC (network parser and cam) unit , through which packet parsing and packet classification is achieved.
Packet parsing extracting different fields from each layer.
DMAC + SMAC --> LA
VLAN ID --> LB
SIP + DIP --> LC
TCP SPORT + DPORT --> LD
And packet classification is achieved through flow identification in key extraction and mcam search key . User can install mcam rules
With action as
forward packet to PF and to receive queue 0
forward packet to VF and with as RSS ( Receive side scaling)
drop the packet
etc..
Now with switch header ( EDSA /FDSA) and HIGIG2 appended to regular packet , NPC can not parse these
Ingress packets as these headers does not have fixed headers. To achieve this Special PKIND( port kind) is allocated in hardware
which will help NPC to parse the packets.
For example incase of EDSA 8 byte header which is placed right after SMAC , special PKIND reserved for EDSA helps NPC to
Identify the input packet is EDSA . Such that NPC can extract fields in this header and forward to
Parse rest of the headers.
Same is the case with higig2 header where 16 bytes header is placed at start of the packet.
In this case private flags helps user to configure interface in EDSA/FDSA or HIGIG2. Such that special
PKIND reserved for that header are assigned to the interface. The scope of the patch series is how
User can configure interface mode as switch header(HIGIG2/EDSA etc) .In our case no DSA logical
Ports are created as these headers can be stripped by NPC.
Thanks,
Hariprasad k
> Andrew
On Tue, Mar 23, 2021 at 06:13:28PM +0000, Hariprasad Kelam wrote:
>
> Hi Andrew ,
>
> Please see inline,
No need to say that. That is the correct way to right emails.
> > Hi Hariprasad
> >
> > Private flags sound very wrong here. I would expect to see some integration
> > between the switchdev/DSA driver and the MAC driver.
> > Please show how this works in combination with drivers/net/dsa/mv88e6xxx
> > or drivers/net/ethernet/marvell/prestera.
> >
> Octeontx2 silicon supports NPC (network parser and cam) unit , through which packet parsing and packet classification is achieved.
> Packet parsing extracting different fields from each layer.
> DMAC + SMAC --> LA
> VLAN ID --> LB
> SIP + DIP --> LC
> TCP SPORT + DPORT --> LD
> And packet classification is achieved through flow identification in key extraction and mcam search key . User can install mcam rules
> With action as
> forward packet to PF and to receive queue 0
> forward packet to VF and with as RSS ( Receive side scaling)
> drop the packet
> etc..
>
> Now with switch header ( EDSA /FDSA) and HIGIG2 appended to regular packet , NPC can not parse these
> Ingress packets as these headers does not have fixed headers. To achieve this Special PKIND( port kind) is allocated in hardware
> which will help NPC to parse the packets.
>
> For example incase of EDSA 8 byte header which is placed right after SMAC , special PKIND reserved for EDSA helps NPC to
> Identify the input packet is EDSA . Such that NPC can extract fields in this header and forward to
> Parse rest of the headers.
>
> Same is the case with higig2 header where 16 bytes header is placed at start of the packet.
>
> In this case private flags helps user to configure interface in EDSA/FDSA or HIGIG2. Such that special
> PKIND reserved for that header are assigned to the interface. The scope of the patch series is how
> User can configure interface mode as switch header(HIGIG2/EDSA etc) .In our case no DSA logical
> Ports are created as these headers can be stripped by NPC.
So you completely skipped how this works with mv88e6xxx or
prestera. If you need this private flag for some out of mainline
Marvell SDK, it is very unlikely to be accepted.
Andrew
Hi Andrew,
Please see inline,
> -----Original Message-----
> From: Andrew Lunn <[email protected]>
> Sent: Sunday, March 21, 2021 7:58 PM
> To: Hariprasad Kelam <[email protected]>
> Cc: [email protected]; [email protected]; [email protected];
> [email protected]; Sunil Kovvuri Goutham <[email protected]>;
> Linu Cherian <[email protected]>; Geethasowjanya Akula
> <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>;
> Subbaraya Sundeep Bhatta <[email protected]>
> Subject: Re: [net-next PATCH 2/8] octeontx2-pf: Add ethtool priv flag to
> control PAM4 on/off
>
> On Sun, Mar 21, 2021 at 05:39:52PM +0530, Hariprasad Kelam wrote:
> > From: Felix Manlunas <[email protected]>
> >
> > For PHYs that support changing modulation type (NRZ or PAM4), enable
> > these
> > commands:
> >
> > ethtool --set-priv-flags ethX pam4 on
> > ethtool --set-priv-flags ethX pam4 off # means NRZ modulation
> > ethtool --show-priv-flags ethX
>
> Why is this not derived from the link mode? How do other Vendors support
> this in their high speed MAC/PHY combinations.
>
> Please stop using priv flags like this. This is not a Marvell specific problem.
> Any high speed MAC/PHY combination is going to need some way to
> configure this. So please think about the best generic solution.
>
> This combined with your DSA changes give me a bad feeling. It seems like you
> are just trying to dump your SDK features into the kernel, without properly
> integrating the features in a vendor neutral way.
>
Thanks for your suggestion . Will try to evaluate this can be achieved through link mode or any generic solution.
Will try to submit his feature as a separate patch.
Thanks,
Hariprasad k
> Andrew
> > > Hi Hariprasad
> > >
> > > Private flags sound very wrong here. I would expect to see some integration
> > > between the switchdev/DSA driver and the MAC driver.
> > > Please show how this works in combination with drivers/net/dsa/mv88e6xxx
> > > or drivers/net/ethernet/marvell/prestera.
> > >
> > Octeontx2 silicon supports NPC (network parser and cam) unit , through which packet parsing and packet classification is achieved.
> > Packet parsing extracting different fields from each layer.
> > DMAC + SMAC --> LA
> > VLAN ID --> LB
> > SIP + DIP --> LC
> > TCP SPORT + DPORT --> LD
> > And packet classification is achieved through flow identification in key extraction and mcam search key . User can install mcam rules
> > With action as
> > forward packet to PF and to receive queue 0
> > forward packet to VF and with as RSS ( Receive side scaling)
> > drop the packet
> > etc..
> >
> > Now with switch header ( EDSA /FDSA) and HIGIG2 appended to regular packet , NPC can not parse these
> > Ingress packets as these headers does not have fixed headers. To achieve this Special PKIND( port kind) is allocated in hardware
> > which will help NPC to parse the packets.
> >
> > For example incase of EDSA 8 byte header which is placed right after SMAC , special PKIND reserved for EDSA helps NPC to
> > Identify the input packet is EDSA . Such that NPC can extract fields in this header and forward to
> > Parse rest of the headers.
> >
> > Same is the case with higig2 header where 16 bytes header is placed at start of the packet.
> >
> > In this case private flags helps user to configure interface in EDSA/FDSA or HIGIG2. Such that special
> > PKIND reserved for that header are assigned to the interface. The scope of the patch series is how
> > User can configure interface mode as switch header(HIGIG2/EDSA etc) .In our case no DSA logical
> > Ports are created as these headers can be stripped by NPC.
>
> So you completely skipped how this works with mv88e6xxx or
> prestera. If you need this private flag for some out of mainline
> Marvell SDK, it is very unlikely to be accepted.
>
> Andrew
What we are trying to do here has no dependency on DSA drivers and
neither impacts that functionality.
Here we are just notifying the HW to parse the packets properly.
Thanks,
Sunil.
> > So you completely skipped how this works with mv88e6xxx or
> > prestera. If you need this private flag for some out of mainline
> > Marvell SDK, it is very unlikely to be accepted.
> >
> > Andrew
>
> What we are trying to do here has no dependency on DSA drivers and
> neither impacts that functionality.
So this is an indirect way of saying: Yes, this is for some out of
mainline Marvell SDK.
> Here we are just notifying the HW to parse the packets properly.
But the correct way for this to happen is probably some kernel
internal API between the MAC and the DSA driver. Mainline probably has
no need for this private flag.
Andrew
On Thu, Mar 25, 2021 at 6:20 PM Andrew Lunn <[email protected]> wrote:
>
> > > So you completely skipped how this works with mv88e6xxx or
> > > prestera. If you need this private flag for some out of mainline
> > > Marvell SDK, it is very unlikely to be accepted.
> > >
> > > Andrew
> >
> > What we are trying to do here has no dependency on DSA drivers and
> > neither impacts that functionality.
>
> So this is an indirect way of saying: Yes, this is for some out of
> mainline Marvell SDK.
>
> > Here we are just notifying the HW to parse the packets properly.
>
> But the correct way for this to happen is probably some kernel
> internal API between the MAC and the DSA driver. Mainline probably has
> no need for this private flag.
>
> Andrew
Didn't get why you say so.
HW expects some info from SW to do the packet parsing properly and
this is specific to this hardware.
How can we generalize this ?
It's not just the DSA tags, the requirement is also for packets with
Higig header ie when system is connected to a switch
which appends Higig2 header to all pkts.
Thanks,
Sunil.
On Thu, Mar 25, 2021 at 06:32:12PM +0530, Sunil Kovvuri wrote:
> On Thu, Mar 25, 2021 at 6:20 PM Andrew Lunn <[email protected]> wrote:
> >
> > > > So you completely skipped how this works with mv88e6xxx or
> > > > prestera. If you need this private flag for some out of mainline
> > > > Marvell SDK, it is very unlikely to be accepted.
> > > >
> > > > Andrew
> > >
> > > What we are trying to do here has no dependency on DSA drivers and
> > > neither impacts that functionality.
> >
> > So this is an indirect way of saying: Yes, this is for some out of
> > mainline Marvell SDK.
> >
> > > Here we are just notifying the HW to parse the packets properly.
> >
> > But the correct way for this to happen is probably some kernel
> > internal API between the MAC and the DSA driver. Mainline probably has
> > no need for this private flag.
> >
> > Andrew
>
> Didn't get why you say so.
> HW expects some info from SW to do the packet parsing properly and
> this is specific to this hardware.
Anything which needs out of mainline code is going to be rejected,
unless you can show there is an in mainline use case as well. Which is
why i keep pointing you to mv88e6xxx and prestira. That provides the
necessary {E}DSA tags. You have an mv88e6xxx and prestira switch being
controlled by Linux with DSA tagged frames flowing out of it into your
MAC driver. What is the big picture use case that requires this
private flag to enable DSA parsing? Why don't the MAC driver and the
DSA driver just talk to each other, and setup the parsing?
Andrew
On Thu, Mar 25, 2021 at 6:51 PM Andrew Lunn <[email protected]> wrote:
>
> On Thu, Mar 25, 2021 at 06:32:12PM +0530, Sunil Kovvuri wrote:
> > On Thu, Mar 25, 2021 at 6:20 PM Andrew Lunn <[email protected]> wrote:
> > >
> > > > > So you completely skipped how this works with mv88e6xxx or
> > > > > prestera. If you need this private flag for some out of mainline
> > > > > Marvell SDK, it is very unlikely to be accepted.
> > > > >
> > > > > Andrew
> > > >
> > > > What we are trying to do here has no dependency on DSA drivers and
> > > > neither impacts that functionality.
> > >
> > > So this is an indirect way of saying: Yes, this is for some out of
> > > mainline Marvell SDK.
> > >
> > > > Here we are just notifying the HW to parse the packets properly.
> > >
> > > But the correct way for this to happen is probably some kernel
> > > internal API between the MAC and the DSA driver. Mainline probably has
> > > no need for this private flag.
> > >
> > > Andrew
> >
> > Didn't get why you say so.
> > HW expects some info from SW to do the packet parsing properly and
> > this is specific to this hardware.
>
> Anything which needs out of mainline code is going to be rejected,
> unless you can show there is an in mainline use case as well. Which is
> why i keep pointing you to mv88e6xxx and prestira. That provides the
> necessary {E}DSA tags. You have an mv88e6xxx and prestira switch being
> controlled by Linux with DSA tagged frames flowing out of it into your
> MAC driver. What is the big picture use case that requires this
> private flag to enable DSA parsing? Why don't the MAC driver and the
> DSA driver just talk to each other, and setup the parsing?
>
> Andrew
The usecase is simple, unlike DSA tag, this 4byte FDSA tag doesn't
have a ethertype,
so HW cannot recognize this header. If such packers arise, then HW parsing will
fail and RSS will not work.
Hypothetically if we introduce some communication between MAC driver
and DSA driver,
wouldn't that also become specific to the device, what generic usecase
that communication
will have ?
Thanks,
Sunil.
> The usecase is simple, unlike DSA tag, this 4byte FDSA tag doesn't
> have a ethertype,
> so HW cannot recognize this header. If such packers arise, then HW parsing will
> fail and RSS will not work.
>
> Hypothetically if we introduce some communication between MAC driver
> and DSA driver,
> wouldn't that also become specific to the device, what generic usecase
> that communication
> will have ?
Hi Sunil
We need to be careful with wording. Due to history, the Linux kernel
uses dsa to mean any driver to control an Ethernet switch. It does not
imply the {E}DSA protocol used by Marvell switches, or even that the
switch is a Marvell switch.
netdev_uses_dsa(ndev) will tell you if the MAC is being used to
connect to a switch. It is set by the Linux DSA core when the switch
cluster is setup. That could be before or after the MAC is configured
up, which makes it a bit hard to use, since you don't have a clear
indicator when to evaluate to determine if you need to change your
packet parsing.
netdev_uses_dsa() looks at ndev->dsa_ptr. This is a pointer to the
structure which represents the port on the switch the MAC is connected
to. In Linux DSA terms, this is the CPU port. You can follow
dsa_ptr->tag_ops which gives you the tagger operations, i.e. those
used to add and remove the header/trailer. One member of that is
proto. This contains the tagging protocol, so EDSA, DSA, or
potentially FDSA, if that is ever supported. And this is all within
the core DSA code, so is generic. It should work for any tagging
protocol used by any switch which Linux DSA supports.
So actually, everything you need is already present, you don't need a
private flag. But adding a notifier that the MAC has been connected to
a switch and ndev->dsa_ptr is set would be useful. We could maybe use
NETDEV_CHANGE for that, or NETDEV_CHANGELOWERSTATE, since the MAC is
below the switch slave interfaces.
Andrew
> -----Original Message-----
> From: Andrew Lunn <[email protected]>
> Sent: Sunday, March 28, 2021 11:17 PM
> To: Sunil Kovvuri <[email protected]>
> Cc: Hariprasad Kelam <[email protected]>; [email protected];
> [email protected]; [email protected]; [email protected];
> Sunil Kovvuri Goutham <[email protected]>; Linu Cherian
> <[email protected]>; Geethasowjanya Akula <[email protected]>;
> Jerin Jacob Kollanukkaran <[email protected]>; Subbaraya Sundeep Bhatta
> <[email protected]>
> Subject: [EXT] Re: [net-next PATCH 0/8] configuration support for switch
> headers & phy
>
> > The usecase is simple, unlike DSA tag, this 4byte FDSA tag doesn't
> > have a ethertype, so HW cannot recognize this header. If such packers
> > arise, then HW parsing will fail and RSS will not work.
> >
> > Hypothetically if we introduce some communication between MAC driver
> > and DSA driver, wouldn't that also become specific to the device, what
> > generic usecase that communication will have ?
>
> Hi Sunil
>
> We need to be careful with wording. Due to history, the Linux kernel uses
> dsa to mean any driver to control an Ethernet switch. It does not imply the
> {E}DSA protocol used by Marvell switches, or even that the switch is a
> Marvell switch.
>
> netdev_uses_dsa(ndev) will tell you if the MAC is being used to connect to a
> switch. It is set by the Linux DSA core when the switch cluster is setup. That
> could be before or after the MAC is configured up, which makes it a bit hard
> to use, since you don't have a clear indicator when to evaluate to determine
> if you need to change your packet parsing.
>
> netdev_uses_dsa() looks at ndev->dsa_ptr. This is a pointer to the structure
> which represents the port on the switch the MAC is connected to. In Linux
> DSA terms, this is the CPU port. You can follow dsa_ptr->tag_ops which gives
> you the tagger operations, i.e. those used to add and remove the
> header/trailer. One member of that is proto. This contains the tagging
> protocol, so EDSA, DSA, or potentially FDSA, if that is ever supported. And
> this is all within the core DSA code, so is generic. It should work for any
> tagging protocol used by any switch which Linux DSA supports.
>
> So actually, everything you need is already present, you don't need a private
> flag. But adding a notifier that the MAC has been connected to a switch and
> ndev->dsa_ptr is set would be useful. We could maybe use NETDEV_CHANGE
> for that, or NETDEV_CHANGELOWERSTATE, since the MAC is below the
> switch slave interfaces.
Hi Andrew,
We are looking into DSA to MAC driver communication options, will get back once we have clear picture.
Thanks,
Hariprasad k
>
> Andrew