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