18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * This file is part of the Chelsio T4 PCI-E SR-IOV Virtual Function Ethernet 38c2ecf20Sopenharmony_ci * driver for Linux. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2009-2010 Chelsio Communications, Inc. All rights reserved. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two 88c2ecf20Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 98c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 108c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the 118c2ecf20Sopenharmony_ci * OpenIB.org BSD license below: 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or 148c2ecf20Sopenharmony_ci * without modification, are permitted provided that the following 158c2ecf20Sopenharmony_ci * conditions are met: 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * - Redistributions of source code must retain the above 188c2ecf20Sopenharmony_ci * copyright notice, this list of conditions and the following 198c2ecf20Sopenharmony_ci * disclaimer. 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * - Redistributions in binary form must reproduce the above 228c2ecf20Sopenharmony_ci * copyright notice, this list of conditions and the following 238c2ecf20Sopenharmony_ci * disclaimer in the documentation and/or other materials 248c2ecf20Sopenharmony_ci * provided with the distribution. 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 278c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 288c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 298c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 308c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 318c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 328c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 338c2ecf20Sopenharmony_ci * SOFTWARE. 348c2ecf20Sopenharmony_ci */ 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci/* 378c2ecf20Sopenharmony_ci * This file should not be included directly. Include t4vf_common.h instead. 388c2ecf20Sopenharmony_ci */ 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#ifndef __CXGB4VF_ADAPTER_H__ 418c2ecf20Sopenharmony_ci#define __CXGB4VF_ADAPTER_H__ 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 448c2ecf20Sopenharmony_ci#include <linux/pci.h> 458c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 468c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 478c2ecf20Sopenharmony_ci#include <linux/if_ether.h> 488c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#include "../cxgb4/t4_hw.h" 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/* 538c2ecf20Sopenharmony_ci * Constants of the implementation. 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_cienum { 568c2ecf20Sopenharmony_ci MAX_NPORTS = 1, /* max # of "ports" */ 578c2ecf20Sopenharmony_ci MAX_PORT_QSETS = 8, /* max # of Queue Sets / "port" */ 588c2ecf20Sopenharmony_ci MAX_ETH_QSETS = MAX_NPORTS*MAX_PORT_QSETS, 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci /* 618c2ecf20Sopenharmony_ci * MSI-X interrupt index usage. 628c2ecf20Sopenharmony_ci */ 638c2ecf20Sopenharmony_ci MSIX_FW = 0, /* MSI-X index for firmware Q */ 648c2ecf20Sopenharmony_ci MSIX_IQFLINT = 1, /* MSI-X index base for Ingress Qs */ 658c2ecf20Sopenharmony_ci MSIX_EXTRAS = 1, 668c2ecf20Sopenharmony_ci MSIX_ENTRIES = MAX_ETH_QSETS + MSIX_EXTRAS, 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci /* 698c2ecf20Sopenharmony_ci * The maximum number of Ingress and Egress Queues is determined by 708c2ecf20Sopenharmony_ci * the maximum number of "Queue Sets" which we support plus any 718c2ecf20Sopenharmony_ci * ancillary queues. Each "Queue Set" requires one Ingress Queue 728c2ecf20Sopenharmony_ci * for RX Packet Ingress Event notifications and two Egress Queues for 738c2ecf20Sopenharmony_ci * a Free List and an Ethernet TX list. 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ci INGQ_EXTRAS = 2, /* firmware event queue and */ 768c2ecf20Sopenharmony_ci /* forwarded interrupts */ 778c2ecf20Sopenharmony_ci MAX_INGQ = MAX_ETH_QSETS+INGQ_EXTRAS, 788c2ecf20Sopenharmony_ci MAX_EGRQ = MAX_ETH_QSETS*2, 798c2ecf20Sopenharmony_ci}; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci/* 828c2ecf20Sopenharmony_ci * Forward structure definition references. 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_cistruct adapter; 858c2ecf20Sopenharmony_cistruct sge_eth_rxq; 868c2ecf20Sopenharmony_cistruct sge_rspq; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci/* 898c2ecf20Sopenharmony_ci * Per-"port" information. This is really per-Virtual Interface information 908c2ecf20Sopenharmony_ci * but the use of the "port" nomanclature makes it easier to go back and forth 918c2ecf20Sopenharmony_ci * between the PF and VF drivers ... 928c2ecf20Sopenharmony_ci */ 938c2ecf20Sopenharmony_cistruct port_info { 948c2ecf20Sopenharmony_ci struct adapter *adapter; /* our adapter */ 958c2ecf20Sopenharmony_ci u32 vlan_id; /* vlan id for VST */ 968c2ecf20Sopenharmony_ci u16 viid; /* virtual interface ID */ 978c2ecf20Sopenharmony_ci int xact_addr_filt; /* index of our MAC address filter */ 988c2ecf20Sopenharmony_ci u16 rss_size; /* size of VI's RSS table slice */ 998c2ecf20Sopenharmony_ci u8 pidx; /* index into adapter port[] */ 1008c2ecf20Sopenharmony_ci s8 mdio_addr; 1018c2ecf20Sopenharmony_ci u8 port_type; /* firmware port type */ 1028c2ecf20Sopenharmony_ci u8 mod_type; /* firmware module type */ 1038c2ecf20Sopenharmony_ci u8 port_id; /* physical port ID */ 1048c2ecf20Sopenharmony_ci u8 nqsets; /* # of "Queue Sets" */ 1058c2ecf20Sopenharmony_ci u8 first_qset; /* index of first "Queue Set" */ 1068c2ecf20Sopenharmony_ci struct link_config link_cfg; /* physical port configuration */ 1078c2ecf20Sopenharmony_ci}; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/* 1108c2ecf20Sopenharmony_ci * Scatter Gather Engine resources for the "adapter". Our ingress and egress 1118c2ecf20Sopenharmony_ci * queues are organized into "Queue Sets" with one ingress and one egress 1128c2ecf20Sopenharmony_ci * queue per Queue Set. These Queue Sets are aportionable between the "ports" 1138c2ecf20Sopenharmony_ci * (Virtual Interfaces). One extra ingress queue is used to receive 1148c2ecf20Sopenharmony_ci * asynchronous messages from the firmware. Note that the "Queue IDs" that we 1158c2ecf20Sopenharmony_ci * use here are really "Relative Queue IDs" which are returned as part of the 1168c2ecf20Sopenharmony_ci * firmware command to allocate queues. These queue IDs are relative to the 1178c2ecf20Sopenharmony_ci * absolute Queue ID base of the section of the Queue ID space allocated to 1188c2ecf20Sopenharmony_ci * the PF/VF. 1198c2ecf20Sopenharmony_ci */ 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci/* 1228c2ecf20Sopenharmony_ci * SGE free-list queue state. 1238c2ecf20Sopenharmony_ci */ 1248c2ecf20Sopenharmony_cistruct rx_sw_desc; 1258c2ecf20Sopenharmony_cistruct sge_fl { 1268c2ecf20Sopenharmony_ci unsigned int avail; /* # of available RX buffers */ 1278c2ecf20Sopenharmony_ci unsigned int pend_cred; /* new buffers since last FL DB ring */ 1288c2ecf20Sopenharmony_ci unsigned int cidx; /* consumer index */ 1298c2ecf20Sopenharmony_ci unsigned int pidx; /* producer index */ 1308c2ecf20Sopenharmony_ci unsigned long alloc_failed; /* # of buffer allocation failures */ 1318c2ecf20Sopenharmony_ci unsigned long large_alloc_failed; 1328c2ecf20Sopenharmony_ci unsigned long starving; /* # of times FL was found starving */ 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci /* 1358c2ecf20Sopenharmony_ci * Write-once/infrequently fields. 1368c2ecf20Sopenharmony_ci * ------------------------------- 1378c2ecf20Sopenharmony_ci */ 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci unsigned int cntxt_id; /* SGE relative QID for the free list */ 1408c2ecf20Sopenharmony_ci unsigned int abs_id; /* SGE absolute QID for the free list */ 1418c2ecf20Sopenharmony_ci unsigned int size; /* capacity of free list */ 1428c2ecf20Sopenharmony_ci struct rx_sw_desc *sdesc; /* address of SW RX descriptor ring */ 1438c2ecf20Sopenharmony_ci __be64 *desc; /* address of HW RX descriptor ring */ 1448c2ecf20Sopenharmony_ci dma_addr_t addr; /* PCI bus address of hardware ring */ 1458c2ecf20Sopenharmony_ci void __iomem *bar2_addr; /* address of BAR2 Queue registers */ 1468c2ecf20Sopenharmony_ci unsigned int bar2_qid; /* Queue ID for BAR2 Queue registers */ 1478c2ecf20Sopenharmony_ci}; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci/* 1508c2ecf20Sopenharmony_ci * An ingress packet gather list. 1518c2ecf20Sopenharmony_ci */ 1528c2ecf20Sopenharmony_cistruct pkt_gl { 1538c2ecf20Sopenharmony_ci struct page_frag frags[MAX_SKB_FRAGS]; 1548c2ecf20Sopenharmony_ci void *va; /* virtual address of first byte */ 1558c2ecf20Sopenharmony_ci unsigned int nfrags; /* # of fragments */ 1568c2ecf20Sopenharmony_ci unsigned int tot_len; /* total length of fragments */ 1578c2ecf20Sopenharmony_ci}; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_citypedef int (*rspq_handler_t)(struct sge_rspq *, const __be64 *, 1608c2ecf20Sopenharmony_ci const struct pkt_gl *); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci/* 1638c2ecf20Sopenharmony_ci * State for an SGE Response Queue. 1648c2ecf20Sopenharmony_ci */ 1658c2ecf20Sopenharmony_cistruct sge_rspq { 1668c2ecf20Sopenharmony_ci struct napi_struct napi; /* NAPI scheduling control */ 1678c2ecf20Sopenharmony_ci const __be64 *cur_desc; /* current descriptor in queue */ 1688c2ecf20Sopenharmony_ci unsigned int cidx; /* consumer index */ 1698c2ecf20Sopenharmony_ci u8 gen; /* current generation bit */ 1708c2ecf20Sopenharmony_ci u8 next_intr_params; /* holdoff params for next interrupt */ 1718c2ecf20Sopenharmony_ci int offset; /* offset into current FL buffer */ 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci unsigned int unhandled_irqs; /* bogus interrupts */ 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci /* 1768c2ecf20Sopenharmony_ci * Write-once/infrequently fields. 1778c2ecf20Sopenharmony_ci * ------------------------------- 1788c2ecf20Sopenharmony_ci */ 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci u8 intr_params; /* interrupt holdoff parameters */ 1818c2ecf20Sopenharmony_ci u8 pktcnt_idx; /* interrupt packet threshold */ 1828c2ecf20Sopenharmony_ci u8 idx; /* queue index within its group */ 1838c2ecf20Sopenharmony_ci u16 cntxt_id; /* SGE rel QID for the response Q */ 1848c2ecf20Sopenharmony_ci u16 abs_id; /* SGE abs QID for the response Q */ 1858c2ecf20Sopenharmony_ci __be64 *desc; /* address of hardware response ring */ 1868c2ecf20Sopenharmony_ci dma_addr_t phys_addr; /* PCI bus address of ring */ 1878c2ecf20Sopenharmony_ci void __iomem *bar2_addr; /* address of BAR2 Queue registers */ 1888c2ecf20Sopenharmony_ci unsigned int bar2_qid; /* Queue ID for BAR2 Queue registers */ 1898c2ecf20Sopenharmony_ci unsigned int iqe_len; /* entry size */ 1908c2ecf20Sopenharmony_ci unsigned int size; /* capcity of response Q */ 1918c2ecf20Sopenharmony_ci struct adapter *adapter; /* our adapter */ 1928c2ecf20Sopenharmony_ci struct net_device *netdev; /* associated net device */ 1938c2ecf20Sopenharmony_ci rspq_handler_t handler; /* the handler for this response Q */ 1948c2ecf20Sopenharmony_ci}; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci/* 1978c2ecf20Sopenharmony_ci * Ethernet queue statistics 1988c2ecf20Sopenharmony_ci */ 1998c2ecf20Sopenharmony_cistruct sge_eth_stats { 2008c2ecf20Sopenharmony_ci unsigned long pkts; /* # of ethernet packets */ 2018c2ecf20Sopenharmony_ci unsigned long lro_pkts; /* # of LRO super packets */ 2028c2ecf20Sopenharmony_ci unsigned long lro_merged; /* # of wire packets merged by LRO */ 2038c2ecf20Sopenharmony_ci unsigned long rx_cso; /* # of Rx checksum offloads */ 2048c2ecf20Sopenharmony_ci unsigned long vlan_ex; /* # of Rx VLAN extractions */ 2058c2ecf20Sopenharmony_ci unsigned long rx_drops; /* # of packets dropped due to no mem */ 2068c2ecf20Sopenharmony_ci}; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci/* 2098c2ecf20Sopenharmony_ci * State for an Ethernet Receive Queue. 2108c2ecf20Sopenharmony_ci */ 2118c2ecf20Sopenharmony_cistruct sge_eth_rxq { 2128c2ecf20Sopenharmony_ci struct sge_rspq rspq; /* Response Queue */ 2138c2ecf20Sopenharmony_ci struct sge_fl fl; /* Free List */ 2148c2ecf20Sopenharmony_ci struct sge_eth_stats stats; /* receive statistics */ 2158c2ecf20Sopenharmony_ci}; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci/* 2188c2ecf20Sopenharmony_ci * SGE Transmit Queue state. This contains all of the resources associated 2198c2ecf20Sopenharmony_ci * with the hardware status of a TX Queue which is a circular ring of hardware 2208c2ecf20Sopenharmony_ci * TX Descriptors. For convenience, it also contains a pointer to a parallel 2218c2ecf20Sopenharmony_ci * "Software Descriptor" array but we don't know anything about it here other 2228c2ecf20Sopenharmony_ci * than its type name. 2238c2ecf20Sopenharmony_ci */ 2248c2ecf20Sopenharmony_cistruct tx_desc { 2258c2ecf20Sopenharmony_ci /* 2268c2ecf20Sopenharmony_ci * Egress Queues are measured in units of SGE_EQ_IDXSIZE by the 2278c2ecf20Sopenharmony_ci * hardware: Sizes, Producer and Consumer indices, etc. 2288c2ecf20Sopenharmony_ci */ 2298c2ecf20Sopenharmony_ci __be64 flit[SGE_EQ_IDXSIZE/sizeof(__be64)]; 2308c2ecf20Sopenharmony_ci}; 2318c2ecf20Sopenharmony_cistruct tx_sw_desc; 2328c2ecf20Sopenharmony_cistruct sge_txq { 2338c2ecf20Sopenharmony_ci unsigned int in_use; /* # of in-use TX descriptors */ 2348c2ecf20Sopenharmony_ci unsigned int size; /* # of descriptors */ 2358c2ecf20Sopenharmony_ci unsigned int cidx; /* SW consumer index */ 2368c2ecf20Sopenharmony_ci unsigned int pidx; /* producer index */ 2378c2ecf20Sopenharmony_ci unsigned long stops; /* # of times queue has been stopped */ 2388c2ecf20Sopenharmony_ci unsigned long restarts; /* # of queue restarts */ 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci /* 2418c2ecf20Sopenharmony_ci * Write-once/infrequently fields. 2428c2ecf20Sopenharmony_ci * ------------------------------- 2438c2ecf20Sopenharmony_ci */ 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci unsigned int cntxt_id; /* SGE relative QID for the TX Q */ 2468c2ecf20Sopenharmony_ci unsigned int abs_id; /* SGE absolute QID for the TX Q */ 2478c2ecf20Sopenharmony_ci struct tx_desc *desc; /* address of HW TX descriptor ring */ 2488c2ecf20Sopenharmony_ci struct tx_sw_desc *sdesc; /* address of SW TX descriptor ring */ 2498c2ecf20Sopenharmony_ci struct sge_qstat *stat; /* queue status entry */ 2508c2ecf20Sopenharmony_ci dma_addr_t phys_addr; /* PCI bus address of hardware ring */ 2518c2ecf20Sopenharmony_ci void __iomem *bar2_addr; /* address of BAR2 Queue registers */ 2528c2ecf20Sopenharmony_ci unsigned int bar2_qid; /* Queue ID for BAR2 Queue registers */ 2538c2ecf20Sopenharmony_ci}; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci/* 2568c2ecf20Sopenharmony_ci * State for an Ethernet Transmit Queue. 2578c2ecf20Sopenharmony_ci */ 2588c2ecf20Sopenharmony_cistruct sge_eth_txq { 2598c2ecf20Sopenharmony_ci struct sge_txq q; /* SGE TX Queue */ 2608c2ecf20Sopenharmony_ci struct netdev_queue *txq; /* associated netdev TX queue */ 2618c2ecf20Sopenharmony_ci unsigned long tso; /* # of TSO requests */ 2628c2ecf20Sopenharmony_ci unsigned long tx_cso; /* # of TX checksum offloads */ 2638c2ecf20Sopenharmony_ci unsigned long vlan_ins; /* # of TX VLAN insertions */ 2648c2ecf20Sopenharmony_ci unsigned long mapping_err; /* # of I/O MMU packet mapping errors */ 2658c2ecf20Sopenharmony_ci}; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci/* 2688c2ecf20Sopenharmony_ci * The complete set of Scatter/Gather Engine resources. 2698c2ecf20Sopenharmony_ci */ 2708c2ecf20Sopenharmony_cistruct sge { 2718c2ecf20Sopenharmony_ci /* 2728c2ecf20Sopenharmony_ci * Our "Queue Sets" ... 2738c2ecf20Sopenharmony_ci */ 2748c2ecf20Sopenharmony_ci struct sge_eth_txq ethtxq[MAX_ETH_QSETS]; 2758c2ecf20Sopenharmony_ci struct sge_eth_rxq ethrxq[MAX_ETH_QSETS]; 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci /* 2788c2ecf20Sopenharmony_ci * Extra ingress queues for asynchronous firmware events and 2798c2ecf20Sopenharmony_ci * forwarded interrupts (when in MSI mode). 2808c2ecf20Sopenharmony_ci */ 2818c2ecf20Sopenharmony_ci struct sge_rspq fw_evtq ____cacheline_aligned_in_smp; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci struct sge_rspq intrq ____cacheline_aligned_in_smp; 2848c2ecf20Sopenharmony_ci spinlock_t intrq_lock; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci /* 2878c2ecf20Sopenharmony_ci * State for managing "starving Free Lists" -- Free Lists which have 2888c2ecf20Sopenharmony_ci * fallen below a certain threshold of buffers available to the 2898c2ecf20Sopenharmony_ci * hardware and attempts to refill them up to that threshold have 2908c2ecf20Sopenharmony_ci * failed. We have a regular "slow tick" timer process which will 2918c2ecf20Sopenharmony_ci * make periodic attempts to refill these starving Free Lists ... 2928c2ecf20Sopenharmony_ci */ 2938c2ecf20Sopenharmony_ci DECLARE_BITMAP(starving_fl, MAX_EGRQ); 2948c2ecf20Sopenharmony_ci struct timer_list rx_timer; 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci /* 2978c2ecf20Sopenharmony_ci * State for cleaning up completed TX descriptors. 2988c2ecf20Sopenharmony_ci */ 2998c2ecf20Sopenharmony_ci struct timer_list tx_timer; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci /* 3028c2ecf20Sopenharmony_ci * Write-once/infrequently fields. 3038c2ecf20Sopenharmony_ci * ------------------------------- 3048c2ecf20Sopenharmony_ci */ 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci u16 max_ethqsets; /* # of available Ethernet queue sets */ 3078c2ecf20Sopenharmony_ci u16 ethqsets; /* # of active Ethernet queue sets */ 3088c2ecf20Sopenharmony_ci u16 ethtxq_rover; /* Tx queue to clean up next */ 3098c2ecf20Sopenharmony_ci u16 timer_val[SGE_NTIMERS]; /* interrupt holdoff timer array */ 3108c2ecf20Sopenharmony_ci u8 counter_val[SGE_NCOUNTERS]; /* interrupt RX threshold array */ 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci /* Decoded Adapter Parameters. 3138c2ecf20Sopenharmony_ci */ 3148c2ecf20Sopenharmony_ci u32 fl_pg_order; /* large page allocation size */ 3158c2ecf20Sopenharmony_ci u32 stat_len; /* length of status page at ring end */ 3168c2ecf20Sopenharmony_ci u32 pktshift; /* padding between CPL & packet data */ 3178c2ecf20Sopenharmony_ci u32 fl_align; /* response queue message alignment */ 3188c2ecf20Sopenharmony_ci u32 fl_starve_thres; /* Free List starvation threshold */ 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci /* 3218c2ecf20Sopenharmony_ci * Reverse maps from Absolute Queue IDs to associated queue pointers. 3228c2ecf20Sopenharmony_ci * The absolute Queue IDs are in a compact range which start at a 3238c2ecf20Sopenharmony_ci * [potentially large] Base Queue ID. We perform the reverse map by 3248c2ecf20Sopenharmony_ci * first converting the Absolute Queue ID into a Relative Queue ID by 3258c2ecf20Sopenharmony_ci * subtracting off the Base Queue ID and then use a Relative Queue ID 3268c2ecf20Sopenharmony_ci * indexed table to get the pointer to the corresponding software 3278c2ecf20Sopenharmony_ci * queue structure. 3288c2ecf20Sopenharmony_ci */ 3298c2ecf20Sopenharmony_ci unsigned int egr_base; 3308c2ecf20Sopenharmony_ci unsigned int ingr_base; 3318c2ecf20Sopenharmony_ci void *egr_map[MAX_EGRQ]; 3328c2ecf20Sopenharmony_ci struct sge_rspq *ingr_map[MAX_INGQ]; 3338c2ecf20Sopenharmony_ci}; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci/* 3368c2ecf20Sopenharmony_ci * Utility macros to convert Absolute- to Relative-Queue indices and Egress- 3378c2ecf20Sopenharmony_ci * and Ingress-Queues. The EQ_MAP() and IQ_MAP() macros which provide 3388c2ecf20Sopenharmony_ci * pointers to Ingress- and Egress-Queues can be used as both L- and R-values 3398c2ecf20Sopenharmony_ci */ 3408c2ecf20Sopenharmony_ci#define EQ_IDX(s, abs_id) ((unsigned int)((abs_id) - (s)->egr_base)) 3418c2ecf20Sopenharmony_ci#define IQ_IDX(s, abs_id) ((unsigned int)((abs_id) - (s)->ingr_base)) 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci#define EQ_MAP(s, abs_id) ((s)->egr_map[EQ_IDX(s, abs_id)]) 3448c2ecf20Sopenharmony_ci#define IQ_MAP(s, abs_id) ((s)->ingr_map[IQ_IDX(s, abs_id)]) 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci/* 3478c2ecf20Sopenharmony_ci * Macro to iterate across Queue Sets ("rxq" is a historic misnomer). 3488c2ecf20Sopenharmony_ci */ 3498c2ecf20Sopenharmony_ci#define for_each_ethrxq(sge, iter) \ 3508c2ecf20Sopenharmony_ci for (iter = 0; iter < (sge)->ethqsets; iter++) 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_cistruct hash_mac_addr { 3538c2ecf20Sopenharmony_ci struct list_head list; 3548c2ecf20Sopenharmony_ci u8 addr[ETH_ALEN]; 3558c2ecf20Sopenharmony_ci unsigned int iface_mac; 3568c2ecf20Sopenharmony_ci}; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_cistruct mbox_list { 3598c2ecf20Sopenharmony_ci struct list_head list; 3608c2ecf20Sopenharmony_ci}; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci/* 3638c2ecf20Sopenharmony_ci * Per-"adapter" (Virtual Function) information. 3648c2ecf20Sopenharmony_ci */ 3658c2ecf20Sopenharmony_cistruct adapter { 3668c2ecf20Sopenharmony_ci /* PCI resources */ 3678c2ecf20Sopenharmony_ci void __iomem *regs; 3688c2ecf20Sopenharmony_ci void __iomem *bar2; 3698c2ecf20Sopenharmony_ci struct pci_dev *pdev; 3708c2ecf20Sopenharmony_ci struct device *pdev_dev; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci /* "adapter" resources */ 3738c2ecf20Sopenharmony_ci unsigned long registered_device_map; 3748c2ecf20Sopenharmony_ci unsigned long open_device_map; 3758c2ecf20Sopenharmony_ci unsigned long flags; 3768c2ecf20Sopenharmony_ci struct adapter_params params; 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci /* queue and interrupt resources */ 3798c2ecf20Sopenharmony_ci struct { 3808c2ecf20Sopenharmony_ci unsigned short vec; 3818c2ecf20Sopenharmony_ci char desc[22]; 3828c2ecf20Sopenharmony_ci } msix_info[MSIX_ENTRIES]; 3838c2ecf20Sopenharmony_ci struct sge sge; 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci /* Linux network device resources */ 3868c2ecf20Sopenharmony_ci struct net_device *port[MAX_NPORTS]; 3878c2ecf20Sopenharmony_ci const char *name; 3888c2ecf20Sopenharmony_ci unsigned int msg_enable; 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci /* debugfs resources */ 3918c2ecf20Sopenharmony_ci struct dentry *debugfs_root; 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci /* various locks */ 3948c2ecf20Sopenharmony_ci spinlock_t stats_lock; 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci /* lock for mailbox cmd list */ 3978c2ecf20Sopenharmony_ci spinlock_t mbox_lock; 3988c2ecf20Sopenharmony_ci struct mbox_list mlist; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci /* support for mailbox command/reply logging */ 4018c2ecf20Sopenharmony_ci#define T4VF_OS_LOG_MBOX_CMDS 256 4028c2ecf20Sopenharmony_ci struct mbox_cmd_log *mbox_log; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci /* list of MAC addresses in MPS Hash */ 4058c2ecf20Sopenharmony_ci struct list_head mac_hlist; 4068c2ecf20Sopenharmony_ci}; 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_cienum { /* adapter flags */ 4098c2ecf20Sopenharmony_ci CXGB4VF_FULL_INIT_DONE = (1UL << 0), 4108c2ecf20Sopenharmony_ci CXGB4VF_USING_MSI = (1UL << 1), 4118c2ecf20Sopenharmony_ci CXGB4VF_USING_MSIX = (1UL << 2), 4128c2ecf20Sopenharmony_ci CXGB4VF_QUEUES_BOUND = (1UL << 3), 4138c2ecf20Sopenharmony_ci CXGB4VF_ROOT_NO_RELAXED_ORDERING = (1UL << 4), 4148c2ecf20Sopenharmony_ci CXGB4VF_FW_OK = (1UL << 5), 4158c2ecf20Sopenharmony_ci}; 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci/* 4188c2ecf20Sopenharmony_ci * The following register read/write routine definitions are required by 4198c2ecf20Sopenharmony_ci * the common code. 4208c2ecf20Sopenharmony_ci */ 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci/** 4238c2ecf20Sopenharmony_ci * t4_read_reg - read a HW register 4248c2ecf20Sopenharmony_ci * @adapter: the adapter 4258c2ecf20Sopenharmony_ci * @reg_addr: the register address 4268c2ecf20Sopenharmony_ci * 4278c2ecf20Sopenharmony_ci * Returns the 32-bit value of the given HW register. 4288c2ecf20Sopenharmony_ci */ 4298c2ecf20Sopenharmony_cistatic inline u32 t4_read_reg(struct adapter *adapter, u32 reg_addr) 4308c2ecf20Sopenharmony_ci{ 4318c2ecf20Sopenharmony_ci return readl(adapter->regs + reg_addr); 4328c2ecf20Sopenharmony_ci} 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci/** 4358c2ecf20Sopenharmony_ci * t4_write_reg - write a HW register 4368c2ecf20Sopenharmony_ci * @adapter: the adapter 4378c2ecf20Sopenharmony_ci * @reg_addr: the register address 4388c2ecf20Sopenharmony_ci * @val: the value to write 4398c2ecf20Sopenharmony_ci * 4408c2ecf20Sopenharmony_ci * Write a 32-bit value into the given HW register. 4418c2ecf20Sopenharmony_ci */ 4428c2ecf20Sopenharmony_cistatic inline void t4_write_reg(struct adapter *adapter, u32 reg_addr, u32 val) 4438c2ecf20Sopenharmony_ci{ 4448c2ecf20Sopenharmony_ci writel(val, adapter->regs + reg_addr); 4458c2ecf20Sopenharmony_ci} 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci#ifndef readq 4488c2ecf20Sopenharmony_cistatic inline u64 readq(const volatile void __iomem *addr) 4498c2ecf20Sopenharmony_ci{ 4508c2ecf20Sopenharmony_ci return readl(addr) + ((u64)readl(addr + 4) << 32); 4518c2ecf20Sopenharmony_ci} 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_cistatic inline void writeq(u64 val, volatile void __iomem *addr) 4548c2ecf20Sopenharmony_ci{ 4558c2ecf20Sopenharmony_ci writel(val, addr); 4568c2ecf20Sopenharmony_ci writel(val >> 32, addr + 4); 4578c2ecf20Sopenharmony_ci} 4588c2ecf20Sopenharmony_ci#endif 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci/** 4618c2ecf20Sopenharmony_ci * t4_read_reg64 - read a 64-bit HW register 4628c2ecf20Sopenharmony_ci * @adapter: the adapter 4638c2ecf20Sopenharmony_ci * @reg_addr: the register address 4648c2ecf20Sopenharmony_ci * 4658c2ecf20Sopenharmony_ci * Returns the 64-bit value of the given HW register. 4668c2ecf20Sopenharmony_ci */ 4678c2ecf20Sopenharmony_cistatic inline u64 t4_read_reg64(struct adapter *adapter, u32 reg_addr) 4688c2ecf20Sopenharmony_ci{ 4698c2ecf20Sopenharmony_ci return readq(adapter->regs + reg_addr); 4708c2ecf20Sopenharmony_ci} 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci/** 4738c2ecf20Sopenharmony_ci * t4_write_reg64 - write a 64-bit HW register 4748c2ecf20Sopenharmony_ci * @adapter: the adapter 4758c2ecf20Sopenharmony_ci * @reg_addr: the register address 4768c2ecf20Sopenharmony_ci * @val: the value to write 4778c2ecf20Sopenharmony_ci * 4788c2ecf20Sopenharmony_ci * Write a 64-bit value into the given HW register. 4798c2ecf20Sopenharmony_ci */ 4808c2ecf20Sopenharmony_cistatic inline void t4_write_reg64(struct adapter *adapter, u32 reg_addr, 4818c2ecf20Sopenharmony_ci u64 val) 4828c2ecf20Sopenharmony_ci{ 4838c2ecf20Sopenharmony_ci writeq(val, adapter->regs + reg_addr); 4848c2ecf20Sopenharmony_ci} 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci/** 4878c2ecf20Sopenharmony_ci * port_name - return the string name of a port 4888c2ecf20Sopenharmony_ci * @adapter: the adapter 4898c2ecf20Sopenharmony_ci * @pidx: the port index 4908c2ecf20Sopenharmony_ci * 4918c2ecf20Sopenharmony_ci * Return the string name of the selected port. 4928c2ecf20Sopenharmony_ci */ 4938c2ecf20Sopenharmony_cistatic inline const char *port_name(struct adapter *adapter, int pidx) 4948c2ecf20Sopenharmony_ci{ 4958c2ecf20Sopenharmony_ci return adapter->port[pidx]->name; 4968c2ecf20Sopenharmony_ci} 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci/** 4998c2ecf20Sopenharmony_ci * t4_os_set_hw_addr - store a port's MAC address in SW 5008c2ecf20Sopenharmony_ci * @adapter: the adapter 5018c2ecf20Sopenharmony_ci * @pidx: the port index 5028c2ecf20Sopenharmony_ci * @hw_addr: the Ethernet address 5038c2ecf20Sopenharmony_ci * 5048c2ecf20Sopenharmony_ci * Store the Ethernet address of the given port in SW. Called by the common 5058c2ecf20Sopenharmony_ci * code when it retrieves a port's Ethernet address from EEPROM. 5068c2ecf20Sopenharmony_ci */ 5078c2ecf20Sopenharmony_cistatic inline void t4_os_set_hw_addr(struct adapter *adapter, int pidx, 5088c2ecf20Sopenharmony_ci u8 hw_addr[]) 5098c2ecf20Sopenharmony_ci{ 5108c2ecf20Sopenharmony_ci memcpy(adapter->port[pidx]->dev_addr, hw_addr, ETH_ALEN); 5118c2ecf20Sopenharmony_ci} 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci/** 5148c2ecf20Sopenharmony_ci * netdev2pinfo - return the port_info structure associated with a net_device 5158c2ecf20Sopenharmony_ci * @dev: the netdev 5168c2ecf20Sopenharmony_ci * 5178c2ecf20Sopenharmony_ci * Return the struct port_info associated with a net_device 5188c2ecf20Sopenharmony_ci */ 5198c2ecf20Sopenharmony_cistatic inline struct port_info *netdev2pinfo(const struct net_device *dev) 5208c2ecf20Sopenharmony_ci{ 5218c2ecf20Sopenharmony_ci return netdev_priv(dev); 5228c2ecf20Sopenharmony_ci} 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci/** 5258c2ecf20Sopenharmony_ci * adap2pinfo - return the port_info of a port 5268c2ecf20Sopenharmony_ci * @adap: the adapter 5278c2ecf20Sopenharmony_ci * @pidx: the port index 5288c2ecf20Sopenharmony_ci * 5298c2ecf20Sopenharmony_ci * Return the port_info structure for the adapter. 5308c2ecf20Sopenharmony_ci */ 5318c2ecf20Sopenharmony_cistatic inline struct port_info *adap2pinfo(struct adapter *adapter, int pidx) 5328c2ecf20Sopenharmony_ci{ 5338c2ecf20Sopenharmony_ci return netdev_priv(adapter->port[pidx]); 5348c2ecf20Sopenharmony_ci} 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci/** 5378c2ecf20Sopenharmony_ci * netdev2adap - return the adapter structure associated with a net_device 5388c2ecf20Sopenharmony_ci * @dev: the netdev 5398c2ecf20Sopenharmony_ci * 5408c2ecf20Sopenharmony_ci * Return the struct adapter associated with a net_device 5418c2ecf20Sopenharmony_ci */ 5428c2ecf20Sopenharmony_cistatic inline struct adapter *netdev2adap(const struct net_device *dev) 5438c2ecf20Sopenharmony_ci{ 5448c2ecf20Sopenharmony_ci return netdev2pinfo(dev)->adapter; 5458c2ecf20Sopenharmony_ci} 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci/* 5488c2ecf20Sopenharmony_ci * OS "Callback" function declarations. These are functions that the OS code 5498c2ecf20Sopenharmony_ci * is "contracted" to provide for the common code. 5508c2ecf20Sopenharmony_ci */ 5518c2ecf20Sopenharmony_civoid t4vf_os_link_changed(struct adapter *, int, int); 5528c2ecf20Sopenharmony_civoid t4vf_os_portmod_changed(struct adapter *, int); 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci/* 5558c2ecf20Sopenharmony_ci * SGE function prototype declarations. 5568c2ecf20Sopenharmony_ci */ 5578c2ecf20Sopenharmony_ciint t4vf_sge_alloc_rxq(struct adapter *, struct sge_rspq *, bool, 5588c2ecf20Sopenharmony_ci struct net_device *, int, 5598c2ecf20Sopenharmony_ci struct sge_fl *, rspq_handler_t); 5608c2ecf20Sopenharmony_ciint t4vf_sge_alloc_eth_txq(struct adapter *, struct sge_eth_txq *, 5618c2ecf20Sopenharmony_ci struct net_device *, struct netdev_queue *, 5628c2ecf20Sopenharmony_ci unsigned int); 5638c2ecf20Sopenharmony_civoid t4vf_free_sge_resources(struct adapter *); 5648c2ecf20Sopenharmony_ci 5658c2ecf20Sopenharmony_cinetdev_tx_t t4vf_eth_xmit(struct sk_buff *, struct net_device *); 5668c2ecf20Sopenharmony_ciint t4vf_ethrx_handler(struct sge_rspq *, const __be64 *, 5678c2ecf20Sopenharmony_ci const struct pkt_gl *); 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ciirq_handler_t t4vf_intr_handler(struct adapter *); 5708c2ecf20Sopenharmony_ciirqreturn_t t4vf_sge_intr_msix(int, void *); 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ciint t4vf_sge_init(struct adapter *); 5738c2ecf20Sopenharmony_civoid t4vf_sge_start(struct adapter *); 5748c2ecf20Sopenharmony_civoid t4vf_sge_stop(struct adapter *); 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_ci#endif /* __CXGB4VF_ADAPTER_H__ */ 577