* Updated the FreeBSD compatibility layer for network drivers to FreeBSD 7

(RELENG_7_BP).
* There are many white spots, though, most notable PCI MSI(-X) support, and
  jumbo frames.
* Fixed removing interrupts for the INTR_FAST case. Since FreeBSD 7 added
  a new interrupt "filter" mechanism, we can finally report if the interface
  was handled by a device or not (though only very few devices support this
  yet).
* Updated the 3com, rtl8139, e1000, and via_rhine drivers to the latest code
  base. They all compile, but I haven't tested them after the changes yet!


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22991 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2007-11-25 11:29:29 +00:00
parent 3721f6df39
commit 239239c8a0
67 changed files with 25297 additions and 14505 deletions

View File

@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/pci/if_xl.c,v 1.190.2.10 2006/08/17 00:13:07 yongari Exp $");
__FBSDID("$FreeBSD: src/sys/pci/if_xl.c,v 1.210 2007/08/06 14:26:03 rwatson Exp $");
/*
* 3Com 3c90x Etherlink XL PCI NIC driver
@ -245,7 +245,7 @@ static int xl_ioctl(struct ifnet *, u_long, caddr_t);
static void xl_init(void *);
static void xl_init_locked(struct xl_softc *);
static void xl_stop(struct xl_softc *);
static void xl_watchdog(struct ifnet *);
static int xl_watchdog(struct xl_softc *);
static void xl_shutdown(device_t);
static int xl_suspend(device_t);
static int xl_resume(device_t);
@ -391,7 +391,7 @@ xl_wait(struct xl_softc *sc)
}
if (i == XL_TIMEOUT)
if_printf(sc->xl_ifp, "command never completed!\n");
device_printf(sc->xl_dev, "command never completed!\n");
}
/*
@ -656,8 +656,7 @@ xl_miibus_mediainit(device_t dev)
if (sc->xl_type == XL_TYPE_905B &&
sc->xl_media == XL_MEDIAOPT_10FL) {
if (bootverbose)
if_printf(sc->xl_ifp,
"found 10baseFL\n");
device_printf(sc->xl_dev, "found 10baseFL\n");
ifmedia_add(ifm, IFM_ETHER | IFM_10_FL, 0, NULL);
ifmedia_add(ifm, IFM_ETHER | IFM_10_FL|IFM_HDX, 0,
NULL);
@ -666,14 +665,14 @@ xl_miibus_mediainit(device_t dev)
IFM_ETHER | IFM_10_FL | IFM_FDX, 0, NULL);
} else {
if (bootverbose)
if_printf(sc->xl_ifp, "found AUI\n");
device_printf(sc->xl_dev, "found AUI\n");
ifmedia_add(ifm, IFM_ETHER | IFM_10_5, 0, NULL);
}
}
if (sc->xl_media & XL_MEDIAOPT_BNC) {
if (bootverbose)
if_printf(sc->xl_ifp, "found BNC\n");
device_printf(sc->xl_dev, "found BNC\n");
ifmedia_add(ifm, IFM_ETHER | IFM_10_2, 0, NULL);
}
}
@ -695,7 +694,7 @@ xl_eeprom_wait(struct xl_softc *sc)
}
if (i == 100) {
if_printf(sc->xl_ifp, "eeprom failed to come ready\n");
device_printf(sc->xl_dev, "eeprom failed to come ready\n");
return (1);
}
@ -857,9 +856,9 @@ xl_testpacket(struct xl_softc *sc)
if (m == NULL)
return;
bcopy(&IFP2ENADDR(sc->xl_ifp),
bcopy(IF_LLADDR(sc->xl_ifp),
mtod(m, struct ether_header *)->ether_dhost, ETHER_ADDR_LEN);
bcopy(&IFP2ENADDR(sc->xl_ifp),
bcopy(IF_LLADDR(sc->xl_ifp),
mtod(m, struct ether_header *)->ether_shost, ETHER_ADDR_LEN);
mtod(m, struct ether_header *)->ether_type = htons(3);
mtod(m, unsigned char *)[14] = 0;
@ -984,7 +983,7 @@ xl_setmode(struct xl_softc *sc, int media)
DELAY(800);
XL_SEL_WIN(7);
if_printf(sc->xl_ifp, "selecting %s, %s duplex\n", pmsg, dmsg);
device_printf(sc->xl_dev, "selecting %s, %s duplex\n", pmsg, dmsg);
}
static void
@ -1016,7 +1015,7 @@ xl_reset(struct xl_softc *sc)
}
if (i == XL_TIMEOUT)
if_printf(sc->xl_ifp, "reset didn't complete\n");
device_printf(sc->xl_dev, "reset didn't complete\n");
/* Reset TX and RX. */
/* Note: the RX reset takes an absurd amount of time
@ -1099,20 +1098,20 @@ xl_mediacheck(struct xl_softc *sc)
if (sc->xl_xcvr <= XL_XCVR_AUTO)
return;
else {
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"bogus xcvr value in EEPROM (%x)\n", sc->xl_xcvr);
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"choosing new default based on card type\n");
}
} else {
if (sc->xl_type == XL_TYPE_905B &&
sc->xl_media & XL_MEDIAOPT_10FL)
return;
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"WARNING: no media options bits set in the media options register!!\n");
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"this could be a manufacturing defect in your adapter or system\n");
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"attempting to guess media type; you should probably consult your vendor\n");
}
@ -1137,7 +1136,7 @@ xl_choose_xcvr(struct xl_softc *sc, int verbose)
sc->xl_media = XL_MEDIAOPT_BT;
sc->xl_xcvr = XL_XCVR_10BT;
if (verbose)
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"guessing 10BaseT transceiver\n");
break;
case TC_DEVICEID_BOOMERANG_10BT_COMBO: /* 3c900-COMBO */
@ -1145,20 +1144,20 @@ xl_choose_xcvr(struct xl_softc *sc, int verbose)
sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
sc->xl_xcvr = XL_XCVR_10BT;
if (verbose)
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"guessing COMBO (AUI/BNC/TP)\n");
break;
case TC_DEVICEID_KRAKATOA_10BT_TPC: /* 3c900B-TPC */
sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC;
sc->xl_xcvr = XL_XCVR_10BT;
if (verbose)
if_printf(sc->xl_ifp, "guessing TPC (BNC/TP)\n");
device_printf(sc->xl_dev, "guessing TPC (BNC/TP)\n");
break;
case TC_DEVICEID_CYCLONE_10FL: /* 3c900B-FL */
sc->xl_media = XL_MEDIAOPT_10FL;
sc->xl_xcvr = XL_XCVR_AUI;
if (verbose)
if_printf(sc->xl_ifp, "guessing 10baseFL\n");
device_printf(sc->xl_dev, "guessing 10baseFL\n");
break;
case TC_DEVICEID_BOOMERANG_10_100BT: /* 3c905-TX */
case TC_DEVICEID_HURRICANE_555: /* 3c555 */
@ -1175,15 +1174,14 @@ xl_choose_xcvr(struct xl_softc *sc, int verbose)
sc->xl_media = XL_MEDIAOPT_MII;
sc->xl_xcvr = XL_XCVR_MII;
if (verbose)
if_printf(sc->xl_ifp, "guessing MII\n");
device_printf(sc->xl_dev, "guessing MII\n");
break;
case TC_DEVICEID_BOOMERANG_100BT4: /* 3c905-T4 */
case TC_DEVICEID_CYCLONE_10_100BT4: /* 3c905B-T4 */
sc->xl_media = XL_MEDIAOPT_BT4;
sc->xl_xcvr = XL_XCVR_MII;
if (verbose)
if_printf(sc->xl_ifp,
"guessing 100baseT4/MII\n");
device_printf(sc->xl_dev, "guessing 100baseT4/MII\n");
break;
case TC_DEVICEID_HURRICANE_10_100BT: /* 3c905B-TX */
case TC_DEVICEID_HURRICANE_10_100BT_SERV:/*3c980-TX */
@ -1194,18 +1192,17 @@ xl_choose_xcvr(struct xl_softc *sc, int verbose)
sc->xl_media = XL_MEDIAOPT_BTX;
sc->xl_xcvr = XL_XCVR_AUTO;
if (verbose)
if_printf(sc->xl_ifp,
"guessing 10/100 internal\n");
device_printf(sc->xl_dev, "guessing 10/100 internal\n");
break;
case TC_DEVICEID_CYCLONE_10_100_COMBO: /* 3c905B-COMBO */
sc->xl_media = XL_MEDIAOPT_BTX|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
sc->xl_xcvr = XL_XCVR_AUTO;
if (verbose)
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"guessing 10/100 plus BNC/AUI\n");
break;
default:
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"unknown device ID: %x -- defaulting to 10baseT\n", devid);
sc->xl_media = XL_MEDIAOPT_BT;
break;
@ -1228,6 +1225,8 @@ xl_attach(device_t dev)
uint16_t did;
sc = device_get_softc(dev);
sc->xl_dev = dev;
unit = device_get_unit(dev);
mtx_init(&sc->xl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
@ -1250,13 +1249,18 @@ xl_attach(device_t dev)
if (did == TC_DEVICEID_HURRICANE_556B)
sc->xl_flags |= XL_FLAG_NO_XCVR_PWR;
if (did == TC_DEVICEID_HURRICANE_575B ||
did == TC_DEVICEID_HURRICANE_575C ||
did == TC_DEVICEID_HURRICANE_656B ||
did == TC_DEVICEID_TORNADO_656C)
sc->xl_flags |= XL_FLAG_FUNCREG;
if (did == TC_DEVICEID_HURRICANE_575A ||
did == TC_DEVICEID_HURRICANE_575B ||
did == TC_DEVICEID_HURRICANE_575C ||
did == TC_DEVICEID_HURRICANE_656B ||
did == TC_DEVICEID_TORNADO_656C)
sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_8BITROM;
sc->xl_flags |= XL_FLAG_PHYOK | XL_FLAG_EEPROM_OFFSET_30 |
XL_FLAG_8BITROM;
if (did == TC_DEVICEID_HURRICANE_656)
sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK;
if (did == TC_DEVICEID_HURRICANE_575B)
@ -1322,7 +1326,7 @@ xl_attach(device_t dev)
RF_ACTIVE);
if (sc->xl_fres == NULL) {
device_printf(dev, "couldn't map ports/memory\n");
device_printf(dev, "couldn't map funcreg memory\n");
error = ENXIO;
goto fail;
}
@ -1376,7 +1380,7 @@ xl_attach(device_t dev)
* All of our lists are allocated as a contiguous block
* of memory.
*/
error = bus_dma_tag_create(NULL, 8, 0,
error = bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
XL_RX_LIST_SZ, 1, XL_RX_LIST_SZ, 0, NULL, NULL,
&sc->xl_ldata.xl_rx_tag);
@ -1408,7 +1412,7 @@ xl_attach(device_t dev)
goto fail;
}
error = bus_dma_tag_create(NULL, 8, 0,
error = bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
XL_TX_LIST_SZ, 1, XL_TX_LIST_SZ, 0, NULL, NULL,
&sc->xl_ldata.xl_tx_tag);
@ -1443,7 +1447,7 @@ xl_attach(device_t dev)
/*
* Allocate a DMA tag for the mapping of mbufs.
*/
error = bus_dma_tag_create(NULL, 1, 0,
error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
MCLBYTES * XL_MAXFRAGS, XL_MAXFRAGS, MCLBYTES, 0, NULL,
NULL, &sc->xl_mtag);
@ -1477,7 +1481,6 @@ xl_attach(device_t dev)
/* Set the TX start threshold for best performance. */
sc->xl_tx_thresh = XL_MIN_FRAMELEN;
ifp->if_mtu = ETHERMTU;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = xl_ioctl;
ifp->if_capabilities = IFCAP_VLAN_MTU;
@ -1494,7 +1497,6 @@ xl_attach(device_t dev)
ifp->if_capabilities |= IFCAP_POLLING;
#endif
ifp->if_start = xl_start;
ifp->if_watchdog = xl_watchdog;
ifp->if_init = xl_init;
IFQ_SET_MAXLEN(&ifp->if_snd, XL_TX_LIST_CNT - 1);
ifp->if_snd.ifq_drv_maxlen = XL_TX_LIST_CNT - 1;
@ -1604,7 +1606,7 @@ done:
ether_ifattach(ifp, eaddr);
error = bus_setup_intr(dev, sc->xl_irq, INTR_TYPE_NET | INTR_MPSAFE,
xl_intr, sc, &sc->xl_intrhand);
NULL, xl_intr, sc, &sc->xl_intrhand);
if (error) {
device_printf(dev, "couldn't set up irq\n");
ether_ifdetach(ifp);
@ -1658,7 +1660,7 @@ xl_choose_media(struct xl_softc *sc, int *media)
*media = IFM_ETHER|IFM_100_FX;
break;
default:
if_printf(sc->xl_ifp, "unknown XCVR type: %d\n",
device_printf(sc->xl_dev, "unknown XCVR type: %d\n",
sc->xl_xcvr);
/*
* This will probably be wrong, but it prevents
@ -1713,8 +1715,6 @@ xl_detach(device_t dev)
callout_drain(&sc->xl_stat_callout);
ether_ifdetach(ifp);
}
if (ifp)
if_free(ifp);
if (sc->xl_miibus)
device_delete_child(dev, sc->xl_miibus);
bus_generic_detach(dev);
@ -1730,6 +1730,9 @@ xl_detach(device_t dev)
if (sc->xl_res)
bus_release_resource(dev, res, rid, sc->xl_res);
if (ifp)
if_free(ifp);
if (sc->xl_mtag) {
bus_dmamap_destroy(sc->xl_mtag, sc->xl_tmpmap);
bus_dma_tag_destroy(sc->xl_mtag);
@ -1905,7 +1908,7 @@ xl_newbuf(struct xl_softc *sc, struct xl_chain_onefrag *c)
xl_dma_map_rxbuf, &baddr, BUS_DMA_NOWAIT);
if (error) {
m_freem(m_new);
if_printf(sc->xl_ifp, "can't map mbuf (error %d)\n",
device_printf(sc->xl_dev, "can't map mbuf (error %d)\n",
error);
return (error);
}
@ -2004,7 +2007,7 @@ again:
* If not, something truly strange has happened.
*/
if (!(rxstat & XL_RXSTAT_UP_CMPLT)) {
if_printf(ifp,
device_printf(sc->xl_dev,
"bad receive status -- packet dropped\n");
ifp->if_ierrors++;
cur_rx->xl_ptr->xl_status = 0;
@ -2099,12 +2102,10 @@ xl_rxeof_task(void *arg, int pending)
{
struct xl_softc *sc = (struct xl_softc *)arg;
NET_LOCK_GIANT();
XL_LOCK(sc);
if (sc->xl_ifp->if_drv_flags & IFF_DRV_RUNNING)
xl_rxeof(sc);
XL_UNLOCK(sc);
NET_UNLOCK_GIANT();
}
/*
@ -2148,8 +2149,7 @@ xl_txeof(struct xl_softc *sc)
if (sc->xl_cdata.xl_tx_head == NULL) {
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
/* Clear the timeout timer. */
ifp->if_timer = 0;
sc->xl_wdog_timer = 0;
sc->xl_cdata.xl_tx_tail = NULL;
} else {
if (CSR_READ_4(sc, XL_DMACTL) & XL_DMACTL_DOWN_STALLED ||
@ -2196,7 +2196,7 @@ xl_txeof_90xB(struct xl_softc *sc)
}
if (sc->xl_cdata.xl_tx_cnt == 0)
ifp->if_timer = 0;
sc->xl_wdog_timer = 0;
sc->xl_cdata.xl_tx_cons = idx;
if (cur_tx != NULL)
@ -2219,7 +2219,7 @@ xl_txeoc(struct xl_softc *sc)
if (txstat & XL_TXSTATUS_UNDERRUN ||
txstat & XL_TXSTATUS_JABBER ||
txstat & XL_TXSTATUS_RECLAIM) {
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"transmission error: %x\n", txstat);
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
xl_wait(sc);
@ -2247,7 +2247,7 @@ xl_txeoc(struct xl_softc *sc)
if (txstat & XL_TXSTATUS_UNDERRUN &&
sc->xl_tx_thresh < XL_PACKET_SIZE) {
sc->xl_tx_thresh += XL_MIN_FRAMELEN;
if_printf(sc->xl_ifp,
device_printf(sc->xl_dev,
"tx underrun, increasing tx start threshold to %d bytes\n", sc->xl_tx_thresh);
}
CSR_WRITE_2(sc, XL_COMMAND,
@ -2286,17 +2286,11 @@ xl_intr(void *arg)
}
#endif
#ifndef __HAIKU__
while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS &&
status != 0xFFFF) {
CSR_WRITE_2(sc, XL_COMMAND,
XL_CMD_INTR_ACK|(status & XL_INTRS));
#else
status = atomic_and((int32 *)&sc->xl_intr_status, 0);
// if (status & XL_INTRS)
// dprintf("GOT %x\n", status & XL_INTRS);
if ((status & XL_INTRS) != 0 && status != 0xFFFF) {
#endif
if (status & XL_STAT_UP_COMPLETE) {
int curpkts;
@ -2412,6 +2406,10 @@ xl_stats_update(void *xsc)
struct xl_softc *sc = xsc;
XL_LOCK_ASSERT(sc);
if (xl_watchdog(sc) == EJUSTRETURN)
return;
xl_stats_update_locked(sc);
}
@ -2667,7 +2665,7 @@ xl_start_locked(struct ifnet *ifp)
/*
* Set a timeout in case the chip goes out to lunch.
*/
ifp->if_timer = 5;
sc->xl_wdog_timer = 5;
/*
* XXX Under certain conditions, usually on slower machines
@ -2765,7 +2763,7 @@ xl_start_90xB_locked(struct ifnet *ifp)
/*
* Set a timeout in case the chip goes out to lunch.
*/
ifp->if_timer = 5;
sc->xl_wdog_timer = 5;
}
static void
@ -2808,7 +2806,7 @@ xl_init_locked(struct xl_softc *sc)
XL_SEL_WIN(2);
for (i = 0; i < ETHER_ADDR_LEN; i++) {
CSR_WRITE_1(sc, XL_W2_STATION_ADDR_LO + i,
IFP2ENADDR(sc->xl_ifp)[i]);
IF_LLADDR(sc->xl_ifp)[i]);
}
/* Clear the station mask. */
@ -2824,7 +2822,7 @@ xl_init_locked(struct xl_softc *sc)
/* Init circular RX list. */
error = xl_list_rx_init(sc);
if (error) {
if_printf(ifp, "initialization of the rx ring failed (%d)\n",
device_printf(sc->xl_dev, "initialization of the rx ring failed (%d)\n",
error);
xl_stop(sc);
return;
@ -2836,7 +2834,7 @@ xl_init_locked(struct xl_softc *sc)
else
error = xl_list_tx_init(sc);
if (error) {
if_printf(ifp, "initialization of the tx ring failed (%d)\n",
device_printf(sc->xl_dev, "initialization of the tx ring failed (%d)\n",
error);
xl_stop(sc);
return;
@ -3000,6 +2998,7 @@ xl_init_locked(struct xl_softc *sc)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
sc->xl_wdog_timer = 0;
callout_reset(&sc->xl_stat_callout, hz, xl_stats_update, sc);
}
@ -3232,24 +3231,25 @@ xl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
return (error);
}
/*
* XXX: Invoked from ifnet slow timer. Lock coverage needed.
*/
static void
xl_watchdog(struct ifnet *ifp)
static int
xl_watchdog(struct xl_softc *sc)
{
struct xl_softc *sc = ifp->if_softc;
struct ifnet *ifp = sc->xl_ifp;
u_int16_t status = 0;
XL_LOCK(sc);
XL_LOCK_ASSERT(sc);
if (sc->xl_wdog_timer == 0 || --sc->xl_wdog_timer != 0)
return (0);
ifp->if_oerrors++;
XL_SEL_WIN(4);
status = CSR_READ_2(sc, XL_W4_MEDIA_STATUS);
if_printf(ifp, "watchdog timeout\n");
device_printf(sc->xl_dev, "watchdog timeout\n");
if (status & XL_MEDIASTAT_CARRIER)
if_printf(ifp, "no carrier - transceiver cable problem?\n");
device_printf(sc->xl_dev,
"no carrier - transceiver cable problem?\n");
xl_txeoc(sc);
xl_txeof(sc);
@ -3264,7 +3264,7 @@ xl_watchdog(struct ifnet *ifp)
xl_start_locked(ifp);
}
XL_UNLOCK(sc);
return (EJUSTRETURN);
}
/*
@ -3279,7 +3279,7 @@ xl_stop(struct xl_softc *sc)
XL_LOCK_ASSERT(sc);
ifp->if_timer = 0;
sc->xl_wdog_timer = 0;
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISABLE);
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);

View File

@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/pci/if_xlreg.h,v 1.55.2.1 2005/08/26 14:46:22 jhb Exp $
* $FreeBSD: src/sys/pci/if_xlreg.h,v 1.59 2006/12/06 02:18:41 marius Exp $
*/
#define XL_EE_READ 0x0080 /* read, 5 bit address */
@ -581,6 +581,7 @@ struct xl_mii_frame {
struct xl_softc {
struct ifnet *xl_ifp; /* interface info */
device_t xl_dev; /* device info */
struct ifmedia ifmedia; /* media info */
bus_space_handle_t xl_bhandle;
bus_space_tag_t xl_btag;
@ -602,6 +603,7 @@ struct xl_softc {
struct xl_list_data xl_ldata;
struct xl_chain_data xl_cdata;
struct callout xl_stat_callout;
int xl_wdog_timer;
int xl_flags;
struct resource *xl_fres;
bus_space_handle_t xl_fhandle;
@ -612,7 +614,7 @@ struct xl_softc {
int rxcycles;
#endif
#ifdef __HAIKU__
u_int32_t xl_intr_status;
u_int32_t xl_intr_status;
#endif
};

View File

@ -8,8 +8,21 @@ UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : tr
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 EM_FAST_INTR=1 ] ;
KernelAddon e1000 :
e1000_80003es2lan.c
e1000_82540.c
e1000_82541.c
e1000_82542.c
e1000_82543.c
e1000_82571.c
e1000_82575.c
e1000_api.c
e1000_ich8lan.c
e1000_mac.c
e1000_manage.c
e1000_nvm.c
e1000_phy.c
if_em.c
if_em_hw.c
glue.c
: libfreebsd_network.a
;

View File

@ -1,31 +1,31 @@
$FreeBSD: src/sys/dev/em/LICENSE,v 1.3.2.1 2006/08/08 09:20:26 glebius Exp $
/*-
Copyright (c) 2001-2005, Intel Corporation
All rights reserved.
$FreeBSD: src/sys/dev/em/LICENSE,v 1.6 2007/05/04 00:00:11 jfv Exp $
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Copyright (c) 2001-2007, Intel Corporation
All rights reserved.
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
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.
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
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 Intel 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.
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.
*/

View File

@ -1,8 +1,8 @@
$FreeBSD: src/sys/dev/em/README,v 1.10.2.1 2006/08/08 09:20:26 glebius Exp $
FreeBSD* Driver for the Intel(R) PRO/1000 Family of Adapters
============================================================
$FreeBSD: src/sys/dev/em/README,v 1.15 2007/05/30 23:32:21 jfv Exp $
FreeBSD* Driver for Intel Network Connection
=============================================
May 2, 2006
May 30, 2007
Contents
@ -21,11 +21,11 @@ Contents
Overview
========
This file describes the FreeBSD* driver for the Intel(R) PRO/1000 Family of
Adapters. This driver has been developed for use with FreeBSD, Release 6.x.
This file describes the FreeBSD* driver for Intel Network Connection.
This driver has been developed for use with FreeBSD, Release 7.x.
For questions related to hardware requirements, refer to the documentation
supplied with your Intel PRO/1000 adapter. All hardware requirements listed
supplied with your Gigabit adapter. All hardware requirements listed
apply to use with FreeBSD.
@ -62,7 +62,7 @@ name of the driver tar file.
2. Untar/unzip the archive:
tar xvfz em-x.x.x.tar.gz
tar xzvf em-x.x.x.tar.gz
This will create an em-x.x.x directory.
@ -74,7 +74,7 @@ name of the driver tar file.
cd em-x.x.x
make
b. To install the compiled module in system directory:
b. To install the compiled module to the system directory:
make install
@ -84,35 +84,19 @@ name of the driver tar file.
if_em_load="YES"
4. To compile the driver into the kernel:
4. To compile the driver into the kernel, enter:
cd em-x.x.x/src
cp *.[ch] /usr/src/sys/dev/em
cp if_em* /usr/src/sys/dev/em
cp Makefile.kernel /usr/src/sys/modules/em/Makefile
Edit the /usr/src/sys/conf/files file, and add the following lines only if
they don't already exist:
dev/em/if_em.c optional em
dev/em/if_em_hw.c optional em
Remove the following lines from the /usr/src/sys/conf/files file,
if they exist:
dev/em/if_em_fxhw.c optional em
dev/em/if_em_phy.c optional em
Edit the kernel configuration file (i.e., GENERIC or MYKERNEL) in
/usr/src/sys/i386/conf, and ensure the following line is present:
Edit the kernel configuration file (i.e., GENERIC or MYKERNEL) in
/usr/src/sys/i386/conf, and ensure the following line is present:
device em
Compile and install the kernel. The system must be rebooted for the kernel
updates to take effect. For additional information on compiling the
kernel, consult the FreeBSD operating system documentation.
Compile and install the kernel. The system must be rebooted for the
kernel updates to take effect. For additional information on compiling
the kernel, consult the FreeBSD operating system documentation.
5. To assign an IP address to the interface, enter the following:
@ -150,6 +134,12 @@ configure the speed and duplex settings on the adapter. Example usage:
not specified and you are not running at gigabit speed, the driver
defaults to half-duplex.
If the interface is currently forced to 100 full duplex, in order to change
to half duplex you must use this command:
ifconfig em<interface_num> <IP_address> media 100baseTX -mediaopt
full-duplex
This driver supports the following media type options:
@ -207,13 +197,15 @@ Identifying Your Adapter section.
- Some Intel gigabit adapters that support Jumbo Frames have a frame size
limit of 9238 bytes, with a corresponding MTU size limit of 9216 bytes.
The adapters with this limitation are based on the Intel(R) 82571EB,
82572EI, 82573L and 80003ES2LAN controller. These correspond to the
following product names:
82572EI, 82573L, 82566, 82562, and 80003ES2LAN controller. These
correspond to the following product names:
Intel(R) PRO/1000 PT Server Adapter
Intel(R) PRO/1000 PT Desktop Adapter
Intel(R) PRO/1000 PT Network Connection
Intel(R) PRO/1000 PT Dual Port Server Adapter
Intel(R) PRO/1000 PT Dual Port Network Connection
Intel(R) PRO/1000 PT Quad Port Server Adapter
Intel(R) PRO/1000 PF Quad Port Server Adapter
Intel(R) PRO/1000 PF Server Adapter
Intel(R) PRO/1000 PF Network Connection
Intel(R) PRO/1000 PF Dual Port Server Adapter
@ -221,6 +213,7 @@ Identifying Your Adapter section.
Intel(R) PRO/1000 PL Network Connection
Intel(R) PRO/1000 EB Network Connection with I/O Acceleration
Intel(R) PRO/1000 EB Backplane Connection with I/O Acceleration
Intel(R) 82566DM-2 Gigabit Network Connection
- Adapters based on the Intel(R) 82542 and 82573V/E controller do not
support Jumbo Frames. These correspond to the following product names:
@ -236,7 +229,12 @@ Identifying Your Adapter section.
Intel(R) 82566DC Gigabit Network Connection
Intel(R) 82566MM Gigabit Network Connection
Intel(R) 82566MC Gigabit Network Connection
Intel(R) 82562GT 10/100 Network Connection
Intel(R) 82562G 10/100 Network Connection
Intel(R) 82566DC-2 Gigabit Network Connection
Intel(R) 82562V-2 10/100 Network Connection
Intel(R) 82562G-2 10/100 Network Connection
Intel(R) 82562GT-2 10/100 Network Connection
VLANs
-----
@ -252,18 +250,19 @@ Identifying Your Adapter section.
Example:
ifconfig vlan10 10.0.0.1 netmask 255.255.255.0 vlan10 vlandev em0
ifconfig vlan10 10.0.0.1 netmask 255.255.255.0 vlan 10 vlandev em0
In this example, all packets will be marked on egress with 802.1Q VLAN
In this example, all packets will be marked on egress with 802.1Q VLAN
tags, specifying a VLAN ID of 10.
To remove a VLAN interface:
ifconfig <vlan_name> destroy
Intel Network Connection ifconfig <vlan_name> destroy
Polling
-------
To enable polling in the driver, add the following options to the kernel
configuration, and then recompile the kernel:
@ -271,9 +270,9 @@ Identifying Your Adapter section.
options HZ=1000
At runtime use:
ifconfig em0 polling to turn polling on
Use:
ifconfig em0 -polling to turn polling off
ifconfig emX polling (to turn polling on)
and:
ifconfig emX -polling (to turn it off)
Checksum Offload
@ -306,16 +305,49 @@ Identifying Your Adapter section.
See the ifconfig man page for further information.
TSO
---
The FreeBSD driver offers support for TSO (TCP Segmentation Offload).
You can enable/disable it in two ways/places:
- sysctl net.inet.tcp.tso=0 (or 1 to enable it)
Doing this disables TSO in the stack and will affect all adapters.
- ifconfig emX -tso
Doing this will disable TSO only for this adapter.
To enable:
- ifconfig emX tso
NOTES: By default only PCI-Express adapters are ENABLED to do TSO. Others
can be enabled by the user at their own risk
TSO is not supported on 82547 and 82544-based adapters, as well as older adapters.
Known Limitations
=================
In FreeBSD version 4.x with Symmetric MultiProcessing (SMP), there is a known
issue on some newer hardware. The problem is generic kernel and only in SMP
mode. The workaround is to either use FreeBSD version 4.x in single processor
mode, or use FreeBSD 5.4 or later.
Detected Tx Unit Hang in Quad Port Adapters
-------------------------------------------
In some cases ports 3 and 4 wont pass traffic. Ports 1 and 2 don't show
any errors and will pass traffic.
This issue MAY be resolved by updating to the latest BIOS. You can
check your system's BIOS by downloading the Linux Firmware Developer Kit
that can be obtained at http://www.linuxfirmwarekit.org/
There are known performance issues with this driver when running UDP traffic
with Jumbo Frames.
----------------------------------------------------------------------------
82541/82547 can't link or is slow to link with some link partners
-----------------------------------------------------------------
There is a known compatibility issue where time to link is slow or link is not
established between 82541/82547 controllers and some switches. Known switches
@ -325,12 +357,12 @@ Known Limitations
The driver can be compiled with the following changes:
Edit ./em.x.x.x/src/if_em.h to uncomment the #define EM_MASTER_SLAVE
from within the comments. For example, change from:
Edit ./em.x.x.x/src/if_em.h to change the #define EM_MASTER_SLAVE
For example, change from:
/* #define EM_MASTER_SLAVE 2 */
#define EM_MASTER_SLAVE e1000_ms_hw_default
to:
#define EM_MASTER_SLAVE 2
#define EM_MASTER_SLAVE 2
Use one of the following options:
1 = Master mode

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,97 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_80003es2lan.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_80003ES2LAN_H_
#define _E1000_80003ES2LAN_H_
#define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00
#define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02
#define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10
#define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008
#define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800
#define E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING 0x0010
#define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004
#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000
#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000
#define DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8
#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9
/* GG82563 PHY Specific Status Register (Page 0, Register 16 */
#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Disabled */
#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060
#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI */
#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX */
#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Auto crossover */
/* PHY Specific Control Register 2 (Page 0, Register 26) */
#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000
/* 1=Reverse Auto-Negotiation */
/* MAC Specific Control Register (Page 2, Register 21) */
/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */
#define GG82563_MSCR_TX_CLK_MASK 0x0007
#define GG82563_MSCR_TX_CLK_10MBPS_2_5 0x0004
#define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005
#define GG82563_MSCR_TX_CLK_1000MBPS_2_5 0x0006
#define GG82563_MSCR_TX_CLK_1000MBPS_25 0x0007
#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */
/* DSP Distance Register (Page 5, Register 26) */
#define GG82563_DSPD_CABLE_LENGTH 0x0007 /* 0 = <50M;
1 = 50-80M;
2 = 80-110M;
3 = 110-140M;
4 = >140M */
/* Kumeran Mode Control Register (Page 193, Register 16) */
#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800
/* Max number of times Kumeran read/write should be validated */
#define GG82563_MAX_KMRN_RETRY 0x5
/* Power Management Control Register (Page 193, Register 20) */
#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001
/* 1=Enable SERDES Electrical Idle */
/* In-Band Control Register (Page 194, Register 18) */
#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */
#endif

View File

@ -0,0 +1,677 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_82540.c,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
/* e1000_82540
* e1000_82545
* e1000_82546
* e1000_82545_rev_3
* e1000_82546_rev_3
*/
#include "e1000_api.h"
void e1000_init_function_pointers_82540(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_82540(struct e1000_hw *hw);
STATIC s32 e1000_init_nvm_params_82540(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_82540(struct e1000_hw *hw);
static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw);
STATIC void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw);
STATIC s32 e1000_init_hw_82540(struct e1000_hw *hw);
STATIC s32 e1000_reset_hw_82540(struct e1000_hw *hw);
static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw);
static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw);
STATIC s32 e1000_setup_copper_link_82540(struct e1000_hw *hw);
STATIC s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw);
/**
* e1000_init_phy_params_82540 - Init PHY func ptrs.
* @hw: pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_phy_params_82540(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
phy->addr = 1;
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
phy->reset_delay_us = 10000;
phy->type = e1000_phy_m88;
/* Function Pointers */
func->check_polarity = e1000_check_polarity_m88;
func->commit_phy = e1000_phy_sw_reset_generic;
func->force_speed_duplex = e1000_phy_force_speed_duplex_m88;
func->get_cable_length = e1000_get_cable_length_m88;
func->get_cfg_done = e1000_get_cfg_done_generic;
func->read_phy_reg = e1000_read_phy_reg_m88;
func->reset_phy = e1000_phy_hw_reset_generic;
func->write_phy_reg = e1000_write_phy_reg_m88;
func->get_phy_info = e1000_get_phy_info_m88;
ret_val = e1000_get_phy_id(hw);
if (ret_val)
goto out;
/* Verify phy id */
switch (hw->mac.type) {
case e1000_82540:
case e1000_82545:
case e1000_82545_rev_3:
case e1000_82546:
case e1000_82546_rev_3:
if (phy->id == M88E1011_I_PHY_ID)
break;
/* Fall Through */
default:
ret_val = -E1000_ERR_PHY;
goto out;
break;
}
out:
return ret_val;
}
/**
* e1000_init_nvm_params_82540 - Init NVM func ptrs.
* @hw: pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_nvm_params_82540(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
struct e1000_functions *func = &hw->func;
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
DEBUGFUNC("e1000_init_nvm_params_82540");
nvm->type = e1000_nvm_eeprom_microwire;
nvm->delay_usec = 50;
nvm->opcode_bits = 3;
switch (nvm->override) {
case e1000_nvm_override_microwire_large:
nvm->address_bits = 8;
nvm->word_size = 256;
break;
case e1000_nvm_override_microwire_small:
nvm->address_bits = 6;
nvm->word_size = 64;
break;
default:
nvm->address_bits = eecd & E1000_EECD_SIZE ? 8 : 6;
nvm->word_size = eecd & E1000_EECD_SIZE ? 256 : 64;
break;
}
/* Function Pointers */
func->acquire_nvm = e1000_acquire_nvm_generic;
func->read_nvm = e1000_read_nvm_microwire;
func->release_nvm = e1000_release_nvm_generic;
func->update_nvm = e1000_update_nvm_checksum_generic;
func->valid_led_default = e1000_valid_led_default_generic;
func->validate_nvm = e1000_validate_nvm_checksum_generic;
func->write_nvm = e1000_write_nvm_microwire;
return E1000_SUCCESS;
}
/**
* e1000_init_mac_params_82540 - Init MAC func ptrs.
* @hw: pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_mac_params_82540(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_mac_params_82540");
/* Set media type */
switch (hw->device_id) {
case E1000_DEV_ID_82545EM_FIBER:
case E1000_DEV_ID_82545GM_FIBER:
case E1000_DEV_ID_82546EB_FIBER:
case E1000_DEV_ID_82546GB_FIBER:
hw->media_type = e1000_media_type_fiber;
break;
case E1000_DEV_ID_82545GM_SERDES:
case E1000_DEV_ID_82546GB_SERDES:
hw->media_type = e1000_media_type_internal_serdes;
break;
default:
hw->media_type = e1000_media_type_copper;
break;
}
/* Set mta register count */
mac->mta_reg_count = 128;
/* Set rar entry count */
mac->rar_entry_count = E1000_RAR_ENTRIES;
/* Function pointers */
/* bus type/speed/width */
func->get_bus_info = e1000_get_bus_info_pci_generic;
/* reset */
func->reset_hw = e1000_reset_hw_82540;
/* hw initialization */
func->init_hw = e1000_init_hw_82540;
/* link setup */
func->setup_link = e1000_setup_link_generic;
/* physical interface setup */
func->setup_physical_interface =
(hw->media_type == e1000_media_type_copper)
? e1000_setup_copper_link_82540
: e1000_setup_fiber_serdes_link_82540;
/* check for link */
switch (hw->media_type) {
case e1000_media_type_copper:
func->check_for_link = e1000_check_for_copper_link_generic;
break;
case e1000_media_type_fiber:
func->check_for_link = e1000_check_for_fiber_link_generic;
break;
case e1000_media_type_internal_serdes:
func->check_for_link = e1000_check_for_serdes_link_generic;
break;
default:
ret_val = -E1000_ERR_CONFIG;
goto out;
break;
}
/* link info */
func->get_link_up_info =
(hw->media_type == e1000_media_type_copper)
? e1000_get_speed_and_duplex_copper_generic
: e1000_get_speed_and_duplex_fiber_serdes_generic;
/* multicast address update */
func->mc_addr_list_update = e1000_mc_addr_list_update_generic;
/* writing VFTA */
func->write_vfta = e1000_write_vfta_generic;
/* clearing VFTA */
func->clear_vfta = e1000_clear_vfta_generic;
/* setting MTA */
func->mta_set = e1000_mta_set_generic;
/* setup LED */
func->setup_led = e1000_setup_led_generic;
/* cleanup LED */
func->cleanup_led = e1000_cleanup_led_generic;
/* turn on/off LED */
func->led_on = e1000_led_on_generic;
func->led_off = e1000_led_off_generic;
/* clear hardware counters */
func->clear_hw_cntrs = e1000_clear_hw_cntrs_82540;
out:
return ret_val;
}
/**
* e1000_init_function_pointers_82540 - Init func ptrs.
* @hw: pointer to the HW structure
*
* The only function explicitly called by the api module to initialize
* all function pointers and parameters.
**/
void
e1000_init_function_pointers_82540(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_init_function_pointers_82540");
hw->func.init_mac_params = e1000_init_mac_params_82540;
hw->func.init_nvm_params = e1000_init_nvm_params_82540;
hw->func.init_phy_params = e1000_init_phy_params_82540;
}
/**
* e1000_reset_hw_82540 - Reset hardware
* @hw: pointer to the HW structure
*
* This resets the hardware into a known state. This is a
* function pointer entry point called by the api module.
**/
STATIC s32
e1000_reset_hw_82540(struct e1000_hw *hw)
{
u32 ctrl, icr, manc;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_reset_hw_82540");
DEBUGOUT("Masking off all interrupts\n");
E1000_WRITE_REG(hw, E1000_IMC, 0xFFFFFFFF);
E1000_WRITE_REG(hw, E1000_RCTL, 0);
E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
E1000_WRITE_FLUSH(hw);
/* Delay to allow any outstanding PCI transactions to complete
* before resetting the device.
*/
msec_delay(10);
ctrl = E1000_READ_REG(hw, E1000_CTRL);
DEBUGOUT("Issuing a global reset to 82540/82545/82546 MAC\n");
switch (hw->mac.type) {
case e1000_82545_rev_3:
case e1000_82546_rev_3:
E1000_WRITE_REG(hw, E1000_CTRL_DUP, ctrl | E1000_CTRL_RST);
break;
default:
/* These controllers can't ack the 64-bit write when
* issuing the reset, so we use IO-mapping as a
* workaround to issue the reset.
*/
E1000_WRITE_REG_IO(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
break;
}
/* Wait for EEPROM reload */
msec_delay(5);
/* Disable HW ARPs on ASF enabled adapters */
manc = E1000_READ_REG(hw, E1000_MANC);
manc &= ~E1000_MANC_ARP_EN;
E1000_WRITE_REG(hw, E1000_MANC, manc);
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
icr = E1000_READ_REG(hw, E1000_ICR);
return ret_val;
}
/**
* e1000_init_hw_82540 - Initialize hardware
* @hw: pointer to the HW structure
*
* This inits the hardware readying it for operation. This is a
* function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_hw_82540(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
u32 txdctl, ctrl_ext;
s32 ret_val = E1000_SUCCESS;
u16 i;
DEBUGFUNC("e1000_init_hw_82540");
/* Initialize identification LED */
ret_val = e1000_id_led_init_generic(hw);
if (ret_val) {
DEBUGOUT("Error initializing identification LED\n");
goto out;
}
/* Disabling VLAN filtering */
DEBUGOUT("Initializing the IEEE VLAN\n");
if (mac->type < e1000_82545_rev_3) {
E1000_WRITE_REG(hw, E1000_VET, 0);
}
e1000_clear_vfta(hw);
/* Setup the receive address. */
e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
/* Zero out the Multicast HASH table */
DEBUGOUT("Zeroing the MTA\n");
for (i = 0; i < mac->mta_reg_count; i++) {
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
/* Avoid back to back register writes by adding the register
* read (flush). This is to protect against some strange
* bridge configurations that may issue Memory Write Block
* (MWB) to our register space. The *_rev_3 hardware at
* least doesn't respond correctly to every other dword in an
* MWB to our register space.
*/
E1000_WRITE_FLUSH(hw);
}
if (mac->type < e1000_82545_rev_3)
e1000_pcix_mmrbc_workaround_generic(hw);
/* Setup link and flow control */
ret_val = e1000_setup_link(hw);
txdctl = E1000_READ_REG(hw, E1000_TXDCTL);
txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) |
E1000_TXDCTL_FULL_TX_DESC_WB;
E1000_WRITE_REG(hw, E1000_TXDCTL, txdctl);
/* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there
* is no link.
*/
e1000_clear_hw_cntrs_82540(hw);
if ((hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER) ||
(hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3)) {
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
/* Relaxed ordering must be disabled to avoid a parity
* error crash in a PCI slot. */
ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
}
out:
return ret_val;
}
/**
* e1000_setup_copper_link_82540 - Configure copper link settings
* @hw: pointer to the HW structure
*
* Calls the appropriate function to configure the link for auto-neg or forced
* speed and duplex. Then we check for link, once link is established calls
* to configure collision distance and flow control are called. If link is
* not established, we return -E1000_ERR_PHY (-2). This is a function
* pointer entry point called by the api module.
**/
STATIC s32
e1000_setup_copper_link_82540(struct e1000_hw *hw)
{
u32 ctrl;
s32 ret_val = E1000_SUCCESS;
u16 data;
DEBUGFUNC("e1000_setup_copper_link_82540");
ctrl = E1000_READ_REG(hw, E1000_CTRL);
ctrl |= E1000_CTRL_SLU;
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
ret_val = e1000_set_phy_mode_82540(hw);
if (ret_val)
goto out;
if (hw->mac.type == e1000_82545_rev_3 ||
hw->mac.type == e1000_82546_rev_3) {
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &data);
if (ret_val)
goto out;
data |= 0x00000008;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, data);
if (ret_val)
goto out;
}
ret_val = e1000_copper_link_setup_m88(hw);
if (ret_val)
goto out;
ret_val = e1000_setup_copper_link_generic(hw);
out:
return ret_val;
}
/**
* e1000_setup_fiber_serdes_link_82540 - Setup link for fiber/serdes
* @hw: pointer to the HW structure
*
* Set the output amplitude to the value in the EEPROM and adjust the VCO
* speed to improve Bit Error Rate (BER) performance. Configures collision
* distance and flow control for fiber and serdes links. Upon successful
* setup, poll for link. This is a function pointer entry point called by
* the api module.
**/
STATIC s32
e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_setup_fiber_serdes_link_82540");
switch (mac->type) {
case e1000_82545_rev_3:
case e1000_82546_rev_3:
if (hw->media_type == e1000_media_type_internal_serdes) {
/* If we're on serdes media, adjust the output
* amplitude to value set in the EEPROM.
*/
ret_val = e1000_adjust_serdes_amplitude_82540(hw);
if (ret_val)
goto out;
}
/* Adjust VCO speed to improve BER performance */
ret_val = e1000_set_vco_speed_82540(hw);
if (ret_val)
goto out;
default:
break;
}
ret_val = e1000_setup_fiber_serdes_link_generic(hw);
out:
return ret_val;
}
/**
* e1000_adjust_serdes_amplitude_82540 - Adjust amplitude based on EEPROM
* @hw: pointer to the HW structure
*
* Adjust the SERDES ouput amplitude based on the EEPROM settings.
**/
static s32
e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 nvm_data;
DEBUGFUNC("e1000_adjust_serdes_amplitude_82540");
ret_val = e1000_read_nvm(hw, NVM_SERDES_AMPLITUDE, 1, &nvm_data);
if (ret_val) {
goto out;
}
if (nvm_data != NVM_RESERVED_WORD) {
/* Adjust serdes output amplitude only. */
nvm_data &= NVM_SERDES_AMPLITUDE_MASK;
ret_val = e1000_write_phy_reg(hw,
M88E1000_PHY_EXT_CTRL,
nvm_data);
if (ret_val)
goto out;
}
out:
return ret_val;
}
/**
* e1000_set_vco_speed_82540 - Set VCO speed for better performance
* @hw: pointer to the HW structure
*
* Set the VCO speed to improve Bit Error Rate (BER) performance.
**/
static s32
e1000_set_vco_speed_82540(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 default_page = 0;
u16 phy_data;
DEBUGFUNC("e1000_set_vco_speed_82540");
/* Set PHY register 30, page 5, bit 8 to 0 */
ret_val = e1000_read_phy_reg(hw,
M88E1000_PHY_PAGE_SELECT,
&default_page);
if (ret_val)
goto out;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
if (ret_val)
goto out;
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
if (ret_val)
goto out;
phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
if (ret_val)
goto out;
/* Set PHY register 30, page 4, bit 11 to 1 */
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
if (ret_val)
goto out;
ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
if (ret_val)
goto out;
phy_data |= M88E1000_PHY_VCO_REG_BIT11;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
if (ret_val)
goto out;
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
default_page);
out:
return ret_val;
}
/**
* e1000_set_phy_mode_82540 - Set PHY to class A mode
* @hw: pointer to the HW structure
*
* Sets the PHY to class A mode and assumes the following operations will
* follow to enable the new class mode:
* 1. Do a PHY soft reset.
* 2. Restart auto-negotiation or force link.
**/
static s32
e1000_set_phy_mode_82540(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS;
u16 nvm_data;
DEBUGFUNC("e1000_set_phy_mode_82540");
if (hw->mac.type != e1000_82545_rev_3)
goto out;
ret_val = e1000_read_nvm(hw, NVM_PHY_CLASS_WORD, 1, &nvm_data);
if (ret_val) {
ret_val = -E1000_ERR_PHY;
goto out;
}
if ((nvm_data != NVM_RESERVED_WORD) && (nvm_data & NVM_PHY_CLASS_A)) {
ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT,
0x000B);
if (ret_val) {
ret_val = -E1000_ERR_PHY;
goto out;
}
ret_val = e1000_write_phy_reg(hw,
M88E1000_PHY_GEN_CONTROL,
0x8104);
if (ret_val) {
ret_val = -E1000_ERR_PHY;
goto out;
}
phy->reset_disable = FALSE;
}
out:
return ret_val;
}
/**
* e1000_clear_hw_cntrs_82540 - Clear device specific hardware counters
* @hw: pointer to the HW structure
*
* Clears the hardware counters by reading the counter registers.
**/
STATIC void
e1000_clear_hw_cntrs_82540(struct e1000_hw *hw)
{
volatile u32 temp;
DEBUGFUNC("e1000_clear_hw_cntrs_82540");
e1000_clear_hw_cntrs_base_generic(hw);
temp = E1000_READ_REG(hw, E1000_PRC64);
temp = E1000_READ_REG(hw, E1000_PRC127);
temp = E1000_READ_REG(hw, E1000_PRC255);
temp = E1000_READ_REG(hw, E1000_PRC511);
temp = E1000_READ_REG(hw, E1000_PRC1023);
temp = E1000_READ_REG(hw, E1000_PRC1522);
temp = E1000_READ_REG(hw, E1000_PTC64);
temp = E1000_READ_REG(hw, E1000_PTC127);
temp = E1000_READ_REG(hw, E1000_PTC255);
temp = E1000_READ_REG(hw, E1000_PTC511);
temp = E1000_READ_REG(hw, E1000_PTC1023);
temp = E1000_READ_REG(hw, E1000_PTC1522);
temp = E1000_READ_REG(hw, E1000_ALGNERRC);
temp = E1000_READ_REG(hw, E1000_RXERRC);
temp = E1000_READ_REG(hw, E1000_TNCRS);
temp = E1000_READ_REG(hw, E1000_CEXTERR);
temp = E1000_READ_REG(hw, E1000_TSCTC);
temp = E1000_READ_REG(hw, E1000_TSCTFC);
temp = E1000_READ_REG(hw, E1000_MGTPRC);
temp = E1000_READ_REG(hw, E1000_MGTPDC);
temp = E1000_READ_REG(hw, E1000_MGTPTC);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,91 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_82541.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_82541_H_
#define _E1000_82541_H_
#define NVM_WORD_SIZE_BASE_SHIFT_82541 (NVM_WORD_SIZE_BASE_SHIFT + 1)
#define IGP01E1000_PHY_CHANNEL_NUM 4
#define IGP01E1000_PHY_AGC_A 0x1172
#define IGP01E1000_PHY_AGC_B 0x1272
#define IGP01E1000_PHY_AGC_C 0x1472
#define IGP01E1000_PHY_AGC_D 0x1872
#define IGP01E1000_PHY_AGC_PARAM_A 0x1171
#define IGP01E1000_PHY_AGC_PARAM_B 0x1271
#define IGP01E1000_PHY_AGC_PARAM_C 0x1471
#define IGP01E1000_PHY_AGC_PARAM_D 0x1871
#define IGP01E1000_PHY_EDAC_MU_INDEX 0xC000
#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000
#define IGP01E1000_PHY_DSP_RESET 0x1F33
#define IGP01E1000_PHY_DSP_FFE 0x1F35
#define IGP01E1000_PHY_DSP_FFE_CM_CP 0x0069
#define IGP01E1000_PHY_DSP_FFE_DEFAULT 0x002A
#define IGP01E1000_IEEE_FORCE_GIG 0x0140
#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
#define IGP01E1000_AGC_LENGTH_SHIFT 7
#define IGP01E1000_AGC_RANGE 10
#define FFE_IDLE_ERR_COUNT_TIMEOUT_20 20
#define FFE_IDLE_ERR_COUNT_TIMEOUT_100 100
#define IGP01E1000_ANALOG_FUSE_STATUS 0x20D0
#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x20D1
#define IGP01E1000_ANALOG_FUSE_CONTROL 0x20DC
#define IGP01E1000_ANALOG_FUSE_BYPASS 0x20DE
#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED 0x0100
#define IGP01E1000_ANALOG_FUSE_FINE_MASK 0x0F80
#define IGP01E1000_ANALOG_FUSE_COARSE_MASK 0x0070
#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH 0x0040
#define IGP01E1000_ANALOG_FUSE_COARSE_10 0x0010
#define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080
#define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500
#define IGP01E1000_ANALOG_FUSE_POLY_MASK 0xF000
#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL 0x0002
#define IGP01E1000_MSE_CHANNEL_D 0x000F
#define IGP01E1000_MSE_CHANNEL_C 0x00F0
#define IGP01E1000_MSE_CHANNEL_B 0x0F00
#define IGP01E1000_MSE_CHANNEL_A 0xF000
#endif

View File

@ -0,0 +1,558 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_82542.c,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
/* e1000_82542 (rev 1 & 2)
*/
#include "e1000_api.h"
void e1000_init_function_pointers_82542(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_82542(struct e1000_hw *hw);
STATIC s32 e1000_init_nvm_params_82542(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_82542(struct e1000_hw *hw);
STATIC s32 e1000_get_bus_info_82542(struct e1000_hw *hw);
STATIC s32 e1000_reset_hw_82542(struct e1000_hw *hw);
STATIC s32 e1000_init_hw_82542(struct e1000_hw *hw);
STATIC s32 e1000_setup_link_82542(struct e1000_hw *hw);
STATIC s32 e1000_led_on_82542(struct e1000_hw *hw);
STATIC s32 e1000_led_off_82542(struct e1000_hw *hw);
STATIC void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw);
struct e1000_dev_spec_82542 {
boolean_t dma_fairness;
};
/**
* e1000_init_phy_params_82542 - Init PHY func ptrs.
* @hw: pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_phy_params_82542(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_phy_params_82542");
phy->type = e1000_phy_none;
return ret_val;
}
/**
* e1000_init_nvm_params_82542 - Init NVM func ptrs.
* @hw: pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_nvm_params_82542(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
struct e1000_functions *func = &hw->func;
DEBUGFUNC("e1000_init_nvm_params_82542");
nvm->address_bits = 6;
nvm->delay_usec = 50;
nvm->opcode_bits = 3;
nvm->type = e1000_nvm_eeprom_microwire;
nvm->word_size = 64;
/* Function Pointers */
func->read_nvm = e1000_read_nvm_microwire;
func->release_nvm = e1000_stop_nvm;
func->write_nvm = e1000_write_nvm_microwire;
func->update_nvm = e1000_update_nvm_checksum_generic;
func->validate_nvm = e1000_validate_nvm_checksum_generic;
return E1000_SUCCESS;
}
/**
* e1000_init_mac_params_82542 - Init MAC func ptrs.
* @hw: pointer to the HW structure
*
* This is a function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_mac_params_82542(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_mac_params_82542");
/* Set media type */
hw->media_type = e1000_media_type_fiber;
/* Set mta register count */
mac->mta_reg_count = 128;
/* Set rar entry count */
mac->rar_entry_count = E1000_RAR_ENTRIES;
/* Function pointers */
/* bus type/speed/width */
func->get_bus_info = e1000_get_bus_info_82542;
/* reset */
func->reset_hw = e1000_reset_hw_82542;
/* hw initialization */
func->init_hw = e1000_init_hw_82542;
/* link setup */
func->setup_link = e1000_setup_link_82542;
/* phy/fiber/serdes setup */
func->setup_physical_interface = e1000_setup_fiber_serdes_link_generic;
/* check for link */
func->check_for_link = e1000_check_for_fiber_link_generic;
/* multicast address update */
func->mc_addr_list_update = e1000_mc_addr_list_update_generic;
/* writing VFTA */
func->write_vfta = e1000_write_vfta_generic;
/* clearing VFTA */
func->clear_vfta = e1000_clear_vfta_generic;
/* setting MTA */
func->mta_set = e1000_mta_set_generic;
/* turn on/off LED */
func->led_on = e1000_led_on_82542;
func->led_off = e1000_led_off_82542;
/* remove device */
func->remove_device = e1000_remove_device_generic;
/* clear hardware counters */
func->clear_hw_cntrs = e1000_clear_hw_cntrs_82542;
/* link info */
func->get_link_up_info = e1000_get_speed_and_duplex_fiber_serdes_generic;
hw->dev_spec_size = sizeof(struct e1000_dev_spec_82542);
/* Device-specific structure allocation */
ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size);
return ret_val;
}
/**
* e1000_init_function_pointers_82542 - Init func ptrs.
* @hw: pointer to the HW structure
*
* The only function explicitly called by the api module to initialize
* all function pointers and parameters.
**/
void
e1000_init_function_pointers_82542(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_init_function_pointers_82542");
hw->func.init_mac_params = e1000_init_mac_params_82542;
hw->func.init_nvm_params = e1000_init_nvm_params_82542;
hw->func.init_phy_params = e1000_init_phy_params_82542;
}
/**
* e1000_get_bus_info_82542 - Obtain bus information for adapter
* @hw: pointer to the HW structure
*
* This will obtain information about the HW bus for which the
* adaper is attached and stores it in the hw structure. This is a function
* pointer entry point called by the api module.
**/
STATIC s32
e1000_get_bus_info_82542(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_get_bus_info_82542");
hw->bus.type = e1000_bus_type_pci;
hw->bus.speed = e1000_bus_speed_unknown;
hw->bus.width = e1000_bus_width_unknown;
return E1000_SUCCESS;
}
/**
* e1000_reset_hw_82542 - Reset hardware
* @hw: pointer to the HW structure
*
* This resets the hardware into a known state. This is a
* function pointer entry point called by the api module.
**/
STATIC s32
e1000_reset_hw_82542(struct e1000_hw *hw)
{
struct e1000_bus_info *bus = &hw->bus;
s32 ret_val = E1000_SUCCESS;
u32 ctrl, icr;
DEBUGFUNC("e1000_reset_hw_82542");
if (hw->revision_id == E1000_REVISION_2) {
DEBUGOUT("Disabling MWI on 82542 rev 2\n");
e1000_pci_clear_mwi(hw);
}
DEBUGOUT("Masking off all interrupts\n");
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
E1000_WRITE_REG(hw, E1000_RCTL, 0);
E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
E1000_WRITE_FLUSH(hw);
/* Delay to allow any outstanding PCI transactions to complete before
* resetting the device
*/
msec_delay(10);
ctrl = E1000_READ_REG(hw, E1000_CTRL);
DEBUGOUT("Issuing a global reset to 82542/82543 MAC\n");
E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
e1000_reload_nvm(hw);
msec_delay(2);
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
icr = E1000_READ_REG(hw, E1000_ICR);
if (hw->revision_id == E1000_REVISION_2) {
if (bus->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
e1000_pci_set_mwi(hw);
}
return ret_val;
}
/**
* e1000_init_hw_82542 - Initialize hardware
* @hw: pointer to the HW structure
*
* This inits the hardware readying it for operation. This is a
* function pointer entry point called by the api module.
**/
STATIC s32
e1000_init_hw_82542(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
struct e1000_dev_spec_82542 *dev_spec;
s32 ret_val = E1000_SUCCESS;
u32 ctrl;
u16 i;
DEBUGFUNC("e1000_init_hw_82542");
dev_spec = (struct e1000_dev_spec_82542 *)hw->dev_spec;
/* Disabling VLAN filtering */
E1000_WRITE_REG(hw, E1000_VET, 0);
e1000_clear_vfta(hw);
/* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
if (hw->revision_id == E1000_REVISION_2) {
DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
e1000_pci_clear_mwi(hw);
E1000_WRITE_REG(hw, E1000_RCTL, E1000_RCTL_RST);
E1000_WRITE_FLUSH(hw);
msec_delay(5);
}
/* Setup the receive address. */
e1000_init_rx_addrs_generic(hw, mac->rar_entry_count);
/* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
if (hw->revision_id == E1000_REVISION_2) {
E1000_WRITE_REG(hw, E1000_RCTL, 0);
E1000_WRITE_FLUSH(hw);
msec_delay(1);
if (hw->bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
e1000_pci_set_mwi(hw);
}
/* Zero out the Multicast HASH table */
DEBUGOUT("Zeroing the MTA\n");
for (i = 0; i < mac->mta_reg_count; i++)
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
/* Set the PCI priority bit correctly in the CTRL register. This
* determines if the adapter gives priority to receives, or if it
* gives equal priority to transmits and receives.
*/
if (dev_spec->dma_fairness) {
ctrl = E1000_READ_REG(hw, E1000_CTRL);
E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PRIOR);
}
/* Setup link and flow control */
ret_val = e1000_setup_link_82542(hw);
/* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there
* is no link.
*/
e1000_clear_hw_cntrs_82542(hw);
return ret_val;
}
/**
* e1000_setup_link_82542 - Setup flow control and link settings
* @hw: pointer to the HW structure
*
* Determines which flow control settings to use, then configures flow
* control. Calls the appropriate media-specific link configuration
* function. Assuming the adapter has a valid link partner, a valid link
* should be established. Assumes the hardware has previously been reset
* and the transmitter and receiver are not enabled. This is a function
* pointer entry point called by the api module.
**/
STATIC s32
e1000_setup_link_82542(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
struct e1000_functions *func = &hw->func;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_setup_link_82542");
ret_val = e1000_set_default_fc_generic(hw);
if (ret_val)
goto out;
mac->fc &= ~e1000_fc_tx_pause;
if (mac->report_tx_early == 1)
mac->fc &= ~e1000_fc_rx_pause;
/* We want to save off the original Flow Control configuration just in
* case we get disconnected and then reconnected into a different hub
* or switch with different Flow Control capabilities.
*/
mac->original_fc = mac->fc;
DEBUGOUT1("After fix-ups FlowControl is now = %x\n", mac->fc);
/* Call the necessary subroutine to configure the link. */
ret_val = func->setup_physical_interface(hw);
if (ret_val)
goto out;
/* Initialize the flow control address, type, and PAUSE timer
* registers to their default values. This is done even if flow
* control is disabled, because it does not hurt anything to
* initialize these registers.
*/
DEBUGOUT("Initializing Flow Control address, type and timer regs\n");
E1000_WRITE_REG(hw, E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW);
E1000_WRITE_REG(hw, E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH);
E1000_WRITE_REG(hw, E1000_FCT, FLOW_CONTROL_TYPE);
E1000_WRITE_REG(hw, E1000_FCTTV, mac->fc_pause_time);
ret_val = e1000_set_fc_watermarks_generic(hw);
out:
return ret_val;
}
/**
* e1000_led_on_82542 - Turn on SW controllable LED
* @hw: pointer to the HW structure
*
* Turns the SW defined LED on. This is a function pointer entry point
* called by the api module.
**/
STATIC s32
e1000_led_on_82542(struct e1000_hw *hw)
{
u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
DEBUGFUNC("e1000_led_on_82542");
ctrl |= E1000_CTRL_SWDPIN0;
ctrl |= E1000_CTRL_SWDPIO0;
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
return E1000_SUCCESS;
}
/**
* e1000_led_off_82542 - Turn off SW controllable LED
* @hw: pointer to the HW structure
*
* Turns the SW defined LED off. This is a function pointer entry point
* called by the api module.
**/
STATIC s32
e1000_led_off_82542(struct e1000_hw *hw)
{
u32 ctrl = E1000_READ_REG(hw, E1000_CTRL);
DEBUGFUNC("e1000_led_off_82542");
ctrl &= ~E1000_CTRL_SWDPIN0;
ctrl |= E1000_CTRL_SWDPIO0;
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
return E1000_SUCCESS;
}
/**
* e1000_translate_register_82542 - Translate the proper regiser offset
* @reg: e1000 register to be read
*
* Registers in 82542 are located in different offsets than other adapters
* even though they function in the same manner. This function takes in
* the name of the register to read and returns the correct offset for
* 82542 silicon.
**/
u32
e1000_translate_register_82542(u32 reg)
{
/* Some of the 82542 registers are located at different
* offsets than they are in newer adapters.
* Despite the difference in location, the registers
* function in the same manner.
*/
switch (reg) {
case E1000_RA:
reg = 0x00040;
break;
case E1000_RDTR:
reg = 0x00108;
break;
case E1000_RDBAL:
reg = 0x00110;
break;
case E1000_RDBAH:
reg = 0x00114;
break;
case E1000_RDLEN:
reg = 0x00118;
break;
case E1000_RDH:
reg = 0x00120;
break;
case E1000_RDT:
reg = 0x00128;
break;
case E1000_RDBAL1:
reg = 0x00138;
break;
case E1000_RDBAH1:
reg = 0x0013C;
break;
case E1000_RDLEN1:
reg = 0x00140;
break;
case E1000_RDH1:
reg = 0x00148;
break;
case E1000_RDT1:
reg = 0x00150;
break;
case E1000_FCRTH:
reg = 0x00160;
break;
case E1000_FCRTL:
reg = 0x00168;
break;
case E1000_MTA:
reg = 0x00200;
break;
case E1000_TDBAL:
reg = 0x00420;
break;
case E1000_TDBAH:
reg = 0x00424;
break;
case E1000_TDLEN:
reg = 0x00428;
break;
case E1000_TDH:
reg = 0x00430;
break;
case E1000_TDT:
reg = 0x00438;
break;
case E1000_TIDV:
reg = 0x00440;
break;
case E1000_VFTA:
reg = 0x00600;
break;
case E1000_TDFH:
reg = 0x08010;
break;
case E1000_TDFT:
reg = 0x08018;
break;
default:
break;
}
return reg;
}
/**
* e1000_clear_hw_cntrs_82542 - Clear device specific hardware counters
* @hw: pointer to the HW structure
*
* Clears the hardware counters by reading the counter registers.
**/
STATIC void
e1000_clear_hw_cntrs_82542(struct e1000_hw *hw)
{
volatile u32 temp;
DEBUGFUNC("e1000_clear_hw_cntrs_82542");
e1000_clear_hw_cntrs_base_generic(hw);
temp = E1000_READ_REG(hw, E1000_PRC64);
temp = E1000_READ_REG(hw, E1000_PRC127);
temp = E1000_READ_REG(hw, E1000_PRC255);
temp = E1000_READ_REG(hw, E1000_PRC511);
temp = E1000_READ_REG(hw, E1000_PRC1023);
temp = E1000_READ_REG(hw, E1000_PRC1522);
temp = E1000_READ_REG(hw, E1000_PTC64);
temp = E1000_READ_REG(hw, E1000_PTC127);
temp = E1000_READ_REG(hw, E1000_PTC255);
temp = E1000_READ_REG(hw, E1000_PTC511);
temp = E1000_READ_REG(hw, E1000_PTC1023);
temp = E1000_READ_REG(hw, E1000_PTC1522);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_82543.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_82543_H_
#define _E1000_82543_H_
#define PHY_PREAMBLE 0xFFFFFFFF
#define PHY_PREAMBLE_SIZE 32
#define PHY_SOF 0x1
#define PHY_OP_READ 0x2
#define PHY_OP_WRITE 0x1
#define PHY_TURNAROUND 0x2
#define TBI_COMPAT_ENABLED 0x1 /* Global "knob" for the workaround */
#define TBI_SBP_ENABLED 0x2 /* If TBI_COMPAT_ENABLED,
* then this is the current state (on/off) */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_82571.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_82571_H_
#define _E1000_82571_H_
#define ID_LED_RESERVED_F746 0xF746
#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_OFF1_ON2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_DEF1_DEF2))
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,298 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_82575.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_82575_H_
#define _E1000_82575_H_
/* Receive Address Register Count
* Number of high/low register pairs in the RAR. The RAR (Receive Address
* Registers) holds the directed and multicast addresses that we monitor.
* These entries are also used for MAC-based filtering.
*/
#define E1000_RAR_ENTRIES_82575 16
#ifdef E1000_BIT_FIELDS
struct e1000_adv_data_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
union {
u32 data;
struct {
u32 datalen :16; /* Data buffer length */
u32 rsvd :4;
u32 dtyp :4; /* Descriptor type */
u32 dcmd :8; /* Descriptor command */
} config;
} lower;
union {
u32 data;
struct {
u32 status :4; /* Descriptor status */
u32 idx :4;
u32 popts :6; /* Packet Options */
u32 paylen :18; /* Payload length */
} options;
} upper;
};
#define E1000_TXD_DTYP_ADV_C 0x2 /* Advanced Context Descriptor */
#define E1000_TXD_DTYP_ADV_D 0x3 /* Advanced Data Descriptor */
#define E1000_ADV_TXD_CMD_DEXT 0x20 /* Descriptor extension (0 = legacy) */
#define E1000_ADV_TUCMD_IPV4 0x2 /* IP Packet Type: 1=IPv4 */
#define E1000_ADV_TUCMD_IPV6 0x0 /* IP Packet Type: 0=IPv6 */
#define E1000_ADV_TUCMD_L4T_UDP 0x0 /* L4 Packet TYPE of UDP */
#define E1000_ADV_TUCMD_L4T_TCP 0x4 /* L4 Packet TYPE of TCP */
#define E1000_ADV_TUCMD_MKRREQ 0x10 /* Indicates markers are required */
#define E1000_ADV_DCMD_EOP 0x1 /* End of Packet */
#define E1000_ADV_DCMD_IFCS 0x2 /* Insert FCS (Ethernet CRC) */
#define E1000_ADV_DCMD_RS 0x8 /* Report Status */
#define E1000_ADV_DCMD_VLE 0x40 /* Add VLAN tag */
#define E1000_ADV_DCMD_TSE 0x80 /* TCP Seg enable */
struct e1000_adv_context_desc {
union {
u32 ip_config;
struct {
u32 iplen :9;
u32 maclen :7;
u32 vlan_tag :16;
} fields;
} ip_setup;
u32 seq_num;
union {
u64 l4_config;
struct {
u32 mkrloc :9;
u32 tucmd :11;
u32 dtyp :4;
u32 adv :8;
u32 rsvd :4;
u32 idx :4;
u32 l4len :8;
u32 mss :16;
} fields;
} l4_setup;
};
#endif
/* SRRCTL bit definitions */
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00
#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
#define E1000_SRRCTL_DESCTYPE_LEGACY 0x00000000
#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000
#define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
#define E1000_TX_HEAD_WB_ENABLE 0x1
#define E1000_TX_SEQNUM_WB_ENABLE 0x2
#define E1000_MRQC_ENABLE_RSS_4Q 0x00000002
#define E1000_MRQC_RSS_FIELD_IPV4_UDP 0x00400000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
#define E1000_EICR_TX_QUEUE ( \
E1000_EICR_TX_QUEUE0 | \
E1000_EICR_TX_QUEUE1 | \
E1000_EICR_TX_QUEUE2 | \
E1000_EICR_TX_QUEUE3)
#define E1000_EICR_RX_QUEUE ( \
E1000_EICR_RX_QUEUE0 | \
E1000_EICR_RX_QUEUE1 | \
E1000_EICR_RX_QUEUE2 | \
E1000_EICR_RX_QUEUE3)
#define E1000_EIMS_RX_QUEUE E1000_EICR_RX_QUEUE
#define E1000_EIMS_TX_QUEUE E1000_EICR_TX_QUEUE
#define EIMS_ENABLE_MASK ( \
E1000_EIMS_RX_QUEUE | \
E1000_EIMS_TX_QUEUE | \
E1000_EIMS_TCP_TIMER | \
E1000_EIMS_OTHER)
/* Immediate Interrupt RX (A.K.A. Low Latency Interrupt) */
#define E1000_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */
#define E1000_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */
#define E1000_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
#define E1000_IMIREXT_CTRL_URG 0x00002000 /* Check URG bit in header */
#define E1000_IMIREXT_CTRL_ACK 0x00004000 /* Check ACK bit in header */
#define E1000_IMIREXT_CTRL_PSH 0x00008000 /* Check PSH bit in header */
#define E1000_IMIREXT_CTRL_RST 0x00010000 /* Check RST bit in header */
#define E1000_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */
#define E1000_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */
#define E1000_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of control bits */
/* Receive Descriptor - Advanced */
union e1000_adv_rx_desc {
struct {
u64 pkt_addr; /* Packet buffer address */
u64 hdr_addr; /* Header buffer address */
} read;
struct {
struct {
struct {
u16 pkt_info; /* RSS type, Packet type */
u16 hdr_info; /* Split Header,
* header buffer length */
} lo_dword;
union {
u32 rss; /* RSS Hash */
struct {
u16 ip_id; /* IP id */
u16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
u32 status_error; /* ext status/error */
u16 length; /* Packet length */
u16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define E1000_RXDADV_RSSTYPE_MASK 0x0000F000
#define E1000_RXDADV_RSSTYPE_SHIFT 12
#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
#define E1000_RXDADV_SPLITHEADER_EN 0x00001000
#define E1000_RXDADV_SPH 0x8000
#define E1000_RXDADV_HBO 0x00800000
/* RSS Hash results */
#define E1000_RXDADV_RSSTYPE_NONE 0x00000000
#define E1000_RXDADV_RSSTYPE_IPV4_TCP 0x00000001
#define E1000_RXDADV_RSSTYPE_IPV4 0x00000002
#define E1000_RXDADV_RSSTYPE_IPV6_TCP 0x00000003
#define E1000_RXDADV_RSSTYPE_IPV6_EX 0x00000004
#define E1000_RXDADV_RSSTYPE_IPV6 0x00000005
#define E1000_RXDADV_RSSTYPE_IPV6_TCP_EX 0x00000006
#define E1000_RXDADV_RSSTYPE_IPV4_UDP 0x00000007
#define E1000_RXDADV_RSSTYPE_IPV6_UDP 0x00000008
#define E1000_RXDADV_RSSTYPE_IPV6_UDP_EX 0x00000009
/* Transmit Descriptor - Advanced */
union e1000_adv_tx_desc {
struct {
u64 buffer_addr; /* Address of descriptor's data buf */
u32 cmd_type_len;
u32 olinfo_status;
} read;
struct {
u64 rsvd; /* Reserved */
u32 nxtseq_seed;
u32 status;
} wb;
};
/* Adv Transmit Descriptor Config Masks */
#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
#define E1000_ADVTXD_DCMD_RDMA 0x04000000 /* RDMA */
#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
#define E1000_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */
#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
#define E1000_ADVTXD_MAC_LINKSEC 0x00040000 /* Apply LinkSec on packet */
#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp packet */
#define E1000_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED present in WB */
#define E1000_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */
#define E1000_ADVTXD_POPTS_EOM 0x00000400 /* Enable L bit in RDMA DDP hdr */
#define E1000_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
#define E1000_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU*/
#define E1000_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */
#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
/* Context descriptors */
struct e1000_adv_tx_context_desc {
u32 vlan_macip_lens;
u32 seqnum_seed;
u32 type_tucmd_mlhl;
u32 mss_l4len_idx;
};
#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
#define E1000_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */
#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
#define E1000_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */
#define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
#define E1000_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
/* IPSec Encrypt Enable for ESP */
#define E1000_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000
#define E1000_ADVTXD_TUCMD_MKRREQ 0x00002000 /* Req requires Markers and CRC */
#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
/* Adv ctxt IPSec SA IDX mask */
#define E1000_ADVTXD_IPSEC_SA_INDEX_MASK 0x000000FF
/* Adv ctxt IPSec ESP len mask */
#define E1000_ADVTXD_IPSEC_ESP_LEN_MASK 0x000000FF
/* Additional Transmit Descriptor Control definitions */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
#define E1000_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. write-back flushing */
#define E1000_TXDCTL_PRIORITY 0x08000000 /* Tx Queue Arbitration Priority
0=low, 1=high */
/* Additional Receive Descriptor Control definitions */
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
#define E1000_RXDCTL_SWFLSH 0x04000000 /* Rx Desc. write-back flushing */
/* Direct Cache Access (DCA) definitions */
#define E1000_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */
#define E1000_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */
#define E1000_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */
#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
#define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
#define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,163 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_api.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_API_H_
#define _E1000_API_H_
#include "e1000_hw.h"
s32 e1000_set_mac_type(struct e1000_hw *hw);
s32 e1000_setup_init_funcs(struct e1000_hw *hw, boolean_t init_device);
s32 e1000_init_mac_params(struct e1000_hw *hw);
s32 e1000_init_nvm_params(struct e1000_hw *hw);
s32 e1000_init_phy_params(struct e1000_hw *hw);
void e1000_remove_device(struct e1000_hw *hw);
s32 e1000_get_bus_info(struct e1000_hw *hw);
void e1000_clear_vfta(struct e1000_hw *hw);
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
s32 e1000_force_mac_fc(struct e1000_hw *hw);
s32 e1000_check_for_link(struct e1000_hw *hw);
s32 e1000_reset_hw(struct e1000_hw *hw);
s32 e1000_init_hw(struct e1000_hw *hw);
s32 e1000_setup_link(struct e1000_hw *hw);
s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 e1000_disable_pcie_master(struct e1000_hw *hw);
void e1000_config_collision_dist(struct e1000_hw *hw);
void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
void e1000_mta_set(struct e1000_hw *hw, u32 hash_value);
u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
void e1000_mc_addr_list_update(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count);
s32 e1000_setup_led(struct e1000_hw *hw);
s32 e1000_cleanup_led(struct e1000_hw *hw);
s32 e1000_check_reset_block(struct e1000_hw *hw);
s32 e1000_blink_led(struct e1000_hw *hw);
s32 e1000_led_on(struct e1000_hw *hw);
s32 e1000_led_off(struct e1000_hw *hw);
void e1000_reset_adaptive(struct e1000_hw *hw);
void e1000_update_adaptive(struct e1000_hw *hw);
s32 e1000_get_cable_length(struct e1000_hw *hw);
s32 e1000_validate_mdi_setting(struct e1000_hw *hw);
s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
s32 e1000_get_phy_info(struct e1000_hw *hw);
s32 e1000_phy_hw_reset(struct e1000_hw *hw);
s32 e1000_phy_commit(struct e1000_hw *hw);
s32 e1000_read_mac_addr(struct e1000_hw *hw);
s32 e1000_read_part_num(struct e1000_hw *hw, u32 *part_num);
void e1000_reload_nvm(struct e1000_hw *hw);
s32 e1000_update_nvm_checksum(struct e1000_hw *hw);
s32 e1000_validate_nvm_checksum(struct e1000_hw *hw);
s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data);
s32 e1000_wait_autoneg(struct e1000_hw *hw);
s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
boolean_t e1000_check_mng_mode(struct e1000_hw *hw);
boolean_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
s32 e1000_mng_enable_host_if(struct e1000_hw *hw);
s32 e1000_mng_host_if_write(struct e1000_hw *hw,
u8 *buffer, u16 length, u16 offset, u8 *sum);
s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr);
s32 e1000_mng_write_dhcp_info(struct e1000_hw * hw,
u8 *buffer, u16 length);
void e1000_tbi_adjust_stats_82543(struct e1000_hw *hw,
struct e1000_hw_stats *stats,
u32 frame_len, u8 *mac_addr);
void e1000_set_tbi_compatibility_82543(struct e1000_hw *hw,
boolean_t state);
boolean_t e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw);
#ifndef NO_82542_SUPPORT
u32 e1000_translate_register_82542(u32 reg);
#endif
void e1000_init_script_state_82541(struct e1000_hw *hw, boolean_t state);
boolean_t e1000_get_laa_state_82571(struct e1000_hw *hw);
void e1000_set_laa_state_82571(struct e1000_hw *hw, boolean_t state);
void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
boolean_t state);
void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
/* TBI_ACCEPT macro definition:
*
* This macro requires:
* adapter = a pointer to struct e1000_hw
* status = the 8 bit status field of the RX descriptor with EOP set
* error = the 8 bit error field of the RX descriptor with EOP set
* length = the sum of all the length fields of the RX descriptors that
* make up the current frame
* last_byte = the last byte of the frame DMAed by the hardware
* max_frame_length = the maximum frame length we want to accept.
* min_frame_length = the minimum frame length we want to accept.
*
* This macro is a conditional that should be used in the interrupt
* handler's Rx processing routine when RxErrors have been detected.
*
* Typical use:
* ...
* if (TBI_ACCEPT) {
* accept_frame = TRUE;
* e1000_tbi_adjust_stats(adapter, MacAddress);
* frame_length--;
* } else {
* accept_frame = FALSE;
* }
* ...
*/
/* The carrier extension symbol, as received by the NIC. */
#define CARRIER_EXTENSION 0x0F
#define TBI_ACCEPT(a, status, errors, length, last_byte) \
(e1000_tbi_sbp_enabled_82543(a) && \
(((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
((last_byte) == CARRIER_EXTENSION) && \
(((status) & E1000_RXD_STAT_VP) ? \
(((length) > ((a)->mac.min_frame_size - VLAN_TAG_SIZE)) && \
((length) <= ((a)->mac.max_frame_size + 1))) : \
(((length) > (a)->mac.min_frame_size) && \
((length) <= ((a)->mac.max_frame_size + VLAN_TAG_SIZE + 1)))))
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,726 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_hw.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_HW_H_
#define _E1000_HW_H_
#include "e1000_osdep.h"
#include "e1000_regs.h"
#include "e1000_defines.h"
struct e1000_hw;
#ifndef NO_82542_SUPPORT
#define E1000_DEV_ID_82542 0x1000
#endif
#define E1000_DEV_ID_82543GC_FIBER 0x1001
#define E1000_DEV_ID_82543GC_COPPER 0x1004
#define E1000_DEV_ID_82544EI_COPPER 0x1008
#define E1000_DEV_ID_82544EI_FIBER 0x1009
#define E1000_DEV_ID_82544GC_COPPER 0x100C
#define E1000_DEV_ID_82544GC_LOM 0x100D
#define E1000_DEV_ID_82540EM 0x100E
#define E1000_DEV_ID_82540EM_LOM 0x1015
#define E1000_DEV_ID_82540EP_LOM 0x1016
#define E1000_DEV_ID_82540EP 0x1017
#define E1000_DEV_ID_82540EP_LP 0x101E
#define E1000_DEV_ID_82545EM_COPPER 0x100F
#define E1000_DEV_ID_82545EM_FIBER 0x1011
#define E1000_DEV_ID_82545GM_COPPER 0x1026
#define E1000_DEV_ID_82545GM_FIBER 0x1027
#define E1000_DEV_ID_82545GM_SERDES 0x1028
#define E1000_DEV_ID_82546EB_COPPER 0x1010
#define E1000_DEV_ID_82546EB_FIBER 0x1012
#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
#define E1000_DEV_ID_82546GB_COPPER 0x1079
#define E1000_DEV_ID_82546GB_FIBER 0x107A
#define E1000_DEV_ID_82546GB_SERDES 0x107B
#define E1000_DEV_ID_82546GB_PCIE 0x108A
#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
#define E1000_DEV_ID_82541EI 0x1013
#define E1000_DEV_ID_82541EI_MOBILE 0x1018
#define E1000_DEV_ID_82541ER_LOM 0x1014
#define E1000_DEV_ID_82541ER 0x1078
#define E1000_DEV_ID_82541GI 0x1076
#define E1000_DEV_ID_82541GI_LF 0x107C
#define E1000_DEV_ID_82541GI_MOBILE 0x1077
#define E1000_DEV_ID_82547EI 0x1019
#define E1000_DEV_ID_82547EI_MOBILE 0x101A
#define E1000_DEV_ID_82547GI 0x1075
#define E1000_DEV_ID_82571EB_COPPER 0x105E
#define E1000_DEV_ID_82571EB_FIBER 0x105F
#define E1000_DEV_ID_82571EB_SERDES 0x1060
#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5
#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC
#define E1000_DEV_ID_82572EI_COPPER 0x107D
#define E1000_DEV_ID_82572EI_FIBER 0x107E
#define E1000_DEV_ID_82572EI_SERDES 0x107F
#define E1000_DEV_ID_82572EI 0x10B9
#define E1000_DEV_ID_82573E 0x108B
#define E1000_DEV_ID_82573E_IAMT 0x108C
#define E1000_DEV_ID_82573L 0x109A
#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB
#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049
#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A
#define E1000_DEV_ID_ICH8_IGP_C 0x104B
#define E1000_DEV_ID_ICH8_IFE 0x104C
#define E1000_DEV_ID_ICH8_IFE_GT 0x10C4
#define E1000_DEV_ID_ICH8_IFE_G 0x10C5
#define E1000_DEV_ID_ICH8_IGP_M 0x104D
#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD
#define E1000_DEV_ID_ICH9_IGP_C 0x294C
#define E1000_DEV_ID_ICH9_IFE 0x10C0
#define E1000_DEV_ID_ICH9_IFE_GT 0x10C3
#define E1000_DEV_ID_ICH9_IFE_G 0x10C2
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575EM_COPPER 0x10AA
#define E1000_DEV_ID_82575EM_FIBER_SERDES 0x10AC
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
#define E1000_REVISION_0 0
#define E1000_REVISION_1 1
#define E1000_REVISION_2 2
#define E1000_REVISION_3 3
#define E1000_REVISION_4 4
#define E1000_FUNC_0 0
#define E1000_FUNC_1 1
typedef enum {
e1000_undefined = 0,
#ifndef NO_82542_SUPPORT
e1000_82542,
#endif
e1000_82543,
e1000_82544,
e1000_82540,
e1000_82545,
e1000_82545_rev_3,
e1000_82546,
e1000_82546_rev_3,
e1000_82541,
e1000_82541_rev_2,
e1000_82547,
e1000_82547_rev_2,
e1000_82571,
e1000_82572,
e1000_82573,
e1000_80003es2lan,
e1000_ich8lan,
e1000_ich9lan,
e1000_82575,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
} e1000_mac_type;
typedef enum {
e1000_media_type_unknown = 0,
e1000_media_type_copper = 1,
e1000_media_type_fiber = 2,
e1000_media_type_internal_serdes = 3,
e1000_num_media_types
} e1000_media_type;
typedef enum {
e1000_nvm_unknown = 0,
e1000_nvm_none,
e1000_nvm_eeprom_spi,
e1000_nvm_eeprom_microwire,
e1000_nvm_flash_hw,
e1000_nvm_flash_sw
} e1000_nvm_type;
typedef enum {
e1000_nvm_override_none = 0,
e1000_nvm_override_spi_small,
e1000_nvm_override_spi_large,
e1000_nvm_override_microwire_small,
e1000_nvm_override_microwire_large
} e1000_nvm_override;
typedef enum {
e1000_phy_unknown = 0,
e1000_phy_none,
e1000_phy_m88,
e1000_phy_igp,
e1000_phy_igp_2,
e1000_phy_gg82563,
e1000_phy_igp_3,
e1000_phy_ife,
} e1000_phy_type;
typedef enum {
e1000_bus_type_unknown = 0,
e1000_bus_type_pci,
e1000_bus_type_pcix,
e1000_bus_type_pci_express,
e1000_bus_type_reserved
} e1000_bus_type;
typedef enum {
e1000_bus_speed_unknown = 0,
e1000_bus_speed_33,
e1000_bus_speed_66,
e1000_bus_speed_100,
e1000_bus_speed_120,
e1000_bus_speed_133,
e1000_bus_speed_2500,
e1000_bus_speed_reserved
} e1000_bus_speed;
typedef enum {
e1000_bus_width_unknown = 0,
e1000_bus_width_pcie_x1,
e1000_bus_width_pcie_x2,
e1000_bus_width_pcie_x4 = 4,
e1000_bus_width_32,
e1000_bus_width_64,
e1000_bus_width_reserved
} e1000_bus_width;
typedef enum {
e1000_1000t_rx_status_not_ok = 0,
e1000_1000t_rx_status_ok,
e1000_1000t_rx_status_undefined = 0xFF
} e1000_1000t_rx_status;
typedef enum {
e1000_rev_polarity_normal = 0,
e1000_rev_polarity_reversed,
e1000_rev_polarity_undefined = 0xFF
} e1000_rev_polarity;
typedef enum {
e1000_fc_none = 0,
e1000_fc_rx_pause,
e1000_fc_tx_pause,
e1000_fc_full,
e1000_fc_default = 0xFF
} e1000_fc_mode;
typedef enum {
e1000_ffe_config_enabled = 0,
e1000_ffe_config_active,
e1000_ffe_config_blocked
} e1000_ffe_config;
typedef enum {
e1000_dsp_config_disabled = 0,
e1000_dsp_config_enabled,
e1000_dsp_config_activated,
e1000_dsp_config_undefined = 0xFF
} e1000_dsp_config;
/* Receive Descriptor */
struct e1000_rx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
u16 length; /* Length of data DMAed into data buffer */
u16 csum; /* Packet checksum */
u8 status; /* Descriptor status */
u8 errors; /* Descriptor Errors */
u16 special;
};
/* Receive Descriptor - Extended */
union e1000_rx_desc_extended {
struct {
u64 buffer_addr;
u64 reserved;
} read;
struct {
struct {
u32 mrq; /* Multiple Rx Queues */
union {
u32 rss; /* RSS Hash */
struct {
u16 ip_id; /* IP id */
u16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
u32 status_error; /* ext status/error */
u16 length;
u16 vlan; /* VLAN tag */
} upper;
} wb; /* writeback */
};
#define MAX_PS_BUFFERS 4
/* Receive Descriptor - Packet Split */
union e1000_rx_desc_packet_split {
struct {
/* one buffer for protocol header(s), three data buffers */
u64 buffer_addr[MAX_PS_BUFFERS];
} read;
struct {
struct {
u32 mrq; /* Multiple Rx Queues */
union {
u32 rss; /* RSS Hash */
struct {
u16 ip_id; /* IP id */
u16 csum; /* Packet Checksum */
} csum_ip;
} hi_dword;
} lower;
struct {
u32 status_error; /* ext status/error */
u16 length0; /* length of buffer 0 */
u16 vlan; /* VLAN tag */
} middle;
struct {
u16 header_status;
u16 length[3]; /* length of buffers 1-3 */
} upper;
u64 reserved;
} wb; /* writeback */
};
/* Transmit Descriptor */
struct e1000_tx_desc {
u64 buffer_addr; /* Address of the descriptor's data buffer */
union {
u32 data;
struct {
u16 length; /* Data buffer length */
u8 cso; /* Checksum offset */
u8 cmd; /* Descriptor control */
} flags;
} lower;
union {
u32 data;
struct {
u8 status; /* Descriptor status */
u8 css; /* Checksum start */
u16 special;
} fields;
} upper;
};
/* Offload Context Descriptor */
struct e1000_context_desc {
union {
u32 ip_config;
struct {
u8 ipcss; /* IP checksum start */
u8 ipcso; /* IP checksum offset */
u16 ipcse; /* IP checksum end */
} ip_fields;
} lower_setup;
union {
u32 tcp_config;
struct {
u8 tucss; /* TCP checksum start */
u8 tucso; /* TCP checksum offset */
u16 tucse; /* TCP checksum end */
} tcp_fields;
} upper_setup;
u32 cmd_and_length;
union {
u32 data;
struct {
u8 status; /* Descriptor status */
u8 hdr_len; /* Header length */
u16 mss; /* Maximum segment size */
} fields;
} tcp_seg_setup;
};
/* Offload data descriptor */
struct e1000_data_desc {
u64 buffer_addr; /* Address of the descriptor's buffer address */
union {
u32 data;
struct {
u16 length; /* Data buffer length */
u8 typ_len_ext;
u8 cmd;
} flags;
} lower;
union {
u32 data;
struct {
u8 status; /* Descriptor status */
u8 popts; /* Packet Options */
u16 special; /* */
} fields;
} upper;
};
/* Statistics counters collected by the MAC */
struct e1000_hw_stats {
u64 crcerrs;
u64 algnerrc;
u64 symerrs;
u64 rxerrc;
u64 mpc;
u64 scc;
u64 ecol;
u64 mcc;
u64 latecol;
u64 colc;
u64 dc;
u64 tncrs;
u64 sec;
u64 cexterr;
u64 rlec;
u64 xonrxc;
u64 xontxc;
u64 xoffrxc;
u64 xofftxc;
u64 fcruc;
u64 prc64;
u64 prc127;
u64 prc255;
u64 prc511;
u64 prc1023;
u64 prc1522;
u64 gprc;
u64 bprc;
u64 mprc;
u64 gptc;
u64 gorcl;
u64 gorch;
u64 gotcl;
u64 gotch;
u64 rnbc;
u64 ruc;
u64 rfc;
u64 roc;
u64 rjc;
u64 mgprc;
u64 mgpdc;
u64 mgptc;
u64 torl;
u64 torh;
u64 totl;
u64 toth;
u64 tpr;
u64 tpt;
u64 ptc64;
u64 ptc127;
u64 ptc255;
u64 ptc511;
u64 ptc1023;
u64 ptc1522;
u64 mptc;
u64 bptc;
u64 tsctc;
u64 tsctfc;
u64 iac;
u64 icrxptc;
u64 icrxatc;
u64 ictxptc;
u64 ictxatc;
u64 ictxqec;
u64 ictxqmtc;
u64 icrxdmtc;
u64 icrxoc;
u64 cbtmpc;
u64 htdpmc;
u64 cbrdpc;
u64 cbrmpc;
u64 rpthc;
u64 hgptc;
u64 htcbdpc;
u64 hgorcl;
u64 hgorch;
u64 hgotcl;
u64 hgotch;
u64 lenerrs;
u64 scvpc;
u64 hrmpc;
};
struct e1000_phy_stats {
u32 idle_errors;
u32 receive_errors;
};
struct e1000_host_mng_dhcp_cookie {
u32 signature;
u8 status;
u8 reserved0;
u16 vlan_id;
u32 reserved1;
u16 reserved2;
u8 reserved3;
u8 checksum;
};
/* Host Interface "Rev 1" */
struct e1000_host_command_header {
u8 command_id;
u8 command_length;
u8 command_options;
u8 checksum;
};
#define E1000_HI_MAX_DATA_LENGTH 252
struct e1000_host_command_info {
struct e1000_host_command_header command_header;
u8 command_data[E1000_HI_MAX_DATA_LENGTH];
};
/* Host Interface "Rev 2" */
struct e1000_host_mng_command_header {
u8 command_id;
u8 checksum;
u16 reserved1;
u16 reserved2;
u16 command_length;
};
#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8
struct e1000_host_mng_command_info {
struct e1000_host_mng_command_header command_header;
u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH];
};
#include "e1000_mac.h"
#include "e1000_phy.h"
#include "e1000_nvm.h"
#include "e1000_manage.h"
struct e1000_functions {
/* Function pointers for the MAC. */
s32 (*init_mac_params)(struct e1000_hw *);
s32 (*blink_led)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
boolean_t (*check_mng_mode)(struct e1000_hw *hw);
s32 (*cleanup_led)(struct e1000_hw *);
void (*clear_hw_cntrs)(struct e1000_hw *);
void (*clear_vfta)(struct e1000_hw *);
s32 (*get_bus_info)(struct e1000_hw *);
s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
s32 (*led_on)(struct e1000_hw *);
s32 (*led_off)(struct e1000_hw *);
void (*mc_addr_list_update)(struct e1000_hw *, u8 *, u32, u32,
u32);
void (*remove_device)(struct e1000_hw *);
s32 (*reset_hw)(struct e1000_hw *);
s32 (*init_hw)(struct e1000_hw *);
s32 (*setup_link)(struct e1000_hw *);
s32 (*setup_physical_interface)(struct e1000_hw *);
s32 (*setup_led)(struct e1000_hw *);
void (*write_vfta)(struct e1000_hw *, u32, u32);
void (*mta_set)(struct e1000_hw *, u32);
void (*config_collision_dist)(struct e1000_hw*);
void (*rar_set)(struct e1000_hw*, u8*, u32);
s32 (*validate_mdi_setting)(struct e1000_hw*);
s32 (*mng_host_if_write)(struct e1000_hw*, u8*, u16, u16, u8*);
s32 (*mng_write_cmd_header)(struct e1000_hw *hw,
struct e1000_host_mng_command_header*);
s32 (*mng_enable_host_if)(struct e1000_hw*);
s32 (*wait_autoneg)(struct e1000_hw*);
/* Function pointers for the PHY. */
s32 (*init_phy_params)(struct e1000_hw *);
s32 (*acquire_phy)(struct e1000_hw *);
s32 (*check_polarity)(struct e1000_hw *);
s32 (*check_reset_block)(struct e1000_hw *);
s32 (*commit_phy)(struct e1000_hw *);
s32 (*force_speed_duplex)(struct e1000_hw *);
s32 (*get_cfg_done)(struct e1000_hw *hw);
s32 (*get_cable_length)(struct e1000_hw *);
s32 (*get_phy_info)(struct e1000_hw *);
s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *);
void (*release_phy)(struct e1000_hw *);
s32 (*reset_phy)(struct e1000_hw *);
s32 (*set_d0_lplu_state)(struct e1000_hw *, boolean_t);
s32 (*set_d3_lplu_state)(struct e1000_hw *, boolean_t);
s32 (*write_phy_reg)(struct e1000_hw *, u32, u16);
/* Function pointers for the NVM. */
s32 (*init_nvm_params)(struct e1000_hw *);
s32 (*acquire_nvm)(struct e1000_hw *);
s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *);
void (*release_nvm)(struct e1000_hw *);
void (*reload_nvm)(struct e1000_hw *);
s32 (*update_nvm)(struct e1000_hw *);
s32 (*valid_led_default)(struct e1000_hw *, u16 *);
s32 (*validate_nvm)(struct e1000_hw *);
s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *);
};
struct e1000_mac_info {
u8 addr[6];
u8 perm_addr[6];
e1000_mac_type type;
e1000_fc_mode fc;
e1000_fc_mode original_fc;
u32 collision_delta;
u32 ledctl_default;
u32 ledctl_mode1;
u32 ledctl_mode2;
u32 max_frame_size;
u32 mc_filter_type;
u32 min_frame_size;
u32 tx_packet_delta;
u32 txcw;
u16 current_ifs_val;
u16 ifs_max_val;
u16 ifs_min_val;
u16 ifs_ratio;
u16 ifs_step_size;
u16 mta_reg_count;
u16 rar_entry_count;
u16 fc_high_water;
u16 fc_low_water;
u16 fc_pause_time;
u8 forced_speed_duplex;
boolean_t adaptive_ifs;
boolean_t arc_subsystem_valid;
boolean_t asf_firmware_present;
boolean_t autoneg;
boolean_t autoneg_failed;
boolean_t disable_av;
boolean_t disable_hw_init_bits;
boolean_t fc_send_xon;
boolean_t fc_strict_ieee;
boolean_t get_link_status;
boolean_t ifs_params_forced;
boolean_t in_ifs_mode;
boolean_t report_tx_early;
boolean_t serdes_has_link;
boolean_t tx_pkt_filtering;
};
struct e1000_phy_info {
e1000_phy_type type;
e1000_1000t_rx_status local_rx;
e1000_1000t_rx_status remote_rx;
e1000_ms_type ms_type;
e1000_ms_type original_ms_type;
e1000_rev_polarity cable_polarity;
e1000_smart_speed smart_speed;
u32 addr;
u32 id;
u32 reset_delay_us; /* in usec */
u32 revision;
u16 autoneg_advertised;
u16 autoneg_mask;
u16 cable_length;
u16 max_cable_length;
u16 min_cable_length;
u8 mdix;
boolean_t disable_polarity_correction;
boolean_t is_mdix;
boolean_t polarity_correction;
boolean_t reset_disable;
boolean_t speed_downgraded;
boolean_t wait_for_link;
};
struct e1000_nvm_info {
e1000_nvm_type type;
e1000_nvm_override override;
u32 flash_bank_size;
u32 flash_base_addr;
u16 word_size;
u16 delay_usec;
u16 address_bits;
u16 opcode_bits;
u16 page_size;
};
struct e1000_bus_info {
e1000_bus_type type;
e1000_bus_speed speed;
e1000_bus_width width;
u32 snoop;
u16 func;
u16 pci_cmd_word;
};
struct e1000_hw {
void *back;
void *dev_spec;
u8 *hw_addr;
u8 *flash_address;
unsigned long io_base;
struct e1000_functions func;
struct e1000_mac_info mac;
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
struct e1000_host_mng_dhcp_cookie mng_cookie;
e1000_media_type media_type;
u32 dev_spec_size;
u16 device_id;
u16 subsystem_vendor_id;
u16 subsystem_device_id;
u16 vendor_id;
u8 revision_id;
};
/* These functions must be implemented by drivers */
void e1000_pci_clear_mwi(struct e1000_hw *hw);
void e1000_pci_set_mwi(struct e1000_hw *hw);
s32 e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, u32 size);
s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
void e1000_free_dev_spec_struct(struct e1000_hw *hw);
void e1000_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
void e1000_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,115 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_ich8lan.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_ICH8LAN_H_
#define _E1000_ICH8LAN_H_
#define ICH_FLASH_GFPREG 0x0000
#define ICH_FLASH_HSFSTS 0x0004
#define ICH_FLASH_HSFCTL 0x0006
#define ICH_FLASH_FADDR 0x0008
#define ICH_FLASH_FDATA0 0x0010
#define ICH_FLASH_READ_COMMAND_TIMEOUT 500
#define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500
#define ICH_FLASH_ERASE_COMMAND_TIMEOUT 3000000
#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
#define ICH_FLASH_CYCLE_REPEAT_COUNT 10
#define ICH_CYCLE_READ 0
#define ICH_CYCLE_WRITE 2
#define ICH_CYCLE_ERASE 3
#define FLASH_GFPREG_BASE_MASK 0x1FFF
#define FLASH_SECTOR_ADDR_SHIFT 12
#define E1000_SHADOW_RAM_WORDS 2048
#define ICH_FLASH_SEG_SIZE_256 256
#define ICH_FLASH_SEG_SIZE_4K 4096
#define ICH_FLASH_SEG_SIZE_8K 8192
#define ICH_FLASH_SEG_SIZE_64K 65536
#define ICH_FLASH_SECTOR_SIZE 4096
#define ICH_FLASH_REG_MAPSIZE 0x00A0
#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */
#define E1000_ICH_FWSM_DISSW 0x10000000 /* FW Disables SW Writes */
#define E1000_ICH_FWSM_FW_VALID 0x00008000 /* FW established a valid
* mode.
*/
#define E1000_ICH_MNG_IAMT_MODE 0x2
#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_DEF1_OFF2 << 8) | \
(ID_LED_DEF1_ON2 << 4) | \
(ID_LED_DEF1_DEF2))
#define E1000_ICH_NVM_SIG_WORD 0x13
#define E1000_ICH_NVM_SIG_MASK 0xC000
#define E1000_ICH8_LAN_INIT_TIMEOUT 1500
#define E1000_FEXTNVM_SW_CONFIG 1
#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
#define E1000_ICH_RAR_ENTRIES 7
#define PHY_PAGE_SHIFT 5
#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
((reg) & MAX_PHY_REG_ADDRESS))
#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */
#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */
#define IGP3_CAPABILITY PHY_REG(776, 19) /* Capability */
#define IGP3_PM_CTRL PHY_REG(769, 20) /* Power Management Control */
#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002
#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200
#define IGP3_PM_CTRL_FORCE_PWR_DOWN 0x0020
/* Additional interrupts need to be handled for ICH family:
DSW = The FW changed the status of the DISSW bit in FWSM
PHYINT = The LAN connected device generates an interrupt
EPRST = Manageability reset event */
#define IMS_ICH_ENABLE_MASK (\
E1000_IMS_DSW | \
E1000_IMS_PHYINT | \
E1000_IMS_EPRST)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,91 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_mac.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_MAC_H_
#define _E1000_MAC_H_
/* Functions that should not be called directly from drivers but can be used
* by other files in this 'shared code'
*/
s32 e1000_blink_led_generic(struct e1000_hw *hw);
s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw);
s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw);
s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw);
s32 e1000_cleanup_led_generic(struct e1000_hw *hw);
s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw);
s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw);
s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw);
s32 e1000_force_mac_fc_generic(struct e1000_hw *hw);
s32 e1000_get_auto_rd_done_generic(struct e1000_hw *hw);
s32 e1000_get_bus_info_pci_generic(struct e1000_hw *hw);
s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw);
s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw);
s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
u16 *duplex);
s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
u16 *speed, u16 *duplex);
s32 e1000_id_led_init_generic(struct e1000_hw *hw);
s32 e1000_led_on_generic(struct e1000_hw *hw);
s32 e1000_led_off_generic(struct e1000_hw *hw);
void e1000_mc_addr_list_update_generic(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count);
s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw);
s32 e1000_set_default_fc_generic(struct e1000_hw *hw);
s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw);
s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw);
s32 e1000_setup_led_generic(struct e1000_hw *hw);
s32 e1000_setup_link_generic(struct e1000_hw *hw);
s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw);
s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data);
u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr);
void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw);
void e1000_clear_vfta_generic(struct e1000_hw *hw);
void e1000_config_collision_dist_generic(struct e1000_hw *hw);
void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count);
void e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value);
void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw);
void e1000_put_hw_semaphore_generic(struct e1000_hw *hw);
void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
void e1000_remove_device_generic(struct e1000_hw *hw);
void e1000_reset_adaptive_generic(struct e1000_hw *hw);
void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop);
void e1000_update_adaptive_generic(struct e1000_hw *hw);
void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
#endif

