Commit d3d5df2c authored by David S. Miller's avatar David S. Miller

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc-next

Ben Hutchings says:

====================
Some bug fixes that should go into 3.7:

1. Fix oops when removing device with SR-IOV enabled.  (This regression
was introduced by the last set of changes, so the fix does not need to
be applied to any earlier kernel versions.)
2. Fix firmware structure field lookup bug that resulted in missing
sensor information.
3. Fix bug that makes self-test do very little in some configurations.
4. Fix the numbering of ethtool RX flow steering filters to reflect the
real hardware priorities.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d342894c 6ac7ef14
...@@ -120,10 +120,10 @@ typedef union efx_oword { ...@@ -120,10 +120,10 @@ typedef union efx_oword {
* [0,high-low), with garbage in bits [high-low+1,...). * [0,high-low), with garbage in bits [high-low+1,...).
*/ */
#define EFX_EXTRACT_NATIVE(native_element, min, max, low, high) \ #define EFX_EXTRACT_NATIVE(native_element, min, max, low, high) \
(((low > max) || (high < min)) ? 0 : \ ((low) > (max) || (high) < (min) ? 0 : \
((low > min) ? \ (low) > (min) ? \
((native_element) >> (low - min)) : \ (native_element) >> ((low) - (min)) : \
((native_element) << (min - low)))) (native_element) << ((min) - (low)))
/* /*
* Extract bit field portion [low,high) from the 64-bit little-endian * Extract bit field portion [low,high) from the 64-bit little-endian
...@@ -142,27 +142,27 @@ typedef union efx_oword { ...@@ -142,27 +142,27 @@ typedef union efx_oword {
#define EFX_EXTRACT_OWORD64(oword, low, high) \ #define EFX_EXTRACT_OWORD64(oword, low, high) \
((EFX_EXTRACT64((oword).u64[0], 0, 63, low, high) | \ ((EFX_EXTRACT64((oword).u64[0], 0, 63, low, high) | \
EFX_EXTRACT64((oword).u64[1], 64, 127, low, high)) & \ EFX_EXTRACT64((oword).u64[1], 64, 127, low, high)) & \
EFX_MASK64(high + 1 - low)) EFX_MASK64((high) + 1 - (low)))
#define EFX_EXTRACT_QWORD64(qword, low, high) \ #define EFX_EXTRACT_QWORD64(qword, low, high) \
(EFX_EXTRACT64((qword).u64[0], 0, 63, low, high) & \ (EFX_EXTRACT64((qword).u64[0], 0, 63, low, high) & \
EFX_MASK64(high + 1 - low)) EFX_MASK64((high) + 1 - (low)))
#define EFX_EXTRACT_OWORD32(oword, low, high) \ #define EFX_EXTRACT_OWORD32(oword, low, high) \
((EFX_EXTRACT32((oword).u32[0], 0, 31, low, high) | \ ((EFX_EXTRACT32((oword).u32[0], 0, 31, low, high) | \
EFX_EXTRACT32((oword).u32[1], 32, 63, low, high) | \ EFX_EXTRACT32((oword).u32[1], 32, 63, low, high) | \
EFX_EXTRACT32((oword).u32[2], 64, 95, low, high) | \ EFX_EXTRACT32((oword).u32[2], 64, 95, low, high) | \
EFX_EXTRACT32((oword).u32[3], 96, 127, low, high)) & \ EFX_EXTRACT32((oword).u32[3], 96, 127, low, high)) & \
EFX_MASK32(high + 1 - low)) EFX_MASK32((high) + 1 - (low)))
#define EFX_EXTRACT_QWORD32(qword, low, high) \ #define EFX_EXTRACT_QWORD32(qword, low, high) \
((EFX_EXTRACT32((qword).u32[0], 0, 31, low, high) | \ ((EFX_EXTRACT32((qword).u32[0], 0, 31, low, high) | \
EFX_EXTRACT32((qword).u32[1], 32, 63, low, high)) & \ EFX_EXTRACT32((qword).u32[1], 32, 63, low, high)) & \
EFX_MASK32(high + 1 - low)) EFX_MASK32((high) + 1 - (low)))
#define EFX_EXTRACT_DWORD(dword, low, high) \ #define EFX_EXTRACT_DWORD(dword, low, high) \
(EFX_EXTRACT32((dword).u32[0], 0, 31, low, high) & \ (EFX_EXTRACT32((dword).u32[0], 0, 31, low, high) & \
EFX_MASK32(high + 1 - low)) EFX_MASK32((high) + 1 - (low)))
#define EFX_OWORD_FIELD64(oword, field) \ #define EFX_OWORD_FIELD64(oword, field) \
EFX_EXTRACT_OWORD64(oword, EFX_LOW_BIT(field), \ EFX_EXTRACT_OWORD64(oword, EFX_LOW_BIT(field), \
...@@ -442,10 +442,10 @@ typedef union efx_oword { ...@@ -442,10 +442,10 @@ typedef union efx_oword {
cpu_to_le32(EFX_INSERT_NATIVE(min, max, low, high, value)) cpu_to_le32(EFX_INSERT_NATIVE(min, max, low, high, value))
#define EFX_INPLACE_MASK64(min, max, low, high) \ #define EFX_INPLACE_MASK64(min, max, low, high) \
EFX_INSERT64(min, max, low, high, EFX_MASK64(high + 1 - low)) EFX_INSERT64(min, max, low, high, EFX_MASK64((high) + 1 - (low)))
#define EFX_INPLACE_MASK32(min, max, low, high) \ #define EFX_INPLACE_MASK32(min, max, low, high) \
EFX_INSERT32(min, max, low, high, EFX_MASK32(high + 1 - low)) EFX_INSERT32(min, max, low, high, EFX_MASK32((high) + 1 - (low)))
#define EFX_SET_OWORD64(oword, low, high, value) do { \ #define EFX_SET_OWORD64(oword, low, high, value) do { \
(oword).u64[0] = (((oword).u64[0] \ (oword).u64[0] = (((oword).u64[0] \
......
...@@ -337,7 +337,8 @@ static int efx_fill_loopback_test(struct efx_nic *efx, ...@@ -337,7 +337,8 @@ static int efx_fill_loopback_test(struct efx_nic *efx,
unsigned int test_index, unsigned int test_index,
struct ethtool_string *strings, u64 *data) struct ethtool_string *strings, u64 *data)
{ {
struct efx_channel *channel = efx_get_channel(efx, 0); struct efx_channel *channel =
efx_get_channel(efx, efx->tx_channel_offset);
struct efx_tx_queue *tx_queue; struct efx_tx_queue *tx_queue;
efx_for_each_channel_tx_queue(tx_queue, channel) { efx_for_each_channel_tx_queue(tx_queue, channel) {
...@@ -960,9 +961,7 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx, ...@@ -960,9 +961,7 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx,
int rc; int rc;
/* Check that user wants us to choose the location */ /* Check that user wants us to choose the location */
if (rule->location != RX_CLS_LOC_ANY && if (rule->location != RX_CLS_LOC_ANY)
rule->location != RX_CLS_LOC_FIRST &&
rule->location != RX_CLS_LOC_LAST)
return -EINVAL; return -EINVAL;
/* Range-check ring_cookie */ /* Range-check ring_cookie */
...@@ -976,9 +975,7 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx, ...@@ -976,9 +975,7 @@ static int efx_ethtool_set_class_rule(struct efx_nic *efx,
rule->m_ext.data[1])) rule->m_ext.data[1]))
return -EINVAL; return -EINVAL;
efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, efx_filter_init_rx(&spec, EFX_FILTER_PRI_MANUAL, 0,
(rule->location == RX_CLS_LOC_FIRST) ?
EFX_FILTER_FLAG_RX_OVERRIDE_IP : 0,
(rule->ring_cookie == RX_CLS_FLOW_DISC) ? (rule->ring_cookie == RX_CLS_FLOW_DISC) ?
0xfff : rule->ring_cookie); 0xfff : rule->ring_cookie);
......
...@@ -161,10 +161,6 @@ static void efx_filter_push_rx_config(struct efx_nic *efx) ...@@ -161,10 +161,6 @@ static void efx_filter_push_rx_config(struct efx_nic *efx)
filter_ctl, FRF_CZ_UNICAST_NOMATCH_RSS_ENABLED, filter_ctl, FRF_CZ_UNICAST_NOMATCH_RSS_ENABLED,
!!(table->spec[EFX_FILTER_INDEX_UC_DEF].flags & !!(table->spec[EFX_FILTER_INDEX_UC_DEF].flags &
EFX_FILTER_FLAG_RX_RSS)); EFX_FILTER_FLAG_RX_RSS));
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_UNICAST_NOMATCH_IP_OVERRIDE,
!!(table->spec[EFX_FILTER_INDEX_UC_DEF].flags &
EFX_FILTER_FLAG_RX_OVERRIDE_IP));
EFX_SET_OWORD_FIELD( EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_MULTICAST_NOMATCH_Q_ID, filter_ctl, FRF_CZ_MULTICAST_NOMATCH_Q_ID,
table->spec[EFX_FILTER_INDEX_MC_DEF].dmaq_id); table->spec[EFX_FILTER_INDEX_MC_DEF].dmaq_id);
...@@ -172,10 +168,6 @@ static void efx_filter_push_rx_config(struct efx_nic *efx) ...@@ -172,10 +168,6 @@ static void efx_filter_push_rx_config(struct efx_nic *efx)
filter_ctl, FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED, filter_ctl, FRF_CZ_MULTICAST_NOMATCH_RSS_ENABLED,
!!(table->spec[EFX_FILTER_INDEX_MC_DEF].flags & !!(table->spec[EFX_FILTER_INDEX_MC_DEF].flags &
EFX_FILTER_FLAG_RX_RSS)); EFX_FILTER_FLAG_RX_RSS));
EFX_SET_OWORD_FIELD(
filter_ctl, FRF_CZ_MULTICAST_NOMATCH_IP_OVERRIDE,
!!(table->spec[EFX_FILTER_INDEX_MC_DEF].flags &
EFX_FILTER_FLAG_RX_OVERRIDE_IP));
} }
efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL); efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
...@@ -480,14 +472,12 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec) ...@@ -480,14 +472,12 @@ static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
case EFX_FILTER_TABLE_RX_MAC: { case EFX_FILTER_TABLE_RX_MAC: {
bool is_wild = spec->type == EFX_FILTER_MAC_WILD; bool is_wild = spec->type == EFX_FILTER_MAC_WILD;
EFX_POPULATE_OWORD_8( EFX_POPULATE_OWORD_7(
*filter, *filter,
FRF_CZ_RMFT_RSS_EN, FRF_CZ_RMFT_RSS_EN,
!!(spec->flags & EFX_FILTER_FLAG_RX_RSS), !!(spec->flags & EFX_FILTER_FLAG_RX_RSS),
FRF_CZ_RMFT_SCATTER_EN, FRF_CZ_RMFT_SCATTER_EN,
!!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER), !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER),
FRF_CZ_RMFT_IP_OVERRIDE,
!!(spec->flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP),
FRF_CZ_RMFT_RXQ_ID, spec->dmaq_id, FRF_CZ_RMFT_RXQ_ID, spec->dmaq_id,
FRF_CZ_RMFT_WILDCARD_MATCH, is_wild, FRF_CZ_RMFT_WILDCARD_MATCH, is_wild,
FRF_CZ_RMFT_DEST_MAC_HI, spec->data[2], FRF_CZ_RMFT_DEST_MAC_HI, spec->data[2],
...@@ -567,49 +557,62 @@ static int efx_filter_search(struct efx_filter_table *table, ...@@ -567,49 +557,62 @@ static int efx_filter_search(struct efx_filter_table *table,
} }
/* /*
* Construct/deconstruct external filter IDs. These must be ordered * Construct/deconstruct external filter IDs. At least the RX filter
* by matching priority, for RX NFC semantics. * IDs must be ordered by matching priority, for RX NFC semantics.
* *
* Each RX MAC filter entry has a flag for whether it can override an * Deconstruction needs to be robust against invalid IDs so that
* RX IP filter that also matches. So we assign locations for MAC * efx_filter_remove_id_safe() and efx_filter_get_filter_safe() can
* filters with overriding behaviour, then for IP filters, then for * accept user-provided IDs.
* MAC filters without overriding behaviour.
*/ */
#define EFX_FILTER_MATCH_PRI_RX_MAC_OVERRIDE_IP 0 #define EFX_FILTER_MATCH_PRI_COUNT 5
#define EFX_FILTER_MATCH_PRI_RX_DEF_OVERRIDE_IP 1
#define EFX_FILTER_MATCH_PRI_NORMAL_BASE 2 static const u8 efx_filter_type_match_pri[EFX_FILTER_TYPE_COUNT] = {
[EFX_FILTER_TCP_FULL] = 0,
[EFX_FILTER_UDP_FULL] = 0,
[EFX_FILTER_TCP_WILD] = 1,
[EFX_FILTER_UDP_WILD] = 1,
[EFX_FILTER_MAC_FULL] = 2,
[EFX_FILTER_MAC_WILD] = 3,
[EFX_FILTER_UC_DEF] = 4,
[EFX_FILTER_MC_DEF] = 4,
};
static const enum efx_filter_table_id efx_filter_range_table[] = {
EFX_FILTER_TABLE_RX_IP, /* RX match pri 0 */
EFX_FILTER_TABLE_RX_IP,
EFX_FILTER_TABLE_RX_MAC,
EFX_FILTER_TABLE_RX_MAC,
EFX_FILTER_TABLE_RX_DEF, /* RX match pri 4 */
EFX_FILTER_TABLE_COUNT, /* TX match pri 0; invalid */
EFX_FILTER_TABLE_COUNT, /* invalid */
EFX_FILTER_TABLE_TX_MAC,
EFX_FILTER_TABLE_TX_MAC, /* TX match pri 3 */
};
#define EFX_FILTER_INDEX_WIDTH 13 #define EFX_FILTER_INDEX_WIDTH 13
#define EFX_FILTER_INDEX_MASK ((1 << EFX_FILTER_INDEX_WIDTH) - 1) #define EFX_FILTER_INDEX_MASK ((1 << EFX_FILTER_INDEX_WIDTH) - 1)
static inline u32 efx_filter_make_id(enum efx_filter_table_id table_id, static inline u32
unsigned int index, u8 flags) efx_filter_make_id(const struct efx_filter_spec *spec, unsigned int index)
{ {
unsigned int match_pri = EFX_FILTER_MATCH_PRI_NORMAL_BASE + table_id; unsigned int range;
if (flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP) { range = efx_filter_type_match_pri[spec->type];
if (table_id == EFX_FILTER_TABLE_RX_MAC) if (!(spec->flags & EFX_FILTER_FLAG_RX))
match_pri = EFX_FILTER_MATCH_PRI_RX_MAC_OVERRIDE_IP; range += EFX_FILTER_MATCH_PRI_COUNT;
else if (table_id == EFX_FILTER_TABLE_RX_DEF)
match_pri = EFX_FILTER_MATCH_PRI_RX_DEF_OVERRIDE_IP;
}
return match_pri << EFX_FILTER_INDEX_WIDTH | index; return range << EFX_FILTER_INDEX_WIDTH | index;
} }
static inline enum efx_filter_table_id efx_filter_id_table_id(u32 id) static inline enum efx_filter_table_id efx_filter_id_table_id(u32 id)
{ {
unsigned int match_pri = id >> EFX_FILTER_INDEX_WIDTH; unsigned int range = id >> EFX_FILTER_INDEX_WIDTH;
switch (match_pri) { if (range < ARRAY_SIZE(efx_filter_range_table))
case EFX_FILTER_MATCH_PRI_RX_MAC_OVERRIDE_IP: return efx_filter_range_table[range];
return EFX_FILTER_TABLE_RX_MAC; else
case EFX_FILTER_MATCH_PRI_RX_DEF_OVERRIDE_IP: return EFX_FILTER_TABLE_COUNT; /* invalid */
return EFX_FILTER_TABLE_RX_DEF;
default:
return match_pri - EFX_FILTER_MATCH_PRI_NORMAL_BASE;
}
} }
static inline unsigned int efx_filter_id_index(u32 id) static inline unsigned int efx_filter_id_index(u32 id)
...@@ -619,12 +622,9 @@ static inline unsigned int efx_filter_id_index(u32 id) ...@@ -619,12 +622,9 @@ static inline unsigned int efx_filter_id_index(u32 id)
static inline u8 efx_filter_id_flags(u32 id) static inline u8 efx_filter_id_flags(u32 id)
{ {
unsigned int match_pri = id >> EFX_FILTER_INDEX_WIDTH; unsigned int range = id >> EFX_FILTER_INDEX_WIDTH;
if (match_pri < EFX_FILTER_MATCH_PRI_NORMAL_BASE) if (range < EFX_FILTER_MATCH_PRI_COUNT)
return EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_RX_OVERRIDE_IP;
else if (match_pri <=
EFX_FILTER_MATCH_PRI_NORMAL_BASE + EFX_FILTER_TABLE_RX_DEF)
return EFX_FILTER_FLAG_RX; return EFX_FILTER_FLAG_RX;
else else
return EFX_FILTER_FLAG_TX; return EFX_FILTER_FLAG_TX;
...@@ -633,14 +633,15 @@ static inline u8 efx_filter_id_flags(u32 id) ...@@ -633,14 +633,15 @@ static inline u8 efx_filter_id_flags(u32 id)
u32 efx_filter_get_rx_id_limit(struct efx_nic *efx) u32 efx_filter_get_rx_id_limit(struct efx_nic *efx)
{ {
struct efx_filter_state *state = efx->filter_state; struct efx_filter_state *state = efx->filter_state;
unsigned int table_id = EFX_FILTER_TABLE_RX_DEF; unsigned int range = EFX_FILTER_MATCH_PRI_COUNT - 1;
enum efx_filter_table_id table_id;
do { do {
table_id = efx_filter_range_table[range];
if (state->table[table_id].size != 0) if (state->table[table_id].size != 0)
return ((EFX_FILTER_MATCH_PRI_NORMAL_BASE + table_id) return range << EFX_FILTER_INDEX_WIDTH |
<< EFX_FILTER_INDEX_WIDTH) +
state->table[table_id].size; state->table[table_id].size;
} while (table_id--); } while (range--);
return 0; return 0;
} }
...@@ -718,7 +719,7 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, ...@@ -718,7 +719,7 @@ s32 efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
netif_vdbg(efx, hw, efx->net_dev, netif_vdbg(efx, hw, efx->net_dev,
"%s: filter type %d index %d rxq %u set", "%s: filter type %d index %d rxq %u set",
__func__, spec->type, filter_idx, spec->dmaq_id); __func__, spec->type, filter_idx, spec->dmaq_id);
rc = efx_filter_make_id(table->id, filter_idx, spec->flags); rc = efx_filter_make_id(spec, filter_idx);
out: out:
spin_unlock_bh(&state->lock); spin_unlock_bh(&state->lock);
...@@ -781,8 +782,7 @@ int efx_filter_remove_id_safe(struct efx_nic *efx, ...@@ -781,8 +782,7 @@ int efx_filter_remove_id_safe(struct efx_nic *efx,
spin_lock_bh(&state->lock); spin_lock_bh(&state->lock);
if (test_bit(filter_idx, table->used_bitmap) && if (test_bit(filter_idx, table->used_bitmap) &&
spec->priority == priority && spec->priority == priority) {
!((spec->flags ^ filter_flags) & EFX_FILTER_FLAG_RX_OVERRIDE_IP)) {
efx_filter_table_clear_entry(efx, table, filter_idx); efx_filter_table_clear_entry(efx, table, filter_idx);
if (table->used == 0) if (table->used == 0)
efx_filter_table_reset_search_depth(table); efx_filter_table_reset_search_depth(table);
...@@ -833,8 +833,7 @@ int efx_filter_get_filter_safe(struct efx_nic *efx, ...@@ -833,8 +833,7 @@ int efx_filter_get_filter_safe(struct efx_nic *efx,
spin_lock_bh(&state->lock); spin_lock_bh(&state->lock);
if (test_bit(filter_idx, table->used_bitmap) && if (test_bit(filter_idx, table->used_bitmap) &&
spec->priority == priority && spec->priority == priority) {
!((spec->flags ^ filter_flags) & EFX_FILTER_FLAG_RX_OVERRIDE_IP)) {
*spec_buf = *spec; *spec_buf = *spec;
rc = 0; rc = 0;
} else { } else {
...@@ -927,8 +926,7 @@ s32 efx_filter_get_rx_ids(struct efx_nic *efx, ...@@ -927,8 +926,7 @@ s32 efx_filter_get_rx_ids(struct efx_nic *efx,
goto out; goto out;
} }
buf[count++] = efx_filter_make_id( buf[count++] = efx_filter_make_id(
table_id, filter_idx, &table->spec[filter_idx], filter_idx);
table->spec[filter_idx].flags);
} }
} }
} }
......
...@@ -61,16 +61,12 @@ enum efx_filter_priority { ...@@ -61,16 +61,12 @@ enum efx_filter_priority {
* according to the indirection table. * according to the indirection table.
* @EFX_FILTER_FLAG_RX_SCATTER: Enable DMA scatter on the receiving * @EFX_FILTER_FLAG_RX_SCATTER: Enable DMA scatter on the receiving
* queue. * queue.
* @EFX_FILTER_FLAG_RX_OVERRIDE_IP: Enables a MAC filter to override
* any IP filter that matches the same packet. By default, IP
* filters take precedence.
* @EFX_FILTER_FLAG_RX: Filter is for RX * @EFX_FILTER_FLAG_RX: Filter is for RX
* @EFX_FILTER_FLAG_TX: Filter is for TX * @EFX_FILTER_FLAG_TX: Filter is for TX
*/ */
enum efx_filter_flags { enum efx_filter_flags {
EFX_FILTER_FLAG_RX_RSS = 0x01, EFX_FILTER_FLAG_RX_RSS = 0x01,
EFX_FILTER_FLAG_RX_SCATTER = 0x02, EFX_FILTER_FLAG_RX_SCATTER = 0x02,
EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04,
EFX_FILTER_FLAG_RX = 0x08, EFX_FILTER_FLAG_RX = 0x08,
EFX_FILTER_FLAG_TX = 0x10, EFX_FILTER_FLAG_TX = 0x10,
}; };
...@@ -88,8 +84,7 @@ enum efx_filter_flags { ...@@ -88,8 +84,7 @@ enum efx_filter_flags {
* *
* The @priority field is used by software to determine whether a new * The @priority field is used by software to determine whether a new
* filter may replace an old one. The hardware priority of a filter * filter may replace an old one. The hardware priority of a filter
* depends on the filter type and %EFX_FILTER_FLAG_RX_OVERRIDE_IP * depends on the filter type.
* flag.
*/ */
struct efx_filter_spec { struct efx_filter_spec {
u8 type:4; u8 type:4;
......
...@@ -113,11 +113,13 @@ extern void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); ...@@ -113,11 +113,13 @@ extern void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
#define MCDI_EVENT_FIELD(_ev, _field) \ #define MCDI_EVENT_FIELD(_ev, _field) \
EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field) EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field)
#define MCDI_ARRAY_FIELD(_buf, _field1, _type, _index, _field2) \ #define MCDI_ARRAY_FIELD(_buf, _field1, _type, _index, _field2) \
EFX_DWORD_FIELD( \ EFX_EXTRACT_DWORD( \
*((efx_dword_t *) \ *((efx_dword_t *) \
(MCDI_ARRAY_PTR(_buf, _field1, _type, _index) + \ (MCDI_ARRAY_PTR(_buf, _field1, _type, _index) + \
(MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _OFST & ~3))), \ (MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _OFST & ~3))), \
MC_CMD_ ## _type ## _TYPEDEF_ ## _field2) MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _LBN & 0x1f, \
(MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _LBN & 0x1f) + \
MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _WIDTH - 1)
extern void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len); extern void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len);
extern int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, extern int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating,
......
...@@ -614,7 +614,8 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, ...@@ -614,7 +614,8 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
{ {
enum efx_loopback_mode mode; enum efx_loopback_mode mode;
struct efx_loopback_state *state; struct efx_loopback_state *state;
struct efx_channel *channel = efx_get_channel(efx, 0); struct efx_channel *channel =
efx_get_channel(efx, efx->tx_channel_offset);
struct efx_tx_queue *tx_queue; struct efx_tx_queue *tx_queue;
int rc = 0; int rc = 0;
......
...@@ -1035,6 +1035,7 @@ efx_sriov_get_channel_name(struct efx_channel *channel, char *buf, size_t len) ...@@ -1035,6 +1035,7 @@ efx_sriov_get_channel_name(struct efx_channel *channel, char *buf, size_t len)
static const struct efx_channel_type efx_sriov_channel_type = { static const struct efx_channel_type efx_sriov_channel_type = {
.handle_no_channel = efx_sriov_handle_no_channel, .handle_no_channel = efx_sriov_handle_no_channel,
.pre_probe = efx_sriov_probe_channel, .pre_probe = efx_sriov_probe_channel,
.post_remove = efx_channel_dummy_op_void,
.get_name = efx_sriov_get_channel_name, .get_name = efx_sriov_get_channel_name,
/* no copy operation; channel must not be reallocated */ /* no copy operation; channel must not be reallocated */
.keep_eventq = true, .keep_eventq = true,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment