MFC: sync the mxge driver with HEAD, modulo some slight differences

due to RELENG_6 limitations.
	(no TSO in RELENG_6, no VLAN tag insertion/removal due to
         vlan differences, etc).
This commit is contained in:
gallatin 2007-10-02 15:59:54 +00:00
parent 889525161a
commit ce75f1ca36
13 changed files with 461 additions and 2275 deletions

View File

@ -230,6 +230,7 @@ options DRM_DEBUG # Include debug printfs (slow)
# (requires miibus)
# lnc: Lance/PCnet cards (Isolan, Novell NE2100, NE32-VL, AMD Am7990 and
# Am79C960)
# mxge: Myricom Myri-10G 10GbE NIC
# nve: nVidia nForce MCP on-board Ethernet Networking
#XXX# still calls MD i386 kvtop function instead of vtophys etc
@ -238,6 +239,7 @@ options DRM_DEBUG # Include debug printfs (slow)
#XXX#options ED_HPP
#XXX#options ED_SIC
#XXX#device lnc
device mxge # Myricom Myri-10G 10GbE NIC
device nve # nVidia nForce MCP on-board Ethernet Networking
device ath

View File

@ -184,6 +184,11 @@ dev/kbd/kbd.c optional atkbd
dev/kbd/kbd.c optional sc
dev/kbd/kbd.c optional ukbd
dev/mem/memutil.c optional mem
dev/mxge/if_mxge.c optional mxge pci
dev/mxge/mxge_lro.c optional mxge pci
dev/mxge/mxge_eth_z8e.c optional mxge pci
dev/mxge/mxge_ethp_z8e.c optional mxge pci
net/zlib.c optional mxge
dev/nve/if_nve.c optional nve pci
dev/rr232x/os_bsd.c optional rr232x
dev/rr232x/osm_bsd.c optional rr232x

View File