View File

@ -0,0 +1,392 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_manage.c,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#include "e1000_api.h"
#include "e1000_manage.h"
static u8 e1000_calculate_checksum(u8 *buffer, u32 length);
/**
* e1000_calculate_checksum - Calculate checksum for buffer
* @buffer: pointer to EEPROM
* @length: size of EEPROM to calculate a checksum for
*
* Calculates the checksum for some buffer on a specified length. The
* checksum calculated is returned.
**/
static u8
e1000_calculate_checksum(u8 *buffer, u32 length)
{
u32 i;
u8 sum = 0;
DEBUGFUNC("e1000_calculate_checksum");
if (!buffer)
return 0;
for (i = 0; i < length; i++)
sum += buffer[i];
return (u8) (0 - sum);
}
/**
* e1000_mng_enable_host_if_generic - Checks host interface is enabled
* @hw: pointer to the HW structure
*
* Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
*
* This function checks whether the HOST IF is enabled for command operaton
* and also checks whether the previous command is completed. It busy waits
* in case of previous command is not completed.
**/
s32
e1000_mng_enable_host_if_generic(struct e1000_hw * hw)
{
u32 hicr;
s32 ret_val = E1000_SUCCESS;
u8 i;
DEBUGFUNC("e1000_mng_enable_host_if_generic");
/* Check that the host interface is enabled. */
hicr = E1000_READ_REG(hw, E1000_HICR);
if ((hicr & E1000_HICR_EN) == 0) {
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
}
/* check the previous command is completed */
for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
hicr = E1000_READ_REG(hw, E1000_HICR);
if (!(hicr & E1000_HICR_C))
break;
msec_delay_irq(1);
}
if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
DEBUGOUT("Previous command timeout failed .\n");
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
goto out;
}
out:
return ret_val;
}
/**
* e1000_check_mng_mode_generic - Generic check managament mode
* @hw: pointer to the HW structure
*
* Reads the firmware semaphore register and returns true (>0) if
* manageability is enabled, else false (0).
**/
boolean_t
e1000_check_mng_mode_generic(struct e1000_hw *hw)
{
u32 fwsm;
DEBUGFUNC("e1000_check_mng_mode_generic");
fwsm = E1000_READ_REG(hw, E1000_FWSM);
return ((fwsm & E1000_FWSM_MODE_MASK) ==
(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT));
}
/**
* e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on TX
* @hw: pointer to the HW structure
*
* Enables packet filtering on transmit packets if manageability is enabled
* and host interface is enabled.
**/
boolean_t
e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
{
struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie;
u32 *buffer = (u32 *)&hw->mng_cookie;
u32 offset;
s32 ret_val, hdr_csum, csum;
u8 i, len;
boolean_t tx_filter = TRUE;
DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic");
/* No manageability, no filtering */
if (!e1000_check_mng_mode(hw)) {
tx_filter = FALSE;
goto out;
}
/* If we can't read from the host interface for whatever
* reason, disable filtering.
*/
ret_val = e1000_mng_enable_host_if(hw);
if (ret_val != E1000_SUCCESS) {
tx_filter = FALSE;
goto out;
}
/* Read in the header. Length and offset are in dwords. */
len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2;
offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
for (i = 0; i < len; i++) {
*(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
E1000_HOST_IF,
offset + i);
}
hdr_csum = hdr->checksum;
hdr->checksum = 0;
csum = e1000_calculate_checksum((u8 *)hdr,
E1000_MNG_DHCP_COOKIE_LENGTH);
/* If either the checksums or signature don't match, then
* the cookie area isn't considered valid, in which case we
* take the safe route of assuming Tx filtering is enabled.
*/
if (hdr_csum != csum)
goto out;
if (hdr->signature != E1000_IAMT_SIGNATURE)
goto out;
/* Cookie area is valid, make the final check for filtering. */
if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
tx_filter = FALSE;
out:
hw->mac.tx_pkt_filtering = tx_filter;
return tx_filter;
}
/**
* e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface
* @length: size of the buffer
*
* Writes the DHCP information to the host interface.
**/
s32
e1000_mng_write_dhcp_info_generic(struct e1000_hw * hw, u8 *buffer, u16 length)
{
struct e1000_host_mng_command_header hdr;
s32 ret_val;
u32 hicr;
DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
hdr.command_length = length;
hdr.reserved1 = 0;
hdr.reserved2 = 0;
hdr.checksum = 0;
/* Enable the host interface */
ret_val = e1000_mng_enable_host_if(hw);
if (ret_val)
goto out;
/* Populate the host interface with the contents of "buffer". */
ret_val = e1000_mng_host_if_write(hw, buffer, length,
sizeof(hdr), &(hdr.checksum));
if (ret_val)
goto out;
/* Write the manageability command header */
ret_val = e1000_mng_write_cmd_header(hw, &hdr);
if (ret_val)
goto out;
/* Tell the ARC a new command is pending. */
hicr = E1000_READ_REG(hw, E1000_HICR);
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
out:
return ret_val;
}
/**
* e1000_mng_write_cmd_header_generic - Writes manageability command header
* @hw: pointer to the HW structure
* @hdr: pointer to the host interface command header
*
* Writes the command header after does the checksum calculation.
**/
s32
e1000_mng_write_cmd_header_generic(struct e1000_hw * hw,
struct e1000_host_mng_command_header * hdr)
{
u16 i, length = sizeof(struct e1000_host_mng_command_header);
DEBUGFUNC("e1000_mng_write_cmd_header_generic");
/* Write the whole command header structure with new checksum. */
hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length);
length >>= 2;
/* Write the relevant command block into the ram area. */
for (i = 0; i < length; i++) {
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i, *((u32 *) hdr + i));
E1000_WRITE_FLUSH(hw);
}
return E1000_SUCCESS;
}
/**
* e1000_mng_host_if_write_generic - Writes to the manageability host interface
* @hw: pointer to the HW structure
* @buffer: pointer to the host interface buffer
* @length: size of the buffer
* @offset: location in the buffer to write to
* @sum: sum of the data (not checksum)
*
* This function writes the buffer content at the offset given on the host if.
* It also does alignment considerations to do the writes in most efficient
* way. Also fills up the sum of the buffer in *buffer parameter.
**/
s32
e1000_mng_host_if_write_generic(struct e1000_hw * hw, u8 *buffer, u16 length,
u16 offset, u8 *sum)
{
u8 *tmp;
u8 *bufptr = buffer;
u32 data = 0;
s32 ret_val = E1000_SUCCESS;
u16 remaining, i, j, prev_bytes;
DEBUGFUNC("e1000_mng_host_if_write_generic");
/* sum = only sum of the data and it is not checksum */
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
ret_val = -E1000_ERR_PARAM;
goto out;
}
tmp = (u8 *)&data;
prev_bytes = offset & 0x3;
offset >>= 2;
if (prev_bytes) {
data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset);
for (j = prev_bytes; j < sizeof(u32); j++) {
*(tmp + j) = *bufptr++;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset, data);
length -= j - prev_bytes;
offset++;
}
remaining = length & 0x3;
length -= remaining;
/* Calculate length in DWORDs */
length >>= 2;
/* The device driver writes the relevant command block into the
* ram area. */
for (i = 0; i < length; i++) {
for (j = 0; j < sizeof(u32); j++) {
*(tmp + j) = *bufptr++;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
}
if (remaining) {
for (j = 0; j < sizeof(u32); j++) {
if (j < remaining)
*(tmp + j) = *bufptr++;
else
*(tmp + j) = 0;
*sum += *(tmp + j);
}
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
}
out:
return ret_val;
}
/**
* e1000_enable_mng_pass_thru - Enable processing of ARP's
* @hw: pointer to the HW structure
*
* Verifies the hardware needs to allow ARPs to be processed by the host.
**/
boolean_t
e1000_enable_mng_pass_thru(struct e1000_hw *hw)
{
u32 manc;
u32 fwsm, factps;
boolean_t ret_val = FALSE;
DEBUGFUNC("e1000_enable_mng_pass_thru");
if (!hw->mac.asf_firmware_present)
goto out;
manc = E1000_READ_REG(hw, E1000_MANC);
if (!(manc & E1000_MANC_RCV_TCO_EN) ||
!(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
goto out;
if (hw->mac.arc_subsystem_valid == TRUE) {
fwsm = E1000_READ_REG(hw, E1000_FWSM);
factps = E1000_READ_REG(hw, E1000_FACTPS);
if (!(factps & E1000_FACTPS_MNGCG) &&
((fwsm & E1000_FWSM_MODE_MASK) ==
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
ret_val = TRUE;
goto out;
}
} else
if ((manc & E1000_MANC_SMBUS_EN) &&
!(manc & E1000_MANC_ASF_EN)) {
ret_val = TRUE;
goto out;
}
out:
return ret_val;
}

View File

@ -0,0 +1,88 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_manage.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_MANAGE_H_
#define _E1000_MANAGE_H_
boolean_t e1000_check_mng_mode_generic(struct e1000_hw *hw);
boolean_t e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw);
s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw);
s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
u16 length, u16 offset, u8 *sum);
s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr);
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw,
u8 *buffer, u16 length);
typedef enum {
e1000_mng_mode_none = 0,
e1000_mng_mode_asf,
e1000_mng_mode_pt,
e1000_mng_mode_ipmi,
e1000_mng_mode_host_if_only
} e1000_mng_mode;
#define E1000_FACTPS_MNGCG 0x20000000
#define E1000_FWSM_MODE_MASK 0xE
#define E1000_FWSM_MODE_SHIFT 1
#define E1000_MNG_IAMT_MODE 0x3
#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10
#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0
#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
#define E1000_VFTA_ENTRY_SHIFT 5
#define E1000_VFTA_ENTRY_MASK 0x7F
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Number of bytes in range */
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Number of dwords in range */
#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */
#define E1000_HICR_EN 0x01 /* Enable bit - RO */
#define E1000_HICR_C 0x02 /* Driver sets this bit when done
* to put command in RAM */
#define E1000_HICR_SV 0x04 /* Status Validity */
#define E1000_HICR_FW_RESET_ENABLE 0x40
#define E1000_HICR_FW_RESET 0x80
#define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management
* Technology signature */
#endif

