Import updated support code for the TOM (tcp offload module).
This commit is contained in:
parent
a0d231fbb8
commit
3e96c7e790
@ -55,12 +55,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifdef CONFIG_DEFINED
|
||||
#include <cxgb_osdep.h>
|
||||
#include <ulp/toecore/toedev.h>
|
||||
#include <t3cdev.h>
|
||||
#include <sys/mbufq.h>
|
||||
#include <ulp/toecore/cxgb_toedev.h>
|
||||
#else
|
||||
#include <dev/cxgb/cxgb_osdep.h>
|
||||
#include <dev/cxgb/t3cdev.h>
|
||||
#include <dev/cxgb/sys/mbufq.h>
|
||||
#include <dev/cxgb/ulp/toecore/toedev.h>
|
||||
#include <dev/cxgb/ulp/toecore/cxgb_toedev.h>
|
||||
#endif
|
||||
|
||||
#define USE_SX
|
||||
@ -371,7 +373,7 @@ struct adapter {
|
||||
|
||||
struct port_info port[MAX_NPORTS];
|
||||
device_t portdev[MAX_NPORTS];
|
||||
struct toedev tdev;
|
||||
struct t3cdev tdev;
|
||||
char fw_version[64];
|
||||
uint32_t open_device_map;
|
||||
uint32_t registered_device_map;
|
||||
@ -497,7 +499,7 @@ int t3_os_pci_restore_state(struct adapter *adapter);
|
||||
void t3_os_link_changed(adapter_t *adapter, int port_id, int link_status,
|
||||
int speed, int duplex, int fc);
|
||||
void t3_sge_err_intr_handler(adapter_t *adapter);
|
||||
int t3_offload_tx(struct toedev *, struct mbuf *);
|
||||
int t3_offload_tx(struct t3cdev *, struct mbuf *);
|
||||
void t3_os_ext_intr_handler(adapter_t *adapter);
|
||||
void t3_os_set_hw_addr(adapter_t *adapter, int port_idx, u8 hw_addr[]);
|
||||
int t3_mgmt_tx(adapter_t *adap, struct mbuf *m);
|
||||
@ -554,7 +556,7 @@ txq_to_qset(struct sge_txq *q, int qidx)
|
||||
}
|
||||
|
||||
static __inline struct adapter *
|
||||
tdev2adap(struct toedev *d)
|
||||
tdev2adap(struct t3cdev *d)
|
||||
{
|
||||
return container_of(d, struct adapter, tdev);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifdef CONFIG_DEFINED
|
||||
#include <cxgb_osdep.h>
|
||||
#include <common/cxgb_common.h>
|
||||
@ -14,11 +15,9 @@
|
||||
#include <common/cxgb_sge_defs.h>
|
||||
#include <common/cxgb_firmware_exports.h>
|
||||
#include <sys/mvec.h>
|
||||
#include <ulp/toecore/toedev.h>
|
||||
#include <sys/mbufq.h>
|
||||
#include <common/jhash.h>
|
||||
|
||||
|
||||
#include <ulp/toecore/cxgb_toedev.h>
|
||||
#else
|
||||
#include <dev/cxgb/cxgb_osdep.h>
|
||||
#include <dev/cxgb/common/cxgb_common.h>
|
||||
@ -31,7 +30,9 @@
|
||||
#include <dev/cxgb/common/cxgb_firmware_exports.h>
|
||||
|
||||
#include <dev/cxgb/sys/mvec.h>
|
||||
#include <dev/cxgb/ulp/toecore/toedev.h>
|
||||
#include <dev/cxgb/sys/mbufq.h>
|
||||
#include <dev/cxgb/common/jhash.h>
|
||||
#include <dev/cxgb/ulp/toecore/cxgb_toedev.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -59,7 +59,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define VLAN_NONE 0xfff
|
||||
#define SDL(s) ((struct sockaddr_dl *)s)
|
||||
#define RT_ENADDR(rt) ((u_char *)LLADDR(SDL((rt))))
|
||||
#define RT_ENADDR(sa) ((u_char *)LLADDR(SDL((sa))))
|
||||
#define rt_expire rt_rmx.rmx_expire
|
||||
|
||||
struct llinfo_arp {
|
||||
@ -103,11 +103,8 @@ neigh_replace(struct l2t_entry *e, struct rtentry *rt)
|
||||
RT_ADDREF(rt);
|
||||
RT_UNLOCK(rt);
|
||||
|
||||
if (e->neigh) {
|
||||
RT_LOCK(e->neigh);
|
||||
RT_REMREF(e->neigh);
|
||||
RT_UNLOCK(e->neigh);
|
||||
}
|
||||
if (e->neigh)
|
||||
RTFREE(e->neigh);
|
||||
e->neigh = rt;
|
||||
}
|
||||
|
||||
@ -117,7 +114,7 @@ neigh_replace(struct l2t_entry *e, struct rtentry *rt)
|
||||
* entry locked.
|
||||
*/
|
||||
static int
|
||||
setup_l2e_send_pending(struct toedev *dev, struct mbuf *m,
|
||||
setup_l2e_send_pending(struct t3cdev *dev, struct mbuf *m,
|
||||
struct l2t_entry *e)
|
||||
{
|
||||
struct cpl_l2t_write_req *req;
|
||||
@ -130,13 +127,14 @@ setup_l2e_send_pending(struct toedev *dev, struct mbuf *m,
|
||||
* XXX MH_ALIGN
|
||||
*/
|
||||
req = mtod(m, struct cpl_l2t_write_req *);
|
||||
m->m_pkthdr.len = m->m_len = sizeof(*req);
|
||||
|
||||
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
|
||||
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, e->idx));
|
||||
req->params = htonl(V_L2T_W_IDX(e->idx) | V_L2T_W_IFF(e->smt_idx) |
|
||||
V_L2T_W_VLAN(e->vlan & EVL_VLID_MASK) |
|
||||
V_L2T_W_PRIO(vlan_prio(e)));
|
||||
|
||||
memcpy(e->dmac, RT_ENADDR(e->neigh), sizeof(e->dmac));
|
||||
memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
|
||||
m_set_priority(m, CPL_PRIORITY_CONTROL);
|
||||
cxgb_ofld_send(dev, m);
|
||||
@ -168,21 +166,24 @@ arpq_enqueue(struct l2t_entry *e, struct mbuf *m)
|
||||
}
|
||||
|
||||
int
|
||||
t3_l2t_send_slow(struct toedev *dev, struct mbuf *m,
|
||||
struct l2t_entry *e)
|
||||
t3_l2t_send_slow(struct t3cdev *dev, struct mbuf *m, struct l2t_entry *e)
|
||||
{
|
||||
struct rtentry *rt;
|
||||
struct mbuf *m0;
|
||||
|
||||
if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
|
||||
return (ENOMEM);
|
||||
struct rtentry *rt = e->neigh;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
rt = e->neigh;
|
||||
bzero(&sin, sizeof(struct sockaddr_in));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_len = sizeof(struct sockaddr_in);
|
||||
sin.sin_addr.s_addr = e->addr;
|
||||
|
||||
|
||||
|
||||
printf("send slow on rt=%p eaddr=0x%08x\n", rt, e->addr);
|
||||
|
||||
again:
|
||||
switch (e->state) {
|
||||
case L2T_STATE_STALE: /* entry is stale, kick off revalidation */
|
||||
arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt));
|
||||
arpresolve(rt->rt_ifp, rt, NULL, (struct sockaddr *)&sin, e->dmac);
|
||||
mtx_lock(&e->lock);
|
||||
if (e->state == L2T_STATE_STALE)
|
||||
e->state = L2T_STATE_VALID;
|
||||
@ -197,9 +198,8 @@ t3_l2t_send_slow(struct toedev *dev, struct mbuf *m,
|
||||
}
|
||||
arpq_enqueue(e, m);
|
||||
mtx_unlock(&e->lock);
|
||||
|
||||
if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
|
||||
return (ENOMEM);
|
||||
printf("enqueueing arp request\n");
|
||||
|
||||
/*
|
||||
* Only the first packet added to the arpq should kick off
|
||||
* resolution. However, because the m_gethdr below can fail,
|
||||
@ -208,7 +208,13 @@ t3_l2t_send_slow(struct toedev *dev, struct mbuf *m,
|
||||
* A better way would be to use a work request to retry L2T
|
||||
* entries when there's no memory.
|
||||
*/
|
||||
if (arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt)) == 0) {
|
||||
printf("doing arpresolve on 0x%x \n", e->addr);
|
||||
if (arpresolve(rt->rt_ifp, rt, NULL, (struct sockaddr *)&sin, e->dmac) == 0) {
|
||||
printf("mac=%x:%x:%x:%x:%x:%x\n",
|
||||
e->dmac[0], e->dmac[1], e->dmac[2], e->dmac[3], e->dmac[4], e->dmac[5]);
|
||||
|
||||
if ((m = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
mtx_lock(&e->lock);
|
||||
if (e->arpq_head)
|
||||
@ -216,16 +222,21 @@ t3_l2t_send_slow(struct toedev *dev, struct mbuf *m,
|
||||
else
|
||||
m_freem(m);
|
||||
mtx_unlock(&e->lock);
|
||||
}
|
||||
} else
|
||||
printf("arpresolve returned non-zero\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
t3_l2t_send_event(struct toedev *dev, struct l2t_entry *e)
|
||||
t3_l2t_send_event(struct t3cdev *dev, struct l2t_entry *e)
|
||||
{
|
||||
struct rtentry *rt;
|
||||
struct mbuf *m0;
|
||||
struct sockaddr_in sin;
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_len = sizeof(struct sockaddr_in);
|
||||
sin.sin_addr.s_addr = e->addr;
|
||||
|
||||
if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
|
||||
return;
|
||||
@ -234,7 +245,7 @@ t3_l2t_send_event(struct toedev *dev, struct l2t_entry *e)
|
||||
again:
|
||||
switch (e->state) {
|
||||
case L2T_STATE_STALE: /* entry is stale, kick off revalidation */
|
||||
arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt));
|
||||
arpresolve(rt->rt_ifp, rt, m0, (struct sockaddr *)&sin, e->dmac);
|
||||
mtx_lock(&e->lock);
|
||||
if (e->state == L2T_STATE_STALE) {
|
||||
e->state = L2T_STATE_VALID;
|
||||
@ -261,7 +272,7 @@ t3_l2t_send_event(struct toedev *dev, struct l2t_entry *e)
|
||||
* A better way would be to use a work request to retry L2T
|
||||
* entries when there's no memory.
|
||||
*/
|
||||
arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt));
|
||||
arpresolve(rt->rt_ifp, rt, m0, (struct sockaddr *)&sin, e->dmac);
|
||||
|
||||
}
|
||||
return;
|
||||
@ -301,6 +312,7 @@ alloc_l2e(struct l2t_data *d)
|
||||
}
|
||||
e->state = L2T_STATE_UNUSED;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
@ -318,19 +330,21 @@ alloc_l2e(struct l2t_data *d)
|
||||
void
|
||||
t3_l2e_free(struct l2t_data *d, struct l2t_entry *e)
|
||||
{
|
||||
struct rtentry *rt = NULL;
|
||||
|
||||
mtx_lock(&e->lock);
|
||||
if (atomic_load_acq_int(&e->refcnt) == 0) { /* hasn't been recycled */
|
||||
if (e->neigh) {
|
||||
RT_LOCK(e->neigh);
|
||||
RT_REMREF(e->neigh);
|
||||
RT_UNLOCK(e->neigh);
|
||||
e->neigh = NULL;
|
||||
}
|
||||
rt = e->neigh;
|
||||
e->neigh = NULL;
|
||||
}
|
||||
|
||||
mtx_unlock(&e->lock);
|
||||
atomic_add_int(&d->nfree, 1);
|
||||
if (rt)
|
||||
RTFREE(rt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update an L2T entry that was previously used for the same next hop as neigh.
|
||||
* Must be called with softirqs disabled.
|
||||
@ -346,7 +360,7 @@ reuse_entry(struct l2t_entry *e, struct rtentry *neigh)
|
||||
if (neigh != e->neigh)
|
||||
neigh_replace(e, neigh);
|
||||
|
||||
if (memcmp(e->dmac, RT_ENADDR(neigh), sizeof(e->dmac)) ||
|
||||
if (memcmp(e->dmac, RT_ENADDR(neigh->rt_gateway), sizeof(e->dmac)) ||
|
||||
(neigh->rt_expire > time_uptime))
|
||||
e->state = L2T_STATE_RESOLVING;
|
||||
else if (la->la_hold == NULL)
|
||||
@ -357,14 +371,15 @@ reuse_entry(struct l2t_entry *e, struct rtentry *neigh)
|
||||
}
|
||||
|
||||
struct l2t_entry *
|
||||
t3_l2t_get(struct toedev *dev, struct rtentry *neigh,
|
||||
unsigned int smt_idx)
|
||||
t3_l2t_get(struct t3cdev *dev, struct rtentry *neigh, struct ifnet *ifp,
|
||||
struct sockaddr *sa)
|
||||
{
|
||||
struct l2t_entry *e;
|
||||
struct l2t_data *d = L2DATA(dev);
|
||||
u32 addr = *(u32 *) rt_key(neigh);
|
||||
u32 addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
|
||||
int ifidx = neigh->rt_ifp->if_index;
|
||||
int hash = arp_hash(addr, ifidx, d);
|
||||
unsigned int smt_idx = ((struct port_info *)ifp->if_softc)->port_id;
|
||||
|
||||
rw_wlock(&d->lock);
|
||||
for (e = d->l2tab[hash].first; e; e = e->next)
|
||||
@ -379,14 +394,21 @@ t3_l2t_get(struct toedev *dev, struct rtentry *neigh,
|
||||
/* Need to allocate a new entry */
|
||||
e = alloc_l2e(d);
|
||||
if (e) {
|
||||
printf("initializing new entry\n");
|
||||
|
||||
mtx_lock(&e->lock); /* avoid race with t3_l2t_free */
|
||||
e->next = d->l2tab[hash].first;
|
||||
d->l2tab[hash].first = e;
|
||||
rw_wunlock(&d->lock);
|
||||
|
||||
e->state = L2T_STATE_RESOLVING;
|
||||
e->addr = addr;
|
||||
e->ifindex = ifidx;
|
||||
e->smt_idx = smt_idx;
|
||||
atomic_store_rel_int(&e->refcnt, 1);
|
||||
e->neigh = NULL;
|
||||
|
||||
|
||||
neigh_replace(e, neigh);
|
||||
#ifdef notyet
|
||||
/*
|
||||
@ -398,7 +420,10 @@ t3_l2t_get(struct toedev *dev, struct rtentry *neigh,
|
||||
#endif
|
||||
e->vlan = VLAN_NONE;
|
||||
mtx_unlock(&e->lock);
|
||||
|
||||
return (e);
|
||||
}
|
||||
|
||||
done:
|
||||
rw_wunlock(&d->lock);
|
||||
return e;
|
||||
@ -413,7 +438,7 @@ t3_l2t_get(struct toedev *dev, struct rtentry *neigh,
|
||||
* handler.
|
||||
*/
|
||||
static void
|
||||
handle_failed_resolution(struct toedev *dev, struct mbuf *arpq)
|
||||
handle_failed_resolution(struct t3cdev *dev, struct mbuf *arpq)
|
||||
{
|
||||
|
||||
while (arpq) {
|
||||
@ -433,21 +458,20 @@ handle_failed_resolution(struct toedev *dev, struct mbuf *arpq)
|
||||
|
||||
}
|
||||
|
||||
#if defined(NETEVENT) || !defined(CONFIG_CHELSIO_T3_MODULE)
|
||||
/*
|
||||
* Called when the host's ARP layer makes a change to some entry that is
|
||||
* loaded into the HW L2 table.
|
||||
*/
|
||||
void
|
||||
t3_l2t_update(struct toedev *dev, struct rtentry *neigh)
|
||||
t3_l2t_update(struct t3cdev *dev, struct rtentry *neigh, struct sockaddr *sa)
|
||||
{
|
||||
struct l2t_entry *e;
|
||||
struct mbuf *arpq = NULL;
|
||||
struct l2t_data *d = L2DATA(dev);
|
||||
u32 addr = *(u32 *) rt_key(neigh);
|
||||
u32 addr = *(u32 *) &((struct sockaddr_in *)sa)->sin_addr;
|
||||
int ifidx = neigh->rt_ifp->if_index;
|
||||
int hash = arp_hash(addr, ifidx, d);
|
||||
struct llinfo_arp *la;
|
||||
u_char edst[ETHER_ADDR_LEN];
|
||||
|
||||
|
||||
printf("t3_l2t_update called with arp info\n");
|
||||
|
||||
rw_rlock(&d->lock);
|
||||
for (e = d->l2tab[hash].first; e; e = e->next)
|
||||
@ -456,10 +480,16 @@ t3_l2t_update(struct toedev *dev, struct rtentry *neigh)
|
||||
goto found;
|
||||
}
|
||||
rw_runlock(&d->lock);
|
||||
printf("addr=0x%08x not found\n", addr);
|
||||
return;
|
||||
|
||||
found:
|
||||
printf("found 0x%08x\n", addr);
|
||||
arpresolve(neigh->rt_ifp, neigh, NULL, sa, edst);
|
||||
|
||||
rw_runlock(&d->lock);
|
||||
memcpy(e->dmac, edst, ETHER_ADDR_LEN);
|
||||
|
||||
if (atomic_load_acq_int(&e->refcnt)) {
|
||||
if (neigh != e->neigh)
|
||||
neigh_replace(e, neigh);
|
||||
@ -470,12 +500,11 @@ t3_l2t_update(struct toedev *dev, struct rtentry *neigh)
|
||||
if (la->la_asked >= 5 /* arp_maxtries */) {
|
||||
arpq = e->arpq_head;
|
||||
e->arpq_head = e->arpq_tail = NULL;
|
||||
} else if (la->la_hold == NULL)
|
||||
} else
|
||||
setup_l2e_send_pending(dev, NULL, e);
|
||||
} else {
|
||||
e->state = (la->la_hold == NULL) ?
|
||||
L2T_STATE_VALID : L2T_STATE_STALE;
|
||||
if (memcmp(e->dmac, RT_ENADDR(neigh), 6))
|
||||
e->state = L2T_STATE_VALID;
|
||||
if (memcmp(e->dmac, RT_ENADDR(neigh->rt_gateway), 6))
|
||||
setup_l2e_send_pending(dev, NULL, e);
|
||||
}
|
||||
}
|
||||
@ -484,71 +513,6 @@ t3_l2t_update(struct toedev *dev, struct rtentry *neigh)
|
||||
if (arpq)
|
||||
handle_failed_resolution(dev, arpq);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Called from a kprobe, interrupts are off.
|
||||
*/
|
||||
void
|
||||
t3_l2t_update(struct toedev *dev, struct rtentry *neigh)
|
||||
{
|
||||
struct l2t_entry *e;
|
||||
struct l2t_data *d = L2DATA(dev);
|
||||
u32 addr = *(u32 *) rt_key(neigh);
|
||||
int ifidx = neigh->dev->ifindex;
|
||||
int hash = arp_hash(addr, ifidx, d);
|
||||
|
||||
rw_rlock(&d->lock);
|
||||
for (e = d->l2tab[hash].first; e; e = e->next)
|
||||
if (e->addr == addr && e->ifindex == ifidx) {
|
||||
mtx_lock(&e->lock);
|
||||
if (atomic_load_acq_int(&e->refcnt)) {
|
||||
if (neigh != e->neigh)
|
||||
neigh_replace(e, neigh);
|
||||
e->tdev = dev;
|
||||
mod_timer(&e->update_timer, jiffies + 1);
|
||||
}
|
||||
mtx_unlock(&e->lock);
|
||||
break;
|
||||
}
|
||||
rw_runlock(&d->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
update_timer_cb(unsigned long data)
|
||||
{
|
||||
struct mbuf *arpq = NULL;
|
||||
struct l2t_entry *e = (struct l2t_entry *)data;
|
||||
struct rtentry *neigh = e->neigh;
|
||||
struct toedev *dev = e->tdev;
|
||||
|
||||
barrier();
|
||||
if (!atomic_load_acq_int(&e->refcnt))
|
||||
return;
|
||||
|
||||
rw_rlock(&neigh->lock);
|
||||
mtx_lock(&e->lock);
|
||||
|
||||
if (atomic_load_acq_int(&e->refcnt)) {
|
||||
if (e->state == L2T_STATE_RESOLVING) {
|
||||
if (neigh->nud_state & NUD_FAILED) {
|
||||
arpq = e->arpq_head;
|
||||
e->arpq_head = e->arpq_tail = NULL;
|
||||
} else if (neigh_is_connected(neigh) && e->arpq_head)
|
||||
setup_l2e_send_pending(dev, NULL, e);
|
||||
} else {
|
||||
e->state = neigh_is_connected(neigh) ?
|
||||
L2T_STATE_VALID : L2T_STATE_STALE;
|
||||
if (memcmp(e->dmac, RT_ENADDR(neigh), sizeof(e->dmac)))
|
||||
setup_l2e_send_pending(dev, NULL, e);
|
||||
}
|
||||
}
|
||||
mtx_unlock(&e->lock);
|
||||
rw_runlock(&neigh->lock);
|
||||
|
||||
if (arpq)
|
||||
handle_failed_resolution(dev, arpq);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct l2t_data *
|
||||
t3_init_l2t(unsigned int l2t_capacity)
|
||||
@ -570,12 +534,6 @@ t3_init_l2t(unsigned int l2t_capacity)
|
||||
d->l2tab[i].state = L2T_STATE_UNUSED;
|
||||
mtx_init(&d->l2tab[i].lock, "L2TAB", NULL, MTX_DEF);
|
||||
atomic_store_rel_int(&d->l2tab[i].refcnt, 0);
|
||||
#ifndef NETEVENT
|
||||
#ifdef CONFIG_CHELSIO_T3_MODULE
|
||||
setup_timer(&d->l2tab[i].update_timer, update_timer_cb,
|
||||
(unsigned long)&d->l2tab[i]);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return d;
|
||||
}
|
||||
@ -583,86 +541,6 @@ t3_init_l2t(unsigned int l2t_capacity)
|
||||
void
|
||||
t3_free_l2t(struct l2t_data *d)
|
||||
{
|
||||
#ifndef NETEVENT
|
||||
#ifdef CONFIG_CHELSIO_T3_MODULE
|
||||
int i;
|
||||
|
||||
/* Stop all L2T timers */
|
||||
for (i = 0; i < d->nentries; ++i)
|
||||
del_timer_sync(&d->l2tab[i].update_timer);
|
||||
#endif
|
||||
#endif
|
||||
cxgb_free_mem(d);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
#include <linux/module.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
static inline void *
|
||||
l2t_get_idx(struct seq_file *seq, loff_t pos)
|
||||
{
|
||||
struct l2t_data *d = seq->private;
|
||||
|
||||
return pos >= d->nentries ? NULL : &d->l2tab[pos];
|
||||
}
|
||||
|
||||
static void *
|
||||
l2t_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
return *pos ? l2t_get_idx(seq, *pos) : SEQ_START_TOKEN;
|
||||
}
|
||||
|
||||
static void *
|
||||
l2t_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
v = l2t_get_idx(seq, *pos + 1);
|
||||
if (v)
|
||||
++*pos;
|
||||
return v;
|
||||
}
|
||||
|
||||
static void
|
||||
l2t_seq_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
}
|
||||
|
||||
static char
|
||||
l2e_state(const struct l2t_entry *e)
|
||||
{
|
||||
switch (e->state) {
|
||||
case L2T_STATE_VALID: return 'V'; /* valid, fast-path entry */
|
||||
case L2T_STATE_STALE: return 'S'; /* needs revalidation, but usable */
|
||||
case L2T_STATE_RESOLVING:
|
||||
return e->arpq_head ? 'A' : 'R';
|
||||
default:
|
||||
return 'U';
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
l2t_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
if (v == SEQ_START_TOKEN)
|
||||
seq_puts(seq, "Index IP address Ethernet address VLAN "
|
||||
"Prio State Users SMTIDX Port\n");
|
||||
else {
|
||||
char ip[20];
|
||||
struct l2t_entry *e = v;
|
||||
|
||||
mtx_lock(&e->lock);
|
||||
sprintf(ip, "%u.%u.%u.%u", NIPQUAD(e->addr));
|
||||
seq_printf(seq, "%-5u %-15s %02x:%02x:%02x:%02x:%02x:%02x %4d"
|
||||
" %3u %c %7u %4u %s\n",
|
||||
e->idx, ip, e->dmac[0], e->dmac[1], e->dmac[2],
|
||||
e->dmac[3], e->dmac[4], e->dmac[5],
|
||||
e->vlan & EVL_VLID_MASK, vlan_prio(e),
|
||||
l2e_state(e), atomic_load_acq_int(&e->refcnt), e->smt_idx,
|
||||
e->neigh ? e->neigh->dev->name : "");
|
||||
mtx_unlock(&e->lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef _CHELSIO_L2T_H
|
||||
#define _CHELSIO_L2T_H
|
||||
|
||||
#include <dev/cxgb/ulp/toecore/toedev.h>
|
||||
#include <dev/cxgb/ulp/toecore/cxgb_toedev.h>
|
||||
#include <sys/lock.h>
|
||||
|
||||
#if __FreeBSD_version > 700000
|
||||
@ -76,12 +76,6 @@ struct l2t_entry {
|
||||
struct mtx lock;
|
||||
volatile uint32_t refcnt; /* entry reference count */
|
||||
uint8_t dmac[6]; /* neighbour's MAC address */
|
||||
#ifndef NETEVENT
|
||||
#ifdef CONFIG_CHELSIO_T3_MODULE
|
||||
struct timer_list update_timer;
|
||||
struct toedev *tdev;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
struct l2t_data {
|
||||
@ -92,7 +86,10 @@ struct l2t_data {
|
||||
struct l2t_entry l2tab[0];
|
||||
};
|
||||
|
||||
typedef void (*arp_failure_handler_func)(struct toedev *dev,
|
||||
typedef void (*arp_failure_handler_func)(struct t3cdev *dev,
|
||||
struct mbuf *m);
|
||||
|
||||
typedef void (*opaque_arp_failure_handler_func)(void *dev,
|
||||
struct mbuf *m);
|
||||
|
||||
/*
|
||||
@ -111,10 +108,8 @@ struct l2t_mbuf_cb {
|
||||
static __inline void set_arp_failure_handler(struct mbuf *m,
|
||||
arp_failure_handler_func hnd)
|
||||
{
|
||||
#if 0
|
||||
L2T_SKB_CB(skb)->arp_failure_handler = hnd;
|
||||
#endif
|
||||
panic("implement me");
|
||||
m->m_pkthdr.header = (opaque_arp_failure_handler_func)hnd;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -123,12 +118,12 @@ static __inline void set_arp_failure_handler(struct mbuf *m,
|
||||
#define L2DATA(dev) ((dev)->l2opt)
|
||||
|
||||
void t3_l2e_free(struct l2t_data *d, struct l2t_entry *e);
|
||||
void t3_l2t_update(struct toedev *dev, struct rtentry *ifp);
|
||||
struct l2t_entry *t3_l2t_get(struct toedev *dev, struct rtentry *neigh,
|
||||
unsigned int smt_idx);
|
||||
int t3_l2t_send_slow(struct toedev *dev, struct mbuf *m,
|
||||
void t3_l2t_update(struct t3cdev *dev, struct rtentry *rt, struct sockaddr *sa);
|
||||
struct l2t_entry *t3_l2t_get(struct t3cdev *dev, struct rtentry *neigh,
|
||||
struct ifnet *ifp, struct sockaddr *sa);
|
||||
int t3_l2t_send_slow(struct t3cdev *dev, struct mbuf *m,
|
||||
struct l2t_entry *e);
|
||||
void t3_l2t_send_event(struct toedev *dev, struct l2t_entry *e);
|
||||
void t3_l2t_send_event(struct t3cdev *dev, struct l2t_entry *e);
|
||||
struct l2t_data *t3_init_l2t(unsigned int l2t_capacity);
|
||||
void t3_free_l2t(struct l2t_data *d);
|
||||
|
||||
@ -140,14 +135,17 @@ void t3_l2t_proc_free(struct proc_dir_entry *dir);
|
||||
#define l2t_proc_free(dir)
|
||||
#endif
|
||||
|
||||
int cxgb_ofld_send(struct toedev *dev, struct mbuf *m);
|
||||
int cxgb_ofld_send(struct t3cdev *dev, struct mbuf *m);
|
||||
|
||||
static inline int l2t_send(struct toedev *dev, struct mbuf *m,
|
||||
static inline int l2t_send(struct t3cdev *dev, struct mbuf *m,
|
||||
struct l2t_entry *e)
|
||||
{
|
||||
if (__predict_true(e->state == L2T_STATE_VALID))
|
||||
return cxgb_ofld_send(dev, m);
|
||||
return t3_l2t_send_slow(dev, m, e);
|
||||
if (__predict_true(e->state == L2T_STATE_VALID)) {
|
||||
return cxgb_ofld_send(dev, (struct mbuf *)m);
|
||||
}
|
||||
printf("send slow\n");
|
||||
|
||||
return t3_l2t_send_slow(dev, (struct mbuf *)m, e);
|
||||
}
|
||||
|
||||
static inline void l2t_release(struct l2t_data *d, struct l2t_entry *e)
|
||||
|
@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/ioccom.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/firmware.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
@ -116,7 +117,7 @@ static int offload_open(struct port_info *pi);
|
||||
static void touch_bars(device_t dev);
|
||||
|
||||
#ifdef notyet
|
||||
static int offload_close(struct toedev *tdev);
|
||||
static int offload_close(struct t3cdev *tdev);
|
||||
#endif
|
||||
|
||||
|
||||
@ -1235,7 +1236,7 @@ setup_rss(adapter_t *adap)
|
||||
* after dealing with any active network taps.
|
||||
*/
|
||||
static inline int
|
||||
offload_tx(struct toedev *tdev, struct mbuf *m)
|
||||
offload_tx(struct t3cdev *tdev, struct mbuf *m)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -1556,7 +1557,7 @@ static int
|
||||
offload_open(struct port_info *pi)
|
||||
{
|
||||
struct adapter *adapter = pi->adapter;
|
||||
struct toedev *tdev = TOEDEV(pi->ifp);
|
||||
struct t3cdev *tdev = TOEDEV(pi->ifp);
|
||||
int adap_up = adapter->open_device_map & PORT_MASK;
|
||||
int err = 0;
|
||||
|
||||
@ -1599,7 +1600,7 @@ offload_open(struct port_info *pi)
|
||||
}
|
||||
#ifdef notyet
|
||||
static int
|
||||
offload_close(struct toedev *tdev)
|
||||
offload_close(struct t3cev *tdev)
|
||||
{
|
||||
struct adapter *adapter = tdev2adap(tdev);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,13 +38,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <cxgb_config.h>
|
||||
#include <cxgb_l2t.h>
|
||||
#include <common/cxgb_tcb.h>
|
||||
#include <t3cdev.h>
|
||||
#else
|
||||
#include <dev/cxgb/common/cxgb_version.h>
|
||||
#include <dev/cxgb/cxgb_config.h>
|
||||
#include <dev/cxgb/cxgb_l2t.h>
|
||||
#include <dev/cxgb/common/cxgb_tcb.h>
|
||||
#include <dev/cxgb/t3cdev.h>
|
||||
#endif
|
||||
|
||||
MALLOC_DECLARE(M_CXGB);
|
||||
|
||||
struct adapter;
|
||||
struct cxgb_client;
|
||||
|
||||
@ -55,30 +59,30 @@ void cxgb_adapter_ofld(struct adapter *adapter);
|
||||
void cxgb_adapter_unofld(struct adapter *adapter);
|
||||
int cxgb_offload_activate(struct adapter *adapter);
|
||||
void cxgb_offload_deactivate(struct adapter *adapter);
|
||||
int cxgb_ofld_recv(struct toedev *dev, struct mbuf **m, int n);
|
||||
int cxgb_ofld_recv(struct t3cdev *dev, struct mbuf **m, int n);
|
||||
|
||||
void cxgb_set_dummy_ops(struct toedev *dev);
|
||||
void cxgb_set_dummy_ops(struct t3cdev *dev);
|
||||
|
||||
|
||||
/*
|
||||
* Client registration. Users of T3 driver must register themselves.
|
||||
* The T3 driver will call the add function of every client for each T3
|
||||
* adapter activated, passing up the toedev ptr. Each client fills out an
|
||||
* adapter activated, passing up the t3cdev ptr. Each client fills out an
|
||||
* array of callback functions to process CPL messages.
|
||||
*/
|
||||
|
||||
void cxgb_register_client(struct cxgb_client *client);
|
||||
void cxgb_unregister_client(struct cxgb_client *client);
|
||||
void cxgb_add_clients(struct toedev *tdev);
|
||||
void cxgb_remove_clients(struct toedev *tdev);
|
||||
void cxgb_add_clients(struct t3cdev *tdev);
|
||||
void cxgb_remove_clients(struct t3cdev *tdev);
|
||||
|
||||
typedef int (*cxgb_cpl_handler_func)(struct toedev *dev,
|
||||
typedef int (*cxgb_cpl_handler_func)(struct t3cdev *dev,
|
||||
struct mbuf *m, void *ctx);
|
||||
|
||||
struct cxgb_client {
|
||||
char *name;
|
||||
void (*add) (struct toedev *);
|
||||
void (*remove) (struct toedev *);
|
||||
void (*add) (struct t3cdev *);
|
||||
void (*remove) (struct t3cdev *);
|
||||
cxgb_cpl_handler_func *handlers;
|
||||
int (*redirect)(void *ctx, struct rtentry *old,
|
||||
struct rtentry *new,
|
||||
@ -89,17 +93,18 @@ struct cxgb_client {
|
||||
/*
|
||||
* TID allocation services.
|
||||
*/
|
||||
int cxgb_alloc_atid(struct toedev *dev, struct cxgb_client *client,
|
||||
int cxgb_alloc_atid(struct t3cdev *dev, struct cxgb_client *client,
|
||||
void *ctx);
|
||||
int cxgb_alloc_stid(struct toedev *dev, struct cxgb_client *client,
|
||||
int cxgb_alloc_stid(struct t3cdev *dev, struct cxgb_client *client,
|
||||
void *ctx);
|
||||
void *cxgb_free_atid(struct toedev *dev, int atid);
|
||||
void cxgb_free_stid(struct toedev *dev, int stid);
|
||||
void cxgb_insert_tid(struct toedev *dev, struct cxgb_client *client,
|
||||
void *cxgb_free_atid(struct t3cdev *dev, int atid);
|
||||
void cxgb_free_stid(struct t3cdev *dev, int stid);
|
||||
void *cxgb_get_lctx(struct t3cdev *tdev, int stid);
|
||||
void cxgb_insert_tid(struct t3cdev *dev, struct cxgb_client *client,
|
||||
void *ctx,
|
||||
unsigned int tid);
|
||||
void cxgb_queue_tid_release(struct toedev *dev, unsigned int tid);
|
||||
void cxgb_remove_tid(struct toedev *dev, void *ctx, unsigned int tid);
|
||||
void cxgb_queue_tid_release(struct t3cdev *dev, unsigned int tid);
|
||||
void cxgb_remove_tid(struct t3cdev *dev, void *ctx, unsigned int tid);
|
||||
|
||||
struct toe_tid_entry {
|
||||
struct cxgb_client *client;
|
||||
@ -123,7 +128,7 @@ enum {
|
||||
CPL_RET_UNKNOWN_TID = 4 // unexpected unknown TID
|
||||
};
|
||||
|
||||
typedef int (*cpl_handler_func)(struct toedev *dev, struct mbuf *m);
|
||||
typedef int (*cpl_handler_func)(struct t3cdev *dev, struct mbuf *m);
|
||||
|
||||
/*
|
||||
* Returns a pointer to the first byte of the CPL header in an sk_buff that
|
||||
@ -181,11 +186,8 @@ struct tid_info {
|
||||
unsigned int stids_in_use;
|
||||
};
|
||||
|
||||
struct toe_data {
|
||||
#ifdef notyet
|
||||
struct list_head list_node;
|
||||
#endif
|
||||
struct toedev *dev;
|
||||
struct t3c_data {
|
||||
struct t3cdev *dev;
|
||||
unsigned int tx_max_chunk; /* max payload for TX_DATA */
|
||||
unsigned int max_wrs; /* max in-flight WRs per connection */
|
||||
unsigned int nmtus;
|
||||
@ -198,9 +200,9 @@ struct toe_data {
|
||||
};
|
||||
|
||||
/*
|
||||
* toedev -> toe_data accessor
|
||||
* t3cdev -> toe_data accessor
|
||||
*/
|
||||
#define TOE_DATA(dev) (*(struct toe_data **)&(dev)->l4opt)
|
||||
#define T3C_DATA(dev) (*(struct t3c_data **)&(dev)->l4opt)
|
||||
|
||||
/*
|
||||
* Map an ATID or STID to their entries in the corresponding TID tables.
|
||||
@ -251,11 +253,11 @@ static inline struct toe_tid_entry *lookup_atid(const struct tid_info *t,
|
||||
|
||||
void *cxgb_alloc_mem(unsigned long size);
|
||||
void cxgb_free_mem(void *addr);
|
||||
void cxgb_neigh_update(struct rtentry *rt);
|
||||
void cxgb_redirect(struct rtentry *old, struct rtentry *new);
|
||||
int process_rx(struct toedev *dev, struct mbuf **m, int n);
|
||||
int attach_toedev(struct toedev *dev);
|
||||
void detach_toedev(struct toedev *dev);
|
||||
|
||||
void cxgb_neigh_update(struct rtentry *rt, struct sockaddr *sa);
|
||||
void cxgb_redirect(struct rtentry *old, struct rtentry *new, struct sockaddr *sa);
|
||||
int process_rx(struct t3cdev *dev, struct mbuf **m, int n);
|
||||
int attach_t3cdev(struct t3cdev *dev);
|
||||
void detach_t3cdev(struct t3cdev *dev);
|
||||
|
||||
#define UNIMPLEMENTED() panic("IMPLEMENT: %s:%s:%d", __FUNCTION__, __FILE__, __LINE__)
|
||||
#endif
|
||||
|
@ -60,7 +60,7 @@ struct t3_mbuf_hdr {
|
||||
|
||||
#define PANIC_IF(exp) do { \
|
||||
if (exp) \
|
||||
panic("BUG: %s", exp); \
|
||||
panic("BUG: %s", #exp); \
|
||||
} while (0)
|
||||
|
||||
|
||||
@ -97,9 +97,6 @@ struct t3_mbuf_hdr {
|
||||
|
||||
#define CXGB_TX_CLEANUP_THRESHOLD 32
|
||||
|
||||
#define LOG_WARNING 1
|
||||
#define LOG_ERR 2
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
#define DPRINTF printf
|
||||
#else
|
||||
|
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/rman.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/taskqueue.h>
|
||||
|
||||
#include <sys/proc.h>
|
||||
@ -1988,7 +1989,7 @@ is_ctrl_pkt(const struct mbuf *m)
|
||||
* should be sent as regular or control, bits 1-3 select the queue set.
|
||||
*/
|
||||
int
|
||||
t3_offload_tx(struct toedev *tdev, struct mbuf *m)
|
||||
t3_offload_tx(struct t3cdev *tdev, struct mbuf *m)
|
||||
{
|
||||
adapter_t *adap = tdev2adap(tdev);
|
||||
struct sge_qset *qs = &adap->sge.qs[queue_set(m)];
|
||||
@ -2009,7 +2010,7 @@ t3_offload_tx(struct toedev *tdev, struct mbuf *m)
|
||||
* Delivers a (partial) bundle of Rx offload packets to an offload device.
|
||||
*/
|
||||
static __inline void
|
||||
deliver_partial_bundle(struct toedev *tdev,
|
||||
deliver_partial_bundle(struct t3cdev *tdev,
|
||||
struct sge_rspq *q,
|
||||
struct mbuf *mbufs[], int n)
|
||||
{
|
||||
@ -2020,7 +2021,7 @@ deliver_partial_bundle(struct toedev *tdev,
|
||||
}
|
||||
|
||||
static __inline int
|
||||
rx_offload(struct toedev *tdev, struct sge_rspq *rq,
|
||||
rx_offload(struct t3cdev *tdev, struct sge_rspq *rq,
|
||||
struct mbuf *m, struct mbuf *rx_gather[],
|
||||
unsigned int gather_idx)
|
||||
{
|
||||
|
61
sys/dev/cxgb/t3cdev.h
Normal file
61
sys/dev/cxgb/t3cdev.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*-
|
||||
* Copyright (c) 2007, Chelsio Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Neither the name of the Chelsio Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _T3CDEV_H_
|
||||
#define _T3CDEV_H_
|
||||
|
||||
#define T3CNAMSIZ 16
|
||||
|
||||
/* Get the t3cdev associated with an ifnet */
|
||||
#define T3CDEV(ifp) (&(((struct port_info *)(ifp)->if_softc))->adapter->tdev)
|
||||
|
||||
struct cxgb3_client;
|
||||
|
||||
enum t3ctype {
|
||||
T3A = 0,
|
||||
T3B
|
||||
};
|
||||
|
||||
struct t3cdev {
|
||||
char name[T3CNAMSIZ]; /* T3C device name */
|
||||
enum t3ctype type;
|
||||
TAILQ_ENTRY(t3cdev) entry; /* for list linking */
|
||||
struct ifnet *lldev; /* LL dev associated with T3C messages */
|
||||
struct adapter *adapter;
|
||||
int (*send)(struct t3cdev *dev, struct mbuf *m);
|
||||
int (*recv)(struct t3cdev *dev, struct mbuf **m, int n);
|
||||
int (*ctl)(struct t3cdev *dev, unsigned int req, void *data);
|
||||
void (*arp_update)(struct t3cdev *dev, struct rtentry *neigh, struct sockaddr *sa);
|
||||
void *priv; /* driver private data */
|
||||
void *l2opt; /* optional layer 2 data */
|
||||
void *l3opt; /* optional layer 3 data */
|
||||
void *l4opt; /* optional layer 4 data */
|
||||
void *ulp; /* ulp stuff */
|
||||
};
|
||||
|
||||
#endif /* _T3CDEV_H_ */
|
46
sys/dev/cxgb/ulp/toecore/cxgb_toedev.h
Normal file
46
sys/dev/cxgb/ulp/toecore/cxgb_toedev.h
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
/**************************************************************************
|
||||
|
||||
Copyright (c) 2007, Chelsio Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Neither the name of the Chelsio Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
$FreeBSD$
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _CXGB_TOEDEV_H_
|
||||
#define _CXGB_TOEDEV_H_
|
||||
#include <netinet/toedev.h>
|
||||
|
||||
/* offload type ids */
|
||||
enum {
|
||||
TOE_ID_CHELSIO_T1 = 1,
|
||||
TOE_ID_CHELSIO_T1C,
|
||||
TOE_ID_CHELSIO_T2,
|
||||
TOE_ID_CHELSIO_T3,
|
||||
TOE_ID_CHELSIO_T3B,
|
||||
};
|
||||
|
||||
#endif
|
424
sys/dev/cxgb/ulp/toecore/toedev.c
Normal file
424
sys/dev/cxgb/ulp/toecore/toedev.c
Normal file
@ -0,0 +1,424 @@
|
||||
|
||||
/**************************************************************************
|
||||
|
||||
Copyright (c) 2007, Chelsio Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Neither the name of the Chelsio Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#include <net/bpf.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
|
||||
|
||||
/*
|
||||
* XXX
|
||||
*/
|
||||
#ifdef CONFIG_DEFINED
|
||||
#include <cxgb_include.h>
|
||||
#else
|
||||
#include <dev/cxgb/cxgb_include.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static struct mtx offload_db_lock;
|
||||
static TAILQ_HEAD(, toedev) offload_dev_list;
|
||||
static TAILQ_HEAD(, tom_info) offload_module_list;
|
||||
|
||||
/*
|
||||
* Returns the entry in the given table with the given offload id, or NULL
|
||||
* if the id is not found.
|
||||
*/
|
||||
static const struct offload_id *
|
||||
id_find(unsigned int id, const struct offload_id *table)
|
||||
{
|
||||
for ( ; table->id; ++table)
|
||||
if (table->id == id)
|
||||
return table;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if an offload device is presently attached to an offload module.
|
||||
*/
|
||||
static inline int
|
||||
is_attached(const struct toedev *dev)
|
||||
{
|
||||
return dev->tod_offload_mod != NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to attach a new offload device to an existing TCP offload module that
|
||||
* can handle the device's offload id. Returns 0 if it succeeds.
|
||||
*
|
||||
* Must be called with the offload_db_lock held.
|
||||
*/
|
||||
static int
|
||||
offload_attach(struct toedev *dev)
|
||||
{
|
||||
struct tom_info *t;
|
||||
|
||||
TAILQ_FOREACH(t, &offload_module_list, entry) {
|
||||
const struct offload_id *entry;
|
||||
|
||||
entry = id_find(dev->tod_ttid, t->ti_id_table);
|
||||
if (entry && t->ti_attach(dev, entry) == 0) {
|
||||
dev->tod_offload_mod = t;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return (ENOPROTOOPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* register_tom - register a TCP Offload Module (TOM)
|
||||
* @t: the offload module to register
|
||||
*
|
||||
* Register a TCP Offload Module (TOM).
|
||||
*/
|
||||
int
|
||||
register_tom(struct tom_info *t)
|
||||
{
|
||||
mtx_lock(&offload_db_lock);
|
||||
TAILQ_INSERT_HEAD(&offload_module_list, t, entry);
|
||||
mtx_unlock(&offload_db_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* unregister_tom - unregister a TCP Offload Module (TOM)
|
||||
* @t: the offload module to register
|
||||
*
|
||||
* Unregister a TCP Offload Module (TOM). Note that this does not affect any
|
||||
* TOE devices to which the TOM is already attached.
|
||||
*/
|
||||
int
|
||||
unregister_tom(struct tom_info *t)
|
||||
{
|
||||
mtx_lock(&offload_db_lock);
|
||||
TAILQ_REMOVE(&offload_module_list, t, entry);
|
||||
mtx_unlock(&offload_db_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an offload device by name. Must be called with offload_db_lock held.
|
||||
*/
|
||||
static struct toedev *
|
||||
__find_offload_dev_by_name(const char *name)
|
||||
{
|
||||
struct toedev *dev;
|
||||
|
||||
TAILQ_FOREACH(dev, &offload_dev_list, entry) {
|
||||
if (!strncmp(dev->tod_name, name, TOENAMSIZ))
|
||||
return dev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if an offload device is already registered.
|
||||
* Must be called with the offload_db_lock held.
|
||||
*/
|
||||
static int
|
||||
is_registered(const struct toedev *dev)
|
||||
{
|
||||
struct toedev *d;
|
||||
|
||||
TAILQ_FOREACH(d, &offload_dev_list, entry) {
|
||||
if (d == dev)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finalize the name of an offload device by assigning values to any format
|
||||
* strings in its name.
|
||||
*/
|
||||
static int
|
||||
assign_name(struct toedev *dev, const char *name, int limit)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < limit; ++i) {
|
||||
char s[TOENAMSIZ];
|
||||
|
||||
if (snprintf(s, sizeof(s), name, i) >= sizeof(s))
|
||||
return -1; /* name too long */
|
||||
if (!__find_offload_dev_by_name(s)) {
|
||||
strcpy(dev->tod_name, s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* register_toedev - register a TOE device
|
||||
* @dev: the device
|
||||
* @name: a name template for the device
|
||||
*
|
||||
* Register a TOE device and try to attach an appropriate TCP offload module
|
||||
* to it. @name is a template that may contain at most one %d format
|
||||
* specifier.
|
||||
*/
|
||||
int
|
||||
register_toedev(struct toedev *dev, const char *name)
|
||||
{
|
||||
int ret;
|
||||
const char *p;
|
||||
|
||||
/*
|
||||
* Validate the name template. Only one %d allowed and name must be
|
||||
* a valid filename so it can appear in sysfs.
|
||||
*/
|
||||
if (!name || !*name || !strcmp(name, ".") || !strcmp(name, "..") ||
|
||||
strchr(name, '/'))
|
||||
return EINVAL;
|
||||
|
||||
p = strchr(name, '%');
|
||||
if (p && (p[1] != 'd' || strchr(p + 2, '%')))
|
||||
return EINVAL;
|
||||
|
||||
mtx_lock(&offload_db_lock);
|
||||
if (is_registered(dev)) { /* device already registered */
|
||||
ret = EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((ret = assign_name(dev, name, 32)) != 0)
|
||||
goto out;
|
||||
|
||||
dev->tod_offload_mod = NULL;
|
||||
TAILQ_INSERT_TAIL(&offload_dev_list, dev, entry);
|
||||
out:
|
||||
mtx_unlock(&offload_db_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* unregister_toedev - unregister a TOE device
|
||||
* @dev: the device
|
||||
*
|
||||
* Unregister a TOE device. The device must not be attached to an offload
|
||||
* module.
|
||||
*/
|
||||
int
|
||||
unregister_toedev(struct toedev *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mtx_lock(&offload_db_lock);
|
||||
if (!is_registered(dev)) {
|
||||
ret = ENODEV;
|
||||
goto out;
|
||||
}
|
||||
if (is_attached(dev)) {
|
||||
ret = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
TAILQ_REMOVE(&offload_dev_list, dev, entry);
|
||||
out:
|
||||
mtx_unlock(&offload_db_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* activate_offload - activate an offload device
|
||||
* @dev: the device
|
||||
*
|
||||
* Activate an offload device by locating an appropriate registered offload
|
||||
* module. If no module is found the operation fails and may be retried at
|
||||
* a later time.
|
||||
*/
|
||||
int
|
||||
activate_offload(struct toedev *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mtx_lock(&offload_db_lock);
|
||||
if (!is_registered(dev))
|
||||
ret = ENODEV;
|
||||
else if (!is_attached(dev))
|
||||
ret = offload_attach(dev);
|
||||
mtx_unlock(&offload_db_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* toe_send - send a packet to a TOE device
|
||||
* @dev: the device
|
||||
* @m: the packet
|
||||
*
|
||||
* Sends an mbuf to a TOE driver after dealing with any active network taps.
|
||||
*/
|
||||
int
|
||||
toe_send(struct toedev *dev, struct mbuf *m)
|
||||
{
|
||||
int r;
|
||||
|
||||
critical_enter(); /* XXX neccessary? */
|
||||
r = dev->tod_send(dev, m);
|
||||
critical_exit();
|
||||
if (r)
|
||||
BPF_MTAP(dev->tod_lldev, m);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* toe_receive_mbuf - process n received TOE packets
|
||||
* @dev: the toe device
|
||||
* @m: an array of offload packets
|
||||
* @n: the number of offload packets
|
||||
*
|
||||
* Process an array of ingress offload packets. Each packet is forwarded
|
||||
* to any active network taps and then passed to the toe device's receive
|
||||
* method. We optimize passing packets to the receive method by passing
|
||||
* it the whole array at once except when there are active taps.
|
||||
*/
|
||||
int
|
||||
toe_receive_mbuf(struct toedev *dev, struct mbuf **m, int n)
|
||||
{
|
||||
if (__predict_true(!bpf_peers_present(dev->tod_lldev->if_bpf)))
|
||||
return dev->tod_recv(dev, m, n);
|
||||
|
||||
for ( ; n; n--, m++) {
|
||||
m[0]->m_pkthdr.rcvif = dev->tod_lldev;
|
||||
BPF_MTAP(dev->tod_lldev, m[0]);
|
||||
dev->tod_recv(dev, m, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ifnet_is_offload(const struct ifnet *ifp)
|
||||
{
|
||||
return (ifp->if_flags & IFCAP_TOE);
|
||||
}
|
||||
|
||||
void
|
||||
toe_arp_update(struct rtentry *rt)
|
||||
{
|
||||
struct ifnet *ifp = rt->rt_ifp;
|
||||
|
||||
if (ifp && ifnet_is_offload(ifp)) {
|
||||
struct toedev *tdev = TOEDEV(ifp);
|
||||
|
||||
if (tdev && tdev->tod_arp_update)
|
||||
tdev->tod_arp_update(tdev, rt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* offload_get_phys_egress - find the physical egress device
|
||||
* @root_dev: the root device anchoring the search
|
||||
* @so: the socket used to determine egress port in bonding mode
|
||||
* @context: in bonding mode, indicates a connection set up or failover
|
||||
*
|
||||
* Given a root network device it returns the physical egress device that is a
|
||||
* descendant of the root device. The root device may be either a physical
|
||||
* device, in which case it is the device returned, or a virtual device, such
|
||||
* as a VLAN or bonding device. In case of a bonding device the search
|
||||
* considers the decisions of the bonding device given its mode to locate the
|
||||
* correct egress device.
|
||||
*/
|
||||
struct ifnet *
|
||||
offload_get_phys_egress(struct ifnet *root_dev, struct socket *so, int context)
|
||||
{
|
||||
|
||||
#if 0
|
||||
while (root_dev && ifnet_is_offload(root_dev)) {
|
||||
if (root_dev->tod_priv_flags & IFF_802_1Q_VLAN)
|
||||
root_dev = VLAN_DEV_INFO(root_dev)->real_dev;
|
||||
else if (root_dev->tod_flags & IFF_MASTER)
|
||||
root_dev = toe_bond_get_slave(root_dev, sk, context);
|
||||
else
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return root_dev;
|
||||
}
|
||||
|
||||
static int
|
||||
toecore_load(module_t mod, int cmd, void *arg)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case MOD_LOAD:
|
||||
mtx_init(&offload_db_lock, "toedev lock", NULL, MTX_DEF);
|
||||
TAILQ_INIT(&offload_dev_list);
|
||||
TAILQ_INIT(&offload_module_list);
|
||||
break;
|
||||
case MOD_QUIESCE:
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
mtx_lock(&offload_db_lock);
|
||||
if (!TAILQ_EMPTY(&offload_dev_list) ||
|
||||
!TAILQ_EMPTY(&offload_module_list)) {
|
||||
err = EBUSY;
|
||||
mtx_unlock(&offload_db_lock);
|
||||
break;
|
||||
}
|
||||
mtx_unlock(&offload_db_lock);
|
||||
mtx_destroy(&offload_db_lock);
|
||||
break;
|
||||
case MOD_SHUTDOWN:
|
||||
break;
|
||||
default:
|
||||
err = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
||||
static moduledata_t mod_data= {
|
||||
"toecore",
|
||||
toecore_load,
|
||||
0
|
||||
};
|
||||
|
||||
MODULE_VERSION(toecore, 1);
|
||||
DECLARE_MODULE(toecore, mod_data, SI_SUB_EXEC, SI_ORDER_ANY);
|
@ -1,172 +0,0 @@
|
||||
|
||||
/**************************************************************************
|
||||
|
||||
Copyright (c) 2007, Chelsio Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Neither the name of the Chelsio Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
$FreeBSD$
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _OFFLOAD_DEV_H_
|
||||
#define _OFFLOAD_DEV_H_
|
||||
|
||||
|
||||
/* Parameter values for offload_get_phys_egress() */
|
||||
enum {
|
||||
TOE_OPEN,
|
||||
TOE_FAILOVER,
|
||||
};
|
||||
|
||||
/* Parameter values for toe_failover() */
|
||||
enum {
|
||||
TOE_ACTIVE_SLAVE,
|
||||
TOE_LINK_DOWN,
|
||||
TOE_LINK_UP,
|
||||
TOE_RELEASE,
|
||||
TOE_RELEASE_ALL,
|
||||
};
|
||||
|
||||
|
||||
#define TOENAMSIZ 16
|
||||
|
||||
/* belongs in linux/netdevice.h */
|
||||
#define NETIF_F_TCPIP_OFFLOAD (1 << 15)
|
||||
|
||||
/* Get the toedev associated with a ifnet */
|
||||
#define TOEDEV(netdev) (*(struct toedev **)&(netdev)->if_softc)
|
||||
|
||||
/* offload type ids */
|
||||
enum {
|
||||
TOE_ID_CHELSIO_T1 = 1,
|
||||
TOE_ID_CHELSIO_T1C,
|
||||
TOE_ID_CHELSIO_T2,
|
||||
TOE_ID_CHELSIO_T3,
|
||||
TOE_ID_CHELSIO_T3B,
|
||||
};
|
||||
|
||||
struct offload_id {
|
||||
unsigned int id;
|
||||
unsigned long data;
|
||||
};
|
||||
|
||||
struct ifnet;
|
||||
struct rt_entry;
|
||||
struct tom_info;
|
||||
struct sysctl_oid;
|
||||
struct socket;
|
||||
struct mbuf;
|
||||
|
||||
enum toetype {
|
||||
T3A = 0,
|
||||
T3B
|
||||
};
|
||||
|
||||
struct toedev {
|
||||
char name[TOENAMSIZ]; /* TOE device name */
|
||||
enum toetype type;
|
||||
struct adapter *adapter;
|
||||
unsigned int ttid; /* TOE type id */
|
||||
unsigned long flags; /* device flags */
|
||||
unsigned int mtu; /* max size of TX offloaded data */
|
||||
unsigned int nconn; /* max # of offloaded connections */
|
||||
struct ifnet *lldev; /* LL device associated with TOE messages */
|
||||
const struct tom_info *offload_mod; /* attached TCP offload module */
|
||||
struct sysctl_oid *sysctl_root; /* root of proc dir for this TOE */
|
||||
TAILQ_ENTRY(toedev) ofld_entry; /* for list linking */
|
||||
int (*open)(struct toedev *dev);
|
||||
int (*close)(struct toedev *dev);
|
||||
int (*can_offload)(struct toedev *dev, struct socket *so);
|
||||
int (*connect)(struct toedev *dev, struct socket *so,
|
||||
struct ifnet *egress_ifp);
|
||||
int (*send)(struct toedev *dev, struct mbuf *m);
|
||||
int (*recv)(struct toedev *dev, struct mbuf **m, int n);
|
||||
int (*ctl)(struct toedev *dev, unsigned int req, void *data);
|
||||
void (*neigh_update)(struct toedev *dev, struct rtentry *neigh);
|
||||
void (*failover)(struct toedev *dev, struct ifnet *bond_ifp,
|
||||
struct ifnet *ndev, int event);
|
||||
void *priv; /* driver private data */
|
||||
void *l2opt; /* optional layer 2 data */
|
||||
void *l3opt; /* optional layer 3 data */
|
||||
void *l4opt; /* optional layer 4 data */
|
||||
void *ulp; /* ulp stuff */
|
||||
};
|
||||
|
||||
struct tom_info {
|
||||
int (*attach)(struct toedev *dev, const struct offload_id *entry);
|
||||
int (*detach)(struct toedev *dev);
|
||||
const char *name;
|
||||
const struct offload_id *id_table;
|
||||
TAILQ_ENTRY(tom_info) entry;
|
||||
};
|
||||
|
||||
static inline void init_offload_dev(struct toedev *dev)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
extern int register_tom(struct tom_info *t);
|
||||
extern int unregister_tom(struct tom_info *t);
|
||||
extern int register_toedev(struct toedev *dev, const char *name);
|
||||
extern int unregister_toedev(struct toedev *dev);
|
||||
extern int activate_offload(struct toedev *dev);
|
||||
extern int toe_send(struct toedev *dev, struct mbuf *m);
|
||||
extern struct ifnet *offload_get_phys_egress(struct ifnet *dev,
|
||||
struct socket *so,
|
||||
int context);
|
||||
|
||||
#if defined(CONFIG_TCP_OFFLOAD_MODULE)
|
||||
static inline int toe_receive_mbuf(struct toedev *dev, struct mbuf **m,
|
||||
int n)
|
||||
{
|
||||
return dev->recv(dev, m, n);
|
||||
}
|
||||
|
||||
extern int prepare_tcp_for_offload(void);
|
||||
extern void restore_tcp_to_nonoffload(void);
|
||||
#elif defined(CONFIG_TCP_OFFLOAD)
|
||||
extern int toe_receive_mbuf(struct toedev *dev, struct mbuf **m, int n);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_TCP_OFFLOAD) || \
|
||||
(defined(CONFIG_TCP_OFFLOAD_MODULE) && defined(MODULE))
|
||||
extern void toe_neigh_update(struct rtentry *neigh);
|
||||
extern void toe_failover(struct ifnet *bond_ifp,
|
||||
struct ifnet *fail_ifp, int event);
|
||||
extern int toe_enslave(struct ifnet *bond_ifp,
|
||||
struct ifnet *slave_ifp);
|
||||
#else
|
||||
static inline void toe_neigh_update(struct ifnet *neigh) {}
|
||||
static inline void toe_failover(struct ifnet *bond_ifp,
|
||||
struct ifnet *fail_ifp, int event)
|
||||
{}
|
||||
static inline int toe_enslave(struct ifnet *bond_ifp,
|
||||
struct ifnet *slave_ifp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_TCP_OFFLOAD */
|
||||
|
||||
#endif /* _OFFLOAD_DEV_H_ */
|
Loading…
Reference in New Issue
Block a user