1222509Snp/*- 2222509Snp * Copyright (c) 2011 Chelsio Communications, Inc. 3222509Snp * All rights reserved. 4222509Snp * 5222509Snp * Redistribution and use in source and binary forms, with or without 6222509Snp * modification, are permitted provided that the following conditions 7222509Snp * are met: 8222509Snp * 1. Redistributions of source code must retain the above copyright 9222509Snp * notice, this list of conditions and the following disclaimer. 10222509Snp * 2. Redistributions in binary form must reproduce the above copyright 11222509Snp * notice, this list of conditions and the following disclaimer in the 12222509Snp * documentation and/or other materials provided with the distribution. 13222509Snp * 14222509Snp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15222509Snp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16222509Snp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17222509Snp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18222509Snp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19222509Snp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20222509Snp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21222509Snp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22222509Snp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23222509Snp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24222509Snp * SUCH DAMAGE. 25222509Snp * 26222509Snp * $FreeBSD$ 27222509Snp * 28222509Snp */ 29222509Snp 30222509Snp#ifndef __T4_L2T_H 31222509Snp#define __T4_L2T_H 32222509Snp 33237263Snp/* identifies sync vs async L2T_WRITE_REQs */ 34237263Snp#define S_SYNC_WR 12 35237263Snp#define V_SYNC_WR(x) ((x) << S_SYNC_WR) 36237263Snp#define F_SYNC_WR V_SYNC_WR(1) 37237263Snp 38222509Snpenum { L2T_SIZE = 4096 }; /* # of L2T entries */ 39222509Snp 40237263Snpenum { 41237263Snp L2T_STATE_VALID, /* entry is up to date */ 42237263Snp L2T_STATE_STALE, /* entry may be used but needs revalidation */ 43237263Snp L2T_STATE_RESOLVING, /* entry needs address resolution */ 44237263Snp L2T_STATE_FAILED, /* failed to resolve */ 45237263Snp L2T_STATE_SYNC_WRITE, /* synchronous write of entry underway */ 46237263Snp 47237263Snp /* when state is one of the below the entry is not hashed */ 48237263Snp L2T_STATE_SWITCHING, /* entry is being used by a switching filter */ 49237263Snp L2T_STATE_UNUSED /* entry not in use */ 50237263Snp}; 51237263Snp 52222509Snp/* 53222509Snp * Each L2T entry plays multiple roles. First of all, it keeps state for the 54222509Snp * corresponding entry of the HW L2 table and maintains a queue of offload 55222509Snp * packets awaiting address resolution. Second, it is a node of a hash table 56222509Snp * chain, where the nodes of the chain are linked together through their next 57222509Snp * pointer. Finally, each node is a bucket of a hash table, pointing to the 58222509Snp * first element in its chain through its first pointer. 59222509Snp */ 60222509Snpstruct l2t_entry { 61222509Snp uint16_t state; /* entry state */ 62222509Snp uint16_t idx; /* entry index */ 63245434Snp uint32_t addr[4]; /* next hop IP or IPv6 address */ 64222509Snp struct ifnet *ifp; /* outgoing interface */ 65222509Snp uint16_t smt_idx; /* SMT index */ 66222509Snp uint16_t vlan; /* VLAN TCI (id: 0-11, prio: 13-15) */ 67222509Snp struct l2t_entry *first; /* start of hash chain */ 68222509Snp struct l2t_entry *next; /* next l2t_entry on chain */ 69237263Snp STAILQ_HEAD(, wrqe) wr_list; /* list of WRs awaiting resolution */ 70222509Snp struct mtx lock; 71228561Snp volatile int refcnt; /* entry reference count */ 72222509Snp uint16_t hash; /* hash bucket the entry is on */ 73245434Snp uint8_t ipv6; /* entry is for an IPv6 address */ 74222509Snp uint8_t lport; /* associated offload logical port */ 75222509Snp uint8_t dmac[ETHER_ADDR_LEN]; /* next hop's MAC address */ 76222509Snp}; 77222509Snp 78237263Snpstruct l2t_data { 79237263Snp struct rwlock lock; 80245434Snp u_int l2t_size; 81237263Snp volatile int nfree; /* number of free entries */ 82237263Snp struct l2t_entry *rover;/* starting point for next allocation */ 83245434Snp struct l2t_entry l2tab[]; 84237263Snp}; 85237263Snp 86237263Snp 87228561Snpint t4_init_l2t(struct adapter *, int); 88222509Snpint t4_free_l2t(struct l2t_data *); 89237263Snpstruct l2t_entry *t4_alloc_l2e(struct l2t_data *); 90222509Snpstruct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *); 91222509Snpint t4_l2t_set_switching(struct adapter *, struct l2t_entry *, uint16_t, 92222509Snp uint8_t, uint8_t *); 93237263Snpint t4_write_l2e(struct adapter *, struct l2t_entry *, int); 94237263Snpint do_l2t_write_rpl(struct sge_iq *, const struct rss_header *, struct mbuf *); 95237263Snp 96237263Snpstatic inline void 97237263Snpt4_l2t_release(struct l2t_entry *e) 98237263Snp{ 99241733Sed struct l2t_data *d = __containerof(e, struct l2t_data, l2tab[e->idx]); 100237263Snp 101237263Snp if (atomic_fetchadd_int(&e->refcnt, -1) == 1) 102237263Snp atomic_add_int(&d->nfree, 1); 103237263Snp} 104237263Snp 105237263Snp 106231115Snp#ifdef SBUF_DRAIN 107228561Snpint sysctl_l2t(SYSCTL_HANDLER_ARGS); 108231115Snp#endif 109222509Snp 110222509Snp#endif /* __T4_L2T_H */ 111