View File

@ -0,0 +1,901 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_nvm.c,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#include "e1000_api.h"
#include "e1000_nvm.h"
/**
* e1000_raise_eec_clk - Raise EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Enable/Raise the EEPROM clock bit.
**/
static void
e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd | E1000_EECD_SK;
E1000_WRITE_REG(hw, E1000_EECD, *eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(hw->nvm.delay_usec);
}
/**
* e1000_lower_eec_clk - Lower EEPROM clock
* @hw: pointer to the HW structure
* @eecd: pointer to the EEPROM
*
* Clear/Lower the EEPROM clock bit.
**/
static void
e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
{
*eecd = *eecd & ~E1000_EECD_SK;
E1000_WRITE_REG(hw, E1000_EECD, *eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(hw->nvm.delay_usec);
}
/**
* e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
* @hw: pointer to the HW structure
* @data: data to send to the EEPROM
* @count: number of bits to shift out
*
* We need to shift 'count' bits out to the EEPROM. So, the value in the
* "data" parameter will be shifted out to the EEPROM one bit at a time.
* In order to do this, "data" must be broken down into bits.
**/
static void
e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
u32 mask;
DEBUGFUNC("e1000_shift_out_eec_bits");
mask = 0x01 << (count - 1);
if (nvm->type == e1000_nvm_eeprom_microwire)
eecd &= ~E1000_EECD_DO;
else if (nvm->type == e1000_nvm_eeprom_spi)
eecd |= E1000_EECD_DO;
do {
eecd &= ~E1000_EECD_DI;
if (data & mask)
eecd |= E1000_EECD_DI;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(nvm->delay_usec);
e1000_raise_eec_clk(hw, &eecd);
e1000_lower_eec_clk(hw, &eecd);
mask >>= 1;
} while (mask);
eecd &= ~E1000_EECD_DI;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
}
/**
* e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
* @hw: pointer to the HW structure
* @count: number of bits to shift in
*
* In order to read a register from the EEPROM, we need to shift 'count' bits
* in from the EEPROM. Bits are "shifted in" by raising the clock input to
* the EEPROM (setting the SK bit), and then reading the value of the data out
* "DO" bit. During this "shifting in" process the data in "DI" bit should
* always be clear.
**/
static u16
e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
{
u32 eecd;
u32 i;
u16 data;
DEBUGFUNC("e1000_shift_in_eec_bits");
eecd = E1000_READ_REG(hw, E1000_EECD);
eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
data = 0;
for (i = 0; i < count; i++) {
data <<= 1;
e1000_raise_eec_clk(hw, &eecd);
eecd = E1000_READ_REG(hw, E1000_EECD);
eecd &= ~E1000_EECD_DI;
if (eecd & E1000_EECD_DO)
data |= 1;
e1000_lower_eec_clk(hw, &eecd);
}
return data;
}
/**
* e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion
* @hw: pointer to the HW structure
* @ee_reg: EEPROM flag for polling
*
* Polls the EEPROM status bit for either read or write completion based
* upon the value of 'ee_reg'.
**/
s32
e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
{
u32 attempts = 100000;
u32 i, reg = 0;
s32 ret_val = -E1000_ERR_NVM;
DEBUGFUNC("e1000_poll_eerd_eewr_done");
for (i = 0; i < attempts; i++) {
if (ee_reg == E1000_NVM_POLL_READ)
reg = E1000_READ_REG(hw, E1000_EERD);
else
reg = E1000_READ_REG(hw, E1000_EEWR);
if (reg & E1000_NVM_RW_REG_DONE) {
ret_val = E1000_SUCCESS;
break;
}
usec_delay(5);
}
return ret_val;
}
/**
* e1000_acquire_nvm_generic - Generic request for access to EEPROM
* @hw: pointer to the HW structure
*
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
* Return successful if access grant bit set, else clear the request for
* EEPROM access and return -E1000_ERR_NVM (-1).
**/
s32
e1000_acquire_nvm_generic(struct e1000_hw *hw)
{
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_acquire_nvm_generic");
E1000_WRITE_REG(hw, E1000_EECD, eecd | E1000_EECD_REQ);
eecd = E1000_READ_REG(hw, E1000_EECD);
while (timeout) {
if (eecd & E1000_EECD_GNT)
break;
usec_delay(5);
eecd = E1000_READ_REG(hw, E1000_EECD);
timeout--;
}
if (!timeout) {
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
DEBUGOUT("Could not acquire NVM grant\n");
ret_val = -E1000_ERR_NVM;
}
return ret_val;
}
/**
* e1000_standby_nvm - Return EEPROM to standby state
* @hw: pointer to the HW structure
*
* Return the EEPROM to a standby state.
**/
static void
e1000_standby_nvm(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
DEBUGFUNC("e1000_standby_nvm");
if (nvm->type == e1000_nvm_eeprom_microwire) {
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(nvm->delay_usec);
e1000_raise_eec_clk(hw, &eecd);
/* Select EEPROM */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(nvm->delay_usec);
e1000_lower_eec_clk(hw, &eecd);
} else if (nvm->type == e1000_nvm_eeprom_spi) {
/* Toggle CS to flush commands */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(nvm->delay_usec);
eecd &= ~E1000_EECD_CS;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
E1000_WRITE_FLUSH(hw);
usec_delay(nvm->delay_usec);
}
}
/**
* e1000_stop_nvm - Terminate EEPROM command
* @hw: pointer to the HW structure
*
* Terminates the current command by inverting the EEPROM's chip select pin.
**/
void
e1000_stop_nvm(struct e1000_hw *hw)
{
u32 eecd;
DEBUGFUNC("e1000_stop_nvm");
eecd = E1000_READ_REG(hw, E1000_EECD);
if (hw->nvm.type == e1000_nvm_eeprom_spi) {
/* Pull CS high */
eecd |= E1000_EECD_CS;
e1000_lower_eec_clk(hw, &eecd);
} else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
/* CS on Microcwire is active-high */
eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
e1000_raise_eec_clk(hw, &eecd);
e1000_lower_eec_clk(hw, &eecd);
}
}
/**
* e1000_release_nvm_generic - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* Stop any current commands to the EEPROM and clear the EEPROM request bit.
**/
void
e1000_release_nvm_generic(struct e1000_hw *hw)
{
u32 eecd;
DEBUGFUNC("e1000_release_nvm_generic");
e1000_stop_nvm(hw);
eecd = E1000_READ_REG(hw, E1000_EECD);
eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
}
/**
* e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
* @hw: pointer to the HW structure
*
* Setups the EEPROM for reading and writing.
**/
static s32
e1000_ready_nvm_eeprom(struct e1000_hw *hw)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = E1000_READ_REG(hw, E1000_EECD);
s32 ret_val = E1000_SUCCESS;
u16 timeout = 0;
u8 spi_stat_reg;
DEBUGFUNC("e1000_ready_nvm_eeprom");
if (nvm->type == e1000_nvm_eeprom_microwire) {
/* Clear SK and DI */
eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
/* Set CS */
eecd |= E1000_EECD_CS;
E1000_WRITE_REG(hw, E1000_EECD, eecd);
} else if (nvm->type == e1000_nvm_eeprom_spi) {
/* Clear SK and CS */
eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
usec_delay(1);
timeout = NVM_MAX_RETRY_SPI;
/* Read "Status Register" repeatedly until the LSB is cleared.
* The EEPROM will signal that the command has been completed
* by clearing bit 0 of the internal status register. If it's
* not cleared within 'timeout', then error out. */
while (timeout) {
e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
hw->nvm.opcode_bits);
spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
break;
usec_delay(5);
e1000_standby_nvm(hw);
timeout--;
}
if (!timeout) {
DEBUGOUT("SPI NVM Status error\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
}
out:
return ret_val;
}
/**
* e1000_read_nvm_spi - Read EEPROM's using SPI
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM.
**/
s32
e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i = 0;
s32 ret_val;
u16 word_in;
u8 read_opcode = NVM_READ_OPCODE_SPI;
DEBUGFUNC("e1000_read_nvm_spi");
/* A check for invalid values: offset too large, too many words,
* and not enough words. */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = e1000_acquire_nvm(hw);
if (ret_val)
goto out;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
e1000_standby_nvm(hw);
if ((nvm->address_bits == 8) && (offset >= 128))
read_opcode |= NVM_A8_OPCODE_SPI;
/* Send the READ command (opcode + addr) */
e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
/* Read the data. SPI NVMs increment the address with each byte
* read and will roll over if reading beyond the end. This allows
* us to read the whole NVM from any offset */
for (i = 0; i < words; i++) {
word_in = e1000_shift_in_eec_bits(hw, 16);
data[i] = (word_in >> 8) | (word_in << 8);
}
release:
e1000_release_nvm(hw);
out:
return ret_val;
}
/**
* e1000_read_nvm_microwire - Reads EEPROM's using microwire
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM.
**/
s32
e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i = 0;
s32 ret_val;
u8 read_opcode = NVM_READ_OPCODE_MICROWIRE;
DEBUGFUNC("e1000_read_nvm_microwire");
/* A check for invalid values: offset too large, too many words,
* and not enough words. */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = e1000_acquire_nvm(hw);
if (ret_val)
goto out;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
for (i = 0; i < words; i++) {
/* Send the READ command (opcode + addr) */
e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)(offset + i),
nvm->address_bits);
/* Read the data. For microwire, each word requires the
* overhead of setup and tear-down. */
data[i] = e1000_shift_in_eec_bits(hw, 16);
e1000_standby_nvm(hw);
}
release:
e1000_release_nvm(hw);
out:
return ret_val;
}
/**
* e1000_read_nvm_eerd - Reads EEPROM using EERD register
* @hw: pointer to the HW structure
* @offset: offset of word in the EEPROM to read
* @words: number of words to read
* @data: word read from the EEPROM
*
* Reads a 16 bit word from the EEPROM using the EERD register.
**/
s32
e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, eerd = 0;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_nvm_eerd");
/* A check for invalid values: offset too large, too many words,
* and not enough words. */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
for (i = 0; i < words; i++) {
eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
E1000_NVM_RW_REG_START;
E1000_WRITE_REG(hw, E1000_EERD, eerd);
ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
if (ret_val)
break;
data[i] = (E1000_READ_REG(hw, E1000_EERD) >> E1000_NVM_RW_REG_DATA);
}
out:
return ret_val;
}
/**
* e1000_write_nvm_spi - Write to EEPROM using SPI
* @hw: pointer to the HW structure
* @offset: offset within the EEPROM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the EEPROM
*
* Writes data to EEPROM at offset using SPI interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
* EEPROM will most likley contain an invalid checksum.
**/
s32
e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val;
u16 widx = 0;
DEBUGFUNC("e1000_write_nvm_spi");
/* A check for invalid values: offset too large, too many words,
* and not enough words. */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = e1000_acquire_nvm(hw);
if (ret_val)
goto out;
msec_delay(10);
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
e1000_standby_nvm(hw);
/* Send the WRITE ENABLE command (8 bit opcode) */
e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
nvm->opcode_bits);
e1000_standby_nvm(hw);
/* Some SPI eeproms use the 8th address bit embedded in the
* opcode */
if ((nvm->address_bits == 8) && (offset >= 128))
write_opcode |= NVM_A8_OPCODE_SPI;
/* Send the Write command (8-bit opcode + addr) */
e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
nvm->address_bits);
/* Loop to allow for up to whole page write of eeprom */
while (widx < words) {
u16 word_out = data[widx];
word_out = (word_out >> 8) | (word_out << 8);
e1000_shift_out_eec_bits(hw, word_out, 16);
widx++;
if ((((offset + widx) * 2) % nvm->page_size) == 0) {
e1000_standby_nvm(hw);
break;
}
}
}
msec_delay(10);
release:
e1000_release_nvm(hw);
out:
return ret_val;
}
/**
* e1000_write_nvm_microwire - Writes EEPROM using microwire
* @hw: pointer to the HW structure
* @offset: offset within the EEPROM to be written to
* @words: number of words to write
* @data: 16 bit word(s) to be written to the EEPROM
*
* Writes data to EEPROM at offset using microwire interface.
*
* If e1000_update_nvm_checksum is not called after this function , the
* EEPROM will most likley contain an invalid checksum.
**/
s32
e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{
struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val;
u32 eecd;
u16 words_written = 0;
u16 widx = 0;
DEBUGFUNC("e1000_write_nvm_microwire");
/* A check for invalid values: offset too large, too many words,
* and not enough words. */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
ret_val = e1000_acquire_nvm(hw);
if (ret_val)
goto out;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val)
goto release;
e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE,
(u16)(nvm->opcode_bits + 2));
e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
e1000_standby_nvm(hw);
while (words_written < words) {
e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE,
nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)(offset + words_written),
nvm->address_bits);
e1000_shift_out_eec_bits(hw, data[words_written], 16);
e1000_standby_nvm(hw);
for (widx = 0; widx < 200; widx++) {
eecd = E1000_READ_REG(hw, E1000_EECD);
if (eecd & E1000_EECD_DO)
break;
usec_delay(50);
}
if (widx == 200) {
DEBUGOUT("NVM Write did not complete\n");
ret_val = -E1000_ERR_NVM;
goto release;
}
e1000_standby_nvm(hw);
words_written++;
}
e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE,
(u16)(nvm->opcode_bits + 2));
e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
release:
e1000_release_nvm(hw);
out:
return ret_val;
}
/**
* e1000_read_part_num_generic - Read device part number
* @hw: pointer to the HW structure
* @part_num: pointer to device part number
*
* Reads the product board assembly (PBA) number from the EEPROM and stores
* the value in part_num.
**/
s32
e1000_read_part_num_generic(struct e1000_hw *hw, u32 *part_num)
{
s32 ret_val;
u16 nvm_data;
DEBUGFUNC("e1000_read_part_num_generic");
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
*part_num = (u32)(nvm_data << 16);
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
*part_num |= nvm_data;
out:
return ret_val;
}
/**
* e1000_read_mac_addr_generic - Read device MAC address
* @hw: pointer to the HW structure
*
* Reads the device MAC address from the EEPROM and stores the value.
* Since devices with two ports use the same EEPROM, we increment the
* last bit in the MAC address for the second port.
**/
s32
e1000_read_mac_addr_generic(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 offset, nvm_data, i;
DEBUGFUNC("e1000_read_mac_addr");
for (i = 0; i < ETH_ADDR_LEN; i += 2) {
offset = i >> 1;
ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
}
/* Flip last bit of mac address if we're on second port */
if (hw->bus.func == E1000_FUNC_1)
hw->mac.perm_addr[5] ^= 1;
for (i = 0; i < ETH_ADDR_LEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
out:
return ret_val;
}
/**
* e1000_validate_nvm_checksum_generic - Validate EEPROM checksum
* @hw: pointer to the HW structure
*
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
s32
e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
{
s32 ret_val = E1000_SUCCESS;
u16 checksum = 0;
u16 i, nvm_data;
DEBUGFUNC("e1000_validate_nvm_checksum_generic");
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error\n");
goto out;
}
checksum += nvm_data;
}
if (checksum != (u16) NVM_SUM) {
DEBUGOUT("NVM Checksum Invalid\n");
ret_val = -E1000_ERR_NVM;
goto out;
}
out:
return ret_val;
}
/**
* e1000_update_nvm_checksum_generic - Update EEPROM checksum
* @hw: pointer to the HW structure
*
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
* up to the checksum. Then calculates the EEPROM checksum and writes the
* value to the EEPROM.
**/
s32
e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
{
s32 ret_val;
u16 checksum = 0;
u16 i, nvm_data;
DEBUGFUNC("e1000_update_nvm_checksum");
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
if (ret_val) {
DEBUGOUT("NVM Read Error while updating checksum.\n");
goto out;
}
checksum += nvm_data;
}
checksum = (u16) NVM_SUM - checksum;
ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum);
if (ret_val) {
DEBUGOUT("NVM Write Error while updating checksum.\n");
}
out:
return ret_val;
}
/**
* e1000_reload_nvm_generic - Reloads EEPROM
* @hw: pointer to the HW structure
*
* Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
* extended control register.
**/
void
e1000_reload_nvm_generic(struct e1000_hw *hw)
{
u32 ctrl_ext;
DEBUGFUNC("e1000_reload_nvm_generic");
usec_delay(10);
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
ctrl_ext |= E1000_CTRL_EXT_EE_RST;
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
E1000_WRITE_FLUSH(hw);
}
/* Function pointers local to this file and not intended for public use */
/**
* e1000_acquire_nvm - Acquire exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* For those silicon families which have implemented a NVM acquire function,
* run the defined function else return success.
**/
s32
e1000_acquire_nvm(struct e1000_hw *hw)
{
if (hw->func.acquire_nvm != NULL)
return hw->func.acquire_nvm(hw);
else
return E1000_SUCCESS;
}
/**
* e1000_release_nvm - Release exclusive access to EEPROM
* @hw: pointer to the HW structure
*
* For those silicon families which have implemented a NVM release function,
* run the defined fucntion else return success.
**/
void
e1000_release_nvm(struct e1000_hw *hw)
{
if (hw->func.release_nvm != NULL)
hw->func.release_nvm(hw);
}