@ -219,6 +219,11 @@ dev/lnc/if_lnc_isa.c optional lnc isa
dev/mem/memutil.c optional mem
dev/mse/mse.c optional mse
dev/mse/mse_isa.c optional mse isa
dev/mxge/if_mxge.c optional mxge pci
dev/mxge/mxge_lro.c optional mxge pci
dev/mxge/mxge_eth_z8e.c optional mxge pci
dev/mxge/mxge_ethp_z8e.c optional mxge pci
net/zlib.c optional mxge
dev/nve/if_nve.c optional nve pci
dev/ppc/ppc.c optional ppc
dev/ppc/ppc_puc.c optional ppc puc pci

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/******************************************************************************
Copyright (c) 2006, Myricom Inc.
Copyright (c) 2006-2007, Myricom Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -9,11 +9,7 @@ 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. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Myricom Inc, nor the names of its
2. Neither the name of the Myricom Inc, nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
@ -80,6 +76,10 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h> /* for pmap_mapdev() */
#include <vm/pmap.h>
#if defined(__i386) || defined(__amd64)
#include <machine/specialreg.h>
#endif
#include <dev/mxge/mxge_mcp.h>
#include <dev/mxge/mcp_gen_header.h>
#include <dev/mxge/if_mxge_var.h>
@ -91,6 +91,7 @@ static int mxge_intr_coal_delay = 30;
static int mxge_deassert_wait = 1;
static int mxge_flow_control = 1;
static int mxge_verbose = 0;
static int mxge_lro_cnt = 8;
static int mxge_ticks;
static char *mxge_fw_unaligned = "mxge_ethp_z8e";
static char *mxge_fw_aligned = "mxge_eth_z8e";
@ -123,15 +124,20 @@ static devclass_t mxge_devclass;
/* Declare ourselves to be a child of the PCI bus.*/
DRIVER_MODULE(mxge, pci, mxge_driver, mxge_devclass, 0, 0);
MODULE_DEPEND(mxge, firmware, 1, 1, 1);
MODULE_DEPEND(mxge, zlib, 1, 1, 1);
static int mxge_load_firmware(mxge_softc_t *sc);
static int mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data);
static int mxge_close(mxge_softc_t *sc);
static int mxge_open(mxge_softc_t *sc);
static void mxge_tick(void *arg);
static int
mxge_probe(device_t dev)
{
if ((pci_get_vendor(dev) == MXGE_PCI_VENDOR_MYRICOM) &&
(pci_get_device(dev) == MXGE_PCI_DEVICE_Z8E)) {
((pci_get_device(dev) == MXGE_PCI_DEVICE_Z8E) ||
(pci_get_device(dev) == MXGE_PCI_DEVICE_Z8E_9))) {
device_set_desc(dev, "Myri10G-PCIE-8A");
return 0;
}
@ -141,13 +147,22 @@ mxge_probe(device_t dev)
static void
mxge_enable_wc(mxge_softc_t *sc)
{
#if defined(__i386) || defined(__amd64)
struct mem_range_desc mrdesc;
vm_paddr_t pa;
vm_offset_t len;
int err, action;
pa = rman_get_start(sc->mem_res);
sc->wc = 1;
len = rman_get_size(sc->mem_res);
err = pmap_change_attr((vm_offset_t) sc->sram,
len, PAT_WRITE_COMBINING);
if (err == 0)
return;
else
device_printf(sc->dev, "pmap_change_attr failed, %d\n",
err);
pa = rman_get_start(sc->mem_res);
mrdesc.mr_base = pa;
mrdesc.mr_len = len;
mrdesc.mr_flags = MDF_WRITECOMBINE;
@ -155,12 +170,12 @@ mxge_enable_wc(mxge_softc_t *sc)
strcpy((char *)&mrdesc.mr_owner, "mxge");
err = mem_range_attr_set(&mrdesc, &action);
if (err != 0) {
sc->wc = 0;
device_printf(sc->dev,
"w/c failed for pa 0x%lx, len 0x%lx, err = %d\n",
(unsigned long)pa, (unsigned long)len, err);
} else {
sc->wc = 1;
}
#endif
}
@ -410,7 +425,7 @@ mxge_enable_nvidia_ecrc(mxge_softc_t *sc)
}
#else
static void
mxge_enable_nvidia_ecrc(mxge_softc_t *sc, device_t pdev)
mxge_enable_nvidia_ecrc(mxge_softc_t *sc)
{
device_printf(sc->dev,
"Nforce 4 chipset on non-x86/amd64!?!?!\n");
@ -631,62 +646,101 @@ mxge_validate_firmware(mxge_softc_t *sc, const mcp_gen_header_t *hdr)
}
static void *
z_alloc(void *nil, u_int items, u_int size)
{
void *ptr;
ptr = malloc(items * size, M_TEMP, M_NOWAIT);
return ptr;
}
static void
z_free(void *nil, void *ptr)
{
free(ptr, M_TEMP);
}
static int
mxge_load_firmware_helper(mxge_softc_t *sc, uint32_t *limit)
{
z_stream zs;
char *inflate_buffer;
const struct firmware *fw;
const mcp_gen_header_t *hdr;
unsigned hdr_offset;
const char *fw_data;
union qualhack hack;
int status;
unsigned int i;
char dummy;
size_t fw_len;
fw = firmware_get(sc->fw_name);
if (fw == NULL) {
device_printf(sc->dev, "Could not find firmware image %s\n",
sc->fw_name);
return ENOENT;
}
if (fw->datasize > *limit ||
fw->datasize < MCP_HEADER_PTR_OFFSET + 4) {
device_printf(sc->dev, "Firmware image %s too large (%d/%d)\n",
sc->fw_name, (int)fw->datasize, (int) *limit);
status = ENOSPC;
goto abort_with_fw;
}
*limit = fw->datasize;
/* check id */
fw_data = (const char *)fw->data;
hdr_offset = htobe32(*(const uint32_t *)
(fw_data + MCP_HEADER_PTR_OFFSET));
if ((hdr_offset & 3) || hdr_offset + sizeof(*hdr) > fw->datasize) {
device_printf(sc->dev, "Bad firmware file");
/* setup zlib and decompress f/w */
bzero(&zs, sizeof (zs));
zs.zalloc = z_alloc;
zs.zfree = z_free;
status = inflateInit(&zs);
if (status != Z_OK) {
status = EIO;
goto abort_with_fw;
}
hdr = (const void*)(fw_data + hdr_offset);
/* the uncompressed size is stored as the firmware version,
which would otherwise go unused */
fw_len = (size_t) fw->version;
inflate_buffer = malloc(fw_len, M_TEMP, M_NOWAIT);
if (inflate_buffer == NULL)
goto abort_with_zs;
zs.avail_in = fw->datasize;
zs.next_in = __DECONST(char *, fw->data);
zs.avail_out = fw_len;
zs.next_out = inflate_buffer;
status = inflate(&zs, Z_FINISH);
if (status != Z_STREAM_END) {
device_printf(sc->dev, "zlib %d\n", status);
status = EIO;
goto abort_with_buffer;
}
/* check id */
hdr_offset = htobe32(*(const uint32_t *)
(inflate_buffer + MCP_HEADER_PTR_OFFSET));
if ((hdr_offset & 3) || hdr_offset + sizeof(*hdr) > fw_len) {
device_printf(sc->dev, "Bad firmware file");
status = EIO;
goto abort_with_buffer;
}
hdr = (const void*)(inflate_buffer + hdr_offset);
status = mxge_validate_firmware(sc, hdr);
if (status != 0)
goto abort_with_fw;
goto abort_with_buffer;
hack.ro_char = fw_data;
/* Copy the inflated firmware to NIC SRAM. */
for (i = 0; i < *limit; i += 256) {
for (i = 0; i < fw_len; i += 256) {
mxge_pio_copy(sc->sram + MXGE_FW_OFFSET + i,
hack.rw_char + i,
min(256U, (unsigned)(*limit - i)));
inflate_buffer + i,
min(256U, (unsigned)(fw_len - i)));
mb();
dummy = *sc->sram;
mb();
}
*limit = fw_len;
status = 0;
abort_with_buffer:
free(inflate_buffer, M_TEMP);
abort_with_zs:
inflateEnd(&zs);
abort_with_fw:
firmware_put(fw, FIRMWARE_UNLOAD);
return status;
@ -796,6 +850,9 @@ mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data)
case MXGEFW_CMD_ERROR_UNALIGNED:
err = E2BIG;
break;
case MXGEFW_CMD_ERROR_BUSY:
err = EBUSY;
break;
default:
device_printf(sc->dev,
"mxge: command %d "
@ -1221,6 +1278,53 @@ mxge_change_flow_control(SYSCTL_HANDLER_ARGS)
return err;
}
static int
mxge_change_lro_locked(mxge_softc_t *sc, int lro_cnt)
{
struct ifnet *ifp;
int err = 0;
ifp = sc->ifp;
if (lro_cnt == 0)
ifp->if_capenable &= ~IFCAP_LRO;
else
ifp->if_capenable |= IFCAP_LRO;
sc->lro_cnt = lro_cnt;
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
callout_stop(&sc->co_hdl);
mxge_close(sc);
err = mxge_open(sc);
if (err == 0)
callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc);
}
return err;
}
static int
mxge_change_lro(SYSCTL_HANDLER_ARGS)
{
mxge_softc_t *sc;
unsigned int lro_cnt;
int err;
sc = arg1;
lro_cnt = sc->lro_cnt;
err = sysctl_handle_int(oidp, &lro_cnt, arg2, req);
if (err != 0)
return err;
if (lro_cnt == sc->lro_cnt)
return 0;
if (lro_cnt > 128)
return EINVAL;
mtx_lock(&sc->driver_mtx);
err = mxge_change_lro_locked(sc, lro_cnt);
mtx_unlock(&sc->driver_mtx);
return err;
}
static int
mxge_handle_be32(SYSCTL_HANDLER_ARGS)
{
@ -1419,9 +1523,11 @@ mxge_add_sysctls(mxge_softc_t *sc)
0, "verbose printing");
/* lro */
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
"lro_cnt", CTLFLAG_RD, &sc->lro_cnt,
0, "number of lro merge queues");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
"lro_cnt",
CTLTYPE_INT|CTLFLAG_RW, sc,
0, mxge_change_lro,
"I", "number of lro merge queues");
SYSCTL_ADD_INT(ctx, children, OID_AUTO,
"lro_flushed", CTLFLAG_RD, &sc->lro_flushed,
@ -1853,9 +1959,10 @@ mxge_vlan_tag_remove(struct mbuf *m, uint32_t *csum)
/* restore checksum to network byte order;
later consumers expect this */
*csum = htons(*csum);
/* save the tag */
mtag = m_tag_alloc(MTAG_VLAN, MTAG_VLAN_TAG, sizeof(u_int),
M_NOWAIT);
M_NOWAIT);
if (mtag == NULL)
return;
m->m_flags |= M_VLANTAG;
@ -2013,7 +2120,7 @@ mxge_clean_rx_done(mxge_softc_t *sc)
rx_done->idx = rx_done->cnt & rx_done->mask;
/* limit potential for livelock */
if (__predict_false(++limit > 2 * rx_done->mask))
if (__predict_false(++limit > rx_done->mask / 2))
break;
}
while(!SLIST_EMPTY(&sc->lro_active)) {
@ -2031,9 +2138,8 @@ mxge_tx_done(mxge_softc_t *sc, uint32_t mcp_idx)
mxge_tx_buf_t *tx;
struct mbuf *m;
bus_dmamap_t map;
int idx, limit;
int idx;
limit = 0;
tx = &sc->tx;
ifp = sc->ifp;
while (tx->pkt_done != mcp_idx) {
@ -2053,10 +2159,6 @@ mxge_tx_done(mxge_softc_t *sc, uint32_t mcp_idx)
tx->info[idx].flag = 0;
tx->pkt_done++;
}
/* limit potential for livelock by only handling
2 full tx rings per call */
if (__predict_false(++limit > 2 * tx->mask))
break;
}
/* If we have space, clear IFF_OACTIVE to tell the stack that
@ -2072,6 +2174,142 @@ mxge_tx_done(mxge_softc_t *sc, uint32_t mcp_idx)
}
}
static struct mxge_media_type mxge_media_types[] =
{
{IFM_10G_CX4, 0x7f, "10GBASE-CX4 (module)"},
{IFM_10G_SR, (1 << 7), "10GBASE-SR"},
{IFM_10G_LR, (1 << 6), "10GBASE-LR"},
{0, (1 << 5), "10GBASE-ER"},
{0, (1 << 4), "10GBASE-LRM"},
{0, (1 << 3), "10GBASE-SW"},
{0, (1 << 2), "10GBASE-LW"},
{0, (1 << 1), "10GBASE-EW"},
{0, (1 << 0), "Reserved"}
};
static void
mxge_set_media(mxge_softc_t *sc, int type)
{
sc->media_flags |= type;
ifmedia_add(&sc->media, sc->media_flags, 0, NULL);
ifmedia_set(&sc->media, sc->media_flags);
}
/*
* Determine the media type for a NIC. Some XFPs will identify
* themselves only when their link is up, so this is initiated via a
* link up interrupt. However, this can potentially take up to
* several milliseconds, so it is run via the watchdog routine, rather
* than in the interrupt handler itself. This need only be done
* once, not each time the link is up.
*/
static void
mxge_media_probe(mxge_softc_t *sc)
{
mxge_cmd_t cmd;
char *ptr;
int i, err, ms;
sc->need_media_probe = 0;
/* if we've already set a media type, we're done */
if (sc->media_flags != (IFM_ETHER | IFM_AUTO))
return;
/*
* parse the product code to deterimine the interface type
* (CX4, XFP, Quad Ribbon Fiber) by looking at the character
* after the 3rd dash in the driver's cached copy of the
* EEPROM's product code string.
*/
ptr = sc->product_code_string;
if (ptr == NULL) {
device_printf(sc->dev, "Missing product code\n");
}
for (i = 0; i < 3; i++, ptr++) {
ptr = index(ptr, '-');
if (ptr == NULL) {
device_printf(sc->dev,
"only %d dashes in PC?!?\n", i);
return;
}
}
if (*ptr == 'C') {
mxge_set_media(sc, IFM_10G_CX4);
return;
}
else if (*ptr == 'Q') {
device_printf(sc->dev, "Quad Ribbon Fiber Media\n");
/* FreeBSD has no media type for Quad ribbon fiber */
return;
}
if (*ptr != 'R') {
device_printf(sc->dev, "Unknown media type: %c\n", *ptr);
return;
}
/*
* At this point we know the NIC has an XFP cage, so now we
* try to determine what is in the cage by using the
* firmware's XFP I2C commands to read the XFP 10GbE compilance
* register. We read just one byte, which may take over
* a millisecond
*/
cmd.data0 = 0; /* just fetch 1 byte, not all 256 */
cmd.data1 = MXGE_XFP_COMPLIANCE_BYTE; /* the byte we want */
err = mxge_send_cmd(sc, MXGEFW_CMD_XFP_I2C_READ, &cmd);
if (err == MXGEFW_CMD_ERROR_XFP_FAILURE) {
device_printf(sc->dev, "failed to read XFP\n");
}
if (err == MXGEFW_CMD_ERROR_XFP_ABSENT) {
device_printf(sc->dev, "Type R with no XFP!?!?\n");
}
if (err != MXGEFW_CMD_OK) {
return;
}
/* now we wait for the data to be cached */
cmd.data0 = MXGE_XFP_COMPLIANCE_BYTE;
err = mxge_send_cmd(sc, MXGEFW_CMD_XFP_BYTE, &cmd);
for (ms = 0; (err == EBUSY) && (ms < 50); ms++) {
DELAY(1000);
cmd.data0 = MXGE_XFP_COMPLIANCE_BYTE;
err = mxge_send_cmd(sc, MXGEFW_CMD_XFP_BYTE, &cmd);
}
if (err != MXGEFW_CMD_OK) {
device_printf(sc->dev, "failed to read XFP (%d, %dms)\n",
err, ms);
return;
}
if (cmd.data0 == mxge_media_types[0].bitmask) {
if (mxge_verbose)
device_printf(sc->dev, "XFP:%s\n",
mxge_media_types[0].name);
mxge_set_media(sc, IFM_10G_CX4);
return;
}
for (i = 1;
i < sizeof (mxge_media_types) / sizeof (mxge_media_types[0]);
i++) {
if (cmd.data0 & mxge_media_types[i].bitmask) {
if (mxge_verbose)
device_printf(sc->dev, "XFP:%s\n",
mxge_media_types[i].name);
mxge_set_media(sc, mxge_media_types[i].flag);
return;
}
}
device_printf(sc->dev, "XFP media 0x%x unknown\n", cmd.data0);
return;
}
static void
mxge_intr(void *arg)
{
@ -2123,6 +2361,7 @@ mxge_intr(void *arg)
if (mxge_verbose)
device_printf(sc->dev, "link down\n");
}
sc->need_media_probe = 1;
}
if (sc->rdma_tags_available !=
be32toh(sc->fw_stats->rdma_tags_available)) {
@ -2131,7 +2370,12 @@ mxge_intr(void *arg)
device_printf(sc->dev, "RDMA timed out! %d tags "
"left\n", sc->rdma_tags_available);
}
sc->down_cnt += stats->link_down;
if (stats->link_down) {
sc->down_cnt += stats->link_down;
sc->link_state = 0;
if_link_state_change(sc->ifp, LINK_STATE_DOWN);
}
}
/* check to see if we have rx token to pass back */
@ -2749,16 +2993,27 @@ static void
mxge_watchdog(mxge_softc_t *sc)
{
mxge_tx_buf_t *tx = &sc->tx;
uint32_t rx_pause = be32toh(sc->fw_stats->dropped_pause);
/* see if we have outstanding transmits, which
have been pending for more than mxge_ticks */
if (tx->req != tx->done &&
tx->watchdog_req != tx->watchdog_done &&
tx->done == tx->watchdog_done)
mxge_watchdog_reset(sc);
tx->done == tx->watchdog_done) {
/* check for pause blocking before resetting */
if (tx->watchdog_rx_pause == rx_pause)
mxge_watchdog_reset(sc);
else
device_printf(sc->dev, "Flow control blocking "
"xmits, check link partner\n");
}
tx->watchdog_req = tx->req;
tx->watchdog_done = tx->done;
tx->watchdog_rx_pause = rx_pause;
if (sc->need_media_probe)
mxge_media_probe(sc);
}
static void
@ -2822,9 +3077,9 @@ mxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
if (sc == NULL)
return;
ifmr->ifm_status = IFM_AVALID;
ifmr->ifm_status |= sc->fw_stats->link_up ? IFM_ACTIVE : 0;
ifmr->ifm_status |= sc->link_state ? IFM_ACTIVE : 0;
ifmr->ifm_active = IFM_AUTO | IFM_ETHER;
ifmr->ifm_active |= sc->fw_stats->link_up ? IFM_FDX : 0;
ifmr->ifm_active |= sc->link_state ? IFM_FDX : 0;
}
static int
@ -2880,8 +3135,9 @@ mxge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
mask = ifr->ifr_reqcap ^ ifp->if_capenable;
if (mask & IFCAP_TXCSUM) {
if (IFCAP_TXCSUM & ifp->if_capenable) {
ifp->if_capenable &= ~(IFCAP_TXCSUM);
ifp->if_hwassist &= ~(CSUM_TCP | CSUM_UDP);
ifp->if_capenable &= ~(IFCAP_TXCSUM|IFCAP_TSO4);
ifp->if_hwassist &= ~(CSUM_TCP | CSUM_UDP
| CSUM_TSO);
} else {
ifp->if_capenable |= IFCAP_TXCSUM;
ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP);
@ -2928,6 +3184,8 @@ mxge_fetch_tunables(mxge_softc_t *sc)
&mxge_verbose);
TUNABLE_INT_FETCH("hw.mxge.ticks", &mxge_ticks);
TUNABLE_INT_FETCH("hw.mxge.lro_cnt", &sc->lro_cnt);
if (sc->lro_cnt != 0)
mxge_lro_cnt = sc->lro_cnt;
if (bootverbose)
mxge_verbose = 1;
@ -3093,23 +3351,26 @@ mxge_attach(device_t dev)
device_printf(dev, "MTU limited to %d. Install "
"latest firmware for 9000 byte jumbo support\n",
sc->max_mtu - ETHER_HDR_LEN);
ifp->if_hwassist = CSUM_TCP | CSUM_UDP;
ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_TSO;
ifp->if_capenable = ifp->if_capabilities;
if (sc->lro_cnt == 0)
ifp->if_capenable &= ~IFCAP_LRO;
sc->csum_flag = 1;
ifp->if_init = mxge_init;
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = mxge_ioctl;
ifp->if_start = mxge_start;
/* Initialise the ifmedia structure */
ifmedia_init(&sc->media, 0, mxge_media_change,
mxge_media_status);
mxge_set_media(sc, IFM_ETHER | IFM_AUTO);
mxge_media_probe(sc);
ether_ifattach(ifp, sc->mac_addr);
/* ether_ifattach sets mtu to 1500 */
if (ifp->if_capabilities & IFCAP_JUMBO_MTU)
ifp->if_mtu = 9000;
/* Initialise the ifmedia structure */
ifmedia_init(&sc->media, 0, mxge_media_change,
mxge_media_status);
ifmedia_add(&sc->media, IFM_ETHER|IFM_AUTO, 0, NULL);
mxge_add_sysctls(sc);
return 0;
@ -3164,7 +3425,6 @@ mxge_detach(device_t dev)
pci_release_msi(dev);
sc->rx_done.entry = NULL;
mxge_dma_free(&sc->rx_done.dma);
mxge_dma_free(&sc->fw_stats_dma);
mxge_dma_free(&sc->dmabench_dma);
mxge_dma_free(&sc->zeropad_dma);

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2006, Myricom Inc.
Copyright (c) 2006-2007, Myricom Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -9,11 +9,7 @@ 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. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Myricom Inc, nor the names of its
2. Neither the name of the Myricom Inc, nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
@ -109,6 +105,7 @@ typedef struct
int wake; /* #times irq re-enabled xmit */
int watchdog_req; /* cache of req */
int watchdog_done; /* cache of done */
int watchdog_rx_pause; /* cache of pause rq recvd */
} mxge_tx_buf_t;
struct lro_entry;
@ -194,6 +191,8 @@ typedef struct {
int link_width;
int max_mtu;
int tx_defrag;
int media_flags;
int need_media_probe;
mxge_dma_t dmabench_dma;
struct callout co_hdl;
char *mac_addr_string;
@ -208,11 +207,19 @@ typedef struct {
#define MXGE_PCI_VENDOR_MYRICOM 0x14c1
#define MXGE_PCI_DEVICE_Z8E 0x0008
#define MXGE_PCI_DEVICE_Z8E_9 0x0009
#define MXGE_XFP_COMPLIANCE_BYTE 131
#define MXGE_HIGHPART_TO_U32(X) \
(sizeof (X) == 8) ? ((uint32_t)((uint64_t)(X) >> 32)) : (0)
#define MXGE_LOWPART_TO_U32(X) ((uint32_t)(X))
struct mxge_media_type
{
int flag;
uint8_t bitmask;
char *name;
};
/* implement our own memory barriers, since bus_space_barrier
cannot handle write-combining regions */
@ -250,9 +257,22 @@ mxge_pio_copy(volatile void *to_v, void *from_v, size_t size)
void mxge_lro_flush(mxge_softc_t *mgp, struct lro_entry *lro);
int mxge_lro_rx(mxge_softc_t *mgp, struct mbuf *m_head, uint32_t csum);
#ifndef IFCAP_LRO
#define IFCAP_LRO 0
#endif
#ifndef IFCAP_TSO
#define IFCAP_TSO 0
#endif
#ifndef IFCAP_TSO4
#define IFCAP_TSO4 0
#endif
#ifndef CSUM_TSO
#define CSUM_TSO 0
#endif
/*
This file uses Myri10GE driver indentation.

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2006, Myricom Inc.
Copyright (c) 2006-2007, Myricom Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -9,11 +9,7 @@ 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. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Myricom Inc, nor the names of its
2. Neither the name of the Myricom Inc, nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

View File

@ -9,11 +9,7 @@ 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. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Myricom Inc, nor the names of its
2. Neither the name of the Myricom Inc, nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
@ -244,7 +240,7 @@ mxge_lro_rx(mxge_softc_t *mgp, struct mbuf *m_head, uint32_t csum)
return -1;
}
if (lro->timestamp) {
if (opt_bytes) {
uint32_t tsval = ntohl(*(ts_ptr + 1));
/* make sure timestamp values are increasing */
if (__predict_false(lro->tsval > tsval ||

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright (c) 2006, Myricom Inc.
Copyright (c) 2006-2007, Myricom Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -9,11 +9,7 @@ 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. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Myricom Inc, nor the names of its
2. Neither the name of the Myricom Inc, nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
@ -56,13 +52,27 @@ struct mcp_dma_addr {
};
typedef struct mcp_dma_addr mcp_dma_addr_t;
/* 4 Bytes */
/* 4 Bytes. 8 Bytes for NDIS drivers. */
struct mcp_slot {
#ifdef MXGEFW_NDIS
/* Place at the top so it gets written before length.
* The driver polls length.
*/
uint32_t hash;
#endif
uint16_t checksum;
uint16_t length;
};
typedef struct mcp_slot mcp_slot_t;
#ifdef MXGEFW_NDIS
/* Two bits of length in mcp_slot are used to indicate hash type. */
#define MXGEFW_RSS_HASH_NULL (0 << 14) /* bit 15:14 = 00 */
#define MXGEFW_RSS_HASH_IPV4 (1 << 14) /* bit 15:14 = 01 */
#define MXGEFW_RSS_HASH_TCP_IPV4 (2 << 14) /* bit 15:14 = 10 */
#define MXGEFW_RSS_HASH_MASK (3 << 14) /* bit 15:14 = 11 */
#endif
/* 64 Bytes */
struct mcp_cmd {
uint32_t cmd;
@ -265,7 +275,7 @@ enum myri10ge_mcp_cmd_type {
MXGEFW_CMD_UNALIGNED_STATUS,
/* return data = boolean, true if the chipset is known to be unaligned */
MXGEFW_CMD_ALWAYS_USE_N_BIG_BUFFERS,
/* data0 = number of big buffers to use. It must be 0 or a power of 2.
* 0 indicates that the NIC consumes as many buffers as they are required
@ -275,6 +285,70 @@ enum myri10ge_mcp_cmd_type {
* It is up to the driver to ensure that this value is big enough for
* the NIC to be able to receive maximum-sized packets.
*/
MXGEFW_CMD_GET_MAX_RSS_QUEUES,
MXGEFW_CMD_ENABLE_RSS_QUEUES,
/* data0 = number of slices n (0, 1, ..., n-1) to enable
* data1 = interrupt mode. 0=share one INTx/MSI, 1=use one MSI-X per queue.
* If all queues share one interrupt, the driver must have set
* RSS_SHARED_INTERRUPT_DMA before enabling queues.
*/
MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET,
MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA,
/* data0, data1 = bus address lsw, msw */
MXGEFW_CMD_GET_RSS_TABLE_OFFSET,
/* get the offset of the indirection table */
MXGEFW_CMD_SET_RSS_TABLE_SIZE,
/* set the size of the indirection table */
MXGEFW_CMD_GET_RSS_KEY_OFFSET,
/* get the offset of the secret key */
MXGEFW_CMD_RSS_KEY_UPDATED,
/* tell nic that the secret key's been updated */
MXGEFW_CMD_SET_RSS_ENABLE,
/* data0 = enable/disable rss
* 0: disable rss. nic does not distribute receive packets.
* 1: enable rss. nic distributes receive packets among queues.
* data1 = hash type
* 1: IPV4
* 2: TCP_IPV4
* 3: IPV4 | TCP_IPV4
*/
MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
/* Return data = the max. size of the entire headers of a IPv6 TSO packet.
* If the header size of a IPv6 TSO packet is larger than the specified
* value, then the driver must not use TSO.
* This size restriction only applies to IPv6 TSO.
* For IPv4 TSO, the maximum size of the headers is fixed, and the NIC
* always has enough header buffer to store maximum-sized headers.
*/
MXGEFW_CMD_SET_TSO_MODE,
/* data0 = TSO mode.
* 0: Linux/FreeBSD style (NIC default)
* 1: NDIS/NetBSD style
*/
MXGEFW_CMD_MDIO_READ,
/* data0 = dev_addr (PMA/PMD or PCS ...), data1 = register/addr */
MXGEFW_CMD_MDIO_WRITE,
/* data0 = dev_addr, data1 = register/addr, data2 = value */
MXGEFW_CMD_XFP_I2C_READ,
/* Starts to get a fresh copy of one byte or of the whole xfp i2c table, the
* obtained data is cached inside the xaui-xfi chip :
* data0 : "all" flag : 0 => get one byte, 1=> get 256 bytes,
* data1 : if (data0 == 0): index of byte to refresh [ not used otherwise ]
* The operation might take ~1ms for a single byte or ~65ms when refreshing all 256 bytes
* During the i2c operation, MXGEFW_CMD_XFP_I2C_READ or MXGEFW_CMD_XFP_BYTE attempts
* will return MXGEFW_CMD_ERROR_BUSY
*/
MXGEFW_CMD_XFP_BYTE
/* Return the last obtained copy of a given byte in the xfp i2c table
* (copy cached during the last relevant MXGEFW_CMD_XFP_I2C_READ)
* data0 : index of the desired table entry
* Return data = the byte stored at the requested index in the table
*/
};
typedef enum myri10ge_mcp_cmd_type myri10ge_mcp_cmd_type_t;
@ -290,7 +364,10 @@ enum myri10ge_mcp_cmd_status {
MXGEFW_CMD_ERROR_BAD_PORT,
MXGEFW_CMD_ERROR_RESOURCES,
MXGEFW_CMD_ERROR_MULTICAST,
MXGEFW_CMD_ERROR_UNALIGNED
MXGEFW_CMD_ERROR_UNALIGNED,
MXGEFW_CMD_ERROR_NO_MDIO,
MXGEFW_CMD_ERROR_XFP_FAILURE,
MXGEFW_CMD_ERROR_XFP_ABSENT
};
typedef enum myri10ge_mcp_cmd_status myri10ge_mcp_cmd_status_t;
@ -328,5 +405,12 @@ struct mcp_irq_data {
};
typedef struct mcp_irq_data mcp_irq_data_t;
#ifdef MXGEFW_NDIS
struct mcp_rss_shared_interrupt {
uint8_t pad[2];
uint8_t queue;
uint8_t valid;
};
#endif
#endif /* _myri10ge_mcp_h */

View File

@ -521,6 +521,7 @@ hint.mse.0.irq="5"
# Intel EtherExpress
# lnc: Lance/PCnet cards (Isolan, Novell NE2100, NE32-VL, AMD Am7990 and
# Am79C960)
# mxge: Myricom Myri-10G 10GbE NIC
# nve: nVidia nForce MCP on-board Ethernet Networking
# oltr: Olicom ISA token-ring adapters OC-3115, OC-3117, OC-3118 and OC-3133.
# Olicom PCI token-ring adapters OC-3136, OC-3137, OC-3139, OC-3140,
@ -576,6 +577,7 @@ hint.lnc.0.at="isa"
hint.lnc.0.port="0x280"
hint.lnc.0.irq="10"
hint.lnc.0.drq="0"
device mxge # Myricom Myri-10G 10GbE NIC
device nve # nVidia nForce MCP on-board Ethernet Networking
device sbni
hint.sbni.0.at="isa"

View File

@ -1,13 +1,7 @@
# $FreeBSD$
MXGE= ${.CURDIR}/../../../dev/mxge
.PATH= ${MXGE}
.PATH: ${.CURDIR}/../../../dev/mxge
KMOD= mxge_eth_z8e
FIRMWS= eth_z8e.dat:mxge_eth_z8e
CLEANFILES+= eth_z8e.dat
eth_z8e.dat: ${MXGE}/eth_z8e.dat.gz.uu
uudecode -p < ${MXGE}/eth_z8e.dat.gz.uu \
| gzip -dc > ${.TARGET}
SRCS= mxge_eth_z8e.c
.include <bsd.kmod.mk>

View File

@ -1,13 +1,7 @@
# $FreeBSD$
MXGE= ${.CURDIR}/../../../dev/mxge
.PATH= ${MXGE}
.PATH: ${.CURDIR}/../../../dev/mxge
KMOD= mxge_ethp_z8e
FIRMWS= ethp_z8e.dat:mxge_ethp_z8e
CLEANFILES+= ethp_z8e.dat
ethp_z8e.dat: ${MXGE}/ethp_z8e.dat.gz.uu
uudecode -p < ${MXGE}/ethp_z8e.dat.gz.uu \
| gzip -dc > ${.TARGET}
SRCS= mxge_ethp_z8e.c
.include <bsd.kmod.mk>