aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qede/base/ecore_dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/qede/base/ecore_dev.c')
-rw-r--r--drivers/net/qede/base/ecore_dev.c474
1 files changed, 308 insertions, 166 deletions
diff --git a/drivers/net/qede/base/ecore_dev.c b/drivers/net/qede/base/ecore_dev.c
index 865103c6..65b89b8f 100644
--- a/drivers/net/qede/base/ecore_dev.c
+++ b/drivers/net/qede/base/ecore_dev.c
@@ -1080,7 +1080,7 @@ enum _ecore_status_t ecore_final_cleanup(struct ecore_hwfn *p_hwfn,
}
DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
- "Sending final cleanup for PFVF[%d] [Command %08x\n]",
+ "Sending final cleanup for PFVF[%d] [Command %08x]\n",
id, command);
ecore_wr(p_hwfn, p_ptt, XSDM_REG_OPERATION_GEN, command);
@@ -1776,13 +1776,6 @@ ecore_hw_init_pf(struct ecore_hwfn *p_hwfn,
/* perform debug configuration when chip is out of reset */
OSAL_BEFORE_PF_START((void *)p_hwfn->p_dev, p_hwfn->my_id);
- /* Cleanup chip from previous driver if such remains exist */
- rc = ecore_final_cleanup(p_hwfn, p_ptt, rel_pf_id, false);
- if (rc != ECORE_SUCCESS) {
- ecore_hw_err_notify(p_hwfn, ECORE_HW_ERR_RAMROD_FAIL);
- return rc;
- }
-
/* PF Init sequence */
rc = ecore_init_run(p_hwfn, p_ptt, PHASE_PF, rel_pf_id, hw_mode);
if (rc)
@@ -1866,17 +1859,17 @@ ecore_hw_init_pf(struct ecore_hwfn *p_hwfn,
return rc;
}
-static enum _ecore_status_t
-ecore_change_pci_hwfn(struct ecore_hwfn *p_hwfn,
- struct ecore_ptt *p_ptt, u8 enable)
+enum _ecore_status_t ecore_pglueb_set_pfid_enable(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt,
+ bool b_enable)
{
- u32 delay_idx = 0, val, set_val = enable ? 1 : 0;
+ u32 delay_idx = 0, val, set_val = b_enable ? 1 : 0;
- /* Change PF in PXP */
+ /* Configure the PF's internal FID_enable for master transactions */
ecore_wr(p_hwfn, p_ptt,
PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, set_val);
- /* wait until value is set - try for 1 second every 50us */
+ /* Wait until value is set - try for 1 second every 50us */
for (delay_idx = 0; delay_idx < 20000; delay_idx++) {
val = ecore_rd(p_hwfn, p_ptt,
PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER);
@@ -1918,14 +1911,21 @@ enum _ecore_status_t ecore_vf_start(struct ecore_hwfn *p_hwfn,
return ECORE_SUCCESS;
}
+static void ecore_pglueb_clear_err(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt)
+{
+ ecore_wr(p_hwfn, p_ptt, PGLUE_B_REG_WAS_ERROR_PF_31_0_CLR,
+ 1 << p_hwfn->abs_pf_id);
+}
+
enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
struct ecore_hw_init_params *p_params)
{
struct ecore_load_req_params load_req_params;
- u32 load_code, param, drv_mb_param;
+ u32 load_code, resp, param, drv_mb_param;
bool b_default_mtu = true;
struct ecore_hwfn *p_hwfn;
- enum _ecore_status_t rc = ECORE_SUCCESS, mfw_rc;
+ enum _ecore_status_t rc = ECORE_SUCCESS;
int i;
if ((p_params->int_mode == ECORE_INT_MODE_MSI) &&
@@ -1942,7 +1942,7 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
}
for_each_hwfn(p_dev, i) {
- struct ecore_hwfn *p_hwfn = &p_dev->hwfns[i];
+ p_hwfn = &p_dev->hwfns[i];
/* If management didn't provide a default, set one of our own */
if (!p_hwfn->hw_info.mtu) {
@@ -1955,11 +1955,6 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
continue;
}
- /* Enable DMAE in PXP */
- rc = ecore_change_pci_hwfn(p_hwfn, p_hwfn->p_main_ptt, true);
- if (rc != ECORE_SUCCESS)
- return rc;
-
rc = ecore_calc_hw_mode(p_hwfn);
if (rc != ECORE_SUCCESS)
return rc;
@@ -2009,6 +2004,30 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
qm_lock_init = true;
}
+ /* Clean up chip from previous driver if such remains exist.
+ * This is not needed when the PF is the first one on the
+ * engine, since afterwards we are going to init the FW.
+ */
+ if (load_code != FW_MSG_CODE_DRV_LOAD_ENGINE) {
+ rc = ecore_final_cleanup(p_hwfn, p_hwfn->p_main_ptt,
+ p_hwfn->rel_pf_id, false);
+ if (rc != ECORE_SUCCESS) {
+ ecore_hw_err_notify(p_hwfn,
+ ECORE_HW_ERR_RAMROD_FAIL);
+ goto load_err;
+ }
+ }
+
+ /* Log and clean previous pglue_b errors if such exist */
+ ecore_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_main_ptt);
+ ecore_pglueb_clear_err(p_hwfn, p_hwfn->p_main_ptt);
+
+ /* Enable the PF's internal FID_enable in the PXP */
+ rc = ecore_pglueb_set_pfid_enable(p_hwfn, p_hwfn->p_main_ptt,
+ true);
+ if (rc != ECORE_SUCCESS)
+ goto load_err;
+
switch (load_code) {
case FW_MSG_CODE_DRV_LOAD_ENGINE:
rc = ecore_hw_init_common(p_hwfn, p_hwfn->p_main_ptt,
@@ -2037,35 +2056,28 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
break;
}
- if (rc != ECORE_SUCCESS)
+ if (rc != ECORE_SUCCESS) {
DP_NOTICE(p_hwfn, true,
"init phase failed for loadcode 0x%x (rc %d)\n",
load_code, rc);
+ goto load_err;
+ }
- /* ACK mfw regardless of success or failure of initialization */
- mfw_rc = ecore_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
- DRV_MSG_CODE_LOAD_DONE,
- 0, &load_code, &param);
+ rc = ecore_mcp_load_done(p_hwfn, p_hwfn->p_main_ptt);
if (rc != ECORE_SUCCESS)
return rc;
- if (mfw_rc != ECORE_SUCCESS) {
- DP_NOTICE(p_hwfn, true,
- "Failed sending a LOAD_DONE command\n");
- return mfw_rc;
- }
-
/* send DCBX attention request command */
DP_VERBOSE(p_hwfn, ECORE_MSG_DCB,
"sending phony dcbx set command to trigger DCBx attention handling\n");
- mfw_rc = ecore_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
- DRV_MSG_CODE_SET_DCBX,
- 1 << DRV_MB_PARAM_DCBX_NOTIFY_SHIFT,
- &load_code, &param);
- if (mfw_rc != ECORE_SUCCESS) {
+ rc = ecore_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
+ DRV_MSG_CODE_SET_DCBX,
+ 1 << DRV_MB_PARAM_DCBX_NOTIFY_SHIFT, &resp,
+ &param);
+ if (rc != ECORE_SUCCESS) {
DP_NOTICE(p_hwfn, true,
"Failed to send DCBX attention request\n");
- return mfw_rc;
+ return rc;
}
p_hwfn->hw_init_done = true;
@@ -2076,7 +2088,7 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
drv_mb_param = STORM_FW_VERSION;
rc = ecore_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
DRV_MSG_CODE_OV_UPDATE_STORM_FW_VER,
- drv_mb_param, &load_code, &param);
+ drv_mb_param, &resp, &param);
if (rc != ECORE_SUCCESS)
DP_INFO(p_hwfn, "Failed to update firmware version\n");
@@ -2094,6 +2106,14 @@ enum _ecore_status_t ecore_hw_init(struct ecore_dev *p_dev,
}
return rc;
+
+load_err:
+ /* The MFW load lock should be released regardless of success or failure
+ * of initialization.
+ * TODO: replace this with an attempt to send cancel_load.
+ */
+ ecore_mcp_load_done(p_hwfn, p_hwfn->p_main_ptt);
+ return rc;
}
#define ECORE_HW_STOP_RETRY_LIMIT (10)
@@ -2261,18 +2281,20 @@ enum _ecore_status_t ecore_hw_stop(struct ecore_dev *p_dev)
}
} /* hwfn loop */
- if (IS_PF(p_dev)) {
+ if (IS_PF(p_dev) && !p_dev->recov_in_prog) {
p_hwfn = ECORE_LEADING_HWFN(p_dev);
p_ptt = ECORE_LEADING_HWFN(p_dev)->p_main_ptt;
- /* Disable DMAE in PXP - in CMT, this should only be done for
- * first hw-function, and only after all transactions have
- * stopped for all active hw-functions.
- */
- rc = ecore_change_pci_hwfn(p_hwfn, p_ptt, false);
+ /* Clear the PF's internal FID_enable in the PXP.
+ * In CMT this should only be done for first hw-function, and
+ * only after all transactions have stopped for all active
+ * hw-functions.
+ */
+ rc = ecore_pglueb_set_pfid_enable(p_hwfn, p_hwfn->p_main_ptt,
+ false);
if (rc != ECORE_SUCCESS) {
DP_NOTICE(p_hwfn, true,
- "ecore_change_pci_hwfn failed. rc = %d.\n",
+ "ecore_pglueb_set_pfid_enable() failed. rc = %d.\n",
rc);
rc2 = ECORE_UNKNOWN_ERROR;
}
@@ -2370,9 +2392,8 @@ static void ecore_hw_hwfn_prepare(struct ecore_hwfn *p_hwfn)
PGLUE_B_REG_PGL_ADDR_94_F0_BB, 0);
}
- /* Clean Previous errors if such exist */
- ecore_wr(p_hwfn, p_hwfn->p_main_ptt,
- PGLUE_B_REG_WAS_ERROR_PF_31_0_CLR, 1 << p_hwfn->abs_pf_id);
+ /* Clean previous pglue_b errors if such exist */
+ ecore_pglueb_clear_err(p_hwfn, p_hwfn->p_main_ptt);
/* enable internal target-read */
ecore_wr(p_hwfn, p_hwfn->p_main_ptt,
@@ -3565,6 +3586,7 @@ enum _ecore_status_t ecore_hw_prepare(struct ecore_dev *p_dev,
enum _ecore_status_t rc;
p_dev->chk_reg_fifo = p_params->chk_reg_fifo;
+ p_dev->allow_mdump = p_params->allow_mdump;
if (p_params->b_relaxed_probe)
p_params->p_relaxed_res = ECORE_HW_PREPARE_SUCCESS;
@@ -3718,7 +3740,7 @@ static void ecore_chain_free_pbl(struct ecore_dev *p_dev,
if (!p_chain->b_external_pbl)
OSAL_DMA_FREE_COHERENT(p_dev, p_chain->pbl_sp.p_virt_table,
p_chain->pbl_sp.p_phys_table, pbl_size);
- out:
+out:
OSAL_VFREE(p_dev, p_chain->pbl.pp_virt_addr_tbl);
}
@@ -3994,92 +4016,182 @@ enum _ecore_status_t ecore_fw_rss_eng(struct ecore_hwfn *p_hwfn,
return ECORE_SUCCESS;
}
-enum _ecore_status_t ecore_llh_add_mac_filter(struct ecore_hwfn *p_hwfn,
- struct ecore_ptt *p_ptt,
- u8 *p_filter)
+static enum _ecore_status_t
+ecore_llh_add_mac_filter_bb_ah(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt, u32 high, u32 low,
+ u32 *p_entry_num)
{
- u32 high, low, en;
+ u32 en;
int i;
- if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn)))
- return ECORE_SUCCESS;
-
- high = p_filter[1] | (p_filter[0] << 8);
- low = p_filter[5] | (p_filter[4] << 8) |
- (p_filter[3] << 16) | (p_filter[2] << 24);
-
/* Find a free entry and utilize it */
for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) {
en = ecore_rd(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32));
+ NIG_REG_LLH_FUNC_FILTER_EN_BB_K2 +
+ i * sizeof(u32));
if (en)
continue;
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
2 * i * sizeof(u32), low);
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
(2 * i + 1) * sizeof(u32), high);
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_MODE + i * sizeof(u32), 0);
+ NIG_REG_LLH_FUNC_FILTER_MODE_BB_K2 +
+ i * sizeof(u32), 0);
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE +
+ NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE_BB_K2 +
i * sizeof(u32), 0);
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32), 1);
+ NIG_REG_LLH_FUNC_FILTER_EN_BB_K2 +
+ i * sizeof(u32), 1);
break;
}
- if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE) {
- DP_NOTICE(p_hwfn, false,
- "Failed to find an empty LLH filter to utilize\n");
- return ECORE_INVAL;
- }
- DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
- "MAC: %x:%x:%x:%x:%x:%x is added at %d\n",
- p_filter[0], p_filter[1], p_filter[2],
- p_filter[3], p_filter[4], p_filter[5], i);
+ if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE)
+ return ECORE_NORESOURCES;
+
+ *p_entry_num = i;
return ECORE_SUCCESS;
}
-void ecore_llh_remove_mac_filter(struct ecore_hwfn *p_hwfn,
- struct ecore_ptt *p_ptt, u8 *p_filter)
+enum _ecore_status_t ecore_llh_add_mac_filter(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt, u8 *p_filter)
{
- u32 high, low;
- int i;
+ u32 high, low, entry_num;
+ enum _ecore_status_t rc;
if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn)))
- return;
+ return ECORE_SUCCESS;
high = p_filter[1] | (p_filter[0] << 8);
low = p_filter[5] | (p_filter[4] << 8) |
- (p_filter[3] << 16) | (p_filter[2] << 24);
+ (p_filter[3] << 16) | (p_filter[2] << 24);
+
+ if (ECORE_IS_BB(p_hwfn->p_dev) || ECORE_IS_AH(p_hwfn->p_dev))
+ rc = ecore_llh_add_mac_filter_bb_ah(p_hwfn, p_ptt, high, low,
+ &entry_num);
+ if (rc != ECORE_SUCCESS) {
+ DP_NOTICE(p_hwfn, false,
+ "Failed to find an empty LLH filter to utilize\n");
+ return rc;
+ }
+
+ DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
+ "MAC: %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx is added at %d\n",
+ p_filter[0], p_filter[1], p_filter[2], p_filter[3],
+ p_filter[4], p_filter[5], entry_num);
+
+ return ECORE_SUCCESS;
+}
+
+static enum _ecore_status_t
+ecore_llh_remove_mac_filter_bb_ah(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt, u32 high, u32 low,
+ u32 *p_entry_num)
+{
+ int i;
/* Find the entry and clean it */
for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) {
if (ecore_rd(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
2 * i * sizeof(u32)) != low)
continue;
if (ecore_rd(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
(2 * i + 1) * sizeof(u32)) != high)
continue;
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32), 0);
+ NIG_REG_LLH_FUNC_FILTER_EN_BB_K2 + i * sizeof(u32), 0);
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
2 * i * sizeof(u32), 0);
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
(2 * i + 1) * sizeof(u32), 0);
break;
}
+
if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE)
+ return ECORE_INVAL;
+
+ *p_entry_num = i;
+
+ return ECORE_SUCCESS;
+}
+
+void ecore_llh_remove_mac_filter(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt, u8 *p_filter)
+{
+ u32 high, low, entry_num;
+ enum _ecore_status_t rc;
+
+ if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn)))
+ return;
+
+ high = p_filter[1] | (p_filter[0] << 8);
+ low = p_filter[5] | (p_filter[4] << 8) |
+ (p_filter[3] << 16) | (p_filter[2] << 24);
+
+ if (ECORE_IS_BB(p_hwfn->p_dev) || ECORE_IS_AH(p_hwfn->p_dev))
+ rc = ecore_llh_remove_mac_filter_bb_ah(p_hwfn, p_ptt, high,
+ low, &entry_num);
+ if (rc != ECORE_SUCCESS) {
DP_NOTICE(p_hwfn, false,
"Tried to remove a non-configured filter\n");
+ return;
+ }
+
+
+ DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
+ "MAC: %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx was removed from %d\n",
+ p_filter[0], p_filter[1], p_filter[2], p_filter[3],
+ p_filter[4], p_filter[5], entry_num);
+}
+
+static enum _ecore_status_t
+ecore_llh_add_protocol_filter_bb_ah(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt,
+ enum ecore_llh_port_filter_type_t type,
+ u32 high, u32 low, u32 *p_entry_num)
+{
+ u32 en;
+ int i;
+
+ /* Find a free entry and utilize it */
+ for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) {
+ en = ecore_rd(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_EN_BB_K2 +
+ i * sizeof(u32));
+ if (en)
+ continue;
+ ecore_wr(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
+ 2 * i * sizeof(u32), low);
+ ecore_wr(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
+ (2 * i + 1) * sizeof(u32), high);
+ ecore_wr(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_MODE_BB_K2 +
+ i * sizeof(u32), 1);
+ ecore_wr(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE_BB_K2 +
+ i * sizeof(u32), 1 << type);
+ ecore_wr(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_EN_BB_K2 + i * sizeof(u32), 1);
+ break;
+ }
+
+ if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE)
+ return ECORE_NORESOURCES;
+
+ *p_entry_num = i;
+
+ return ECORE_SUCCESS;
}
enum _ecore_status_t
@@ -4089,14 +4201,15 @@ ecore_llh_add_protocol_filter(struct ecore_hwfn *p_hwfn,
u16 dest_port,
enum ecore_llh_port_filter_type_t type)
{
- u32 high, low, en;
- int i;
+ u32 high, low, entry_num;
+ enum _ecore_status_t rc;
if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn)))
return ECORE_SUCCESS;
high = 0;
low = 0;
+
switch (type) {
case ECORE_LLH_FILTER_ETHERTYPE:
high = source_port_or_eth_type;
@@ -4118,67 +4231,109 @@ ecore_llh_add_protocol_filter(struct ecore_hwfn *p_hwfn,
"Non valid LLH protocol filter type %d\n", type);
return ECORE_INVAL;
}
- /* Find a free entry and utilize it */
- for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) {
- en = ecore_rd(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32));
- if (en)
- continue;
- ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
- 2 * i * sizeof(u32), low);
- ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
- (2 * i + 1) * sizeof(u32), high);
- ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_MODE + i * sizeof(u32), 1);
- ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE +
- i * sizeof(u32), 1 << type);
- ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32), 1);
- break;
- }
- if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE) {
+
+ if (ECORE_IS_BB(p_hwfn->p_dev) || ECORE_IS_AH(p_hwfn->p_dev))
+ rc = ecore_llh_add_protocol_filter_bb_ah(p_hwfn, p_ptt, type,
+ high, low, &entry_num);
+ if (rc != ECORE_SUCCESS) {
DP_NOTICE(p_hwfn, false,
"Failed to find an empty LLH filter to utilize\n");
- return ECORE_NORESOURCES;
+ return rc;
}
switch (type) {
case ECORE_LLH_FILTER_ETHERTYPE:
DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
"ETH type %x is added at %d\n",
- source_port_or_eth_type, i);
+ source_port_or_eth_type, entry_num);
break;
case ECORE_LLH_FILTER_TCP_SRC_PORT:
DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
"TCP src port %x is added at %d\n",
- source_port_or_eth_type, i);
+ source_port_or_eth_type, entry_num);
break;
case ECORE_LLH_FILTER_UDP_SRC_PORT:
DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
"UDP src port %x is added at %d\n",
- source_port_or_eth_type, i);
+ source_port_or_eth_type, entry_num);
break;
case ECORE_LLH_FILTER_TCP_DEST_PORT:
DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
- "TCP dst port %x is added at %d\n", dest_port, i);
+ "TCP dst port %x is added at %d\n", dest_port,
+ entry_num);
break;
case ECORE_LLH_FILTER_UDP_DEST_PORT:
DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
- "UDP dst port %x is added at %d\n", dest_port, i);
+ "UDP dst port %x is added at %d\n", dest_port,
+ entry_num);
break;
case ECORE_LLH_FILTER_TCP_SRC_AND_DEST_PORT:
DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
"TCP src/dst ports %x/%x are added at %d\n",
- source_port_or_eth_type, dest_port, i);
+ source_port_or_eth_type, dest_port, entry_num);
break;
case ECORE_LLH_FILTER_UDP_SRC_AND_DEST_PORT:
DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
"UDP src/dst ports %x/%x are added at %d\n",
- source_port_or_eth_type, dest_port, i);
+ source_port_or_eth_type, dest_port, entry_num);
break;
}
+
+ return ECORE_SUCCESS;
+}
+
+static enum _ecore_status_t
+ecore_llh_remove_protocol_filter_bb_ah(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt,
+ enum ecore_llh_port_filter_type_t type,
+ u32 high, u32 low, u32 *p_entry_num)
+{
+ int i;
+
+ /* Find the entry and clean it */
+ for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) {
+ if (!ecore_rd(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_EN_BB_K2 +
+ i * sizeof(u32)))
+ continue;
+ if (!ecore_rd(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_MODE_BB_K2 +
+ i * sizeof(u32)))
+ continue;
+ if (!(ecore_rd(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE_BB_K2 +
+ i * sizeof(u32)) & (1 << type)))
+ continue;
+ if (ecore_rd(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
+ 2 * i * sizeof(u32)) != low)
+ continue;
+ if (ecore_rd(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
+ (2 * i + 1) * sizeof(u32)) != high)
+ continue;
+
+ ecore_wr(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_EN_BB_K2 + i * sizeof(u32), 0);
+ ecore_wr(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_MODE_BB_K2 +
+ i * sizeof(u32), 0);
+ ecore_wr(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE_BB_K2 +
+ i * sizeof(u32), 0);
+ ecore_wr(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
+ 2 * i * sizeof(u32), 0);
+ ecore_wr(p_hwfn, p_ptt,
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
+ (2 * i + 1) * sizeof(u32), 0);
+ break;
+ }
+
+ if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE)
+ return ECORE_INVAL;
+
+ *p_entry_num = i;
+
return ECORE_SUCCESS;
}
@@ -4189,14 +4344,15 @@ ecore_llh_remove_protocol_filter(struct ecore_hwfn *p_hwfn,
u16 dest_port,
enum ecore_llh_port_filter_type_t type)
{
- u32 high, low;
- int i;
+ u32 high, low, entry_num;
+ enum _ecore_status_t rc;
if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn)))
return;
high = 0;
low = 0;
+
switch (type) {
case ECORE_LLH_FILTER_ETHERTYPE:
high = source_port_or_eth_type;
@@ -4219,49 +4375,24 @@ ecore_llh_remove_protocol_filter(struct ecore_hwfn *p_hwfn,
return;
}
- for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) {
- if (!ecore_rd(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32)))
- continue;
- if (!ecore_rd(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_MODE + i * sizeof(u32)))
- continue;
- if (!(ecore_rd(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE +
- i * sizeof(u32)) & (1 << type)))
- continue;
- if (ecore_rd(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
- 2 * i * sizeof(u32)) != low)
- continue;
- if (ecore_rd(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
- (2 * i + 1) * sizeof(u32)) != high)
- continue;
-
- ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32), 0);
- ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_MODE + i * sizeof(u32), 0);
- ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_PROTOCOL_TYPE +
- i * sizeof(u32), 0);
- ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
- 2 * i * sizeof(u32), 0);
- ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
- (2 * i + 1) * sizeof(u32), 0);
- break;
+ if (ECORE_IS_BB(p_hwfn->p_dev) || ECORE_IS_AH(p_hwfn->p_dev))
+ rc = ecore_llh_remove_protocol_filter_bb_ah(p_hwfn, p_ptt, type,
+ high, low,
+ &entry_num);
+ if (rc != ECORE_SUCCESS) {
+ DP_NOTICE(p_hwfn, false,
+ "Tried to remove a non-configured filter [type %d, source_port_or_eth_type 0x%x, dest_port 0x%x]\n",
+ type, source_port_or_eth_type, dest_port);
+ return;
}
- if (i >= NIG_REG_LLH_FUNC_FILTER_EN_SIZE)
- DP_NOTICE(p_hwfn, false,
- "Tried to remove a non-configured filter\n");
+ DP_VERBOSE(p_hwfn, ECORE_MSG_HW,
+ "Protocol filter [type %d, source_port_or_eth_type 0x%x, dest_port 0x%x] was removed from %d\n",
+ type, source_port_or_eth_type, dest_port, entry_num);
}
-void ecore_llh_clear_all_filters(struct ecore_hwfn *p_hwfn,
- struct ecore_ptt *p_ptt)
+static void ecore_llh_clear_all_filters_bb_ah(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt)
{
int i;
@@ -4270,16 +4401,27 @@ void ecore_llh_clear_all_filters(struct ecore_hwfn *p_hwfn,
for (i = 0; i < NIG_REG_LLH_FUNC_FILTER_EN_SIZE; i++) {
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_EN + i * sizeof(u32), 0);
+ NIG_REG_LLH_FUNC_FILTER_EN_BB_K2 +
+ i * sizeof(u32), 0);
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
2 * i * sizeof(u32), 0);
ecore_wr(p_hwfn, p_ptt,
- NIG_REG_LLH_FUNC_FILTER_VALUE +
+ NIG_REG_LLH_FUNC_FILTER_VALUE_BB_K2 +
(2 * i + 1) * sizeof(u32), 0);
}
}
+void ecore_llh_clear_all_filters(struct ecore_hwfn *p_hwfn,
+ struct ecore_ptt *p_ptt)
+{
+ if (!(IS_MF_SI(p_hwfn) || IS_MF_DEFAULT(p_hwfn)))
+ return;
+
+ if (ECORE_IS_BB(p_hwfn->p_dev) || ECORE_IS_AH(p_hwfn->p_dev))
+ ecore_llh_clear_all_filters_bb_ah(p_hwfn, p_ptt);
+}
+
enum _ecore_status_t
ecore_llh_set_function_as_default(struct ecore_hwfn *p_hwfn,
struct ecore_ptt *p_ptt)
@@ -4396,7 +4538,7 @@ enum _ecore_status_t ecore_set_rxq_coalesce(struct ecore_hwfn *p_hwfn,
if (rc != ECORE_SUCCESS)
goto out;
- out:
+out:
return rc;
}
@@ -4434,7 +4576,7 @@ enum _ecore_status_t ecore_set_txq_coalesce(struct ecore_hwfn *p_hwfn,
rc = ecore_set_coalesce(p_hwfn, p_ptt, address, &eth_qzone,
sizeof(struct xstorm_eth_queue_zone), timeset);
- out:
+out:
return rc;
}