1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-19 10:53:58 +00:00

sfxge: rename hunt filter methods, types etc. to ef10 and use for Medford

New filters types may be added, but the same machinery should be able to
handle them.

Submitted by:   Mark Spender <mspender at solarflare.com>
Reviewed by:    gnn
Sponsored by:   Solarflare Communications, Inc.
MFC after:      2 days
Differential Revision: https://reviews.freebsd.org/D4881
This commit is contained in:
Andrew Rybchenko 2016-01-12 15:24:13 +00:00
parent 1fa702a261
commit 1289fe72c4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=293764
5 changed files with 251 additions and 234 deletions

View File

@ -97,17 +97,17 @@ static efx_filter_ops_t __efx_filter_siena_ops = {
};
#endif /* EFSYS_OPT_SIENA */
#if EFSYS_OPT_HUNTINGTON
static efx_filter_ops_t __efx_filter_hunt_ops = {
hunt_filter_init, /* efo_init */
hunt_filter_fini, /* efo_fini */
hunt_filter_restore, /* efo_restore */
hunt_filter_add, /* efo_add */
hunt_filter_delete, /* efo_delete */
hunt_filter_supported_filters, /* efo_supported_filters */
hunt_filter_reconfigure, /* efo_reconfigure */
#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
static efx_filter_ops_t __efx_filter_ef10_ops = {
ef10_filter_init, /* efo_init */
ef10_filter_fini, /* efo_fini */
ef10_filter_restore, /* efo_restore */
ef10_filter_add, /* efo_add */
ef10_filter_delete, /* efo_delete */
ef10_filter_supported_filters, /* efo_supported_filters */
ef10_filter_reconfigure, /* efo_reconfigure */
};
#endif /* EFSYS_OPT_HUNTINGTON */
#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
__checkReturn efx_rc_t
efx_filter_insert(
@ -189,10 +189,16 @@ efx_filter_init(
#if EFSYS_OPT_HUNTINGTON
case EFX_FAMILY_HUNTINGTON:
efop = (efx_filter_ops_t *)&__efx_filter_hunt_ops;
efop = (efx_filter_ops_t *)&__efx_filter_ef10_ops;
break;
#endif /* EFSYS_OPT_HUNTINGTON */
#if EFSYS_OPT_MEDFORD
case EFX_FAMILY_MEDFORD:
efop = (efx_filter_ops_t *)&__efx_filter_ef10_ops;
break;
#endif /* EFSYS_OPT_MEDFORD */
default:
EFSYS_ASSERT(0);
rc = ENOTSUP;

View File

@ -436,9 +436,9 @@ typedef struct efx_filter_s {
#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
falconsiena_filter_t *ef_falconsiena_filter;
#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
#if EFSYS_OPT_HUNTINGTON
hunt_filter_table_t *ef_hunt_filter_table;
#endif /* EFSYS_OPT_HUNTINGTON */
#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
ef10_filter_table_t *ef_ef10_filter_table;
#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
} efx_filter_t;
extern void

View File

@ -41,90 +41,91 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_FILTER
#define HFE_SPEC(hftp, index) ((hftp)->hft_entry[(index)].hfe_spec)
#define EFE_SPEC(eftp, index) ((eftp)->eft_entry[(index)].efe_spec)
static efx_filter_spec_t *
hunt_filter_entry_spec(
__in const hunt_filter_table_t *hftp,
ef10_filter_entry_spec(
__in const ef10_filter_table_t *eftp,
__in unsigned int index)
{
return ((efx_filter_spec_t *)(HFE_SPEC(hftp, index) &
~(uintptr_t)EFX_HUNT_FILTER_FLAGS));
return ((efx_filter_spec_t *)(EFE_SPEC(eftp, index) &
~(uintptr_t)EFX_EF10_FILTER_FLAGS));
}
static boolean_t
hunt_filter_entry_is_busy(
__in const hunt_filter_table_t *hftp,
ef10_filter_entry_is_busy(
__in const ef10_filter_table_t *eftp,
__in unsigned int index)
{
if (HFE_SPEC(hftp, index) & EFX_HUNT_FILTER_FLAG_BUSY)
if (EFE_SPEC(eftp, index) & EFX_EF10_FILTER_FLAG_BUSY)
return (B_TRUE);
else
return (B_FALSE);
}
static boolean_t
hunt_filter_entry_is_auto_old(
__in const hunt_filter_table_t *hftp,
ef10_filter_entry_is_auto_old(
__in const ef10_filter_table_t *eftp,
__in unsigned int index)
{
if (HFE_SPEC(hftp, index) & EFX_HUNT_FILTER_FLAG_AUTO_OLD)
if (EFE_SPEC(eftp, index) & EFX_EF10_FILTER_FLAG_AUTO_OLD)
return (B_TRUE);
else
return (B_FALSE);
}
static void
hunt_filter_set_entry(
__inout hunt_filter_table_t *hftp,
ef10_filter_set_entry(
__inout ef10_filter_table_t *eftp,
__in unsigned int index,
__in_opt const efx_filter_spec_t *efsp)
{
HFE_SPEC(hftp, index) = (uintptr_t)efsp;
EFE_SPEC(eftp, index) = (uintptr_t)efsp;
}
static void
hunt_filter_set_entry_busy(
__inout hunt_filter_table_t *hftp,
ef10_filter_set_entry_busy(
__inout ef10_filter_table_t *eftp,
__in unsigned int index)
{
HFE_SPEC(hftp, index) |= (uintptr_t)EFX_HUNT_FILTER_FLAG_BUSY;
EFE_SPEC(eftp, index) |= (uintptr_t)EFX_EF10_FILTER_FLAG_BUSY;
}
static void
hunt_filter_set_entry_not_busy(
__inout hunt_filter_table_t *hftp,
ef10_filter_set_entry_not_busy(
__inout ef10_filter_table_t *eftp,
__in unsigned int index)
{
HFE_SPEC(hftp, index) &= ~(uintptr_t)EFX_HUNT_FILTER_FLAG_BUSY;
EFE_SPEC(eftp, index) &= ~(uintptr_t)EFX_EF10_FILTER_FLAG_BUSY;
}
static void
hunt_filter_set_entry_auto_old(
__inout hunt_filter_table_t *hftp,
ef10_filter_set_entry_auto_old(
__inout ef10_filter_table_t *eftp,
__in unsigned int index)
{
EFSYS_ASSERT(hunt_filter_entry_spec(hftp, index) != NULL);
HFE_SPEC(hftp, index) |= (uintptr_t)EFX_HUNT_FILTER_FLAG_AUTO_OLD;
EFSYS_ASSERT(ef10_filter_entry_spec(eftp, index) != NULL);
EFE_SPEC(eftp, index) |= (uintptr_t)EFX_EF10_FILTER_FLAG_AUTO_OLD;
}
static void
hunt_filter_set_entry_not_auto_old(
__inout hunt_filter_table_t *hftp,
ef10_filter_set_entry_not_auto_old(
__inout ef10_filter_table_t *eftp,
__in unsigned int index)
{
HFE_SPEC(hftp, index) &= ~(uintptr_t)EFX_HUNT_FILTER_FLAG_AUTO_OLD;
EFSYS_ASSERT(hunt_filter_entry_spec(hftp, index) != NULL);
EFE_SPEC(eftp, index) &= ~(uintptr_t)EFX_EF10_FILTER_FLAG_AUTO_OLD;
EFSYS_ASSERT(ef10_filter_entry_spec(eftp, index) != NULL);
}
__checkReturn efx_rc_t
hunt_filter_init(
ef10_filter_init(
__in efx_nic_t *enp)
{
efx_rc_t rc;
hunt_filter_table_t *hftp;
ef10_filter_table_t *eftp;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD);
#define MATCH_MASK(match) (EFX_MASK32(match) << EFX_LOW_BIT(match))
EFX_STATIC_ASSERT(EFX_FILTER_MATCH_REM_HOST ==
@ -149,14 +150,14 @@ hunt_filter_init(
MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_IP_PROTO));
#undef MATCH_MASK
EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (hunt_filter_table_t), hftp);
EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (ef10_filter_table_t), eftp);
if (!hftp) {
if (!eftp) {
rc = ENOMEM;
goto fail1;
}
enp->en_filter.ef_hunt_filter_table = hftp;
enp->en_filter.ef_ef10_filter_table = eftp;
return (0);
@ -167,14 +168,15 @@ hunt_filter_init(
}
void
hunt_filter_fini(
ef10_filter_fini(
__in efx_nic_t *enp)
{
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD);
if (enp->en_filter.ef_hunt_filter_table != NULL) {
EFSYS_KMEM_FREE(enp->en_esip, sizeof (hunt_filter_table_t),
enp->en_filter.ef_hunt_filter_table);
if (enp->en_filter.ef_ef10_filter_table != NULL) {
EFSYS_KMEM_FREE(enp->en_esip, sizeof (ef10_filter_table_t),
enp->en_filter.ef_ef10_filter_table);
}
}
@ -183,7 +185,7 @@ efx_mcdi_filter_op_add(
__in efx_nic_t *enp,
__in efx_filter_spec_t *spec,
__in unsigned int filter_op,
__inout hunt_filter_handle_t *handle)
__inout ef10_filter_handle_t *handle)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_FILTER_OP_IN_LEN,
@ -201,9 +203,9 @@ efx_mcdi_filter_op_add(
switch (filter_op) {
case MC_CMD_FILTER_OP_IN_OP_REPLACE:
MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_LO,
handle->hfh_lo);
handle->efh_lo);
MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_HI,
handle->hfh_hi);
handle->efh_hi);
/* Fall through */
case MC_CMD_FILTER_OP_IN_OP_INSERT:
case MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE:
@ -302,8 +304,8 @@ efx_mcdi_filter_op_add(
goto fail3;
}
handle->hfh_lo = MCDI_OUT_DWORD(req, FILTER_OP_OUT_HANDLE_LO);
handle->hfh_hi = MCDI_OUT_DWORD(req, FILTER_OP_OUT_HANDLE_HI);
handle->efh_lo = MCDI_OUT_DWORD(req, FILTER_OP_OUT_HANDLE_LO);
handle->efh_hi = MCDI_OUT_DWORD(req, FILTER_OP_OUT_HANDLE_HI);
return (0);
@ -322,7 +324,7 @@ static __checkReturn efx_rc_t
efx_mcdi_filter_op_delete(
__in efx_nic_t *enp,
__in unsigned int filter_op,
__inout hunt_filter_handle_t *handle)
__inout ef10_filter_handle_t *handle)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_FILTER_OP_IN_LEN,
@ -351,8 +353,8 @@ efx_mcdi_filter_op_delete(
goto fail1;
}
MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_LO, handle->hfh_lo);
MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_HI, handle->hfh_hi);
MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_LO, handle->efh_lo);
MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_HI, handle->efh_hi);
efx_mcdi_execute(enp, &req);
@ -380,7 +382,7 @@ efx_mcdi_filter_op_delete(
}
static __checkReturn boolean_t
hunt_filter_equal(
ef10_filter_equal(
__in const efx_filter_spec_t *left,
__in const efx_filter_spec_t *right)
{
@ -413,7 +415,7 @@ hunt_filter_equal(
}
static __checkReturn boolean_t
hunt_filter_same_dest(
ef10_filter_same_dest(
__in const efx_filter_spec_t *left,
__in const efx_filter_spec_t *right)
{
@ -430,7 +432,7 @@ hunt_filter_same_dest(
}
static __checkReturn uint32_t
hunt_filter_hash(
ef10_filter_hash(
__in efx_filter_spec_t *spec)
{
EFX_STATIC_ASSERT((sizeof (efx_filter_spec_t) % sizeof (uint32_t))
@ -456,7 +458,7 @@ hunt_filter_hash(
* exclusive.
*/
static __checkReturn boolean_t
hunt_filter_is_exclusive(
ef10_filter_is_exclusive(
__in efx_filter_spec_t *spec)
{
if ((spec->efs_match_flags & EFX_FILTER_MATCH_LOC_MAC) &&
@ -478,30 +480,31 @@ hunt_filter_is_exclusive(
}
__checkReturn efx_rc_t
hunt_filter_restore(
ef10_filter_restore(
__in efx_nic_t *enp)
{
int tbl_id;
efx_filter_spec_t *spec;
hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
ef10_filter_table_t *eftp = enp->en_filter.ef_ef10_filter_table;
boolean_t restoring;
int state;
efx_rc_t rc;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD);
for (tbl_id = 0; tbl_id < EFX_HUNT_FILTER_TBL_ROWS; tbl_id++) {
for (tbl_id = 0; tbl_id < EFX_EF10_FILTER_TBL_ROWS; tbl_id++) {
EFSYS_LOCK(enp->en_eslp, state);
spec = hunt_filter_entry_spec(hftp, tbl_id);
spec = ef10_filter_entry_spec(eftp, tbl_id);
if (spec == NULL) {
restoring = B_FALSE;
} else if (hunt_filter_entry_is_busy(hftp, tbl_id)) {
} else if (ef10_filter_entry_is_busy(eftp, tbl_id)) {
/* Ignore busy entries. */
restoring = B_FALSE;
} else {
hunt_filter_set_entry_busy(hftp, tbl_id);
ef10_filter_set_entry_busy(eftp, tbl_id);
restoring = B_TRUE;
}
@ -510,14 +513,14 @@ hunt_filter_restore(
if (restoring == B_FALSE)
continue;
if (hunt_filter_is_exclusive(spec)) {
if (ef10_filter_is_exclusive(spec)) {
rc = efx_mcdi_filter_op_add(enp, spec,
MC_CMD_FILTER_OP_IN_OP_INSERT,
&hftp->hft_entry[tbl_id].hfe_handle);
&eftp->eft_entry[tbl_id].efe_handle);
} else {
rc = efx_mcdi_filter_op_add(enp, spec,
MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE,
&hftp->hft_entry[tbl_id].hfe_handle);
&eftp->eft_entry[tbl_id].efe_handle);
}
if (rc != 0)
@ -525,7 +528,7 @@ hunt_filter_restore(
EFSYS_LOCK(enp->en_eslp, state);
hunt_filter_set_entry_not_busy(hftp, tbl_id);
ef10_filter_set_entry_not_busy(eftp, tbl_id);
EFSYS_UNLOCK(enp->en_eslp, state);
}
@ -542,17 +545,17 @@ hunt_filter_restore(
* An arbitrary search limit for the software hash table. As per the linux net
* driver.
*/
#define EFX_HUNT_FILTER_SEARCH_LIMIT 200
#define EF10_FILTER_SEARCH_LIMIT 200
static __checkReturn efx_rc_t
hunt_filter_add_internal(
ef10_filter_add_internal(
__in efx_nic_t *enp,
__inout efx_filter_spec_t *spec,
__in boolean_t may_replace,
__out_opt uint32_t *filter_id)
{
efx_rc_t rc;
hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
ef10_filter_table_t *eftp = enp->en_filter.ef_ef10_filter_table;
efx_filter_spec_t *saved_spec;
uint32_t hash;
unsigned int depth;
@ -562,13 +565,14 @@ hunt_filter_add_internal(
int state;
boolean_t locked = B_FALSE;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD);
#if EFSYS_OPT_RX_SCALE
spec->efs_rss_context = enp->en_rss_context;
#endif
hash = hunt_filter_hash(spec);
hash = ef10_filter_hash(spec);
/*
* FIXME: Add support for inserting filters of different priorities
@ -587,21 +591,21 @@ hunt_filter_add_internal(
locked = B_TRUE;
for (;;) {
i = (hash + depth) & (EFX_HUNT_FILTER_TBL_ROWS - 1);
saved_spec = hunt_filter_entry_spec(hftp, i);
i = (hash + depth) & (EFX_EF10_FILTER_TBL_ROWS - 1);
saved_spec = ef10_filter_entry_spec(eftp, i);
if (!saved_spec) {
if (ins_index < 0) {
ins_index = i;
}
} else if (hunt_filter_equal(spec, saved_spec)) {
if (hunt_filter_entry_is_busy(hftp, i))
} else if (ef10_filter_equal(spec, saved_spec)) {
if (ef10_filter_entry_is_busy(eftp, i))
break;
if (saved_spec->efs_priority
== EFX_FILTER_PRI_AUTO) {
ins_index = i;
goto found;
} else if (hunt_filter_is_exclusive(spec)) {
} else if (ef10_filter_is_exclusive(spec)) {
if (may_replace) {
ins_index = i;
goto found;
@ -619,7 +623,7 @@ hunt_filter_add_internal(
* the first suitable slot or return EBUSY if
* there was none.
*/
if (depth == EFX_HUNT_FILTER_SEARCH_LIMIT) {
if (depth == EF10_FILTER_SEARCH_LIMIT) {
if (ins_index < 0) {
rc = EBUSY;
goto fail2;
@ -639,11 +643,11 @@ hunt_filter_add_internal(
* insert a conflicting filter while we're waiting for the
* firmware must find the busy entry.
*/
saved_spec = hunt_filter_entry_spec(hftp, ins_index);
saved_spec = ef10_filter_entry_spec(eftp, ins_index);
if (saved_spec) {
if (saved_spec->efs_priority == EFX_FILTER_PRI_AUTO) {
/* This is a filter we are refreshing */
hunt_filter_set_entry_not_auto_old(hftp, ins_index);
ef10_filter_set_entry_not_auto_old(eftp, ins_index);
goto out_unlock;
}
@ -655,9 +659,9 @@ hunt_filter_add_internal(
goto fail3;
}
*saved_spec = *spec;
hunt_filter_set_entry(hftp, ins_index, saved_spec);
ef10_filter_set_entry(eftp, ins_index, saved_spec);
}
hunt_filter_set_entry_busy(hftp, ins_index);
ef10_filter_set_entry_busy(eftp, ins_index);
EFSYS_UNLOCK(enp->en_eslp, state);
locked = B_FALSE;
@ -669,15 +673,15 @@ hunt_filter_add_internal(
if (replacing) {
rc = efx_mcdi_filter_op_add(enp, spec,
MC_CMD_FILTER_OP_IN_OP_REPLACE,
&hftp->hft_entry[ins_index].hfe_handle);
} else if (hunt_filter_is_exclusive(spec)) {
&eftp->eft_entry[ins_index].efe_handle);
} else if (ef10_filter_is_exclusive(spec)) {
rc = efx_mcdi_filter_op_add(enp, spec,
MC_CMD_FILTER_OP_IN_OP_INSERT,
&hftp->hft_entry[ins_index].hfe_handle);
&eftp->eft_entry[ins_index].efe_handle);
} else {
rc = efx_mcdi_filter_op_add(enp, spec,
MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE,
&hftp->hft_entry[ins_index].hfe_handle);
&eftp->eft_entry[ins_index].efe_handle);
}
if (rc != 0)
@ -694,7 +698,7 @@ hunt_filter_add_internal(
saved_spec->efs_dmaq_id = spec->efs_dmaq_id;
}
hunt_filter_set_entry_not_busy(hftp, ins_index);
ef10_filter_set_entry_not_busy(eftp, ins_index);
out_unlock:
@ -713,8 +717,8 @@ hunt_filter_add_internal(
EFSYS_KMEM_FREE(enp->en_esip, sizeof (*spec), saved_spec);
saved_spec = NULL;
}
hunt_filter_set_entry_not_busy(hftp, ins_index);
hunt_filter_set_entry(hftp, ins_index, NULL);
ef10_filter_set_entry_not_busy(eftp, ins_index);
ef10_filter_set_entry(eftp, ins_index, NULL);
fail3:
EFSYS_PROBE(fail3);
@ -732,14 +736,14 @@ hunt_filter_add_internal(
}
__checkReturn efx_rc_t
hunt_filter_add(
ef10_filter_add(
__in efx_nic_t *enp,
__inout efx_filter_spec_t *spec,
__in boolean_t may_replace)
{
efx_rc_t rc;
rc = hunt_filter_add_internal(enp, spec, may_replace, NULL);
rc = ef10_filter_add_internal(enp, spec, may_replace, NULL);
if (rc != 0)
goto fail1;
@ -753,15 +757,15 @@ hunt_filter_add(
static __checkReturn efx_rc_t
hunt_filter_delete_internal(
ef10_filter_delete_internal(
__in efx_nic_t *enp,
__in uint32_t filter_id)
{
efx_rc_t rc;
hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table;
efx_filter_spec_t *spec;
int state;
uint32_t filter_idx = filter_id % EFX_HUNT_FILTER_TBL_ROWS;
uint32_t filter_idx = filter_id % EFX_EF10_FILTER_TBL_ROWS;
/*
* Find the software table entry and mark it busy. Don't
@ -771,13 +775,13 @@ hunt_filter_delete_internal(
* FIXME: What if the busy flag is never cleared?
*/
EFSYS_LOCK(enp->en_eslp, state);
while (hunt_filter_entry_is_busy(table, filter_idx)) {
while (ef10_filter_entry_is_busy(table, filter_idx)) {
EFSYS_UNLOCK(enp->en_eslp, state);
EFSYS_SPIN(1);
EFSYS_LOCK(enp->en_eslp, state);
}
if ((spec = hunt_filter_entry_spec(table, filter_idx)) != NULL) {
hunt_filter_set_entry_busy(table, filter_idx);
if ((spec = ef10_filter_entry_spec(table, filter_idx)) != NULL) {
ef10_filter_set_entry_busy(table, filter_idx);
}
EFSYS_UNLOCK(enp->en_eslp, state);
@ -790,20 +794,20 @@ hunt_filter_delete_internal(
* Try to remove the hardware filter. This may fail if the MC has
* rebooted (which frees all hardware filter resources).
*/
if (hunt_filter_is_exclusive(spec)) {
if (ef10_filter_is_exclusive(spec)) {
rc = efx_mcdi_filter_op_delete(enp,
MC_CMD_FILTER_OP_IN_OP_REMOVE,
&table->hft_entry[filter_idx].hfe_handle);
&table->eft_entry[filter_idx].efe_handle);
} else {
rc = efx_mcdi_filter_op_delete(enp,
MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE,
&table->hft_entry[filter_idx].hfe_handle);
&table->eft_entry[filter_idx].efe_handle);
}
/* Free the software table entry */
EFSYS_LOCK(enp->en_eslp, state);
hunt_filter_set_entry_not_busy(table, filter_idx);
hunt_filter_set_entry(table, filter_idx, NULL);
ef10_filter_set_entry_not_busy(table, filter_idx);
ef10_filter_set_entry(table, filter_idx, NULL);
EFSYS_UNLOCK(enp->en_eslp, state);
EFSYS_KMEM_FREE(enp->en_esip, sizeof (*spec), spec);
@ -824,12 +828,12 @@ hunt_filter_delete_internal(
}
__checkReturn efx_rc_t
hunt_filter_delete(
ef10_filter_delete(
__in efx_nic_t *enp,
__inout efx_filter_spec_t *spec)
{
efx_rc_t rc;
hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table;
efx_filter_spec_t *saved_spec;
unsigned int hash;
unsigned int depth;
@ -837,22 +841,23 @@ hunt_filter_delete(
int state;
boolean_t locked = B_FALSE;
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
enp->en_family == EFX_FAMILY_MEDFORD);
hash = hunt_filter_hash(spec);
hash = ef10_filter_hash(spec);
EFSYS_LOCK(enp->en_eslp, state);
locked = B_TRUE;
depth = 1;
for (;;) {
i = (hash + depth) & (EFX_HUNT_FILTER_TBL_ROWS - 1);
saved_spec = hunt_filter_entry_spec(table, i);
if (saved_spec && hunt_filter_equal(spec, saved_spec) &&
hunt_filter_same_dest(spec, saved_spec)) {
i = (hash + depth) & (EFX_EF10_FILTER_TBL_ROWS - 1);
saved_spec = ef10_filter_entry_spec(table, i);
if (saved_spec && ef10_filter_equal(spec, saved_spec) &&
ef10_filter_same_dest(spec, saved_spec)) {
break;
}
if (depth == EFX_HUNT_FILTER_SEARCH_LIMIT) {
if (depth == EF10_FILTER_SEARCH_LIMIT) {
rc = ENOENT;
goto fail1;
}
@ -862,7 +867,7 @@ hunt_filter_delete(
EFSYS_UNLOCK(enp->en_eslp, state);
locked = B_FALSE;
rc = hunt_filter_delete_internal(enp, i);
rc = ef10_filter_delete_internal(enp, i);
if (rc != 0)
goto fail2;
@ -961,7 +966,7 @@ efx_mcdi_get_parser_disp_info(
}
__checkReturn efx_rc_t
hunt_filter_supported_filters(
ef10_filter_supported_filters(
__in efx_nic_t *enp,
__out uint32_t *list,
__out size_t *length)
@ -980,13 +985,13 @@ hunt_filter_supported_filters(
}
static __checkReturn efx_rc_t
hunt_filter_unicast_refresh(
ef10_filter_unicast_refresh(
__in efx_nic_t *enp,
__in_ecount(6) uint8_t const *addr,
__in boolean_t all_unicst,
__in efx_filter_flag_t filter_flags)
{
hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
ef10_filter_table_t *eftp = enp->en_filter.ef_ef10_filter_table;
efx_filter_spec_t spec;
efx_rc_t rc;
@ -996,11 +1001,11 @@ hunt_filter_unicast_refresh(
/* Insert the filter for the local station address */
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
hftp->hft_default_rxq);
eftp->eft_default_rxq);
efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC, addr);
rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
&hftp->hft_unicst_filter_index);
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_unicst_filter_index);
if (rc != 0) {
/*
* Fall back to an unknown filter. We may be able to subscribe
@ -1008,7 +1013,7 @@ hunt_filter_unicast_refresh(
*/
goto use_uc_def;
}
hftp->hft_unicst_filter_set = B_TRUE;
eftp->eft_unicst_filter_set = B_TRUE;
return (0);
@ -1016,32 +1021,32 @@ hunt_filter_unicast_refresh(
/* Insert the unknown unicast filter */
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
hftp->hft_default_rxq);
eftp->eft_default_rxq);
efx_filter_spec_set_uc_def(&spec);
rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
&hftp->hft_unicst_filter_index);
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_unicst_filter_index);
if (rc != 0)
goto fail1;
hftp->hft_unicst_filter_set = B_TRUE;
eftp->eft_unicst_filter_set = B_TRUE;
return (0);
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
if (hftp->hft_unicst_filter_set != B_FALSE) {
(void) hunt_filter_delete_internal(enp,
hftp->hft_unicst_filter_index);
if (eftp->eft_unicst_filter_set != B_FALSE) {
(void) ef10_filter_delete_internal(enp,
eftp->eft_unicst_filter_index);
hftp->hft_unicst_filter_set = B_FALSE;
eftp->eft_unicst_filter_set = B_FALSE;
}
return (rc);
}
static __checkReturn efx_rc_t
hunt_filter_multicast_refresh(
ef10_filter_multicast_refresh(
__in efx_nic_t *enp,
__in boolean_t mulcst,
__in boolean_t all_mulcst,
@ -1050,7 +1055,7 @@ hunt_filter_multicast_refresh(
__in int count,
__in efx_filter_flag_t filter_flags)
{
hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
ef10_filter_table_t *eftp = enp->en_filter.ef_ef10_filter_table;
efx_filter_spec_t spec;
uint8_t addr[6];
unsigned i;
@ -1063,25 +1068,25 @@ hunt_filter_multicast_refresh(
count = 0;
if (count + (brdcst ? 1 : 0) >
EFX_ARRAY_SIZE(hftp->hft_mulcst_filter_indexes)) {
EFX_ARRAY_SIZE(eftp->eft_mulcst_filter_indexes)) {
/* Too many MAC addresses; use unknown multicast filter */
goto use_mc_def;
}
/* Insert/renew multicast address list filters */
hftp->hft_mulcst_filter_count = count;
for (i = 0; i < hftp->hft_mulcst_filter_count; i++) {
eftp->eft_mulcst_filter_count = count;
for (i = 0; i < eftp->eft_mulcst_filter_count; i++) {
efx_filter_spec_init_rx(&spec,
EFX_FILTER_PRI_AUTO,
filter_flags,
hftp->hft_default_rxq);
eftp->eft_default_rxq);
efx_filter_spec_set_eth_local(&spec,
EFX_FILTER_SPEC_VID_UNSPEC,
&addrs[i * EFX_MAC_ADDR_LEN]);
rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
&hftp->hft_mulcst_filter_indexes[i]);
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_mulcst_filter_indexes[i]);
if (rc != 0) {
/* Rollback, then use unknown multicast filter */
goto rollback;
@ -1090,18 +1095,18 @@ hunt_filter_multicast_refresh(
if (brdcst == B_TRUE) {
/* Insert/renew broadcast address filter */
hftp->hft_mulcst_filter_count++;
eftp->eft_mulcst_filter_count++;
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
hftp->hft_default_rxq);
eftp->eft_default_rxq);
EFX_MAC_BROADCAST_ADDR_SET(addr);
efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC,
addr);
rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
&hftp->hft_mulcst_filter_indexes[
hftp->hft_mulcst_filter_count - 1]);
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_mulcst_filter_indexes[
eftp->eft_mulcst_filter_count - 1]);
if (rc != 0) {
/* Rollback, then use unknown multicast filter */
goto rollback;
@ -1116,24 +1121,24 @@ hunt_filter_multicast_refresh(
* before inserting the unknown multicast filter.
*/
while (i--) {
(void) hunt_filter_delete_internal(enp,
hftp->hft_mulcst_filter_indexes[i]);
(void) ef10_filter_delete_internal(enp,
eftp->eft_mulcst_filter_indexes[i]);
}
hftp->hft_mulcst_filter_count = 0;
eftp->eft_mulcst_filter_count = 0;
use_mc_def:
/* Insert the unknown multicast filter */
efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
filter_flags,
hftp->hft_default_rxq);
eftp->eft_default_rxq);
efx_filter_spec_set_mc_def(&spec);
rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
&hftp->hft_mulcst_filter_indexes[0]);
rc = ef10_filter_add_internal(enp, &spec, B_TRUE,
&eftp->eft_mulcst_filter_indexes[0]);
if (rc != 0)
goto fail1;
hftp->hft_mulcst_filter_count = 1;
eftp->eft_mulcst_filter_count = 1;
/*
* FIXME: If brdcst == B_FALSE, add a filter to drop broadcast traffic.
@ -1192,7 +1197,7 @@ hunt_filter_get_workarounds(
* still applied in this case).
*/
__checkReturn efx_rc_t
hunt_filter_reconfigure(
ef10_filter_reconfigure(
__in efx_nic_t *enp,
__in_ecount(6) uint8_t const *mac_addr,
__in boolean_t all_unicst,
@ -1202,58 +1207,58 @@ hunt_filter_reconfigure(
__in_ecount(6*count) uint8_t const *addrs,
__in int count)
{
hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table;
efx_filter_flag_t filter_flags;
unsigned i;
int all_unicst_rc;
int all_mulcst_rc;
efx_rc_t rc;
if (table->hft_default_rxq == NULL) {
if (table->eft_default_rxq == NULL) {
/*
* Filters direct traffic to the default RXQ, and so cannot be
* inserted until it is available. Any currently configured
* filters must be removed (ignore errors in case the MC
* has rebooted, which removes hardware filters).
*/
if (table->hft_unicst_filter_set != B_FALSE) {
(void) hunt_filter_delete_internal(enp,
table->hft_unicst_filter_index);
table->hft_unicst_filter_set = B_FALSE;
if (table->eft_unicst_filter_set != B_FALSE) {
(void) ef10_filter_delete_internal(enp,
table->eft_unicst_filter_index);
table->eft_unicst_filter_set = B_FALSE;
}
for (i = 0; i < table->hft_mulcst_filter_count; i++) {
(void) hunt_filter_delete_internal(enp,
table->hft_mulcst_filter_indexes[i]);
for (i = 0; i < table->eft_mulcst_filter_count; i++) {
(void) ef10_filter_delete_internal(enp,
table->eft_mulcst_filter_indexes[i]);
}
table->hft_mulcst_filter_count = 0;
table->eft_mulcst_filter_count = 0;
return (0);
}
if (table->hft_using_rss)
if (table->eft_using_rss)
filter_flags = EFX_FILTER_FLAG_RX_RSS;
else
filter_flags = 0;
/* Mark old filters which may need to be removed */
if (table->hft_unicst_filter_set != B_FALSE) {
hunt_filter_set_entry_auto_old(table,
table->hft_unicst_filter_index);
if (table->eft_unicst_filter_set != B_FALSE) {
ef10_filter_set_entry_auto_old(table,
table->eft_unicst_filter_index);
}
for (i = 0; i < table->hft_mulcst_filter_count; i++) {
hunt_filter_set_entry_auto_old(table,
table->hft_mulcst_filter_indexes[i]);
for (i = 0; i < table->eft_mulcst_filter_count; i++) {
ef10_filter_set_entry_auto_old(table,
table->eft_mulcst_filter_indexes[i]);
}
/* Insert or renew unicast filters */
if ((all_unicst_rc = hunt_filter_unicast_refresh(enp, mac_addr,
if ((all_unicst_rc = ef10_filter_unicast_refresh(enp, mac_addr,
all_unicst, filter_flags)) != 0) {
if (all_unicst == B_FALSE) {
rc = all_unicst_rc;
goto fail1;
}
/* Retry without all_unicast flag */
rc = hunt_filter_unicast_refresh(enp, mac_addr,
rc = ef10_filter_unicast_refresh(enp, mac_addr,
B_FALSE, filter_flags);
if (rc != 0)
goto fail2;
@ -1272,12 +1277,14 @@ hunt_filter_reconfigure(
* filters. This ensures that encp->enc_workaround_bug26807 matches the
* firmware state, and that later changes to enable/disable the
* workaround will result in this function seeing a reset (FLR).
*
* FIXME: On Medford mulicast chaining should always be on.
*/
if ((rc = hunt_filter_get_workarounds(enp)) != 0)
goto fail3;
/* Insert or renew multicast filters */
if ((all_mulcst_rc = hunt_filter_multicast_refresh(enp, mulcst,
if ((all_mulcst_rc = ef10_filter_multicast_refresh(enp, mulcst,
all_mulcst, brdcst,
addrs, count, filter_flags)) != 0) {
if (all_mulcst == B_FALSE) {
@ -1285,7 +1292,7 @@ hunt_filter_reconfigure(
goto fail4;
}
/* Retry without all_mulcast flag */
rc = hunt_filter_multicast_refresh(enp, mulcst,
rc = ef10_filter_multicast_refresh(enp, mulcst,
B_FALSE, brdcst,
addrs, count, filter_flags);
if (rc != 0)
@ -1293,9 +1300,9 @@ hunt_filter_reconfigure(
}
/* Remove old filters which were not renewed */
for (i = 0; i < EFX_ARRAY_SIZE(table->hft_entry); i++) {
if (hunt_filter_entry_is_auto_old(table, i)) {
(void) hunt_filter_delete_internal(enp, i);
for (i = 0; i < EFX_ARRAY_SIZE(table->eft_entry); i++) {
if (ef10_filter_entry_is_auto_old(table, i)) {
(void) ef10_filter_delete_internal(enp, i);
}
}
@ -1319,9 +1326,9 @@ hunt_filter_reconfigure(
EFSYS_PROBE1(fail1, efx_rc_t, rc);
/* Clear auto old flags */
for (i = 0; i < EFX_ARRAY_SIZE(table->hft_entry); i++) {
if (hunt_filter_entry_is_auto_old(table, i)) {
hunt_filter_set_entry_not_auto_old(table, i);
for (i = 0; i < EFX_ARRAY_SIZE(table->eft_entry); i++) {
if (ef10_filter_entry_is_auto_old(table, i)) {
ef10_filter_set_entry_not_auto_old(table, i);
}
}
@ -1329,45 +1336,45 @@ hunt_filter_reconfigure(
}
void
hunt_filter_get_default_rxq(
ef10_filter_get_default_rxq(
__in efx_nic_t *enp,
__out efx_rxq_t **erpp,
__out boolean_t *using_rss)
{
hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table;
*erpp = table->hft_default_rxq;
*using_rss = table->hft_using_rss;
*erpp = table->eft_default_rxq;
*using_rss = table->eft_using_rss;
}
void
hunt_filter_default_rxq_set(
ef10_filter_default_rxq_set(
__in efx_nic_t *enp,
__in efx_rxq_t *erp,
__in boolean_t using_rss)
{
hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table;
#if EFSYS_OPT_RX_SCALE
EFSYS_ASSERT((using_rss == B_FALSE) ||
(enp->en_rss_context != EF10_RSS_CONTEXT_INVALID));
table->hft_using_rss = using_rss;
table->eft_using_rss = using_rss;
#else
EFSYS_ASSERT(using_rss == B_FALSE);
table->hft_using_rss = B_FALSE;
table->eft_using_rss = B_FALSE;
#endif
table->hft_default_rxq = erp;
table->eft_default_rxq = erp;
}
void
hunt_filter_default_rxq_clear(
ef10_filter_default_rxq_clear(
__in efx_nic_t *enp)
{
hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
ef10_filter_table_t *table = enp->en_filter.ef_ef10_filter_table;
table->hft_default_rxq = NULL;
table->hft_using_rss = B_FALSE;
table->eft_default_rxq = NULL;
table->eft_using_rss = B_FALSE;
}

View File

@ -914,71 +914,75 @@ ef10_rx_fini(
#if EFSYS_OPT_FILTER
typedef struct hunt_filter_handle_s {
uint32_t hfh_lo;
uint32_t hfh_hi;
} hunt_filter_handle_t;
typedef struct ef10_filter_handle_s {
uint32_t efh_lo;
uint32_t efh_hi;
} ef10_filter_handle_t;
typedef struct hunt_filter_entry_s {
uintptr_t hfe_spec; /* pointer to filter spec plus busy bit */
hunt_filter_handle_t hfe_handle;
} hunt_filter_entry_t;
typedef struct ef10_filter_entry_s {
uintptr_t efe_spec; /* pointer to filter spec plus busy bit */
ef10_filter_handle_t efe_handle;
} ef10_filter_entry_t;
/*
* BUSY flag indicates that an update is in progress.
* AUTO_OLD flag is used to mark and sweep MAC packet filters.
*/
#define EFX_HUNT_FILTER_FLAG_BUSY 1U
#define EFX_HUNT_FILTER_FLAG_AUTO_OLD 2U
#define EFX_HUNT_FILTER_FLAGS 3U
#define EFX_EF10_FILTER_FLAG_BUSY 1U
#define EFX_EF10_FILTER_FLAG_AUTO_OLD 2U
#define EFX_EF10_FILTER_FLAGS 3U
#define EFX_HUNT_FILTER_TBL_ROWS 8192
/*
* Size of the hash table used by the driver. Doesn't need to be the
* same size as the hardware's table.
*/
#define EFX_EF10_FILTER_TBL_ROWS 8192
/* Allow for the broadcast address to be added to the multicast list */
#define EFX_HUNT_FILTER_MULTICAST_FILTERS_MAX (EFX_MAC_MULTICAST_LIST_MAX + 1)
#define EFX_EF10_FILTER_MULTICAST_FILTERS_MAX (EFX_MAC_MULTICAST_LIST_MAX + 1)
typedef struct hunt_filter_table_s {
hunt_filter_entry_t hft_entry[EFX_HUNT_FILTER_TBL_ROWS];
efx_rxq_t * hft_default_rxq;
boolean_t hft_using_rss;
uint32_t hft_unicst_filter_index;
boolean_t hft_unicst_filter_set;
uint32_t hft_mulcst_filter_indexes[
EFX_HUNT_FILTER_MULTICAST_FILTERS_MAX];
uint32_t hft_mulcst_filter_count;
} hunt_filter_table_t;
typedef struct ef10_filter_table_s {
ef10_filter_entry_t eft_entry[EFX_EF10_FILTER_TBL_ROWS];
efx_rxq_t * eft_default_rxq;
boolean_t eft_using_rss;
uint32_t eft_unicst_filter_index;
boolean_t eft_unicst_filter_set;
uint32_t eft_mulcst_filter_indexes[
EFX_EF10_FILTER_MULTICAST_FILTERS_MAX];
uint32_t eft_mulcst_filter_count;
} ef10_filter_table_t;
__checkReturn efx_rc_t
hunt_filter_init(
ef10_filter_init(
__in efx_nic_t *enp);
void
hunt_filter_fini(
ef10_filter_fini(
__in efx_nic_t *enp);
__checkReturn efx_rc_t
hunt_filter_restore(
ef10_filter_restore(
__in efx_nic_t *enp);
__checkReturn efx_rc_t
hunt_filter_add(
ef10_filter_add(
__in efx_nic_t *enp,
__inout efx_filter_spec_t *spec,
__in boolean_t may_replace);
__checkReturn efx_rc_t
hunt_filter_delete(
ef10_filter_delete(
__in efx_nic_t *enp,
__inout efx_filter_spec_t *spec);
extern __checkReturn efx_rc_t
hunt_filter_supported_filters(
ef10_filter_supported_filters(
__in efx_nic_t *enp,
__out uint32_t *list,
__out size_t *length);
extern __checkReturn efx_rc_t
hunt_filter_reconfigure(
ef10_filter_reconfigure(
__in efx_nic_t *enp,
__in_ecount(6) uint8_t const *mac_addr,
__in boolean_t all_unicst,
@ -989,19 +993,19 @@ hunt_filter_reconfigure(
__in int count);
extern void
hunt_filter_get_default_rxq(
ef10_filter_get_default_rxq(
__in efx_nic_t *enp,
__out efx_rxq_t **erpp,
__out boolean_t *using_rss);
extern void
hunt_filter_default_rxq_set(
ef10_filter_default_rxq_set(
__in efx_nic_t *enp,
__in efx_rxq_t *erp,
__in boolean_t using_rss);
extern void
hunt_filter_default_rxq_clear(
ef10_filter_default_rxq_clear(
__in efx_nic_t *enp);

View File

@ -281,9 +281,9 @@ hunt_mac_filter_default_rxq_set(
boolean_t old_using_rss;
efx_rc_t rc;
hunt_filter_get_default_rxq(enp, &old_rxq, &old_using_rss);
ef10_filter_get_default_rxq(enp, &old_rxq, &old_using_rss);
hunt_filter_default_rxq_set(enp, erp, using_rss);
ef10_filter_default_rxq_set(enp, erp, using_rss);
rc = efx_filter_reconfigure(enp, epp->ep_mac_addr,
epp->ep_all_unicst, epp->ep_mulcst,
@ -299,7 +299,7 @@ hunt_mac_filter_default_rxq_set(
fail1:
EFSYS_PROBE1(fail1, efx_rc_t, rc);
hunt_filter_default_rxq_set(enp, old_rxq, old_using_rss);
ef10_filter_default_rxq_set(enp, old_rxq, old_using_rss);
return (rc);
}
@ -310,7 +310,7 @@ hunt_mac_filter_default_rxq_clear(
{
efx_port_t *epp = &(enp->en_port);
hunt_filter_default_rxq_clear(enp);
ef10_filter_default_rxq_clear(enp);
efx_filter_reconfigure(enp, epp->ep_mac_addr,
epp->ep_all_unicst, epp->ep_mulcst,