View File

@ -0,0 +1,66 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_nvm.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_NVM_H_
#define _E1000_NVM_H_
s32 e1000_acquire_nvm_generic(struct e1000_hw *hw);
s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg);
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
s32 e1000_read_part_num_generic(struct e1000_hw *hw, u32 *part_num);
s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data);
s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw);
s32 e1000_write_nvm_eewr(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw);
void e1000_stop_nvm(struct e1000_hw *hw);
void e1000_release_nvm_generic(struct e1000_hw *hw);
void e1000_reload_nvm_generic(struct e1000_hw *hw);
/* Function pointers */
s32 e1000_acquire_nvm(struct e1000_hw *hw);
void e1000_release_nvm(struct e1000_hw *hw);
#define E1000_STM_OPCODE 0xDB00
#endif

View File

@ -1,6 +1,6 @@
/**************************************************************************
Copyright (c) 2001-2006, Intel Corporation
Copyright (c) 2001-2007, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -30,8 +30,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
/*$FreeBSD: src/sys/dev/em/e1000_osdep.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
/*$FreeBSD: src/sys/dev/em/if_em_osdep.h,v 1.14.2.3 2006/10/28 01:37:14 jfv Exp $*/
#ifndef _FREEBSD_OS_H_
#define _FREEBSD_OS_H_
@ -65,26 +65,32 @@ POSSIBILITY OF SUCH DAMAGE.
#define MSGOUT(S, A, B) printf(S "\n", A, B)
#define DEBUGFUNC(F) DEBUGOUT(F);
#if DBG
#define DEBUGOUT(S) printf(S "\n")
#define DEBUGOUT1(S,A) printf(S "\n",A)
#define DEBUGOUT2(S,A,B) printf(S "\n",A,B)
#define DEBUGOUT3(S,A,B,C) printf(S "\n",A,B,C)
#define DEBUGOUT7(S,A,B,C,D,E,F,G) printf(S "\n",A,B,C,D,E,F,G)
#else
#define DEBUGOUT(S)
#define DEBUGOUT1(S,A)
#define DEBUGOUT2(S,A,B)
#define DEBUGOUT3(S,A,B,C)
#define DEBUGOUT7(S,A,B,C,D,E,F,G)
#endif
#define STATIC static
#define FALSE 0
#define TRUE 1
#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */
#define PCI_COMMAND_REGISTER PCIR_COMMAND
struct em_osdep
/*
** These typedefs are necessary due to the new
** shared code, they are native to Linux.
*/
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
struct e1000_osdep
{
bus_space_tag_t mem_bus_space_tag;
bus_space_handle_t mem_bus_space_handle;
@ -95,77 +101,88 @@ struct em_osdep
struct device *dev;
};
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
#ifdef NO_82542_SUPPORT
#define E1000_REGISTER(hw, reg) reg
#else
#define E1000_REGISTER(hw, reg) (((hw)->mac.type >= e1000_82543) \
? reg : e1000_translate_register_82542(reg))
#endif
#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, E1000_STATUS)
/* Read from an absolute offset in the adapter's memory space */
#define E1000_READ_OFFSET(hw, offset) \
bus_space_read_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, offset)
bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, offset)
/* Write to an absolute offset in the adapter's memory space */
#define E1000_WRITE_OFFSET(hw, offset, value) \
bus_space_write_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, offset, value)
/* Convert a register name to its offset in the adapter's memory space */
#define E1000_REG_OFFSET(hw, reg) \
((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg)
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, offset, value)
/* Register READ/WRITE macros */
#define E1000_READ_REG(hw, reg) \
bus_space_read_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg))
bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg))
#define E1000_WRITE_REG(hw, reg, value) \
bus_space_write_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg), \
value)
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg), value)
#define E1000_READ_REG_ARRAY(hw, reg, index) \
bus_space_read_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg) \
+ ((index) << 2))
bus_space_read_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg) + ((index)<< 2))
#define E1000_WRITE_REG_ARRAY(hw, reg, index, value) \
bus_space_write_4(((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg) \
+ ((index) << 2), value)
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg) + ((index)<< 2), value)
#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
#define E1000_READ_REG_ARRAY_BYTE(hw, reg, index) \
bus_space_read_1(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg) + index)
#define E1000_WRITE_REG_ARRAY_BYTE(hw, reg, index, value) \
bus_space_write_1( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg \
+ index), value)
bus_space_write_1(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg) + index, value)
#define E1000_WRITE_REG_ARRAY_WORD(hw, reg, index, value) \
bus_space_write_2( ((struct em_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct em_osdep *)(hw)->back)->mem_bus_space_handle, \
((hw)->mac_type >= em_82543 ? E1000_##reg : E1000_82542_##reg \
+ (index << 1)), value)
bus_space_write_2(((struct e1000_osdep *)(hw)->back)->mem_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->mem_bus_space_handle, \
E1000_REGISTER(hw, reg) + (index << 1), value)
#define E1000_READ_ICH_FLASH_REG(hw, reg) \
bus_space_read_4(((struct em_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct em_osdep *)(hw)->back)->flash_bus_space_handle, reg)
#define E1000_WRITE_REG_IO(hw, reg, value) do {\
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->io_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->io_bus_space_handle, \
(hw)->io_base, reg); \
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->io_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->io_bus_space_handle, \
(hw)->io_base + 4, value); } while (0)
#define E1000_READ_ICH_FLASH_REG16(hw, reg) \
bus_space_read_2(((struct em_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct em_osdep *)(hw)->back)->flash_bus_space_handle, reg)
#define E1000_READ_FLASH_REG(hw, reg) \
bus_space_read_4(((struct e1000_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg)
#define E1000_WRITE_ICH_FLASH_REG(hw, reg, value) \
bus_space_write_4(((struct em_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct em_osdep *)(hw)->back)->flash_bus_space_handle, reg, value)
#define E1000_READ_FLASH_REG16(hw, reg) \
bus_space_read_2(((struct e1000_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg)
#define E1000_WRITE_ICH_FLASH_REG16(hw, reg, value) \
bus_space_write_2(((struct em_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct em_osdep *)(hw)->back)->flash_bus_space_handle, reg, value)
#define E1000_WRITE_FLASH_REG(hw, reg, value) \
bus_space_write_4(((struct e1000_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg, value)
#define E1000_WRITE_FLASH_REG16(hw, reg, value) \
bus_space_write_2(((struct e1000_osdep *)(hw)->back)->flash_bus_space_tag, \
((struct e1000_osdep *)(hw)->back)->flash_bus_space_handle, reg, value)
#endif /* _FREEBSD_OS_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,177 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_phy.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_PHY_H_
#define _E1000_PHY_H_
typedef enum {
e1000_ms_hw_default = 0,
e1000_ms_force_master,
e1000_ms_force_slave,
e1000_ms_auto
} e1000_ms_type;
typedef enum {
e1000_smart_speed_default = 0,
e1000_smart_speed_on,
e1000_smart_speed_off
} e1000_smart_speed;
s32 e1000_check_downshift_generic(struct e1000_hw *hw);
s32 e1000_check_polarity_m88(struct e1000_hw *hw);
s32 e1000_check_polarity_igp(struct e1000_hw *hw);
s32 e1000_check_reset_block_generic(struct e1000_hw *hw);
s32 e1000_copper_link_autoneg(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
s32 e1000_copper_link_setup_igp(struct e1000_hw *hw);
s32 e1000_copper_link_setup_m88(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw);
s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw);
s32 e1000_get_cable_length_m88(struct e1000_hw *hw);
s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw);
s32 e1000_get_cfg_done_generic(struct e1000_hw *hw);
s32 e1000_get_phy_id(struct e1000_hw *hw);
s32 e1000_get_phy_info_igp(struct e1000_hw *hw);
s32 e1000_get_phy_info_m88(struct e1000_hw *hw);
s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw);
void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw);
s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw);
s32 e1000_phy_setup_autoneg(struct e1000_hw *hw);
s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, boolean_t active);
s32 e1000_setup_copper_link_generic(struct e1000_hw *hw);
s32 e1000_wait_autoneg_generic(struct e1000_hw *hw);
s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, boolean_t *success);
s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
#define E1000_MAX_PHY_ADDR 4
/* IGP01E1000 Specific Registers */
#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */
#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */
#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO */
#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality */
#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
#define IGP4_PHY_PAGE_SELECT 22 /* Page Select for IGP 4 */
#define IGP_PAGE_SHIFT 5
#define PHY_REG_MASK 0x1F
#define IGP4_WUC_PAGE 800
#define IGP4_WUC_ADDRESS_OPCODE 0x11
#define IGP4_WUC_DATA_OPCODE 0x12
#define IGP4_WUC_ENABLE_PAGE 769
#define IGP4_WUC_ENABLE_REG 17
#define IGP4_WUC_ENABLE_BIT (1 << 2)
#define IGP4_WUC_HOST_WU_BIT (1 << 4)
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */
#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
#define IGP01E1000_GMII_FLEX_SPD 0x0010 /* Enable flexible speed
* on link-up */
#define IGP01E1000_GMII_SPD 0x0020 /* Enable SPD */
#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */
#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
#define IGP01E1000_PSSR_MDIX 0x0008
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
#define IGP02E1000_PHY_CHANNEL_NUM 4
#define IGP02E1000_PHY_AGC_A 0x11B1
#define IGP02E1000_PHY_AGC_B 0x12B1
#define IGP02E1000_PHY_AGC_C 0x14B1
#define IGP02E1000_PHY_AGC_D 0x18B1
#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */
#define IGP02E1000_AGC_LENGTH_MASK 0x7F
#define IGP02E1000_AGC_RANGE 15
#define IGP03E1000_PHY_MISC_CTRL 0x1B
#define IGP03E1000_PHY_MISC_DUPLEX_MANUAL_SET 0x1000 /* Manually Set Duplex */
#define E1000_CABLE_LENGTH_UNDEFINED 0xFF
#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000
#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16
#define E1000_KMRNCTRLSTA_REN 0x00200000
#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */
#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Control */
#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */
/* IFE PHY Extended Status Control */
#define IFE_PESC_POLARITY_REVERSED 0x0100
/* IFE PHY Special Control */
#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010
#define IFE_PSC_FORCE_POLARITY 0x0020
#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100
/* IFE PHY Special Control and LED Control */
#define IFE_PSCL_PROBE_MODE 0x0020
#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
/* IFE PHY MDIX Control */
#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */
#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto MDI/MDI-X, 0=disable */
#endif

