diff options
Diffstat (limited to 'drivers/net/sfc/net_driver.h')
-rw-r--r-- | drivers/net/sfc/net_driver.h | 182 |
1 files changed, 115 insertions, 67 deletions
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 0a7e26d73b52..215d5c51bfa0 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -1,7 +1,7 @@ /**************************************************************************** * Driver for Solarflare Solarstorm network controllers and boards * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2005-2009 Solarflare Communications Inc. + * Copyright 2005-2011 Solarflare Communications Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -41,7 +41,7 @@ * **************************************************************************/ -#define EFX_DRIVER_VERSION "3.0" +#define EFX_DRIVER_VERSION "3.1" #ifdef EFX_ENABLE_DEBUG #define EFX_BUG_ON_PARANOID(x) BUG_ON(x) @@ -63,10 +63,12 @@ /* Checksum generation is a per-queue option in hardware, so each * queue visible to the networking core is backed by two hardware TX * queues. */ -#define EFX_MAX_CORE_TX_QUEUES EFX_MAX_CHANNELS -#define EFX_TXQ_TYPE_OFFLOAD 1 -#define EFX_TXQ_TYPES 2 -#define EFX_MAX_TX_QUEUES (EFX_TXQ_TYPES * EFX_MAX_CORE_TX_QUEUES) +#define EFX_MAX_TX_TC 2 +#define EFX_MAX_CORE_TX_QUEUES (EFX_MAX_TX_TC * EFX_MAX_CHANNELS) +#define EFX_TXQ_TYPE_OFFLOAD 1 /* flag */ +#define EFX_TXQ_TYPE_HIGHPRI 2 /* flag */ +#define EFX_TXQ_TYPES 4 +#define EFX_MAX_TX_QUEUES (EFX_TXQ_TYPES * EFX_MAX_CHANNELS) /** * struct efx_special_buffer - An Efx special buffer @@ -136,14 +138,20 @@ struct efx_tx_buffer { * @efx: The associated Efx NIC * @queue: DMA queue number * @channel: The associated channel + * @core_txq: The networking core TX queue structure * @buffer: The software buffer ring * @txd: The hardware descriptor ring * @ptr_mask: The size of the ring minus 1. + * @initialised: Has hardware queue been initialised? * @flushed: Used when handling queue flushing * @read_count: Current read pointer. * This is the number of buffers that have been removed from both rings. - * @stopped: Stopped count. - * Set if this TX queue is currently stopping its port. + * @old_write_count: The value of @write_count when last checked. + * This is here for performance reasons. The xmit path will + * only get the up-to-date value of @write_count if this + * variable indicates that the queue is empty. This is to + * avoid cache-line ping-pong between the xmit path and the + * completion path. * @insert_count: Current insert pointer * This is the number of buffers that have been added to the * software ring. @@ -163,21 +171,26 @@ struct efx_tx_buffer { * @tso_long_headers: Number of packets with headers too long for standard * blocks * @tso_packets: Number of packets via the TSO xmit path + * @pushes: Number of times the TX push feature has been used + * @empty_read_count: If the completion path has seen the queue as empty + * and the transmission path has not yet checked this, the value of + * @read_count bitwise-added to %EFX_EMPTY_COUNT_VALID; otherwise 0. */ struct efx_tx_queue { /* Members which don't change on the fast path */ struct efx_nic *efx ____cacheline_aligned_in_smp; unsigned queue; struct efx_channel *channel; - struct efx_nic *nic; + struct netdev_queue *core_txq; struct efx_tx_buffer *buffer; struct efx_special_buffer txd; unsigned int ptr_mask; + bool initialised; enum efx_flush_state flushed; /* Members used mainly on the completion path */ unsigned int read_count ____cacheline_aligned_in_smp; - int stopped; + unsigned int old_write_count; /* Members used only on the xmit path */ unsigned int insert_count ____cacheline_aligned_in_smp; @@ -187,6 +200,11 @@ struct efx_tx_queue { unsigned int tso_bursts; unsigned int tso_long_headers; unsigned int tso_packets; + unsigned int pushes; + + /* Members shared between paths and sometimes updated */ + unsigned int empty_read_count ____cacheline_aligned_in_smp; +#define EFX_EMPTY_COUNT_VALID 0x80000000 }; /** @@ -196,15 +214,17 @@ struct efx_tx_queue { * If both this and page are %NULL, the buffer slot is currently free. * @page: The associated page buffer, if any. * If both this and skb are %NULL, the buffer slot is currently free. - * @data: Pointer to ethernet header * @len: Buffer length, in bytes. + * @is_page: Indicates if @page is valid. If false, @skb is valid. */ struct efx_rx_buffer { dma_addr_t dma_addr; - struct sk_buff *skb; - struct page *page; - char *data; + union { + struct sk_buff *skb; + struct page *page; + } u; unsigned int len; + bool is_page; }; /** @@ -305,7 +325,6 @@ enum efx_rx_alloc_method { * @irq_moderation: IRQ moderation value (in hardware ticks) * @napi_dev: Net device used with NAPI * @napi_str: NAPI control structure - * @reset_work: Scheduled reset work thread * @work_pending: Is work pending via NAPI? * @eventq: Event queue buffer * @eventq_mask: Event queue pointer mask @@ -326,8 +345,6 @@ enum efx_rx_alloc_method { * @n_rx_overlength: Count of RX_OVERLENGTH errors * @n_skbuff_leaks: Count of skbuffs leaked due to RX overrun * @rx_queue: RX queue for this channel - * @tx_stop_count: Core TX queue stop count - * @tx_stop_lock: Core TX queue stop lock * @tx_queue: TX queues for this channel */ struct efx_channel { @@ -347,6 +364,9 @@ struct efx_channel { unsigned int irq_count; unsigned int irq_mod_score; +#ifdef CONFIG_RFS_ACCEL + unsigned int rfs_filters_added; +#endif int rx_alloc_level; int rx_alloc_push_pages; @@ -366,11 +386,7 @@ struct efx_channel { bool rx_pkt_csummed; struct efx_rx_queue rx_queue; - - atomic_t tx_stop_count; - spinlock_t tx_stop_lock; - - struct efx_tx_queue tx_queue[2]; + struct efx_tx_queue tx_queue[EFX_TXQ_TYPES]; }; enum efx_led_mode { @@ -621,14 +637,13 @@ struct efx_filter_state; * @pci_dev: The PCI device * @type: Controller type attributes * @legacy_irq: IRQ number + * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)? * @workqueue: Workqueue for port reconfigures and the HW monitor. * Work items do not hold and must not acquire RTNL. * @workqueue_name: Name of workqueue * @reset_work: Scheduled reset workitem - * @monitor_work: Hardware monitor workitem * @membase_phys: Memory BAR value as physical address * @membase: Memory BAR value - * @biu_lock: BIU (bus interface unit) lock * @interrupt_mode: Interrupt mode * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues * @irq_rx_moderation: IRQ moderation time for RX event queues @@ -647,23 +662,14 @@ struct efx_filter_state; * @n_tx_channels: Number of channels used for TX * @rx_buffer_len: RX buffer length * @rx_buffer_order: Order (log2) of number of pages for each RX buffer + * @rx_hash_key: Toeplitz hash key for RSS * @rx_indir_table: Indirection table for RSS * @int_error_count: Number of internal errors seen recently * @int_error_expire: Time at which error count will be expired * @irq_status: Interrupt status buffer - * @last_irq_cpu: Last CPU to handle interrupt. - * This register is written with the SMP processor ID whenever an - * interrupt is handled. It is used by efx_nic_test_interrupt() - * to verify that an interrupt has occurred. * @irq_zero_count: Number of legacy IRQs seen with queue flags == 0 * @fatal_irq_level: IRQ level (bit number) used for serious errors - * @spi_flash: SPI flash device - * This field will be %NULL if no flash device is present (or for Siena). - * @spi_eeprom: SPI EEPROM device - * This field will be %NULL if no EEPROM device is present (or for Siena). - * @spi_lock: SPI bus lock * @mtd_list: List of MTDs attached to the NIC - * @n_rx_nodesc_drop_cnt: RX no descriptor drop count * @nic_data: Hardware dependant state * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, * @port_inhibited, efx_monitor() and efx_reconfigure_port() @@ -676,21 +682,14 @@ struct efx_filter_state; * @port_initialized: Port initialized? * @net_dev: Operating system network device. Consider holding the rtnl lock * @rx_checksum_enabled: RX checksumming enabled - * @mac_stats: MAC statistics. These include all statistics the MACs - * can provide. Generic code converts these into a standard - * &struct net_device_stats. * @stats_buffer: DMA buffer for statistics - * @stats_lock: Statistics update lock. Serialises statistics fetches * @mac_op: MAC interface - * @mac_address: Permanent MAC address * @phy_type: PHY type - * @mdio_lock: MDIO lock * @phy_op: PHY interface * @phy_data: PHY private data (including PHY-specific stats) * @mdio: PHY MDIO interface * @mdio_bus: PHY MDIO bus ID (only used by Siena) * @phy_mode: PHY operating mode. Serialised by @mac_lock. - * @xmac_poll_required: XMAC link state needs polling * @link_advertising: Autonegotiation advertising flags * @link_state: Current state of the link * @n_link_state_changes: Number of times the link has changed state @@ -701,21 +700,34 @@ struct efx_filter_state; * @loopback_mode: Loopback status * @loopback_modes: Supported loopback mode bitmask * @loopback_selftest: Offline self-test private state + * @monitor_work: Hardware monitor workitem + * @biu_lock: BIU (bus interface unit) lock + * @last_irq_cpu: Last CPU to handle interrupt. + * This register is written with the SMP processor ID whenever an + * interrupt is handled. It is used by efx_nic_test_interrupt() + * to verify that an interrupt has occurred. + * @n_rx_nodesc_drop_cnt: RX no descriptor drop count + * @mac_stats: MAC statistics. These include all statistics the MACs + * can provide. Generic code converts these into a standard + * &struct net_device_stats. + * @stats_lock: Statistics update lock. Serialises statistics fetches * * This is stored in the private area of the &struct net_device. */ struct efx_nic { + /* The following fields should be written very rarely */ + char name[IFNAMSIZ]; struct pci_dev *pci_dev; const struct efx_nic_type *type; int legacy_irq; + bool legacy_irq_enabled; struct workqueue_struct *workqueue; char workqueue_name[16]; struct work_struct reset_work; - struct delayed_work monitor_work; resource_size_t membase_phys; void __iomem *membase; - spinlock_t biu_lock; + enum efx_int_mode interrupt_mode; bool irq_rx_adaptive; unsigned int irq_rx_moderation; @@ -732,6 +744,7 @@ struct efx_nic { unsigned next_buffer_table; unsigned n_channels; unsigned n_rx_channels; + unsigned tx_channel_offset; unsigned n_tx_channels; unsigned int rx_buffer_len; unsigned int rx_buffer_order; @@ -742,19 +755,13 @@ struct efx_nic { unsigned long int_error_expire; struct efx_buffer irq_status; - volatile signed int last_irq_cpu; unsigned irq_zero_count; unsigned fatal_irq_level; - struct efx_spi_device *spi_flash; - struct efx_spi_device *spi_eeprom; - struct mutex spi_lock; #ifdef CONFIG_SFC_MTD struct list_head mtd_list; #endif - unsigned n_rx_nodesc_drop_cnt; - void *nic_data; struct mutex mac_lock; @@ -766,22 +773,17 @@ struct efx_nic { struct net_device *net_dev; bool rx_checksum_enabled; - struct efx_mac_stats mac_stats; struct efx_buffer stats_buffer; - spinlock_t stats_lock; struct efx_mac_operations *mac_op; - unsigned char mac_address[ETH_ALEN]; unsigned int phy_type; - struct mutex mdio_lock; struct efx_phy_operations *phy_op; void *phy_data; struct mdio_if_info mdio; unsigned int mdio_bus; enum efx_phy_mode phy_mode; - bool xmac_poll_required; u32 link_advertising; struct efx_link_state link_state; unsigned int n_link_state_changes; @@ -797,6 +799,15 @@ struct efx_nic { void *loopback_selftest; struct efx_filter_state *filter_state; + + /* The following fields may be written more often */ + + struct delayed_work monitor_work ____cacheline_aligned_in_smp; + spinlock_t biu_lock; + volatile signed int last_irq_cpu; + unsigned n_rx_nodesc_drop_cnt; + struct efx_mac_stats mac_stats; + spinlock_t stats_lock; }; static inline int efx_dev_registered(struct efx_nic *efx) @@ -829,6 +840,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * be called while the controller is uninitialised. * @probe_port: Probe the MAC and PHY * @remove_port: Free resources allocated by probe_port() + * @handle_global_event: Handle a "global" event (may be %NULL) * @prepare_flush: Prepare the hardware for flushing the DMA queues * @update_stats: Update statistics not provided by event handling * @start_stats: Start the regular fetching of statistics @@ -873,6 +885,7 @@ struct efx_nic_type { int (*reset)(struct efx_nic *efx, enum reset_type method); int (*probe_port)(struct efx_nic *efx); void (*remove_port)(struct efx_nic *efx); + bool (*handle_global_event)(struct efx_channel *channel, efx_qword_t *); void (*prepare_flush)(struct efx_nic *efx); void (*update_stats)(struct efx_nic *efx); void (*start_stats)(struct efx_nic *efx); @@ -902,7 +915,7 @@ struct efx_nic_type { unsigned int phys_addr_channels; unsigned int tx_dc_base; unsigned int rx_dc_base; - unsigned long offload_features; + u32 offload_features; u32 reset_world_flags; }; @@ -926,21 +939,48 @@ efx_get_channel(struct efx_nic *efx, unsigned index) _channel = (_channel->channel + 1 < (_efx)->n_channels) ? \ (_efx)->channel[_channel->channel + 1] : NULL) -extern struct efx_tx_queue * -efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type); +static inline struct efx_tx_queue * +efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type) +{ + EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels || + type >= EFX_TXQ_TYPES); + return &efx->channel[efx->tx_channel_offset + index]->tx_queue[type]; +} + +static inline bool efx_channel_has_tx_queues(struct efx_channel *channel) +{ + return channel->channel - channel->efx->tx_channel_offset < + channel->efx->n_tx_channels; +} static inline struct efx_tx_queue * efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type) { - struct efx_tx_queue *tx_queue = channel->tx_queue; - EFX_BUG_ON_PARANOID(type >= EFX_TXQ_TYPES); - return tx_queue->channel ? tx_queue + type : NULL; + EFX_BUG_ON_PARANOID(!efx_channel_has_tx_queues(channel) || + type >= EFX_TXQ_TYPES); + return &channel->tx_queue[type]; +} + +static inline bool efx_tx_queue_used(struct efx_tx_queue *tx_queue) +{ + return !(tx_queue->efx->net_dev->num_tc < 2 && + tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI); } /* Iterate over all TX queues belonging to a channel */ #define efx_for_each_channel_tx_queue(_tx_queue, _channel) \ - for (_tx_queue = efx_channel_get_tx_queue(channel, 0); \ - _tx_queue && _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \ + if (!efx_channel_has_tx_queues(_channel)) \ + ; \ + else \ + for (_tx_queue = (_channel)->tx_queue; \ + _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES && \ + efx_tx_queue_used(_tx_queue); \ + _tx_queue++) + +/* Iterate over all possible TX queues belonging to a channel */ +#define efx_for_each_possible_channel_tx_queue(_tx_queue, _channel) \ + for (_tx_queue = (_channel)->tx_queue; \ + _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \ _tx_queue++) static inline struct efx_rx_queue * @@ -950,18 +990,26 @@ efx_get_rx_queue(struct efx_nic *efx, unsigned index) return &efx->channel[index]->rx_queue; } +static inline bool efx_channel_has_rx_queue(struct efx_channel *channel) +{ + return channel->channel < channel->efx->n_rx_channels; +} + static inline struct efx_rx_queue * efx_channel_get_rx_queue(struct efx_channel *channel) { - return channel->channel < channel->efx->n_rx_channels ? - &channel->rx_queue : NULL; + EFX_BUG_ON_PARANOID(!efx_channel_has_rx_queue(channel)); + return &channel->rx_queue; } /* Iterate over all RX queues belonging to a channel */ #define efx_for_each_channel_rx_queue(_rx_queue, _channel) \ - for (_rx_queue = efx_channel_get_rx_queue(channel); \ - _rx_queue; \ - _rx_queue = NULL) + if (!efx_channel_has_rx_queue(_channel)) \ + ; \ + else \ + for (_rx_queue = &(_channel)->rx_queue; \ + _rx_queue; \ + _rx_queue = NULL) static inline struct efx_channel * efx_rx_queue_channel(struct efx_rx_queue *rx_queue) |