18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * This file is part of the Chelsio T4 Ethernet driver for Linux.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (c) 2003-2016 Chelsio Communications, Inc. All rights reserved.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two
78c2ecf20Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
88c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
98c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the
108c2ecf20Sopenharmony_ci * OpenIB.org BSD license below:
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
138c2ecf20Sopenharmony_ci *     without modification, are permitted provided that the following
148c2ecf20Sopenharmony_ci *     conditions are met:
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci *      - Redistributions of source code must retain the above
178c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
188c2ecf20Sopenharmony_ci *        disclaimer.
198c2ecf20Sopenharmony_ci *
208c2ecf20Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
218c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
228c2ecf20Sopenharmony_ci *        disclaimer in the documentation and/or other materials
238c2ecf20Sopenharmony_ci *        provided with the distribution.
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
268c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
278c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
288c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
298c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
308c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
318c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
328c2ecf20Sopenharmony_ci * SOFTWARE.
338c2ecf20Sopenharmony_ci */
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#ifndef __CXGB4_ULD_H
368c2ecf20Sopenharmony_ci#define __CXGB4_ULD_H
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#include <linux/cache.h>
398c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
408c2ecf20Sopenharmony_ci#include <linux/skbuff.h>
418c2ecf20Sopenharmony_ci#include <linux/inetdevice.h>
428c2ecf20Sopenharmony_ci#include <linux/atomic.h>
438c2ecf20Sopenharmony_ci#include <net/tls.h>
448c2ecf20Sopenharmony_ci#include "cxgb4.h"
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#define MAX_ULD_QSETS 16
478c2ecf20Sopenharmony_ci#define MAX_ULD_NPORTS 4
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/* ulp_mem_io + ulptx_idata + payload + padding */
508c2ecf20Sopenharmony_ci#define MAX_IMM_ULPTX_WR_LEN (32 + 8 + 256 + 8)
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/* CPL message priority levels */
538c2ecf20Sopenharmony_cienum {
548c2ecf20Sopenharmony_ci	CPL_PRIORITY_DATA     = 0,  /* data messages */
558c2ecf20Sopenharmony_ci	CPL_PRIORITY_SETUP    = 1,  /* connection setup messages */
568c2ecf20Sopenharmony_ci	CPL_PRIORITY_TEARDOWN = 0,  /* connection teardown messages */
578c2ecf20Sopenharmony_ci	CPL_PRIORITY_LISTEN   = 1,  /* listen start/stop messages */
588c2ecf20Sopenharmony_ci	CPL_PRIORITY_ACK      = 1,  /* RX ACK messages */
598c2ecf20Sopenharmony_ci	CPL_PRIORITY_CONTROL  = 1   /* control messages */
608c2ecf20Sopenharmony_ci};
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci#define INIT_TP_WR(w, tid) do { \
638c2ecf20Sopenharmony_ci	(w)->wr.wr_hi = htonl(FW_WR_OP_V(FW_TP_WR) | \
648c2ecf20Sopenharmony_ci			      FW_WR_IMMDLEN_V(sizeof(*w) - sizeof(w->wr))); \
658c2ecf20Sopenharmony_ci	(w)->wr.wr_mid = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*w), 16)) | \
668c2ecf20Sopenharmony_ci			       FW_WR_FLOWID_V(tid)); \
678c2ecf20Sopenharmony_ci	(w)->wr.wr_lo = cpu_to_be64(0); \
688c2ecf20Sopenharmony_ci} while (0)
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#define INIT_TP_WR_CPL(w, cpl, tid) do { \
718c2ecf20Sopenharmony_ci	INIT_TP_WR(w, tid); \
728c2ecf20Sopenharmony_ci	OPCODE_TID(w) = htonl(MK_OPCODE_TID(cpl, tid)); \
738c2ecf20Sopenharmony_ci} while (0)
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci#define INIT_ULPTX_WR(w, wrlen, atomic, tid) do { \
768c2ecf20Sopenharmony_ci	(w)->wr.wr_hi = htonl(FW_WR_OP_V(FW_ULPTX_WR) | \
778c2ecf20Sopenharmony_ci			      FW_WR_ATOMIC_V(atomic)); \
788c2ecf20Sopenharmony_ci	(w)->wr.wr_mid = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(wrlen, 16)) | \
798c2ecf20Sopenharmony_ci			       FW_WR_FLOWID_V(tid)); \
808c2ecf20Sopenharmony_ci	(w)->wr.wr_lo = cpu_to_be64(0); \
818c2ecf20Sopenharmony_ci} while (0)
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci/* Special asynchronous notification message */
848c2ecf20Sopenharmony_ci#define CXGB4_MSG_AN ((void *)1)
858c2ecf20Sopenharmony_ci#define TX_ULD(uld)(((uld) != CXGB4_ULD_CRYPTO) ? CXGB4_TX_OFLD :\
868c2ecf20Sopenharmony_ci		      CXGB4_TX_CRYPTO)
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_cistruct serv_entry {
898c2ecf20Sopenharmony_ci	void *data;
908c2ecf20Sopenharmony_ci};
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciunion aopen_entry {
938c2ecf20Sopenharmony_ci	void *data;
948c2ecf20Sopenharmony_ci	union aopen_entry *next;
958c2ecf20Sopenharmony_ci};
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistruct eotid_entry {
988c2ecf20Sopenharmony_ci	void *data;
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci/*
1028c2ecf20Sopenharmony_ci * Holds the size, base address, free list start, etc of the TID, server TID,
1038c2ecf20Sopenharmony_ci * and active-open TID tables.  The tables themselves are allocated dynamically.
1048c2ecf20Sopenharmony_ci */
1058c2ecf20Sopenharmony_cistruct tid_info {
1068c2ecf20Sopenharmony_ci	void **tid_tab;
1078c2ecf20Sopenharmony_ci	unsigned int tid_base;
1088c2ecf20Sopenharmony_ci	unsigned int ntids;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	struct serv_entry *stid_tab;
1118c2ecf20Sopenharmony_ci	unsigned long *stid_bmap;
1128c2ecf20Sopenharmony_ci	unsigned int nstids;
1138c2ecf20Sopenharmony_ci	unsigned int stid_base;
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	unsigned int nhash;
1168c2ecf20Sopenharmony_ci	unsigned int hash_base;
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	union aopen_entry *atid_tab;
1198c2ecf20Sopenharmony_ci	unsigned int natids;
1208c2ecf20Sopenharmony_ci	unsigned int atid_base;
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	struct filter_entry *hpftid_tab;
1238c2ecf20Sopenharmony_ci	unsigned long *hpftid_bmap;
1248c2ecf20Sopenharmony_ci	unsigned int nhpftids;
1258c2ecf20Sopenharmony_ci	unsigned int hpftid_base;
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	struct filter_entry *ftid_tab;
1288c2ecf20Sopenharmony_ci	unsigned long *ftid_bmap;
1298c2ecf20Sopenharmony_ci	unsigned int nftids;
1308c2ecf20Sopenharmony_ci	unsigned int ftid_base;
1318c2ecf20Sopenharmony_ci	unsigned int aftid_base;
1328c2ecf20Sopenharmony_ci	unsigned int aftid_end;
1338c2ecf20Sopenharmony_ci	/* Server filter region */
1348c2ecf20Sopenharmony_ci	unsigned int sftid_base;
1358c2ecf20Sopenharmony_ci	unsigned int nsftids;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	spinlock_t atid_lock ____cacheline_aligned_in_smp;
1388c2ecf20Sopenharmony_ci	union aopen_entry *afree;
1398c2ecf20Sopenharmony_ci	unsigned int atids_in_use;
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	spinlock_t stid_lock;
1428c2ecf20Sopenharmony_ci	unsigned int stids_in_use;
1438c2ecf20Sopenharmony_ci	unsigned int v6_stids_in_use;
1448c2ecf20Sopenharmony_ci	unsigned int sftids_in_use;
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	/* ETHOFLD range */
1478c2ecf20Sopenharmony_ci	struct eotid_entry *eotid_tab;
1488c2ecf20Sopenharmony_ci	unsigned long *eotid_bmap;
1498c2ecf20Sopenharmony_ci	unsigned int eotid_base;
1508c2ecf20Sopenharmony_ci	unsigned int neotids;
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci	/* TIDs in the TCAM */
1538c2ecf20Sopenharmony_ci	atomic_t tids_in_use;
1548c2ecf20Sopenharmony_ci	/* TIDs in the HASH */
1558c2ecf20Sopenharmony_ci	atomic_t hash_tids_in_use;
1568c2ecf20Sopenharmony_ci	atomic_t conns_in_use;
1578c2ecf20Sopenharmony_ci	/* ETHOFLD TIDs used for rate limiting */
1588c2ecf20Sopenharmony_ci	atomic_t eotids_in_use;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	/* lock for setting/clearing filter bitmap */
1618c2ecf20Sopenharmony_ci	spinlock_t ftid_lock;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	unsigned int tc_hash_tids_max_prio;
1648c2ecf20Sopenharmony_ci};
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_cistatic inline void *lookup_tid(const struct tid_info *t, unsigned int tid)
1678c2ecf20Sopenharmony_ci{
1688c2ecf20Sopenharmony_ci	tid -= t->tid_base;
1698c2ecf20Sopenharmony_ci	return tid < t->ntids ? t->tid_tab[tid] : NULL;
1708c2ecf20Sopenharmony_ci}
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_cistatic inline bool tid_out_of_range(const struct tid_info *t, unsigned int tid)
1738c2ecf20Sopenharmony_ci{
1748c2ecf20Sopenharmony_ci	return ((tid - t->tid_base) >= t->ntids);
1758c2ecf20Sopenharmony_ci}
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_cistatic inline void *lookup_atid(const struct tid_info *t, unsigned int atid)
1788c2ecf20Sopenharmony_ci{
1798c2ecf20Sopenharmony_ci	return atid < t->natids ? t->atid_tab[atid].data : NULL;
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic inline void *lookup_stid(const struct tid_info *t, unsigned int stid)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	/* Is it a server filter TID? */
1858c2ecf20Sopenharmony_ci	if (t->nsftids && (stid >= t->sftid_base)) {
1868c2ecf20Sopenharmony_ci		stid -= t->sftid_base;
1878c2ecf20Sopenharmony_ci		stid += t->nstids;
1888c2ecf20Sopenharmony_ci	} else {
1898c2ecf20Sopenharmony_ci		stid -= t->stid_base;
1908c2ecf20Sopenharmony_ci	}
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	return stid < (t->nstids + t->nsftids) ? t->stid_tab[stid].data : NULL;
1938c2ecf20Sopenharmony_ci}
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistatic inline void cxgb4_insert_tid(struct tid_info *t, void *data,
1968c2ecf20Sopenharmony_ci				    unsigned int tid, unsigned short family)
1978c2ecf20Sopenharmony_ci{
1988c2ecf20Sopenharmony_ci	t->tid_tab[tid - t->tid_base] = data;
1998c2ecf20Sopenharmony_ci	if (t->hash_base && (tid >= t->hash_base)) {
2008c2ecf20Sopenharmony_ci		if (family == AF_INET6)
2018c2ecf20Sopenharmony_ci			atomic_add(2, &t->hash_tids_in_use);
2028c2ecf20Sopenharmony_ci		else
2038c2ecf20Sopenharmony_ci			atomic_inc(&t->hash_tids_in_use);
2048c2ecf20Sopenharmony_ci	} else {
2058c2ecf20Sopenharmony_ci		if (family == AF_INET6)
2068c2ecf20Sopenharmony_ci			atomic_add(2, &t->tids_in_use);
2078c2ecf20Sopenharmony_ci		else
2088c2ecf20Sopenharmony_ci			atomic_inc(&t->tids_in_use);
2098c2ecf20Sopenharmony_ci	}
2108c2ecf20Sopenharmony_ci	atomic_inc(&t->conns_in_use);
2118c2ecf20Sopenharmony_ci}
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_cistatic inline struct eotid_entry *cxgb4_lookup_eotid(struct tid_info *t,
2148c2ecf20Sopenharmony_ci						     u32 eotid)
2158c2ecf20Sopenharmony_ci{
2168c2ecf20Sopenharmony_ci	return eotid < t->neotids ? &t->eotid_tab[eotid] : NULL;
2178c2ecf20Sopenharmony_ci}
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_cistatic inline int cxgb4_get_free_eotid(struct tid_info *t)
2208c2ecf20Sopenharmony_ci{
2218c2ecf20Sopenharmony_ci	int eotid;
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci	eotid = find_first_zero_bit(t->eotid_bmap, t->neotids);
2248c2ecf20Sopenharmony_ci	if (eotid >= t->neotids)
2258c2ecf20Sopenharmony_ci		eotid = -1;
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci	return eotid;
2288c2ecf20Sopenharmony_ci}
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_cistatic inline void cxgb4_alloc_eotid(struct tid_info *t, u32 eotid, void *data)
2318c2ecf20Sopenharmony_ci{
2328c2ecf20Sopenharmony_ci	set_bit(eotid, t->eotid_bmap);
2338c2ecf20Sopenharmony_ci	t->eotid_tab[eotid].data = data;
2348c2ecf20Sopenharmony_ci	atomic_inc(&t->eotids_in_use);
2358c2ecf20Sopenharmony_ci}
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_cistatic inline void cxgb4_free_eotid(struct tid_info *t, u32 eotid)
2388c2ecf20Sopenharmony_ci{
2398c2ecf20Sopenharmony_ci	clear_bit(eotid, t->eotid_bmap);
2408c2ecf20Sopenharmony_ci	t->eotid_tab[eotid].data = NULL;
2418c2ecf20Sopenharmony_ci	atomic_dec(&t->eotids_in_use);
2428c2ecf20Sopenharmony_ci}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ciint cxgb4_alloc_atid(struct tid_info *t, void *data);
2458c2ecf20Sopenharmony_ciint cxgb4_alloc_stid(struct tid_info *t, int family, void *data);
2468c2ecf20Sopenharmony_ciint cxgb4_alloc_sftid(struct tid_info *t, int family, void *data);
2478c2ecf20Sopenharmony_civoid cxgb4_free_atid(struct tid_info *t, unsigned int atid);
2488c2ecf20Sopenharmony_civoid cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family);
2498c2ecf20Sopenharmony_civoid cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid,
2508c2ecf20Sopenharmony_ci		      unsigned short family);
2518c2ecf20Sopenharmony_cistruct in6_addr;
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ciint cxgb4_create_server(const struct net_device *dev, unsigned int stid,
2548c2ecf20Sopenharmony_ci			__be32 sip, __be16 sport, __be16 vlan,
2558c2ecf20Sopenharmony_ci			unsigned int queue);
2568c2ecf20Sopenharmony_ciint cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
2578c2ecf20Sopenharmony_ci			 const struct in6_addr *sip, __be16 sport,
2588c2ecf20Sopenharmony_ci			 unsigned int queue);
2598c2ecf20Sopenharmony_ciint cxgb4_remove_server(const struct net_device *dev, unsigned int stid,
2608c2ecf20Sopenharmony_ci			unsigned int queue, bool ipv6);
2618c2ecf20Sopenharmony_ciint cxgb4_create_server_filter(const struct net_device *dev, unsigned int stid,
2628c2ecf20Sopenharmony_ci			       __be32 sip, __be16 sport, __be16 vlan,
2638c2ecf20Sopenharmony_ci			       unsigned int queue,
2648c2ecf20Sopenharmony_ci			       unsigned char port, unsigned char mask);
2658c2ecf20Sopenharmony_ciint cxgb4_remove_server_filter(const struct net_device *dev, unsigned int stid,
2668c2ecf20Sopenharmony_ci			       unsigned int queue, bool ipv6);
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci/* Filter operation context to allow callers of cxgb4_set_filter() and
2698c2ecf20Sopenharmony_ci * cxgb4_del_filter() to wait for an asynchronous completion.
2708c2ecf20Sopenharmony_ci */
2718c2ecf20Sopenharmony_cistruct filter_ctx {
2728c2ecf20Sopenharmony_ci	struct completion completion;	/* completion rendezvous */
2738c2ecf20Sopenharmony_ci	void *closure;			/* caller's opaque information */
2748c2ecf20Sopenharmony_ci	int result;			/* result of operation */
2758c2ecf20Sopenharmony_ci	u32 tid;			/* to store tid */
2768c2ecf20Sopenharmony_ci};
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_cistruct chcr_ktls {
2798c2ecf20Sopenharmony_ci	refcount_t ktls_refcount;
2808c2ecf20Sopenharmony_ci};
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_cistruct ch_filter_specification;
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ciint cxgb4_get_free_ftid(struct net_device *dev, u8 family, bool hash_en,
2858c2ecf20Sopenharmony_ci			u32 tc_prio);
2868c2ecf20Sopenharmony_ciint __cxgb4_set_filter(struct net_device *dev, int filter_id,
2878c2ecf20Sopenharmony_ci		       struct ch_filter_specification *fs,
2888c2ecf20Sopenharmony_ci		       struct filter_ctx *ctx);
2898c2ecf20Sopenharmony_ciint __cxgb4_del_filter(struct net_device *dev, int filter_id,
2908c2ecf20Sopenharmony_ci		       struct ch_filter_specification *fs,
2918c2ecf20Sopenharmony_ci		       struct filter_ctx *ctx);
2928c2ecf20Sopenharmony_ciint cxgb4_set_filter(struct net_device *dev, int filter_id,
2938c2ecf20Sopenharmony_ci		     struct ch_filter_specification *fs);
2948c2ecf20Sopenharmony_ciint cxgb4_del_filter(struct net_device *dev, int filter_id,
2958c2ecf20Sopenharmony_ci		     struct ch_filter_specification *fs);
2968c2ecf20Sopenharmony_ciint cxgb4_get_filter_counters(struct net_device *dev, unsigned int fidx,
2978c2ecf20Sopenharmony_ci			      u64 *hitcnt, u64 *bytecnt, bool hash);
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_cistatic inline void set_wr_txq(struct sk_buff *skb, int prio, int queue)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	skb_set_queue_mapping(skb, (queue << 1) | prio);
3028c2ecf20Sopenharmony_ci}
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_cienum cxgb4_uld {
3058c2ecf20Sopenharmony_ci	CXGB4_ULD_INIT,
3068c2ecf20Sopenharmony_ci	CXGB4_ULD_RDMA,
3078c2ecf20Sopenharmony_ci	CXGB4_ULD_ISCSI,
3088c2ecf20Sopenharmony_ci	CXGB4_ULD_ISCSIT,
3098c2ecf20Sopenharmony_ci	CXGB4_ULD_CRYPTO,
3108c2ecf20Sopenharmony_ci	CXGB4_ULD_IPSEC,
3118c2ecf20Sopenharmony_ci	CXGB4_ULD_TLS,
3128c2ecf20Sopenharmony_ci	CXGB4_ULD_KTLS,
3138c2ecf20Sopenharmony_ci	CXGB4_ULD_MAX
3148c2ecf20Sopenharmony_ci};
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_cienum cxgb4_tx_uld {
3178c2ecf20Sopenharmony_ci	CXGB4_TX_OFLD,
3188c2ecf20Sopenharmony_ci	CXGB4_TX_CRYPTO,
3198c2ecf20Sopenharmony_ci	CXGB4_TX_MAX
3208c2ecf20Sopenharmony_ci};
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_cienum cxgb4_txq_type {
3238c2ecf20Sopenharmony_ci	CXGB4_TXQ_ETH,
3248c2ecf20Sopenharmony_ci	CXGB4_TXQ_ULD,
3258c2ecf20Sopenharmony_ci	CXGB4_TXQ_CTRL,
3268c2ecf20Sopenharmony_ci	CXGB4_TXQ_MAX
3278c2ecf20Sopenharmony_ci};
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_cienum cxgb4_state {
3308c2ecf20Sopenharmony_ci	CXGB4_STATE_UP,
3318c2ecf20Sopenharmony_ci	CXGB4_STATE_START_RECOVERY,
3328c2ecf20Sopenharmony_ci	CXGB4_STATE_DOWN,
3338c2ecf20Sopenharmony_ci	CXGB4_STATE_DETACH,
3348c2ecf20Sopenharmony_ci	CXGB4_STATE_FATAL_ERROR
3358c2ecf20Sopenharmony_ci};
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_cienum cxgb4_control {
3388c2ecf20Sopenharmony_ci	CXGB4_CONTROL_DB_FULL,
3398c2ecf20Sopenharmony_ci	CXGB4_CONTROL_DB_EMPTY,
3408c2ecf20Sopenharmony_ci	CXGB4_CONTROL_DB_DROP,
3418c2ecf20Sopenharmony_ci};
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_cistruct adapter;
3448c2ecf20Sopenharmony_cistruct pci_dev;
3458c2ecf20Sopenharmony_cistruct l2t_data;
3468c2ecf20Sopenharmony_cistruct net_device;
3478c2ecf20Sopenharmony_cistruct pkt_gl;
3488c2ecf20Sopenharmony_cistruct tp_tcp_stats;
3498c2ecf20Sopenharmony_cistruct t4_lro_mgr;
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_cistruct cxgb4_range {
3528c2ecf20Sopenharmony_ci	unsigned int start;
3538c2ecf20Sopenharmony_ci	unsigned int size;
3548c2ecf20Sopenharmony_ci};
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_cistruct cxgb4_virt_res {                      /* virtualized HW resources */
3578c2ecf20Sopenharmony_ci	struct cxgb4_range ddp;
3588c2ecf20Sopenharmony_ci	struct cxgb4_range iscsi;
3598c2ecf20Sopenharmony_ci	struct cxgb4_range stag;
3608c2ecf20Sopenharmony_ci	struct cxgb4_range rq;
3618c2ecf20Sopenharmony_ci	struct cxgb4_range srq;
3628c2ecf20Sopenharmony_ci	struct cxgb4_range pbl;
3638c2ecf20Sopenharmony_ci	struct cxgb4_range qp;
3648c2ecf20Sopenharmony_ci	struct cxgb4_range cq;
3658c2ecf20Sopenharmony_ci	struct cxgb4_range ocq;
3668c2ecf20Sopenharmony_ci	struct cxgb4_range key;
3678c2ecf20Sopenharmony_ci	unsigned int ncrypto_fc;
3688c2ecf20Sopenharmony_ci	struct cxgb4_range ppod_edram;
3698c2ecf20Sopenharmony_ci};
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE)
3728c2ecf20Sopenharmony_cistruct ch_ktls_port_stats_debug {
3738c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_connection_open;
3748c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_connection_fail;
3758c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_connection_close;
3768c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_encrypted_packets;
3778c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_encrypted_bytes;
3788c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_ctx;
3798c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_ooo;
3808c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_skip_no_sync_data;
3818c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_drop_no_sync_data;
3828c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_drop_bypass_req;
3838c2ecf20Sopenharmony_ci};
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_cistruct ch_ktls_stats_debug {
3868c2ecf20Sopenharmony_ci	struct ch_ktls_port_stats_debug ktls_port[MAX_ULD_NPORTS];
3878c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_send_records;
3888c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_end_pkts;
3898c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_start_pkts;
3908c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_middle_pkts;
3918c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_retransmit_pkts;
3928c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_complete_pkts;
3938c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_trimmed_pkts;
3948c2ecf20Sopenharmony_ci	atomic64_t ktls_tx_fallback;
3958c2ecf20Sopenharmony_ci};
3968c2ecf20Sopenharmony_ci#endif
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_cistruct chcr_stats_debug {
3998c2ecf20Sopenharmony_ci	atomic_t cipher_rqst;
4008c2ecf20Sopenharmony_ci	atomic_t digest_rqst;
4018c2ecf20Sopenharmony_ci	atomic_t aead_rqst;
4028c2ecf20Sopenharmony_ci	atomic_t complete;
4038c2ecf20Sopenharmony_ci	atomic_t error;
4048c2ecf20Sopenharmony_ci	atomic_t fallback;
4058c2ecf20Sopenharmony_ci	atomic_t tls_pdu_tx;
4068c2ecf20Sopenharmony_ci	atomic_t tls_pdu_rx;
4078c2ecf20Sopenharmony_ci	atomic_t tls_key;
4088c2ecf20Sopenharmony_ci};
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE)
4118c2ecf20Sopenharmony_cistruct ch_ipsec_stats_debug {
4128c2ecf20Sopenharmony_ci	atomic_t ipsec_cnt;
4138c2ecf20Sopenharmony_ci};
4148c2ecf20Sopenharmony_ci#endif
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci#define OCQ_WIN_OFFSET(pdev, vres) \
4178c2ecf20Sopenharmony_ci	(pci_resource_len((pdev), 2) - roundup_pow_of_two((vres)->ocq.size))
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_ci/*
4208c2ecf20Sopenharmony_ci * Block of information the LLD provides to ULDs attaching to a device.
4218c2ecf20Sopenharmony_ci */
4228c2ecf20Sopenharmony_cistruct cxgb4_lld_info {
4238c2ecf20Sopenharmony_ci	struct pci_dev *pdev;                /* associated PCI device */
4248c2ecf20Sopenharmony_ci	struct l2t_data *l2t;                /* L2 table */
4258c2ecf20Sopenharmony_ci	struct tid_info *tids;               /* TID table */
4268c2ecf20Sopenharmony_ci	struct net_device **ports;           /* device ports */
4278c2ecf20Sopenharmony_ci	const struct cxgb4_virt_res *vr;     /* assorted HW resources */
4288c2ecf20Sopenharmony_ci	const unsigned short *mtus;          /* MTU table */
4298c2ecf20Sopenharmony_ci	const unsigned short *rxq_ids;       /* the ULD's Rx queue ids */
4308c2ecf20Sopenharmony_ci	const unsigned short *ciq_ids;       /* the ULD's concentrator IQ ids */
4318c2ecf20Sopenharmony_ci	unsigned short nrxq;                 /* # of Rx queues */
4328c2ecf20Sopenharmony_ci	unsigned short ntxq;                 /* # of Tx queues */
4338c2ecf20Sopenharmony_ci	unsigned short nciq;		     /* # of concentrator IQ */
4348c2ecf20Sopenharmony_ci	unsigned char nchan:4;               /* # of channels */
4358c2ecf20Sopenharmony_ci	unsigned char nports:4;              /* # of ports */
4368c2ecf20Sopenharmony_ci	unsigned char wr_cred;               /* WR 16-byte credits */
4378c2ecf20Sopenharmony_ci	unsigned char adapter_type;          /* type of adapter */
4388c2ecf20Sopenharmony_ci	unsigned char fw_api_ver;            /* FW API version */
4398c2ecf20Sopenharmony_ci	unsigned char crypto;                /* crypto support */
4408c2ecf20Sopenharmony_ci	unsigned int fw_vers;                /* FW version */
4418c2ecf20Sopenharmony_ci	unsigned int iscsi_iolen;            /* iSCSI max I/O length */
4428c2ecf20Sopenharmony_ci	unsigned int cclk_ps;                /* Core clock period in psec */
4438c2ecf20Sopenharmony_ci	unsigned short udb_density;          /* # of user DB/page */
4448c2ecf20Sopenharmony_ci	unsigned short ucq_density;          /* # of user CQs/page */
4458c2ecf20Sopenharmony_ci	unsigned int sge_host_page_size;     /* SGE host page size */
4468c2ecf20Sopenharmony_ci	unsigned short filt_mode;            /* filter optional components */
4478c2ecf20Sopenharmony_ci	unsigned short tx_modq[NCHAN];       /* maps each tx channel to a */
4488c2ecf20Sopenharmony_ci					     /* scheduler queue */
4498c2ecf20Sopenharmony_ci	void __iomem *gts_reg;               /* address of GTS register */
4508c2ecf20Sopenharmony_ci	void __iomem *db_reg;                /* address of kernel doorbell */
4518c2ecf20Sopenharmony_ci	int dbfifo_int_thresh;		     /* doorbell fifo int threshold */
4528c2ecf20Sopenharmony_ci	unsigned int sge_ingpadboundary;     /* SGE ingress padding boundary */
4538c2ecf20Sopenharmony_ci	unsigned int sge_egrstatuspagesize;  /* SGE egress status page size */
4548c2ecf20Sopenharmony_ci	unsigned int sge_pktshift;           /* Padding between CPL and */
4558c2ecf20Sopenharmony_ci					     /*	packet data */
4568c2ecf20Sopenharmony_ci	unsigned int pf;		     /* Physical Function we're using */
4578c2ecf20Sopenharmony_ci	bool enable_fw_ofld_conn;            /* Enable connection through fw */
4588c2ecf20Sopenharmony_ci					     /* WR */
4598c2ecf20Sopenharmony_ci	unsigned int max_ordird_qp;          /* Max ORD/IRD depth per RDMA QP */
4608c2ecf20Sopenharmony_ci	unsigned int max_ird_adapter;        /* Max IRD memory per adapter */
4618c2ecf20Sopenharmony_ci	bool ulptx_memwrite_dsgl;            /* use of T5 DSGL allowed */
4628c2ecf20Sopenharmony_ci	unsigned int iscsi_tagmask;	     /* iscsi ddp tag mask */
4638c2ecf20Sopenharmony_ci	unsigned int iscsi_pgsz_order;	     /* iscsi ddp page size orders */
4648c2ecf20Sopenharmony_ci	unsigned int iscsi_llimit;	     /* chip's iscsi region llimit */
4658c2ecf20Sopenharmony_ci	unsigned int ulp_crypto;             /* crypto lookaside support */
4668c2ecf20Sopenharmony_ci	void **iscsi_ppm;		     /* iscsi page pod manager */
4678c2ecf20Sopenharmony_ci	int nodeid;			     /* device numa node id */
4688c2ecf20Sopenharmony_ci	bool fr_nsmr_tpte_wr_support;	     /* FW supports FR_NSMR_TPTE_WR */
4698c2ecf20Sopenharmony_ci	bool write_w_imm_support;         /* FW supports WRITE_WITH_IMMEDIATE */
4708c2ecf20Sopenharmony_ci	bool write_cmpl_support;             /* FW supports WRITE_CMPL WR */
4718c2ecf20Sopenharmony_ci};
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_cistruct cxgb4_uld_info {
4748c2ecf20Sopenharmony_ci	char name[IFNAMSIZ];
4758c2ecf20Sopenharmony_ci	void *handle;
4768c2ecf20Sopenharmony_ci	unsigned int nrxq;
4778c2ecf20Sopenharmony_ci	unsigned int rxq_size;
4788c2ecf20Sopenharmony_ci	unsigned int ntxq;
4798c2ecf20Sopenharmony_ci	bool ciq;
4808c2ecf20Sopenharmony_ci	bool lro;
4818c2ecf20Sopenharmony_ci	void *(*add)(const struct cxgb4_lld_info *p);
4828c2ecf20Sopenharmony_ci	int (*rx_handler)(void *handle, const __be64 *rsp,
4838c2ecf20Sopenharmony_ci			  const struct pkt_gl *gl);
4848c2ecf20Sopenharmony_ci	int (*state_change)(void *handle, enum cxgb4_state new_state);
4858c2ecf20Sopenharmony_ci	int (*control)(void *handle, enum cxgb4_control control, ...);
4868c2ecf20Sopenharmony_ci	int (*lro_rx_handler)(void *handle, const __be64 *rsp,
4878c2ecf20Sopenharmony_ci			      const struct pkt_gl *gl,
4888c2ecf20Sopenharmony_ci			      struct t4_lro_mgr *lro_mgr,
4898c2ecf20Sopenharmony_ci			      struct napi_struct *napi);
4908c2ecf20Sopenharmony_ci	void (*lro_flush)(struct t4_lro_mgr *);
4918c2ecf20Sopenharmony_ci	int (*tx_handler)(struct sk_buff *skb, struct net_device *dev);
4928c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_CHELSIO_TLS_DEVICE)
4938c2ecf20Sopenharmony_ci	const struct tlsdev_ops *tlsdev_ops;
4948c2ecf20Sopenharmony_ci#endif
4958c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_XFRM_OFFLOAD)
4968c2ecf20Sopenharmony_ci	const struct xfrmdev_ops *xfrmdev_ops;
4978c2ecf20Sopenharmony_ci#endif
4988c2ecf20Sopenharmony_ci};
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_cistatic inline bool cxgb4_is_ktls_skb(struct sk_buff *skb)
5018c2ecf20Sopenharmony_ci{
5028c2ecf20Sopenharmony_ci	return skb->sk && tls_is_sk_tx_device_offloaded(skb->sk);
5038c2ecf20Sopenharmony_ci}
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_civoid cxgb4_uld_enable(struct adapter *adap);
5068c2ecf20Sopenharmony_civoid cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
5078c2ecf20Sopenharmony_ciint cxgb4_unregister_uld(enum cxgb4_uld type);
5088c2ecf20Sopenharmony_ciint cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
5098c2ecf20Sopenharmony_ciint cxgb4_immdata_send(struct net_device *dev, unsigned int idx,
5108c2ecf20Sopenharmony_ci		       const void *src, unsigned int len);
5118c2ecf20Sopenharmony_ciint cxgb4_crypto_send(struct net_device *dev, struct sk_buff *skb);
5128c2ecf20Sopenharmony_ciunsigned int cxgb4_dbfifo_count(const struct net_device *dev, int lpfifo);
5138c2ecf20Sopenharmony_ciunsigned int cxgb4_port_chan(const struct net_device *dev);
5148c2ecf20Sopenharmony_ciunsigned int cxgb4_port_e2cchan(const struct net_device *dev);
5158c2ecf20Sopenharmony_ciunsigned int cxgb4_port_viid(const struct net_device *dev);
5168c2ecf20Sopenharmony_ciunsigned int cxgb4_tp_smt_idx(enum chip_type chip, unsigned int viid);
5178c2ecf20Sopenharmony_ciunsigned int cxgb4_port_idx(const struct net_device *dev);
5188c2ecf20Sopenharmony_ciunsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu,
5198c2ecf20Sopenharmony_ci			    unsigned int *idx);
5208c2ecf20Sopenharmony_ciunsigned int cxgb4_best_aligned_mtu(const unsigned short *mtus,
5218c2ecf20Sopenharmony_ci				    unsigned short header_size,
5228c2ecf20Sopenharmony_ci				    unsigned short data_size_max,
5238c2ecf20Sopenharmony_ci				    unsigned short data_size_align,
5248c2ecf20Sopenharmony_ci				    unsigned int *mtu_idxp);
5258c2ecf20Sopenharmony_civoid cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4,
5268c2ecf20Sopenharmony_ci			 struct tp_tcp_stats *v6);
5278c2ecf20Sopenharmony_civoid cxgb4_iscsi_init(struct net_device *dev, unsigned int tag_mask,
5288c2ecf20Sopenharmony_ci		      const unsigned int *pgsz_order);
5298c2ecf20Sopenharmony_cistruct sk_buff *cxgb4_pktgl_to_skb(const struct pkt_gl *gl,
5308c2ecf20Sopenharmony_ci				   unsigned int skb_len, unsigned int pull_len);
5318c2ecf20Sopenharmony_ciint cxgb4_sync_txq_pidx(struct net_device *dev, u16 qid, u16 pidx, u16 size);
5328c2ecf20Sopenharmony_ciint cxgb4_flush_eq_cache(struct net_device *dev);
5338c2ecf20Sopenharmony_ciint cxgb4_read_tpte(struct net_device *dev, u32 stag, __be32 *tpte);
5348c2ecf20Sopenharmony_ciu64 cxgb4_read_sge_timestamp(struct net_device *dev);
5358c2ecf20Sopenharmony_ci
5368c2ecf20Sopenharmony_cienum cxgb4_bar2_qtype { CXGB4_BAR2_QTYPE_EGRESS, CXGB4_BAR2_QTYPE_INGRESS };
5378c2ecf20Sopenharmony_ciint cxgb4_bar2_sge_qregs(struct net_device *dev,
5388c2ecf20Sopenharmony_ci			 unsigned int qid,
5398c2ecf20Sopenharmony_ci			 enum cxgb4_bar2_qtype qtype,
5408c2ecf20Sopenharmony_ci			 int user,
5418c2ecf20Sopenharmony_ci			 u64 *pbar2_qoffset,
5428c2ecf20Sopenharmony_ci			 unsigned int *pbar2_qid);
5438c2ecf20Sopenharmony_ci
5448c2ecf20Sopenharmony_ci#endif  /* !__CXGB4_ULD_H */
545