View File

@ -0,0 +1,441 @@
/*******************************************************************************
Copyright (c) 2001-2007, Intel Corporation
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. 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 Intel 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: src/sys/dev/em/e1000_regs.h,v 1.3 2007/05/16 00:14:23 jfv Exp $*/
#ifndef _E1000_REGS_H_
#define _E1000_REGS_H_
#define E1000_CTRL 0x00000 /* Device Control - RW */
#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
#define E1000_STATUS 0x00008 /* Device Status - RO */
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_FLA 0x0001C /* Flash Access - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
#define E1000_RCTL 0x00100 /* RX Control - RW */
#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */
#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */
#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */
#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */
#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */
#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
#define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */
#define E1000_EITR0 0x01680 /* Ext. Int. Throttling Rate Vector 0 - RW */
#define E1000_EITR1 0x01684 /* Ext. Int. Throttling Rate Vector 1 - RW */
#define E1000_EITR2 0x01688 /* Ext. Int. Throttling Rate Vector 2 - RW */
#define E1000_EITR3 0x0168C /* Ext. Int. Throttling Rate Vector 3 - RW */
#define E1000_EITR4 0x01690 /* Ext. Int. Throttling Rate Vector 4 - RW */
#define E1000_EITR5 0x01694 /* Ext. Int. Throttling Rate Vector 5 - RW */
#define E1000_EITR6 0x01698 /* Ext. Int. Throttling Rate Vector 6 - RW */
#define E1000_EITR7 0x0169C /* Ext. Int. Throttling Rate Vector 7 - RW */
#define E1000_EITR8 0x016A0 /* Ext. Int. Throttling Rate Vector 8 - RW */
#define E1000_EITR9 0x016A4 /* Ext. Int. Throttling Rate Vector 9 - RW */
#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */
#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */
#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
#define E1000_TCTL 0x00400 /* TX Control - RW */
#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
#define E1000_TBT 0x00448 /* TX Burst Timer - RW */
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_FLSWCTL 0x01030 /* FLASH control register */
#define E1000_FLSWDATA 0x01034 /* FLASH data register */
#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
#define E1000_I2CCMD 0x01028 /* SFPI2C Command Register - RW */
#define E1000_I2CPARAMS 0x0102C /* SFPI2C Parameters Register - RW */
#define E1000_WDSTP 0x01040 /* Watchdog Setup - RW */
#define E1000_SWDSTS 0x01044 /* SW Device Status - RW */
#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */
#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */
#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
#define E1000_RDFPCQ0 0x02430
#define E1000_RDFPCQ1 0x02434
#define E1000_RDFPCQ2 0x02438
#define E1000_RDFPCQ3 0x0243C
#define E1000_PBRTH 0x02458 /* PB RX Arbitration Threshold - RW */
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
#define E1000_SRRCTL0 0x0280C
#define E1000_SRRCTL(_n) (0x280C + (_n << 8)) /* Split and Replication
* RX Control - RW */
#define E1000_RDPUMB 0x025CC /* DMA RX Descriptor uC Mailbox - RW */
#define E1000_RDPUAD 0x025D0 /* DMA RX Descriptor uC Addr Command - RW */
#define E1000_RDPUWD 0x025D4 /* DMA RX Descriptor uC Data Write - RW */
#define E1000_RDPURD 0x025D8 /* DMA RX Descriptor uC Data Read - RW */
#define E1000_RDPUCTL 0x025DC /* DMA RX Descriptor uC Control - RW */
#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */
#define E1000_RDBAL0 E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
#define E1000_RDBAH0 E1000_RDBAH /* RX Desc Base Address High (0) - RW */
#define E1000_RDLEN0 E1000_RDLEN /* RX Desc Length (0) - RW */
#define E1000_RDH0 E1000_RDH /* RX Desc Head (0) - RW */
#define E1000_RDT0 E1000_RDT /* RX Desc Tail (0) - RW */
#define E1000_RDTR0 E1000_RDTR /* RX Delay Timer (0) - RW */
#define E1000_RXDCTL 0x02828 /* RX Descriptor Control queue 0 - RW */
#define E1000_RXDCTL1 0x02928 /* RX Descriptor Control queue 1 - RW */
#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
/* Convenience macros
*
* Note: "_n" is the queue number of the register to be written to.
*
* Example usage:
* E1000_RDBAL_REG(current_rx_queue)
*
*/
#define E1000_RDBAL_REG(_n) (E1000_RDBAL + (_n << 8))
#define E1000_RDBAH_REG(_n) (E1000_RDBAH + (_n << 8))
#define E1000_RDLEN_REG(_n) (E1000_RDLEN + (_n << 8))
#define E1000_RDH_REG(_n) (E1000_RDH + (_n << 8))
#define E1000_RDT_REG(_n) (E1000_RDT + (_n << 8))
#define E1000_RXDCTL_REG(_n) (E1000_RXDCTL + (_n << 8))
#define E1000_TDBAL_REG(_n) (E1000_TDBAL + (_n << 8))
#define E1000_TDBAH_REG(_n) (E1000_TDBAH + (_n << 8))
#define E1000_TDLEN_REG(_n) (E1000_TDLEN + (_n << 8))
#define E1000_TDH_REG(_n) (E1000_TDH + (_n << 8))
#define E1000_TDT_REG(_n) (E1000_TDT + (_n << 8))
#define E1000_TXDCTL_REG(_n) (E1000_TXDCTL + (_n << 8))
#define E1000_TARC_REG(_n) (E1000_TARC0 + (_n << 8))
#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8))
#define E1000_DCA_RXCTRL0 0x02814 /* RX Queue 0 DCA CTRL - RW */
#define E1000_DCA_RXCTRL1 0x02914 /* RX Queue 1 DCA CTRL - RW */
#define E1000_RDBAL2 0x02A00 /* RX Descriptor Base Low Queue 2 - RW */
#define E1000_RDBAH2 0x02A04 /* RX Descriptor Base High Queue 2 - RW */
#define E1000_RDLEN2 0x02A08 /* RX Descriptor Length Queue 2 - RW */
#define E1000_RDH2 0x02A10 /* RX Descriptor Head Queue 2 - RW */
#define E1000_DCA_RXCTRL2 0x02A14 /* RX Queue 2 DCA CTRL - RW */
#define E1000_RDT2 0x02A18 /* RX Descriptor Tail Queue 2 - RW */
#define E1000_RXDCTL2 0x02A28 /* RX Descriptor Control queue 2 - RW */
#define E1000_RDBAL3 0x02B00 /* RX Descriptor Base Low Queue 3 - RW */
#define E1000_RDBAH3 0x02B04 /* RX Descriptor Base High Queue 3 - RW */
#define E1000_RDLEN3 0x02B08 /* RX Descriptor Length Queue 3 - RW */
#define E1000_RDH3 0x02B10 /* RX Descriptor Head Queue 3 - RW */
#define E1000_DCA_RXCTRL3 0x02B14 /* RX Queue 3 DCA Control - RW */
#define E1000_RDT3 0x02B18 /* RX Descriptor Tail Queue 3 - RW */
#define E1000_RXDCTL3 0x02B28 /* RX Descriptor Control Queue 3 - RW */
#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */
#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */
#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
#define E1000_TDPUMB 0x0357C /* DMA TX Descriptor uC Mail Box - RW */
#define E1000_TDPUAD 0x03580 /* DMA TX Descriptor uC Addr Command - RW */
#define E1000_TDPUWD 0x03584 /* DMA TX Descriptor uC Data Write - RW */
#define E1000_TDPURD 0x03588 /* DMA TX Descriptor uC Data Read - RW */
#define E1000_TDPUCTL 0x0358C /* DMA TX Descriptor uC Control - RW */
#define E1000_DTXCTL 0x03590 /* DMA TX Control - RW */
#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
#define E1000_TDT 0x03818 /* TX Descriptor Tail - RW */
#define E1000_TDBAL0 E1000_TDBAL /* TX Descriptor Base Address Low - RW */
#define E1000_TDBAH0 E1000_TDBAH /* TX Descriptor Base Address High - RW */
#define E1000_TDLEN0 E1000_TDLEN /* TX Descriptor Length - RW */
#define E1000_TDH0 E1000_TDH /* TX Descriptor Head - RW */
#define E1000_TDT0 E1000_TDT /* TX Descriptor Tail - RW */
#define E1000_TIDV 0x03820 /* TX Interrupt Delay Value - RW */
#define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */
#define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */
#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */
#define E1000_DCA_TXCTRL0 0x03814 /* TX Queue 0 DCA CTRL - RW */
#define E1000_TDWBAL0 0x03838 /* TX Desc. WB Addr Low Queue 0 - RW */
#define E1000_TDWBAH0 0x0383C /* TX Desc. WB Addr High Queue 0 - RW */
#define E1000_DCA_TXCTRL(_n) (E1000_DCA_TXCTRL0 + (_n << 8))
#define E1000_TDWBAL_REG(_n) (E1000_TDWBAL0 + (_n << 8))
#define E1000_TDWBAH_REG(_n) (E1000_TDWBAH0 + (_n << 8))
#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */
#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */
#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */
#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */
#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */
#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */
#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */
#define E1000_DCA_TXCTRL1 0x03914 /* TX Queue 0 DCA CTRL - RW */
#define E1000_TDWBAL1 0x03938 /* TX Descriptor WB Addr Low Queue 1 - RW */
#define E1000_TDWBAH1 0x0393C /* TX Descriptor WB Addr High Queue 1 - RW */
#define E1000_TDBAL2 0x03A00 /* TX Descriptor Base Low Queue 2 - RW */
#define E1000_TDBAH2 0x03A04 /* TX Descriptor Base High Queue 2 - RW */
#define E1000_TDLEN2 0x03A08 /* TX Descriptor Length Queue 2 - RW */
#define E1000_TDH2 0x03A10 /* TX Descriptor Head Queue 2 - RW */
#define E1000_DCA_TXCTRL2 0x03A14 /* TX Queue 2 DCA Control - RW */
#define E1000_TDT2 0x03A18 /* TX Descriptor Tail Queue 2 - RW */
#define E1000_TXDCTL2 0x03A28 /* TX Descriptor Control 2 - RW */
#define E1000_TDWBAL2 0x03A38 /* TX Descriptor WB Addr Low Queue 2 - RW */
#define E1000_TDWBAH2 0x03A3C /* TX Descriptor WB Addr High Queue 2 - RW */
#define E1000_TDBAL3 0x03B00 /* TX Descriptor Base Low Queue 3 - RW */
#define E1000_TDBAH3 0x03B04 /* TX Descriptor Base High Queue 3 - RW */
#define E1000_TDLEN3 0x03B08 /* TX Descriptor Length Queue 3 - RW */
#define E1000_TDH3 0x03B10 /* TX Descriptor Head Queue 3 - RW */
#define E1000_DCA_TXCTRL3 0x03B14 /* TX Queue 3 DCA Control - RW */
#define E1000_TDT3 0x03B18 /* TX Descriptor Tail Queue 3 - RW */
#define E1000_TXDCTL3 0x03B28 /* TX Descriptor Control 3 - RW */
#define E1000_TDWBAL3 0x03B38 /* TX Descriptor WB Addr Low Queue 3 - RW */
#define E1000_TDWBAH3 0x03B3C /* TX Descriptor WB Addr High Queue 3 - RW */
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
#define E1000_COLC 0x04028 /* Collision Count - R/clr */
#define E1000_DC 0x04030 /* Defer Count - R/clr */
#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */
#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */
#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */
#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */
#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */
#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */
#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */
#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */
#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */
#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */
#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */
#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */
#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */
#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */
#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */
#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */
#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */
#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */
#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */
#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */
#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */
#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */
#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */
#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */
#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */
#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */
#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */
#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */
#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */
#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */
#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */
#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */
#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */
#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */
#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */
#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */
#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */
#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire Count */
#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */
#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
#define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */
#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */
#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */
#define E1000_CBTMPC 0x0402C /* Circuit Breaker TX Packet Count */
#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */
#define E1000_CBRDPC 0x04044 /* Circuit Breaker RX Dropped Count */
#define E1000_CBRMPC 0x040FC /* Circuit Breaker RX Packet Count */
#define E1000_RPTHC 0x04104 /* Rx Packets To Host */
#define E1000_HGPTC 0x04118 /* Host Good Packets TX Count */
#define E1000_HTCBDPC 0x04124 /* Host TX Circuit Breaker Dropped Count */
#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */
#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */
#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */
#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */
#define E1000_LENERRS 0x04138 /* Length Errors Count */
#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */
#define E1000_HRMPC 0x0A018 /* Header Redirection Missed Packet Count */
#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */
#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Packet Count - RW */
#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
#define E1000_RLPML 0x05004 /* RX Long Packet Max Length */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
#define E1000_RA 0x05400 /* Receive Address - RW Array */
#define E1000_PSRTYPE 0x05480 /* Packet Split Receive Type - RW */
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
#define E1000_VMD_CTL 0x0581C /* VMDq Control - RW */
#define E1000_VFQA0 0x0B000 /* VLAN Filter Queue Array 0 - RW Array */
#define E1000_VFQA1 0x0B200 /* VLAN Filter Queue Array 1 - RW Array */
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
#define E1000_WUS 0x05810 /* Wakeup Status - RO */
#define E1000_MANC 0x05820 /* Management Control - RW */
#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
#define E1000_HOST_IF 0x08800 /* Host Interface */
#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
#define E1000_GCR 0x05B00 /* PCI-Ex Control */
#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
#define E1000_HICR 0x08F00 /* Host Inteface Control */
/* RSS registers */
#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt RX VLAN Priority - RW */
#define E1000_MSIXBM0 0x01600 /* MSI-X Allocation Register 0 - RW */
#define E1000_MSIXBM1 0x01604 /* MSI-X Allocation Register 1 - RW */
#define E1000_MSIXBM2 0x01608 /* MSI-X Allocation Register 2 - RW */
#define E1000_MSIXBM3 0x0160C /* MSI-X Allocation Register 3 - RW */
#define E1000_MSIXBM4 0x01610 /* MSI-X Allocation Register 4 - RW */
#define E1000_MSIXBM5 0x01614 /* MSI-X Allocation Register 5 - RW */
#define E1000_MSIXBM6 0x01618 /* MSI-X Allocation Register 6 - RW */
#define E1000_MSIXBM7 0x0161C /* MSI-X Allocation Register 7 - RW */
#define E1000_MSIXBM8 0x01620 /* MSI-X Allocation Register 8 - RW */
#define E1000_MSIXBM9 0x01624 /* MSI-X Allocation Register 9 - RW */
#define E1000_MSIXTADD0 0x0C000 /* MSI-X Table entry addr low reg 0 - RW */
#define E1000_MSIXTADD1 0x0C010 /* MSI-X Table entry addr low reg 1 - RW */
#define E1000_MSIXTADD2 0x0C020 /* MSI-X Table entry addr low reg 2 - RW */
#define E1000_MSIXTADD3 0x0C030 /* MSI-X Table entry addr low reg 3 - RW */
#define E1000_MSIXTADD4 0x0C040 /* MSI-X Table entry addr low reg 4 - RW */
#define E1000_MSIXTADD5 0x0C050 /* MSI-X Table entry addr low reg 5 - RW */
#define E1000_MSIXTADD6 0x0C060 /* MSI-X Table entry addr low reg 6 - RW */
#define E1000_MSIXTADD7 0x0C070 /* MSI-X Table entry addr low reg 7 - RW */
#define E1000_MSIXTADD8 0x0C080 /* MSI-X Table entry addr low reg 8 - RW */
#define E1000_MSIXTADD9 0x0C090 /* MSI-X Table entry addr low reg 9 - RW */
#define E1000_MSIXTUADD0 0x0C004 /* MSI-X Table entry addr upper reg 0 - RW */
#define E1000_MSIXTUADD1 0x0C014 /* MSI-X Table entry addr upper reg 1 - RW */
#define E1000_MSIXTUADD2 0x0C024 /* MSI-X Table entry addr upper reg 2 - RW */
#define E1000_MSIXTUADD3 0x0C034 /* MSI-X Table entry addr upper reg 3 - RW */
#define E1000_MSIXTUADD4 0x0C044 /* MSI-X Table entry addr upper reg 4 - RW */
#define E1000_MSIXTUADD5 0x0C054 /* MSI-X Table entry addr upper reg 5 - RW */
#define E1000_MSIXTUADD6 0x0C064 /* MSI-X Table entry addr upper reg 6 - RW */
#define E1000_MSIXTUADD7 0x0C074 /* MSI-X Table entry addr upper reg 7 - RW */
#define E1000_MSIXTUADD8 0x0C084 /* MSI-X Table entry addr upper reg 8 - RW */
#define E1000_MSIXTUADD9 0x0C094 /* MSI-X Table entry addr upper reg 9 - RW */
#define E1000_MSIXTMSG0 0x0C008 /* MSI-X Table entry message reg 0 - RW */
#define E1000_MSIXTMSG1 0x0C018 /* MSI-X Table entry message reg 1 - RW */
#define E1000_MSIXTMSG2 0x0C028 /* MSI-X Table entry message reg 2 - RW */
#define E1000_MSIXTMSG3 0x0C038 /* MSI-X Table entry message reg 3 - RW */
#define E1000_MSIXTMSG4 0x0C048 /* MSI-X Table entry message reg 4 - RW */
#define E1000_MSIXTMSG5 0x0C058 /* MSI-X Table entry message reg 5 - RW */
#define E1000_MSIXTMSG6 0x0C068 /* MSI-X Table entry message reg 6 - RW */
#define E1000_MSIXTMSG7 0x0C078 /* MSI-X Table entry message reg 7 - RW */
#define E1000_MSIXTMSG8 0x0C088 /* MSI-X Table entry message reg 8 - RW */
#define E1000_MSIXTMSG9 0x0C098 /* MSI-X Table entry message reg 9 - RW */
#define E1000_MSIXVCTRL0 0x0C00C /* MSI-X Table entry vector ctrl reg 0 - RW */
#define E1000_MSIXVCTRL1 0x0C01C /* MSI-X Table entry vector ctrl reg 1 - RW */
#define E1000_MSIXVCTRL2 0x0C02C /* MSI-X Table entry vector ctrl reg 2 - RW */
#define E1000_MSIXVCTRL3 0x0C03C /* MSI-X Table entry vector ctrl reg 3 - RW */
#define E1000_MSIXVCTRL4 0x0C04C /* MSI-X Table entry vector ctrl reg 4 - RW */
#define E1000_MSIXVCTRL5 0x0C05C /* MSI-X Table entry vector ctrl reg 5 - RW */
#define E1000_MSIXVCTRL6 0x0C06C /* MSI-X Table entry vector ctrl reg 6 - RW */
#define E1000_MSIXVCTRL7 0x0C07C /* MSI-X Table entry vector ctrl reg 7 - RW */
#define E1000_MSIXVCTRL8 0x0C08C /* MSI-X Table entry vector ctrl reg 8 - RW */
#define E1000_MSIXVCTRL9 0x0C09C /* MSI-X Table entry vector ctrl reg 9 - RW */
#define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */
#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */
#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/**************************************************************************
Copyright (c) 2001-2006, Intel Corporation
Copyright (c) 2001-2007, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -30,7 +30,7 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
/*$FreeBSD: src/sys/dev/em/if_em.h,v 1.32.2.6 2006/11/10 09:30:27 jfv Exp $*/
/*$FreeBSD: src/sys/dev/em/if_em.h,v 1.62 2007/09/10 21:50:40 jfv Exp $*/
#ifndef _EM_H_DEFINED_
#define _EM_H_DEFINED_
@ -47,7 +47,7 @@ POSSIBILITY OF SUCH DAMAGE.
* descriptor is 16 bytes.
* Since TDLEN should be multiple of 128bytes, the number of transmit
* desscriptors should meet the following condition.
* (num_tx_desc * sizeof(struct em_tx_desc)) % 128 == 0
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
*/
#define EM_MIN_TXD 80
#define EM_MAX_TXD_82543 256
@ -65,12 +65,12 @@ POSSIBILITY OF SUCH DAMAGE.
* descriptor. The maximum MTU size is 16110.
* Since TDLEN should be multiple of 128bytes, the number of transmit
* desscriptors should meet the following condition.
* (num_tx_desc * sizeof(struct em_tx_desc)) % 128 == 0
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
*/
#define EM_MIN_RXD 80
#define EM_MAX_RXD_82543 256
#define EM_MAX_RXD 4096
#define EM_DEFAULT_RXD EM_MAX_RXD_82543
#define EM_DEFAULT_RXD EM_MAX_RXD_82543
/*
* EM_TIDV - Transmit Interrupt Delay Value
@ -132,29 +132,17 @@ POSSIBILITY OF SUCH DAMAGE.
*/
#define EM_RADV 64
/*
* Inform the stack about transmit checksum offload capabilities.
*/
#define EM_CHECKSUM_FEATURES (CSUM_TCP | CSUM_UDP)
#ifdef EM_TSO
/*
* Inform the stack about transmit segmentation offload capabilities.
*/
#define EM_TCPSEG_FEATURES CSUM_TSO
#endif
/*
* This parameter controls the duration of transmit watchdog timer.
*/
#define EM_TX_TIMEOUT 5 /* set to 5 seconds */
/*
* These parameters controls when the driver calls the routine to reclaim
* This parameter controls when the driver calls the routine to reclaim
* transmit descriptors.
*/
#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
#define EM_TX_OP_THRESHOLD (adapter->num_tx_desc / 32)
#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
#define EM_TX_OP_THRESHOLD (adapter->num_tx_desc / 32)
/*
* This parameter controls whether or not autonegotation is enabled.
@ -171,36 +159,35 @@ POSSIBILITY OF SUCH DAMAGE.
*/
#define WAIT_FOR_AUTO_NEG_DEFAULT 0
/*
* EM_MASTER_SLAVE is only defined to enable a workaround for a known
* compatibility issue with 82541/82547 devices and some switches.
* See the "Known Limitations" section of the README file for a complete
* description and a list of affected switches.
*
* 0 = Hardware default
* 1 = Master mode
* 2 = Slave mode
* 3 = Auto master/slave
*/
/* #define EM_MASTER_SLAVE 2 */
/* Tunables -- End */
#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
ADVERTISE_1000_FULL)
#define AUTO_ALL_MODES 0
/* PHY master/slave setting */
#define EM_MASTER_SLAVE e1000_ms_hw_default
/*
* Micellaneous constants
*/
#define EM_VENDOR_ID 0x8086
#define EM_FLASH 0x0014 /* Flash memory on ICH8 */
#define EM_FLASH 0x0014
#define EM_JUMBO_PBA 0x00000028
#define EM_DEFAULT_PBA 0x00000030
#define EM_SMARTSPEED_DOWNSHIFT 3
#define EM_SMARTSPEED_MAX 15
#define EM_MAX_INTR 10
#define MAX_NUM_MULTICAST_ADDRESSES 128
#define PCI_ANY_ID (~0U)
#define ETHER_ALIGN 2
#define EM_TX_BUFFER_SIZE ((uint32_t) 1514)
#define EM_FC_PAUSE_TIME 0x0680
#define EM_EEPROM_APME 0x400;
/*
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
@ -212,25 +199,21 @@ POSSIBILITY OF SUCH DAMAGE.
#define SPEED_MODE_BIT (1<<21) /* On PCI-E MACs only */
/* PCI Config defines */
#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
#define EM_BAR_TYPE_MASK 0x00000001
#define EM_BAR_TYPE_MMEM 0x00000000
#define EM_BAR_TYPE_IO 0x00000001
#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK)
#define EM_BAR_MEM_TYPE_MASK 0x00000006
#define EM_BAR_MEM_TYPE_32BIT 0x00000000
#define EM_BAR_MEM_TYPE_64BIT 0x00000004
/*
* Backward compatibility workaround
*/
#if !defined(PCIR_CIS)
#define PCIR_CIS PCIR_CARDBUSCIS
#endif
#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
#define EM_BAR_TYPE_MASK 0x00000001
#define EM_BAR_TYPE_MMEM 0x00000000
#define EM_BAR_TYPE_IO 0x00000001
#define EM_BAR_TYPE_FLASH 0x0014
#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK)
#define EM_BAR_MEM_TYPE_MASK 0x00000006
#define EM_BAR_MEM_TYPE_32BIT 0x00000000
#define EM_BAR_MEM_TYPE_64BIT 0x00000004
#define EM_MSIX_BAR 3 /* On 82575 */
/* Defines for printing debug information */
#define DEBUG_INIT 1
#define DEBUG_IOCTL 1
#define DEBUG_HW 1
#define DEBUG_INIT 0
#define DEBUG_IOCTL 0
#define DEBUG_HW 0
#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n")
#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A)
@ -242,41 +225,24 @@ POSSIBILITY OF SUCH DAMAGE.
#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
/* Supported RX Buffer Sizes */
#define EM_RXBUFFER_2048 2048
#define EM_RXBUFFER_4096 4096
#define EM_RXBUFFER_8192 8192
#define EM_RXBUFFER_16384 16384
#define EM_MAX_SCATTER 64
#define EM_TSO_SIZE 65535 /* maxsize of a dma transfer */
#define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */
#define ETH_ZLEN 60
#define ETH_ADDR_LEN 6
#define CSUM_OFFLOAD 7 /* Offload bits in csum flags */
/* ******************************************************************************
* vendor_info_array
*
* This array contains the list of Subvendor/Subdevice IDs on which the driver
* should load.
*
* ******************************************************************************/
typedef struct _em_vendor_info_t {
unsigned int vendor_id;
unsigned int device_id;
unsigned int subvendor_id;
unsigned int subdevice_id;
unsigned int index;
} em_vendor_info_t;
struct adapter;
struct em_buffer {
int next_eop; /* Index of the desc to watch */
struct mbuf *m_head;
bus_dmamap_t map; /* bus_dma map for packet */
struct em_int_delay_info {
struct adapter *adapter; /* Back-pointer to the adapter struct */
int offset; /* Register offset to read/write */
int value; /* Current value in usecs */
};
/*
* Bus dma allocation structure used by
* em_dma_malloc and em_dma_free.
* e1000_dma_malloc and e1000_dma_free.
*/
struct em_dma_alloc {
bus_addr_t dma_paddr;
@ -287,42 +253,17 @@ struct em_dma_alloc {
int dma_nseg;
};
typedef enum _XSUM_CONTEXT_T {
OFFLOAD_NONE,
OFFLOAD_TCP_IP,
OFFLOAD_UDP_IP
} XSUM_CONTEXT_T;
struct adapter;
struct em_int_delay_info {
struct adapter *adapter; /* Back-pointer to the adapter struct */
int offset; /* Register offset to read/write */
int value; /* Current value in usecs */
};
/* For 82544 PCIX Workaround */
typedef struct _ADDRESS_LENGTH_PAIR
{
uint64_t address;
uint32_t length;
} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
typedef struct _DESCRIPTOR_PAIR
{
ADDRESS_LENGTH_PAIR descriptor[4];
uint32_t elements;
} DESC_ARRAY, *PDESC_ARRAY;
/* Our adapter structure */
struct adapter {
struct ifnet *ifp;
struct em_hw hw;
struct e1000_hw hw;
/* FreeBSD operating-system-specific structures. */
struct em_osdep osdep;
struct e1000_osdep osdep;
struct device *dev;
struct resource *res_memory;
struct resource *flash_mem;
struct resource *msix_mem;
struct resource *res_ioport;
struct resource *res_interrupt;
void *int_handler_tag;
@ -331,15 +272,17 @@ struct adapter {
struct callout tx_fifo_timer;
int watchdog_timer;
int io_rid;
int msi;
int if_flags;
struct mtx mtx;
int em_insert_vlan_header;
struct task link_task;
struct task rxtx_task;
struct taskqueue *tq; /* private task queue */
/* Management and WOL features */
int wol;
int has_manage;
#ifdef EM_FAST_INTR
struct task link_task;
struct task rxtx_task;
struct taskqueue *tq;
#endif
/* Info about the board itself */
uint32_t part_num;
uint8_t link_active;
@ -351,8 +294,6 @@ struct adapter {
struct em_int_delay_info rx_int_delay;
struct em_int_delay_info rx_abs_int_delay;
XSUM_CONTEXT_T active_checksum_context;
/*
* Transmit definitions
*
@ -363,7 +304,7 @@ struct adapter {
* The number of remaining tx_desc is num_tx_desc_avail.
*/
struct em_dma_alloc txdma; /* bus_dma glue for tx desc */
struct em_tx_desc *tx_desc_base;
struct e1000_tx_desc *tx_desc_base;
uint32_t next_avail_tx_desc;
uint32_t next_tx_to_clean;
volatile uint16_t num_tx_desc_avail;
@ -373,6 +314,12 @@ struct adapter {
bus_dma_tag_t txtag; /* dma tag for tx */
uint32_t tx_tso; /* last tx was tso */
/*
* Transmit function pointer:
* legacy or advanced (82575 and later)
*/
int (*em_xmit) (struct adapter *adapter, struct mbuf **m_headp);
/*
* Receive definitions
*
@ -382,13 +329,14 @@ struct adapter {
* The next pair to check on receive is at offset next_rx_desc_to_check
*/
struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */
struct em_rx_desc *rx_desc_base;
struct e1000_rx_desc *rx_desc_base;
uint32_t next_rx_desc_to_check;
uint32_t rx_buffer_len;
uint16_t num_rx_desc;
int rx_process_limit;
struct em_buffer *rx_buffer_area;
bus_dma_tag_t rxtag;
bus_dmamap_t rx_sparemap;
/*
* First/last mbuf pointers, for
@ -427,9 +375,44 @@ struct adapter {
boolean_t pcix_82544;
boolean_t in_detach;
struct em_hw_stats stats;
struct e1000_hw_stats stats;
};
/* ******************************************************************************
* vendor_info_array
*
* This array contains the list of Subvendor/Subdevice IDs on which the driver
* should load.
*
* ******************************************************************************/
typedef struct _em_vendor_info_t {
unsigned int vendor_id;
unsigned int device_id;
unsigned int subvendor_id;
unsigned int subdevice_id;
unsigned int index;
} em_vendor_info_t;
struct em_buffer {
int next_eop; /* Index of the desc to watch */
struct mbuf *m_head;
bus_dmamap_t map; /* bus_dma map for packet */
};
/* For 82544 PCIX Workaround */
typedef struct _ADDRESS_LENGTH_PAIR
{
uint64_t address;
uint32_t length;
} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
typedef struct _DESCRIPTOR_PAIR
{
ADDRESS_LENGTH_PAIR descriptor[4];
uint32_t elements;
} DESC_ARRAY, *PDESC_ARRAY;
#define EM_LOCK_INIT(_sc, _name) \
mtx_init(&(_sc)->mtx, _name, MTX_NETWORK_LOCK, MTX_DEF)
#define EM_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/pci/if_rl.c,v 1.152.2.6 2006/10/13 07:39:25 glebius Exp $");
__FBSDID("$FreeBSD: src/sys/pci/if_rl.c,v 1.170 2007/07/24 01:24:03 yongari Exp $");
/*
* RealTek 8129/8139 PCI NIC driver
@ -121,7 +121,7 @@ MODULE_DEPEND(rl, pci, 1, 1, 1);
MODULE_DEPEND(rl, ether, 1, 1, 1);
MODULE_DEPEND(rl, miibus, 1, 1, 1);
/* "controller miibus0" required. See GENERIC if you get errors here. */
/* "device miibus" required. See GENERIC if you get errors here. */
#include "miibus_if.h"
/*
@ -215,7 +215,7 @@ static void rl_stop(struct rl_softc *);
static int rl_suspend(device_t);
static void rl_tick(void *);
static void rl_txeof(struct rl_softc *);
static void rl_watchdog(struct ifnet *);
static void rl_watchdog(struct rl_softc *);
#ifdef RL_USEIOSPACE
#define RL_RES SYS_RES_IOPORT
@ -828,10 +828,10 @@ rl_attach(device_t dev)
/* Allocate interrupt */
rid = 0;
sc->rl_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
sc->rl_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->rl_irq == NULL) {
if (sc->rl_irq[0] == NULL) {
device_printf(dev, "couldn't map interrupt\n");
error = ENXIO;
goto fail;
@ -885,7 +885,7 @@ rl_attach(device_t dev)
* Allocate the parent bus DMA tag appropriate for PCI.
*/
#define RL_NSEG_NEW 32
error = bus_dma_tag_create(NULL, /* parent */
error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
1, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
@ -955,7 +955,6 @@ rl_attach(device_t dev)
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = rl_ioctl;
ifp->if_start = rl_start;
ifp->if_watchdog = rl_watchdog;
ifp->if_init = rl_init;
ifp->if_capabilities = IFCAP_VLAN_MTU;
ifp->if_capenable = ifp->if_capabilities;
@ -972,8 +971,8 @@ rl_attach(device_t dev)
ether_ifattach(ifp, eaddr);
/* Hook interrupt last to avoid having to lock softc */
error = bus_setup_intr(dev, sc->rl_irq, INTR_TYPE_NET | INTR_MPSAFE,
rl_intr, sc, &sc->rl_intrhand);
error = bus_setup_intr(dev, sc->rl_irq[0], INTR_TYPE_NET | INTR_MPSAFE,
NULL, rl_intr, sc, &sc->rl_intrhand[0]);
if (error) {
device_printf(sc->rl_dev, "couldn't set up irq\n");
ether_ifdetach(ifp);
@ -1003,6 +1002,7 @@ rl_detach(device_t dev)
ifp = sc->rl_ifp;
KASSERT(mtx_initialized(&sc->rl_mtx), ("rl mutex not initialized"));
#ifdef DEVICE_POLLING
if (ifp->if_capenable & IFCAP_POLLING)
ether_poll_deregister(ifp);
@ -1018,19 +1018,20 @@ rl_detach(device_t dev)
#if 0
sc->suspended = 1;
#endif
if (ifp)
if_free(ifp);
if (sc->rl_miibus)
device_delete_child(dev, sc->rl_miibus);
bus_generic_detach(dev);
if (sc->rl_intrhand)
bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand);
if (sc->rl_irq)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
if (sc->rl_intrhand[0])
bus_teardown_intr(dev, sc->rl_irq[0], sc->rl_intrhand[0]);
if (sc->rl_irq[0])
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq[0]);
if (sc->rl_res)
bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res);
if (ifp)
if_free(ifp);
if (sc->rl_tag) {
bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap);
bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf,
@ -1263,9 +1264,9 @@ rl_txeof(struct rl_softc *sc)
} while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx);
if (RL_LAST_TXMBUF(sc) == NULL)
ifp->if_timer = 0;
else if (ifp->if_timer == 0)
ifp->if_timer = 5;
sc->rl_watchdog_timer = 0;
else if (sc->rl_watchdog_timer == 0)
sc->rl_watchdog_timer = 5;
}
static void
@ -1278,6 +1279,8 @@ rl_tick(void *xsc)
mii = device_get_softc(sc->rl_miibus);
mii_tick(mii);
rl_watchdog(sc);
callout_reset(&sc->rl_stat_callout, hz, rl_tick, sc);
}
@ -1464,7 +1467,7 @@ rl_start_locked(struct ifnet *ifp)
RL_INC(sc->rl_cdata.cur_tx);
/* Set a timeout in case the chip goes out to lunch. */
ifp->if_timer = 5;
sc->rl_watchdog_timer = 5;
}
/*
@ -1492,6 +1495,7 @@ rl_init_locked(struct rl_softc *sc)
struct ifnet *ifp = sc->rl_ifp;
struct mii_data *mii;
uint32_t rxcfg = 0;
uint32_t eaddr[2];
RL_LOCK_ASSERT(sc);
@ -1508,10 +1512,10 @@ rl_init_locked(struct rl_softc *sc)
* register write enable" mode to modify the ID registers.
*/
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG);
CSR_WRITE_STREAM_4(sc, RL_IDR0,
*(uint32_t *)(&IFP2ENADDR(sc->rl_ifp)[0]));
CSR_WRITE_STREAM_4(sc, RL_IDR4,
*(uint32_t *)(&IFP2ENADDR(sc->rl_ifp)[4]));
bzero(eaddr, sizeof(eaddr));
bcopy(IF_LLADDR(sc->rl_ifp), eaddr, ETHER_ADDR_LEN);
CSR_WRITE_STREAM_4(sc, RL_IDR0, eaddr[0]);
CSR_WRITE_STREAM_4(sc, RL_IDR4, eaddr[1]);
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
/* Init the RX buffer pointer register. */
@ -1562,11 +1566,11 @@ rl_init_locked(struct rl_softc *sc)
#ifdef DEVICE_POLLING
/* Disable interrupts if we are polling. */
if (ifp->if_capenable & IFCAP_POLLING)
HAIKU_PROTECT_INTR_REGISTER(CSR_WRITE_2(sc, RL_IMR, 0));
CSR_WRITE_2(sc, RL_IMR, 0);
else
#endif
/* Enable interrupts. */
HAIKU_PROTECT_INTR_REGISTER(CSR_WRITE_2(sc, RL_IMR, RL_INTRS));
CSR_WRITE_2(sc, RL_IMR, RL_INTRS);
/* Set initial TX threshold */
sc->rl_txthresh = RL_TX_THRESH_INIT;
@ -1664,7 +1668,7 @@ rl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
return(error);
RL_LOCK(sc);
/* Disable interrupts */
HAIKU_PROTECT_INTR_REGISTER(CSR_WRITE_2(sc, RL_IMR, 0x0000));
CSR_WRITE_2(sc, RL_IMR, 0x0000);
ifp->if_capenable |= IFCAP_POLLING;
RL_UNLOCK(sc);
return (error);
@ -1675,7 +1679,7 @@ rl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
error = ether_poll_deregister(ifp);
/* Enable interrupts. */
RL_LOCK(sc);
HAIKU_PROTECT_INTR_REGISTER(CSR_WRITE_2(sc, RL_IMR, RL_INTRS));
CSR_WRITE_2(sc, RL_IMR, RL_INTRS);
ifp->if_capenable &= ~IFCAP_POLLING;
RL_UNLOCK(sc);
return (error);
@ -1691,20 +1695,20 @@ rl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
static void
rl_watchdog(struct ifnet *ifp)
rl_watchdog(struct rl_softc *sc)
{
struct rl_softc *sc = ifp->if_softc;
RL_LOCK(sc);
RL_LOCK_ASSERT(sc);
if_printf(ifp, "watchdog timeout\n");
ifp->if_oerrors++;
if (sc->rl_watchdog_timer == 0 || --sc->rl_watchdog_timer >0)
return;
device_printf(sc->rl_dev, "watchdog timeout\n");
sc->rl_ifp->if_oerrors++;
rl_txeof(sc);
rl_rxeof(sc);
rl_init_locked(sc);
RL_UNLOCK(sc);
}
/*
@ -1719,12 +1723,12 @@ rl_stop(struct rl_softc *sc)
RL_LOCK_ASSERT(sc);
ifp->if_timer = 0;
sc->rl_watchdog_timer = 0;
callout_stop(&sc->rl_stat_callout);
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
CSR_WRITE_1(sc, RL_COMMAND, 0x00);
HAIKU_PROTECT_INTR_REGISTER(CSR_WRITE_2(sc, RL_IMR, 0x0000));
CSR_WRITE_2(sc, RL_IMR, 0x0000);
bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap);
/*

View File

@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/pci/if_rlreg.h,v 1.51.2.7 2006/08/01 17:36:50 wpaul Exp $
* $FreeBSD: src/sys/pci/if_rlreg.h,v 1.67 2007/07/24 01:24:03 yongari Exp $
*/
/*
@ -312,6 +312,8 @@
#define RL_EEMODE_WRITECFG (0x80|0x40)
/* 9346 EEPROM commands */
#define RL_9346_ADDR_LEN 6 /* 93C46 1K: 128x16 */
#define RL_9356_ADDR_LEN 8 /* 93C56 2K: 256x16 */
#define RL_9346_WRITE 0x5
#define RL_9346_READ 0x6
@ -541,6 +543,7 @@ struct rl_desc {
#define RL_TDESC_CMD_UDPCSUM 0x00020000 /* UDP checksum enable */
#define RL_TDESC_CMD_IPCSUM 0x00040000 /* IP header checksum enable */
#define RL_TDESC_CMD_MSSVAL 0x07FF0000 /* Large send MSS value */
#define RL_TDESC_CMD_MSSVAL_SHIFT 16 /* Large send MSS value shift */
#define RL_TDESC_CMD_LGSEND 0x08000000 /* TCP large send enb */
#define RL_TDESC_CMD_EOF 0x10000000 /* end of frame marker */
#define RL_TDESC_CMD_SOF 0x20000000 /* start of frame marker */
@ -637,11 +640,12 @@ struct rl_stats {
* due to the 8139C+. We need to put the number of descriptors in the ring
* structure and use that value instead.
*/
#if !defined(__i386__) && !defined(__amd64__)
#ifndef __NO_STRICT_ALIGNMENT
#define RE_FIXUP_RX 1
#endif
#define RL_TX_DESC_CNT 64
#define RL_TX_DESC_THLD 4
#define RL_RX_DESC_CNT RL_TX_DESC_CNT
#define RL_RX_LIST_SZ (RL_RX_DESC_CNT * sizeof(struct rl_desc))
@ -660,6 +664,8 @@ struct rl_stats {
#define RE_RX_DESC_BUFLEN MCLBYTES
#endif
#define RL_MSI_MESSAGES 2
#define RL_ADDR_LO(y) ((uint64_t) (y) & 0xFFFFFFFF)
#define RL_ADDR_HI(y) ((uint64_t) (y) >> 32)
@ -670,7 +676,6 @@ struct rl_stats {
struct rl_softc;
struct rl_dmaload_arg {
struct rl_softc *sc;
int rl_idx;
int rl_maxsegs;
uint32_t rl_flags;
@ -707,8 +712,8 @@ struct rl_softc {
bus_space_tag_t rl_btag; /* bus space tag */
device_t rl_dev;
struct resource *rl_res;
struct resource *rl_irq;
void *rl_intrhand;
struct resource *rl_irq[RL_MSI_MESSAGES];
void *rl_intrhand[RL_MSI_MESSAGES];
device_t rl_miibus;
bus_dma_tag_t rl_parent_tag;
bus_dma_tag_t rl_tag;
@ -720,12 +725,14 @@ struct rl_softc {
struct rl_chain_data rl_cdata;
struct rl_list_data rl_ldata;
struct callout rl_stat_callout;
int rl_watchdog_timer;
struct mtx rl_mtx;
struct mbuf *rl_head;
struct mbuf *rl_tail;
uint32_t rl_hwrev;
uint32_t rl_rxlenmask;
int rl_testmode;
int rl_if_flags;
int suspended; /* 0 = normal 1 = suspended */
#ifdef DEVICE_POLLING
int rxcycles;
@ -737,6 +744,7 @@ struct rl_softc {
struct mtx rl_intlock;
int rl_txstart;
int rl_link;
int rl_msi;
};
#define RL_LOCK(_sc) mtx_lock(&(_sc)->rl_mtx)

View File

@ -6,8 +6,6 @@
#include <sys/bus.h>
#include "if_vrreg.h"
HAIKU_FBSD_DRIVER_GLUE(via_rhine, vr, pci);
HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_SWI_TASKQUEUE);
@ -28,26 +26,3 @@ __haiku_select_miibus_driver(device_t dev)
return __haiku_probe_miibus(dev, drivers, 2);
}
int
__haiku_disable_interrupts(device_t dev)
{
struct vr_softc *sc = device_get_softc(dev);
if (CSR_READ_2(sc, VR_ISR) == 0)
return 0;
CSR_WRITE_2(sc, VR_IMR, 0x0000);
return 1;
}
void
__haiku_reenable_interrupts(device_t dev)
{
struct vr_softc *sc = device_get_softc(dev);
CSR_WRITE_2(sc, VR_IMR, VR_INTRS);
}

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/pci/if_vrreg.h,v 1.22.2.1 2005/11/08 16:05:56 jhb Exp $
* $FreeBSD: src/sys/pci/if_vrreg.h,v 1.34 2007/04/23 12:19:02 phk Exp $
*/
/*
@ -330,13 +330,14 @@
struct vr_desc {
u_int32_t vr_status;
u_int32_t vr_ctl;
u_int32_t vr_ptr1;
u_int32_t vr_ptr2;
u_int32_t vr_data;
u_int32_t vr_nextphys;
struct mbuf *vr_mbuf;
struct vr_desc *vr_next;
u_int32_t *vxr1;
u_int32_t *vxr2;
};
#define vr_data vr_ptr1
#define vr_next vr_ptr2
#define VR_RXSTAT_RXERR 0x00000001
#define VR_RXSTAT_CRCERR 0x00000002
@ -364,6 +365,8 @@ struct vr_desc {
#define VR_RXCTL_BUFLEN_EXT 0x00007800
#define VR_RXCTL_CHAIN 0x00008000
#define VR_RXCTL_RX_INTR 0x00800000
#define VR_RXCTL_GOODIP 0x00280000
#define VR_RXCTL_GOODTCPUDP 0x00100000
#define VR_RXCTL (VR_RXCTL_CHAIN|VR_RXCTL_RX_INTR)
@ -383,52 +386,22 @@ struct vr_desc {
#define VR_TXCTL_BUFLEN 0x000007FF
#define VR_TXCTL_BUFLEN_EXT 0x00007800
#define VR_TXCTL_TLINK 0x00008000
#define VR_TXCTL_NOCRC 0x00010000
#define VR_TXCTL_INSERTTAG 0x00020000
#define VR_TXCTL_IPCSUM 0x00040000
#define VR_TXCTL_UDPCSUM 0x00080000
#define VR_TXCTL_TCPCSUM 0x00100000
#define VR_TXCTL_FIRSTFRAG 0x00200000
#define VR_TXCTL_LASTFRAG 0x00400000
#define VR_TXCTL_FINT 0x00800000
#define VR_MAXFRAGS 16
#define VR_RX_LIST_CNT 64
#define VR_TX_LIST_CNT 128
#define VR_RX_LIST_CNT 256
#define VR_TX_LIST_CNT 256
#define VR_MIN_FRAMELEN 60
#define VR_FRAMELEN 1536
#define VR_RXLEN 1520
#define VR_TXOWN(x) x->vr_ptr->vr_status
struct vr_list_data {
struct vr_desc vr_rx_list[VR_RX_LIST_CNT];
struct vr_desc vr_tx_list[VR_TX_LIST_CNT];
};
struct vr_chain {
struct vr_desc *vr_ptr;
struct mbuf *vr_mbuf;
struct vr_chain *vr_nextdesc;
};
struct vr_chain_onefrag {
struct vr_desc *vr_ptr;
struct mbuf *vr_mbuf;
struct vr_chain_onefrag *vr_nextdesc;
};
struct vr_chain_data {
struct vr_chain_onefrag vr_rx_chain[VR_RX_LIST_CNT];
struct vr_chain vr_tx_chain[VR_TX_LIST_CNT];
struct vr_chain_onefrag *vr_rx_head;
struct vr_chain *vr_tx_cons;
struct vr_chain *vr_tx_prod;
};
struct vr_type {
u_int16_t vr_vid;
u_int16_t vr_did;
char *vr_name;
};
#define VR_RXLEN 1524
struct vr_mii_frame {
u_int8_t mii_stdelim;
@ -451,50 +424,6 @@ struct vr_mii_frame {
#define VR_FLAG_SCHEDDELAY 2
#define VR_FLAG_DELAYTIMEO 3
struct vr_softc {
struct ifnet *vr_ifp; /* interface info */
bus_space_handle_t vr_bhandle; /* bus space handle */
bus_space_tag_t vr_btag; /* bus space tag */
struct resource *vr_res;
struct resource *vr_irq;
void *vr_intrhand;
device_t vr_miibus;
struct vr_type *vr_info; /* Rhine adapter info */
u_int8_t vr_type;
u_int8_t vr_revid; /* Rhine chip revision */
u_int8_t vr_flags; /* See VR_F_* below */
struct vr_list_data *vr_ldata;
struct vr_chain_data vr_cdata;
struct callout vr_stat_callout;
struct mtx vr_mtx;
int suspended; /* if 1, sleeping/detaching */
#ifdef DEVICE_POLLING
int rxcycles;
#endif
};
#define VR_F_RESTART 0x01 /* Restart unit on next tick */
#define VR_LOCK(_sc) mtx_lock(&(_sc)->vr_mtx)
#define VR_UNLOCK(_sc) mtx_unlock(&(_sc)->vr_mtx)
#define VR_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->vr_mtx, MA_OWNED)
/*
* register space access macros
*/
#define CSR_WRITE_4(sc, reg, val) \
bus_space_write_4(sc->vr_btag, sc->vr_bhandle, reg, val)
#define CSR_WRITE_2(sc, reg, val) \
bus_space_write_2(sc->vr_btag, sc->vr_bhandle, reg, val)
#define CSR_WRITE_1(sc, reg, val) \
bus_space_write_1(sc->vr_btag, sc->vr_bhandle, reg, val)
#define CSR_READ_4(sc, reg) \
bus_space_read_4(sc->vr_btag, sc->vr_bhandle, reg)
#define CSR_READ_2(sc, reg) \
bus_space_read_2(sc->vr_btag, sc->vr_bhandle, reg)
#define CSR_READ_1(sc, reg) \
bus_space_read_1(sc->vr_btag, sc->vr_bhandle, reg)
#define VR_TIMEOUT 1000
#define ETHER_ALIGN 2
@ -589,9 +518,3 @@ struct vr_softc {
#define VR_PSTATE_D3 0x0003
#define VR_PME_EN 0x0010
#define VR_PME_STATUS 0x8000
#ifdef __alpha__
#undef vtophys
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va)
#endif

View File

@ -1,6 +1,7 @@
SubDir HAIKU_TOP src libs compat freebsd_network ;
UsePrivateHeaders kernel net ;
UseHeaders $(HAIKU_PRIVATE_KERNEL_HEADERS) : true ;
UsePrivateHeaders net ;
UseHeaders [ FDirName $(SUBDIR) ] : true ;
UseHeaders [ FDirName $(SUBDIR) compat ] : true ;

View File

@ -1,3 +0,0 @@
FreeBSD network driver compatibility layer. Based on FreeBSD 6.2.
- Hugo, 3 May 2007

View File

@ -7,7 +7,9 @@
#include "device.h"
#include <malloc.h>
#include <stdlib.h>
#include <arch/cpu.h>
#include <compat/dev/pci/pcivar.h>
#include <compat/machine/resource.h>
@ -24,22 +26,20 @@
#define ROUNDUP(a, b) (((a) + ((b)-1)) & ~((b)-1))
struct resource {
int type;
bus_space_tag_t tag;
bus_space_handle_t handle;
area_id mapped_area;
};
// TODO: x86 specific!
#define I386_BUS_SPACE_IO 0
#define I386_BUS_SPACE_MEM 1
struct internal_intr {
device_t dev;
driver_intr_t handler;
void *arg;
int irq;
device_t dev;
driver_filter_t filter;
driver_intr_t handler;
void *arg;
int irq;
uint32 flags;
thread_id thread;
sem_id sem;
thread_id thread;
sem_id sem;
};
@ -73,9 +73,9 @@ bus_alloc_irq_resource(device_t dev, struct resource *res)
if (irq == 0 || irq == 0xff)
return -1;
/* XXX */
res->tag = 0;
res->handle = irq;
/* TODO: IRQ resources! */
res->r_bustag = 0;
res->r_bushandle = irq;
return 0;
}
@ -88,14 +88,13 @@ bus_alloc_mem_resource(device_t dev, struct resource *res, int regid)
uint32 size = 128 * 1024; /* XXX */
void *virtualAddr;
res->mapped_area = map_mem(&virtualAddr, (void *)addr, size, 0,
res->r_mapped_area = map_mem(&virtualAddr, (void *)addr, size, 0,
"bus_alloc_resource(MEMORY)");
if (res->mapped_area < 0)
if (res->r_mapped_area < B_OK)
return -1;
res->tag = I386_BUS_SPACE_MEM;
res->handle = (bus_space_handle_t)virtualAddr;
res->r_bustag = I386_BUS_SPACE_MEM;
res->r_bushandle = (bus_space_handle_t)virtualAddr;
return 0;
}
@ -103,8 +102,8 @@ bus_alloc_mem_resource(device_t dev, struct resource *res, int regid)
static int
bus_alloc_ioport_resource(device_t dev, struct resource *res, int regid)
{
res->tag = I386_BUS_SPACE_IO;
res->handle = pci_read_config(dev, regid, 4) & PCI_address_io_mask;
res->r_bustag = I386_BUS_SPACE_IO;
res->r_bushandle = pci_read_config(dev, regid, 4) & PCI_address_io_mask;
return 0;
}
@ -140,7 +139,7 @@ bus_alloc_resource(device_t dev, int type, int *rid, unsigned long start,
return NULL;
}
res->type = type;
res->r_type = type;
return res;
}
@ -148,31 +147,74 @@ bus_alloc_resource(device_t dev, int type, int *rid, unsigned long start,
int
bus_release_resource(device_t dev, int type, int rid, struct resource *res)
{
if (res->type != type)
if (res->r_type != type)
panic("bus_release_resource: mismatch");
if (type == SYS_RES_MEMORY)
delete_area(res->mapped_area);
delete_area(res->r_mapped_area);
free(res);
return 0;
}
int
bus_alloc_resources(device_t dev, struct resource_spec *resourceSpec,
struct resource **resources)
{
int i;
for (i = 0; resourceSpec[i].type != -1; i++) {
resources[i] = bus_alloc_resource_any(dev,
resourceSpec[i].type, &resourceSpec[i].rid, resourceSpec[i].flags);
if (resources[i] == NULL
&& (resourceSpec[i].flags & RF_OPTIONAL) == 0) {
for (++i; resourceSpec[i].type != -1; i++) {
resources[i] = NULL;
}
bus_release_resources(dev, resourceSpec, resources);
return ENXIO;
}
}
return 0;
}
void
bus_release_resources(device_t dev, const struct resource_spec *resourceSpec,
struct resource **resources)
{
int i;
for (i = 0; resourceSpec[i].type != -1; i++) {
if (resources[i] == NULL)
continue;
bus_release_resource(dev, resourceSpec[i].type, resourceSpec[i].rid,
resources[i]);
resources[i] = NULL;
}
}
bus_space_handle_t
rman_get_bushandle(struct resource *res)
{
return res->handle;
return res->r_bushandle;
}
bus_space_tag_t
rman_get_bustag(struct resource *res)
{
return res->tag;
return res->r_bustag;
}
// #pragma mark - Interrupt handling
static int32
intr_wrapper(void *data)
{
@ -236,7 +278,7 @@ free_internal_intr(struct internal_intr *intr)
int
bus_setup_intr(device_t dev, struct resource *res, int flags,
driver_intr_t handler, void *arg, void **cookiep)
driver_filter_t filter, driver_intr_t handler, void *arg, void **_cookie)
{
/* TODO check MPSAFE etc */
@ -249,16 +291,23 @@ bus_setup_intr(device_t dev, struct resource *res, int flags,
return B_NO_MEMORY;
intr->dev = dev;
intr->filter = filter;
intr->handler = handler;
intr->arg = arg;
intr->irq = res->handle;
intr->irq = res->r_bushandle;
intr->flags = flags;
if (flags & INTR_FAST) {
intr->sem = -1;
intr->thread = -1;
status = install_io_interrupt_handler(intr->irq,
intr_fast_wrapper, intr, 0);
if (filter != NULL) {
status = install_io_interrupt_handler(intr->irq,
(interrupt_handler)intr->filter, intr->arg, 0);
} else {
status = install_io_interrupt_handler(intr->irq,
intr_fast_wrapper, intr, 0);
}
} else {
snprintf(semName, sizeof(semName), "%s intr", dev->dev_name);
@ -289,8 +338,7 @@ bus_setup_intr(device_t dev, struct resource *res, int flags,
resume_thread(intr->thread);
*cookiep = intr;
*_cookie = intr;
return 0;
}
@ -299,12 +347,31 @@ int
bus_teardown_intr(device_t dev, struct resource *res, void *arg)
{
struct internal_intr *intr = arg;
remove_io_interrupt_handler(intr->irq, intr_wrapper, intr);
if (intr->filter != NULL) {
remove_io_interrupt_handler(intr->irq, (interrupt_handler)intr->filter,
intr->arg);
} else if (intr->flags & INTR_FAST) {
remove_io_interrupt_handler(intr->irq, intr_fast_wrapper, intr);
} else {
remove_io_interrupt_handler(intr->irq, intr_wrapper, intr);
}
free_internal_intr(intr);
return 0;
}
// #pragma mark - bus functions
bus_dma_tag_t
bus_get_dma_tag(device_t dev)
{
return NULL;
}
int
bus_generic_detach(device_t dev)
{

View File

@ -13,6 +13,7 @@
#include <KernelExport.h>
#include <compat/machine/resource.h>
#include <compat/dev/pci/pcireg.h>
#include <compat/dev/pci/pcivar.h>
#include <compat/sys/bus.h>
@ -135,6 +136,81 @@ pci_enable_io(device_t dev, int space)
}
int
pci_find_extcap(device_t child, int capability, int *_capabilityRegister)
{
uint8 capabilityPointer;
uint8 headerType;
uint16 status;
status = pci_read_config(child, PCIR_STATUS, 2);
if ((status & PCIM_STATUS_CAPPRESENT) == 0)
return ENXIO;
headerType = pci_read_config(child, PCI_header_type, 1);
switch (headerType & PCIM_HDRTYPE) {
case 0:
case 1:
capabilityPointer = PCIR_CAP_PTR;
break;
case 2:
capabilityPointer = PCIR_CAP_PTR_2;
break;
default:
return ENXIO;
}
capabilityPointer = pci_read_config(child, capabilityPointer, 1);
while (capabilityPointer != 0) {
if (pci_read_config(child, capabilityPointer + PCICAP_ID, 1)
== capability) {
if (_capabilityRegister != NULL)
*_capabilityRegister = capabilityPointer;
return 0;
}
capabilityPointer = pci_read_config(child,
capabilityPointer + PCICAP_NEXTPTR, 1);
}
return ENOENT;
}
int
pci_msi_count(device_t dev)
{
return 0;
}
int
pci_alloc_msi(device_t dev, int *count)
{
return ENODEV;
}
int
pci_release_msi(device_t dev)
{
return ENODEV;
}
int
pci_msix_count(device_t dev)
{
return 0;
}
int
pci_alloc_msix(device_t dev, int *count)
{
return ENODEV;
}
// #pragma mark - Device
@ -321,6 +397,13 @@ device_set_driver(device_t dev, driver_t *driver)
}
int
device_is_alive(device_t dev)
{
return dev->driver != NULL;
}
void
uninit_device(device_t dev)
{
@ -397,7 +480,7 @@ __haiku_probe_miibus(device_t dev, driver_t *drivers[], int count)
}
void
int
bus_generic_attach(device_t dev)
{
device_t child = NULL;
@ -415,9 +498,14 @@ bus_generic_attach(device_t dev)
} else if (child->driver == &miibus_driver)
child->methods.probe(child);
if (child->driver != NULL)
child->methods.attach(child);
if (child->driver != NULL) {
int result = child->methods.attach(child);
if (result != 0)
return result;
}
}
return 0;
}

View File

@ -1,19 +1,607 @@
#ifndef _FBSD_COMPAT_DEV_PCI_PCIREG_H_
#define _FBSD_COMPAT_DEV_PCI_PCIREG_H_
/*-
* Copyright (c) 1997, Stefan Esser <se@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 unmodified, 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/pci/pcireg.h,v 1.64 2007/09/19 13:05:58 sepotvin Exp $
*
*/
#define PCIR_COMMAND 0x04
#define PCIR_REVID 0x08
#define PCIR_CACHELNSZ 0x0c
#define PCIR_SUBVEND_0 0x2c
#define PCIR_SUBDEV_0 0x2e
/*
* PCIM_xxx: mask to locate subfield in register
* PCIR_xxx: config register offset
* PCIC_xxx: device class
* PCIS_xxx: device subclass
* PCIP_xxx: device programming interface
* PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
* PCID_xxx: device ID
* PCIY_xxx: capability identification number
*/
#define PCIM_CMD_PORTEN 0x0001
#define PCIM_CMD_MEMEN 0x0002
#define PCIM_CMD_BUSMASTEREN 0x0004
#define PCIM_CMD_MWRICEN 0x0010
/* some PCI bus constants */
#define PCIR_BARS 0x10
#define PCIR_BAR(x) (PCIR_BARS + (x) * 4)
#define PCIR_CIS 0x28
#define PCI_BUSMAX 255
#define PCI_SLOTMAX 31
#define PCI_FUNCMAX 7
#define PCI_REGMAX 255
#define PCI_MAXHDRTYPE 2
#endif
/* PCI config header registers for all devices */
#define PCIR_DEVVENDOR 0x00
#define PCIR_VENDOR 0x00
#define PCIR_DEVICE 0x02
#define PCIR_COMMAND 0x04
#define PCIM_CMD_PORTEN 0x0001
#define PCIM_CMD_MEMEN 0x0002
#define PCIM_CMD_BUSMASTEREN 0x0004
#define PCIM_CMD_SPECIALEN 0x0008
#define PCIM_CMD_MWRICEN 0x0010
#define PCIM_CMD_PERRESPEN 0x0040
#define PCIM_CMD_SERRESPEN 0x0100
#define PCIM_CMD_BACKTOBACK 0x0200
#define PCIR_STATUS 0x06
#define PCIM_STATUS_CAPPRESENT 0x0010
#define PCIM_STATUS_66CAPABLE 0x0020
#define PCIM_STATUS_BACKTOBACK 0x0080
#define PCIM_STATUS_PERRREPORT 0x0100
#define PCIM_STATUS_SEL_FAST 0x0000
#define PCIM_STATUS_SEL_MEDIMUM 0x0200
#define PCIM_STATUS_SEL_SLOW 0x0400
#define PCIM_STATUS_SEL_MASK 0x0600
#define PCIM_STATUS_STABORT 0x0800
#define PCIM_STATUS_RTABORT 0x1000
#define PCIM_STATUS_RMABORT 0x2000
#define PCIM_STATUS_SERR 0x4000
#define PCIM_STATUS_PERR 0x8000
#define PCIR_REVID 0x08
#define PCIR_PROGIF 0x09
#define PCIR_SUBCLASS 0x0a
#define PCIR_CLASS 0x0b
#define PCIR_CACHELNSZ 0x0c
#define PCIR_LATTIMER 0x0d
#define PCIR_HDRTYPE 0x0e
#define PCIM_HDRTYPE 0x7f
#define PCIM_HDRTYPE_NORMAL 0x00
#define PCIM_HDRTYPE_BRIDGE 0x01
#define PCIM_HDRTYPE_CARDBUS 0x02
#define PCIM_MFDEV 0x80
#define PCIR_BIST 0x0f
/* Capability Register Offsets */
#define PCICAP_ID 0x0
#define PCICAP_NEXTPTR 0x1
/* Capability Identification Numbers */
#define PCIY_PMG 0x01 /* PCI Power Management */
#define PCIY_AGP 0x02 /* AGP */
#define PCIY_VPD 0x03 /* Vital Product Data */
#define PCIY_SLOTID 0x04 /* Slot Identification */
#define PCIY_MSI 0x05 /* Message Signaled Interrupts */
#define PCIY_CHSWP 0x06 /* CompactPCI Hot Swap */
#define PCIY_PCIX 0x07 /* PCI-X */
#define PCIY_HT 0x08 /* HyperTransport */
#define PCIY_VENDOR 0x09 /* Vendor Unique */
#define PCIY_DEBUG 0x0a /* Debug port */
#define PCIY_CRES 0x0b /* CompactPCI central resource control */
#define PCIY_HOTPLUG 0x0c /* PCI Hot-Plug */
#define PCIY_SUBVENDOR 0x0d /* PCI-PCI bridge subvendor ID */
#define PCIY_AGP8X 0x0e /* AGP 8x */
#define PCIY_SECDEV 0x0f /* Secure Device */
#define PCIY_EXPRESS 0x10 /* PCI Express */
#define PCIY_MSIX 0x11 /* MSI-X */
/* config registers for header type 0 devices */
#define PCIR_BARS 0x10
#define PCIR_BAR(x) (PCIR_BARS + (x) * 4)
#define PCI_MAX_BAR_0 5 /* Number of standard bars */
#define PCI_RID2BAR(rid) (((rid) - PCIR_BARS) / 4)
#define PCI_BAR_IO(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_IO_SPACE)
#define PCI_BAR_MEM(x) (((x) & PCIM_BAR_SPACE) == PCIM_BAR_MEM_SPACE)
#define PCIM_BAR_SPACE 0x00000001
#define PCIM_BAR_MEM_SPACE 0
#define PCIM_BAR_IO_SPACE 1
#define PCIM_BAR_MEM_TYPE 0x00000006
#define PCIM_BAR_MEM_32 0
#define PCIM_BAR_MEM_1MB 2 /* Locate below 1MB in PCI <= 2.1 */
#define PCIM_BAR_MEM_64 4
#define PCIM_BAR_MEM_PREFETCH 0x00000008
#define PCIM_BAR_MEM_BASE 0xfffffff0
#define PCIM_BAR_IO_RESERVED 0x00000002
#define PCIM_BAR_IO_BASE 0xfffffffc
#define PCIR_CIS 0x28
#define PCIM_CIS_ASI_MASK 0x7
#define PCIM_CIS_ASI_CONFIG 0
#define PCIM_CIS_ASI_BAR0 1
#define PCIM_CIS_ASI_BAR1 2
#define PCIM_CIS_ASI_BAR2 3
#define PCIM_CIS_ASI_BAR3 4
#define PCIM_CIS_ASI_BAR4 5
#define PCIM_CIS_ASI_BAR5 6
#define PCIM_CIS_ASI_ROM 7
#define PCIM_CIS_ADDR_MASK 0x0ffffff8
#define PCIM_CIS_ROM_MASK 0xf0000000
#define PCIM_CIS_CONFIG_MASK 0xff
#define PCIR_SUBVEND_0 0x2c
#define PCIR_SUBDEV_0 0x2e
#define PCIR_BIOS 0x30
#define PCIM_BIOS_ENABLE 0x01
#define PCIM_BIOS_ADDR_MASK 0xfffff800
#define PCIR_CAP_PTR 0x34
#define PCIR_INTLINE 0x3c
#define PCIR_INTPIN 0x3d
#define PCIR_MINGNT 0x3e
#define PCIR_MAXLAT 0x3f
/* config registers for header type 1 (PCI-to-PCI bridge) devices */
#define PCIR_SECSTAT_1 0x1e
#define PCIR_PRIBUS_1 0x18
#define PCIR_SECBUS_1 0x19
#define PCIR_SUBBUS_1 0x1a
#define PCIR_SECLAT_1 0x1b
#define PCIR_IOBASEL_1 0x1c
#define PCIR_IOLIMITL_1 0x1d
#define PCIR_IOBASEH_1 0x30
#define PCIR_IOLIMITH_1 0x32
#define PCIM_BRIO_16 0x0
#define PCIM_BRIO_32 0x1
#define PCIM_BRIO_MASK 0xf
#define PCIR_MEMBASE_1 0x20
#define PCIR_MEMLIMIT_1 0x22
#define PCIR_PMBASEL_1 0x24
#define PCIR_PMLIMITL_1 0x26
#define PCIR_PMBASEH_1 0x28
#define PCIR_PMLIMITH_1 0x2c
#define PCIR_BRIDGECTL_1 0x3e
/* config registers for header type 2 (CardBus) devices */
#define PCIR_CAP_PTR_2 0x14
#define PCIR_SECSTAT_2 0x16
#define PCIR_PRIBUS_2 0x18
#define PCIR_SECBUS_2 0x19
#define PCIR_SUBBUS_2 0x1a
#define PCIR_SECLAT_2 0x1b
#define PCIR_MEMBASE0_2 0x1c
#define PCIR_MEMLIMIT0_2 0x20
#define PCIR_MEMBASE1_2 0x24
#define PCIR_MEMLIMIT1_2 0x28
#define PCIR_IOBASE0_2 0x2c
#define PCIR_IOLIMIT0_2 0x30
#define PCIR_IOBASE1_2 0x34
#define PCIR_IOLIMIT1_2 0x38
#define PCIR_BRIDGECTL_2 0x3e
#define PCIR_SUBVEND_2 0x40
#define PCIR_SUBDEV_2 0x42
#define PCIR_PCCARDIF_2 0x44
/* PCI device class, subclass and programming interface definitions */
#define PCIC_OLD 0x00
#define PCIS_OLD_NONVGA 0x00
#define PCIS_OLD_VGA 0x01
#define PCIC_STORAGE 0x01
#define PCIS_STORAGE_SCSI 0x00
#define PCIS_STORAGE_IDE 0x01
#define PCIP_STORAGE_IDE_MODEPRIM 0x01
#define PCIP_STORAGE_IDE_PROGINDPRIM 0x02
#define PCIP_STORAGE_IDE_MODESEC 0x04
#define PCIP_STORAGE_IDE_PROGINDSEC 0x08
#define PCIP_STORAGE_IDE_MASTERDEV 0x80
#define PCIS_STORAGE_FLOPPY 0x02
#define PCIS_STORAGE_IPI 0x03
#define PCIS_STORAGE_RAID 0x04
#define PCIS_STORAGE_ATA_ADMA 0x05
#define PCIS_STORAGE_SATA 0x06
#define PCIP_STORAGE_SATA_AHCI_1_0 0x01
#define PCIS_STORAGE_SAS 0x07
#define PCIS_STORAGE_OTHER 0x80
#define PCIC_NETWORK 0x02
#define PCIS_NETWORK_ETHERNET 0x00
#define PCIS_NETWORK_TOKENRING 0x01
#define PCIS_NETWORK_FDDI 0x02
#define PCIS_NETWORK_ATM 0x03
#define PCIS_NETWORK_ISDN 0x04
#define PCIS_NETWORK_WORLDFIP 0x05
#define PCIS_NETWORK_PICMG 0x06
#define PCIS_NETWORK_OTHER 0x80
#define PCIC_DISPLAY 0x03
#define PCIS_DISPLAY_VGA 0x00
#define PCIS_DISPLAY_XGA 0x01
#define PCIS_DISPLAY_3D 0x02
#define PCIS_DISPLAY_OTHER 0x80
#define PCIC_MULTIMEDIA 0x04
#define PCIS_MULTIMEDIA_VIDEO 0x00
#define PCIS_MULTIMEDIA_AUDIO 0x01
#define PCIS_MULTIMEDIA_TELE 0x02
#define PCIS_MULTIMEDIA_OTHER 0x80
#define PCIC_MEMORY 0x05
#define PCIS_MEMORY_RAM 0x00
#define PCIS_MEMORY_FLASH 0x01
#define PCIS_MEMORY_OTHER 0x80
#define PCIC_BRIDGE 0x06
#define PCIS_BRIDGE_HOST 0x00
#define PCIS_BRIDGE_ISA 0x01
#define PCIS_BRIDGE_EISA 0x02
#define PCIS_BRIDGE_MCA 0x03
#define PCIS_BRIDGE_PCI 0x04
#define PCIP_BRIDGE_PCI_SUBTRACTIVE 0x01
#define PCIS_BRIDGE_PCMCIA 0x05
#define PCIS_BRIDGE_NUBUS 0x06
#define PCIS_BRIDGE_CARDBUS 0x07
#define PCIS_BRIDGE_RACEWAY 0x08
#define PCIS_BRIDGE_PCI_TRANSPARENT 0x09
#define PCIS_BRIDGE_INFINIBAND 0x0a
#define PCIS_BRIDGE_OTHER 0x80
#define PCIC_SIMPLECOMM 0x07
#define PCIS_SIMPLECOMM_UART 0x00
#define PCIP_SIMPLECOMM_UART_8250 0x00
#define PCIP_SIMPLECOMM_UART_16450A 0x01
#define PCIP_SIMPLECOMM_UART_16550A 0x02
#define PCIP_SIMPLECOMM_UART_16650A 0x03
#define PCIP_SIMPLECOMM_UART_16750A 0x04
#define PCIP_SIMPLECOMM_UART_16850A 0x05
#define PCIP_SIMPLECOMM_UART_16950A 0x06
#define PCIS_SIMPLECOMM_PAR 0x01
#define PCIS_SIMPLECOMM_MULSER 0x02
#define PCIS_SIMPLECOMM_MODEM 0x03
#define PCIS_SIMPLECOMM_GPIB 0x04
#define PCIS_SIMPLECOMM_SMART_CARD 0x05
#define PCIS_SIMPLECOMM_OTHER 0x80
#define PCIC_BASEPERIPH 0x08
#define PCIS_BASEPERIPH_PIC 0x00
#define PCIP_BASEPERIPH_PIC_8259A 0x00
#define PCIP_BASEPERIPH_PIC_ISA 0x01
#define PCIP_BASEPERIPH_PIC_EISA 0x02
#define PCIP_BASEPERIPH_PIC_IO_APIC 0x10
#define PCIP_BASEPERIPH_PIC_IOX_APIC 0x20
#define PCIS_BASEPERIPH_DMA 0x01
#define PCIS_BASEPERIPH_TIMER 0x02
#define PCIS_BASEPERIPH_RTC 0x03
#define PCIS_BASEPERIPH_PCIHOT 0x04
#define PCIS_BASEPERIPH_SDHC 0x05
#define PCIS_BASEPERIPH_OTHER 0x80
#define PCIC_INPUTDEV 0x09
#define PCIS_INPUTDEV_KEYBOARD 0x00
#define PCIS_INPUTDEV_DIGITIZER 0x01
#define PCIS_INPUTDEV_MOUSE 0x02
#define PCIS_INPUTDEV_SCANNER 0x03
#define PCIS_INPUTDEV_GAMEPORT 0x04
#define PCIS_INPUTDEV_OTHER 0x80
#define PCIC_DOCKING 0x0a
#define PCIS_DOCKING_GENERIC 0x00
#define PCIS_DOCKING_OTHER 0x80
#define PCIC_PROCESSOR 0x0b
#define PCIS_PROCESSOR_386 0x00
#define PCIS_PROCESSOR_486 0x01
#define PCIS_PROCESSOR_PENTIUM 0x02
#define PCIS_PROCESSOR_ALPHA 0x10
#define PCIS_PROCESSOR_POWERPC 0x20
#define PCIS_PROCESSOR_MIPS 0x30
#define PCIS_PROCESSOR_COPROC 0x40
#define PCIC_SERIALBUS 0x0c
#define PCIS_SERIALBUS_FW 0x00
#define PCIS_SERIALBUS_ACCESS 0x01
#define PCIS_SERIALBUS_SSA 0x02
#define PCIS_SERIALBUS_USB 0x03
#define PCIP_SERIALBUS_USB_UHCI 0x00
#define PCIP_SERIALBUS_USB_OHCI 0x10
#define PCIP_SERIALBUS_USB_EHCI 0x20
#define PCIP_SERIALBUS_USB_DEVICE 0xfe
#define PCIS_SERIALBUS_FC 0x04
#define PCIS_SERIALBUS_SMBUS 0x05
#define PCIS_SERIALBUS_INFINIBAND 0x06
#define PCIS_SERIALBUS_IPMI 0x07
#define PCIP_SERIALBUS_IPMI_SMIC 0x00
#define PCIP_SERIALBUS_IPMI_KCS 0x01
#define PCIP_SERIALBUS_IPMI_BT 0x02
#define PCIS_SERIALBUS_SERCOS 0x08
#define PCIS_SERIALBUS_CANBUS 0x09
#define PCIC_WIRELESS 0x0d
#define PCIS_WIRELESS_IRDA 0x00
#define PCIS_WIRELESS_IR 0x01
#define PCIS_WIRELESS_RF 0x10
#define PCIS_WIRELESS_BLUETOOTH 0x11
#define PCIS_WIRELESS_BROADBAND 0x12
#define PCIS_WIRELESS_80211A 0x20
#define PCIS_WIRELESS_80211B 0x21
#define PCIS_WIRELESS_OTHER 0x80
#define PCIC_INTELLIIO 0x0e
#define PCIS_INTELLIIO_I2O 0x00
#define PCIC_SATCOM 0x0f
#define PCIS_SATCOM_TV 0x01
#define PCIS_SATCOM_AUDIO 0x02
#define PCIS_SATCOM_VOICE 0x03
#define PCIS_SATCOM_DATA 0x04
#define PCIC_CRYPTO 0x10
#define PCIS_CRYPTO_NETCOMP 0x00
#define PCIS_CRYPTO_ENTERTAIN 0x10
#define PCIS_CRYPTO_OTHER 0x80
#define PCIC_DASP 0x11
#define PCIS_DASP_DPIO 0x00
#define PCIS_DASP_PERFCNTRS 0x01
#define PCIS_DASP_COMM_SYNC 0x10
#define PCIS_DASP_MGMT_CARD 0x20
#define PCIS_DASP_OTHER 0x80
#define PCIC_OTHER 0xff
/* Bridge Control Values. */
#define PCIB_BCR_PERR_ENABLE 0x0001
#define PCIB_BCR_SERR_ENABLE 0x0002
#define PCIB_BCR_ISA_ENABLE 0x0004
#define PCIB_BCR_VGA_ENABLE 0x0008
#define PCIB_BCR_MASTER_ABORT_MODE 0x0020
#define PCIB_BCR_SECBUS_RESET 0x0040
#define PCIB_BCR_SECBUS_BACKTOBACK 0x0080
#define PCIB_BCR_PRI_DISCARD_TIMEOUT 0x0100
#define PCIB_BCR_SEC_DISCARD_TIMEOUT 0x0200
#define PCIB_BCR_DISCARD_TIMER_STATUS 0x0400
#define PCIB_BCR_DISCARD_TIMER_SERREN 0x0800
/* PCI power manangement */
#define PCIR_POWER_CAP 0x2
#define PCIM_PCAP_SPEC 0x0007
#define PCIM_PCAP_PMEREQCLK 0x0008
#define PCIM_PCAP_PMEREQPWR 0x0010
#define PCIM_PCAP_DEVSPECINIT 0x0020
#define PCIM_PCAP_DYNCLOCK 0x0040
#define PCIM_PCAP_SECCLOCK 0x00c0
#define PCIM_PCAP_CLOCKMASK 0x00c0
#define PCIM_PCAP_REQFULLCLOCK 0x0100
#define PCIM_PCAP_D1SUPP 0x0200
#define PCIM_PCAP_D2SUPP 0x0400
#define PCIM_PCAP_D0PME 0x0800
#define PCIM_PCAP_D1PME 0x1000
#define PCIM_PCAP_D2PME 0x2000
#define PCIM_PCAP_D3PME_HOT 0x4000
#define PCIM_PCAP_D3PME_COLD 0x8000
#define PCIR_POWER_STATUS 0x4
#define PCIM_PSTAT_D0 0x0000
#define PCIM_PSTAT_D1 0x0001
#define PCIM_PSTAT_D2 0x0002
#define PCIM_PSTAT_D3 0x0003
#define PCIM_PSTAT_DMASK 0x0003
#define PCIM_PSTAT_REPENABLE 0x0010
#define PCIM_PSTAT_PMEENABLE 0x0100
#define PCIM_PSTAT_D0POWER 0x0000
#define PCIM_PSTAT_D1POWER 0x0200
#define PCIM_PSTAT_D2POWER 0x0400
#define PCIM_PSTAT_D3POWER 0x0600
#define PCIM_PSTAT_D0HEAT 0x0800
#define PCIM_PSTAT_D1HEAT 0x1000
#define PCIM_PSTAT_D2HEAT 0x1200
#define PCIM_PSTAT_D3HEAT 0x1400
#define PCIM_PSTAT_DATAUNKN 0x0000
#define PCIM_PSTAT_DATADIV10 0x2000
#define PCIM_PSTAT_DATADIV100 0x4000
#define PCIM_PSTAT_DATADIV1000 0x6000
#define PCIM_PSTAT_DATADIVMASK 0x6000
#define PCIM_PSTAT_PME 0x8000
#define PCIR_POWER_PMCSR 0x6
#define PCIM_PMCSR_DCLOCK 0x10
#define PCIM_PMCSR_B2SUPP 0x20
#define PCIM_BMCSR_B3SUPP 0x40
#define PCIM_BMCSR_BPCE 0x80
#define PCIR_POWER_DATA 0x7
/* VPD capability registers */
#define PCIR_VPD_ADDR 0x2
#define PCIR_VPD_DATA 0x4
/* PCI Message Signalled Interrupts (MSI) */
#define PCIR_MSI_CTRL 0x2
#define PCIM_MSICTRL_VECTOR 0x0100
#define PCIM_MSICTRL_64BIT 0x0080
#define PCIM_MSICTRL_MME_MASK 0x0070
#define PCIM_MSICTRL_MME_1 0x0000
#define PCIM_MSICTRL_MME_2 0x0010
#define PCIM_MSICTRL_MME_4 0x0020
#define PCIM_MSICTRL_MME_8 0x0030
#define PCIM_MSICTRL_MME_16 0x0040
#define PCIM_MSICTRL_MME_32 0x0050
#define PCIM_MSICTRL_MMC_MASK 0x000E
#define PCIM_MSICTRL_MMC_1 0x0000
#define PCIM_MSICTRL_MMC_2 0x0002
#define PCIM_MSICTRL_MMC_4 0x0004
#define PCIM_MSICTRL_MMC_8 0x0006
#define PCIM_MSICTRL_MMC_16 0x0008
#define PCIM_MSICTRL_MMC_32 0x000A
#define PCIM_MSICTRL_MSI_ENABLE 0x0001
#define PCIR_MSI_ADDR 0x4
#define PCIR_MSI_ADDR_HIGH 0x8
#define PCIR_MSI_DATA 0x8
#define PCIR_MSI_DATA_64BIT 0xc
#define PCIR_MSI_MASK 0x10
#define PCIR_MSI_PENDING 0x14
/* PCI-X definitions */
/* For header type 0 devices */
#define PCIXR_COMMAND 0x2
#define PCIXM_COMMAND_DPERR_E 0x0001 /* Data Parity Error Recovery */
#define PCIXM_COMMAND_ERO 0x0002 /* Enable Relaxed Ordering */
#define PCIXM_COMMAND_MAX_READ 0x000c /* Maximum Burst Read Count */
#define PCIXM_COMMAND_MAX_READ_512 0x0000
#define PCIXM_COMMAND_MAX_READ_1024 0x0004
#define PCIXM_COMMAND_MAX_READ_2048 0x0008
#define PCIXM_COMMAND_MAX_READ_4096 0x000c
#define PCIXM_COMMAND_MAX_SPLITS 0x0070 /* Maximum Split Transactions */
#define PCIXM_COMMAND_MAX_SPLITS_1 0x0000
#define PCIXM_COMMAND_MAX_SPLITS_2 0x0010
#define PCIXM_COMMAND_MAX_SPLITS_3 0x0020
#define PCIXM_COMMAND_MAX_SPLITS_4 0x0030
#define PCIXM_COMMAND_MAX_SPLITS_8 0x0040
#define PCIXM_COMMAND_MAX_SPLITS_12 0x0050
#define PCIXM_COMMAND_MAX_SPLITS_16 0x0060
#define PCIXM_COMMAND_MAX_SPLITS_32 0x0070
#define PCIXM_COMMAND_VERSION 0x3000
#define PCIXR_STATUS 0x4
#define PCIXM_STATUS_DEVFN 0x000000FF
#define PCIXM_STATUS_BUS 0x0000FF00
#define PCIXM_STATUS_64BIT 0x00010000
#define PCIXM_STATUS_133CAP 0x00020000
#define PCIXM_STATUS_SC_DISCARDED 0x00040000
#define PCIXM_STATUS_UNEXP_SC 0x00080000
#define PCIXM_STATUS_COMPLEX_DEV 0x00100000
#define PCIXM_STATUS_MAX_READ 0x00600000
#define PCIXM_STATUS_MAX_READ_512 0x00000000
#define PCIXM_STATUS_MAX_READ_1024 0x00200000
#define PCIXM_STATUS_MAX_READ_2048 0x00400000
#define PCIXM_STATUS_MAX_READ_4096 0x00600000
#define PCIXM_STATUS_MAX_SPLITS 0x03800000
#define PCIXM_STATUS_MAX_SPLITS_1 0x00000000
#define PCIXM_STATUS_MAX_SPLITS_2 0x00800000
#define PCIXM_STATUS_MAX_SPLITS_3 0x01000000
#define PCIXM_STATUS_MAX_SPLITS_4 0x01800000
#define PCIXM_STATUS_MAX_SPLITS_8 0x02000000
#define PCIXM_STATUS_MAX_SPLITS_12 0x02800000
#define PCIXM_STATUS_MAX_SPLITS_16 0x03000000
#define PCIXM_STATUS_MAX_SPLITS_32 0x03800000
#define PCIXM_STATUS_MAX_CUM_READ 0x1C000000
#define PCIXM_STATUS_RCVD_SC_ERR 0x20000000
#define PCIXM_STATUS_266CAP 0x40000000
#define PCIXM_STATUS_533CAP 0x80000000
/* For header type 1 devices (PCI-X bridges) */
#define PCIXR_SEC_STATUS 0x2
#define PCIXM_SEC_STATUS_64BIT 0x0001
#define PCIXM_SEC_STATUS_133CAP 0x0002
#define PCIXM_SEC_STATUS_SC_DISC 0x0004
#define PCIXM_SEC_STATUS_UNEXP_SC 0x0008
#define PCIXM_SEC_STATUS_SC_OVERRUN 0x0010
#define PCIXM_SEC_STATUS_SR_DELAYED 0x0020
#define PCIXM_SEC_STATUS_BUS_MODE 0x03c0
#define PCIXM_SEC_STATUS_VERSION 0x3000
#define PCIXM_SEC_STATUS_266CAP 0x4000
#define PCIXM_SEC_STATUS_533CAP 0x8000
#define PCIXR_BRIDGE_STATUS 0x4
#define PCIXM_BRIDGE_STATUS_DEVFN 0x000000FF
#define PCIXM_BRIDGE_STATUS_BUS 0x0000FF00
#define PCIXM_BRIDGE_STATUS_64BIT 0x00010000
#define PCIXM_BRIDGE_STATUS_133CAP 0x00020000
#define PCIXM_BRIDGE_STATUS_SC_DISCARDED 0x00040000
#define PCIXM_BRIDGE_STATUS_UNEXP_SC 0x00080000
#define PCIXM_BRIDGE_STATUS_SC_OVERRUN 0x00100000
#define PCIXM_BRIDGE_STATUS_SR_DELAYED 0x00200000
#define PCIXM_BRIDGE_STATUS_DEVID_MSGCAP 0x20000000
#define PCIXM_BRIDGE_STATUS_266CAP 0x40000000
#define PCIXM_BRIDGE_STATUS_533CAP 0x80000000
/* HT (HyperTransport) Capability definitions */
#define PCIR_HT_COMMAND 0x2
#define PCIM_HTCMD_CAP_MASK 0xf800 /* Capability type. */
#define PCIM_HTCAP_SLAVE 0x0000 /* 000xx */
#define PCIM_HTCAP_HOST 0x2000 /* 001xx */
#define PCIM_HTCAP_SWITCH 0x4000 /* 01000 */
#define PCIM_HTCAP_INTERRUPT 0x8000 /* 10000 */
#define PCIM_HTCAP_REVISION_ID 0x8800 /* 10001 */
#define PCIM_HTCAP_UNITID_CLUMPING 0x9000 /* 10010 */
#define PCIM_HTCAP_EXT_CONFIG_SPACE 0x9800 /* 10011 */
#define PCIM_HTCAP_ADDRESS_MAPPING 0xa000 /* 10100 */
#define PCIM_HTCAP_MSI_MAPPING 0xa800 /* 10101 */
#define PCIM_HTCAP_DIRECT_ROUTE 0xb000 /* 10110 */
#define PCIM_HTCAP_VCSET 0xb800 /* 10111 */
#define PCIM_HTCAP_RETRY_MODE 0xc000 /* 11000 */
#define PCIM_HTCAP_X86_ENCODING 0xc800 /* 11001 */
/* HT MSI Mapping Capability definitions. */
#define PCIM_HTCMD_MSI_ENABLE 0x0001
#define PCIM_HTCMD_MSI_FIXED 0x0002
#define PCIR_HTMSI_ADDRESS_LO 0x4
#define PCIR_HTMSI_ADDRESS_HI 0x8
/* PCI Vendor capability definitions */
#define PCIR_VENDOR_LENGTH 0x2
#define PCIR_VENDOR_DATA 0x3
/* PCI EHCI Debug Port definitions */
#define PCIR_DEBUG_PORT 0x2
#define PCIM_DEBUG_PORT_OFFSET 0x1FFF
#define PCIM_DEBUG_PORT_BAR 0xe000
/* PCI-PCI Bridge Subvendor definitions */
#define PCIR_SUBVENDCAP_ID 0x4
/* PCI Express definitions */
#define PCIR_EXPRESS_FLAGS 0x2
#define PCIM_EXP_FLAGS_VERSION 0x000F
#define PCIM_EXP_FLAGS_TYPE 0x00F0
#define PCIM_EXP_TYPE_ENDPOINT 0x0000
#define PCIM_EXP_TYPE_LEGACY_ENDPOINT 0x0010
#define PCIM_EXP_TYPE_ROOT_PORT 0x0040
#define PCIM_EXP_TYPE_UPSTREAM_PORT 0x0050
#define PCIM_EXP_TYPE_DOWNSTREAM_PORT 0x0060
#define PCIM_EXP_TYPE_PCI_BRIDGE 0x0070
#define PCIM_EXP_FLAGS_SLOT 0x0100
#define PCIM_EXP_FLAGS_IRQ 0x3e00
/* MSI-X definitions */
#define PCIR_MSIX_CTRL 0x2
#define PCIM_MSIXCTRL_MSIX_ENABLE 0x8000
#define PCIM_MSIXCTRL_FUNCTION_MASK 0x4000
#define PCIM_MSIXCTRL_TABLE_SIZE 0x07FF
#define PCIR_MSIX_TABLE 0x4
#define PCIR_MSIX_PBA 0x8
#define PCIM_MSIX_BIR_MASK 0x7
#define PCIM_MSIX_BIR_BAR_10 0
#define PCIM_MSIX_BIR_BAR_14 1
#define PCIM_MSIX_BIR_BAR_18 2
#define PCIM_MSIX_BIR_BAR_1C 3
#define PCIM_MSIX_BIR_BAR_20 4
#define PCIM_MSIX_BIR_BAR_24 5
#define PCIM_MSIX_VCTRL_MASK 0x1

View File

@ -1,8 +1,14 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_COMPAT_DEV_PCI_PCIVAR_H_
#define _FBSD_COMPAT_DEV_PCI_PCIVAR_H_
#include <sys/bus.h>
int pci_enable_busmaster(device_t dev);
int pci_enable_io(device_t dev, int reg);
@ -19,4 +25,12 @@ uint8_t pci_get_revid(device_t dev);
uint32_t pci_read_config(device_t dev, int reg, int width);
void pci_write_config(device_t dev, int reg, uint32_t val, int width);
#endif
int pci_find_extcap(device_t dev, int capability, int *capreg);
int pci_msi_count(device_t dev);
int pci_alloc_msi(device_t dev, int *count);
int pci_release_msi(device_t dev);
int pci_msix_count(device_t dev);
int pci_alloc_msix(device_t dev, int *count);
#endif /* _FBSD_COMPAT_DEV_PCI_PCIVAR_H_ */

View File

@ -1,12 +1,24 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_COMPAT_MACHINE_ATOMIC_H_
#define _FBSD_COMPAT_MACHINE_ATOMIC_H_
#include <KernelExport.h>
#define atomic_add_int(ptr, value) \
atomic_add((int32 *)ptr, value)
atomic_add((int32 *)(ptr), value)
#define atomic_subtract_int(ptr, value) \
atomic_add((int32 *)ptr, -value)
atomic_add((int32 *)(ptr), -value)
#endif
#define atomic_set_acq_32(ptr, value) \
atomic_set_int(ptr, value)
#define atomic_set_int(ptr, value) \
atomic_or((int32 *)(ptr), value);
#endif /* _FBSD_COMPAT_MACHINE_ATOMIC_H_ */

View File

@ -0,0 +1,30 @@
/*
* Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_COMPAT_MACHINE_IN_CKSUM_H_
#define _FBSD_COMPAT_MACHINE_IN_CKSUM_H_
#include <stdint.h>
static inline u_short
in_pseudo(u_int sum, u_int b, u_int c)
{
// should never be called
panic("in_pseudo() called");
return 0;
}
#define in_cksum(m, len) in_cksum_skip(m, len, 0)
static inline u_short
in_cksum_skip(struct mbuf* m, int len, int skip)
{
// should never be called
panic("in_cksum_skip() called");
return 0;
}
#endif /* _FBSD_COMPAT_MACHINE_IN_CKSUM_H_ */

View File

@ -1,7 +1,17 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_COMPAT_NET_BPF_H_
#define _FBSD_COMPAT_NET_BPF_H_
#define bpf_mtap(bpf_if, mbuf) do { } while (0)
#define BPF_MTAP(ifp, m) do { } while (0)
#endif
static inline int
bpf_peers_present(struct bpf_if *bpf)
{
return 0;
}
#endif /* _FBSD_COMPAT_NET_BPF_H_ */

View File

@ -1,7 +1,7 @@
/*
* Fundamental constants relating to ethernet.
*
* $FreeBSD: src/sys/net/ethernet.h,v 1.24 2004/10/05 19:28:52 sam Exp $
* $FreeBSD: src/sys/net/ethernet.h,v 1.32 2007/05/29 12:40:45 yar Exp $
*
*/
@ -57,18 +57,23 @@
/*
* Structure of a 10Mb/s Ethernet header.
*/
struct ether_header {
struct ether_header {
u_char ether_dhost[ETHER_ADDR_LEN];
u_char ether_shost[ETHER_ADDR_LEN];
u_short ether_type;
};
} __packed;
/*
* Structure of a 48-bit Ethernet address.
*/
struct ether_addr {
struct ether_addr {
u_char octet[ETHER_ADDR_LEN];
};
} __packed;
#ifdef CTASSERT
CTASSERT(sizeof (struct ether_header) == ETHER_ADDR_LEN * 2 + 2);
CTASSERT(sizeof (struct ether_addr) == ETHER_ADDR_LEN);
#endif
#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
@ -311,6 +316,7 @@ struct ether_addr {
#define ETHERTYPE_IPAS 0x876C /* IP Autonomous Systems (RFC1701) */
#define ETHERTYPE_SECUREDATA 0x876D /* Secure Data (RFC1701) */
#define ETHERTYPE_FLOWCONTROL 0x8808 /* 802.3x flow control packet */
#define ETHERTYPE_SLOW 0x8809 /* 802.3ad link aggregation (LACP) */
#define ETHERTYPE_PPP 0x880B /* PPP (obsolete by PPPOE) */
#define ETHERTYPE_HITACHI 0x8820 /* Hitachi Cable (Optoelectronic Systems Laboratory) */
#define ETHERTYPE_MPLS 0x8847 /* MPLS Unicast */
@ -343,6 +349,15 @@ struct ether_addr {
#define ETHERMTU (ETHER_MAX_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
#define ETHERMIN (ETHER_MIN_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
#define ETHERMTU_JUMBO (ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN)
/*
* The ETHER_BPF_MTAP macro should be used by drivers which support hardware
* offload for VLAN tag processing. It will check the mbuf to see if it has
* M_VLANTAG set, and if it does, will pass the packet along to
* ether_vlan_mtap. This function will re-insert VLAN tags for the duration
* of the tap, so they show up properly for network analyzers.
*/
#define ETHER_BPF_MTAP(_ifp, _m) do { \
} while (0)
#ifdef _KERNEL
@ -350,17 +365,20 @@ struct ifnet;
struct mbuf;
struct rtentry;
struct sockaddr;
struct bpf_if;
extern uint32_t ether_crc32_le(const uint8_t *, size_t);
extern uint32_t ether_crc32_be(const uint8_t *, size_t);
extern void ether_demux(struct ifnet *, struct mbuf *);
extern void ether_ifattach(struct ifnet *, const u_int8_t *);
extern void ether_ifdetach(struct ifnet *);
extern int ether_ioctl(struct ifnet *, int, caddr_t);
extern int ether_ioctl(struct ifnet *, u_long, caddr_t);
extern int ether_output(struct ifnet *,
struct mbuf *, struct sockaddr *, struct rtentry *);
extern int ether_output_frame(struct ifnet *, struct mbuf *);
extern char *ether_sprintf(const u_int8_t *);
void ether_vlan_mtap(struct bpf_if *, struct mbuf *,
void *, u_int);
#else /* _KERNEL */
@ -371,9 +389,11 @@ extern char *ether_sprintf(const u_int8_t *);
*/
__BEGIN_DECLS
struct ether_addr *ether_aton(const char *);
struct ether_addr *ether_aton_r(const char *, struct ether_addr *);
int ether_hostton(const char *, struct ether_addr *);
int ether_line(const char *, struct ether_addr *, char *);
char *ether_ntoa(const struct ether_addr *);
char *ether_ntoa_r(const struct ether_addr *, char *);
int ether_ntohost(char *, const struct ether_addr *);
__END_DECLS

View File

@ -1,9 +1,14 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_COMPAT_NET_IF_H_
#define _FBSD_COMPAT_NET_IF_H_
#include <posix/net/if.h>
#include <sys/time.h> /* for timeval */
#include <sys/time.h>
#define IF_Kbps(x) ((x) * 1000)
@ -19,6 +24,8 @@
#define IFCAP_VLAN_HWTAGGING 0x0010 /* hardware VLAN tag support */
#define IFCAP_JUMBO_MTU 0x0020 /* 9000 byte MTU supported */
#define IFCAP_POLLING 0x0040 /* driver supports polling */
#define IFCAP_VLAN_HWCSUM 0x0080
#define IFCAP_TSO4 0x0100 /* supports TCP segmentation offload */
#define IFCAP_HWCSUM (IFCAP_RXCSUM | IFCAP_TXCSUM)

View File

@ -26,7 +26,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/net/if_vlan_var.h,v 1.21.2.2 2006/01/13 19:21:45 glebius Exp $
* $FreeBSD: src/sys/net/if_vlan_var.h,v 1.26 2007/02/28 22:05:30 bms Exp $
*/
#ifndef _NET_IF_VLAN_VAR_H_
@ -40,9 +40,40 @@ struct ether_vlan_header {
u_int16_t evl_proto;
};
#define EVL_VLID_MASK 0x0FFF
#define EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK)
#define EVL_PRIOFTAG(tag) (((tag) >> 13) & 7)
#define EVL_VLID_MASK 0x0FFF
#define EVL_PRI_MASK 0xE000
#define EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK)
#define EVL_PRIOFTAG(tag) (((tag) >> 13) & 7)
#define EVL_CFIOFTAG(tag) (((tag) >> 12) & 1)
#define EVL_MAKETAG(vlid, pri, cfi) \
((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK))
/* Set the VLAN ID in an mbuf packet header non-destructively. */
#define EVL_APPLY_VLID(m, vlid) \
do { \
if ((m)->m_flags & M_VLANTAG) { \
(m)->m_pkthdr.ether_vtag &= EVL_VLID_MASK; \
(m)->m_pkthdr.ether_vtag |= (vlid); \
} else { \
(m)->m_pkthdr.ether_vtag = (vlid); \
(m)->m_flags |= M_VLANTAG; \
} \
} while (0)
/* Set the priority ID in an mbuf packet header non-destructively. */
#define EVL_APPLY_PRI(m, pri) \
do { \
if ((m)->m_flags & M_VLANTAG) { \
uint16_t __vlantag = (m)->m_pkthdr.ether_vtag; \
(m)->m_pkthdr.ether_vtag |= EVL_MAKETAG( \
EVL_VLANOFTAG(__vlantag), (pri), \
EVL_CFIOFTAG(__vlantag)); \
} else { \
(m)->m_pkthdr.ether_vtag = \
EVL_MAKETAG(0, (pri), 0); \
(m)->m_flags |= M_VLANTAG; \
} \
} while (0)
/* sysctl(3) tags, for compatibility purposes */
#define VLANCTL_PROTO 1
@ -59,11 +90,6 @@ struct vlanreq {
#define SIOCGETVLAN SIOCGIFGENERIC
#ifdef _KERNEL
#if 1
#define VLAN_INPUT_TAG_NEW(_ifp, _m, _t) do { } while (0)
#define VLAN_OUTPUT_TAG(_ifp, _m) NULL
#define VLAN_TAG_VALUE(_mt) 0
#else
/*
* Drivers that are capable of adding and removing the VLAN header
* in hardware indicate they support this by marking IFCAP_VLAN_HWTAGGING
@ -75,78 +101,35 @@ struct vlanreq {
*/
/*
* Drivers that support hardware VLAN tagging pass a packet's tag
* up through the stack by appending a packet tag with this value.
* Output is handled likewise, the driver must locate the packet
* tag to extract the VLAN tag. The following macros are used to
* do this work. On input, do:
* VLAN tags are stored in host byte order. Byte swapping may be
* necessary.
*
* VLAN_INPUT_TAG(ifp, m, tag,);
* Drivers that support hardware VLAN tag stripping fill in the
* received VLAN tag (containing both vlan and priority information)
* into the ether_vtag mbuf packet header field:
*
* to mark the packet m with the specified VLAN tag. The last
* parameter provides code to execute in case of an error. On
* output the driver should check mbuf to see if a VLAN tag is
* present and only then check for a tag; this is done with:
* m->m_pkthdr.ether_vtag = vlan_id; // ntohs()?
* m->m_flags |= M_VLANTAG;
*
* struct m_tag *mtag;
* mtag = VLAN_OUTPUT_TAG(ifp, m);
* if (mtag != NULL) {
* ... = VLAN_TAG_VALUE(mtag);
* to mark the packet m with the specified VLAN tag.
*
* On output the driver should check the mbuf for the M_VLANTAG
* flag to see if a VLAN tag is present and valid:
*
* if (m->m_flags & M_VLANTAG) {
* ... = m->m_pkthdr.ether_vtag; // htons()?
* ... pass tag to hardware ...
* }
*
* Note that a driver must indicate it supports hardware VLAN
* tagging by marking IFCAP_VLAN_HWTAGGING in if_capabilities.
* stripping/insertion by marking IFCAP_VLAN_HWTAGGING in
* if_capabilities.
*/
#define MTAG_VLAN 1035328035
#define MTAG_VLAN_TAG 0 /* tag of VLAN interface */
/*
* This macro must expand to a lvalue so that it can be used
* to set a tag with a simple assignment.
*/
#define VLAN_TAG_VALUE(_mt) (*(u_int *)((_mt) + 1))
#define VLAN_CAPABILITIES(_ifp) do { \
} while (0)
/*
* This macro is kept for API compatibility.
*/
#define VLAN_INPUT_TAG(_ifp, _m, _t, _errcase) do { \
struct m_tag *mtag; \
mtag = m_tag_alloc(MTAG_VLAN, MTAG_VLAN_TAG, \
sizeof (u_int), M_NOWAIT); \
if (mtag != NULL) { \
VLAN_TAG_VALUE(mtag) = (_t); \
m_tag_prepend((_m), mtag); \
(_m)->m_flags |= M_VLANTAG; \
} else { \
(_ifp)->if_ierrors++; \
m_freem(_m); \
_errcase; \
} \
} while (0)
/*
* This macro is equal to VLAN_INPUT_TAG() in HEAD.
*/
#define VLAN_INPUT_TAG_NEW(_ifp, _m, _t) do { \
struct m_tag *mtag; \
mtag = m_tag_alloc(MTAG_VLAN, MTAG_VLAN_TAG, \
sizeof (u_int), M_NOWAIT); \
if (mtag != NULL) { \
VLAN_TAG_VALUE(mtag) = (_t); \
m_tag_prepend((_m), mtag); \
(_m)->m_flags |= M_VLANTAG; \
} else { \
(_ifp)->if_ierrors++; \
m_freem(_m); \
_m = NULL; \
} \
} while (0)
#define VLAN_OUTPUT_TAG(_ifp, _m) \
((_m)->m_flags & M_VLANTAG ? \
m_tag_locate((_m), MTAG_VLAN, MTAG_VLAN_TAG, NULL) : NULL)
#endif
extern void (*vlan_trunk_cap_p)(struct ifnet *);
#endif /* _KERNEL */
#endif /* _NET_IF_VLAN_VAR_H_ */

View File

@ -0,0 +1,351 @@
/* $FreeBSD: src/sys/netinet/ip6.h,v 1.15 2005/07/20 10:30:52 ume Exp $ */
/* $KAME: ip6.h,v 1.18 2001/03/29 05:34:30 itojun Exp $ */
/*-
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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. 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 project 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 PROJECT 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 PROJECT 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.
*/
/*-
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. 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. 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.
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
* @(#)ip.h 8.1 (Berkeley) 6/10/93
*/
#ifndef _NETINET_IP6_H_
#define _NETINET_IP6_H_
/*
* Definition for internet protocol version 6.
* RFC 2460
*/
struct ip6_hdr {
union {
struct ip6_hdrctl {
u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */
u_int16_t ip6_un1_plen; /* payload length */
u_int8_t ip6_un1_nxt; /* next header */
u_int8_t ip6_un1_hlim; /* hop limit */
} ip6_un1;
u_int8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */
} ip6_ctlun;
struct in6_addr ip6_src; /* source address */
struct in6_addr ip6_dst; /* destination address */
} __packed;
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
#define IPV6_VERSION 0x60
#define IPV6_VERSION_MASK 0xf0
#if BYTE_ORDER == BIG_ENDIAN
#define IPV6_FLOWINFO_MASK 0x0fffffff /* flow info (28 bits) */
#define IPV6_FLOWLABEL_MASK 0x000fffff /* flow label (20 bits) */
#else
#if BYTE_ORDER == LITTLE_ENDIAN
#define IPV6_FLOWINFO_MASK 0xffffff0f /* flow info (28 bits) */
#define IPV6_FLOWLABEL_MASK 0xffff0f00 /* flow label (20 bits) */
#endif /* LITTLE_ENDIAN */
#endif
#if 1
/* ECN bits proposed by Sally Floyd */
#define IP6TOS_CE 0x01 /* congestion experienced */
#define IP6TOS_ECT 0x02 /* ECN-capable transport */
#endif
/*
* Extension Headers
*/
struct ip6_ext {
u_int8_t ip6e_nxt;
u_int8_t ip6e_len;
} __packed;
/* Hop-by-Hop options header */
/* XXX should we pad it to force alignment on an 8-byte boundary? */
struct ip6_hbh {
u_int8_t ip6h_nxt; /* next header */
u_int8_t ip6h_len; /* length in units of 8 octets */
/* followed by options */
} __packed;
/* Destination options header */
/* XXX should we pad it to force alignment on an 8-byte boundary? */
struct ip6_dest {
u_int8_t ip6d_nxt; /* next header */
u_int8_t ip6d_len; /* length in units of 8 octets */
/* followed by options */
} __packed;
/* Option types and related macros */
#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
#define IP6OPT_PADN 0x01 /* 00 0 00001 */
#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
#define IP6OPT_NSAP_ADDR 0xC3 /* 11 0 00011 */
#define IP6OPT_TUNNEL_LIMIT 0x04 /* 00 0 00100 */
#ifndef _KERNEL
#define IP6OPT_RTALERT 0x05 /* 00 0 00101 (KAME definition) */
#endif
#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 (RFC3542, recommended) */
#define IP6OPT_RTALERT_LEN 4
#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
#define IP6OPT_MINLEN 2
#define IP6OPT_EID 0x8a /* 10 0 01010 */
#define IP6OPT_TYPE(o) ((o) & 0xC0)
#define IP6OPT_TYPE_SKIP 0x00
#define IP6OPT_TYPE_DISCARD 0x40
#define IP6OPT_TYPE_FORCEICMP 0x80
#define IP6OPT_TYPE_ICMP 0xC0
#define IP6OPT_MUTABLE 0x20
/* IPv6 options: common part */
struct ip6_opt {
u_int8_t ip6o_type;
u_int8_t ip6o_len;
} __packed;
/* Jumbo Payload Option */
struct ip6_opt_jumbo {
u_int8_t ip6oj_type;
u_int8_t ip6oj_len;
u_int8_t ip6oj_jumbo_len[4];
} __packed;
#define IP6OPT_JUMBO_LEN 6
/* NSAP Address Option */
struct ip6_opt_nsap {
u_int8_t ip6on_type;
u_int8_t ip6on_len;
u_int8_t ip6on_src_nsap_len;
u_int8_t ip6on_dst_nsap_len;
/* followed by source NSAP */
/* followed by destination NSAP */
} __packed;
/* Tunnel Limit Option */
struct ip6_opt_tunnel {
u_int8_t ip6ot_type;
u_int8_t ip6ot_len;
u_int8_t ip6ot_encap_limit;
} __packed;
/* Router Alert Option */
struct ip6_opt_router {
u_int8_t ip6or_type;
u_int8_t ip6or_len;
u_int8_t ip6or_value[2];
} __packed;
/* Router alert values (in network byte order) */
#if BYTE_ORDER == BIG_ENDIAN
#define IP6_ALERT_MLD 0x0000
#define IP6_ALERT_RSVP 0x0001
#define IP6_ALERT_AN 0x0002
#else
#if BYTE_ORDER == LITTLE_ENDIAN
#define IP6_ALERT_MLD 0x0000
#define IP6_ALERT_RSVP 0x0100
#define IP6_ALERT_AN 0x0200
#endif /* LITTLE_ENDIAN */
#endif
/* Routing header */
struct ip6_rthdr {
u_int8_t ip6r_nxt; /* next header */
u_int8_t ip6r_len; /* length in units of 8 octets */
u_int8_t ip6r_type; /* routing type */
u_int8_t ip6r_segleft; /* segments left */
/* followed by routing type specific data */
} __packed;
/* Type 0 Routing header */
struct ip6_rthdr0 {
u_int8_t ip6r0_nxt; /* next header */
u_int8_t ip6r0_len; /* length in units of 8 octets */
u_int8_t ip6r0_type; /* always zero */
u_int8_t ip6r0_segleft; /* segments left */
u_int32_t ip6r0_reserved; /* reserved field */
/* followed by up to 127 struct in6_addr */
} __packed;
/* Fragment header */
struct ip6_frag {
u_int8_t ip6f_nxt; /* next header */
u_int8_t ip6f_reserved; /* reserved field */
u_int16_t ip6f_offlg; /* offset, reserved, and flag */
u_int32_t ip6f_ident; /* identification */
} __packed;
#if BYTE_ORDER == BIG_ENDIAN
#define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */
#define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */
#define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */
#else /* BYTE_ORDER == LITTLE_ENDIAN */
#define IP6F_OFF_MASK 0xf8ff /* mask out offset from _offlg */
#define IP6F_RESERVED_MASK 0x0600 /* reserved bits in ip6f_offlg */
#define IP6F_MORE_FRAG 0x0100 /* more-fragments flag */
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
/*
* Internet implementation parameters.
*/
#define IPV6_MAXHLIM 255 /* maximum hoplimit */
#define IPV6_DEFHLIM 64 /* default hlim */
#define IPV6_FRAGTTL 120 /* ttl for fragment packets, in slowtimo tick */
#define IPV6_HLIMDEC 1 /* subtracted when forwarding */
#define IPV6_MMTU 1280 /* minimal MTU and reassembly. 1024 + 256 */
#define IPV6_MAXPACKET 65535 /* ip6 max packet size without Jumbo payload*/
#define IPV6_MAXOPTHDR 2048 /* max option header size, 256 64-bit words */
#ifdef _KERNEL
/*
* IP6_EXTHDR_CHECK ensures that region between the IP6 header and the
* target header (including IPv6 itself, extension headers and
* TCP/UDP/ICMP6 headers) are continuous. KAME requires drivers
* to store incoming data into one internal mbuf or one or more external
* mbufs(never into two or more internal mbufs). Thus, the third case is
* supposed to never be matched but is prepared just in case.
*/
#define IP6_EXTHDR_CHECK(m, off, hlen, ret) \
do { \
if ((m)->m_next != NULL) { \
if (((m)->m_flags & M_LOOP) && \
((m)->m_len < (off) + (hlen)) && \
(((m) = m_pullup((m), (off) + (hlen))) == NULL)) { \
ip6stat.ip6s_exthdrtoolong++; \
return ret; \
} else if ((m)->m_flags & M_EXT) { \
if ((m)->m_len < (off) + (hlen)) { \
ip6stat.ip6s_exthdrtoolong++; \
m_freem(m); \
return ret; \
} \
} else { \
if ((m)->m_len < (off) + (hlen)) { \
ip6stat.ip6s_exthdrtoolong++; \
m_freem(m); \
return ret; \
} \
} \
} else { \
if ((m)->m_len < (off) + (hlen)) { \
ip6stat.ip6s_tooshort++; \
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); \
m_freem(m); \
return ret; \
} \
} \
} while (/*CONSTCOND*/ 0)
/*
* IP6_EXTHDR_GET ensures that intermediate protocol header (from "off" to
* "len") is located in single mbuf, on contiguous memory region.
* The pointer to the region will be returned to pointer variable "val",
* with type "typ".
* IP6_EXTHDR_GET0 does the same, except that it aligns the structure at the
* very top of mbuf. GET0 is likely to make memory copy than GET.
*
* XXX we're now testing this, needs m_pulldown()
*/
#define IP6_EXTHDR_GET(val, typ, m, off, len) \
do { \
struct mbuf *t; \
int tmp; \
if ((m)->m_len >= (off) + (len)) \
(val) = (typ)(mtod((m), caddr_t) + (off)); \
else { \
t = m_pulldown((m), (off), (len), &tmp); \
if (t) { \
if (t->m_len < tmp + (len)) \
panic("m_pulldown malfunction"); \
(val) = (typ)(mtod(t, caddr_t) + tmp); \
} else { \
(val) = (typ)NULL; \
(m) = NULL; \
} \
} \
} while (/*CONSTCOND*/ 0)
#define IP6_EXTHDR_GET0(val, typ, m, off, len) \
do { \
struct mbuf *t; \
if ((off) == 0) \
(val) = (typ)mtod(m, caddr_t); \
else { \
t = m_pulldown((m), (off), (len), NULL); \
if (t) { \
if (t->m_len < (len)) \
panic("m_pulldown malfunction"); \
(val) = (typ)mtod(t, caddr_t); \
} else { \
(val) = (typ)NULL; \
(m) = NULL; \
} \
} \
} while (/*CONSTCOND*/ 0)
#endif /*_KERNEL*/
#endif /* not _NETINET_IP6_H_ */

View File

@ -0,0 +1,63 @@
/*-
* Copyright 2006 John-Mark Gurney.
* 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. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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/sys/_bus_dma.h,v 1.1 2006/09/03 00:26:17 jmg Exp $
*
*/
#ifndef _SYS__BUS_DMA_H_
#define _SYS__BUS_DMA_H_
typedef int bus_dmasync_op_t;
/*
* bus_dma_tag_t
*
* A machine-dependent opaque type describing the characteristics
* of how to perform DMA mappings. This structure encapsultes
* information concerning address and alignment restrictions, number
* of S/G segments, amount of data per S/G segment, etc.
*/
typedef struct bus_dma_tag *bus_dma_tag_t;
/*
* bus_dmamap_t
*
* DMA mapping instance information.
*/
typedef struct bus_dmamap *bus_dmamap_t;
/*
* A function that performs driver-specific synchronization on behalf of
* busdma.
*/
typedef enum {
BUS_DMA_LOCK = 0x01,
BUS_DMA_UNLOCK = 0x02,
} bus_dma_lock_op_t;
typedef void bus_dma_lock_t(void *, bus_dma_lock_op_t);
#endif /* !_SYS__BUS_DMA_H_ */

View File

@ -1,22 +1,22 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_COMPAT_SYS_BUS_H_
#define _FBSD_COMPAT_SYS_BUS_H_
#include <arch/x86/arch_cpu.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/haiku-module.h>
// TODO per platform, these are x86
typedef uint32_t bus_addr_t;
typedef uint32_t bus_size_t;
#include <sys/_bus_dma.h>
typedef int bus_space_tag_t;
typedef unsigned int bus_space_handle_t;
#define I386_BUS_SPACE_IO 0
#define I386_BUS_SPACE_MEM 1
// TODO per platform, these are 32-bit
typedef uint32_t bus_addr_t;
typedef uint32_t bus_size_t;
#define BUS_SPACE_MAXADDR_32BIT 0xffffffff
#define BUS_SPACE_MAXADDR 0xffffffff
@ -24,21 +24,37 @@ typedef unsigned int bus_space_handle_t;
#define BUS_SPACE_MAXSIZE_32BIT 0xffffffff
#define BUS_SPACE_MAXSIZE 0xffffffff
typedef int bus_space_tag_t;
typedef unsigned int bus_space_handle_t;
uint8_t bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t offset);
uint16_t bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t offset);
uint32_t bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t offset);
void bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t offset, uint8_t value);
uint16_t bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t offset);
void bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t offset, uint16_t value);
uint32_t bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t offset);
void bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t offset, uint32_t value);
// oh you glorious world of macros
#define bus_space_write_stream_4(t, h, o, v) \
bus_space_write_4((t), (h), (o), (v))
#define bus_read_1(r, o) \
bus_space_read_1((r)->r_bustag, (r)->r_bushandle, (o))
#define bus_read_2(r, o) \
bus_space_read_2((r)->r_bustag, (r)->r_bushandle, (o))
#define bus_read_4(r, o) \
bus_space_read_4((r)->r_bustag, (r)->r_bushandle, (o))
#define bus_write_1(r, o, v) \
bus_space_write_1((r)->r_bustag, (r)->r_bushandle, (o), (v))
#define bus_write_2(r, o, v) \
bus_space_write_2((r)->r_bustag, (r)->r_bushandle, (o), (v))
#define bus_write_4(r, o, v) \
bus_space_write_4((r)->r_bustag, (r)->r_bushandle, (o), (v))
#define BUS_SPACE_BARRIER_READ 1
@ -54,6 +70,13 @@ bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t handle,
__asm__ __volatile__ ("" : : : "memory");
}
struct resource;
struct resource_spec {
int type;
int rid;
int flags;
};
enum intr_type {
INTR_TYPE_NET = 4,
@ -61,14 +84,18 @@ enum intr_type {
INTR_MPSAFE = 512,
};
#define FILTER_STRAY B_UNHANDLED_INTERRUPT
#define FILTER_HANDLED B_HANDLED_INTERRUPT
#define FILTER_SCHEDULE_THREAD B_INVOKE_SCHEDULER
int bus_generic_detach(device_t dev);
int bus_generic_suspend(device_t dev);
int bus_generic_resume(device_t dev);
void bus_generic_shutdown(device_t dev);
typedef int (*driver_filter_t)(void *);
typedef void (*driver_intr_t)(void *);
struct resource;
int resource_int_value(const char *name, int unit, const char *resname,
int *result);
@ -76,6 +103,10 @@ int resource_int_value(const char *name, int unit, const char *resname,
struct resource *bus_alloc_resource(device_t dev, int type, int *rid,
unsigned long start, unsigned long end, unsigned long count, uint32 flags);
int bus_release_resource(device_t dev, int type, int rid, struct resource *r);
int bus_alloc_resources(device_t dev, struct resource_spec *resourceSpec,
struct resource **resources);
void bus_release_resources(device_t dev,
const struct resource_spec *resourceSpec, struct resource **resources);
static inline struct resource *
bus_alloc_resource_any(device_t dev, int type, int *rid, uint32 flags)
@ -83,8 +114,10 @@ bus_alloc_resource_any(device_t dev, int type, int *rid, uint32 flags)
return bus_alloc_resource(dev, type, rid, 0, ~0, 1, flags);
}
bus_dma_tag_t bus_get_dma_tag(device_t dev);
int bus_setup_intr(device_t dev, struct resource *r, int flags,
driver_intr_t handler, void *arg, void **cookiep);
driver_filter_t filter, driver_intr_t handler, void *arg, void **_cookie);
int bus_teardown_intr(device_t dev, struct resource *r, void *cookie);
const char *device_get_name(device_t dev);
@ -105,8 +138,9 @@ int device_delete_child(device_t dev, device_t child);
int device_is_attached(device_t dev);
int bus_generic_print_child(device_t dev, device_t child);
void bus_generic_driver_added(device_t dev, driver_t *driver);
void bus_generic_attach(device_t dev);
int bus_generic_attach(device_t dev);
int device_set_driver(device_t dev, driver_t *driver);
int device_is_alive(device_t dev);
static inline struct sysctl_ctx_list *
device_get_sysctl_ctx(device_t dev)
@ -122,4 +156,4 @@ device_get_sysctl_tree(device_t dev)
#include <sys/bus_dma.h>
#endif
#endif /* _FBSD_COMPAT_SYS_BUS_H_ */

