From d730dc527a5abd4717f6320e82cfce54edc882a3 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Tue, 1 Jun 2010 11:19:09 +0000 Subject: sfc: Allow DRV_GEN events to be used outside of selftests Formerly, efx_test_eventq_irq() assumed it was the only user of driver generated events. Allow it to interoperate with other users. We can create more than 16 channels, so align event codes with a multiple of 256 not 16. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 2e6fd89f2a72..ee0ea01c847e 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -336,7 +336,7 @@ enum efx_rx_alloc_method { * @eventq: Event queue buffer * @eventq_read_ptr: Event queue read pointer * @last_eventq_read_ptr: Last event queue read pointer value. - * @eventq_magic: Event queue magic value for driver-generated test events + * @magic_count: Event queue test event count * @irq_count: Number of IRQs since last adaptive moderation decision * @irq_mod_score: IRQ moderation score * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors @@ -367,7 +367,7 @@ struct efx_channel { struct efx_special_buffer eventq; unsigned int eventq_read_ptr; unsigned int last_eventq_read_ptr; - unsigned int eventq_magic; + unsigned int magic_count; unsigned int irq_count; unsigned int irq_mod_score; -- cgit v1.2.3 From 90d683afd1395016775c8d90508614f8d3000b81 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Tue, 1 Jun 2010 11:19:39 +0000 Subject: sfc: Remove efx_rx_queue::add_lock Ensure that efx_fast_push_rx_descriptors() must only run from efx_process_channel() [NAPI], or when napi_disable() has been executed. Reimplement the slow fill by sending an event to the channel, so that NAPI runs, and hanging the subsequent fast fill off the event handler. Replace the sfc_refill workqueue and delayed work items with a timer. We do not need to stop this timer in efx_flush_all() because it's safe to send the event always; receiving it will be delayed until NAPI is restarted. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index ee0ea01c847e..45398039dee6 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -242,10 +243,6 @@ struct efx_rx_buffer { * @added_count: Number of buffers added to the receive queue. * @notified_count: Number of buffers given to NIC (<= @added_count). * @removed_count: Number of buffers removed from the receive queue. - * @add_lock: Receive queue descriptor add spin lock. - * This lock must be held in order to add buffers to the RX - * descriptor ring (rxd and buffer) and to update added_count (but - * not removed_count). * @max_fill: RX descriptor maximum fill level (<= ring size) * @fast_fill_trigger: RX descriptor fill level that will trigger a fast fill * (<= @max_fill) @@ -259,7 +256,7 @@ struct efx_rx_buffer { * overflow was observed. It should never be set. * @alloc_page_count: RX allocation strategy counter. * @alloc_skb_count: RX allocation strategy counter. - * @work: Descriptor push work thread + * @slow_fill: Timer used to defer efx_nic_generate_fill_event(). * @buf_page: Page for next RX buffer. * We can use a single page for multiple RX buffers. This tracks * the remaining space in the allocation. @@ -277,7 +274,6 @@ struct efx_rx_queue { int added_count; int notified_count; int removed_count; - spinlock_t add_lock; unsigned int max_fill; unsigned int fast_fill_trigger; unsigned int fast_fill_limit; @@ -285,7 +281,7 @@ struct efx_rx_queue { unsigned int min_overfill; unsigned int alloc_page_count; unsigned int alloc_skb_count; - struct delayed_work work; + struct timer_list slow_fill; unsigned int slow_fill_count; struct page *buf_page; -- cgit v1.2.3 From f7d6f379db61233a1740cb2c6818b9c97531771f Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Tue, 1 Jun 2010 11:33:17 +0000 Subject: sfc: Support only two rx buffers per page - Pull the loop handling into efx_init_rx_buffers_(skb|page) - Remove rx_queue->buf_page, and associated clean up code - Remove unmap_addr, since unmap_addr is trivially calculable This will allow us to recycle discarded buffers directly from efx_rx_packet(), since will never be in the middle of splitting a page. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 45398039dee6..59c8ecc39aee 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -222,7 +222,6 @@ struct efx_tx_queue { * If both this and skb are %NULL, the buffer slot is currently free. * @data: Pointer to ethernet header * @len: Buffer length, in bytes. - * @unmap_addr: DMA address to unmap */ struct efx_rx_buffer { dma_addr_t dma_addr; @@ -230,7 +229,6 @@ struct efx_rx_buffer { struct page *page; char *data; unsigned int len; - dma_addr_t unmap_addr; }; /** @@ -257,11 +255,6 @@ struct efx_rx_buffer { * @alloc_page_count: RX allocation strategy counter. * @alloc_skb_count: RX allocation strategy counter. * @slow_fill: Timer used to defer efx_nic_generate_fill_event(). - * @buf_page: Page for next RX buffer. - * We can use a single page for multiple RX buffers. This tracks - * the remaining space in the allocation. - * @buf_dma_addr: Page's DMA address. - * @buf_data: Page's host address. * @flushed: Use when handling queue flushing */ struct efx_rx_queue { @@ -284,9 +277,6 @@ struct efx_rx_queue { struct timer_list slow_fill; unsigned int slow_fill_count; - struct page *buf_page; - dma_addr_t buf_dma_addr; - char *buf_data; enum efx_flush_state flushed; }; -- cgit v1.2.3 From 62b330baede3849897ce7fc5534eadc34cd03a51 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Tue, 1 Jun 2010 11:20:53 +0000 Subject: sfc: Allow shared pages to be recycled Insert a structure at the start of the shared page that tracks the dma mapping refcnt. DMA into the next cache line of the (shared) page (plus EFX_PAGE_IP_ALIGN). When recycling a page, check the page refcnt. If the page is otherwise unused, then resurrect the other receive buffer that previously referenced the page. Be careful not to overflow the receive ring, since we can now resurrect n receive buffers in a row. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 59c8ecc39aee..40c0d931b182 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -231,6 +231,24 @@ struct efx_rx_buffer { unsigned int len; }; +/** + * struct efx_rx_page_state - Page-based rx buffer state + * + * Inserted at the start of every page allocated for receive buffers. + * Used to facilitate sharing dma mappings between recycled rx buffers + * and those passed up to the kernel. + * + * @refcnt: Number of struct efx_rx_buffer's referencing this page. + * When refcnt falls to zero, the page is unmapped for dma + * @dma_addr: The dma address of this page. + */ +struct efx_rx_page_state { + unsigned refcnt; + dma_addr_t dma_addr; + + unsigned int __pad[0] ____cacheline_aligned; +}; + /** * struct efx_rx_queue - An Efx RX queue * @efx: The associated Efx NIC -- cgit v1.2.3 From dd8f61d7ff92eb8a4626565ca37b209b3a8a9ce2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 1 Jun 2010 11:32:43 +0000 Subject: sfc: Get port number from CS_PORT_NUM, not PCI function number A single shared memory region used to communicate with firmware is mapped into both PCI PFs of the SFC9020 and SFL9021. Drivers must be able to identify which port they are addressing in order to use the correct sub-region. Currently we use the PCI function number, but the PCI address may be virtualised. Use the CS_PORT_NUM register field defined for just this purpose. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 40c0d931b182..6b2e4402ec57 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -649,6 +649,7 @@ union efx_multicast_hash { * struct efx_nic - an Efx NIC * @name: Device name (net device name or bus id before net device registered) * @pci_dev: The PCI device + * @port_num: Index of this host port within the controller * @type: Controller type attributes * @legacy_irq: IRQ number * @workqueue: Workqueue for port reconfigures and the HW monitor. @@ -732,6 +733,7 @@ union efx_multicast_hash { struct efx_nic { char name[IFNAMSIZ]; struct pci_dev *pci_dev; + unsigned port_num; const struct efx_nic_type *type; int legacy_irq; struct workqueue_struct *workqueue; @@ -834,7 +836,7 @@ static inline const char *efx_dev_name(struct efx_nic *efx) static inline unsigned int efx_port_num(struct efx_nic *efx) { - return PCI_FUNC(efx->pci_dev->devfn); + return efx->port_num; } /** -- cgit v1.2.3 From 62776d034cc40c49bafdb3551a6ba35f78e3f08d Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 23 Jun 2010 11:30:07 +0000 Subject: sfc: Implement message level control Replace EFX_ERR() with netif_err(), EFX_INFO() with netif_info(), EFX_LOG() with netif_dbg() and EFX_TRACE() and EFX_REGDUMP() with netif_vdbg(). Replace EFX_ERR_RL(), EFX_INFO_RL() and EFX_LOG_RL() using explicit calls to net_ratelimit(). Implement the ethtool operations to get and set message level flags, and add a 'debug' module parameter for the initial value. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index ba636e086fc3..0cca44b4ee44 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -13,6 +13,10 @@ #ifndef EFX_NET_DRIVER_H #define EFX_NET_DRIVER_H +#if defined(EFX_ENABLE_DEBUG) && !defined(DEBUG) +#define DEBUG +#endif + #include #include #include @@ -48,35 +52,6 @@ #define EFX_WARN_ON_PARANOID(x) do {} while (0) #endif -/* Un-rate-limited logging */ -#define EFX_ERR(efx, fmt, args...) \ -dev_err(&((efx)->pci_dev->dev), "ERR: %s " fmt, efx_dev_name(efx), ##args) - -#define EFX_INFO(efx, fmt, args...) \ -dev_info(&((efx)->pci_dev->dev), "INFO: %s " fmt, efx_dev_name(efx), ##args) - -#ifdef EFX_ENABLE_DEBUG -#define EFX_LOG(efx, fmt, args...) \ -dev_info(&((efx)->pci_dev->dev), "DBG: %s " fmt, efx_dev_name(efx), ##args) -#else -#define EFX_LOG(efx, fmt, args...) \ -dev_dbg(&((efx)->pci_dev->dev), "DBG: %s " fmt, efx_dev_name(efx), ##args) -#endif - -#define EFX_TRACE(efx, fmt, args...) do {} while (0) - -#define EFX_REGDUMP(efx, fmt, args...) do {} while (0) - -/* Rate-limited logging */ -#define EFX_ERR_RL(efx, fmt, args...) \ -do {if (net_ratelimit()) EFX_ERR(efx, fmt, ##args); } while (0) - -#define EFX_INFO_RL(efx, fmt, args...) \ -do {if (net_ratelimit()) EFX_INFO(efx, fmt, ##args); } while (0) - -#define EFX_LOG_RL(efx, fmt, args...) \ -do {if (net_ratelimit()) EFX_LOG(efx, fmt, ##args); } while (0) - /************************************************************************** * * Efx data structures @@ -663,6 +638,7 @@ union efx_multicast_hash { * @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 + * @msg_enable: Log message enable flags * @state: Device state flag. Serialised by the rtnl_lock. * @reset_pending: Pending reset method (normally RESET_TYPE_NONE) * @tx_queue: TX DMA queues @@ -746,6 +722,7 @@ struct efx_nic { enum efx_int_mode interrupt_mode; bool irq_rx_adaptive; unsigned int irq_rx_moderation; + u32 msg_enable; enum nic_state state; enum reset_type reset_pending; -- cgit v1.2.3 From c5d5f5fdc76baf0b8d074338c94bd443635ef9d0 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 23 Jun 2010 11:30:26 +0000 Subject: sfc: Replace EFX_DRIVER_NAME with KBUILD_MODNAME Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 0cca44b4ee44..9116dc977abb 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -39,9 +39,7 @@ * Build definitions * **************************************************************************/ -#ifndef EFX_DRIVER_NAME -#define EFX_DRIVER_NAME "sfc" -#endif + #define EFX_DRIVER_VERSION "3.0" #ifdef EFX_ENABLE_DEBUG -- cgit v1.2.3 From 39c9cf07077146b14ab077a0e27c869c6f0e6199 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 23 Jun 2010 11:31:28 +0000 Subject: sfc: Record hardware RX hash on each skb where possible Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 9116dc977abb..bdec542e0c3d 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -847,7 +847,8 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @evq_ptr_tbl_base: Event queue pointer table base address * @evq_rptr_tbl_base: Event queue read-pointer table base address * @max_dma_mask: Maximum possible DMA mask - * @rx_buffer_padding: Padding added to each RX buffer + * @rx_buffer_hash_size: Size of hash at start of RX buffer + * @rx_buffer_padding: Size of padding at end of RX buffer * @max_interrupt_mode: Highest capability interrupt mode supported * from &enum efx_init_mode. * @phys_addr_channels: Number of channels with physically addressed @@ -891,6 +892,7 @@ struct efx_nic_type { unsigned int evq_ptr_tbl_base; unsigned int evq_rptr_tbl_base; u64 max_dma_mask; + unsigned int rx_buffer_hash_size; unsigned int rx_buffer_padding; unsigned int max_interrupt_mode; unsigned int phys_addr_channels; -- cgit v1.2.3 From 5d3a6fca955c18b066f01233f9faeb351c0d966b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 25 Jun 2010 07:05:43 +0000 Subject: sfc: Move siena_nic_data::ipv6_rss_key to efx_nic::rx_hash_key We will use this hash key for Toeplitz IPv4 hashing too. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index bdec542e0c3d..28f3ff4cff4a 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -735,6 +735,7 @@ struct efx_nic { unsigned n_tx_channels; unsigned int rx_buffer_len; unsigned int rx_buffer_order; + u8 rx_hash_key[40]; unsigned int_error_count; unsigned long int_error_expire; -- cgit v1.2.3 From 765c9f46867c3253c02275cbb7a453f2eb56eda1 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 30 Jun 2010 05:06:28 +0000 Subject: sfc: Add support for RX flow hash control Allow ethtool to query the number of RX rings, the fields used in RX flow hashing and the hash indirection table. Allow ethtool to update the RX flow hash indirection table. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 28f3ff4cff4a..bab836c22719 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -648,6 +648,7 @@ union efx_multicast_hash { * @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_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 @@ -736,6 +737,7 @@ struct efx_nic { unsigned int rx_buffer_len; unsigned int rx_buffer_order; u8 rx_hash_key[40]; + u32 rx_indir_table[128]; unsigned int_error_count; unsigned long int_error_expire; -- cgit v1.2.3 From 47562e5d325af9ce5306bce53eb7cdd353fe46be Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 8 Jul 2010 13:36:32 +0000 Subject: sfc: Remove unused field left from mis-merge Commit eedc765ca4b19a41cf0b921a492ac08d640060d1 merged changes from net-2.6 that added and then removed efx_nic::port_num, which was also added in net-next-2.6. The end result should be that it is removed, since it is now unused. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/net_driver.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net/sfc/net_driver.h') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index bab836c22719..64e7caa4bbb5 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -622,7 +622,6 @@ union efx_multicast_hash { * struct efx_nic - an Efx NIC * @name: Device name (net device name or bus id before net device registered) * @pci_dev: The PCI device - * @port_num: Index of this host port within the controller * @type: Controller type attributes * @legacy_irq: IRQ number * @workqueue: Workqueue for port reconfigures and the HW monitor. @@ -708,7 +707,6 @@ union efx_multicast_hash { struct efx_nic { char name[IFNAMSIZ]; struct pci_dev *pci_dev; - unsigned port_num; const struct efx_nic_type *type; int legacy_irq; struct workqueue_struct *workqueue; -- cgit v1.2.3