/******************************************************************************* Intel UDMA driver Copyright(c) 1999 - 2015 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. The full GNU General Public License is included in this distribution in the file called "COPYING". Contact Information: Linux NICS udma-devel Mailing List Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *******************************************************************************/ #ifndef _UDMA_MAIN_H_ #define _UDMA_MAIN_H_ #include #include #include "udma_hw.h" #include #include #include /* * Tx : APPCPU --> L2SW * Rx: APPCPU <-- L2SW */ #define UDMA_RING_DEFAULT_ENTRIES (1 << 10) #define UDMA_RING_MIN_ENTRIES (1 << 4) #define UDMA_RING_MAX_ENTRIES (1 << 13) #define UDMA_RING_VALID_MAX_NUM(ring) ((ring).entries - 2) /* Enable/disable debugging statistics */ #define SOFT_IRQ_STATS 1 struct udma_device; /* Prototype to pop a descriptor from a queue */ typedef void (*udma_queue_pop_t)(struct udma_device *umdev, // UDMA device const unsigned int idx, // Descriptor index bool drop); // Drop descriptor flag enum udma_state { PORT_AVAILABLE = 0, PORT_IN_USE }; enum udma_latency_mode { LOW_LATENCY = 0, BULK_LATENCY = 1, INVALID_LATENCY = 255 }; enum udma_itr_mode { ITR_ADAPTIVE = 0, ITR_FIXED = 1, ITR_DISABLED = 2 }; /* wrapper around a pointer to a buffer, * so a DMA handle can be stored along with the buffer */ struct udma_buffer { struct sk_buff *skb; dma_addr_t dma; u16 length; }; struct udma_ring { struct spinlock lock ____cacheline_aligned_in_smp; struct udma_buffer *buffer_info; /* Descriptor */ struct udma_desc *desc; /* Virtual address of desc. */ dma_addr_t dma ____cacheline_aligned_in_smp; /* Phys address of desc. */ u32 dma_size; u32 entries; u32 ent_mask; /* Empty: to_be_use == tail Full: to_be_clean == tail+1 A free descriptor means the descriptor with no packet buffer attached */ volatile u16 to_be_clean; /* The first free desc. brings nothing */ volatile u16 to_be_use; /* The desc is just started maybe being processed by UDMA */ volatile u16 tail; /* The next avaliable desc. to be cleaned */ volatile u16 new_tail; /* The first free desc. brings nothing */ }; /* ITR data for adaptive mode */ struct udma_adapt_itr { u16 latency; // Latency mode u16 cps; // Chains per second u16 lo_ppc; // Low threshold for packets per chain u16 hi_ppc; // High threshold for packets per chain u32 c_bytes; // Number of bytes in current chain u32 c_packets; // Number of packets in current chain }; /* Interrupt Throttle Rate (ITR) data */ struct udma_itr_config { u32 mode; // ITR mode u32 ns; // Latency in nanoseconds u32 ppc; // Expected packets per chain (adaptive mode) u32 min_cps; // Minimum number of chains per second (adaptive mode) u32 max_cps; // Maximum number of chains per second (adaptive mode) u32 step_cps; // Step size (bulk@adaptive mode) }; /* UDMA statistics */ struct udma_stats { u32 irqs; // Interrupts counter u32 pkts; // Processed packets counter u32 bytes; // Processed bytes counter u32 drops; // Dropped packets counter #ifdef SOFT_IRQ_STATS /* Statistics for finished packets when soft IRQ was triggered */ u32 s_irqs; // Soft-IRQs counter u32 max_pkts; // Max number of packets in queue u32 acc_pkts; // Total accumulated packets #endif }; struct udma_queue { struct udma_ring ring ____cacheline_aligned_in_smp; struct udma_stats stats; struct udma_adapt_itr itr; udma_queue_pop_t pop_desc; rx_callback_t callback; u32 direction; /* 0: UDMA_RX - 1: UDMA_TX*/ }; /* UDMA device structure, includes HW, ring, buffer */ struct udma_device { /* structs defined in udma_hw.h */ struct udma_hw *hw; struct net_device *netdev; struct napi_struct napi; struct hrtimer itr_timer; struct udma_itr_config itr_cfg; struct mutex mutex; enum udma_state state; struct udma_queue rx; struct udma_queue tx; u32 rx_udma_size; u32 rx_skb_reserve; }; struct udma_device *udma_devs[UDMA_PORT_NUM_TOTAL] = {NULL, NULL}; /* UDMA Ring index operations */ #define IDX_ADD(i,j,r) (((i) + (j)) & (r)->ent_mask) #define IDX_SUB(i,j,r) (((i) + ((r)->entries - j)) & (r)->ent_mask) #define PREV_DESC_IDX(i,r) IDX_SUB(i,1,r) #define NEXT_DESC_IDX(i,r) IDX_ADD(i,1,r) /* Desc DMA address to desc index */ #define DESC_DMA_TO_DESC_INDEX(d,ring) \ (((u32)(d - ring->dma))/sizeof(struct udma_desc)) /* Desc index to Desc DMA address */ #define DESC_INDEX_TO_DESC_DMA(i,ring) \ ((ring)->dma + (i) * sizeof(struct udma_desc)) /* Ring index to the ring desc virtual address */ #define INDEX_TO_DESC(i,ring) \ (&(((struct udma_desc *)((ring)->desc))[i])) #ifdef DEBUG #define UDMA_PORT_MAGIC_BASE 100 #define UDMA_PORT0 100 #define UDMA_PORT1 101 #define UDMA_PROC_FS "udma_dbg" #define UDMA_DUMP_TX_CURR_RING 121 #define UDMA_DUMP_RX_CURR_RING 122 #define UDMA_DUMP_STATS 123 #define UDMA_DUMP_ITR_INFO 124 #define UDMA_DUMP_CURR_TX_REGS 125 #define UDMA_DUMP_CURR_RX_REGS 126 #endif #endif /* _UDMA_MAIN_H_ */