View File

@ -67,11 +67,13 @@
* (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/sys/bus_dma.h,v 1.29 2005/03/15 14:57:29 jmg Exp $ */
/* $FreeBSD: src/sys/sys/bus_dma.h,v 1.30 2006/09/03 00:26:17 jmg Exp $ */
#ifndef _BUS_DMA_H_
#define _BUS_DMA_H_
#include <sys/_bus_dma.h>
/*
* Machine independent interface for mapping physical addresses to peripheral
* bus 'physical' addresses, and assisting with DMA operations.
@ -108,29 +110,11 @@ struct uio;
/*
* Operations performed by bus_dmamap_sync().
*/
typedef int bus_dmasync_op_t;
#define BUS_DMASYNC_PREREAD 1
#define BUS_DMASYNC_POSTREAD 2
#define BUS_DMASYNC_PREWRITE 4
#define BUS_DMASYNC_POSTWRITE 8
/*
* bus_dma_tag_t
*
* A machine-dependent opaque type describing the characteristics
* of how to perform DMA mappings. This structure encapsultes
* information concerning address and alignment restrictions, number
* of S/G segments, amount of data per S/G segment, etc.
*/
typedef struct bus_dma_tag *bus_dma_tag_t;
/*
* bus_dmamap_t
*
* DMA mapping instance information.
*/
typedef struct bus_dmamap *bus_dmamap_t;
/*
* bus_dma_segment_t
*
@ -148,17 +132,6 @@ typedef struct bus_dma_segment {
*/
typedef int bus_dma_filter_t(void *, bus_addr_t);
/*
* A function that performs driver-specific synchronization on behalf of
* busdma.
*/
typedef enum {
BUS_DMA_LOCK = 0x01,
BUS_DMA_UNLOCK = 0x02,
} bus_dma_lock_op_t;
typedef void bus_dma_lock_t(void *, bus_dma_lock_op_t);
/*
* Generic helper function for manipulating mutexes.
*/

View File

@ -80,6 +80,18 @@
(m)->m_flags & M_PKTHDR ? (m)->m_data - (m)->m_pktdat : \
(m)->m_data - (m)->m_dat)
/*
* Compute the amount of space available after the end of data in an mbuf.
*
* The M_WRITABLE() is a temporary, conservative safety measure: the burden
* of checking writability of the mbuf data area rests solely with the caller.
*/
#define M_TRAILINGSPACE(m) \
((m)->m_flags & M_EXT ? \
(M_WRITABLE(m) ? (m)->m_ext.ext_buf + (m)->m_ext.ext_size \
- ((m)->m_data + (m)->m_len) : 0) : \
&(m)->m_dat[MLEN] - ((m)->m_data + (m)->m_len))
/*
* Arrange to prepend space of size plen to mbuf m.
* If a new mbuf must be allocated, how specifies whether to wait.

View File

@ -1,16 +1,20 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_COMPAT_SYS_MBUF_H_
#define _FBSD_COMPAT_SYS_MBUF_H_
#include <sys/malloc.h>
#include <sys/param.h>
#define MLEN ((int)(MSIZE - sizeof(struct m_hdr)))
#define MHLEN ((int)(MSIZE - sizeof(struct pkthdr)))
#define MINCLSIZE (MHLEN + 1)
#ifdef _KERNEL
struct m_hdr {
struct mbuf * mh_next;
struct mbuf * mh_nextpkt;
@ -24,7 +28,9 @@ struct pkthdr {
struct ifnet * rcvif;
int len;
int csum_flags;
uint16_t csum_data;
int csum_data;
uint16_t tso_segsz;
uint16_t ether_vtag;
};
struct m_ext {
@ -68,16 +74,20 @@ struct mbuf {
#define M_EXT 0x0001
#define M_PKTHDR 0x0002
#define M_RDONLY 0x0008
#define EXT_CLUSTER 1
#define EXT_PACKET 3
#define EXT_NET_DRV 100
#define M_BCAST 0x0200
#define M_MCAST 0x0400
#define M_BCAST 0x00000200
#define M_MCAST 0x00000400
#define M_VLANTAG 0x00010000
#define CSUM_IP 0x0001
#define CSUM_TCP 0x0002
#define CSUM_UDP 0x0004
#define CSUM_TSO 0x0020
#define CSUM_IP_CHECKED 0x0100
#define CSUM_IP_VALID 0x0200
#define CSUM_DATA_VALID 0x0400
@ -88,6 +98,9 @@ struct mbuf {
#define MGET(m, how, type) ((m) = m_get((how), (type)))
#define MGETHDR(m, how, type) ((m) = m_gethdr((how), (type)))
#define MCLGET(m, how) m_clget((m), (how))
#define MEXTADD(m, buf, size, free, args, flags, type) \
m_extadd((m), (caddr_t)(buf), (size), (free), (args), (flags), (type))
struct mbuf *m_getcl(int how, short type, int flags);
void m_freem(struct mbuf *mbuf);
@ -112,6 +125,10 @@ struct mbuf *m_get(int how, short type);
struct mbuf *m_gethdr(int how, short type);
void m_clget(struct mbuf *m, int how);
void m_extadd(struct mbuf *m, caddr_t buffer, u_int size,
void (*freeHook)(void *, void *), void *args, int flags, int type);
#define mtod(m, type) (type)((m)->m_data)
#define m_tag_delete(mb, tag) \
@ -130,6 +147,4 @@ extern int max_protohdr;
#include <sys/mbuf-fbsd.h>
#endif
#endif
#endif /* _FBSD_COMPAT_SYS_MBUF_H_ */

