diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-02-13 23:45:02 +0000 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2012-02-16 00:25:10 +0000 |
commit | 7f967c011ae9c59fc7e7a017070ef7b22a5a4fbf (patch) | |
tree | c3ad2e039a8596ecbf9c7d1dc58bc8a251ecd8d2 /drivers/net/ethernet/sfc/net_driver.h | |
parent | a16e5b246c5b1aff3141ca6ae443307f3241a133 (diff) |
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: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc/net_driver.h')
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 3260e713791..94b0dcab897 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -54,6 +54,7 @@ #define EFX_MAX_CHANNELS 32U #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 * queue visible to the networking core is backed by two hardware TX @@ -311,6 +312,7 @@ enum efx_rx_alloc_method { * * @efx: Associated Efx NIC * @channel: Channel instance number + * @type: Channel type definition * @enabled: Channel enabled indicator * @irq: IRQ number (MSI and MSI-X only) * @irq_moderation: IRQ moderation value (in hardware ticks) @@ -341,6 +343,7 @@ enum efx_rx_alloc_method { struct efx_channel { struct efx_nic *efx; int channel; + const struct efx_channel_type *type; bool enabled; int irq; unsigned int irq_moderation; @@ -379,6 +382,26 @@ struct efx_channel { 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 { EFX_LED_OFF = 0, EFX_LED_ON = 1, @@ -631,6 +654,8 @@ struct efx_filter_state; * @rx_queue: RX DMA queues * @channel: Channels * @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. * @txq_entries: Size of transmit queues requested by user. * @next_buffer_table: First available buffer table id @@ -723,6 +748,8 @@ struct efx_nic { struct efx_channel *channel[EFX_MAX_CHANNELS]; char channel_name[EFX_MAX_CHANNELS][IFNAMSIZ + 6]; + const struct efx_channel_type * + extra_channel_type[EFX_MAX_EXTRA_CHANNELS]; unsigned rxq_entries; unsigned txq_entries; @@ -921,6 +948,13 @@ efx_get_channel(struct efx_nic *efx, unsigned index) _channel = (_channel->channel + 1 < (_efx)->n_channels) ? \ (_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 * efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type) { |