#define NTMP_GEN_UA_STSEU BIT(1)
/* Specific Update Actions for some tables */
+#define FDBT_UA_ACTEU BIT(1)
#define BPT_UA_BPSEU BIT(1)
/* Query Action: 0: Full query. 1: Query entry ID, the fields after entry
}
EXPORT_SYMBOL_GPL(ntmp_fdbt_search_port_entry);
+/**
+ * ntmp_fdbt_update_activity_element - update the activity element of all
+ * the dynamic entries in the FDB table.
+ * @user: target ntmp_user struct
+ *
+ * A single activity update management could be used to process all the
+ * dynamic entries in the FDB table. When hardware process an activity
+ * update management command for an entry in the FDB table and the entry
+ * does not have its activity flag set, the activity counter is incremented.
+ * However, if the activity flag is set, then both the activity flag and
+ * activity counter are reset. Software can issue the activity update
+ * management commands at predefined times and the value of the activity
+ * counter can then be used to estimate the period of how long an FDB
+ * entry has been inactive.
+ *
+ * Return: 0 on success, otherwise a negative error code
+ */
+int ntmp_fdbt_update_activity_element(struct ntmp_user *user)
+{
+ struct fdbt_req_ua *req;
+ struct netc_swcbd swcbd;
+ struct netc_cbdr *cbdr;
+ union netc_cbd cbd;
+ u32 len;
+ int err;
+
+ swcbd.size = sizeof(*req);
+ err = ntmp_alloc_data_mem(user->dev, &swcbd, (void **)&req);
+ if (err)
+ return err;
+
+ /* Request data */
+ ntmp_fill_crd(&req->crd, user->tbl.fdbt_ver, 0, FDBT_UA_ACTEU);
+ req->ak.search.resume_eid = cpu_to_le32(NTMP_NULL_ENTRY_ID);
+ req->ak.search.cfge.cfg = cpu_to_le32(FDBT_DYNAMIC);
+ req->ak.search.cfge_mc = FDBT_CFGE_MC_DYNAMIC;
+
+ /* Request header */
+ len = NTMP_LEN(swcbd.size, NTMP_STATUS_RESP_LEN);
+ /* For activity update, the access method must be search */
+ ntmp_fill_request_hdr(&cbd, swcbd.dma, len, NTMP_FDBT_ID,
+ NTMP_CMD_UPDATE, NTMP_AM_SEARCH);
+
+ ntmp_select_and_lock_cbdr(user, &cbdr);
+ err = netc_xmit_ntmp_cmd(cbdr, &cbd, &swcbd);
+ if (err)
+ dev_err(user->dev,
+ "Failed to update activity of %s, err: %pe\n",
+ ntmp_table_name(NTMP_FDBT_ID), ERR_PTR(err));
+
+ ntmp_unlock_cbdr(cbdr);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(ntmp_fdbt_update_activity_element);
+
+/**
+ * ntmp_fdbt_delete_ageing_entries - delete all the ageing dynamic entries
+ * in the FDB table
+ * @user: target ntmp_user struct
+ * @act_cnt: the target value of the activity counter
+ *
+ * The matching rule is that the activity flag is not set and the activity
+ * counter is greater than or equal to act_cnt
+ *
+ * Return: 0 on success, otherwise a negative error code
+ */
+int ntmp_fdbt_delete_ageing_entries(struct ntmp_user *user, u8 act_cnt)
+{
+ struct fdbt_req_qd *req;
+ struct netc_swcbd swcbd;
+ struct netc_cbdr *cbdr;
+ union netc_cbd cbd;
+ u32 len;
+ int err;
+
+ if (act_cnt > FDBT_ACT_CNT)
+ 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(&req->crd, user->tbl.fdbt_ver, 0, 0);
+ req->ak.search.resume_eid = cpu_to_le32(NTMP_NULL_ENTRY_ID);
+ req->ak.search.cfge.cfg = cpu_to_le32(FDBT_DYNAMIC);
+ req->ak.search.acte = act_cnt;
+ /* Exact match with ACTE_DATA[ACT_FLAG] AND
+ * match >= ACTE_DATA[ACT_CNT]
+ */
+ req->ak.search.acte_mc = FDBT_ACTE_MC;
+ req->ak.search.cfge_mc = FDBT_CFGE_MC_DYNAMIC;
+
+ /* Request header */
+ len = NTMP_LEN(swcbd.size, NTMP_STATUS_RESP_LEN);
+ ntmp_fill_request_hdr(&cbd, swcbd.dma, len, NTMP_FDBT_ID,
+ NTMP_CMD_DELETE, NTMP_AM_SEARCH);
+
+ ntmp_select_and_lock_cbdr(user, &cbdr);
+ err = netc_xmit_ntmp_cmd(cbdr, &cbd, &swcbd);
+ if (err)
+ dev_err(user->dev,
+ "Failed to delete ageing entries of %s, err: %pe\n",
+ ntmp_table_name(NTMP_FDBT_ID), ERR_PTR(err));
+
+ ntmp_unlock_cbdr(cbdr);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(ntmp_fdbt_delete_ageing_entries);
+
+/**
+ * ntmp_fdbt_delete_port_dynamic_entries - delete all dynamic FDB entries
+ * associated with the specified switch port
+ * @user: target ntmp_user struct
+ * @port: the specified switch port ID
+ *
+ * Return: 0 on success, otherwise a negative error code
+ */
+int ntmp_fdbt_delete_port_dynamic_entries(struct ntmp_user *user, int port)
+{
+ struct fdbt_req_qd *req;
+ struct netc_swcbd swcbd;
+ struct netc_cbdr *cbdr;
+ union netc_cbd cbd;
+ u32 len;
+ int err;
+
+ swcbd.size = sizeof(*req);
+ err = ntmp_alloc_data_mem(user->dev, &swcbd, (void **)&req);
+ if (err)
+ return err;
+
+ /* Request data */
+ ntmp_fill_crd(&req->crd, user->tbl.fdbt_ver, 0, 0);
+ req->ak.search.resume_eid = cpu_to_le32(NTMP_NULL_ENTRY_ID);
+ req->ak.search.cfge.port_bitmap = cpu_to_le32(BIT(port));
+ req->ak.search.cfge.cfg = cpu_to_le32(FDBT_DYNAMIC);
+ /* Match CFGE_DATA[DYNAMIC & PORT_BITMAP] field */
+ req->ak.search.cfge_mc = FDBT_CFGE_MC_DYNAMIC_AND_PORT_BITMAP;
+
+ /* Request header */
+ len = NTMP_LEN(swcbd.size, NTMP_STATUS_RESP_LEN);
+ ntmp_fill_request_hdr(&cbd, swcbd.dma, len, NTMP_FDBT_ID,
+ NTMP_CMD_DELETE, NTMP_AM_SEARCH);
+
+ ntmp_select_and_lock_cbdr(user, &cbdr);
+ err = netc_xmit_ntmp_cmd(cbdr, &cbd, &swcbd);
+ if (err)
+ dev_err(user->dev,
+ "Failed to delete dynamic %s entries on port %d, err: %pe\n",
+ ntmp_table_name(NTMP_FDBT_ID), port, ERR_PTR(err));
+
+ ntmp_unlock_cbdr(cbdr);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(ntmp_fdbt_delete_port_dynamic_entries);
+
/**
* ntmp_vft_add_entry - add an entry into the VLAN filter table
* @user: target ntmp_user struct