162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * This file is part of the Chelsio T4 Ethernet driver for Linux. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (c) 2003-2016 Chelsio Communications, Inc. All rights reserved. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * This software is available to you under a choice of one of two 762306a36Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 862306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 962306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the 1062306a36Sopenharmony_ci * OpenIB.org BSD license below: 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or 1362306a36Sopenharmony_ci * without modification, are permitted provided that the following 1462306a36Sopenharmony_ci * conditions are met: 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * - Redistributions of source code must retain the above 1762306a36Sopenharmony_ci * copyright notice, this list of conditions and the following 1862306a36Sopenharmony_ci * disclaimer. 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * - Redistributions in binary form must reproduce the above 2162306a36Sopenharmony_ci * copyright notice, this list of conditions and the following 2262306a36Sopenharmony_ci * disclaimer in the documentation and/or other materials 2362306a36Sopenharmony_ci * provided with the distribution. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2662306a36Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2762306a36Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2862306a36Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 2962306a36Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3062306a36Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3162306a36Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3262306a36Sopenharmony_ci * SOFTWARE. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#ifndef __CXGB4_ULD_H 3662306a36Sopenharmony_ci#define __CXGB4_ULD_H 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#include <linux/cache.h> 3962306a36Sopenharmony_ci#include <linux/spinlock.h> 4062306a36Sopenharmony_ci#include <linux/skbuff.h> 4162306a36Sopenharmony_ci#include <linux/inetdevice.h> 4262306a36Sopenharmony_ci#include <linux/atomic.h> 4362306a36Sopenharmony_ci#include <net/tls.h> 4462306a36Sopenharmony_ci#include "cxgb4.h" 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#define MAX_ULD_QSETS 16 4762306a36Sopenharmony_ci#define MAX_ULD_NPORTS 4 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci/* ulp_mem_io + ulptx_idata + payload + padding */ 5062306a36Sopenharmony_ci#define MAX_IMM_ULPTX_WR_LEN (32 + 8 + 256 + 8) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* CPL message priority levels */ 5362306a36Sopenharmony_cienum { 5462306a36Sopenharmony_ci CPL_PRIORITY_DATA = 0, /* data messages */ 5562306a36Sopenharmony_ci CPL_PRIORITY_SETUP = 1, /* connection setup messages */ 5662306a36Sopenharmony_ci CPL_PRIORITY_TEARDOWN = 0, /* connection teardown messages */ 5762306a36Sopenharmony_ci CPL_PRIORITY_LISTEN = 1, /* listen start/stop messages */ 5862306a36Sopenharmony_ci CPL_PRIORITY_ACK = 1, /* RX ACK messages */ 5962306a36Sopenharmony_ci CPL_PRIORITY_CONTROL = 1 /* control messages */ 6062306a36Sopenharmony_ci}; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci#define INIT_TP_WR(w, tid) do { \ 6362306a36Sopenharmony_ci (w)->wr.wr_hi = htonl(FW_WR_OP_V(FW_TP_WR) | \ 6462306a36Sopenharmony_ci FW_WR_IMMDLEN_V(sizeof(*w) - sizeof(w->wr))); \ 6562306a36Sopenharmony_ci (w)->wr.wr_mid = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*w), 16)) | \ 6662306a36Sopenharmony_ci FW_WR_FLOWID_V(tid)); \ 6762306a36Sopenharmony_ci (w)->wr.wr_lo = cpu_to_be64(0); \ 6862306a36Sopenharmony_ci} while (0) 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci#define INIT_TP_WR_CPL(w, cpl, tid) do { \ 7162306a36Sopenharmony_ci INIT_TP_WR(w, tid); \ 7262306a36Sopenharmony_ci OPCODE_TID(w) = htonl(MK_OPCODE_TID(cpl, tid)); \ 7362306a36Sopenharmony_ci} while (0) 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci#define INIT_ULPTX_WR(w, wrlen, atomic, tid) do { \ 7662306a36Sopenharmony_ci (w)->wr.wr_hi = htonl(FW_WR_OP_V(FW_ULPTX_WR) | \ 7762306a36Sopenharmony_ci FW_WR_ATOMIC_V(atomic)); \ 7862306a36Sopenharmony_ci (w)->wr.wr_mid = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(wrlen, 16)) | \ 7962306a36Sopenharmony_ci FW_WR_FLOWID_V(tid)); \ 8062306a36Sopenharmony_ci (w)->wr.wr_lo = cpu_to_be64(0); \ 8162306a36Sopenharmony_ci} while (0) 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci/* Special asynchronous notification message */ 8462306a36Sopenharmony_ci#define CXGB4_MSG_AN ((void *)1) 8562306a36Sopenharmony_ci#define TX_ULD(uld)(((uld) != CXGB4_ULD_CRYPTO) ? CXGB4_TX_OFLD :\ 8662306a36Sopenharmony_ci CXGB4_TX_CRYPTO) 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistruct serv_entry { 8962306a36Sopenharmony_ci void *data; 9062306a36Sopenharmony_ci}; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ciunion aopen_entry { 9362306a36Sopenharmony_ci void *data; 9462306a36Sopenharmony_ci union aopen_entry *next; 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistruct eotid_entry { 9862306a36Sopenharmony_ci void *data; 9962306a36Sopenharmony_ci}; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/* 10262306a36Sopenharmony_ci * Holds the size, base address, free list start, etc of the TID, server TID, 10362306a36Sopenharmony_ci * and active-open TID tables. The tables themselves are allocated dynamically. 10462306a36Sopenharmony_ci */ 10562306a36Sopenharmony_cistruct tid_info { 10662306a36Sopenharmony_ci void **tid_tab; 10762306a36Sopenharmony_ci unsigned int tid_base; 10862306a36Sopenharmony_ci unsigned int ntids; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci struct serv_entry *stid_tab; 11162306a36Sopenharmony_ci unsigned long *stid_bmap; 11262306a36Sopenharmony_ci unsigned int nstids; 11362306a36Sopenharmony_ci unsigned int stid_base; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci unsigned int nhash; 11662306a36Sopenharmony_ci unsigned int hash_base; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci union aopen_entry *atid_tab; 11962306a36Sopenharmony_ci unsigned int natids; 12062306a36Sopenharmony_ci unsigned int atid_base; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci struct filter_entry *hpftid_tab; 12362306a36Sopenharmony_ci unsigned long *hpftid_bmap; 12462306a36Sopenharmony_ci unsigned int nhpftids; 12562306a36Sopenharmony_ci unsigned int hpftid_base; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci struct filter_entry *ftid_tab; 12862306a36Sopenharmony_ci unsigned long *ftid_bmap; 12962306a36Sopenharmony_ci unsigned int nftids; 13062306a36Sopenharmony_ci unsigned int ftid_base; 13162306a36Sopenharmony_ci unsigned int aftid_base; 13262306a36Sopenharmony_ci unsigned int aftid_end; 13362306a36Sopenharmony_ci /* Server filter region */ 13462306a36Sopenharmony_ci unsigned int sftid_base; 13562306a36Sopenharmony_ci unsigned int nsftids; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci spinlock_t atid_lock ____cacheline_aligned_in_smp; 13862306a36Sopenharmony_ci union aopen_entry *afree; 13962306a36Sopenharmony_ci unsigned int atids_in_use; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci spinlock_t stid_lock; 14262306a36Sopenharmony_ci unsigned int stids_in_use; 14362306a36Sopenharmony_ci unsigned int v6_stids_in_use; 14462306a36Sopenharmony_ci unsigned int sftids_in_use; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci /* ETHOFLD range */ 14762306a36Sopenharmony_ci struct eotid_entry *eotid_tab; 14862306a36Sopenharmony_ci unsigned long *eotid_bmap; 14962306a36Sopenharmony_ci unsigned int eotid_base; 15062306a36Sopenharmony_ci unsigned int neotids; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci /* TIDs in the TCAM */ 15362306a36Sopenharmony_ci atomic_t tids_in_use; 15462306a36Sopenharmony_ci /* TIDs in the HASH */ 15562306a36Sopenharmony_ci atomic_t hash_tids_in_use; 15662306a36Sopenharmony_ci atomic_t conns_in_use; 15762306a36Sopenharmony_ci /* ETHOFLD TIDs used for rate limiting */ 15862306a36Sopenharmony_ci atomic_t eotids_in_use; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci /* lock for setting/clearing filter bitmap */ 16162306a36Sopenharmony_ci spinlock_t ftid_lock; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci unsigned int tc_hash_tids_max_prio; 16462306a36Sopenharmony_ci}; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cistatic inline void *lookup_tid(const struct tid_info *t, unsigned int tid) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci tid -= t->tid_base; 16962306a36Sopenharmony_ci return tid < t->ntids ? t->tid_tab[tid] : NULL; 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistatic inline bool tid_out_of_range(const struct tid_info *t, unsigned int tid) 17362306a36Sopenharmony_ci{ 17462306a36Sopenharmony_ci return ((tid - t->tid_base) >= t->ntids); 17562306a36Sopenharmony_ci} 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistatic inline void *lookup_atid(const struct tid_info *t, unsigned int atid) 17862306a36Sopenharmony_ci{ 17962306a36Sopenharmony_ci return atid < t->natids ? t->atid_tab[atid].data : NULL; 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistatic inline void *lookup_stid(const struct tid_info *t, unsigned int stid) 18362306a36Sopenharmony_ci{ 18462306a36Sopenharmony_ci /* Is it a server filter TID? */ 18562306a36Sopenharmony_ci if (t->nsftids && (stid >= t->sftid_base)) { 18662306a36Sopenharmony_ci stid -= t->sftid_base; 18762306a36Sopenharmony_ci stid += t->nstids; 18862306a36Sopenharmony_ci } else { 18962306a36Sopenharmony_ci stid -= t->stid_base; 19062306a36Sopenharmony_ci } 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci return stid < (t->nstids + t->nsftids) ? t->stid_tab[stid].data : NULL; 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistatic inline void cxgb4_insert_tid(struct tid_info *t, void *data, 19662306a36Sopenharmony_ci unsigned int tid, unsigned short family) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci t->tid_tab[tid - t->tid_base] = data; 19962306a36Sopenharmony_ci if (t->hash_base && (tid >= t->hash_base)) { 20062306a36Sopenharmony_ci if (family == AF_INET6) 20162306a36Sopenharmony_ci atomic_add(2, &t->hash_tids_in_use); 20262306a36Sopenharmony_ci else 20362306a36Sopenharmony_ci atomic_inc(&t->hash_tids_in_use); 20462306a36Sopenharmony_ci } else { 20562306a36Sopenharmony_ci if (family == AF_INET6) 20662306a36Sopenharmony_ci atomic_add(2, &t->tids_in_use); 20762306a36Sopenharmony_ci else 20862306a36Sopenharmony_ci atomic_inc(&t->tids_in_use); 20962306a36Sopenharmony_ci } 21062306a36Sopenharmony_ci atomic_inc(&t->conns_in_use); 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_cistatic inline struct eotid_entry *cxgb4_lookup_eotid(struct tid_info *t, 21462306a36Sopenharmony_ci u32 eotid) 21562306a36Sopenharmony_ci{ 21662306a36Sopenharmony_ci return eotid < t->neotids ? &t->eotid_tab[eotid] : NULL; 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistatic inline int cxgb4_get_free_eotid(struct tid_info *t) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci int eotid; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci eotid = find_first_zero_bit(t->eotid_bmap, t->neotids); 22462306a36Sopenharmony_ci if (eotid >= t->neotids) 22562306a36Sopenharmony_ci eotid = -1; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci return eotid; 22862306a36Sopenharmony_ci} 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_cistatic inline void cxgb4_alloc_eotid(struct tid_info *t, u32 eotid, void *data) 23162306a36Sopenharmony_ci{ 23262306a36Sopenharmony_ci set_bit(eotid, t->eotid_bmap); 23362306a36Sopenharmony_ci t->eotid_tab[eotid].data = data; 23462306a36Sopenharmony_ci atomic_inc(&t->eotids_in_use); 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic inline void cxgb4_free_eotid(struct tid_info *t, u32 eotid) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci clear_bit(eotid, t->eotid_bmap); 24062306a36Sopenharmony_ci t->eotid_tab[eotid].data = NULL; 24162306a36Sopenharmony_ci atomic_dec(&t->eotids_in_use); 24262306a36Sopenharmony_ci} 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ciint cxgb4_alloc_atid(struct tid_info *t, void *data); 24562306a36Sopenharmony_ciint cxgb4_alloc_stid(struct tid_info *t, int family, void *data); 24662306a36Sopenharmony_ciint cxgb4_alloc_sftid(struct tid_info *t, int family, void *data); 24762306a36Sopenharmony_civoid cxgb4_free_atid(struct tid_info *t, unsigned int atid); 24862306a36Sopenharmony_civoid cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family); 24962306a36Sopenharmony_civoid cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid, 25062306a36Sopenharmony_ci unsigned short family); 25162306a36Sopenharmony_cistruct in6_addr; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ciint cxgb4_create_server(const struct net_device *dev, unsigned int stid, 25462306a36Sopenharmony_ci __be32 sip, __be16 sport, __be16 vlan, 25562306a36Sopenharmony_ci unsigned int queue); 25662306a36Sopenharmony_ciint cxgb4_create_server6(const struct net_device *dev, unsigned int stid, 25762306a36Sopenharmony_ci const struct in6_addr *sip, __be16 sport, 25862306a36Sopenharmony_ci unsigned int queue); 25962306a36Sopenharmony_ciint cxgb4_remove_server(const struct net_device *dev, unsigned int stid, 26062306a36Sopenharmony_ci unsigned int queue, bool ipv6); 26162306a36Sopenharmony_ciint cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid, 26262306a36Sopenharmony_ci __be32 sip, __be16 sport, __be16 vlan, 26362306a36Sopenharmony_ci unsigned int queue, 26462306a36Sopenharmony_ci unsigned char port, unsigned char mask); 26562306a36Sopenharmony_ciint cxgb4_remove_server_filter(const struct net_device *dev, unsigned int stid, 26662306a36Sopenharmony_ci unsigned int queue, bool ipv6); 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci/* Filter operation context to allow callers of cxgb4_set_filter() and 26962306a36Sopenharmony_ci * cxgb4_del_filter() to wait for an asynchronous completion. 27062306a36Sopenharmony_ci */ 27162306a36Sopenharmony_cistruct filter_ctx { 27262306a36Sopenharmony_ci struct completion completion; /* completion rendezvous */ 27362306a36Sopenharmony_ci void *closure; /* caller's opaque information */ 27462306a36Sopenharmony_ci int result; /* result of operation */ 27562306a36Sopenharmony_ci u32 tid; /* to store tid */ 27662306a36Sopenharmony_ci}; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_cistruct chcr_ktls { 27962306a36Sopenharmony_ci refcount_t ktls_refcount; 28062306a36Sopenharmony_ci}; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_cistruct ch_filter_specification; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ciint cxgb4_get_free_ftid(struct net_device *dev, u8 family, bool hash_en, 28562306a36Sopenharmony_ci u32 tc_prio); 28662306a36Sopenharmony_ciint __cxgb4_set_filter(struct net_device *dev, int filter_id, 28762306a36Sopenharmony_ci struct ch_filter_specification *fs, 28862306a36Sopenharmony_ci struct filter_ctx *ctx); 28962306a36Sopenharmony_ciint __cxgb4_del_filter(struct net_device *dev, int filter_id, 29062306a36Sopenharmony_ci struct ch_filter_specification *fs, 29162306a36Sopenharmony_ci struct filter_ctx *ctx); 29262306a36Sopenharmony_ciint cxgb4_set_filter(struct net_device *dev, int filter_id, 29362306a36Sopenharmony_ci struct ch_filter_specification *fs); 29462306a36Sopenharmony_ciint cxgb4_del_filter(struct net_device *dev, int filter_id, 29562306a36Sopenharmony_ci struct ch_filter_specification *fs); 29662306a36Sopenharmony_ciint cxgb4_get_filter_counters(struct net_device *dev, unsigned int fidx, 29762306a36Sopenharmony_ci u64 *hitcnt, u64 *bytecnt, bool hash); 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_cistatic inline void set_wr_txq(struct sk_buff *skb, int prio, int queue) 30062306a36Sopenharmony_ci{ 30162306a36Sopenharmony_ci skb_set_queue_mapping(skb, (queue << 1) | prio); 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_cienum cxgb4_uld { 30562306a36Sopenharmony_ci CXGB4_ULD_INIT, 30662306a36Sopenharmony_ci CXGB4_ULD_RDMA, 30762306a36Sopenharmony_ci CXGB4_ULD_ISCSI, 30862306a36Sopenharmony_ci CXGB4_ULD_ISCSIT, 30962306a36Sopenharmony_ci CXGB4_ULD_CRYPTO, 31062306a36Sopenharmony_ci CXGB4_ULD_IPSEC, 31162306a36Sopenharmony_ci CXGB4_ULD_TLS, 31262306a36Sopenharmony_ci CXGB4_ULD_KTLS, 31362306a36Sopenharmony_ci CXGB4_ULD_MAX 31462306a36Sopenharmony_ci}; 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_cienum cxgb4_tx_uld { 31762306a36Sopenharmony_ci CXGB4_TX_OFLD, 31862306a36Sopenharmony_ci CXGB4_TX_CRYPTO, 31962306a36Sopenharmony_ci CXGB4_TX_MAX 32062306a36Sopenharmony_ci}; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_cienum cxgb4_txq_type { 32362306a36Sopenharmony_ci CXGB4_TXQ_ETH, 32462306a36Sopenharmony_ci CXGB4_TXQ_ULD, 32562306a36Sopenharmony_ci CXGB4_TXQ_CTRL, 32662306a36Sopenharmony_ci CXGB4_TXQ_MAX 32762306a36Sopenharmony_ci}; 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_cienum cxgb4_state { 33062306a36Sopenharmony_ci CXGB4_STATE_UP, 33162306a36Sopenharmony_ci CXGB4_STATE_START_RECOVERY, 33262306a36Sopenharmony_ci CXGB4_STATE_DOWN, 33362306a36Sopenharmony_ci CXGB4_STATE_DETACH, 33462306a36Sopenharmony_ci CXGB4_STATE_FATAL_ERROR 33562306a36Sopenharmony_ci}; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_cienum cxgb4_control { 33862306a36Sopenharmony_ci CXGB4_CONTROL_DB_FULL, 33962306a36Sopenharmony_ci CXGB4_CONTROL_DB_EMPTY, 34062306a36Sopenharmony_ci CXGB4_CONTROL_DB_DROP, 34162306a36Sopenharmony_ci}; 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cistruct adapter; 34462306a36Sopenharmony_cistruct pci_dev; 34562306a36Sopenharmony_cistruct l2t_data; 34662306a36Sopenharmony_cistruct net_device; 34762306a36Sopenharmony_cistruct pkt_gl; 34862306a36Sopenharmony_cistruct tp_tcp_stats; 34962306a36Sopenharmony_cistruct t4_lro_mgr; 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_cistruct cxgb4_range { 35262306a36Sopenharmony_ci unsigned int start; 35362306a36Sopenharmony_ci unsigned int size; 35462306a36Sopenharmony_ci}; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_cistruct cxgb4_virt_res { /* virtualized HW resources */ 35762306a36Sopenharmony_ci struct cxgb4_range ddp; 35862306a36Sopenharmony_ci struct cxgb4_range iscsi; 35962306a36Sopenharmony_ci struct cxgb4_range stag; 36062306a36Sopenharmony_ci struct cxgb4_range rq; 36162306a36Sopenharmony_ci struct cxgb4_range srq; 36262306a36Sopenharmony_ci struct cxgb4_range pbl; 36362306a36Sopenharmony_ci struct cxgb4_range qp; 36462306a36Sopenharmony_ci struct cxgb4_range cq; 36562306a36Sopenharmony_ci struct cxgb4_range ocq; 36662306a36Sopenharmony_ci struct cxgb4_range key; 36762306a36Sopenharmony_ci unsigned int ncrypto_fc; 36862306a36Sopenharmony_ci struct cxgb4_range ppod_edram; 36962306a36Sopenharmony_ci}; 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE) 37262306a36Sopenharmony_cistruct ch_ktls_port_stats_debug { 37362306a36Sopenharmony_ci atomic64_t ktls_tx_connection_open; 37462306a36Sopenharmony_ci atomic64_t ktls_tx_connection_fail; 37562306a36Sopenharmony_ci atomic64_t ktls_tx_connection_close; 37662306a36Sopenharmony_ci atomic64_t ktls_tx_encrypted_packets; 37762306a36Sopenharmony_ci atomic64_t ktls_tx_encrypted_bytes; 37862306a36Sopenharmony_ci atomic64_t ktls_tx_ctx; 37962306a36Sopenharmony_ci atomic64_t ktls_tx_ooo; 38062306a36Sopenharmony_ci atomic64_t ktls_tx_skip_no_sync_data; 38162306a36Sopenharmony_ci atomic64_t ktls_tx_drop_no_sync_data; 38262306a36Sopenharmony_ci atomic64_t ktls_tx_drop_bypass_req; 38362306a36Sopenharmony_ci}; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_cistruct ch_ktls_stats_debug { 38662306a36Sopenharmony_ci struct ch_ktls_port_stats_debug ktls_port[MAX_ULD_NPORTS]; 38762306a36Sopenharmony_ci atomic64_t ktls_tx_send_records; 38862306a36Sopenharmony_ci atomic64_t ktls_tx_end_pkts; 38962306a36Sopenharmony_ci atomic64_t ktls_tx_start_pkts; 39062306a36Sopenharmony_ci atomic64_t ktls_tx_middle_pkts; 39162306a36Sopenharmony_ci atomic64_t ktls_tx_retransmit_pkts; 39262306a36Sopenharmony_ci atomic64_t ktls_tx_complete_pkts; 39362306a36Sopenharmony_ci atomic64_t ktls_tx_trimmed_pkts; 39462306a36Sopenharmony_ci atomic64_t ktls_tx_fallback; 39562306a36Sopenharmony_ci}; 39662306a36Sopenharmony_ci#endif 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_cistruct chcr_stats_debug { 39962306a36Sopenharmony_ci atomic_t cipher_rqst; 40062306a36Sopenharmony_ci atomic_t digest_rqst; 40162306a36Sopenharmony_ci atomic_t aead_rqst; 40262306a36Sopenharmony_ci atomic_t complete; 40362306a36Sopenharmony_ci atomic_t error; 40462306a36Sopenharmony_ci atomic_t fallback; 40562306a36Sopenharmony_ci atomic_t tls_pdu_tx; 40662306a36Sopenharmony_ci atomic_t tls_pdu_rx; 40762306a36Sopenharmony_ci atomic_t tls_key; 40862306a36Sopenharmony_ci}; 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE) 41162306a36Sopenharmony_cistruct ch_ipsec_stats_debug { 41262306a36Sopenharmony_ci atomic_t ipsec_cnt; 41362306a36Sopenharmony_ci}; 41462306a36Sopenharmony_ci#endif 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci#define OCQ_WIN_OFFSET(pdev, vres) \ 41762306a36Sopenharmony_ci (pci_resource_len((pdev), 2) - roundup_pow_of_two((vres)->ocq.size)) 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci/* 42062306a36Sopenharmony_ci * Block of information the LLD provides to ULDs attaching to a device. 42162306a36Sopenharmony_ci */ 42262306a36Sopenharmony_cistruct cxgb4_lld_info { 42362306a36Sopenharmony_ci struct pci_dev *pdev; /* associated PCI device */ 42462306a36Sopenharmony_ci struct l2t_data *l2t; /* L2 table */ 42562306a36Sopenharmony_ci struct tid_info *tids; /* TID table */ 42662306a36Sopenharmony_ci struct net_device **ports; /* device ports */ 42762306a36Sopenharmony_ci const struct cxgb4_virt_res *vr; /* assorted HW resources */ 42862306a36Sopenharmony_ci const unsigned short *mtus; /* MTU table */ 42962306a36Sopenharmony_ci const unsigned short *rxq_ids; /* the ULD's Rx queue ids */ 43062306a36Sopenharmony_ci const unsigned short *ciq_ids; /* the ULD's concentrator IQ ids */ 43162306a36Sopenharmony_ci unsigned short nrxq; /* # of Rx queues */ 43262306a36Sopenharmony_ci unsigned short ntxq; /* # of Tx queues */ 43362306a36Sopenharmony_ci unsigned short nciq; /* # of concentrator IQ */ 43462306a36Sopenharmony_ci unsigned char nchan:4; /* # of channels */ 43562306a36Sopenharmony_ci unsigned char nports:4; /* # of ports */ 43662306a36Sopenharmony_ci unsigned char wr_cred; /* WR 16-byte credits */ 43762306a36Sopenharmony_ci unsigned char adapter_type; /* type of adapter */ 43862306a36Sopenharmony_ci unsigned char fw_api_ver; /* FW API version */ 43962306a36Sopenharmony_ci unsigned char crypto; /* crypto support */ 44062306a36Sopenharmony_ci unsigned int fw_vers; /* FW version */ 44162306a36Sopenharmony_ci unsigned int iscsi_iolen; /* iSCSI max I/O length */ 44262306a36Sopenharmony_ci unsigned int cclk_ps; /* Core clock period in psec */ 44362306a36Sopenharmony_ci unsigned short udb_density; /* # of user DB/page */ 44462306a36Sopenharmony_ci unsigned short ucq_density; /* # of user CQs/page */ 44562306a36Sopenharmony_ci unsigned int sge_host_page_size; /* SGE host page size */ 44662306a36Sopenharmony_ci unsigned short filt_mode; /* filter optional components */ 44762306a36Sopenharmony_ci unsigned short tx_modq[NCHAN]; /* maps each tx channel to a */ 44862306a36Sopenharmony_ci /* scheduler queue */ 44962306a36Sopenharmony_ci void __iomem *gts_reg; /* address of GTS register */ 45062306a36Sopenharmony_ci void __iomem *db_reg; /* address of kernel doorbell */ 45162306a36Sopenharmony_ci int dbfifo_int_thresh; /* doorbell fifo int threshold */ 45262306a36Sopenharmony_ci unsigned int sge_ingpadboundary; /* SGE ingress padding boundary */ 45362306a36Sopenharmony_ci unsigned int sge_egrstatuspagesize; /* SGE egress status page size */ 45462306a36Sopenharmony_ci unsigned int sge_pktshift; /* Padding between CPL and */ 45562306a36Sopenharmony_ci /* packet data */ 45662306a36Sopenharmony_ci unsigned int pf; /* Physical Function we're using */ 45762306a36Sopenharmony_ci bool enable_fw_ofld_conn; /* Enable connection through fw */ 45862306a36Sopenharmony_ci /* WR */ 45962306a36Sopenharmony_ci unsigned int max_ordird_qp; /* Max ORD/IRD depth per RDMA QP */ 46062306a36Sopenharmony_ci unsigned int max_ird_adapter; /* Max IRD memory per adapter */ 46162306a36Sopenharmony_ci bool ulptx_memwrite_dsgl; /* use of T5 DSGL allowed */ 46262306a36Sopenharmony_ci unsigned int iscsi_tagmask; /* iscsi ddp tag mask */ 46362306a36Sopenharmony_ci unsigned int iscsi_pgsz_order; /* iscsi ddp page size orders */ 46462306a36Sopenharmony_ci unsigned int iscsi_llimit; /* chip's iscsi region llimit */ 46562306a36Sopenharmony_ci unsigned int ulp_crypto; /* crypto lookaside support */ 46662306a36Sopenharmony_ci void **iscsi_ppm; /* iscsi page pod manager */ 46762306a36Sopenharmony_ci int nodeid; /* device numa node id */ 46862306a36Sopenharmony_ci bool fr_nsmr_tpte_wr_support; /* FW supports FR_NSMR_TPTE_WR */ 46962306a36Sopenharmony_ci bool write_w_imm_support; /* FW supports WRITE_WITH_IMMEDIATE */ 47062306a36Sopenharmony_ci bool write_cmpl_support; /* FW supports WRITE_CMPL WR */ 47162306a36Sopenharmony_ci}; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_cistruct cxgb4_uld_info { 47462306a36Sopenharmony_ci char name[IFNAMSIZ]; 47562306a36Sopenharmony_ci void *handle; 47662306a36Sopenharmony_ci unsigned int nrxq; 47762306a36Sopenharmony_ci unsigned int rxq_size; 47862306a36Sopenharmony_ci unsigned int ntxq; 47962306a36Sopenharmony_ci bool ciq; 48062306a36Sopenharmony_ci bool lro; 48162306a36Sopenharmony_ci void *(*add)(const struct cxgb4_lld_info *p); 48262306a36Sopenharmony_ci int (*rx_handler)(void *handle, const __be64 *rsp, 48362306a36Sopenharmony_ci const struct pkt_gl *gl); 48462306a36Sopenharmony_ci int (*state_change)(void *handle, enum cxgb4_state new_state); 48562306a36Sopenharmony_ci int (*control)(void *handle, enum cxgb4_control control, ...); 48662306a36Sopenharmony_ci int (*lro_rx_handler)(void *handle, const __be64 *rsp, 48762306a36Sopenharmony_ci const struct pkt_gl *gl, 48862306a36Sopenharmony_ci struct t4_lro_mgr *lro_mgr, 48962306a36Sopenharmony_ci struct napi_struct *napi); 49062306a36Sopenharmony_ci void (*lro_flush)(struct t4_lro_mgr *); 49162306a36Sopenharmony_ci int (*tx_handler)(struct sk_buff *skb, struct net_device *dev); 49262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE) 49362306a36Sopenharmony_ci const struct tlsdev_ops *tlsdev_ops; 49462306a36Sopenharmony_ci#endif 49562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_XFRM_OFFLOAD) 49662306a36Sopenharmony_ci const struct xfrmdev_ops *xfrmdev_ops; 49762306a36Sopenharmony_ci#endif 49862306a36Sopenharmony_ci}; 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_civoid cxgb4_uld_enable(struct adapter *adap); 50162306a36Sopenharmony_civoid cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p); 50262306a36Sopenharmony_ciint cxgb4_unregister_uld(enum cxgb4_uld type); 50362306a36Sopenharmony_ciint cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb); 50462306a36Sopenharmony_ciint cxgb4_immdata_send(struct net_device *dev, unsigned int idx, 50562306a36Sopenharmony_ci const void *src, unsigned int len); 50662306a36Sopenharmony_ciint cxgb4_crypto_send(struct net_device *dev, struct sk_buff *skb); 50762306a36Sopenharmony_ciunsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo); 50862306a36Sopenharmony_ciunsigned int cxgb4_port_chan(const struct net_device *dev); 50962306a36Sopenharmony_ciunsigned int cxgb4_port_e2cchan(const struct net_device *dev); 51062306a36Sopenharmony_ciunsigned int cxgb4_port_viid(const struct net_device *dev); 51162306a36Sopenharmony_ciunsigned int cxgb4_tp_smt_idx(enum chip_type chip, unsigned int viid); 51262306a36Sopenharmony_ciunsigned int cxgb4_port_idx(const struct net_device *dev); 51362306a36Sopenharmony_ciunsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu, 51462306a36Sopenharmony_ci unsigned int *idx); 51562306a36Sopenharmony_ciunsigned int cxgb4_best_aligned_mtu(const unsigned short *mtus, 51662306a36Sopenharmony_ci unsigned short header_size, 51762306a36Sopenharmony_ci unsigned short data_size_max, 51862306a36Sopenharmony_ci unsigned short data_size_align, 51962306a36Sopenharmony_ci unsigned int *mtu_idxp); 52062306a36Sopenharmony_civoid cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4, 52162306a36Sopenharmony_ci struct tp_tcp_stats *v6); 52262306a36Sopenharmony_civoid cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask, 52362306a36Sopenharmony_ci const unsigned int *pgsz_order); 52462306a36Sopenharmony_cistruct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl, 52562306a36Sopenharmony_ci unsigned int skb_len, unsigned int pull_len); 52662306a36Sopenharmony_ciint cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx, u16 size); 52762306a36Sopenharmony_ciint cxgb4_flush_eq_cache(struct net_device *dev); 52862306a36Sopenharmony_ciint cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte); 52962306a36Sopenharmony_ciu64 cxgb4_read_sge_timestamp(struct net_device *dev); 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_cienum cxgb4_bar2_qtype { CXGB4_BAR2_QTYPE_EGRESS, CXGB4_BAR2_QTYPE_INGRESS }; 53262306a36Sopenharmony_ciint cxgb4_bar2_sge_qregs(struct net_device *dev, 53362306a36Sopenharmony_ci unsigned int qid, 53462306a36Sopenharmony_ci enum cxgb4_bar2_qtype qtype, 53562306a36Sopenharmony_ci int user, 53662306a36Sopenharmony_ci u64 *pbar2_qoffset, 53762306a36Sopenharmony_ci unsigned int *pbar2_qid); 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci#endif /* !__CXGB4_ULD_H */ 540