Commit 7f967c01 authored by Ben Hutchings's avatar Ben Hutchings

sfc: Add support for 'extra' channel types

Abstract some of the channel operations to allow for 'extra'
channels that do not have RX or TX queues.

- Try to assign a channel to each extra channel type that is enabled
  for the NIC, but gracefully degrade if we can't allocate sufficient
  MSI-X vectors
- Allow each extra channel type to generate its own channel name
- Allow channel types to disable reallocation and reinitialisation
  of their channels
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
parent a16e5b24
This diff is collapsed.
...@@ -95,6 +95,7 @@ static inline void efx_filter_rfs_expire(struct efx_channel *channel) {} ...@@ -95,6 +95,7 @@ static inline void efx_filter_rfs_expire(struct efx_channel *channel) {}
#endif #endif
/* Channels */ /* Channels */
extern int efx_channel_dummy_op_int(struct efx_channel *channel);
extern void efx_process_channel_now(struct efx_channel *channel); extern void efx_process_channel_now(struct efx_channel *channel);
extern int extern int
efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries); efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries);
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#define EFX_MAX_CHANNELS 32U #define EFX_MAX_CHANNELS 32U
#define EFX_MAX_RX_QUEUES EFX_MAX_CHANNELS #define EFX_MAX_RX_QUEUES EFX_MAX_CHANNELS
#define EFX_MAX_EXTRA_CHANNELS 0U
/* Checksum generation is a per-queue option in hardware, so each /* Checksum generation is a per-queue option in hardware, so each
* queue visible to the networking core is backed by two hardware TX * queue visible to the networking core is backed by two hardware TX
...@@ -311,6 +312,7 @@ enum efx_rx_alloc_method { ...@@ -311,6 +312,7 @@ enum efx_rx_alloc_method {
* *
* @efx: Associated Efx NIC * @efx: Associated Efx NIC
* @channel: Channel instance number * @channel: Channel instance number
* @type: Channel type definition
* @enabled: Channel enabled indicator * @enabled: Channel enabled indicator
* @irq: IRQ number (MSI and MSI-X only) * @irq: IRQ number (MSI and MSI-X only)
* @irq_moderation: IRQ moderation value (in hardware ticks) * @irq_moderation: IRQ moderation value (in hardware ticks)
...@@ -341,6 +343,7 @@ enum efx_rx_alloc_method { ...@@ -341,6 +343,7 @@ enum efx_rx_alloc_method {
struct efx_channel { struct efx_channel {
struct efx_nic *efx; struct efx_nic *efx;
int channel; int channel;
const struct efx_channel_type *type;
bool enabled; bool enabled;
int irq; int irq;
unsigned int irq_moderation; unsigned int irq_moderation;
...@@ -379,6 +382,26 @@ struct efx_channel { ...@@ -379,6 +382,26 @@ struct efx_channel {
struct efx_tx_queue tx_queue[EFX_TXQ_TYPES]; struct efx_tx_queue tx_queue[EFX_TXQ_TYPES];
}; };
/**
* struct efx_channel_type - distinguishes traffic and extra channels
* @handle_no_channel: Handle failure to allocate an extra channel
* @pre_probe: Set up extra state prior to initialisation
* @post_remove: Tear down extra state after finalisation, if allocated.
* May be called on channels that have not been probed.
* @get_name: Generate the channel's name (used for its IRQ handler)
* @copy: Copy the channel state prior to reallocation. May be %NULL if
* reallocation is not supported.
* @keep_eventq: Flag for whether event queue should be kept initialised
* while the device is stopped
*/
struct efx_channel_type {
void (*handle_no_channel)(struct efx_nic *);
int (*pre_probe)(struct efx_channel *);
void (*get_name)(struct efx_channel *, char *buf, size_t len);
struct efx_channel *(*copy)(const struct efx_channel *);
bool keep_eventq;
};
enum efx_led_mode { enum efx_led_mode {
EFX_LED_OFF = 0, EFX_LED_OFF = 0,
EFX_LED_ON = 1, EFX_LED_ON = 1,
...@@ -631,6 +654,8 @@ struct efx_filter_state; ...@@ -631,6 +654,8 @@ struct efx_filter_state;
* @rx_queue: RX DMA queues * @rx_queue: RX DMA queues
* @channel: Channels * @channel: Channels
* @channel_name: Names for channels and their IRQs * @channel_name: Names for channels and their IRQs
* @extra_channel_types: Types of extra (non-traffic) channels that
* should be allocated for this NIC
* @rxq_entries: Size of receive queues requested by user. * @rxq_entries: Size of receive queues requested by user.
* @txq_entries: Size of transmit queues requested by user. * @txq_entries: Size of transmit queues requested by user.
* @next_buffer_table: First available buffer table id * @next_buffer_table: First available buffer table id
...@@ -723,6 +748,8 @@ struct efx_nic { ...@@ -723,6 +748,8 @@ struct efx_nic {
struct efx_channel *channel[EFX_MAX_CHANNELS]; struct efx_channel *channel[EFX_MAX_CHANNELS];
char channel_name[EFX_MAX_CHANNELS][IFNAMSIZ + 6]; char channel_name[EFX_MAX_CHANNELS][IFNAMSIZ + 6];
const struct efx_channel_type *
extra_channel_type[EFX_MAX_EXTRA_CHANNELS];
unsigned rxq_entries; unsigned rxq_entries;
unsigned txq_entries; unsigned txq_entries;
...@@ -921,6 +948,13 @@ efx_get_channel(struct efx_nic *efx, unsigned index) ...@@ -921,6 +948,13 @@ efx_get_channel(struct efx_nic *efx, unsigned index)
_channel = (_channel->channel + 1 < (_efx)->n_channels) ? \ _channel = (_channel->channel + 1 < (_efx)->n_channels) ? \
(_efx)->channel[_channel->channel + 1] : NULL) (_efx)->channel[_channel->channel + 1] : NULL)
/* Iterate over all used channels in reverse */
#define efx_for_each_channel_rev(_channel, _efx) \
for (_channel = (_efx)->channel[(_efx)->n_channels - 1]; \
_channel; \
_channel = _channel->channel ? \
(_efx)->channel[_channel->channel - 1] : NULL)
static inline struct efx_tx_queue * static inline struct efx_tx_queue *
efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type) efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
{ {
......
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