sfc: Generalise packet hash lookup to support EF10 RX prefix

EF10 uses an entirely different RX prefix format from Falcon-arch.
Extend struct efx_nic_type to describe this.

[bwh: Also replace the magic numbers used for the Falcon-arch RX prefix]
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
This commit is contained in:
Jon Cooper 2012-10-18 15:49:54 +01:00 committed by Ben Hutchings
parent 64a27752dc
commit 43a3739d55
6 changed files with 28 additions and 13 deletions

View File

@ -573,7 +573,7 @@ static void efx_start_datapath(struct efx_nic *efx)
* support the current MTU, including padding for header * support the current MTU, including padding for header
* alignment and overruns. * alignment and overruns.
*/ */
efx->rx_dma_len = (efx->type->rx_buffer_hash_size + efx->rx_dma_len = (efx->rx_prefix_size +
EFX_MAX_FRAME_LEN(efx->net_dev->mtu) + EFX_MAX_FRAME_LEN(efx->net_dev->mtu) +
efx->type->rx_buffer_padding); efx->type->rx_buffer_padding);
rx_buf_len = (sizeof(struct efx_rx_page_state) + rx_buf_len = (sizeof(struct efx_rx_page_state) +
@ -2456,6 +2456,9 @@ static int efx_init_struct(struct efx_nic *efx,
strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name)); strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name));
efx->net_dev = net_dev; efx->net_dev = net_dev;
efx->rx_prefix_size = efx->type->rx_prefix_size;
efx->rx_packet_hash_offset =
efx->type->rx_hash_offset - efx->type->rx_prefix_size;
spin_lock_init(&efx->stats_lock); spin_lock_init(&efx->stats_lock);
mutex_init(&efx->mac_lock); mutex_init(&efx->mac_lock);
efx->phy_op = &efx_dummy_phy_operations; efx->phy_op = &efx_dummy_phy_operations;

View File

@ -2827,7 +2827,8 @@ const struct efx_nic_type falcon_b0_nic_type = {
.evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL, .evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL,
.evq_rptr_tbl_base = FR_BZ_EVQ_RPTR, .evq_rptr_tbl_base = FR_BZ_EVQ_RPTR,
.max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH), .max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH),
.rx_buffer_hash_size = 0x10, .rx_prefix_size = FS_BZ_RX_PREFIX_SIZE,
.rx_hash_offset = FS_BZ_RX_PREFIX_HASH_OFST,
.rx_buffer_padding = 0, .rx_buffer_padding = 0,
.can_rx_scatter = true, .can_rx_scatter = true,
.max_interrupt_mode = EFX_INT_MODE_MSIX, .max_interrupt_mode = EFX_INT_MODE_MSIX,

View File

@ -2925,4 +2925,8 @@
#define FSF_AZ_DRV_GEN_EV_MAGIC_LBN 0 #define FSF_AZ_DRV_GEN_EV_MAGIC_LBN 0
#define FSF_AZ_DRV_GEN_EV_MAGIC_WIDTH 32 #define FSF_AZ_DRV_GEN_EV_MAGIC_WIDTH 32
/* RX packet prefix */
#define FS_BZ_RX_PREFIX_HASH_OFST 12
#define FS_BZ_RX_PREFIX_SIZE 16
#endif /* EFX_FARCH_REGS_H */ #endif /* EFX_FARCH_REGS_H */

View File

