diff --git a/drivers/net/ethernet/freescale/enetc/ntmp.c b/drivers/net/ethernet/freescale/enetc/ntmp.c index 4e60bbc38cfa..9249f78219ed 100644 --- a/drivers/net/ethernet/freescale/enetc/ntmp.c +++ b/drivers/net/ethernet/freescale/enetc/ntmp.c @@ -24,6 +24,7 @@ #define NTMP_IPFT_ID 13 #define NTMP_FDBT_ID 15 #define NTMP_VFT_ID 18 +#define NTMP_ETT_ID 33 #define NTMP_BPT_ID 41 /* Generic Update Actions for most tables */ @@ -284,6 +285,8 @@ static const char *ntmp_table_name(int tbl_id) return "FDB Table"; case NTMP_VFT_ID: return "VLAN Filter Table"; + case NTMP_ETT_ID: + return "Egress Treatment Table"; case NTMP_BPT_ID: return "Buffer Pool Table"; default: @@ -1091,6 +1094,109 @@ int ntmp_vft_delete_entry(struct ntmp_user *user, u16 vid) } EXPORT_SYMBOL_GPL(ntmp_vft_delete_entry); +/** + * ntmp_ett_set_entry - add a new entry to the egress treatment table or + * update the configuration element data of the specified entry + * @user: target ntmp_user struct + * @entry_id: entry ID + * @cmd: command type, NTMP_CMD_ADD or NTMP_CMD_UPDATE + * @cfge: configuration element data + * + * Return: 0 on success, otherwise a negative error code + */ +static int ntmp_ett_set_entry(struct ntmp_user *user, u32 entry_id, + int cmd, const struct ett_cfge_data *cfge) +{ + struct netc_swcbd swcbd; + struct ett_req_ua *req; + struct netc_cbdr *cbdr; + union netc_cbd cbd; + int err; + + if (cmd != NTMP_CMD_ADD && cmd != NTMP_CMD_UPDATE) + return -EINVAL; + + swcbd.size = sizeof(*req); + err = ntmp_alloc_data_mem(user->dev, &swcbd, (void **)&req); + if (err) + return err; + + /* Request data */ + ntmp_fill_crd_eid(&req->rbe, user->tbl.ett_ver, 0, + NTMP_GEN_UA_CFGEU, entry_id); + req->cfge = *cfge; + + /* Request header */ + ntmp_fill_request_hdr(&cbd, swcbd.dma, NTMP_LEN(swcbd.size, 0), + NTMP_ETT_ID, cmd, NTMP_AM_ENTRY_ID); + + ntmp_select_and_lock_cbdr(user, &cbdr); + err = netc_xmit_ntmp_cmd(cbdr, &cbd, &swcbd); + ntmp_unlock_cbdr(cbdr); + + return err; +} + +/** + * ntmp_ett_add_entry - add a new entry to the egress treatment table + * @user: target ntmp_user struct + * @entry_id: entry ID + * @cfge: configuration element data + * + * Return: 0 on success, otherwise a negative error code + */ +int ntmp_ett_add_entry(struct ntmp_user *user, u32 entry_id, + const struct ett_cfge_data *cfge) +{ + int err; + + err = ntmp_ett_set_entry(user, entry_id, NTMP_CMD_ADD, cfge); + if (err) + dev_err(user->dev, "Failed to add %s entry 0x%x, err: %pe\n", + ntmp_table_name(NTMP_ETT_ID), entry_id, ERR_PTR(err)); + + return err; +} +EXPORT_SYMBOL_GPL(ntmp_ett_add_entry); + +/** + * ntmp_ett_update_entry - update the configuration element data of the + * specified entry + * @user: target ntmp_user struct + * @entry_id: entry ID + * @cfge: configuration element data + * + * Return: 0 on success, otherwise a negative error code + */ +int ntmp_ett_update_entry(struct ntmp_user *user, u32 entry_id, + const struct ett_cfge_data *cfge) +{ + int err; + + err = ntmp_ett_set_entry(user, entry_id, NTMP_CMD_UPDATE, cfge); + if (err) + dev_err(user->dev, + "Failed to update %s entry 0x%x, err: %pe\n", + ntmp_table_name(NTMP_ETT_ID), entry_id, ERR_PTR(err)); + + return err; +} +EXPORT_SYMBOL_GPL(ntmp_ett_update_entry); + +/** + * ntmp_ett_delete_entry - delete the specified egress treatment table entry + * @user: target ntmp_user struct + * @entry_id: entry ID + * + * Return: 0 on success, otherwise a negative error code + */ +int ntmp_ett_delete_entry(struct ntmp_user *user, u32 entry_id) +{ + return ntmp_delete_entry_by_id(user, NTMP_ETT_ID, user->tbl.ett_ver, + entry_id, NTMP_EID_REQ_LEN, 0); +} +EXPORT_SYMBOL_GPL(ntmp_ett_delete_entry); + int ntmp_bpt_update_entry(struct ntmp_user *user, u32 entry_id, const struct bpt_cfge_data *cfge) { diff --git a/drivers/net/ethernet/freescale/enetc/ntmp_private.h b/drivers/net/ethernet/freescale/enetc/ntmp_private.h index 9d30f128849a..531ea7ddd145 100644 --- a/drivers/net/ethernet/freescale/enetc/ntmp_private.h +++ b/drivers/net/ethernet/freescale/enetc/ntmp_private.h @@ -217,6 +217,14 @@ struct vft_req_qd { union vft_access_key ak; }; +/* Egress Treatment Table Request Data Buffer Format of Update and Add + * actions + */ +struct ett_req_ua { + struct ntmp_req_by_eid rbe; + struct ett_cfge_data cfge; +}; + /* Buffer Pool Table Request Data Buffer Format of Update action */ struct bpt_req_update { struct ntmp_req_by_eid rbe; diff --git a/include/linux/fsl/ntmp.h b/include/linux/fsl/ntmp.h index 36a9089526ad..0c951e1c763d 100644 --- a/include/linux/fsl/ntmp.h +++ b/include/linux/fsl/ntmp.h @@ -36,6 +36,7 @@ struct netc_tbl_vers { u8 vft_ver; u8 bpt_ver; u8 ipft_ver; + u8 ett_ver; }; struct netc_swcbd { @@ -214,6 +215,23 @@ struct vft_cfge_data { __le32 et_eid; }; +struct ett_cfge_data { + __le16 efm_cfg; +#define ETT_EFM_MODE GENMASK(1, 0) +#define ETT_ESQA GENMASK(5, 4) +#define ETT_ECA GENMASK(8, 6) +#define ETT_ECA_INC 1 +#define ETT_EFM_LEN_CHANGE GENMASK(15, 9) +#define ETT_FRM_LEN_DEL_VLAN 0x7c +#define ETT_FRM_LEN_DEL_RTAG 0x7a +#define ETT_FRM_LEN_DEL_VLAN_RTAG 0x76 + __le16 efm_data_len; +#define ETT_EFM_DATA_LEN GENMASK(10, 0) + __le32 efm_eid; + __le32 ec_eid; + __le32 esqa_tgt_eid; +}; + struct bpt_bpse_data { __le32 amount_used; __le32 amount_used_hwm; @@ -271,6 +289,11 @@ int ntmp_vft_add_entry(struct ntmp_user *user, u16 vid, int ntmp_vft_update_entry(struct ntmp_user *user, u16 vid, const struct vft_cfge_data *cfge); int ntmp_vft_delete_entry(struct ntmp_user *user, u16 vid); +int ntmp_ett_add_entry(struct ntmp_user *user, u32 entry_id, + const struct ett_cfge_data *cfge); +int ntmp_ett_update_entry(struct ntmp_user *user, u32 entry_id, + const struct ett_cfge_data *cfge); +int ntmp_ett_delete_entry(struct ntmp_user *user, u32 entry_id); int ntmp_bpt_update_entry(struct ntmp_user *user, u32 entry_id, const struct bpt_cfge_data *cfge); #else