Updating more Chelsio files.

This commit is contained in:
jklos 2007-07-08 02:30:30 +00:00
parent 424b422ccd
commit c2dc605e95
5 changed files with 484 additions and 24 deletions

View File

@ -65,7 +65,7 @@
#include <dev/pci/cxgb_ctl_defs.h>
#include <dev/pci/cxgb_sge_defs.h>
#include <dev/pci/cxgb_firmware_exports.h>
// #include <sys/mvec.h>
#include "cxgb_mvec.h"
#include "cxgb_toedev.h"
// #include <sys/mbufq.h>
#include "cxgb_jhash.h"

View File

@ -46,11 +46,17 @@ __FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_l2t.c,v 1.2 2007/05/28 22:57:26 kmacy
#include <sys/socket.h>
#include <sys/socketvar.h>
#ifdef __FreeBSD__
#include <net/if.h>
#ifdef __FreeBSD__
#include <net/ethernet.h>
#include <net/if_vlan_var.h>
#endif
#ifdef __NetBSD__
#define EVL_VLID_MASK 0x0FFF
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/if_inarp.h>
#endif
#include <net/if_dl.h>
#include <net/route.h>
#include <netinet/in.h>
@ -74,6 +80,7 @@ __FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_l2t.c,v 1.2 2007/05/28 22:57:26 kmacy
#define RT_ENADDR(rt) ((char *)LLADDR(SDL((rt))))
#define rt_expire rt_rmx.rmx_expire
#ifdef __FreeBSD__
struct llinfo_arp {
struct callout la_timer;
struct rtentry *la_rt;
@ -81,6 +88,7 @@ struct llinfo_arp {
u_short la_preempt; /* countdown for pre-expiry arps */
u_short la_asked; /* # requests sent */
};
#endif
/*
* Module locking notes: There is a RW lock protecting the L2 table as a
@ -111,16 +119,30 @@ arp_hash(u32 key, int ifindex, const struct l2t_data *d)
static inline void
neigh_replace(struct l2t_entry *e, struct rtentry *rt)
{
RT_LOCK(rt);
RT_ADDREF(rt);
RT_UNLOCK(rt);
#ifdef __FreeBSD__
mtx_lock(rt->rt_mtx)
rt->rt_refcnt++;
mtx_unlock(rt->rt_mtx);
if (e->neigh) {
RT_LOCK(e->neigh);
RT_REMREF(e->neigh);
RT_UNLOCK(e->neigh);
mtx_lock(e->neigh->rt_mtx);
e->neigh->rt_refcnt--;
mtx_unlock(e->neigh->rt_mtx);
}
e->neigh = rt;
#endif
#ifdef __NetBSD__
int s = splsoftnet();
rt->rt_refcnt++;
if (e->neigh) {
e->neigh->rt_refcnt--;
}
e->neigh = rt;
splx(s);
#endif
}
/*
@ -286,18 +308,39 @@ alloc_l2e(struct l2t_data *d)
{
struct l2t_entry *end, *e, **p;
#ifdef __FreeBSD__
if (!atomic_load_acq_int(&d->nfree))
return NULL;
#endif
#ifdef __NetBSD__
if (!d->nfree)
return NULL;
#endif
/* there's definitely a free entry */
for (e = d->rover, end = &d->l2tab[d->nentries]; e != end; ++e)
#ifdef __FreeBSD__
if (atomic_load_acq_int(&e->refcnt) == 0)
#endif
#ifdef __NetBSD__
if (e->refcnt == 0)
#endif
goto found;
#ifdef __FreeBSD__
for (e = &d->l2tab[1]; atomic_load_acq_int(&e->refcnt); ++e) ;
#endif
#ifdef __NetBSD__
for (e = &d->l2tab[1]; e->refcnt; ++e) ;
#endif
found:
d->rover = e + 1;
#ifdef __FreeBSD__
atomic_add_int(&d->nfree, -1);
#endif
#ifdef __NetBSD__
d->nfree--; // XXXXXXXXXXXXXXXXXXX
#endif
/*
* The entry we found may be an inactive entry that is
@ -331,16 +374,30 @@ void
t3_l2e_free(struct l2t_data *d, struct l2t_entry *e)
{
mtx_lock(&e->lock);
#ifdef __FreeBSD__
if (atomic_load_acq_int(&e->refcnt) == 0) { /* hasn't been recycled */
#endif
#ifdef __NetBSD__
if (e->refcnt == 0) { /* hasn't been recycled */
#endif
if (e->neigh) {
RT_LOCK(e->neigh);
RT_REMREF(e->neigh);
RT_UNLOCK(e->neigh);
#ifdef __FreeBSD__
mtx_lock(e->neigh->rt_mtx);
#endif
e->neigh->rt_refcnt--;
#ifdef __FreeBSD__
mtx_unlock(e->neigh->rt_mtx);
#endif
e->neigh = NULL;
}
}
mtx_unlock(&e->lock);
#ifdef __FreeBSD__
atomic_add_int(&d->nfree, 1);
#endif
#ifdef __NetBSD__
d->nfree++; // XXXXXXXXXXXXXXXXXXXXXXXXXXXX
#endif
}
/*
@ -378,12 +435,22 @@ t3_l2t_get(struct toedev *dev, struct rtentry *neigh,
int ifidx = neigh->rt_ifp->if_index;
int hash = arp_hash(addr, ifidx, d);
#ifdef __FreeBSD__
rw_wlock(&d->lock);
#endif
#ifdef __NetBSD__
rw_enter(&d->lock, RW_WRITER);
#endif
for (e = d->l2tab[hash].first; e; e = e->next)
if (e->addr == addr && e->ifindex == ifidx &&
e->smt_idx == smt_idx) {
l2t_hold(d, e);
#ifdef __FreeBSD__
if (atomic_load_acq_int(&e->refcnt) == 1)
#endif
#ifdef __NetBSD__
if (e->refcnt == 1)
#endif
reuse_entry(e, neigh);
goto done;
}
@ -398,7 +465,12 @@ t3_l2t_get(struct toedev *dev, struct rtentry *neigh,
e->addr = addr;
e->ifindex = ifidx;
e->smt_idx = smt_idx;
#ifdef __FreeBSD__
atomic_store_rel_int(&e->refcnt, 1);
#endif
#ifdef __NetBSD__
e->refcnt = 1;
#endif
neigh_replace(e, neigh);
#ifdef notyet
/*
@ -412,7 +484,12 @@ t3_l2t_get(struct toedev *dev, struct rtentry *neigh,
mtx_unlock(&e->lock);
}
done:
#ifdef __FreeBSD__
rw_wunlock(&d->lock);
#endif
#ifdef __NetBSD__
rw_exit(&d->lock);
#endif
return e;
}
@ -461,18 +538,34 @@ t3_l2t_update(struct toedev *dev, struct rtentry *neigh)
int hash = arp_hash(addr, ifidx, d);
struct llinfo_arp *la;
#ifdef __FreeBSD__
rw_rlock(&d->lock);
#endif
#ifdef __NetBSD__
rw_enter(&d->lock, RW_READER);
#endif
for (e = d->l2tab[hash].first; e; e = e->next)
if (e->addr == addr && e->ifindex == ifidx) {
mtx_lock(&e->lock);
goto found;
}
#ifdef __FreeBSD__
rw_runlock(&d->lock);
#endif
#ifdef __NetBSD__
rw_exit(&d->lock);
#endif
return;
found:
#ifdef __FreeBSD__
rw_runlock(&d->lock);
if (atomic_load_acq_int(&e->refcnt)) {
#endif
#ifdef __NetBSD__
rw_exit(&d->lock);
if (e->refcnt) {
#endif
if (neigh != e->neigh)
neigh_replace(e, neigh);
@ -509,11 +602,21 @@ t3_l2t_update(struct toedev *dev, struct rtentry *neigh)
int ifidx = neigh->dev->ifindex;
int hash = arp_hash(addr, ifidx, d);
#ifdef __FreeBSD__
rw_rlock(&d->lock);
#endif
#ifdef __NetBSD__
rw_enter(&d->lock, RW_READER);
#endif
for (e = d->l2tab[hash].first; e; e = e->next)
if (e->addr == addr && e->ifindex == ifidx) {
mtx_lock(&e->lock);
#ifdef __FreeBSD__
if (atomic_load_acq_int(&e->refcnt)) {
#endif
#ifdef __NetBSD__
if (e->refcnt) {
#endif
if (neigh != e->neigh)
neigh_replace(e, neigh);
e->tdev = dev;
@ -522,7 +625,12 @@ t3_l2t_update(struct toedev *dev, struct rtentry *neigh)
mtx_unlock(&e->lock);
break;
}
#ifdef __FreeBSD__
rw_runlock(&d->lock);
#endif
#ifdef __NetBSD__
rw_exit(&d->lock);
#endif
}
static void
@ -534,13 +642,28 @@ update_timer_cb(unsigned long data)
struct toedev *dev = e->tdev;
barrier();
#ifdef __FreeBSD__
if (!atomic_load_acq_int(&e->refcnt))
#endif
#ifdef __NetBSD__
if (!e->refcnt)
#endif
return;
#ifdef __FreeBSD__
rw_rlock(&neigh->lock);
#endif
#ifdef __NetBSD__
rw_enter(&neigh->lock, RW_READER);
#endif
mtx_lock(&e->lock);
#ifdef __FreeBSD__
if (atomic_load_acq_int(&e->refcnt)) {
#endif
#ifdef __NeteBSD__
if (&e->refcnt) {
#endif
if (e->state == L2T_STATE_RESOLVING) {
if (neigh->nud_state & NUD_FAILED) {
arpq = e->arpq_head;
@ -555,7 +678,12 @@ update_timer_cb(unsigned long data)
}
}
mtx_unlock(&e->lock);
#ifdef __FreeBSD__
rw_runlock(&neigh->lock);
#endif
#ifdef __NetBSD__
rw_exit(&neigh->lock);
#endif
if (arpq)
handle_failed_resolution(dev, arpq);
@ -574,14 +702,25 @@ t3_init_l2t(unsigned int l2t_capacity)
d->nentries = l2t_capacity;
d->rover = &d->l2tab[1]; /* entry 0 is not used */
#ifdef __FreeBSD__
atomic_store_rel_int(&d->nfree, l2t_capacity - 1);
rw_init(&d->lock, "L2T");
#endif
#ifdef __NetBSD__
d->nfree = l2t_capacity - 1;
rw_init(&d->lock);
#endif
for (i = 0; i < l2t_capacity; ++i) {
d->l2tab[i].idx = i;
d->l2tab[i].state = L2T_STATE_UNUSED;
mtx_init(&d->l2tab[i].lock, "L2TAB", NULL, MTX_DEF);
#ifdef __FreeBSD__
atomic_store_rel_int(&d->l2tab[i].refcnt, 0);
#endif
#ifdef __NetBSD__
d->l2tab[i].refcnt = 0;
#endif
#ifndef NETEVENT
#ifdef CONFIG_CHELSIO_T3_MODULE
setup_timer(&d->l2tab[i].update_timer, update_timer_cb,

View File

@ -42,11 +42,15 @@ __FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_lro.c,v 1.7 2007/06/13 05:35:59 kmacy
#endif
#include <sys/conf.h>
#include <machine/bus.h>
#ifdef __FreeBSD__
#include <machine/resource.h>
#include <sys/bus_dma.h>
#include <sys/rman.h>
#endif
#include <sys/queue.h>
#ifdef __FreeBSD__
#include <sys/taskqueue.h>
#endif
#include <netinet/in_systm.h>
#include <netinet/in.h>
@ -60,13 +64,13 @@ __FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_lro.c,v 1.7 2007/06/13 05:35:59 kmacy
#else
#include <dev/cxgb/cxgb_include.h>
#endif
#include <machine/in_cksum.h>
#endif
#ifdef __NetBSD__
#include "cxgb_include.h"
#endif
#include <machine/in_cksum.h>
#ifndef M_LRO
#define M_LRO 0x0200
@ -185,6 +189,25 @@ lro_new_session_init(struct t3_lro_session *s, struct mbuf *m)
}
#ifdef __NetBSD__
u_short in_cksum_hdr(struct ip *ih);
u_short in_cksum_hdr(struct ip *ih)
{
u_long sum = 0;
u_short *p = (u_short *)ih;
int i;
i = ih->ip_hl*2;
while (i--)
sum += *p++;
if (sum > 0xffff)
sum -= 0xffff;
return (~sum);
}
#endif
static void
lro_flush_session(struct sge_qset *qs, struct t3_lro_session *s, struct mbuf *m)
{
@ -192,7 +215,7 @@ lro_flush_session(struct sge_qset *qs, struct t3_lro_session *s, struct mbuf *m)
struct mbuf *sm = s->head;
struct ip *ih = (struct ip *)(mtod(sm, uint8_t *) + IPH_OFFSET);
#ifdef __FreeBSD__
DPRINTF("%s(qs=%p, s=%p, ", __FUNCTION__,
qs, s);
@ -200,6 +223,7 @@ lro_flush_session(struct sge_qset *qs, struct t3_lro_session *s, struct mbuf *m)
DPRINTF("m=%p)\n", m);
else
DPRINTF("m=NULL)\n");
#endif
ih->ip_len = htons(s->ip_len);
ih->ip_sum = 0;
@ -386,9 +410,11 @@ no_lro:
if (s)
lro_flush_session(qs, s, NULL);
#ifdef __FreeBSD__
if (m->m_len == 0 || m->m_pkthdr.len == 0 || (m->m_flags & M_PKTHDR) == 0)
DPRINTF("rx_eth_lro mbuf len=%d pktlen=%d flags=0x%x\n",
m->m_len, m->m_pkthdr.len, m->m_flags);
#endif
t3_rx_eth(pi, rq, m, ethpad);
}

View File

@ -112,11 +112,21 @@ typedef char *caddr_t;
#endif
static int cxgb_setup_msix(adapter_t *, int);
#ifdef __FreeBSD__
static void cxgb_init(void *);
#endif
#ifdef __NetBSD__
static int cxgb_init(struct ifnet *);
#endif
static void cxgb_init_locked(struct port_info *);
static void cxgb_stop_locked(struct port_info *);
static void cxgb_set_rxmode(struct port_info *);
#ifdef __FreeBSD__
static int cxgb_ioctl(struct ifnet *, unsigned long, caddr_t);
#endif
#ifdef __NetBSD__
static int cxgb_ioctl(struct ifnet *, unsigned long, void *);
#endif
static void cxgb_start(struct ifnet *);
static void cxgb_start_proc(void *, int ncount);
static int cxgb_media_change(struct ifnet *);
@ -160,9 +170,16 @@ static int offload_open(struct port_info *pi);
static int offload_close(struct toedev *tdev);
#endif
#ifdef __FreeBSD__
static d_ioctl_t cxgb_extension_ioctl;
#endif
#ifdef __NetBSD__
static int cxgb_extension_ioctl(dev_t dev, u_long cmd, void *data, int fflag, struct lwp *td);
#endif
#ifdef __FreeBSD__
static device_method_t cxgb_controller_methods[] = {
DEVMETHOD(device_probe, cxgb_controller_probe),
DEVMETHOD(device_attach, cxgb_controller_attach),
@ -906,7 +923,7 @@ cxgb_port_probe(device_t dev)
#endif
#ifdef __NetBSD__
static int cxgb_port_match(device_t dev, struct cfdata *match, void *context);
static int cxgb_port_match(device_t dev, struct cfdata *match, void *context)
{
struct port_info *p = (struct port_info *)dev; // device is first thing in adapter
char buf[80];
@ -927,11 +944,11 @@ cxgb_makedev(struct port_info *pi)
if ((cxgb_cdevsw = malloc(sizeof(struct cdevsw), M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
return (ENOMEM);
#ifdef __FreeBSD__
cxgb_cdevsw->d_version = D_VERSION;
cxgb_cdevsw->d_name = strdup(pi->ifp->if_xname, M_DEVBUF);
#ifdef __FreeBSD__
cxgb_cdevsw->d_ioctl = cxgb_extension_ioctl;
#endif
cxgb_cdevsw->d_ioctl = cxgb_extension_ioctl;
pi->port_cdev = make_dev(cxgb_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
pi->ifp->if_xname);
@ -988,26 +1005,45 @@ static void cxgb_port_attach(device_t dev, device_t self, void *context)
#endif
#ifdef __NetBSD__
struct port_info *p = (struct port_info *)dev; // device is first thing in adapter
int err;
#endif
struct ifnet *ifp;
int media_flags;
int err;
char buf[64];
snprintf(buf, sizeof(buf), "cxgb port %d", p->port);
mtx_init(&p->lock, buf, 0, MTX_DEF);
/* Allocate an ifnet object and set it up */
#ifdef __FreeBSD__
ifp = p->ifp = if_alloc(IFT_ETHER);
#endif
#ifdef __NetBSD__
ifp = p->ifp = (void *)malloc(sizeof (struct ifnet), M_IFADDR, M_WAITOK);
#endif
if (ifp == NULL) {
device_printf(dev, "Cannot allocate ifnet\n");
#ifdef __FreeBSD__
return (ENOMEM);
#endif
#ifdef __NetBSD__
return;
#endif
}
#ifdef __NetBSD__
memset(ifp, 0, sizeof(struct ifnet));
#endif
/*
* Note that there is currently no watchdog timer.
*/
#ifdef __FreeBSD__
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
#endif
#ifdef __NetBSD__
snprintf(buf, sizeof(buf), "cxgb%d", p->port);
strcpy(ifp->if_xname, buf);
#endif
ifp->if_init = cxgb_init;
ifp->if_softc = p;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
@ -1015,9 +1051,14 @@ static void cxgb_port_attach(device_t dev, device_t self, void *context)
ifp->if_start = cxgb_start;
ifp->if_timer = 0; /* Disable ifnet watchdog */
ifp->if_watchdog = NULL;
#ifdef __FreeBSD__
ifp->if_snd.ifq_drv_maxlen = TX_ETH_Q_SIZE;
IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
#endif
#ifdef __NetBSD__
ifp->if_snd.ifq_maxlen = TX_ETH_Q_SIZE;
IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_maxlen);
#endif
IFQ_SET_READY(&ifp->if_snd);
#ifdef __FreeBSD__
@ -1037,10 +1078,12 @@ static void cxgb_port_attach(device_t dev, device_t self, void *context)
#ifdef DEFAULT_JUMBO
ifp->if_mtu = 9000;
#endif
#ifdef __FreeBSD__
if ((err = cxgb_makedev(p)) != 0) {
printf("makedev failed %d\n", err);
return (err);
}
#endif
ifmedia_init(&p->media, IFM_IMASK, cxgb_media_change,
cxgb_media_status);
@ -1052,7 +1095,12 @@ static void cxgb_port_attach(device_t dev, device_t self, void *context)
media_flags = IFM_ETHER | IFM_10G_LR;
else {
printf("unsupported media type %s\n", p->port_type->desc);
#ifdef __FreeBSD__
return (ENXIO);
#endif
#ifdef __NetBSD__
return;
#endif
}
ifmedia_add(&p->media, media_flags, 0, NULL);
@ -1074,18 +1122,30 @@ static void cxgb_port_attach(device_t dev, device_t self, void *context)
if (p->tq == NULL) {
device_printf(dev, "failed to allocate port task queue\n");
#ifdef __FreeBSD__
return (ENOMEM);
#endif
#ifdef __NetBSD__
return;
#endif
}
taskqueue_start_threads(&p->tq, 1, PI_NET, "%s taskq",
device_get_nameunit(dev));
TASK_INIT(&p->start_task, 0, cxgb_start_proc, ifp);
#endif
#ifdef __FreeBSD__
return (0);
#endif
}
static int
#ifdef __FreeBSD__
cxgb_port_detach(device_t dev)
#endif
#ifdef __NetBSD__
cxgb_port_detach(device_t dev, int flags)
#endif
{
#ifdef __FreeBSD__
struct port_info *p = device_get_softc(dev);
@ -1108,11 +1168,13 @@ cxgb_port_detach(device_t dev)
#endif
ether_ifdetach(p->ifp);
#ifdef __FreeBSD__
if_free(p->ifp);
destroy_dev(p->port_cdev);
#endif
#ifdef __NetBSD__
if_detach(p->ifp);
#endif
return (0);
}
@ -1638,14 +1700,29 @@ offload_close(struct toedev *tdev)
return 0;
}
#ifdef __FreeBSD__
static void
cxgb_init(void *arg)
#endif
#ifdef __NetBSD__
static int
cxgb_init(struct ifnet *ifp)
#endif
{
#ifdef __FreeBSD__
struct port_info *p = arg;
#endif
#ifdef __NetBSD__
struct port_info *p = ifp->if_softc;
#endif
PORT_LOCK(p);
cxgb_init_locked(p);
PORT_UNLOCK(p);
#ifdef __NetBSD__
return (0); // ???????????
#endif
}
static void
@ -1740,8 +1817,14 @@ cxgb_stop_locked(struct port_info *p)
ADAPTER_UNLOCK(p->adapter);
}
#ifdef __FreeBSD__
static int
cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
#endif
#ifdef __NetBSD__
static int
cxgb_ioctl(struct ifnet *ifp, unsigned long command, void *data)
#endif
{
struct port_info *p = ifp->if_softc;
struct ifaddr *ifa = (struct ifaddr *)data;
@ -1775,7 +1858,12 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
if (!(ifp->if_flags & IFF_RUNNING))
#endif
{
#ifdef __FreeBSD__
cxgb_init(p);
#endif
#ifdef __NetBSD__
cxgb_init(ifp);
#endif
}
arp_ifinit(ifp, ifa);
} else
@ -1833,7 +1921,12 @@ cxgb_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
break;
case SIOCSIFCAP:
PORT_LOCK(p);
#ifdef __FreeBSD__
mask = ifr->ifr_reqcap ^ ifp->if_capenable;
#endif
#ifdef __NetBSD__
mask = ifp->if_capenable;
#endif
if (mask & IFCAP_TXCSUM) {
if (IFCAP_TXCSUM & ifp->if_capenable) {
ifp->if_capenable &= ~(IFCAP_TXCSUM|IFCAP_TSO4);
@ -2189,9 +2282,14 @@ in_range(int val, int lo, int hi)
static int
cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
int fflag, struct thread *td)
#endif
#ifdef __NetBSD__
static int
cxgb_extension_ioctl(dev_t dev, u_long cmd, void *data, int fflag, struct lwp *td)
#endif
{
int mmd, error = 0;
struct port_info *pi = dev->si_drv1;
struct port_info *pi = &dev->si_drv1;
adapter_t *sc = pi->adapter;
#ifdef PRIV_SUPPORTED
@ -2584,7 +2682,6 @@ cxgb_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
return (error);
}
#endif
static __inline void
reg_block_dump(struct adapter *ap, uint8_t *buf, unsigned int start,

198
sys/dev/pci/cxgb_mvec.h Normal file
View File

@ -0,0 +1,198 @@
/**************************************************************************
*
* Copyright (c) 2007, Kip Macy kmacy@freebsd.org
* 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. The name of Kip Macy nor the names of other
* 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: src/sys/dev/cxgb/sys/mvec.h,v 1.5 2007/05/25 16:42:25 kmacy Exp $
*
***************************************************************************/
#ifndef _MVEC_H_
#define _MVEC_H_
#include <sys/mbuf.h>
#define mtomv(m) ((struct mbuf_vec *)((m)->m_pktdat))
#define M_IOVEC 0x100000 /* mbuf immediate data area is used for cluster ptrs */
#define MBUF_IOV_TYPE_MASK ((1<<3)-1)
#define mbuf_vec_set_type(mv, i, type) \
(mv)->mv_vec[(i)].mi_flags = (((mv)->mv_vec[(i)].mi_flags \
& ~MBUF_IOV_TYPE_MASK) | type)
#define mbuf_vec_get_type(mv, i) \
((mv)->mv_vec[(i)].mi_flags & MBUF_IOV_TYPE_MASK)
struct mbuf_iovec {
uint16_t mi_flags; /* per-cluster flags */
uint16_t mi_len; /* length of cluster */
uint32_t mi_offset; /* data offsets into cluster */
uint8_t *mi_base; /* pointers to cluster */
volatile uint32_t *mi_refcnt; /* refcnt for cluster*/
#ifdef __i386__
void *mi_args; /* for sf_buf */
#endif
};
#define MAX_MBUF_IOV ((MHLEN-8)/sizeof(struct mbuf_iovec))
struct mbuf_vec {
uint16_t mv_first; /* first valid cluster */
uint16_t mv_count; /* # of clusters */
uint32_t mv_flags; /* flags for iovec */
struct mbuf_iovec mv_vec[MAX_MBUF_IOV];
};
int _m_explode(struct mbuf *);
int _m_collapse(struct mbuf *, int maxbufs, struct mbuf **);
void mb_free_vec(struct mbuf *m);
static __inline void
m_iovinit(struct mbuf *m)
{
struct mbuf_vec *mv = mtomv(m);
mv->mv_first = mv->mv_count = 0;
m->m_pkthdr.len = m->m_len = 0;
m->m_flags |= M_IOVEC;
}
static __inline void
m_iovappend(struct mbuf *m, uint8_t *cl, int size, int len, int offset)
{
struct mbuf_vec *mv = mtomv(m);
struct mbuf_iovec *iov;
int idx = mv->mv_first + mv->mv_count;
#ifdef __FreeBSD__
KASSERT(idx <= MAX_MBUF_IOV, ("tried to append too many clusters to mbuf iovec"));
#endif
if ((m->m_flags & M_EXT) != 0)
panic("invalid flags in %s", __func__);
if (mv->mv_count == 0)
m->m_data = cl + offset;
iov = &mv->mv_vec[idx];
#ifdef __FreeBSD__
iov->mi_flags = m_gettype(size);
#endif
iov->mi_base = cl;
iov->mi_len = len;
iov->mi_offset = offset;
m->m_pkthdr.len += len;
m->m_len += len;
mv->mv_count++;
}
static __inline int
m_explode(struct mbuf *m)
{
if ((m->m_flags & M_IOVEC) == 0)
return (0);
return _m_explode(m);
}
static __inline int
m_collapse(struct mbuf *m, int maxbufs, struct mbuf **mnew)
{
#if (!defined(__sparc64__) && !defined(__sun4v__))
if (m->m_next == NULL)
#endif
{
*mnew = m;
return (0);
}
return _m_collapse(m, maxbufs, mnew);
}
static __inline struct mbuf *
m_free_vec(struct mbuf *m)
{
struct mbuf *n = m->m_next;
#ifdef __FreeBSD__
if (m->m_flags & M_IOVEC)
mb_free_vec(m);
else if (m->m_flags & M_EXT)
mb_free_ext(m);
else
uma_zfree(zone_mbuf, m);
#endif
return (n);
}
static __inline void
m_freem_vec(struct mbuf *m)
{
while (m != NULL)
m = m_free_vec(m);
}
static __inline uma_zone_t
m_getzonefromtype(int type)
{
uma_zone_t zone;
switch (type) {
case EXT_MBUF:
zone = zone_mbuf;
break;
case EXT_CLUSTER:
zone = zone_clust;
break;
#if MJUMPAGESIZE != MCLBYTES
case EXT_JUMBOP:
zone = zone_jumbop;
break;
#endif
case EXT_JUMBO9:
zone = zone_jumbo9;
break;
case EXT_JUMBO16:
zone = zone_jumbo16;
break;
#ifndef PACKET_ZONE_DISABLED
case EXT_PACKET:
zone = zone_pack;
break;
#endif
default:
panic("%s: invalid cluster type %d", __func__, type);
}
return (zone);
}
#if (!defined(__sparc64__) && !defined(__sun4v__))
int
bus_dmamap_load_mvec_sg(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0,
bus_dma_segment_t *segs, int *nsegs, int flags);
#else
#define bus_dmamap_load_mvec_sg bus_dmamap_load_mbuf_sg
#endif
#endif