@ -663,6 +663,9 @@ struct vfdi_status;
* @rx_buffer_order: Order (log2) of number of pages for each RX buffer * @rx_buffer_order: Order (log2) of number of pages for each RX buffer
* @rx_buffer_truesize: Amortised allocation size of an RX buffer, * @rx_buffer_truesize: Amortised allocation size of an RX buffer,
* for use in sk_buff::truesize * for use in sk_buff::truesize
* @rx_prefix_size: Size of RX prefix before packet data
* @rx_packet_hash_offset: Offset of RX flow hash from start of packet data
* (valid only if @rx_prefix_size != 0; always negative)
* @rx_hash_key: Toeplitz hash key for RSS * @rx_hash_key: Toeplitz hash key for RSS
* @rx_indir_table: Indirection table for RSS * @rx_indir_table: Indirection table for RSS
* @rx_scatter: Scatter mode enabled for receives * @rx_scatter: Scatter mode enabled for receives
@ -793,6 +796,8 @@ struct efx_nic {
unsigned int rx_page_buf_step; unsigned int rx_page_buf_step;
unsigned int rx_bufs_per_page; unsigned int rx_bufs_per_page;
unsigned int rx_pages_per_batch; unsigned int rx_pages_per_batch;
unsigned int rx_prefix_size;
int rx_packet_hash_offset;
u8 rx_hash_key[40]; u8 rx_hash_key[40];
u32 rx_indir_table[128]; u32 rx_indir_table[128];
bool rx_scatter; bool rx_scatter;
@ -1009,7 +1014,8 @@ struct efx_mtd_partition {
* @evq_ptr_tbl_base: Event queue pointer table base address * @evq_ptr_tbl_base: Event queue pointer table base address
* @evq_rptr_tbl_base: Event queue read-pointer table base address * @evq_rptr_tbl_base: Event queue read-pointer table base address
* @max_dma_mask: Maximum possible DMA mask * @max_dma_mask: Maximum possible DMA mask
* @rx_buffer_hash_size: Size of hash at start of RX packet * @rx_prefix_size: Size of RX prefix before packet data
* @rx_hash_offset: Offset of RX flow hash within prefix
* @rx_buffer_padding: Size of padding at end of RX packet * @rx_buffer_padding: Size of padding at end of RX packet
* @can_rx_scatter: NIC is able to scatter packet to multiple buffers * @can_rx_scatter: NIC is able to scatter packet to multiple buffers
* @max_interrupt_mode: Highest capability interrupt mode supported * @max_interrupt_mode: Highest capability interrupt mode supported
@ -1126,7 +1132,8 @@ struct efx_nic_type {
unsigned int evq_ptr_tbl_base; unsigned int evq_ptr_tbl_base;
unsigned int evq_rptr_tbl_base; unsigned int evq_rptr_tbl_base;
u64 max_dma_mask; u64 max_dma_mask;
unsigned int rx_buffer_hash_size; unsigned int rx_prefix_size;
unsigned int rx_hash_offset;
unsigned int rx_buffer_padding; unsigned int rx_buffer_padding;
bool can_rx_scatter; bool can_rx_scatter;
unsigned int max_interrupt_mode; unsigned int max_interrupt_mode;

View File

@ -61,13 +61,12 @@ static inline u8 *efx_rx_buf_va(struct efx_rx_buffer *buf)
return page_address(buf->page) + buf->page_offset; return page_address(buf->page) + buf->page_offset;
} }
static inline u32 efx_rx_buf_hash(const u8 *eh) static inline u32 efx_rx_buf_hash(struct efx_nic *efx, const u8 *eh)
{ {
/* The ethernet header is always directly after any hash. */ #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) || NET_IP_ALIGN % 4 == 0 return __le32_to_cpup((const __le32 *)(eh + efx->rx_packet_hash_offset));
return __le32_to_cpup((const __le32 *)(eh - 4));
#else #else
const u8 *data = eh - 4; const u8 *data = eh + efx->rx_packet_hash_offset;
return (u32)data[0] | return (u32)data[0] |
(u32)data[1] << 8 | (u32)data[1] << 8 |
(u32)data[2] << 16 | (u32)data[2] << 16 |
@ -439,7 +438,7 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
} }
if (efx->net_dev->features & NETIF_F_RXHASH) if (efx->net_dev->features & NETIF_F_RXHASH)
skb->rxhash = efx_rx_buf_hash(eh); skb->rxhash = efx_rx_buf_hash(efx, eh);
skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ? skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ?
CHECKSUM_UNNECESSARY : CHECKSUM_NONE); CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
@ -568,8 +567,8 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
*/ */
prefetch(efx_rx_buf_va(rx_buf)); prefetch(efx_rx_buf_va(rx_buf));
rx_buf->page_offset += efx->type->rx_buffer_hash_size; rx_buf->page_offset += efx->rx_prefix_size;
rx_buf->len -= efx->type->rx_buffer_hash_size; rx_buf->len -= efx->rx_prefix_size;
if (n_frags > 1) { if (n_frags > 1) {
/* Release/sync DMA mapping for additional fragments. /* Release/sync DMA mapping for additional fragments.

View File

@ -965,7 +965,8 @@ const struct efx_nic_type siena_a0_nic_type = {
.evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL, .evq_ptr_tbl_base = FR_BZ_EVQ_PTR_TBL,
.evq_rptr_tbl_base = FR_BZ_EVQ_RPTR, .evq_rptr_tbl_base = FR_BZ_EVQ_RPTR,
.max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH), .max_dma_mask = DMA_BIT_MASK(FSF_AZ_TX_KER_BUF_ADDR_WIDTH),
.rx_buffer_hash_size = 0x10, .rx_prefix_size = FS_BZ_RX_PREFIX_SIZE,
.rx_hash_offset = FS_BZ_RX_PREFIX_HASH_OFST,
.rx_buffer_padding = 0, .rx_buffer_padding = 0,
.can_rx_scatter = true, .can_rx_scatter = true,
.max_interrupt_mode = EFX_INT_MODE_MSIX, .max_interrupt_mode = EFX_INT_MODE_MSIX,