View File

@ -1,8 +1,14 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_COMPAT_SYS_MUTEX_H_
#define _FBSD_COMPAT_SYS_MUTEX_H_
#include <sys/haiku-module.h>
struct mtx {
int type;
union {
@ -58,4 +64,4 @@ void mtx_destroy(struct mtx *m);
extern struct mtx Giant;
#endif
#endif /* _FBSD_COMPAT_SYS_MUTEX_H_ */

View File

@ -1,12 +1,26 @@
/*
* Copyright 2007, Hugo Santos. All Rights Reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_COMPAT_SYS_RMAN_H_
#define _FBSD_COMPAT_SYS_RMAN_H_
#include <sys/bus.h>
#define RF_ACTIVE 0x0002
#define RF_SHAREABLE 0x0004
#define RF_OPTIONAL 0x0080
struct resource {
int r_type;
bus_space_tag_t r_bustag; /* bus_space tag */
bus_space_handle_t r_bushandle; /* bus_space handle */
area_id r_mapped_area;
};
bus_space_handle_t rman_get_bushandle(struct resource *);
bus_space_tag_t rman_get_bustag(struct resource *);
#endif
#endif /* _FBSD_COMPAT_SYS_RMAN_H_ */

View File

@ -5,6 +5,7 @@
#ifndef _FBSD_COMPAT_SYS_SYSTM_H_
#define _FBSD_COMPAT_SYS_SYSTM_H_
#include <stdint.h>
#include <sys/callout.h>
@ -14,6 +15,9 @@
#include <net/if_var.h>
#include <net/if_media.h>
#include <machine/atomic.h>
#define DELAY(n) \
do { \
if (n < 1000) \
@ -22,4 +26,10 @@
snooze(n); \
} while (0)
static inline void
wakeup(void *identifier)
{
panic("wakeup() called.");
}
#endif /* _FBSD_COMPAT_SYS_SYSTM_H_ */

View File

@ -5,22 +5,23 @@
#ifndef _FBSD_COMPAT_VM_VM_H_
#define _FBSD_COMPAT_VM_VM_H_
#include <stdint.h>
#include <KernelExport.h>
// for x86
// for 32 bit machines
typedef uint32_t vm_offset_t;
typedef uint32_t vm_paddr_t;
typedef uint32_t vm_offset_t;
typedef uint32_t vm_paddr_t;
typedef void * pmap_t;
typedef void *pmap_t;
#define vmspace_pmap(...) NULL
#define pmap_extract(...) NULL
#define vmspace_pmap(...) NULL
#define pmap_extract(...) NULL
vm_paddr_t pmap_kextract(vm_offset_t virtualAddress);
#define vtophys(virtualAddress) pmap_kextract(virtualAddress)
#define vtophys(virtualAddress) pmap_kextract((vm_offset_t)(virtualAddress))
#endif /* _FBSD_COMPAT_VM_VM_H_ */

View File

@ -88,7 +88,7 @@ _resolve_method(driver_t *driver, const char *name)
static status_t
compat_open(const char *name, uint32 flags, void **cookie)
{
struct network_device *dev;
struct network_device *device;
status_t status;
int i;
@ -106,22 +106,22 @@ compat_open(const char *name, uint32 flags, void **cookie)
if (gDevNameList[i] == NULL)
return B_ERROR;
dev = gDevices[i];
device = gDevices[i];
if (!atomic_test_and_set(&dev->open, 1, 0))
if (!atomic_test_and_set(&device->open, 1, 0))
return B_BUSY;
/* some drivers expect the softc to be zero'ed out */
memset(dev->base.softc, 0, dev->base.driver->softc_size);
memset(device->base.softc, 0, device->base.driver->softc_size);
status = DEVNET(dev)->methods.attach(DEVNET(dev));
status = DEVNET(device)->methods.attach(DEVNET(device));
if (status != 0)
atomic_and(&dev->open, 0);
atomic_and(&device->open, 0);
driver_printf(" ... status = 0x%ld\n", status);
if (status == 0) {
struct ifnet *ifp = dev->ifp;
struct ifnet *ifp = device->ifp;
struct ifreq ifr;
ifp->if_flags &= ~IFF_UP;
@ -135,7 +135,7 @@ compat_open(const char *name, uint32 flags, void **cookie)
ifp->if_ioctl(ifp, SIOCSIFFLAGS, NULL);
}
*cookie = dev;
*cookie = device;
return status;
}

View File

@ -319,7 +319,7 @@ ether_ifdetach(struct ifnet *ifp)
int
ether_ioctl(struct ifnet *ifp, int command, caddr_t data)
ether_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
{
struct ifreq *ifr = (struct ifreq *)data;

View File

@ -191,6 +191,15 @@ m_free(struct mbuf *m)
}
void
m_extadd(struct mbuf *m, caddr_t buffer, u_int size,
void (*freeHook)(void *, void *), void *args, int flags, int type)
{
// TODO: implement?
panic("m_extadd() called.");
}
status_t
init_mbufs()
{