Commit 960f1627 authored by Alex Maftei (amaftei)'s avatar Alex Maftei (amaftei) Committed by David S. Miller

sfc: move RSS code

Style fixes included.
Signed-off-by: default avatarAlexandru-Mihai Maftei <amaftei@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 88f7df35
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "efx_channels.h" #include "efx_channels.h"
#include "rx_common.h" #include "rx_common.h"
#include "tx_common.h" #include "tx_common.h"
#include "rx_common.h"
#include "nic.h" #include "nic.h"
#include "io.h" #include "io.h"
#include "selftest.h" #include "selftest.h"
...@@ -311,16 +312,6 @@ static void efx_dissociate(struct efx_nic *efx) ...@@ -311,16 +312,6 @@ static void efx_dissociate(struct efx_nic *efx)
} }
} }
void efx_set_default_rx_indir_table(struct efx_nic *efx,
struct efx_rss_context *ctx)
{
size_t i;
for (i = 0; i < ARRAY_SIZE(ctx->rx_indir_table); i++)
ctx->rx_indir_table[i] =
ethtool_rxfh_indir_default(i, efx->rss_spread);
}
static int efx_probe_nic(struct efx_nic *efx) static int efx_probe_nic(struct efx_nic *efx)
{ {
int rc; int rc;
...@@ -1299,61 +1290,6 @@ void efx_rps_hash_del(struct efx_nic *efx, const struct efx_filter_spec *spec) ...@@ -1299,61 +1290,6 @@ void efx_rps_hash_del(struct efx_nic *efx, const struct efx_filter_spec *spec)
} }
#endif #endif
/* RSS contexts. We're using linked lists and crappy O(n) algorithms, because
* (a) this is an infrequent control-plane operation and (b) n is small (max 64)
*/
struct efx_rss_context *efx_alloc_rss_context_entry(struct efx_nic *efx)
{
struct list_head *head = &efx->rss_context.list;
struct efx_rss_context *ctx, *new;
u32 id = 1; /* Don't use zero, that refers to the master RSS context */
WARN_ON(!mutex_is_locked(&efx->rss_lock));
/* Search for first gap in the numbering */
list_for_each_entry(ctx, head, list) {
if (ctx->user_id != id)
break;
id++;
/* Check for wrap. If this happens, we have nearly 2^32
* allocated RSS contexts, which seems unlikely.
*/
if (WARN_ON_ONCE(!id))
return NULL;
}
/* Create the new entry */
new = kmalloc(sizeof(struct efx_rss_context), GFP_KERNEL);
if (!new)
return NULL;
new->context_id = EFX_EF10_RSS_CONTEXT_INVALID;
new->rx_hash_udp_4tuple = false;
/* Insert the new entry into the gap */
new->user_id = id;
list_add_tail(&new->list, &ctx->list);
return new;
}
struct efx_rss_context *efx_find_rss_context_entry(struct efx_nic *efx, u32 id)
{
struct list_head *head = &efx->rss_context.list;
struct efx_rss_context *ctx;
WARN_ON(!mutex_is_locked(&efx->rss_lock));
list_for_each_entry(ctx, head, list)
if (ctx->user_id == id)
return ctx;
return NULL;
}
void efx_free_rss_context_entry(struct efx_rss_context *ctx)
{
list_del(&ctx->list);
kfree(ctx);
}
/************************************************************************** /**************************************************************************
* *
* PCI interface * PCI interface
......
...@@ -26,8 +26,6 @@ extern unsigned int efx_piobuf_size; ...@@ -26,8 +26,6 @@ extern unsigned int efx_piobuf_size;
extern bool efx_separate_tx_channels; extern bool efx_separate_tx_channels;
/* RX */ /* RX */
void efx_set_default_rx_indir_table(struct efx_nic *efx,
struct efx_rss_context *ctx);
void __efx_rx_packet(struct efx_channel *channel); void __efx_rx_packet(struct efx_channel *channel);
void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
unsigned int n_frags, unsigned int len, u16 flags); unsigned int n_frags, unsigned int len, u16 flags);
...@@ -195,9 +193,6 @@ void efx_rps_hash_del(struct efx_nic *efx, const struct efx_filter_spec *spec); ...@@ -195,9 +193,6 @@ void efx_rps_hash_del(struct efx_nic *efx, const struct efx_filter_spec *spec);
#endif #endif
/* RSS contexts */ /* RSS contexts */
struct efx_rss_context *efx_alloc_rss_context_entry(struct efx_nic *efx);
struct efx_rss_context *efx_find_rss_context_entry(struct efx_nic *efx, u32 id);
void efx_free_rss_context_entry(struct efx_rss_context *ctx);
static inline bool efx_rss_active(struct efx_rss_context *ctx) static inline bool efx_rss_active(struct efx_rss_context *ctx)
{ {
return ctx->context_id != EFX_EF10_RSS_CONTEXT_INVALID; return ctx->context_id != EFX_EF10_RSS_CONTEXT_INVALID;
......
...@@ -551,3 +551,68 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, ...@@ -551,3 +551,68 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
napi_gro_frags(napi); napi_gro_frags(napi);
} }
/* RSS contexts. We're using linked lists and crappy O(n) algorithms, because
* (a) this is an infrequent control-plane operation and (b) n is small (max 64)
*/
struct efx_rss_context *efx_alloc_rss_context_entry(struct efx_nic *efx)
{
struct list_head *head = &efx->rss_context.list;
struct efx_rss_context *ctx, *new;
u32 id = 1; /* Don't use zero, that refers to the master RSS context */
WARN_ON(!mutex_is_locked(&efx->rss_lock));
/* Search for first gap in the numbering */
list_for_each_entry(ctx, head, list) {
if (ctx->user_id != id)
break;
id++;
/* Check for wrap. If this happens, we have nearly 2^32
* allocated RSS contexts, which seems unlikely.
*/
if (WARN_ON_ONCE(!id))
return NULL;
}
/* Create the new entry */
new = kmalloc(sizeof(*new), GFP_KERNEL);
if (!new)
return NULL;
new->context_id = EFX_EF10_RSS_CONTEXT_INVALID;
new->rx_hash_udp_4tuple = false;
/* Insert the new entry into the gap */
new->user_id = id;
list_add_tail(&new->list, &ctx->list);
return new;
}
struct efx_rss_context *efx_find_rss_context_entry(struct efx_nic *efx, u32 id)
{
struct list_head *head = &efx->rss_context.list;
struct efx_rss_context *ctx;
WARN_ON(!mutex_is_locked(&efx->rss_lock));
list_for_each_entry(ctx, head, list)
if (ctx->user_id == id)
return ctx;
return NULL;
}
void efx_free_rss_context_entry(struct efx_rss_context *ctx)
{
list_del(&ctx->list);
kfree(ctx);
}
void efx_set_default_rx_indir_table(struct efx_nic *efx,
struct efx_rss_context *ctx)
{
size_t i;
for (i = 0; i < ARRAY_SIZE(ctx->rx_indir_table); i++)
ctx->rx_indir_table[i] =
ethtool_rxfh_indir_default(i, efx->rss_spread);
}
...@@ -68,4 +68,10 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, bool atomic); ...@@ -68,4 +68,10 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue, bool atomic);
void void
efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
unsigned int n_frags, u8 *eh); unsigned int n_frags, u8 *eh);
struct efx_rss_context *efx_alloc_rss_context_entry(struct efx_nic *efx);
struct efx_rss_context *efx_find_rss_context_entry(struct efx_nic *efx, u32 id);
void efx_free_rss_context_entry(struct efx_rss_context *ctx);
void efx_set_default_rx_indir_table(struct efx_nic *efx,
struct efx_rss_context *ctx);
#endif #endif
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