18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright (c) 2006-2008 Chelsio, Inc. All rights reserved.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two
58c2ecf20Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
68c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
78c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the
88c2ecf20Sopenharmony_ci * OpenIB.org BSD license below:
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
118c2ecf20Sopenharmony_ci *     without modification, are permitted provided that the following
128c2ecf20Sopenharmony_ci *     conditions are met:
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci *      - Redistributions of source code must retain the above
158c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
168c2ecf20Sopenharmony_ci *        disclaimer.
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
198c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
208c2ecf20Sopenharmony_ci *        disclaimer in the documentation and/or other materials
218c2ecf20Sopenharmony_ci *        provided with the distribution.
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
248c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
258c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
268c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
278c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
288c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
298c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
308c2ecf20Sopenharmony_ci * SOFTWARE.
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_ci#ifndef _CXGB3_OFFLOAD_H
338c2ecf20Sopenharmony_ci#define _CXGB3_OFFLOAD_H
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#include <linux/list.h>
368c2ecf20Sopenharmony_ci#include <linux/skbuff.h>
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#include "l2t.h"
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci#include "t3cdev.h"
418c2ecf20Sopenharmony_ci#include "t3_cpl.h"
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cistruct adapter;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_civoid cxgb3_offload_init(void);
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_civoid cxgb3_adapter_ofld(struct adapter *adapter);
488c2ecf20Sopenharmony_civoid cxgb3_adapter_unofld(struct adapter *adapter);
498c2ecf20Sopenharmony_ciint cxgb3_offload_activate(struct adapter *adapter);
508c2ecf20Sopenharmony_civoid cxgb3_offload_deactivate(struct adapter *adapter);
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_civoid cxgb3_set_dummy_ops(struct t3cdev *dev);
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistruct t3cdev *dev2t3cdev(struct net_device *dev);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci/*
578c2ecf20Sopenharmony_ci * Client registration.  Users of T3 driver must register themselves.
588c2ecf20Sopenharmony_ci * The T3 driver will call the add function of every client for each T3
598c2ecf20Sopenharmony_ci * adapter activated, passing up the t3cdev ptr.  Each client fills out an
608c2ecf20Sopenharmony_ci * array of callback functions to process CPL messages.
618c2ecf20Sopenharmony_ci */
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_civoid cxgb3_register_client(struct cxgb3_client *client);
648c2ecf20Sopenharmony_civoid cxgb3_unregister_client(struct cxgb3_client *client);
658c2ecf20Sopenharmony_civoid cxgb3_add_clients(struct t3cdev *tdev);
668c2ecf20Sopenharmony_civoid cxgb3_remove_clients(struct t3cdev *tdev);
678c2ecf20Sopenharmony_civoid cxgb3_event_notify(struct t3cdev *tdev, u32 event, u32 port);
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_citypedef int (*cxgb3_cpl_handler_func)(struct t3cdev *dev,
708c2ecf20Sopenharmony_ci				      struct sk_buff *skb, void *ctx);
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cienum {
738c2ecf20Sopenharmony_ci	OFFLOAD_STATUS_UP,
748c2ecf20Sopenharmony_ci	OFFLOAD_STATUS_DOWN,
758c2ecf20Sopenharmony_ci	OFFLOAD_PORT_DOWN,
768c2ecf20Sopenharmony_ci	OFFLOAD_PORT_UP,
778c2ecf20Sopenharmony_ci	OFFLOAD_DB_FULL,
788c2ecf20Sopenharmony_ci	OFFLOAD_DB_EMPTY,
798c2ecf20Sopenharmony_ci	OFFLOAD_DB_DROP
808c2ecf20Sopenharmony_ci};
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_cistruct cxgb3_client {
838c2ecf20Sopenharmony_ci	char *name;
848c2ecf20Sopenharmony_ci	void (*add) (struct t3cdev *);
858c2ecf20Sopenharmony_ci	void (*remove) (struct t3cdev *);
868c2ecf20Sopenharmony_ci	cxgb3_cpl_handler_func *handlers;
878c2ecf20Sopenharmony_ci	int (*redirect)(void *ctx, struct dst_entry *old,
888c2ecf20Sopenharmony_ci			struct dst_entry *new, struct l2t_entry *l2t);
898c2ecf20Sopenharmony_ci	struct list_head client_list;
908c2ecf20Sopenharmony_ci	void (*event_handler)(struct t3cdev *tdev, u32 event, u32 port);
918c2ecf20Sopenharmony_ci};
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci/*
948c2ecf20Sopenharmony_ci * TID allocation services.
958c2ecf20Sopenharmony_ci */
968c2ecf20Sopenharmony_ciint cxgb3_alloc_atid(struct t3cdev *dev, struct cxgb3_client *client,
978c2ecf20Sopenharmony_ci		     void *ctx);
988c2ecf20Sopenharmony_ciint cxgb3_alloc_stid(struct t3cdev *dev, struct cxgb3_client *client,
998c2ecf20Sopenharmony_ci		     void *ctx);
1008c2ecf20Sopenharmony_civoid *cxgb3_free_atid(struct t3cdev *dev, int atid);
1018c2ecf20Sopenharmony_civoid cxgb3_free_stid(struct t3cdev *dev, int stid);
1028c2ecf20Sopenharmony_civoid cxgb3_insert_tid(struct t3cdev *dev, struct cxgb3_client *client,
1038c2ecf20Sopenharmony_ci		      void *ctx, unsigned int tid);
1048c2ecf20Sopenharmony_civoid cxgb3_queue_tid_release(struct t3cdev *dev, unsigned int tid);
1058c2ecf20Sopenharmony_civoid cxgb3_remove_tid(struct t3cdev *dev, void *ctx, unsigned int tid);
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_cistruct t3c_tid_entry {
1088c2ecf20Sopenharmony_ci	struct cxgb3_client *client;
1098c2ecf20Sopenharmony_ci	void *ctx;
1108c2ecf20Sopenharmony_ci};
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci/* CPL message priority levels */
1138c2ecf20Sopenharmony_cienum {
1148c2ecf20Sopenharmony_ci	CPL_PRIORITY_DATA = 0,	/* data messages */
1158c2ecf20Sopenharmony_ci	CPL_PRIORITY_SETUP = 1,	/* connection setup messages */
1168c2ecf20Sopenharmony_ci	CPL_PRIORITY_TEARDOWN = 0,	/* connection teardown messages */
1178c2ecf20Sopenharmony_ci	CPL_PRIORITY_LISTEN = 1,	/* listen start/stop messages */
1188c2ecf20Sopenharmony_ci	CPL_PRIORITY_ACK = 1,	/* RX ACK messages */
1198c2ecf20Sopenharmony_ci	CPL_PRIORITY_CONTROL = 1	/* offload control messages */
1208c2ecf20Sopenharmony_ci};
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci/* Flags for return value of CPL message handlers */
1238c2ecf20Sopenharmony_cienum {
1248c2ecf20Sopenharmony_ci	CPL_RET_BUF_DONE = 1, /* buffer processing done, buffer may be freed */
1258c2ecf20Sopenharmony_ci	CPL_RET_BAD_MSG = 2,  /* bad CPL message (e.g., unknown opcode) */
1268c2ecf20Sopenharmony_ci	CPL_RET_UNKNOWN_TID = 4	/* unexpected unknown TID */
1278c2ecf20Sopenharmony_ci};
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_citypedef int (*cpl_handler_func)(struct t3cdev *dev, struct sk_buff *skb);
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci/*
1328c2ecf20Sopenharmony_ci * Returns a pointer to the first byte of the CPL header in an sk_buff that
1338c2ecf20Sopenharmony_ci * contains a CPL message.
1348c2ecf20Sopenharmony_ci */
1358c2ecf20Sopenharmony_cistatic inline void *cplhdr(struct sk_buff *skb)
1368c2ecf20Sopenharmony_ci{
1378c2ecf20Sopenharmony_ci	return skb->data;
1388c2ecf20Sopenharmony_ci}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_civoid t3_register_cpl_handler(unsigned int opcode, cpl_handler_func h);
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ciunion listen_entry {
1438c2ecf20Sopenharmony_ci	struct t3c_tid_entry t3c_tid;
1448c2ecf20Sopenharmony_ci	union listen_entry *next;
1458c2ecf20Sopenharmony_ci};
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ciunion active_open_entry {
1488c2ecf20Sopenharmony_ci	struct t3c_tid_entry t3c_tid;
1498c2ecf20Sopenharmony_ci	union active_open_entry *next;
1508c2ecf20Sopenharmony_ci};
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci/*
1538c2ecf20Sopenharmony_ci * Holds the size, base address, free list start, etc of the TID, server TID,
1548c2ecf20Sopenharmony_ci * and active-open TID tables for a offload device.
1558c2ecf20Sopenharmony_ci * The tables themselves are allocated dynamically.
1568c2ecf20Sopenharmony_ci */
1578c2ecf20Sopenharmony_cistruct tid_info {
1588c2ecf20Sopenharmony_ci	struct t3c_tid_entry *tid_tab;
1598c2ecf20Sopenharmony_ci	unsigned int ntids;
1608c2ecf20Sopenharmony_ci	atomic_t tids_in_use;
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	union listen_entry *stid_tab;
1638c2ecf20Sopenharmony_ci	unsigned int nstids;
1648c2ecf20Sopenharmony_ci	unsigned int stid_base;
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	union active_open_entry *atid_tab;
1678c2ecf20Sopenharmony_ci	unsigned int natids;
1688c2ecf20Sopenharmony_ci	unsigned int atid_base;
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	/*
1718c2ecf20Sopenharmony_ci	 * The following members are accessed R/W so we put them in their own
1728c2ecf20Sopenharmony_ci	 * cache lines.
1738c2ecf20Sopenharmony_ci	 *
1748c2ecf20Sopenharmony_ci	 * XXX We could combine the atid fields above with the lock here since
1758c2ecf20Sopenharmony_ci	 * atids are use once (unlike other tids).  OTOH the above fields are
1768c2ecf20Sopenharmony_ci	 * usually in cache due to tid_tab.
1778c2ecf20Sopenharmony_ci	 */
1788c2ecf20Sopenharmony_ci	spinlock_t atid_lock ____cacheline_aligned_in_smp;
1798c2ecf20Sopenharmony_ci	union active_open_entry *afree;
1808c2ecf20Sopenharmony_ci	unsigned int atids_in_use;
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	spinlock_t stid_lock ____cacheline_aligned;
1838c2ecf20Sopenharmony_ci	union listen_entry *sfree;
1848c2ecf20Sopenharmony_ci	unsigned int stids_in_use;
1858c2ecf20Sopenharmony_ci};
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_cistruct t3c_data {
1888c2ecf20Sopenharmony_ci	struct list_head list_node;
1898c2ecf20Sopenharmony_ci	struct t3cdev *dev;
1908c2ecf20Sopenharmony_ci	unsigned int tx_max_chunk;	/* max payload for TX_DATA */
1918c2ecf20Sopenharmony_ci	unsigned int max_wrs;	/* max in-flight WRs per connection */
1928c2ecf20Sopenharmony_ci	unsigned int nmtus;
1938c2ecf20Sopenharmony_ci	const unsigned short *mtus;
1948c2ecf20Sopenharmony_ci	struct tid_info tid_maps;
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	struct t3c_tid_entry *tid_release_list;
1978c2ecf20Sopenharmony_ci	spinlock_t tid_release_lock;
1988c2ecf20Sopenharmony_ci	struct work_struct tid_release_task;
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	struct sk_buff *nofail_skb;
2018c2ecf20Sopenharmony_ci	unsigned int release_list_incomplete;
2028c2ecf20Sopenharmony_ci};
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci/*
2058c2ecf20Sopenharmony_ci * t3cdev -> t3c_data accessor
2068c2ecf20Sopenharmony_ci */
2078c2ecf20Sopenharmony_ci#define T3C_DATA(dev) (*(struct t3c_data **)&(dev)->l4opt)
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci#endif
210