Update FreeBSD network drivers with the 9.2 release
This commit is contained in:
@@ -161,7 +161,7 @@ MODULE_DEPEND(xl, miibus, 1, 1, 1);
|
||||
/*
|
||||
* Various supported device vendors/types and their names.
|
||||
*/
|
||||
static const struct xl_type const xl_devs[] = {
|
||||
static const struct xl_type xl_devs[] = {
|
||||
{ TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT,
|
||||
"3Com 3c900-TPO Etherlink XL" },
|
||||
{ TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT_COMBO,
|
||||
@@ -1770,7 +1770,7 @@ xl_newbuf(struct xl_softc *sc, struct xl_chain_onefrag *c)
|
||||
|
||||
XL_LOCK_ASSERT(sc);
|
||||
|
||||
m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m_new = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m_new == NULL)
|
||||
return (ENOBUFS);
|
||||
|
||||
@@ -2379,7 +2379,7 @@ xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf **m_head)
|
||||
* and would waste cycles.
|
||||
*/
|
||||
if (error) {
|
||||
m_new = m_collapse(*m_head, M_DONTWAIT, XL_MAXFRAGS);
|
||||
m_new = m_collapse(*m_head, M_NOWAIT, XL_MAXFRAGS);
|
||||
if (m_new == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
|
||||
@@ -95,7 +95,7 @@ static const struct ale_dev {
|
||||
uint16_t ale_vendorid;
|
||||
uint16_t ale_deviceid;
|
||||
const char *ale_name;
|
||||
} const ale_devs[] = {
|
||||
} ale_devs[] = {
|
||||
{ VENDORID_ATHEROS, DEVICEID_ATHEROS_AR81XX,
|
||||
"Atheros AR8121/AR8113/AR8114 PCIe Ethernet" },
|
||||
};
|
||||
@@ -551,7 +551,7 @@ ale_attach(device_t dev)
|
||||
if (msix_disable == 0 || msi_disable == 0) {
|
||||
if (msix_disable == 0 && msixc == ALE_MSIX_MESSAGES &&
|
||||
pci_alloc_msix(dev, &msixc) == 0) {
|
||||
if (msic == ALE_MSIX_MESSAGES) {
|
||||
if (msixc == ALE_MSIX_MESSAGES) {
|
||||
device_printf(dev, "Using %d MSIX messages.\n",
|
||||
msixc);
|
||||
sc->ale_flags |= ALE_FLAG_MSIX;
|
||||
@@ -1640,7 +1640,7 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
|
||||
|
||||
if (M_WRITABLE(m) == 0) {
|
||||
/* Get a writable copy. */
|
||||
m = m_dup(*m_head, M_DONTWAIT);
|
||||
m = m_dup(*m_head, M_NOWAIT);
|
||||
/* Release original mbufs. */
|
||||
m_freem(*m_head);
|
||||
if (m == NULL) {
|
||||
@@ -1657,7 +1657,7 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
|
||||
if ((sc->ale_flags & ALE_FLAG_TXCSUM_BUG) != 0 &&
|
||||
(m->m_pkthdr.csum_flags & ALE_CSUM_FEATURES) != 0 &&
|
||||
(mtod(m, intptr_t) & 3) != 0) {
|
||||
m = m_defrag(*m_head, M_DONTWAIT);
|
||||
m = m_defrag(*m_head, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
*m_head = NULL;
|
||||
return (ENOBUFS);
|
||||
@@ -1742,7 +1742,7 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->ale_cdata.ale_tx_tag, map,
|
||||
*m_head, txsegs, &nsegs, 0);
|
||||
if (error == EFBIG) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, ALE_MAXTXSEGS);
|
||||
m = m_collapse(*m_head, M_NOWAIT, ALE_MAXTXSEGS);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -2932,7 +2932,7 @@ ale_stop_mac(struct ale_softc *sc)
|
||||
|
||||
reg = CSR_READ_4(sc, ALE_MAC_CFG);
|
||||
if ((reg & (MAC_CFG_TX_ENB | MAC_CFG_RX_ENB)) != 0) {
|
||||
reg &= ~MAC_CFG_TX_ENB | MAC_CFG_RX_ENB;
|
||||
reg &= ~(MAC_CFG_TX_ENB | MAC_CFG_RX_ENB);
|
||||
CSR_WRITE_4(sc, ALE_MAC_CFG, reg);
|
||||
}
|
||||
|
||||
|
||||
@@ -683,7 +683,7 @@ alc_aspm(struct alc_softc *sc, int media)
|
||||
if ((sc->alc_flags & (ALC_FLAG_APS | ALC_FLAG_PCIE)) ==
|
||||
(ALC_FLAG_APS | ALC_FLAG_PCIE))
|
||||
linkcfg = CSR_READ_2(sc, sc->alc_expcap +
|
||||
PCIR_EXPRESS_LINK_CTL);
|
||||
PCIER_LINK_CTL);
|
||||
else
|
||||
linkcfg = 0;
|
||||
pmcfg &= ~PM_CFG_SERDES_PD_EX_L1;
|
||||
@@ -698,7 +698,7 @@ alc_aspm(struct alc_softc *sc, int media)
|
||||
if (sc->alc_ident->deviceid == DEVICEID_ATHEROS_AR8152_B &&
|
||||
sc->alc_rev == ATHEROS_AR8152_B_V10)
|
||||
linkcfg |= 0x80;
|
||||
CSR_WRITE_2(sc, sc->alc_expcap + PCIR_EXPRESS_LINK_CTL,
|
||||
CSR_WRITE_2(sc, sc->alc_expcap + PCIER_LINK_CTL,
|
||||
linkcfg);
|
||||
pmcfg &= ~(PM_CFG_EN_BUFS_RX_L0S | PM_CFG_SA_DLY_ENB |
|
||||
PM_CFG_HOTRST);
|
||||
@@ -798,10 +798,10 @@ alc_attach(device_t dev)
|
||||
if (pci_find_cap(dev, PCIY_EXPRESS, &base) == 0) {
|
||||
sc->alc_flags |= ALC_FLAG_PCIE;
|
||||
sc->alc_expcap = base;
|
||||
burst = CSR_READ_2(sc, base + PCIR_EXPRESS_DEVICE_CTL);
|
||||
burst = CSR_READ_2(sc, base + PCIER_DEVICE_CTL);
|
||||
sc->alc_dma_rd_burst =
|
||||
(burst & PCIM_EXP_CTL_MAX_READ_REQUEST) >> 12;
|
||||
sc->alc_dma_wr_burst = (burst & PCIM_EXP_CTL_MAX_PAYLOAD) >> 5;
|
||||
(burst & PCIEM_CTL_MAX_READ_REQUEST) >> 12;
|
||||
sc->alc_dma_wr_burst = (burst & PCIEM_CTL_MAX_PAYLOAD) >> 5;
|
||||
if (bootverbose) {
|
||||
device_printf(dev, "Read request size : %u bytes.\n",
|
||||
alc_dma_burst[sc->alc_dma_rd_burst]);
|
||||
@@ -831,9 +831,9 @@ alc_attach(device_t dev)
|
||||
CSR_WRITE_4(sc, ALC_PCIE_PHYMISC2, val);
|
||||
}
|
||||
/* Disable ASPM L0S and L1. */
|
||||
cap = CSR_READ_2(sc, base + PCIR_EXPRESS_LINK_CAP);
|
||||
if ((cap & PCIM_LINK_CAP_ASPM) != 0) {
|
||||
ctl = CSR_READ_2(sc, base + PCIR_EXPRESS_LINK_CTL);
|
||||
cap = CSR_READ_2(sc, base + PCIER_LINK_CAP);
|
||||
if ((cap & PCIEM_LINK_CAP_ASPM) != 0) {
|
||||
ctl = CSR_READ_2(sc, base + PCIER_LINK_CTL);
|
||||
if ((ctl & 0x08) != 0)
|
||||
sc->alc_rcb = DMA_CFG_RCB_128;
|
||||
if (bootverbose)
|
||||
@@ -2047,7 +2047,7 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
|
||||
|
||||
if (M_WRITABLE(m) == 0) {
|
||||
/* Get a writable copy. */
|
||||
m = m_dup(*m_head, M_DONTWAIT);
|
||||
m = m_dup(*m_head, M_NOWAIT);
|
||||
/* Release original mbufs. */
|
||||
m_freem(*m_head);
|
||||
if (m == NULL) {
|
||||
@@ -2125,7 +2125,7 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->alc_cdata.alc_tx_tag, map,
|
||||
*m_head, txsegs, &nsegs, 0);
|
||||
if (error == EFBIG) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, ALC_MAXTXSEGS);
|
||||
m = m_collapse(*m_head, M_NOWAIT, ALC_MAXTXSEGS);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -2803,7 +2803,7 @@ alc_newbuf(struct alc_softc *sc, struct alc_rxdesc *rxd)
|
||||
bus_dmamap_t map;
|
||||
int nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
m->m_len = m->m_pkthdr.len = RX_BUF_SIZE_MAX;
|
||||
@@ -2923,7 +2923,7 @@ alc_fixup_rx(struct ifnet *ifp, struct mbuf *m)
|
||||
* header from the mbuf chain. This can save lots of CPU
|
||||
* cycles for jumbo frame.
|
||||
*/
|
||||
MGETHDR(n, M_DONTWAIT, MT_DATA);
|
||||
MGETHDR(n, M_NOWAIT, MT_DATA);
|
||||
if (n == NULL) {
|
||||
ifp->if_iqdrops++;
|
||||
m_freem(m);
|
||||
|
||||
@@ -142,6 +142,9 @@ static int age_init_rx_ring(struct age_softc *);
|
||||
static void age_init_rr_ring(struct age_softc *);
|
||||
static void age_init_cmb_block(struct age_softc *);
|
||||
static void age_init_smb_block(struct age_softc *);
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
static struct mbuf *age_fixup_rx(struct ifnet *, struct mbuf *);
|
||||
#endif
|
||||
static int age_newbuf(struct age_softc *, struct age_rxdesc *);
|
||||
static void age_rxvlan(struct age_softc *);
|
||||
static void age_rxfilter(struct age_softc *);
|
||||
@@ -1133,7 +1136,7 @@ again:
|
||||
/* Create tag for Rx buffers. */
|
||||
error = bus_dma_tag_create(
|
||||
sc->age_cdata.age_buffer_tag, /* parent */
|
||||
1, 0, /* alignment, boundary */
|
||||
AGE_RX_BUF_ALIGN, 0, /* alignment, boundary */
|
||||
BUS_SPACE_MAXADDR, /* lowaddr */
|
||||
BUS_SPACE_MAXADDR, /* highaddr */
|
||||
NULL, NULL, /* filter, filterarg */
|
||||
@@ -1499,7 +1502,7 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
|
||||
struct tcphdr *tcp;
|
||||
bus_dma_segment_t txsegs[AGE_MAXTXSEGS];
|
||||
bus_dmamap_t map;
|
||||
uint32_t cflags, ip_off, poff, vtag;
|
||||
uint32_t cflags, hdrlen, ip_off, poff, vtag;
|
||||
int error, i, nsegs, prod, si;
|
||||
|
||||
AGE_LOCK_ASSERT(sc);
|
||||
@@ -1525,7 +1528,7 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
|
||||
|
||||
if (M_WRITABLE(m) == 0) {
|
||||
/* Get a writable copy. */
|
||||
m = m_dup(*m_head, M_DONTWAIT);
|
||||
m = m_dup(*m_head, M_NOWAIT);
|
||||
/* Release original mbufs. */
|
||||
m_freem(*m_head);
|
||||
if (m == NULL) {
|
||||
@@ -1566,8 +1569,12 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
|
||||
*m_head = NULL;
|
||||
return (ENOBUFS);
|
||||
}
|
||||
ip = (struct ip *)(mtod(m, char *) + ip_off);
|
||||
tcp = (struct tcphdr *)(mtod(m, char *) + poff);
|
||||
m = m_pullup(m, poff + (tcp->th_off << 2));
|
||||
if (m == NULL) {
|
||||
*m_head = NULL;
|
||||
return (ENOBUFS);
|
||||
}
|
||||
/*
|
||||
* L1 requires IP/TCP header size and offset as
|
||||
* well as TCP pseudo checksum which complicates
|
||||
@@ -1582,14 +1589,11 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
|
||||
* Reset IP checksum and recompute TCP pseudo
|
||||
* checksum as NDIS specification said.
|
||||
*/
|
||||
ip = (struct ip *)(mtod(m, char *) + ip_off);
|
||||
tcp = (struct tcphdr *)(mtod(m, char *) + poff);
|
||||
ip->ip_sum = 0;
|
||||
if (poff + (tcp->th_off << 2) == m->m_pkthdr.len)
|
||||
tcp->th_sum = in_pseudo(ip->ip_src.s_addr,
|
||||
ip->ip_dst.s_addr,
|
||||
htons((tcp->th_off << 2) + IPPROTO_TCP));
|
||||
else
|
||||
tcp->th_sum = in_pseudo(ip->ip_src.s_addr,
|
||||
ip->ip_dst.s_addr, htons(IPPROTO_TCP));
|
||||
tcp->th_sum = in_pseudo(ip->ip_src.s_addr,
|
||||
ip->ip_dst.s_addr, htons(IPPROTO_TCP));
|
||||
}
|
||||
*m_head = m;
|
||||
}
|
||||
@@ -1602,7 +1606,7 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->age_cdata.age_tx_tag, map,
|
||||
*m_head, txsegs, &nsegs, 0);
|
||||
if (error == EFBIG) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, AGE_MAXTXSEGS);
|
||||
m = m_collapse(*m_head, M_NOWAIT, AGE_MAXTXSEGS);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -1631,23 +1635,48 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
|
||||
}
|
||||
|
||||
m = *m_head;
|
||||
/* Configure VLAN hardware tag insertion. */
|
||||
if ((m->m_flags & M_VLANTAG) != 0) {
|
||||
vtag = AGE_TX_VLAN_TAG(m->m_pkthdr.ether_vtag);
|
||||
vtag = ((vtag << AGE_TD_VLAN_SHIFT) & AGE_TD_VLAN_MASK);
|
||||
cflags |= AGE_TD_INSERT_VLAN_TAG;
|
||||
}
|
||||
|
||||
desc = NULL;
|
||||
i = 0;
|
||||
if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
|
||||
/* Configure TSO. */
|
||||
if (poff + (tcp->th_off << 2) == m->m_pkthdr.len) {
|
||||
/* Not TSO but IP/TCP checksum offload. */
|
||||
cflags |= AGE_TD_IPCSUM | AGE_TD_TCPCSUM;
|
||||
/* Clear TSO in order not to set AGE_TD_TSO_HDR. */
|
||||
m->m_pkthdr.csum_flags &= ~CSUM_TSO;
|
||||
} else {
|
||||
/* Request TSO and set MSS. */
|
||||
cflags |= AGE_TD_TSO_IPV4;
|
||||
cflags |= AGE_TD_IPCSUM | AGE_TD_TCPCSUM;
|
||||
cflags |= ((uint32_t)m->m_pkthdr.tso_segsz <<
|
||||
AGE_TD_TSO_MSS_SHIFT);
|
||||
}
|
||||
/* Request TSO and set MSS. */
|
||||
cflags |= AGE_TD_TSO_IPV4;
|
||||
cflags |= AGE_TD_IPCSUM | AGE_TD_TCPCSUM;
|
||||
cflags |= ((uint32_t)m->m_pkthdr.tso_segsz <<
|
||||
AGE_TD_TSO_MSS_SHIFT);
|
||||
/* Set IP/TCP header size. */
|
||||
cflags |= ip->ip_hl << AGE_TD_IPHDR_LEN_SHIFT;
|
||||
cflags |= tcp->th_off << AGE_TD_TSO_TCPHDR_LEN_SHIFT;
|
||||
/*
|
||||
* L1 requires the first buffer should only hold IP/TCP
|
||||
* header data. TCP payload should be handled in other
|
||||
* descriptors.
|
||||
*/
|
||||
hdrlen = poff + (tcp->th_off << 2);
|
||||
desc = &sc->age_rdata.age_tx_ring[prod];
|
||||
desc->addr = htole64(txsegs[0].ds_addr);
|
||||
desc->len = htole32(AGE_TX_BYTES(hdrlen) | vtag);
|
||||
desc->flags = htole32(cflags);
|
||||
sc->age_cdata.age_tx_cnt++;
|
||||
AGE_DESC_INC(prod, AGE_TX_RING_CNT);
|
||||
if (m->m_len - hdrlen > 0) {
|
||||
/* Handle remaining payload of the 1st fragment. */
|
||||
desc = &sc->age_rdata.age_tx_ring[prod];
|
||||
desc->addr = htole64(txsegs[0].ds_addr + hdrlen);
|
||||
desc->len = htole32(AGE_TX_BYTES(m->m_len - hdrlen) |
|
||||
vtag);
|
||||
desc->flags = htole32(cflags);
|
||||
sc->age_cdata.age_tx_cnt++;
|
||||
AGE_DESC_INC(prod, AGE_TX_RING_CNT);
|
||||
}
|
||||
/* Handle remaining fragments. */
|
||||
i = 1;
|
||||
} else if ((m->m_pkthdr.csum_flags & AGE_CSUM_FEATURES) != 0) {
|
||||
/* Configure Tx IP/TCP/UDP checksum offload. */
|
||||
cflags |= AGE_TD_CSUM;
|
||||
@@ -1661,16 +1690,7 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
|
||||
cflags |= ((poff + m->m_pkthdr.csum_data) <<
|
||||
AGE_TD_CSUM_XSUMOFFSET_SHIFT);
|
||||
}
|
||||
|
||||
/* Configure VLAN hardware tag insertion. */
|
||||
if ((m->m_flags & M_VLANTAG) != 0) {
|
||||
vtag = AGE_TX_VLAN_TAG(m->m_pkthdr.ether_vtag);
|
||||
vtag = ((vtag << AGE_TD_VLAN_SHIFT) & AGE_TD_VLAN_MASK);
|
||||
cflags |= AGE_TD_INSERT_VLAN_TAG;
|
||||
}
|
||||
|
||||
desc = NULL;
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
for (; i < nsegs; i++) {
|
||||
desc = &sc->age_rdata.age_tx_ring[prod];
|
||||
desc->addr = htole64(txsegs[i].ds_addr);
|
||||
desc->len = htole32(AGE_TX_BYTES(txsegs[i].ds_len) | vtag);
|
||||
@@ -2255,16 +2275,53 @@ age_txintr(struct age_softc *sc, int tpd_cons)
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
static struct mbuf *
|
||||
age_fixup_rx(struct ifnet *ifp, struct mbuf *m)
|
||||
{
|
||||
struct mbuf *n;
|
||||
int i;
|
||||
uint16_t *src, *dst;
|
||||
|
||||
src = mtod(m, uint16_t *);
|
||||
dst = src - 3;
|
||||
|
||||
if (m->m_next == NULL) {
|
||||
for (i = 0; i < (m->m_len / sizeof(uint16_t) + 1); i++)
|
||||
*dst++ = *src++;
|
||||
m->m_data -= 6;
|
||||
return (m);
|
||||
}
|
||||
/*
|
||||
* Append a new mbuf to received mbuf chain and copy ethernet
|
||||
* header from the mbuf chain. This can save lots of CPU
|
||||
* cycles for jumbo frame.
|
||||
*/
|
||||
MGETHDR(n, M_NOWAIT, MT_DATA);
|
||||
if (n == NULL) {
|
||||
ifp->if_iqdrops++;
|
||||
m_freem(m);
|
||||
return (NULL);
|
||||
}
|
||||
bcopy(m->m_data, n->m_data, ETHER_HDR_LEN);
|
||||
m->m_data += ETHER_HDR_LEN;
|
||||
m->m_len -= ETHER_HDR_LEN;
|
||||
n->m_len = ETHER_HDR_LEN;
|
||||
M_MOVE_PKTHDR(n, m);
|
||||
n->m_next = m;
|
||||
return (n);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Receive a frame. */
|
||||
static void
|
||||
age_rxeof(struct age_softc *sc, struct rx_rdesc *rxrd)
|
||||
{
|
||||
struct age_rxdesc *rxd;
|
||||
struct rx_desc *desc;
|
||||
struct ifnet *ifp;
|
||||
struct mbuf *mp, *m;
|
||||
uint32_t status, index, vtag;
|
||||
int count, nsegs, pktlen;
|
||||
int count, nsegs;
|
||||
int rx_cons;
|
||||
|
||||
AGE_LOCK_ASSERT(sc);
|
||||
@@ -2276,9 +2333,7 @@ age_rxeof(struct age_softc *sc, struct rx_rdesc *rxrd)
|
||||
nsegs = AGE_RX_NSEGS(index);
|
||||
|
||||
sc->age_cdata.age_rxlen = AGE_RX_BYTES(le32toh(rxrd->len));
|
||||
if ((status & AGE_RRD_ERROR) != 0 &&
|
||||
(status & (AGE_RRD_CRC | AGE_RRD_CODE | AGE_RRD_DRIBBLE |
|
||||
AGE_RRD_RUNT | AGE_RRD_OFLOW | AGE_RRD_TRUNC)) != 0) {
|
||||
if ((status & (AGE_RRD_ERROR | AGE_RRD_LENGTH_NOK)) != 0) {
|
||||
/*
|
||||
* We want to pass the following frames to upper
|
||||
* layer regardless of error status of Rx return
|
||||
@@ -2288,33 +2343,31 @@ age_rxeof(struct age_softc *sc, struct rx_rdesc *rxrd)
|
||||
* o frame length and protocol specific length
|
||||
* does not match.
|
||||
*/
|
||||
sc->age_cdata.age_rx_cons += nsegs;
|
||||
sc->age_cdata.age_rx_cons %= AGE_RX_RING_CNT;
|
||||
return;
|
||||
status |= AGE_RRD_IPCSUM_NOK | AGE_RRD_TCP_UDPCSUM_NOK;
|
||||
if ((status & (AGE_RRD_CRC | AGE_RRD_CODE | AGE_RRD_DRIBBLE |
|
||||
AGE_RRD_RUNT | AGE_RRD_OFLOW | AGE_RRD_TRUNC)) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
pktlen = 0;
|
||||
for (count = 0; count < nsegs; count++,
|
||||
AGE_DESC_INC(rx_cons, AGE_RX_RING_CNT)) {
|
||||
rxd = &sc->age_cdata.age_rxdesc[rx_cons];
|
||||
mp = rxd->rx_m;
|
||||
desc = rxd->rx_desc;
|
||||
/* Add a new receive buffer to the ring. */
|
||||
if (age_newbuf(sc, rxd) != 0) {
|
||||
ifp->if_iqdrops++;
|
||||
/* Reuse Rx buffers. */
|
||||
if (sc->age_cdata.age_rxhead != NULL) {
|
||||
if (sc->age_cdata.age_rxhead != NULL)
|
||||
m_freem(sc->age_cdata.age_rxhead);
|
||||
AGE_RXCHAIN_RESET(sc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* The length of the first mbuf is computed last. */
|
||||
if (count != 0) {
|
||||
mp->m_len = AGE_RX_BYTES(le32toh(desc->len));
|
||||
pktlen += mp->m_len;
|
||||
}
|
||||
/*
|
||||
* Assume we've received a full sized frame.
|
||||
* Actual size is fixed when we encounter the end of
|
||||
* multi-segmented frame.
|
||||
*/
|
||||
mp->m_len = AGE_RX_BUF_SIZE;
|
||||
|
||||
/* Chain received mbufs. */
|
||||
if (sc->age_cdata.age_rxhead == NULL) {
|
||||
@@ -2329,14 +2382,20 @@ age_rxeof(struct age_softc *sc, struct rx_rdesc *rxrd)
|
||||
}
|
||||
|
||||
if (count == nsegs - 1) {
|
||||
/* Last desc. for this frame. */
|
||||
m = sc->age_cdata.age_rxhead;
|
||||
m->m_flags |= M_PKTHDR;
|
||||
/*
|
||||
* It seems that L1 controller has no way
|
||||
* to tell hardware to strip CRC bytes.
|
||||
*/
|
||||
sc->age_cdata.age_rxlen -= ETHER_CRC_LEN;
|
||||
m->m_pkthdr.len = sc->age_cdata.age_rxlen -
|
||||
ETHER_CRC_LEN;
|
||||
if (nsegs > 1) {
|
||||
/* Set last mbuf size. */
|
||||
mp->m_len = sc->age_cdata.age_rxlen -
|
||||
((nsegs - 1) * AGE_RX_BUF_SIZE);
|
||||
/* Remove the CRC bytes in chained mbufs. */
|
||||
pktlen -= ETHER_CRC_LEN;
|
||||
if (mp->m_len <= ETHER_CRC_LEN) {
|
||||
sc->age_cdata.age_rxtail =
|
||||
sc->age_cdata.age_rxprev_tail;
|
||||
@@ -2347,15 +2406,9 @@ age_rxeof(struct age_softc *sc, struct rx_rdesc *rxrd)
|
||||
} else {
|
||||
mp->m_len -= ETHER_CRC_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
m = sc->age_cdata.age_rxhead;
|
||||
m->m_flags |= M_PKTHDR;
|
||||
} else
|
||||
m->m_len = m->m_pkthdr.len;
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
m->m_pkthdr.len = sc->age_cdata.age_rxlen;
|
||||
/* Set the first mbuf length. */
|
||||
m->m_len = sc->age_cdata.age_rxlen - pktlen;
|
||||
|
||||
/*
|
||||
* Set checksum information.
|
||||
* It seems that L1 controller can compute partial
|
||||
@@ -2370,9 +2423,9 @@ age_rxeof(struct age_softc *sc, struct rx_rdesc *rxrd)
|
||||
*/
|
||||
if ((ifp->if_capenable & IFCAP_RXCSUM) != 0 &&
|
||||
(status & AGE_RRD_IPV4) != 0) {
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
|
||||
if ((status & AGE_RRD_IPCSUM_NOK) == 0)
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
|
||||
m->m_pkthdr.csum_flags |=
|
||||
CSUM_IP_CHECKED | CSUM_IP_VALID;
|
||||
if ((status & (AGE_RRD_TCP | AGE_RRD_UDP)) &&
|
||||
(status & AGE_RRD_TCP_UDPCSUM_NOK) == 0) {
|
||||
m->m_pkthdr.csum_flags |=
|
||||
@@ -2393,22 +2446,21 @@ age_rxeof(struct age_softc *sc, struct rx_rdesc *rxrd)
|
||||
m->m_pkthdr.ether_vtag = AGE_RX_VLAN_TAG(vtag);
|
||||
m->m_flags |= M_VLANTAG;
|
||||
}
|
||||
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
m = age_fixup_rx(ifp, m);
|
||||
if (m != NULL)
|
||||
#endif
|
||||
{
|
||||
/* Pass it on. */
|
||||
AGE_UNLOCK(sc);
|
||||
(*ifp->if_input)(ifp, m);
|
||||
AGE_LOCK(sc);
|
||||
|
||||
/* Reset mbuf chains. */
|
||||
AGE_RXCHAIN_RESET(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count != nsegs) {
|
||||
sc->age_cdata.age_rx_cons += nsegs;
|
||||
sc->age_cdata.age_rx_cons %= AGE_RX_RING_CNT;
|
||||
} else
|
||||
sc->age_cdata.age_rx_cons = rx_cons;
|
||||
/* Reset mbuf chains. */
|
||||
AGE_RXCHAIN_RESET(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2430,7 +2482,7 @@ age_rxintr(struct age_softc *sc, int rr_prod, int count)
|
||||
sc->age_cdata.age_rx_ring_map, BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
for (prog = 0; rr_cons != rr_prod; prog++) {
|
||||
if (count <= 0)
|
||||
if (count-- <= 0)
|
||||
break;
|
||||
rxrd = &sc->age_rdata.age_rr_ring[rr_cons];
|
||||
nsegs = AGE_RX_NSEGS(le32toh(rxrd->index));
|
||||
@@ -2443,16 +2495,16 @@ age_rxintr(struct age_softc *sc, int rr_prod, int count)
|
||||
* I'm not sure whether this check is really needed.
|
||||
*/
|
||||
pktlen = AGE_RX_BYTES(le32toh(rxrd->len));
|
||||
if (nsegs != ((pktlen + (MCLBYTES - ETHER_ALIGN - 1)) /
|
||||
(MCLBYTES - ETHER_ALIGN)))
|
||||
if (nsegs != (pktlen + (AGE_RX_BUF_SIZE - 1)) / AGE_RX_BUF_SIZE)
|
||||
break;
|
||||
|
||||
prog++;
|
||||
/* Received a frame. */
|
||||
age_rxeof(sc, rxrd);
|
||||
/* Clear return ring. */
|
||||
rxrd->index = 0;
|
||||
AGE_DESC_INC(rr_cons, AGE_RR_RING_CNT);
|
||||
sc->age_cdata.age_rx_cons += nsegs;
|
||||
sc->age_cdata.age_rx_cons %= AGE_RX_RING_CNT;
|
||||
}
|
||||
|
||||
if (prog > 0) {
|
||||
@@ -3048,11 +3100,13 @@ age_newbuf(struct age_softc *sc, struct age_rxdesc *rxd)
|
||||
|
||||
AGE_LOCK_ASSERT(sc);
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
m->m_len = m->m_pkthdr.len = MCLBYTES;
|
||||
m_adj(m, ETHER_ALIGN);
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
m_adj(m, AGE_RX_BUF_ALIGN);
|
||||
#endif
|
||||
|
||||
if (bus_dmamap_load_mbuf_sg(sc->age_cdata.age_rx_tag,
|
||||
sc->age_cdata.age_rx_sparemap, m, segs, &nsegs, 0) != 0) {
|
||||
|
||||
@@ -43,6 +43,12 @@
|
||||
#define AGE_TSO_MAXSEGSIZE 4096
|
||||
#define AGE_TSO_MAXSIZE (65535 + sizeof(struct ether_vlan_header))
|
||||
#define AGE_MAXTXSEGS 32
|
||||
#define AGE_RX_BUF_ALIGN 8
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
#define AGE_RX_BUF_SIZE (MCLBYTES - AGE_RX_BUF_ALIGN)
|
||||
#else
|
||||
#define AGE_RX_BUF_SIZE (MCLBYTES)
|
||||
#endif
|
||||
|
||||
#define AGE_ADDR_LO(x) ((uint64_t) (x) & 0xFFFFFFFF)
|
||||
#define AGE_ADDR_HI(x) ((uint64_t) (x) >> 32)
|
||||
|
||||
@@ -585,6 +585,9 @@ ae_init_locked(ae_softc_t *sc)
|
||||
val = eaddr[0] << 8 | eaddr[1];
|
||||
AE_WRITE_4(sc, AE_EADDR1_REG, val);
|
||||
|
||||
bzero(sc->rxd_base_dma, AE_RXD_COUNT_DEFAULT * 1536 + 120);
|
||||
bzero(sc->txd_base, AE_TXD_BUFSIZE_DEFAULT);
|
||||
bzero(sc->txs_base, AE_TXS_COUNT_DEFAULT * 4);
|
||||
/*
|
||||
* Set ring buffers base addresses.
|
||||
*/
|
||||
@@ -1119,7 +1122,7 @@ ae_alloc_rings(ae_softc_t *sc)
|
||||
* Create DMA tag for TxD.
|
||||
*/
|
||||
error = bus_dma_tag_create(sc->dma_parent_tag,
|
||||
4, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
|
||||
8, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
|
||||
NULL, NULL, AE_TXD_BUFSIZE_DEFAULT, 1,
|
||||
AE_TXD_BUFSIZE_DEFAULT, 0, NULL, NULL,
|
||||
&sc->dma_txd_tag);
|
||||
@@ -1132,7 +1135,7 @@ ae_alloc_rings(ae_softc_t *sc)
|
||||
* Create DMA tag for TxS.
|
||||
*/
|
||||
error = bus_dma_tag_create(sc->dma_parent_tag,
|
||||
4, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
|
||||
8, 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
|
||||
NULL, NULL, AE_TXS_COUNT_DEFAULT * 4, 1,
|
||||
AE_TXS_COUNT_DEFAULT * 4, 0, NULL, NULL,
|
||||
&sc->dma_txs_tag);
|
||||
@@ -1765,6 +1768,10 @@ ae_int_task(void *arg, int pending)
|
||||
ifp = sc->ifp;
|
||||
|
||||
val = AE_READ_4(sc, AE_ISR_REG); /* Read interrupt status. */
|
||||
if (val == 0) {
|
||||
AE_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear interrupts and disable them.
|
||||
@@ -1787,12 +1794,16 @@ ae_int_task(void *arg, int pending)
|
||||
ae_tx_intr(sc);
|
||||
if ((val & AE_ISR_RX_EVENT) != 0)
|
||||
ae_rx_intr(sc);
|
||||
}
|
||||
/*
|
||||
* Re-enable interrupts.
|
||||
*/
|
||||
AE_WRITE_4(sc, AE_ISR_REG, 0);
|
||||
|
||||
/*
|
||||
* Re-enable interrupts.
|
||||
*/
|
||||
AE_WRITE_4(sc, AE_ISR_REG, 0);
|
||||
if ((sc->flags & AE_FLAG_TXAVAIL) != 0) {
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
ae_start_locked(ifp);
|
||||
}
|
||||
}
|
||||
|
||||
AE_UNLOCK(sc);
|
||||
}
|
||||
@@ -1853,10 +1864,10 @@ ae_tx_intr(ae_softc_t *sc)
|
||||
ifp->if_oerrors++;
|
||||
|
||||
sc->tx_inproc--;
|
||||
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
}
|
||||
|
||||
if ((sc->flags & AE_FLAG_TXAVAIL) != 0)
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
if (sc->tx_inproc < 0) {
|
||||
if_printf(ifp, "Received stray Tx interrupt(s).\n");
|
||||
sc->tx_inproc = 0;
|
||||
@@ -1864,11 +1875,6 @@ ae_tx_intr(ae_softc_t *sc)
|
||||
|
||||
if (sc->tx_inproc == 0)
|
||||
sc->wd_timer = 0; /* Unarm watchdog. */
|
||||
|
||||
if ((sc->flags & AE_FLAG_TXAVAIL) != 0) {
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
ae_start_locked(ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Syncronize DMA buffers.
|
||||
@@ -1927,7 +1933,7 @@ ae_rx_intr(ae_softc_t *sc)
|
||||
ae_rxd_t *rxd;
|
||||
struct ifnet *ifp;
|
||||
uint16_t flags;
|
||||
int error;
|
||||
int count, error;
|
||||
|
||||
KASSERT(sc != NULL, ("[ae, %d]: sc is NULL!", __LINE__));
|
||||
|
||||
@@ -1941,7 +1947,7 @@ ae_rx_intr(ae_softc_t *sc)
|
||||
bus_dmamap_sync(sc->dma_rxd_tag, sc->dma_rxd_map,
|
||||
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
for (;;) {
|
||||
for (count = 0;; count++) {
|
||||
rxd = (ae_rxd_t *)(sc->rxd_base + sc->rxd_cur);
|
||||
flags = le16toh(rxd->flags);
|
||||
if ((flags & AE_RXD_UPDATE) == 0)
|
||||
@@ -1968,10 +1974,14 @@ ae_rx_intr(ae_softc_t *sc)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update Rx index.
|
||||
*/
|
||||
AE_WRITE_2(sc, AE_MB_RXD_IDX_REG, sc->rxd_cur);
|
||||
if (count > 0) {
|
||||
bus_dmamap_sync(sc->dma_rxd_tag, sc->dma_rxd_map,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
/*
|
||||
* Update Rx index.
|
||||
*/
|
||||
AE_WRITE_2(sc, AE_MB_RXD_IDX_REG, sc->rxd_cur);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -792,7 +792,7 @@ bfe_list_newbuf(struct bfe_softc *sc, int c)
|
||||
u_int32_t ctrl;
|
||||
int nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
m->m_len = m->m_pkthdr.len = MCLBYTES;
|
||||
|
||||
if (bus_dmamap_load_mbuf_sg(sc->bfe_rxmbuf_tag, sc->bfe_rx_sparemap,
|
||||
@@ -1520,7 +1520,7 @@ bfe_encap(struct bfe_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->bfe_txmbuf_tag, r->bfe_map, *m_head,
|
||||
txsegs, &nsegs, 0);
|
||||
if (error == EFBIG) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, BFE_MAXTXSEGS);
|
||||
m = m_collapse(*m_head, M_NOWAIT, BFE_MAXTXSEGS);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
|
||||
@@ -32,10 +32,6 @@
|
||||
#ifndef _BCEREG_H_DEFINED
|
||||
#define _BCEREG_H_DEFINED
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
#include "opt_device_polling.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/systm.h>
|
||||
@@ -623,7 +619,7 @@ struct bce_type {
|
||||
u_int16_t bce_did;
|
||||
u_int16_t bce_svid;
|
||||
u_int16_t bce_sdid;
|
||||
char *bce_name;
|
||||
const char *bce_name;
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -717,7 +713,7 @@ struct flash_spec {
|
||||
u32 page_size;
|
||||
u32 addr_mask;
|
||||
u32 total_size;
|
||||
u8 *name;
|
||||
const u8 *name;
|
||||
};
|
||||
|
||||
|
||||
@@ -2002,7 +1998,7 @@ struct l2_fhdr {
|
||||
#define BCE_MISC_ENABLE_CLR_BITS_UMP_ENABLE (1L<<27)
|
||||
#define BCE_MISC_ENABLE_CLR_BITS_RV2P_CMD_SCHEDULER_ENABLE (1L<<28)
|
||||
#define BCE_MISC_ENABLE_CLR_BITS_RSVD_FUTURE_ENABLE (0x7L<<29)
|
||||
|
||||
|
||||
#define BCE_MISC_ENABLE_CLR_DEFAULT 0x17ffffff
|
||||
|
||||
#define BCE_MISC_CLOCK_CONTROL_BITS 0x00000818
|
||||
@@ -6319,31 +6315,31 @@ struct fw_info {
|
||||
u32 text_addr;
|
||||
u32 text_len;
|
||||
u32 text_index;
|
||||
u32 *text;
|
||||
const u32 *text;
|
||||
|
||||
/* Data section. */
|
||||
u32 data_addr;
|
||||
u32 data_len;
|
||||
u32 data_index;
|
||||
u32 *data;
|
||||
const u32 *data;
|
||||
|
||||
/* SBSS section. */
|
||||
u32 sbss_addr;
|
||||
u32 sbss_len;
|
||||
u32 sbss_index;
|
||||
u32 *sbss;
|
||||
const u32 *sbss;
|
||||
|
||||
/* BSS section. */
|
||||
u32 bss_addr;
|
||||
u32 bss_len;
|
||||
u32 bss_index;
|
||||
u32 *bss;
|
||||
const u32 *bss;
|
||||
|
||||
/* Read-only section. */
|
||||
u32 rodata_addr;
|
||||
u32 rodata_len;
|
||||
u32 rodata_index;
|
||||
u32 *rodata;
|
||||
const u32 *rodata;
|
||||
};
|
||||
|
||||
#define RV2P_PROC1 0
|
||||
@@ -6422,7 +6418,9 @@ struct fw_info {
|
||||
|
||||
struct bce_softc
|
||||
{
|
||||
/* Interface info. Must be first!! */
|
||||
struct mtx bce_mtx;
|
||||
|
||||
/* Interface info */
|
||||
struct ifnet *bce_ifp;
|
||||
|
||||
/* Parent device handle */
|
||||
@@ -6449,13 +6447,8 @@ struct bce_softc
|
||||
/* IRQ Resource Handle */
|
||||
struct resource *bce_res_irq;
|
||||
|
||||
struct mtx bce_mtx;
|
||||
|
||||
/* Interrupt handler. */
|
||||
driver_intr_t *bce_intr;
|
||||
void *bce_intrhand;
|
||||
int bce_irq_rid;
|
||||
int bce_msi_count;
|
||||
|
||||
/* ASIC Chip ID. */
|
||||
u32 bce_chipid;
|
||||
@@ -6473,6 +6466,7 @@ struct bce_softc
|
||||
#define BCE_USING_MSIX_FLAG 0x00000100
|
||||
#define BCE_PCIE_FLAG 0x00000200
|
||||
#define BCE_USING_TX_FLOW_CONTROL 0x00000400
|
||||
#define BCE_USING_RX_FLOW_CONTROL 0x00000800
|
||||
|
||||
/* Controller capability flags. */
|
||||
u32 bce_cap_flags;
|
||||
@@ -6510,7 +6504,7 @@ struct bce_softc
|
||||
u16 link_speed;
|
||||
|
||||
/* Flash NVRAM settings */
|
||||
struct flash_spec *bce_flash_info;
|
||||
const struct flash_spec *bce_flash_info;
|
||||
|
||||
/* Flash NVRAM size */
|
||||
u32 bce_flash_size;
|
||||
@@ -6519,7 +6513,7 @@ struct bce_softc
|
||||
u32 bce_shmem_base;
|
||||
|
||||
/* Name string */
|
||||
char *bce_name;
|
||||
const char *bce_name;
|
||||
|
||||
/* Tracks the version of bootcode firmware. */
|
||||
char bce_bc_ver[32];
|
||||
@@ -6567,14 +6561,6 @@ struct bce_softc
|
||||
u16 bce_rx_ticks;
|
||||
u32 bce_stats_ticks;
|
||||
|
||||
/* ToDo: Can these be removed? */
|
||||
u16 bce_comp_prod_trip_int;
|
||||
u16 bce_comp_prod_trip;
|
||||
u16 bce_com_ticks_int;
|
||||
u16 bce_com_ticks;
|
||||
u16 bce_cmd_ticks_int;
|
||||
u16 bce_cmd_ticks;
|
||||
|
||||
/* The address of the integrated PHY on the MII bus. */
|
||||
int bce_phy_addr;
|
||||
|
||||
@@ -6607,11 +6593,9 @@ struct bce_softc
|
||||
int watchdog_timer;
|
||||
|
||||
/* Frame size and mbuf allocation size for RX frames. */
|
||||
u32 max_frame_size;
|
||||
int rx_bd_mbuf_alloc_size;
|
||||
int rx_bd_mbuf_data_len;
|
||||
int rx_bd_mbuf_align_pad;
|
||||
int pg_bd_mbuf_alloc_size;
|
||||
|
||||
/* Receive mode settings (i.e promiscuous, multicast, etc.). */
|
||||
u32 rx_mode;
|
||||
@@ -6835,4 +6819,3 @@ struct bce_softc
|
||||
};
|
||||
|
||||
#endif /* __BCEREG_H_DEFINED */
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -360,6 +360,7 @@
|
||||
#define BGE_ASICREV_BCM5784 0x5784
|
||||
#define BGE_ASICREV_BCM5785 0x5785
|
||||
#define BGE_ASICREV_BCM57765 0x57785
|
||||
#define BGE_ASICREV_BCM57766 0x57766
|
||||
#define BGE_ASICREV_BCM57780 0x57780
|
||||
|
||||
/* chip revisions */
|
||||
@@ -430,10 +431,14 @@
|
||||
#define BGE_PCISTATE_PCI_BUSMODE 0x00000004 /* 1 = PCI, 0 = PCI-X */
|
||||
#define BGE_PCISTATE_PCI_BUSSPEED 0x00000008 /* 1 = 66/133, 0 = 33/66 */
|
||||
#define BGE_PCISTATE_32BIT_BUS 0x00000010 /* 1 = 32bit, 0 = 64bit */
|
||||
#define BGE_PCISTATE_WANT_EXPROM 0x00000020
|
||||
#define BGE_PCISTATE_EXPROM_RETRY 0x00000040
|
||||
#define BGE_PCISTATE_ROM_ENABLE 0x00000020
|
||||
#define BGE_PCISTATE_ROM_RETRY_ENABLE 0x00000040
|
||||
#define BGE_PCISTATE_FLATVIEW_MODE 0x00000100
|
||||
#define BGE_PCISTATE_PCI_TGT_RETRY_MAX 0x00000E00
|
||||
#define BGE_PCISTATE_RETRY_SAME_DMA 0x00002000
|
||||
#define BGE_PCISTATE_ALLOW_APE_CTLSPC_WR 0x00010000
|
||||
#define BGE_PCISTATE_ALLOW_APE_SHMEM_WR 0x00020000
|
||||
#define BGE_PCISTATE_ALLOW_APE_PSPACE_WR 0x00040000
|
||||
|
||||
/*
|
||||
* PCI Clock Control register -- note, this register is read only
|
||||
@@ -459,6 +464,8 @@
|
||||
#define PCIM_CMD_INTxDIS 0x0400
|
||||
#endif
|
||||
|
||||
/* BAR0 (MAC) Register Definitions */
|
||||
|
||||
/*
|
||||
* High priority mailbox registers
|
||||
* Each mailbox is 64-bits wide, though we only use the
|
||||
@@ -741,6 +748,8 @@
|
||||
#define BGE_MACMODE_TXDMA_ENB 0x00200000
|
||||
#define BGE_MACMODE_RXDMA_ENB 0x00400000
|
||||
#define BGE_MACMODE_FRMHDR_DMA_ENB 0x00800000
|
||||
#define BGE_MACMODE_APE_RX_EN 0x08000000
|
||||
#define BGE_MACMODE_APE_TX_EN 0x10000000
|
||||
|
||||
#define BGE_PORTMODE_NONE 0x00000000
|
||||
#define BGE_PORTMODE_MII 0x00000004
|
||||
@@ -788,7 +797,7 @@
|
||||
#define BGE_LEDCTL_BLINKPERIOD_OVERRIDE 0x80000000
|
||||
|
||||
/* TX backoff seed register */
|
||||
#define BGE_TX_BACKOFF_SEED_MASK 0x3F
|
||||
#define BGE_TX_BACKOFF_SEED_MASK 0x3FF
|
||||
|
||||
/* Autopoll status register */
|
||||
#define BGE_AUTOPOLLSTS_ERROR 0x00000001
|
||||
@@ -828,6 +837,7 @@
|
||||
#define BGE_RXMODE_RX_PROMISC 0x00000100
|
||||
#define BGE_RXMODE_RX_NO_CRC_CHECK 0x00000200
|
||||
#define BGE_RXMODE_RX_KEEP_VLAN_DIAG 0x00000400
|
||||
#define BGE_RXMODE_IPV6_ENABLE 0x01000000
|
||||
|
||||
/* Receive MAC status register */
|
||||
#define BGE_RXSTAT_REMOTE_XOFFED 0x00000001
|
||||
@@ -1577,6 +1587,22 @@
|
||||
#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_BD_4K 0x00030000
|
||||
#define BGE_RDMA_LSO_CRPTEN_CTRL_BLEN_LSO_4K 0x000C0000
|
||||
|
||||
/* BD Read DMA Mode register */
|
||||
#define BGE_RDMA_BD_MODE 0x4A00
|
||||
/* BD Read DMA Mode status register */
|
||||
#define BGE_RDMA_BD_STATUS 0x4A04
|
||||
|
||||
#define BGE_RDMA_BD_MODE_RESET 0x00000001
|
||||
#define BGE_RDMA_BD_MODE_ENABLE 0x00000002
|
||||
|
||||
/* Non-LSO Read DMA Mode register */
|
||||
#define BGE_RDMA_NON_LSO_MODE 0x4B00
|
||||
/* Non-LSO Read DMA Mode status register */
|
||||
#define BGE_RDMA_NON_LSO_STATUS 0x4B04
|
||||
|
||||
#define BGE_RDMA_NON_LSO_MODE_RESET 0x00000001
|
||||
#define BGE_RDMA_NON_LSO_MODE_ENABLE 0x00000002
|
||||
|
||||
/*
|
||||
* Write DMA control registers
|
||||
*/
|
||||
@@ -2064,6 +2090,112 @@
|
||||
#define BGE_MEMWIN_START 0x00008000
|
||||
#define BGE_MEMWIN_END 0x0000FFFF
|
||||
|
||||
/* BAR1 (APE) Register Definitions */
|
||||
|
||||
#define BGE_APE_GPIO_MSG 0x0008
|
||||
#define BGE_APE_EVENT 0x000C
|
||||
#define BGE_APE_LOCK_REQ 0x002C
|
||||
#define BGE_APE_LOCK_GRANT 0x004C
|
||||
|
||||
#define BGE_APE_GPIO_MSG_SHIFT 4
|
||||
|
||||
#define BGE_APE_EVENT_1 0x00000001
|
||||
|
||||
#define BGE_APE_LOCK_REQ_DRIVER0 0x00001000
|
||||
|
||||
#define BGE_APE_LOCK_GRANT_DRIVER0 0x00001000
|
||||
|
||||
/* APE Shared Memory block (writable by APE only) */
|
||||
#define BGE_APE_SEG_SIG 0x4000
|
||||
#define BGE_APE_FW_STATUS 0x400C
|
||||
#define BGE_APE_FW_FEATURES 0x4010
|
||||
#define BGE_APE_FW_BEHAVIOR 0x4014
|
||||
#define BGE_APE_FW_VERSION 0x4018
|
||||
#define BGE_APE_FW_HEARTBEAT_INTERVAL 0x4024
|
||||
#define BGE_APE_FW_HEARTBEAT 0x4028
|
||||
#define BGE_APE_FW_ERROR_FLAGS 0x4074
|
||||
|
||||
#define BGE_APE_SEG_SIG_MAGIC 0x41504521
|
||||
|
||||
#define BGE_APE_FW_STATUS_READY 0x00000100
|
||||
|
||||
#define BGE_APE_FW_FEATURE_DASH 0x00000001
|
||||
#define BGE_APE_FW_FEATURE_NCSI 0x00000002
|
||||
|
||||
#define BGE_APE_FW_VERSION_MAJMSK 0xFF000000
|
||||
#define BGE_APE_FW_VERSION_MAJSFT 24
|
||||
#define BGE_APE_FW_VERSION_MINMSK 0x00FF0000
|
||||
#define BGE_APE_FW_VERSION_MINSFT 16
|
||||
#define BGE_APE_FW_VERSION_REVMSK 0x0000FF00
|
||||
#define BGE_APE_FW_VERSION_REVSFT 8
|
||||
#define BGE_APE_FW_VERSION_BLDMSK 0x000000FF
|
||||
|
||||
/* Host Shared Memory block (writable by host only) */
|
||||
#define BGE_APE_HOST_SEG_SIG 0x4200
|
||||
#define BGE_APE_HOST_SEG_LEN 0x4204
|
||||
#define BGE_APE_HOST_INIT_COUNT 0x4208
|
||||
#define BGE_APE_HOST_DRIVER_ID 0x420C
|
||||
#define BGE_APE_HOST_BEHAVIOR 0x4210
|
||||
#define BGE_APE_HOST_HEARTBEAT_INT_MS 0x4214
|
||||
#define BGE_APE_HOST_HEARTBEAT_COUNT 0x4218
|
||||
#define BGE_APE_HOST_DRVR_STATE 0x421C
|
||||
#define BGE_APE_HOST_WOL_SPEED 0x4224
|
||||
|
||||
#define BGE_APE_HOST_SEG_SIG_MAGIC 0x484F5354
|
||||
|
||||
#define BGE_APE_HOST_SEG_LEN_MAGIC 0x00000020
|
||||
|
||||
#define BGE_APE_HOST_DRIVER_ID_FBSD 0xF6000000
|
||||
#define BGE_APE_HOST_DRIVER_ID_MAGIC(maj, min) \
|
||||
(BGE_APE_HOST_DRIVER_ID_FBSD | \
|
||||
((maj) & 0xffd) << 16 | ((min) & 0xff) << 8)
|
||||
|
||||
#define BGE_APE_HOST_BEHAV_NO_PHYLOCK 0x00000001
|
||||
|
||||
#define BGE_APE_HOST_HEARTBEAT_INT_DISABLE 0
|
||||
#define BGE_APE_HOST_HEARTBEAT_INT_5SEC 5000
|
||||
|
||||
#define BGE_APE_HOST_DRVR_STATE_START 0x00000001
|
||||
#define BGE_APE_HOST_DRVR_STATE_UNLOAD 0x00000002
|
||||
#define BGE_APE_HOST_DRVR_STATE_WOL 0x00000003
|
||||
#define BGE_APE_HOST_DRVR_STATE_SUSPEND 0x00000004
|
||||
|
||||
#define BGE_APE_HOST_WOL_SPEED_AUTO 0x00008000
|
||||
|
||||
#define BGE_APE_EVENT_STATUS 0x4300
|
||||
|
||||
#define BGE_APE_EVENT_STATUS_DRIVER_EVNT 0x00000010
|
||||
#define BGE_APE_EVENT_STATUS_STATE_CHNGE 0x00000500
|
||||
#define BGE_APE_EVENT_STATUS_STATE_START 0x00010000
|
||||
#define BGE_APE_EVENT_STATUS_STATE_UNLOAD 0x00020000
|
||||
#define BGE_APE_EVENT_STATUS_STATE_WOL 0x00030000
|
||||
#define BGE_APE_EVENT_STATUS_STATE_SUSPEND 0x00040000
|
||||
#define BGE_APE_EVENT_STATUS_EVENT_PENDING 0x80000000
|
||||
|
||||
#define BGE_APE_DEBUG_LOG 0x4E00
|
||||
#define BGE_APE_DEBUG_LOG_LEN 0x0100
|
||||
|
||||
#define BGE_APE_PER_LOCK_REQ 0x8400
|
||||
#define BGE_APE_PER_LOCK_GRANT 0x8420
|
||||
|
||||
#define BGE_APE_LOCK_PER_REQ_DRIVER0 0x00001000
|
||||
#define BGE_APE_LOCK_PER_REQ_DRIVER1 0x00000002
|
||||
#define BGE_APE_LOCK_PER_REQ_DRIVER2 0x00000004
|
||||
#define BGE_APE_LOCK_PER_REQ_DRIVER3 0x00000008
|
||||
|
||||
#define BGE_APE_PER_LOCK_GRANT_DRIVER0 0x00001000
|
||||
#define BGE_APE_PER_LOCK_GRANT_DRIVER1 0x00000002
|
||||
#define BGE_APE_PER_LOCK_GRANT_DRIVER2 0x00000004
|
||||
#define BGE_APE_PER_LOCK_GRANT_DRIVER3 0x00000008
|
||||
|
||||
/* APE Mutex Resources */
|
||||
#define BGE_APE_LOCK_PHY0 0
|
||||
#define BGE_APE_LOCK_GRC 1
|
||||
#define BGE_APE_LOCK_PHY1 2
|
||||
#define BGE_APE_LOCK_PHY2 3
|
||||
#define BGE_APE_LOCK_MEM 4
|
||||
#define BGE_APE_LOCK_PHY3 5
|
||||
#define BGE_APE_LOCK_GPIO 7
|
||||
|
||||
#define BGE_MEMWIN_READ(sc, x, val) \
|
||||
do { \
|
||||
@@ -2352,7 +2484,9 @@ struct bge_status_block {
|
||||
#define BCOM_DEVICEID_BCM5906M 0x1713
|
||||
#define BCOM_DEVICEID_BCM57760 0x1690
|
||||
#define BCOM_DEVICEID_BCM57761 0x16B0
|
||||
#define BCOM_DEVICEID_BCM57762 0x1682
|
||||
#define BCOM_DEVICEID_BCM57765 0x16B4
|
||||
#define BCOM_DEVICEID_BCM57766 0x1686
|
||||
#define BCOM_DEVICEID_BCM57780 0x1692
|
||||
#define BCOM_DEVICEID_BCM57781 0x16B1
|
||||
#define BCOM_DEVICEID_BCM57785 0x16B5
|
||||
@@ -2658,7 +2792,7 @@ struct bge_gib {
|
||||
#define BGE_INC(x, y) (x) = (x + 1) % y
|
||||
|
||||
/*
|
||||
* Register access macros. The Tigon always uses memory mapped register
|
||||
* BAR0 MAC register access macros. The Tigon always uses memory mapped register
|
||||
* accesses and all registers must be accessed with 32 bit operations.
|
||||
*/
|
||||
|
||||
@@ -2673,6 +2807,18 @@ struct bge_gib {
|
||||
#define BGE_CLRBIT(sc, reg, x) \
|
||||
CSR_WRITE_4(sc, reg, (CSR_READ_4(sc, reg) & ~(x)))
|
||||
|
||||
/* BAR2 APE register access macros. */
|
||||
#define APE_WRITE_4(sc, reg, val) \
|
||||
bus_write_4(sc->bge_res2, reg, val)
|
||||
|
||||
#define APE_READ_4(sc, reg) \
|
||||
bus_read_4(sc->bge_res2, reg)
|
||||
|
||||
#define APE_SETBIT(sc, reg, x) \
|
||||
APE_WRITE_4(sc, reg, (APE_READ_4(sc, reg) | (x)))
|
||||
#define APE_CLRBIT(sc, reg, x) \
|
||||
APE_WRITE_4(sc, reg, (APE_READ_4(sc, reg) & ~(x)))
|
||||
|
||||
#define PCI_SETBIT(dev, reg, x, s) \
|
||||
pci_write_config(dev, reg, (pci_read_config(dev, reg, s) | (x)), s)
|
||||
#define PCI_CLRBIT(dev, reg, x, s) \
|
||||
@@ -2782,6 +2928,7 @@ struct bge_dmamap_arg {
|
||||
#define BGE_HWREV_TIGON_II 0x02
|
||||
#define BGE_TIMEOUT 100000
|
||||
#define BGE_TXCONS_UNSET 0xFFFF /* impossible value */
|
||||
#define BGE_TX_TIMEOUT 5
|
||||
|
||||
struct bge_bcom_hack {
|
||||
int reg;
|
||||
@@ -2799,9 +2946,11 @@ struct bge_softc {
|
||||
device_t bge_miibus;
|
||||
void *bge_intrhand;
|
||||
struct resource *bge_irq;
|
||||
struct resource *bge_res;
|
||||
struct resource *bge_res; /* MAC mapped I/O */
|
||||
struct resource *bge_res2; /* APE mapped I/O */
|
||||
struct ifmedia bge_ifmedia; /* TBI media info */
|
||||
int bge_expcap;
|
||||
int bge_expmrq;
|
||||
int bge_msicap;
|
||||
int bge_pcixcap;
|
||||
uint32_t bge_flags;
|
||||
@@ -2812,6 +2961,7 @@ struct bge_softc {
|
||||
#define BGE_FLAG_MII_SERDES 0x00000010
|
||||
#define BGE_FLAG_CPMU_PRESENT 0x00000020
|
||||
#define BGE_FLAG_TAGGED_STATUS 0x00000040
|
||||
#define BGE_FLAG_APE 0x00000080
|
||||
#define BGE_FLAG_MSI 0x00000100
|
||||
#define BGE_FLAG_PCIX 0x00000200
|
||||
#define BGE_FLAG_PCIE 0x00000400
|
||||
@@ -2825,12 +2975,21 @@ struct bge_softc {
|
||||
#define BGE_FLAG_5755_PLUS 0x00100000
|
||||
#define BGE_FLAG_5788 0x00200000
|
||||
#define BGE_FLAG_5717_PLUS 0x00400000
|
||||
#define BGE_FLAG_57765_PLUS 0x00800000
|
||||
#define BGE_FLAG_40BIT_BUG 0x01000000
|
||||
#define BGE_FLAG_4G_BNDRY_BUG 0x02000000
|
||||
#define BGE_FLAG_RX_ALIGNBUG 0x04000000
|
||||
#define BGE_FLAG_SHORT_DMA_BUG 0x08000000
|
||||
#define BGE_FLAG_4K_RDMA_BUG 0x10000000
|
||||
#define BGE_FLAG_MBOX_REORDER 0x20000000
|
||||
uint32_t bge_mfw_flags; /* Management F/W flags */
|
||||
#define BGE_MFW_ON_RXCPU 0x00000001
|
||||
#define BGE_MFW_ON_APE 0x00000002
|
||||
#define BGE_MFW_TYPE_NCSI 0x00000004
|
||||
#define BGE_MFW_TYPE_DASH 0x00000008
|
||||
int bge_phy_ape_lock;
|
||||
int bge_func_addr;
|
||||
int bge_phy_addr;
|
||||
uint32_t bge_phy_flags;
|
||||
#define BGE_PHY_NO_WIRESPEED 0x00000001
|
||||
#define BGE_PHY_ADC_BUG 0x00000002
|
||||
@@ -2845,6 +3004,7 @@ struct bge_softc {
|
||||
uint32_t bge_chiprev;
|
||||
uint8_t bge_asf_mode;
|
||||
uint8_t bge_asf_count;
|
||||
uint16_t bge_mps;
|
||||
struct bge_ring_data bge_ldata; /* rings */
|
||||
struct bge_chain_data bge_cdata; /* mbufs */
|
||||
uint16_t bge_tx_saved_considx;
|
||||
|
||||
@@ -204,6 +204,13 @@ brgphy_attach(device_t dev)
|
||||
&brgphy_funcs, 0);
|
||||
|
||||
bsc->serdes_flags = 0;
|
||||
ifp = sc->mii_pdata->mii_ifp;
|
||||
|
||||
/* Find the MAC driver associated with this PHY. */
|
||||
if (strcmp(ifp->if_dname, "bge") == 0)
|
||||
bge_sc = ifp->if_softc;
|
||||
else if (strcmp(ifp->if_dname, "bce") == 0)
|
||||
bce_sc = ifp->if_softc;
|
||||
|
||||
/* Handle any special cases based on the PHY ID */
|
||||
switch (sc->mii_mpd_oui) {
|
||||
@@ -235,22 +242,21 @@ brgphy_attach(device_t dev)
|
||||
sc->mii_flags |= MIIF_HAVEFIBER;
|
||||
break;
|
||||
case MII_MODEL_BROADCOM2_BCM5709S:
|
||||
bsc->serdes_flags |= BRGPHY_5709S;
|
||||
/*
|
||||
* XXX
|
||||
* 5720S and 5709S shares the same PHY id.
|
||||
* Assume 5720S PHY if parent device is bge(4).
|
||||
*/
|
||||
if (bge_sc != NULL)
|
||||
bsc->serdes_flags |= BRGPHY_5708S;
|
||||
else
|
||||
bsc->serdes_flags |= BRGPHY_5709S;
|
||||
sc->mii_flags |= MIIF_HAVEFIBER;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ifp = sc->mii_pdata->mii_ifp;
|
||||
|
||||
/* Find the MAC driver associated with this PHY. */
|
||||
if (strcmp(ifp->if_dname, "bge") == 0) {
|
||||
bge_sc = ifp->if_softc;
|
||||
} else if (strcmp(ifp->if_dname, "bce") == 0) {
|
||||
bce_sc = ifp->if_softc;
|
||||
}
|
||||
|
||||
PHY_RESET(sc);
|
||||
|
||||
/* Read the PHY's capabilities. */
|
||||
@@ -608,6 +614,11 @@ brgphy_mii_phy_auto(struct mii_softc *sc, int media)
|
||||
(sc->mii_flags & MIIF_FORCEPAUSE) != 0)
|
||||
anar |= BRGPHY_ANAR_PC | BRGPHY_ANAR_ASP;
|
||||
PHY_WRITE(sc, BRGPHY_MII_ANAR, anar);
|
||||
ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD;
|
||||
if (sc->mii_mpd_model == MII_MODEL_BROADCOM_BCM5701)
|
||||
ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC;
|
||||
PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr);
|
||||
PHY_READ(sc, BRGPHY_MII_1000CTL);
|
||||
} else {
|
||||
anar = BRGPHY_SERDES_ANAR_FDX | BRGPHY_SERDES_ANAR_HDX;
|
||||
if ((media & IFM_FLOW) != 0 ||
|
||||
@@ -616,12 +627,6 @@ brgphy_mii_phy_auto(struct mii_softc *sc, int media)
|
||||
PHY_WRITE(sc, BRGPHY_SERDES_ANAR, anar);
|
||||
}
|
||||
|
||||
ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD;
|
||||
if (sc->mii_mpd_model == MII_MODEL_BROADCOM_BCM5701)
|
||||
ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC;
|
||||
PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr);
|
||||
ktcr = PHY_READ(sc, BRGPHY_MII_1000CTL);
|
||||
|
||||
PHY_WRITE(sc, BRGPHY_MII_BMCR, BRGPHY_BMCR_AUTOEN |
|
||||
BRGPHY_BMCR_STARTNEG);
|
||||
PHY_WRITE(sc, BRGPHY_MII_IMR, 0xFF00);
|
||||
@@ -918,6 +923,15 @@ brgphy_reset(struct mii_softc *sc)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MII_OUI_BROADCOM3:
|
||||
switch (sc->mii_mpd_model) {
|
||||
case MII_MODEL_BROADCOM3_BCM5717C:
|
||||
case MII_MODEL_BROADCOM3_BCM5719C:
|
||||
case MII_MODEL_BROADCOM3_BCM5720C:
|
||||
case MII_MODEL_BROADCOM3_BCM57765:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ifp = sc->mii_pdata->mii_ifp;
|
||||
|
||||
@@ -150,7 +150,7 @@ MODULE_DEPEND(dc, miibus, 1, 1, 1);
|
||||
/*
|
||||
* Various supported device vendors/types and their names.
|
||||
*/
|
||||
static const struct dc_type const dc_devs[] = {
|
||||
static const struct dc_type dc_devs[] = {
|
||||
{ DC_DEVID(DC_VENDORID_DEC, DC_DEVICEID_21143), 0,
|
||||
"Intel 21143 10/100BaseTX" },
|
||||
{ DC_DEVID(DC_VENDORID_DAVICOM, DC_DEVICEID_DM9009), 0,
|
||||
@@ -2650,7 +2650,7 @@ dc_newbuf(struct dc_softc *sc, int i)
|
||||
bus_dma_segment_t segs[1];
|
||||
int error, nseg;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
m->m_len = m->m_pkthdr.len = MCLBYTES;
|
||||
@@ -3387,7 +3387,7 @@ dc_encap(struct dc_softc *sc, struct mbuf **m_head)
|
||||
defragged = 0;
|
||||
if (sc->dc_flags & DC_TX_COALESCE &&
|
||||
((*m_head)->m_next != NULL || sc->dc_flags & DC_TX_ALIGN)) {
|
||||
m = m_defrag(*m_head, M_DONTWAIT);
|
||||
m = m_defrag(*m_head, M_NOWAIT);
|
||||
defragged = 1;
|
||||
} else {
|
||||
/*
|
||||
@@ -3402,7 +3402,7 @@ dc_encap(struct dc_softc *sc, struct mbuf **m_head)
|
||||
if (i > DC_TX_LIST_CNT / 4 ||
|
||||
DC_TX_LIST_CNT - i + sc->dc_cdata.dc_tx_cnt <=
|
||||
DC_TX_LIST_RSVD) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, DC_MAXFRAGS);
|
||||
m = m_collapse(*m_head, M_NOWAIT, DC_MAXFRAGS);
|
||||
defragged = 1;
|
||||
}
|
||||
}
|
||||
@@ -3419,7 +3419,7 @@ dc_encap(struct dc_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->dc_tx_mtag,
|
||||
sc->dc_cdata.dc_tx_map[idx], *m_head, segs, &nseg, 0);
|
||||
if (error == EFBIG) {
|
||||
if (defragged != 0 || (m = m_collapse(*m_head, M_DONTWAIT,
|
||||
if (defragged != 0 || (m = m_collapse(*m_head, M_NOWAIT,
|
||||
DC_MAXFRAGS)) == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
|
||||
@@ -261,7 +261,7 @@ tulip_txprobe(tulip_softc_t * const sc)
|
||||
* to verify the connectivity.
|
||||
*/
|
||||
TULIP_LOCK_ASSERT(sc);
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
MGETHDR(m, M_NOWAIT, MT_DATA);
|
||||
if (m == NULL)
|
||||
return 0;
|
||||
/*
|
||||
@@ -3521,7 +3521,7 @@ tulip_rx_intr(tulip_softc_t * const sc)
|
||||
ms->m_pkthdr.len = total_len;
|
||||
ms->m_pkthdr.rcvif = ifp;
|
||||
m0 = ms;
|
||||
ms = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
ms = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
#endif
|
||||
TULIP_UNLOCK(sc);
|
||||
CTR1(KTR_TULIP, "tulip_rx_intr: passing %p to upper layer", m0);
|
||||
@@ -3532,7 +3532,7 @@ tulip_rx_intr(tulip_softc_t * const sc)
|
||||
* If we are priming the TULIP with mbufs, then allocate
|
||||
* a new cluster for the next descriptor.
|
||||
*/
|
||||
ms = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
ms = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
|
||||
#ifndef __NO_STRICT_ALIGNMENT
|
||||
skip_input:
|
||||
@@ -3974,7 +3974,7 @@ tulip_txput(tulip_softc_t * const sc, struct mbuf *m)
|
||||
* to recopy it into one mbuf and then try again. If
|
||||
* we can't recopy it, try again later.
|
||||
*/
|
||||
m0 = m_defrag(m, M_DONTWAIT);
|
||||
m0 = m_defrag(m, M_NOWAIT);
|
||||
if (m0 == NULL) {
|
||||
sc->tulip_flags |= TULIP_WANTTXSTART;
|
||||
#if defined(TULIP_DEBUG)
|
||||
|
||||
@@ -111,7 +111,7 @@ static int tx_threshold = 64;
|
||||
*
|
||||
* See struct fxp_cb_config for the bit definitions.
|
||||
*/
|
||||
static const u_char const fxp_cb_config_template[] = {
|
||||
static const u_char fxp_cb_config_template[] = {
|
||||
0x0, 0x0, /* cb_status */
|
||||
0x0, 0x0, /* cb_command */
|
||||
0x0, 0x0, 0x0, 0x0, /* link_addr */
|
||||
@@ -155,7 +155,7 @@ static const u_char const fxp_cb_config_template[] = {
|
||||
* particular variants, but we don't currently differentiate between
|
||||
* them.
|
||||
*/
|
||||
static const struct fxp_ident const fxp_ident_table[] = {
|
||||
static const struct fxp_ident fxp_ident_table[] = {
|
||||
{ 0x1029, -1, 0, "Intel 82559 PCI/CardBus Pro/100" },
|
||||
{ 0x1030, -1, 0, "Intel 82559 Pro/100 Ethernet" },
|
||||
{ 0x1031, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" },
|
||||
@@ -452,7 +452,6 @@ fxp_attach(device_t dev)
|
||||
* Enable bus mastering.
|
||||
*/
|
||||
pci_enable_busmaster(dev);
|
||||
val = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||
|
||||
/*
|
||||
* Figure out which we should try first - memory mapping or i/o mapping?
|
||||
@@ -610,6 +609,7 @@ fxp_attach(device_t dev)
|
||||
* is a valid cacheline size (8 or 16 dwords), then tell
|
||||
* the board to turn on MWI.
|
||||
*/
|
||||
val = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||
if (val & PCIM_CMD_MWRICEN &&
|
||||
pci_read_config(dev, PCIR_CACHELNSZ, 1) != 0)
|
||||
sc->flags |= FXP_FLAG_MWI_ENABLE;
|
||||
@@ -1075,7 +1075,8 @@ fxp_suspend(device_t dev)
|
||||
pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
|
||||
sc->flags |= FXP_FLAG_WOL;
|
||||
/* Reconfigure hardware to accept magic frames. */
|
||||
fxp_init_body(sc, 1);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 0);
|
||||
}
|
||||
pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
|
||||
}
|
||||
@@ -1447,7 +1448,7 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
|
||||
|
||||
if (M_WRITABLE(*m_head) == 0) {
|
||||
/* Get a writable copy. */
|
||||
m = m_dup(*m_head, M_DONTWAIT);
|
||||
m = m_dup(*m_head, M_NOWAIT);
|
||||
m_freem(*m_head);
|
||||
if (m == NULL) {
|
||||
*m_head = NULL;
|
||||
@@ -1563,7 +1564,7 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->fxp_txmtag, txp->tx_map, *m_head,
|
||||
segs, &nseg, 0);
|
||||
if (error == EFBIG) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, sc->maxtxseg);
|
||||
m = m_collapse(*m_head, M_NOWAIT, sc->maxtxseg);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -2141,8 +2142,10 @@ fxp_tick(void *xsc)
|
||||
*/
|
||||
if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) {
|
||||
sc->rx_idle_secs = 0;
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@@ -2240,6 +2243,7 @@ fxp_watchdog(struct fxp_softc *sc)
|
||||
device_printf(sc->dev, "device timeout\n");
|
||||
sc->ifp->if_oerrors++;
|
||||
|
||||
sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 1);
|
||||
}
|
||||
|
||||
@@ -2274,6 +2278,10 @@ fxp_init_body(struct fxp_softc *sc, int setmedia)
|
||||
int i, prm;
|
||||
|
||||
FXP_LOCK_ASSERT(sc, MA_OWNED);
|
||||
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Cancel any pending I/O
|
||||
*/
|
||||
@@ -2628,7 +2636,7 @@ fxp_new_rfabuf(struct fxp_softc *sc, struct fxp_rx *rxp)
|
||||
bus_dmamap_t tmp_map;
|
||||
int error;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
|
||||
@@ -2813,6 +2821,7 @@ fxp_miibus_statchg(device_t dev)
|
||||
*/
|
||||
if (sc->revision == FXP_REV_82557)
|
||||
return;
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 0);
|
||||
}
|
||||
|
||||
@@ -2836,9 +2845,10 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if (((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) &&
|
||||
((ifp->if_flags ^ sc->if_flags) &
|
||||
(IFF_PROMISC | IFF_ALLMULTI | IFF_LINK0)) != 0)
|
||||
(IFF_PROMISC | IFF_ALLMULTI | IFF_LINK0)) != 0) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 0);
|
||||
else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
} else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
fxp_init_body(sc, 1);
|
||||
} else {
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
@@ -2851,8 +2861,10 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
FXP_LOCK(sc);
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 0);
|
||||
}
|
||||
FXP_UNLOCK(sc);
|
||||
break;
|
||||
|
||||
@@ -2942,8 +2954,10 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
~(IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM);
|
||||
reinit++;
|
||||
}
|
||||
if (reinit > 0 && ifp->if_flags & IFF_UP)
|
||||
if (reinit > 0 && (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
fxp_init_body(sc, 0);
|
||||
}
|
||||
FXP_UNLOCK(sc);
|
||||
VLAN_CAPABILITIES(ifp);
|
||||
break;
|
||||
@@ -3053,7 +3067,7 @@ static const struct ucode {
|
||||
int length;
|
||||
u_short int_delay_offset;
|
||||
u_short bundle_max_offset;
|
||||
} const ucode_table[] = {
|
||||
} ucode_table[] = {
|
||||
{ FXP_REV_82558_A4, UCODE(fxp_ucode_d101a), D101_CPUSAVER_DWORD, 0 },
|
||||
{ FXP_REV_82558_B0, UCODE(fxp_ucode_d101b0), D101_CPUSAVER_DWORD, 0 },
|
||||
{ FXP_REV_82559_A0, UCODE(fxp_ucode_d101ma),
|
||||
|
||||
@@ -389,7 +389,7 @@ For general information and support, go to the Intel support website at:
|
||||
http://support.intel.com
|
||||
|
||||
If an issue is identified, support is through email only at:
|
||||
freebsdnic@mailbox.intel.com
|
||||
freebsd@intel.com
|
||||
|
||||
|
||||
License
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,8 +32,7 @@
|
||||
******************************************************************************/
|
||||
/*$FreeBSD$*/
|
||||
|
||||
/*
|
||||
* 82571EB Gigabit Ethernet Controller
|
||||
/* 82571EB Gigabit Ethernet Controller
|
||||
* 82571EB Gigabit Ethernet Controller (Copper)
|
||||
* 82571EB Gigabit Ethernet Controller (Fiber)
|
||||
* 82571EB Dual Port Gigabit Mezzanine Adapter
|
||||
@@ -51,9 +50,6 @@
|
||||
|
||||
#include "e1000_api.h"
|
||||
|
||||
static s32 e1000_init_phy_params_82571(struct e1000_hw *hw);
|
||||
static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw);
|
||||
static s32 e1000_init_mac_params_82571(struct e1000_hw *hw);
|
||||
static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw);
|
||||
static void e1000_release_nvm_82571(struct e1000_hw *hw);
|
||||
static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset,
|
||||
@@ -78,7 +74,6 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw);
|
||||
static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
|
||||
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
|
||||
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
|
||||
static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw);
|
||||
static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw);
|
||||
static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw);
|
||||
static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw);
|
||||
@@ -99,13 +94,13 @@ static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw);
|
||||
static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_init_phy_params_82571");
|
||||
|
||||
if (hw->phy.media_type != e1000_media_type_copper) {
|
||||
phy->type = e1000_phy_none;
|
||||
goto out;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
phy->addr = 1;
|
||||
@@ -165,8 +160,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
|
||||
phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82574;
|
||||
break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
goto out;
|
||||
return -E1000_ERR_PHY;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -174,7 +168,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
|
||||
ret_val = e1000_get_phy_id_82571(hw);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("Error getting PHY ID\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* Verify phy id */
|
||||
@@ -201,7 +195,6 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -241,8 +234,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
|
||||
if (((eecd >> 15) & 0x3) == 0x3) {
|
||||
nvm->type = e1000_nvm_flash_hw;
|
||||
nvm->word_size = 2048;
|
||||
/*
|
||||
* Autonomous Flash update bit must be cleared due
|
||||
/* Autonomous Flash update bit must be cleared due
|
||||
* to Flash update issue.
|
||||
*/
|
||||
eecd &= ~E1000_EECD_AUPDEN;
|
||||
@@ -254,8 +246,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
|
||||
nvm->type = e1000_nvm_eeprom_spi;
|
||||
size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
|
||||
E1000_EECD_SIZE_EX_SHIFT);
|
||||
/*
|
||||
* Added to a constant, "size" becomes the left-shift value
|
||||
/* Added to a constant, "size" becomes the left-shift value
|
||||
* for setting word_size.
|
||||
*/
|
||||
size += NVM_WORD_SIZE_BASE_SHIFT;
|
||||
@@ -382,12 +373,11 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
||||
|
||||
/* FWSM register */
|
||||
mac->has_fwsm = TRUE;
|
||||
/*
|
||||
* ARC supported; valid only if manageability features are
|
||||
/* ARC supported; valid only if manageability features are
|
||||
* enabled.
|
||||
*/
|
||||
mac->arc_subsystem_valid = (E1000_READ_REG(hw, E1000_FWSM) &
|
||||
E1000_FWSM_MODE_MASK) ? TRUE : FALSE;
|
||||
mac->arc_subsystem_valid = !!(E1000_READ_REG(hw, E1000_FWSM) &
|
||||
E1000_FWSM_MODE_MASK);
|
||||
break;
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
@@ -405,8 +395,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that the inter-port SWSM.SMBI lock bit is clear before
|
||||
/* Ensure that the inter-port SWSM.SMBI lock bit is clear before
|
||||
* first NVM or PHY acess. This should be done for single-port
|
||||
* devices, and for one port only on dual-port devices so that
|
||||
* for those devices we can still use the SMBI lock to synchronize
|
||||
@@ -422,8 +411,9 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
||||
E1000_WRITE_REG(hw, E1000_SWSM2, swsm2 |
|
||||
E1000_SWSM2_LOCK);
|
||||
force_clear_smbi = TRUE;
|
||||
} else
|
||||
} else {
|
||||
force_clear_smbi = FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
force_clear_smbi = TRUE;
|
||||
@@ -443,10 +433,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
||||
E1000_WRITE_REG(hw, E1000_SWSM, swsm & ~E1000_SWSM_SMBI);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialze device specific counter of SMBI acquisition
|
||||
* timeouts.
|
||||
*/
|
||||
/* Initialze device specific counter of SMBI acquisition timeouts. */
|
||||
hw->dev_spec._82571.smb_counter = 0;
|
||||
|
||||
return E1000_SUCCESS;
|
||||
@@ -477,7 +464,7 @@ void e1000_init_function_pointers_82571(struct e1000_hw *hw)
|
||||
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 ret_val;
|
||||
u16 phy_id = 0;
|
||||
|
||||
DEBUGFUNC("e1000_get_phy_id_82571");
|
||||
@@ -485,8 +472,7 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82571:
|
||||
case e1000_82572:
|
||||
/*
|
||||
* The 82571 firmware may still be configuring the PHY.
|
||||
/* The 82571 firmware may still be configuring the PHY.
|
||||
* In this case, we cannot access the PHY until the
|
||||
* configuration is done. So we explicitly set the
|
||||
* PHY ID.
|
||||
@@ -494,29 +480,29 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
|
||||
phy->id = IGP01E1000_I_PHY_ID;
|
||||
break;
|
||||
case e1000_82573:
|
||||
ret_val = e1000_get_phy_id(hw);
|
||||
return e1000_get_phy_id(hw);
|
||||
break;
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
phy->id = (u32)(phy_id << 16);
|
||||
usec_delay(20);
|
||||
ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
phy->id |= (u32)(phy_id);
|
||||
phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
|
||||
break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
return -E1000_ERR_PHY;
|
||||
break;
|
||||
}
|
||||
out:
|
||||
return ret_val;
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -528,15 +514,13 @@ out:
|
||||
static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
|
||||
{
|
||||
u32 swsm;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 sw_timeout = hw->nvm.word_size + 1;
|
||||
s32 fw_timeout = hw->nvm.word_size + 1;
|
||||
s32 i = 0;
|
||||
|
||||
DEBUGFUNC("e1000_get_hw_semaphore_82571");
|
||||
|
||||
/*
|
||||
* If we have timedout 3 times on trying to acquire
|
||||
/* If we have timedout 3 times on trying to acquire
|
||||
* the inter-port SMBI semaphore, there is old code
|
||||
* operating on the other port, and it is not
|
||||
* releasing SMBI. Modify the number of times that
|
||||
@@ -576,12 +560,10 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
|
||||
/* Release semaphores */
|
||||
e1000_put_hw_semaphore_82571(hw);
|
||||
DEBUGOUT("Driver can't access the NVM\n");
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
goto out;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -613,22 +595,19 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
|
||||
static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
|
||||
{
|
||||
u32 extcnf_ctrl;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 i = 0;
|
||||
|
||||
DEBUGFUNC("e1000_get_hw_semaphore_82573");
|
||||
|
||||
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
|
||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
|
||||
do {
|
||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
|
||||
E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
|
||||
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
|
||||
|
||||
if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
|
||||
break;
|
||||
|
||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
|
||||
|
||||
msec_delay(2);
|
||||
i++;
|
||||
} while (i < MDIO_OWNERSHIP_TIMEOUT);
|
||||
@@ -637,12 +616,10 @@ static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
|
||||
/* Release semaphores */
|
||||
e1000_put_hw_semaphore_82573(hw);
|
||||
DEBUGOUT("Driver can't access the PHY\n");
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
goto out;
|
||||
return -E1000_ERR_PHY;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -712,7 +689,7 @@ static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw)
|
||||
**/
|
||||
static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, bool active)
|
||||
{
|
||||
u16 data = E1000_READ_REG(hw, E1000_POEMB);
|
||||
u32 data = E1000_READ_REG(hw, E1000_POEMB);
|
||||
|
||||
DEBUGFUNC("e1000_set_d0_lplu_state_82574");
|
||||
|
||||
@@ -738,7 +715,7 @@ static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, bool active)
|
||||
**/
|
||||
static s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, bool active)
|
||||
{
|
||||
u16 data = E1000_READ_REG(hw, E1000_POEMB);
|
||||
u32 data = E1000_READ_REG(hw, E1000_POEMB);
|
||||
|
||||
DEBUGFUNC("e1000_set_d3_lplu_state_82574");
|
||||
|
||||
@@ -771,7 +748,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
|
||||
|
||||
ret_val = e1000_get_hw_semaphore_82571(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82573:
|
||||
@@ -784,7 +761,6 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
e1000_put_hw_semaphore_82571(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -817,7 +793,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw)
|
||||
static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
u16 *data)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_write_nvm_82571");
|
||||
|
||||
@@ -857,31 +833,27 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
|
||||
|
||||
ret_val = e1000_update_nvm_checksum_generic(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* If our nvm is an EEPROM, then we're done
|
||||
/* If our nvm is an EEPROM, then we're done
|
||||
* otherwise, commit the checksum to the flash NVM.
|
||||
*/
|
||||
if (hw->nvm.type != e1000_nvm_flash_hw)
|
||||
goto out;
|
||||
return E1000_SUCCESS;
|
||||
|
||||
/* Check for pending operations. */
|
||||
for (i = 0; i < E1000_FLASH_UPDATES; i++) {
|
||||
msec_delay(1);
|
||||
if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD) == 0)
|
||||
if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == E1000_FLASH_UPDATES) {
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
goto out;
|
||||
}
|
||||
if (i == E1000_FLASH_UPDATES)
|
||||
return -E1000_ERR_NVM;
|
||||
|
||||
/* Reset the firmware if using STM opcode. */
|
||||
if ((E1000_READ_REG(hw, E1000_FLOP) & 0xFF00) == E1000_STM_OPCODE) {
|
||||
/*
|
||||
* The enabling of and the actual reset must be done
|
||||
/* The enabling of and the actual reset must be done
|
||||
* in two write cycles.
|
||||
*/
|
||||
E1000_WRITE_REG(hw, E1000_HICR, E1000_HICR_FW_RESET_ENABLE);
|
||||
@@ -895,17 +867,14 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
|
||||
|
||||
for (i = 0; i < E1000_FLASH_UPDATES; i++) {
|
||||
msec_delay(1);
|
||||
if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD) == 0)
|
||||
if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == E1000_FLASH_UPDATES) {
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
goto out;
|
||||
}
|
||||
if (i == E1000_FLASH_UPDATES)
|
||||
return -E1000_ERR_NVM;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -944,19 +913,17 @@ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
|
||||
{
|
||||
struct e1000_nvm_info *nvm = &hw->nvm;
|
||||
u32 i, eewr = 0;
|
||||
s32 ret_val = 0;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
DEBUGFUNC("e1000_write_nvm_eewr_82571");
|
||||
|
||||
/*
|
||||
* A check for invalid values: offset too large, too many words,
|
||||
/* 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;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
for (i = 0; i < words; i++) {
|
||||
@@ -975,7 +942,6 @@ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -988,7 +954,6 @@ out:
|
||||
static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw)
|
||||
{
|
||||
s32 timeout = PHY_CFG_TIMEOUT;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
DEBUGFUNC("e1000_get_cfg_done_82571");
|
||||
|
||||
@@ -1001,12 +966,10 @@ static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw)
|
||||
}
|
||||
if (!timeout) {
|
||||
DEBUGOUT("MNG configuration cycle has not completed.\n");
|
||||
ret_val = -E1000_ERR_RESET;
|
||||
goto out;
|
||||
return -E1000_ERR_RESET;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1023,39 +986,40 @@ out:
|
||||
static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 ret_val;
|
||||
u16 data;
|
||||
|
||||
DEBUGFUNC("e1000_set_d0_lplu_state_82571");
|
||||
|
||||
if (!(phy->ops.read_reg))
|
||||
goto out;
|
||||
return E1000_SUCCESS;
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
if (active) {
|
||||
data |= IGP02E1000_PM_D0_LPLU;
|
||||
ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
|
||||
data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
/* When LPLU is enabled, we should disable SmartSpeed */
|
||||
ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
|
||||
&data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
|
||||
ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
|
||||
data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
} else {
|
||||
data &= ~IGP02E1000_PM_D0_LPLU;
|
||||
ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
|
||||
data);
|
||||
/*
|
||||
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
|
||||
/* LPLU and SmartSpeed are mutually exclusive. LPLU is used
|
||||
* during Dx states where the power conservation is most
|
||||
* important. During driver activity we should enable
|
||||
* SmartSpeed, so performance is maintained.
|
||||
@@ -1065,32 +1029,31 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
|
||||
IGP01E1000_PHY_PORT_CONFIG,
|
||||
&data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
data |= IGP01E1000_PSCFR_SMART_SPEED;
|
||||
ret_val = phy->ops.write_reg(hw,
|
||||
IGP01E1000_PHY_PORT_CONFIG,
|
||||
data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
} else if (phy->smart_speed == e1000_smart_speed_off) {
|
||||
ret_val = phy->ops.read_reg(hw,
|
||||
IGP01E1000_PHY_PORT_CONFIG,
|
||||
&data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
data &= ~IGP01E1000_PSCFR_SMART_SPEED;
|
||||
ret_val = phy->ops.write_reg(hw,
|
||||
IGP01E1000_PHY_PORT_CONFIG,
|
||||
data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1101,13 +1064,12 @@ out:
|
||||
**/
|
||||
static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
|
||||
{
|
||||
u32 ctrl, ctrl_ext;
|
||||
u32 ctrl, ctrl_ext, eecd, tctl;
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_reset_hw_82571");
|
||||
|
||||
/*
|
||||
* Prevent the PCI-E bus from sticking if there is no TLP connection
|
||||
/* Prevent the PCI-E bus from sticking if there is no TLP connection
|
||||
* on the last TLP read/write transaction when MAC is reset.
|
||||
*/
|
||||
ret_val = e1000_disable_pcie_master_generic(hw);
|
||||
@@ -1118,13 +1080,14 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
|
||||
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_RCTL, 0);
|
||||
E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
|
||||
tctl = E1000_READ_REG(hw, E1000_TCTL);
|
||||
tctl &= ~E1000_TCTL_EN;
|
||||
E1000_WRITE_REG(hw, E1000_TCTL, tctl);
|
||||
E1000_WRITE_FLUSH(hw);
|
||||
|
||||
msec_delay(10);
|
||||
|
||||
/*
|
||||
* Must acquire the MDIO ownership before MAC reset.
|
||||
/* Must acquire the MDIO ownership before MAC reset.
|
||||
* Ownership defaults to firmware after a reset.
|
||||
*/
|
||||
switch (hw->mac.type) {
|
||||
@@ -1167,15 +1130,23 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
|
||||
ret_val = e1000_get_auto_rd_done_generic(hw);
|
||||
if (ret_val)
|
||||
/* We don't want to continue accessing MAC registers. */
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* Phy configuration from NVM just starts after EECD_AUTO_RD is set.
|
||||
/* Phy configuration from NVM just starts after EECD_AUTO_RD is set.
|
||||
* Need to wait for Phy configuration completion before accessing
|
||||
* NVM and Phy.
|
||||
*/
|
||||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82571:
|
||||
case e1000_82572:
|
||||
/* REQ and GNT bits need to be cleared when using AUTO_RD
|
||||
* to access the EEPROM.
|
||||
*/
|
||||
eecd = E1000_READ_REG(hw, E1000_EECD);
|
||||
eecd &= ~(E1000_EECD_REQ | E1000_EECD_GNT);
|
||||
E1000_WRITE_REG(hw, E1000_EECD, eecd);
|
||||
break;
|
||||
case e1000_82573:
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
@@ -1193,7 +1164,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
|
||||
/* Install any alternate MAC address into RAR0 */
|
||||
ret_val = e1000_check_alt_mac_addr_generic(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
e1000_set_laa_state_82571(hw, TRUE);
|
||||
}
|
||||
@@ -1202,8 +1173,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
|
||||
if (hw->phy.media_type == e1000_media_type_internal_serdes)
|
||||
hw->mac.serdes_link_state = e1000_serdes_link_down;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1225,16 +1195,15 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
|
||||
|
||||
/* Initialize identification LED */
|
||||
ret_val = mac->ops.id_led_init(hw);
|
||||
/* An error is not fatal and we should not stop init due to this */
|
||||
if (ret_val)
|
||||
DEBUGOUT("Error initializing identification LED\n");
|
||||
/* This is not fatal and we should not stop init due to this */
|
||||
|
||||
/* Disabling VLAN filtering */
|
||||
DEBUGOUT("Initializing the IEEE VLAN\n");
|
||||
mac->ops.clear_vfta(hw);
|
||||
|
||||
/* Setup the receive address. */
|
||||
/*
|
||||
/* Setup the receive address.
|
||||
* If, however, a locally administered address was assigned to the
|
||||
* 82571, we must reserve a RAR for it to work around an issue where
|
||||
* resetting one port will reload the MAC on the other port.
|
||||
@@ -1277,8 +1246,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear all of the statistics registers (clear on read). It is
|
||||
/* 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.
|
||||
@@ -1377,8 +1345,7 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
|
||||
E1000_WRITE_REG(hw, E1000_PBA_ECC, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Workaround for hardware errata.
|
||||
/* Workaround for hardware errata.
|
||||
* Ensure that DMA Dynamic Clock gating is disabled on 82571 and 82572
|
||||
*/
|
||||
if ((hw->mac.type == e1000_82571) ||
|
||||
@@ -1388,6 +1355,15 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
|
||||
E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
|
||||
}
|
||||
|
||||
/* Disable IPv6 extension header parsing because some malformed
|
||||
* IPv6 headers can hang the Rx.
|
||||
*/
|
||||
if (hw->mac.type <= e1000_82573) {
|
||||
reg = E1000_READ_REG(hw, E1000_RFCTL);
|
||||
reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS);
|
||||
E1000_WRITE_REG(hw, E1000_RFCTL, reg);
|
||||
}
|
||||
|
||||
/* PCI-Ex Control Registers */
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
@@ -1396,8 +1372,7 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
|
||||
reg |= (1 << 22);
|
||||
E1000_WRITE_REG(hw, E1000_GCR, reg);
|
||||
|
||||
/*
|
||||
* Workaround for hardware errata.
|
||||
/* Workaround for hardware errata.
|
||||
* apply workaround for hardware errata documented in errata
|
||||
* docs Fixes issue where some error prone or unreliable PCIe
|
||||
* completions are occurring, particularly with ASPM enabled.
|
||||
@@ -1435,25 +1410,25 @@ static void e1000_clear_vfta_82571(struct e1000_hw *hw)
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
if (hw->mng_cookie.vlan_id != 0) {
|
||||
/*
|
||||
* The VFTA is a 4096b bit-field, each identifying
|
||||
/* The VFTA is a 4096b bit-field, each identifying
|
||||
* a single VLAN ID. The following operations
|
||||
* determine which 32b entry (i.e. offset) into the
|
||||
* array we want to set the VLAN ID (i.e. bit) of
|
||||
* the manageability unit.
|
||||
*/
|
||||
vfta_offset = (hw->mng_cookie.vlan_id >>
|
||||
E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
|
||||
vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
|
||||
E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
|
||||
E1000_VFTA_ENTRY_SHIFT) &
|
||||
E1000_VFTA_ENTRY_MASK;
|
||||
vfta_bit_in_reg =
|
||||
1 << (hw->mng_cookie.vlan_id &
|
||||
E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
|
||||
/*
|
||||
* If the offset we want to clear is the same offset of the
|
||||
/* If the offset we want to clear is the same offset of the
|
||||
* manageability VLAN ID, then clear all bits except that of
|
||||
* the manageability unit.
|
||||
*/
|
||||
@@ -1495,8 +1470,7 @@ static s32 e1000_led_on_82574(struct e1000_hw *hw)
|
||||
|
||||
ctrl = hw->mac.ledctl_mode2;
|
||||
if (!(E1000_STATUS_LU & E1000_READ_REG(hw, E1000_STATUS))) {
|
||||
/*
|
||||
* If no link, then turn LED on by setting the invert bit
|
||||
/* If no link, then turn LED on by setting the invert bit
|
||||
* for each LED that's "on" (0x0E) in ledctl_mode2.
|
||||
*/
|
||||
for (i = 0; i < 4; i++)
|
||||
@@ -1519,30 +1493,28 @@ bool e1000_check_phy_82574(struct e1000_hw *hw)
|
||||
{
|
||||
u16 status_1kbt = 0;
|
||||
u16 receive_errors = 0;
|
||||
bool phy_hung = FALSE;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_check_phy_82574");
|
||||
|
||||
/*
|
||||
* Read PHY Receive Error counter first, if its is max - all F's then
|
||||
/* Read PHY Receive Error counter first, if its is max - all F's then
|
||||
* read the Base1000T status register If both are max then PHY is hung.
|
||||
*/
|
||||
ret_val = hw->phy.ops.read_reg(hw, E1000_RECEIVE_ERROR_COUNTER,
|
||||
&receive_errors);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return FALSE;
|
||||
if (receive_errors == E1000_RECEIVE_ERROR_MAX) {
|
||||
ret_val = hw->phy.ops.read_reg(hw, E1000_BASE1000T_STATUS,
|
||||
&status_1kbt);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return FALSE;
|
||||
if ((status_1kbt & E1000_IDLE_ERROR_COUNT_MASK) ==
|
||||
E1000_IDLE_ERROR_COUNT_MASK)
|
||||
phy_hung = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
out:
|
||||
return phy_hung;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -1560,8 +1532,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_setup_link_82571");
|
||||
|
||||
/*
|
||||
* 82573 does not have a word in the NVM to determine
|
||||
/* 82573 does not have a word in the NVM to determine
|
||||
* the default flow control setting, so we explicitly
|
||||
* set it to full.
|
||||
*/
|
||||
@@ -1608,17 +1579,14 @@ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
|
||||
ret_val = e1000_copper_link_setup_igp(hw);
|
||||
break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
return -E1000_ERR_PHY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
ret_val = e1000_setup_copper_link_generic(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return e1000_setup_copper_link_generic(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1635,8 +1603,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82571:
|
||||
case e1000_82572:
|
||||
/*
|
||||
* If SerDes loopback mode is entered, there is no form
|
||||
/* If SerDes loopback mode is entered, there is no form
|
||||
* of reset to take the adapter out of that mode. So we
|
||||
* have to explicitly take the adapter out of loopback
|
||||
* mode. This prevents drivers from twiddling their thumbs
|
||||
@@ -1685,16 +1652,17 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
||||
|
||||
ctrl = E1000_READ_REG(hw, E1000_CTRL);
|
||||
status = E1000_READ_REG(hw, E1000_STATUS);
|
||||
E1000_READ_REG(hw, E1000_RXCW);
|
||||
/* SYNCH bit and IV bit are sticky */
|
||||
usec_delay(10);
|
||||
rxcw = E1000_READ_REG(hw, E1000_RXCW);
|
||||
|
||||
if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) {
|
||||
|
||||
/* Receiver is synchronized with no invalid bits. */
|
||||
switch (mac->serdes_link_state) {
|
||||
case e1000_serdes_link_autoneg_complete:
|
||||
if (!(status & E1000_STATUS_LU)) {
|
||||
/*
|
||||
* We have lost link, retry autoneg before
|
||||
/* We have lost link, retry autoneg before
|
||||
* reporting link failure
|
||||
*/
|
||||
mac->serdes_link_state =
|
||||
@@ -1707,15 +1675,12 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
||||
break;
|
||||
|
||||
case e1000_serdes_link_forced_up:
|
||||
/*
|
||||
* If we are receiving /C/ ordered sets, re-enable
|
||||
/* If we are receiving /C/ ordered sets, re-enable
|
||||
* auto-negotiation in the TXCW register and disable
|
||||
* forced link in the Device Control register in an
|
||||
* attempt to auto-negotiate with our link partner.
|
||||
* If the partner code word is null, stop forcing
|
||||
* and restart auto negotiation.
|
||||
*/
|
||||
if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) {
|
||||
if (rxcw & E1000_RXCW_C) {
|
||||
/* Enable autoneg, and unforce link up */
|
||||
E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
|
||||
E1000_WRITE_REG(hw, E1000_CTRL,
|
||||
@@ -1731,8 +1696,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
||||
|
||||
case e1000_serdes_link_autoneg_progress:
|
||||
if (rxcw & E1000_RXCW_C) {
|
||||
/*
|
||||
* We received /C/ ordered sets, meaning the
|
||||
/* We received /C/ ordered sets, meaning the
|
||||
* link partner has autonegotiated, and we can
|
||||
* trust the Link Up (LU) status bit.
|
||||
*/
|
||||
@@ -1748,8 +1712,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
||||
DEBUGOUT("AN_PROG -> DOWN\n");
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* The link partner did not autoneg.
|
||||
/* The link partner did not autoneg.
|
||||
* Force link up and full duplex, and change
|
||||
* state to forced.
|
||||
*/
|
||||
@@ -1774,8 +1737,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
||||
|
||||
case e1000_serdes_link_down:
|
||||
default:
|
||||
/*
|
||||
* The link was down but the receiver has now gained
|
||||
/* The link was down but the receiver has now gained
|
||||
* valid sync, so lets see if we can bring the link
|
||||
* up.
|
||||
*/
|
||||
@@ -1794,17 +1756,18 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
||||
mac->serdes_link_state = e1000_serdes_link_down;
|
||||
DEBUGOUT("ANYSTATE -> DOWN\n");
|
||||
} else {
|
||||
/*
|
||||
* Check several times, if Sync and Config
|
||||
* both are consistently 1 then simply ignore
|
||||
* the Invalid bit and restart Autoneg
|
||||
/* Check several times, if SYNCH bit and CONFIG
|
||||
* bit both are consistently 1 then simply ignore
|
||||
* the IV bit and restart Autoneg
|
||||
*/
|
||||
for (i = 0; i < AN_RETRY_COUNT; i++) {
|
||||
usec_delay(10);
|
||||
rxcw = E1000_READ_REG(hw, E1000_RXCW);
|
||||
if ((rxcw & E1000_RXCW_IV) &&
|
||||
!((rxcw & E1000_RXCW_SYNCH) &&
|
||||
(rxcw & E1000_RXCW_C))) {
|
||||
if ((rxcw & E1000_RXCW_SYNCH) &&
|
||||
(rxcw & E1000_RXCW_C))
|
||||
continue;
|
||||
|
||||
if (rxcw & E1000_RXCW_IV) {
|
||||
mac->serdes_has_link = FALSE;
|
||||
mac->serdes_link_state =
|
||||
e1000_serdes_link_down;
|
||||
@@ -1845,7 +1808,7 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
|
||||
ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
switch (hw->mac.type) {
|
||||
@@ -1862,8 +1825,7 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1900,15 +1862,14 @@ void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state)
|
||||
|
||||
/* If workaround is activated... */
|
||||
if (state)
|
||||
/*
|
||||
* Hold a copy of the LAA in RAR[14] This is done so that
|
||||
/* Hold a copy of the LAA in RAR[14] This is done so that
|
||||
* between the time RAR[0] gets clobbered and the time it
|
||||
* gets fixed, the actual LAA is in one of the RARs and no
|
||||
* incoming packets directed to this port are dropped.
|
||||
* Eventually the LAA will be in RAR[0] and RAR[14].
|
||||
*/
|
||||
hw->mac.ops.rar_set(hw, hw->mac.addr,
|
||||
hw->mac.rar_entry_count - 1);
|
||||
hw->mac.rar_entry_count - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1925,25 +1886,23 @@ void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state)
|
||||
static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_nvm_info *nvm = &hw->nvm;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 ret_val;
|
||||
u16 data;
|
||||
|
||||
DEBUGFUNC("e1000_fix_nvm_checksum_82571");
|
||||
|
||||
if (nvm->type != e1000_nvm_flash_hw)
|
||||
goto out;
|
||||
return E1000_SUCCESS;
|
||||
|
||||
/*
|
||||
* Check bit 4 of word 10h. If it is 0, firmware is done updating
|
||||
/* Check bit 4 of word 10h. If it is 0, firmware is done updating
|
||||
* 10h-12h. Checksum may need to be fixed.
|
||||
*/
|
||||
ret_val = nvm->ops.read(hw, 0x10, 1, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
if (!(data & 0x10)) {
|
||||
/*
|
||||
* Read 0x23 and check bit 15. This bit is a 1
|
||||
/* Read 0x23 and check bit 15. This bit is a 1
|
||||
* when the checksum has already been fixed. If
|
||||
* the checksum is still wrong and this bit is a
|
||||
* 1, we need to return bad checksum. Otherwise,
|
||||
@@ -1952,19 +1911,20 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw)
|
||||
*/
|
||||
ret_val = nvm->ops.read(hw, 0x23, 1, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
if (!(data & 0x8000)) {
|
||||
data |= 0x8000;
|
||||
ret_val = nvm->ops.write(hw, 0x23, 1, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
ret_val = nvm->ops.update(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1974,25 +1934,21 @@ out:
|
||||
**/
|
||||
static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
DEBUGFUNC("e1000_read_mac_addr_82571");
|
||||
|
||||
if (hw->mac.type == e1000_82571) {
|
||||
/*
|
||||
* If there's an alternate MAC address place it in RAR0
|
||||
s32 ret_val;
|
||||
|
||||
/* If there's an alternate MAC address place it in RAR0
|
||||
* so that it will override the Si installed default perm
|
||||
* address.
|
||||
*/
|
||||
ret_val = e1000_check_alt_mac_addr_generic(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
ret_val = e1000_read_mac_addr_generic(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return e1000_read_mac_addr_generic(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2007,7 +1963,7 @@ static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw)
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
|
||||
if (!(phy->ops.check_reset_block))
|
||||
if (!phy->ops.check_reset_block)
|
||||
return;
|
||||
|
||||
/* If the management interface is not enabled, then power down */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -144,6 +144,8 @@ static bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw)
|
||||
break;
|
||||
case e1000_82580:
|
||||
case e1000_i350:
|
||||
case e1000_i210:
|
||||
case e1000_i211:
|
||||
reg = E1000_READ_REG(hw, E1000_MDICNFG);
|
||||
ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO);
|
||||
break;
|
||||
@@ -332,6 +334,7 @@ s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
|
||||
} else {
|
||||
nvm->type = e1000_nvm_flash_hw;
|
||||
}
|
||||
|
||||
/* Function Pointers */
|
||||
nvm->ops.acquire = e1000_acquire_nvm_82575;
|
||||
nvm->ops.release = e1000_release_nvm_82575;
|
||||
@@ -385,11 +388,16 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
|
||||
mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
|
||||
if (mac->type == e1000_82580)
|
||||
mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
|
||||
if (mac->type == e1000_i350) {
|
||||
if (mac->type == e1000_i350)
|
||||
mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
|
||||
/* Enable EEE default settings for i350 */
|
||||
|
||||
/* Enable EEE default settings for EEE supported devices */
|
||||
if (mac->type >= e1000_i350)
|
||||
dev_spec->eee_disable = FALSE;
|
||||
}
|
||||
|
||||
/* Allow a single clear of the SW semaphore on I210 and newer */
|
||||
if (mac->type >= e1000_i210)
|
||||
dev_spec->clear_semaphore_once = TRUE;
|
||||
|
||||
/* Set if part includes ASF firmware */
|
||||
mac->asf_firmware_present = TRUE;
|
||||
@@ -428,7 +436,7 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
|
||||
mac->ops.config_collision_dist = e1000_config_collision_dist_82575;
|
||||
/* multicast address update */
|
||||
mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
|
||||
if (hw->mac.type == e1000_i350) {
|
||||
if (mac->type == e1000_i350) {
|
||||
/* writing VFTA */
|
||||
mac->ops.write_vfta = e1000_write_vfta_i350;
|
||||
/* clearing VFTA */
|
||||
@@ -439,6 +447,9 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
|
||||
/* clearing VFTA */
|
||||
mac->ops.clear_vfta = e1000_clear_vfta_generic;
|
||||
}
|
||||
if (hw->mac.type >= e1000_82580)
|
||||
mac->ops.validate_mdi_setting =
|
||||
e1000_validate_mdi_setting_crossover_generic;
|
||||
/* ID LED init */
|
||||
mac->ops.id_led_init = e1000_id_led_init_generic;
|
||||
/* blink LED */
|
||||
@@ -634,6 +645,8 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw)
|
||||
break;
|
||||
case e1000_82580:
|
||||
case e1000_i350:
|
||||
case e1000_i210:
|
||||
case e1000_i211:
|
||||
mdic = E1000_READ_REG(hw, E1000_MDICNFG);
|
||||
mdic &= E1000_MDICNFG_PHY_MASK;
|
||||
phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT;
|
||||
@@ -1143,6 +1156,15 @@ static s32 e1000_check_for_link_82575(struct e1000_hw *hw)
|
||||
*/
|
||||
hw->mac.get_link_status = !hw->mac.serdes_has_link;
|
||||
|
||||
/*
|
||||
* Configure Flow Control now that Auto-Neg has completed.
|
||||
* First, we need to restore the desired flow control
|
||||
* settings because we may have had to re-autoneg with a
|
||||
* different link partner.
|
||||
*/
|
||||
ret_val = e1000_config_fc_after_link_up_generic(hw);
|
||||
if (ret_val)
|
||||
DEBUGOUT("Error configuring flow control\n");
|
||||
} else {
|
||||
ret_val = e1000_check_for_copper_link_generic(hw);
|
||||
}
|
||||
@@ -1222,6 +1244,7 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
|
||||
*duplex = FULL_DUPLEX;
|
||||
else
|
||||
*duplex = HALF_DUPLEX;
|
||||
|
||||
} else {
|
||||
mac->serdes_has_link = FALSE;
|
||||
*speed = 0;
|
||||
@@ -1397,7 +1420,8 @@ static s32 e1000_init_hw_82575(struct e1000_hw *hw)
|
||||
static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
|
||||
{
|
||||
u32 ctrl;
|
||||
s32 ret_val;
|
||||
s32 ret_val;
|
||||
u32 phpm_reg;
|
||||
|
||||
DEBUGFUNC("e1000_setup_copper_link_82575");
|
||||
|
||||
@@ -1406,6 +1430,13 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
|
||||
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
|
||||
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
|
||||
|
||||
/* Clear Go Link Disconnect bit */
|
||||
if (hw->mac.type >= e1000_82580) {
|
||||
phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
|
||||
phpm_reg &= ~E1000_82580_PM_GO_LINKD;
|
||||
E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg);
|
||||
}
|
||||
|
||||
ret_val = e1000_setup_serdes_link_82575(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
@@ -1423,12 +1454,17 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
|
||||
switch (hw->phy.type) {
|
||||
case e1000_phy_i210:
|
||||
case e1000_phy_m88:
|
||||
if (hw->phy.id == I347AT4_E_PHY_ID ||
|
||||
hw->phy.id == M88E1112_E_PHY_ID ||
|
||||
hw->phy.id == M88E1340M_E_PHY_ID)
|
||||
switch (hw->phy.id) {
|
||||
case I347AT4_E_PHY_ID:
|
||||
case M88E1112_E_PHY_ID:
|
||||
case M88E1340M_E_PHY_ID:
|
||||
case I210_I_PHY_ID:
|
||||
ret_val = e1000_copper_link_setup_m88_gen2(hw);
|
||||
else
|
||||
break;
|
||||
default:
|
||||
ret_val = e1000_copper_link_setup_m88(hw);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case e1000_phy_igp_3:
|
||||
ret_val = e1000_copper_link_setup_igp(hw);
|
||||
@@ -1460,7 +1496,7 @@ out:
|
||||
**/
|
||||
static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
|
||||
{
|
||||
u32 ctrl_ext, ctrl_reg, reg;
|
||||
u32 ctrl_ext, ctrl_reg, reg, anadv_reg;
|
||||
bool pcs_autoneg;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 data;
|
||||
@@ -1544,26 +1580,47 @@ static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
|
||||
reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
|
||||
E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
|
||||
|
||||
/*
|
||||
* We force flow control to prevent the CTRL register values from being
|
||||
* overwritten by the autonegotiated flow control values
|
||||
*/
|
||||
reg |= E1000_PCS_LCTL_FORCE_FCTRL;
|
||||
|
||||
if (pcs_autoneg) {
|
||||
/* Set PCS register for autoneg */
|
||||
reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
|
||||
E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
|
||||
|
||||
/* Disable force flow control for autoneg */
|
||||
reg &= ~E1000_PCS_LCTL_FORCE_FCTRL;
|
||||
|
||||
/* Configure flow control advertisement for autoneg */
|
||||
anadv_reg = E1000_READ_REG(hw, E1000_PCS_ANADV);
|
||||
anadv_reg &= ~(E1000_TXCW_ASM_DIR | E1000_TXCW_PAUSE);
|
||||
|
||||
switch (hw->fc.requested_mode) {
|
||||
case e1000_fc_full:
|
||||
case e1000_fc_rx_pause:
|
||||
anadv_reg |= E1000_TXCW_ASM_DIR;
|
||||
anadv_reg |= E1000_TXCW_PAUSE;
|
||||
break;
|
||||
case e1000_fc_tx_pause:
|
||||
anadv_reg |= E1000_TXCW_ASM_DIR;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_PCS_ANADV, anadv_reg);
|
||||
|
||||
DEBUGOUT1("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg);
|
||||
} else {
|
||||
/* Set PCS register for forced link */
|
||||
reg |= E1000_PCS_LCTL_FSD; /* Force Speed */
|
||||
|
||||
/* Force flow control for forced link */
|
||||
reg |= E1000_PCS_LCTL_FORCE_FCTRL;
|
||||
|
||||
DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg);
|
||||
}
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
|
||||
|
||||
if (!e1000_sgmii_active_82575(hw))
|
||||
if (!pcs_autoneg && !e1000_sgmii_active_82575(hw))
|
||||
e1000_force_mac_fc_generic(hw);
|
||||
|
||||
return ret_val;
|
||||
@@ -1582,137 +1639,70 @@ static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
|
||||
**/
|
||||
static s32 e1000_get_media_type_82575(struct e1000_hw *hw)
|
||||
{
|
||||
u32 lan_id = 0;
|
||||
s32 ret_val = E1000_ERR_CONFIG;
|
||||
struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u32 ctrl_ext = 0;
|
||||
u32 current_link_mode = 0;
|
||||
u16 init_ctrl_wd_3 = 0;
|
||||
u8 init_ctrl_wd_3_offset = 0;
|
||||
u8 init_ctrl_wd_3_bit_offset = 0;
|
||||
u32 link_mode = 0;
|
||||
|
||||
/* Set internal phy as default */
|
||||
dev_spec->sgmii_active = FALSE;
|
||||
dev_spec->module_plugged = FALSE;
|
||||
|
||||
/*
|
||||
* Check if NVM access method is attached already.
|
||||
* If it is then Init Control Word #3 is considered
|
||||
* otherwise runtime CSR register content is taken.
|
||||
*/
|
||||
|
||||
/* Get CSR setting */
|
||||
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
|
||||
|
||||
/* Get link mode setting */
|
||||
if ((hw->nvm.ops.read) && (hw->nvm.ops.read != e1000_null_read_nvm)) {
|
||||
/* Take link mode from EEPROM */
|
||||
|
||||
/*
|
||||
* Get LAN port ID to derive its
|
||||
* adequate Init Control Word #3
|
||||
*/
|
||||
lan_id = ((E1000_READ_REG(hw, E1000_STATUS) &
|
||||
E1000_STATUS_LAN_ID_MASK) >> E1000_STATUS_LAN_ID_OFFSET);
|
||||
/*
|
||||
* Derive Init Control Word #3 offset
|
||||
* and mask to pick up link mode setting.
|
||||
*/
|
||||
if (hw->mac.type < e1000_82580) {
|
||||
init_ctrl_wd_3_offset = lan_id ?
|
||||
NVM_INIT_CONTROL3_PORT_A : NVM_INIT_CONTROL3_PORT_B;
|
||||
init_ctrl_wd_3_bit_offset = NVM_WORD24_LNK_MODE_OFFSET;
|
||||
} else {
|
||||
init_ctrl_wd_3_offset =
|
||||
NVM_82580_LAN_FUNC_OFFSET(lan_id) +
|
||||
NVM_INIT_CONTROL3_PORT_A;
|
||||
init_ctrl_wd_3_bit_offset =
|
||||
NVM_WORD24_82580_LNK_MODE_OFFSET;
|
||||
}
|
||||
/* Read Init Control Word #3*/
|
||||
hw->nvm.ops.read(hw, init_ctrl_wd_3_offset, 1, &init_ctrl_wd_3);
|
||||
|
||||
/*
|
||||
* Align link mode bits to
|
||||
* their CTRL_EXT location.
|
||||
*/
|
||||
current_link_mode = init_ctrl_wd_3;
|
||||
current_link_mode <<= (E1000_CTRL_EXT_LINK_MODE_OFFSET -
|
||||
init_ctrl_wd_3_bit_offset);
|
||||
current_link_mode &= E1000_CTRL_EXT_LINK_MODE_MASK;
|
||||
|
||||
/*
|
||||
* Switch to CSR for all but internal PHY.
|
||||
*/
|
||||
if (current_link_mode != E1000_CTRL_EXT_LINK_MODE_GMII)
|
||||
/* Take link mode from CSR */
|
||||
current_link_mode = ctrl_ext &
|
||||
E1000_CTRL_EXT_LINK_MODE_MASK;
|
||||
} else {
|
||||
/* Take link mode from CSR */
|
||||
current_link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK;
|
||||
}
|
||||
|
||||
switch (current_link_mode) {
|
||||
/* extract link mode setting */
|
||||
link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK;
|
||||
|
||||
switch (link_mode) {
|
||||
case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
|
||||
hw->phy.media_type = e1000_media_type_internal_serdes;
|
||||
current_link_mode = E1000_CTRL_EXT_LINK_MODE_1000BASE_KX;
|
||||
break;
|
||||
case E1000_CTRL_EXT_LINK_MODE_GMII:
|
||||
hw->phy.media_type = e1000_media_type_copper;
|
||||
current_link_mode = E1000_CTRL_EXT_LINK_MODE_GMII;
|
||||
break;
|
||||
case E1000_CTRL_EXT_LINK_MODE_SGMII:
|
||||
case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
|
||||
/* Get phy control interface type set (MDIO vs. I2C)*/
|
||||
if (e1000_sgmii_uses_mdio_82575(hw)) {
|
||||
hw->phy.media_type = e1000_media_type_copper;
|
||||
dev_spec->sgmii_active = TRUE;
|
||||
current_link_mode = E1000_CTRL_EXT_LINK_MODE_SGMII;
|
||||
} else {
|
||||
ret_val = e1000_set_sfp_media_type_82575(hw);
|
||||
if (ret_val != E1000_SUCCESS)
|
||||
goto out;
|
||||
if (hw->phy.media_type ==
|
||||
e1000_media_type_internal_serdes) {
|
||||
current_link_mode =
|
||||
E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
|
||||
} else if (hw->phy.media_type ==
|
||||
e1000_media_type_copper) {
|
||||
current_link_mode =
|
||||
E1000_CTRL_EXT_LINK_MODE_SGMII;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEBUGOUT("Link mode mask doesn't fit bit field size\n");
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Do not change current link mode setting
|
||||
* if media type is fibre or has not been
|
||||
* recognized.
|
||||
*/
|
||||
if ((hw->phy.media_type != e1000_media_type_unknown) &&
|
||||
(hw->phy.media_type != e1000_media_type_fiber)) {
|
||||
/* Update link mode */
|
||||
ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
|
||||
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext |
|
||||
current_link_mode);
|
||||
}
|
||||
|
||||
ret_val = E1000_SUCCESS;
|
||||
out:
|
||||
/*
|
||||
* If media type was not identified then return media type
|
||||
* defined by the CTRL_EXT settings.
|
||||
*/
|
||||
if (hw->phy.media_type == e1000_media_type_unknown) {
|
||||
if (current_link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII)
|
||||
hw->phy.media_type = e1000_media_type_copper;
|
||||
else
|
||||
/* fall through for I2C based SGMII */
|
||||
case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
|
||||
/* read media type from SFP EEPROM */
|
||||
ret_val = e1000_set_sfp_media_type_82575(hw);
|
||||
if ((ret_val != E1000_SUCCESS) ||
|
||||
(hw->phy.media_type == e1000_media_type_unknown)) {
|
||||
/*
|
||||
* If media type was not identified then return media
|
||||
* type defined by the CTRL_EXT settings.
|
||||
*/
|
||||
hw->phy.media_type = e1000_media_type_internal_serdes;
|
||||
|
||||
if (link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII) {
|
||||
hw->phy.media_type = e1000_media_type_copper;
|
||||
dev_spec->sgmii_active = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* do not change link mode for 100BaseFX */
|
||||
if (dev_spec->eth_flags.e100_base_fx)
|
||||
break;
|
||||
|
||||
/* change current link mode setting */
|
||||
ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
|
||||
|
||||
if (hw->phy.media_type == e1000_media_type_copper)
|
||||
ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII;
|
||||
else
|
||||
ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
@@ -1730,40 +1720,52 @@ static s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw)
|
||||
s32 ret_val = E1000_ERR_CONFIG;
|
||||
u32 ctrl_ext = 0;
|
||||
struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
|
||||
struct sfp_e1000_flags eth_flags = {0};
|
||||
struct sfp_e1000_flags *eth_flags = &dev_spec->eth_flags;
|
||||
u8 tranceiver_type = 0;
|
||||
s32 timeout = 3;
|
||||
|
||||
/* Turn I2C interface ON */
|
||||
/* Turn I2C interface ON and power on sfp cage */
|
||||
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
|
||||
ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
|
||||
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA);
|
||||
|
||||
E1000_WRITE_FLUSH(hw);
|
||||
|
||||
/* Read SFP module data */
|
||||
ret_val = e1000_read_sfp_data_byte(hw,
|
||||
while (timeout) {
|
||||
ret_val = e1000_read_sfp_data_byte(hw,
|
||||
E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET),
|
||||
&tranceiver_type);
|
||||
if (ret_val == E1000_SUCCESS)
|
||||
break;
|
||||
msec_delay(100);
|
||||
timeout--;
|
||||
}
|
||||
if (ret_val != E1000_SUCCESS)
|
||||
goto out;
|
||||
|
||||
ret_val = e1000_read_sfp_data_byte(hw,
|
||||
E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET),
|
||||
(u8 *)ð_flags);
|
||||
(u8 *)eth_flags);
|
||||
if (ret_val != E1000_SUCCESS)
|
||||
goto out;
|
||||
/*
|
||||
* Check if there is some SFP
|
||||
* module plugged and powered
|
||||
*/
|
||||
|
||||
/* Check if there is some SFP module plugged and powered */
|
||||
if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) ||
|
||||
(tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) {
|
||||
dev_spec->module_plugged = TRUE;
|
||||
if (eth_flags.e1000_base_lx || eth_flags.e1000_base_sx) {
|
||||
if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) {
|
||||
hw->phy.media_type = e1000_media_type_internal_serdes;
|
||||
} else if (eth_flags.e1000_base_t) {
|
||||
} else if (eth_flags->e100_base_fx) {
|
||||
dev_spec->sgmii_active = TRUE;
|
||||
hw->phy.media_type = e1000_media_type_internal_serdes;
|
||||
} else if (eth_flags->e1000_base_t) {
|
||||
dev_spec->sgmii_active = TRUE;
|
||||
hw->phy.media_type = e1000_media_type_copper;
|
||||
} else {
|
||||
hw->phy.media_type = e1000_media_type_unknown;
|
||||
DEBUGOUT("PHY module has not been recognized\n");
|
||||
goto out;
|
||||
hw->phy.media_type = e1000_media_type_unknown;
|
||||
DEBUGOUT("PHY module has not been recognized\n");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
hw->phy.media_type = e1000_media_type_unknown;
|
||||
@@ -2334,6 +2336,10 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
|
||||
|
||||
hw->dev_spec._82575.global_device_reset = FALSE;
|
||||
|
||||
/* 82580 does not reliably do global_device_reset due to hw errata */
|
||||
if (hw->mac.type == e1000_82580)
|
||||
global_device_reset = FALSE;
|
||||
|
||||
/* Get current control state. */
|
||||
ctrl = E1000_READ_REG(hw, E1000_CTRL);
|
||||
|
||||
@@ -2660,10 +2666,15 @@ s32 e1000_set_eee_i350(struct e1000_hw *hw)
|
||||
|
||||
/* enable or disable per user setting */
|
||||
if (!(hw->dev_spec._82575.eee_disable)) {
|
||||
u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU);
|
||||
|
||||
ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
|
||||
eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
|
||||
E1000_EEER_LPI_FC);
|
||||
|
||||
/* This bit should not be set in normal operation. */
|
||||
if (eee_su & E1000_EEE_SU_LPI_CLK_STP)
|
||||
DEBUGOUT("LPI Clock Stop Bit should not be set!\n");
|
||||
} else {
|
||||
ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
|
||||
eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
|
||||
@@ -3275,3 +3286,4 @@ void e1000_i2c_bus_clear(struct e1000_hw *hw)
|
||||
e1000_i2c_stop(hw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -360,10 +360,13 @@ struct e1000_adv_tx_context_desc {
|
||||
#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 ena */
|
||||
#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload ena */
|
||||
#define E1000_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx Desc Relax Order */
|
||||
|
||||
#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
|
||||
#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
|
||||
#define E1000_DCA_TXCTRL_DESC_RRO_EN (1 << 9) /* Tx rd Desc Relax Order */
|
||||
#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
|
||||
#define E1000_DCA_TXCTRL_DATA_RRO_EN (1 << 13) /* Tx rd data Relax Order */
|
||||
|
||||
#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
|
||||
#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -289,6 +289,12 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
|
||||
case E1000_DEV_ID_PCH2_LV_V:
|
||||
mac->type = e1000_pch2lan;
|
||||
break;
|
||||
case E1000_DEV_ID_PCH_LPT_I217_LM:
|
||||
case E1000_DEV_ID_PCH_LPT_I217_V:
|
||||
case E1000_DEV_ID_PCH_LPTLP_I218_LM:
|
||||
case E1000_DEV_ID_PCH_LPTLP_I218_V:
|
||||
mac->type = e1000_pch_lpt;
|
||||
break;
|
||||
case E1000_DEV_ID_82575EB_COPPER:
|
||||
case E1000_DEV_ID_82575EB_FIBER_SERDES:
|
||||
case E1000_DEV_ID_82575GB_QUAD_COPPER:
|
||||
@@ -323,6 +329,9 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
|
||||
case E1000_DEV_ID_I350_DA4:
|
||||
mac->type = e1000_i350;
|
||||
break;
|
||||
#if defined(QV_RELEASE) && defined(SPRINGVILLE_FLASHLESS_HW)
|
||||
case E1000_DEV_ID_I210_NVMLESS:
|
||||
#endif /* QV_RELEASE && SPRINGVILLE_FLASHLESS_HW */
|
||||
case E1000_DEV_ID_I210_COPPER:
|
||||
case E1000_DEV_ID_I210_COPPER_OEM1:
|
||||
case E1000_DEV_ID_I210_COPPER_IT:
|
||||
@@ -332,14 +341,17 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
|
||||
mac->type = e1000_i210;
|
||||
break;
|
||||
case E1000_DEV_ID_I211_COPPER:
|
||||
mac->type = e1000_i211;
|
||||
break;
|
||||
mac->type = e1000_i211;
|
||||
break;
|
||||
case E1000_DEV_ID_82576_VF:
|
||||
case E1000_DEV_ID_82576_VF_HV:
|
||||
mac->type = e1000_vfadapt;
|
||||
break;
|
||||
case E1000_DEV_ID_I350_VF:
|
||||
case E1000_DEV_ID_I350_VF_HV:
|
||||
mac->type = e1000_vfadapt_i350;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Should never have loaded on this device */
|
||||
ret_val = -E1000_ERR_MAC_INIT;
|
||||
@@ -428,6 +440,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
|
||||
case e1000_ich10lan:
|
||||
case e1000_pchlan:
|
||||
case e1000_pch2lan:
|
||||
case e1000_pch_lpt:
|
||||
e1000_init_function_pointers_ich8lan(hw);
|
||||
break;
|
||||
case e1000_82575:
|
||||
@@ -873,11 +886,7 @@ bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
|
||||
s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
|
||||
u16 offset, u8 *sum)
|
||||
{
|
||||
if (hw->mac.ops.mng_host_if_write)
|
||||
return hw->mac.ops.mng_host_if_write(hw, buffer, length,
|
||||
offset, sum);
|
||||
|
||||
return E1000_NOT_IMPLEMENTED;
|
||||
return e1000_mng_host_if_write_generic(hw, buffer, length, offset, sum);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -890,10 +899,7 @@ s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
|
||||
s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
|
||||
struct e1000_host_mng_command_header *hdr)
|
||||
{
|
||||
if (hw->mac.ops.mng_write_cmd_header)
|
||||
return hw->mac.ops.mng_write_cmd_header(hw, hdr);
|
||||
|
||||
return E1000_NOT_IMPLEMENTED;
|
||||
return e1000_mng_write_cmd_header_generic(hw, hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -908,23 +914,20 @@ s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
|
||||
**/
|
||||
s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
|
||||
{
|
||||
if (hw->mac.ops.mng_enable_host_if)
|
||||
return hw->mac.ops.mng_enable_host_if(hw);
|
||||
|
||||
return E1000_NOT_IMPLEMENTED;
|
||||
return e1000_mng_enable_host_if_generic(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_wait_autoneg - Waits for autonegotiation completion
|
||||
* e1000_set_obff_timer - Set Optimized Buffer Flush/Fill timer
|
||||
* @hw: pointer to the HW structure
|
||||
* @itr: u32 indicating itr value
|
||||
*
|
||||
* Waits for autoneg to complete. Currently no func pointer exists and all
|
||||
* implementations are handled in the generic version of this function.
|
||||
* Set the OBFF timer based on the given interrupt rate.
|
||||
**/
|
||||
s32 e1000_wait_autoneg(struct e1000_hw *hw)
|
||||
s32 e1000_set_obff_timer(struct e1000_hw *hw, u32 itr)
|
||||
{
|
||||
if (hw->mac.ops.wait_autoneg)
|
||||
return hw->mac.ops.wait_autoneg(hw);
|
||||
if (hw->mac.ops.set_obff_timer)
|
||||
return hw->mac.ops.set_obff_timer(hw, itr);
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -51,6 +51,7 @@ extern void e1000_power_up_fiber_serdes_link(struct e1000_hw *hw);
|
||||
extern void e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw);
|
||||
extern void e1000_init_function_pointers_i210(struct e1000_hw *hw);
|
||||
|
||||
s32 e1000_set_obff_timer(struct e1000_hw *hw, u32 itr);
|
||||
s32 e1000_set_mac_type(struct e1000_hw *hw);
|
||||
s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device);
|
||||
s32 e1000_init_mac_params(struct e1000_hw *hw);
|
||||
@@ -105,7 +106,6 @@ 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, bool active);
|
||||
s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
|
||||
bool e1000_check_mng_mode(struct e1000_hw *hw);
|
||||
@@ -162,4 +162,6 @@ u32 e1000_translate_register_82542(u32 reg);
|
||||
(((length) > min_frame_size) && \
|
||||
((length) <= (max_frame_size + VLAN_TAG_SIZE + 1)))))
|
||||
|
||||
#endif
|
||||
#define E1000_MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define E1000_DIVIDE_ROUND_UP(a, b) (((a) + (b) - 1) / (b)) /* ceil(a/b) */
|
||||
#endif /* _E1000_API_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -123,13 +123,16 @@ struct e1000_hw;
|
||||
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
|
||||
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
|
||||
#define E1000_DEV_ID_ICH10_D_BM_V 0x1525
|
||||
|
||||
#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA
|
||||
#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB
|
||||
#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF
|
||||
#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0
|
||||
#define E1000_DEV_ID_PCH2_LV_LM 0x1502
|
||||
#define E1000_DEV_ID_PCH2_LV_V 0x1503
|
||||
#define E1000_DEV_ID_PCH_LPT_I217_LM 0x153A
|
||||
#define E1000_DEV_ID_PCH_LPT_I217_V 0x153B
|
||||
#define E1000_DEV_ID_PCH_LPTLP_I218_LM 0x155A
|
||||
#define E1000_DEV_ID_PCH_LPTLP_I218_V 0x1559
|
||||
#define E1000_DEV_ID_82576 0x10C9
|
||||
#define E1000_DEV_ID_82576_FIBER 0x10E6
|
||||
#define E1000_DEV_ID_82576_SERDES 0x10E7
|
||||
@@ -139,7 +142,9 @@ struct e1000_hw;
|
||||
#define E1000_DEV_ID_82576_NS_SERDES 0x1518
|
||||
#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
|
||||
#define E1000_DEV_ID_82576_VF 0x10CA
|
||||
#define E1000_DEV_ID_82576_VF_HV 0x152D
|
||||
#define E1000_DEV_ID_I350_VF 0x1520
|
||||
#define E1000_DEV_ID_I350_VF_HV 0x152F
|
||||
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
|
||||
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
|
||||
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
|
||||
@@ -165,6 +170,7 @@ struct e1000_hw;
|
||||
#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A
|
||||
#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C
|
||||
#define E1000_DEV_ID_DH89XXCC_SFP 0x0440
|
||||
|
||||
#define E1000_REVISION_0 0
|
||||
#define E1000_REVISION_1 1
|
||||
#define E1000_REVISION_2 2
|
||||
@@ -206,6 +212,7 @@ enum e1000_mac_type {
|
||||
e1000_ich10lan,
|
||||
e1000_pchlan,
|
||||
e1000_pch2lan,
|
||||
e1000_pch_lpt,
|
||||
e1000_82575,
|
||||
e1000_82576,
|
||||
e1000_82580,
|
||||
@@ -255,6 +262,7 @@ enum e1000_phy_type {
|
||||
e1000_phy_82578,
|
||||
e1000_phy_82577,
|
||||
e1000_phy_82579,
|
||||
e1000_phy_i217,
|
||||
e1000_phy_82580,
|
||||
e1000_phy_vf,
|
||||
e1000_phy_i210,
|
||||
@@ -651,13 +659,13 @@ struct e1000_host_mng_command_info {
|
||||
#include "e1000_manage.h"
|
||||
#include "e1000_mbx.h"
|
||||
|
||||
/* Function pointers for the MAC. */
|
||||
struct e1000_mac_operations {
|
||||
/* Function pointers for the MAC. */
|
||||
s32 (*init_params)(struct e1000_hw *);
|
||||
s32 (*id_led_init)(struct e1000_hw *);
|
||||
s32 (*blink_led)(struct e1000_hw *);
|
||||
bool (*check_mng_mode)(struct e1000_hw *);
|
||||
s32 (*check_for_link)(struct e1000_hw *);
|
||||
bool (*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 *);
|
||||
@@ -679,17 +687,12 @@ struct e1000_mac_operations {
|
||||
void (*rar_set)(struct e1000_hw *, u8*, u32);
|
||||
s32 (*read_mac_addr)(struct e1000_hw *);
|
||||
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 *);
|
||||
s32 (*set_obff_timer)(struct e1000_hw *, u32);
|
||||
s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
|
||||
void (*release_swfw_sync)(struct e1000_hw *, u16);
|
||||
};
|
||||
|
||||
/*
|
||||
* When to use various PHY register access functions:
|
||||
/* When to use various PHY register access functions:
|
||||
*
|
||||
* Func Caller
|
||||
* Function Does Does When to use
|
||||
@@ -731,6 +734,7 @@ struct e1000_phy_operations {
|
||||
s32 (*write_i2c_byte)(struct e1000_hw *, u8, u8, u8);
|
||||
};
|
||||
|
||||
/* Function pointers for the NVM. */
|
||||
struct e1000_nvm_operations {
|
||||
s32 (*init_params)(struct e1000_hw *);
|
||||
s32 (*acquire)(struct e1000_hw *);
|
||||
@@ -785,6 +789,7 @@ struct e1000_mac_info {
|
||||
enum e1000_serdes_link_state serdes_link_state;
|
||||
bool serdes_has_link;
|
||||
bool tx_pkt_filtering;
|
||||
u32 max_frame_size;
|
||||
};
|
||||
|
||||
struct e1000_phy_info {
|
||||
@@ -915,7 +920,7 @@ struct e1000_shadow_ram {
|
||||
bool modified;
|
||||
};
|
||||
|
||||
#define E1000_SHADOW_RAM_WORDS 2048
|
||||
#define E1000_SHADOW_RAM_WORDS 2048
|
||||
|
||||
struct e1000_dev_spec_ich8lan {
|
||||
bool kmrn_lock_loss_workaround_enabled;
|
||||
@@ -924,6 +929,7 @@ struct e1000_dev_spec_ich8lan {
|
||||
E1000_MUTEX swflag_mutex;
|
||||
bool nvm_k1_enabled;
|
||||
bool eee_disable;
|
||||
u16 eee_lp_ability;
|
||||
};
|
||||
|
||||
struct e1000_dev_spec_82575 {
|
||||
@@ -931,7 +937,9 @@ struct e1000_dev_spec_82575 {
|
||||
bool global_device_reset;
|
||||
bool eee_disable;
|
||||
bool module_plugged;
|
||||
bool clear_semaphore_once;
|
||||
u32 mtu;
|
||||
struct sfp_e1000_flags eth_flags;
|
||||
};
|
||||
|
||||
struct e1000_dev_spec_vf {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -38,7 +38,6 @@
|
||||
static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw);
|
||||
static void e1000_release_nvm_i210(struct e1000_hw *hw);
|
||||
static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw);
|
||||
static void e1000_put_hw_semaphore_i210(struct e1000_hw *hw);
|
||||
static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
u16 *data);
|
||||
static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw);
|
||||
@@ -105,13 +104,14 @@ s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
|
||||
}
|
||||
|
||||
swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
|
||||
if (!(swfw_sync & fwmask))
|
||||
if (!(swfw_sync & (fwmask | swmask)))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Firmware currently using resource (fwmask)
|
||||
* or other software thread using resource (swmask)
|
||||
*/
|
||||
e1000_put_hw_semaphore_i210(hw);
|
||||
e1000_put_hw_semaphore_generic(hw);
|
||||
msec_delay_irq(5);
|
||||
i++;
|
||||
}
|
||||
@@ -125,7 +125,7 @@ s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
|
||||
swfw_sync |= swmask;
|
||||
E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
|
||||
|
||||
e1000_put_hw_semaphore_i210(hw);
|
||||
e1000_put_hw_semaphore_generic(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
@@ -152,7 +152,7 @@ void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
|
||||
swfw_sync &= ~mask;
|
||||
E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
|
||||
|
||||
e1000_put_hw_semaphore_i210(hw);
|
||||
e1000_put_hw_semaphore_generic(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,12 +164,45 @@ void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
|
||||
static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw)
|
||||
{
|
||||
u32 swsm;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 timeout = hw->nvm.word_size + 1;
|
||||
s32 i = 0;
|
||||
|
||||
DEBUGFUNC("e1000_get_hw_semaphore_i210");
|
||||
|
||||
/* Get the SW semaphore */
|
||||
while (i < timeout) {
|
||||
swsm = E1000_READ_REG(hw, E1000_SWSM);
|
||||
if (!(swsm & E1000_SWSM_SMBI))
|
||||
break;
|
||||
|
||||
usec_delay(50);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == timeout) {
|
||||
/*
|
||||
* In rare circumstances, the driver may not have released the
|
||||
* SW semaphore. Clear the semaphore once before giving up.
|
||||
*/
|
||||
if (hw->dev_spec._82575.clear_semaphore_once) {
|
||||
hw->dev_spec._82575.clear_semaphore_once = FALSE;
|
||||
e1000_put_hw_semaphore_generic(hw);
|
||||
for (i = 0; i < timeout; i++) {
|
||||
swsm = E1000_READ_REG(hw, E1000_SWSM);
|
||||
if (!(swsm & E1000_SWSM_SMBI))
|
||||
break;
|
||||
|
||||
usec_delay(50);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we do not have the semaphore here, we have to give up. */
|
||||
if (i == timeout) {
|
||||
DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the FW semaphore. */
|
||||
for (i = 0; i < timeout; i++) {
|
||||
swsm = E1000_READ_REG(hw, E1000_SWSM);
|
||||
@@ -186,31 +219,10 @@ static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw)
|
||||
/* Release semaphores */
|
||||
e1000_put_hw_semaphore_generic(hw);
|
||||
DEBUGOUT("Driver can't access the NVM\n");
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
goto out;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_put_hw_semaphore_i210 - Release hardware semaphore
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Release hardware semaphore used to access the PHY or NVM
|
||||
**/
|
||||
static void e1000_put_hw_semaphore_i210(struct e1000_hw *hw)
|
||||
{
|
||||
u32 swsm;
|
||||
|
||||
DEBUGFUNC("e1000_put_hw_semaphore_i210");
|
||||
|
||||
swsm = E1000_READ_REG(hw, E1000_SWSM);
|
||||
|
||||
swsm &= ~E1000_SWSM_SWESMBI;
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_SWSM, swsm);
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,8 +376,8 @@ out:
|
||||
*
|
||||
* Wrapper function to return data formerly found in the NVM.
|
||||
**/
|
||||
static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
u16 *data)
|
||||
static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset,
|
||||
u16 words, u16 *data)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
@@ -380,15 +392,40 @@ static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
if (ret_val != E1000_SUCCESS)
|
||||
DEBUGOUT("MAC Addr not found in iNVM\n");
|
||||
break;
|
||||
case NVM_ID_LED_SETTINGS:
|
||||
case NVM_INIT_CTRL_2:
|
||||
case NVM_INIT_CTRL_4:
|
||||
case NVM_LED_1_CFG:
|
||||
case NVM_LED_0_2_CFG:
|
||||
e1000_read_invm_i211(hw, (u8)offset, data);
|
||||
ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
|
||||
if (ret_val != E1000_SUCCESS) {
|
||||
*data = NVM_INIT_CTRL_2_DEFAULT_I211;
|
||||
ret_val = E1000_SUCCESS;
|
||||
}
|
||||
break;
|
||||
case NVM_COMPAT:
|
||||
*data = ID_LED_DEFAULT_I210;
|
||||
case NVM_INIT_CTRL_4:
|
||||
ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
|
||||
if (ret_val != E1000_SUCCESS) {
|
||||
*data = NVM_INIT_CTRL_4_DEFAULT_I211;
|
||||
ret_val = E1000_SUCCESS;
|
||||
}
|
||||
break;
|
||||
case NVM_LED_1_CFG:
|
||||
ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
|
||||
if (ret_val != E1000_SUCCESS) {
|
||||
*data = NVM_LED_1_CFG_DEFAULT_I211;
|
||||
ret_val = E1000_SUCCESS;
|
||||
}
|
||||
break;
|
||||
case NVM_LED_0_2_CFG:
|
||||
ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
|
||||
if (ret_val != E1000_SUCCESS) {
|
||||
*data = NVM_LED_0_2_CFG_DEFAULT_I211;
|
||||
ret_val = E1000_SUCCESS;
|
||||
}
|
||||
break;
|
||||
case NVM_ID_LED_SETTINGS:
|
||||
ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
|
||||
if (ret_val != E1000_SUCCESS) {
|
||||
*data = ID_LED_RESERVED_FFFF;
|
||||
ret_val = E1000_SUCCESS;
|
||||
}
|
||||
break;
|
||||
case NVM_SUB_DEV_ID:
|
||||
*data = hw->subsystem_device_id;
|
||||
@@ -554,26 +591,6 @@ out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_flash_presence_i210 - Check if flash device is detected.
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
**/
|
||||
static bool e1000_get_flash_presence_i210(struct e1000_hw *hw)
|
||||
{
|
||||
u32 eec = 0;
|
||||
bool ret_val = FALSE;
|
||||
|
||||
DEBUGFUNC("e1000_get_flash_presence_i210");
|
||||
|
||||
eec = E1000_READ_REG(hw, E1000_EECD);
|
||||
|
||||
if (eec & E1000_EECD_FLASH_DETECTED_I210)
|
||||
ret_val = TRUE;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_update_flash_i210 - Commit EEPROM to the flash
|
||||
* @hw: pointer to the HW structure
|
||||
@@ -690,10 +707,7 @@ void e1000_init_function_pointers_i210(struct e1000_hw *hw)
|
||||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_i210:
|
||||
if (e1000_get_flash_presence_i210(hw))
|
||||
hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
|
||||
else
|
||||
hw->nvm.ops.init_params = e1000_init_nvm_params_i211;
|
||||
hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
|
||||
break;
|
||||
case e1000_i211:
|
||||
hw->nvm.ops.init_params = e1000_init_nvm_params_i211;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -43,8 +43,6 @@ s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset,
|
||||
s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
|
||||
u16 words, u16 *data);
|
||||
s32 e1000_read_invm_i211(struct e1000_hw *hw, u8 address, u16 *data);
|
||||
s32 e1000_check_for_copper_link_i210(struct e1000_hw *hw);
|
||||
s32 e1000_set_ltr_i210(struct e1000_hw *hw, bool link);
|
||||
s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
|
||||
void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
|
||||
|
||||
@@ -69,6 +67,15 @@ enum E1000_INVM_STRUCTURE_TYPE {
|
||||
|
||||
#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
|
||||
#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
|
||||
#define E1000_INVM_ULT_BYTES_SIZE 8
|
||||
#define E1000_INVM_RECORD_SIZE_IN_BYTES 4
|
||||
#define E1000_INVM_VER_FIELD_ONE 0x1FF8
|
||||
#define E1000_INVM_VER_FIELD_TWO 0x7FE000
|
||||
#define E1000_INVM_IMGTYPE_FIELD 0x1F800000
|
||||
|
||||
#define E1000_INVM_MAJOR_MASK 0x3F0
|
||||
#define E1000_INVM_MINOR_MASK 0xF
|
||||
#define E1000_INVM_MAJOR_SHIFT 4
|
||||
|
||||
#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \
|
||||
(ID_LED_DEF1_DEF2 << 4) | \
|
||||
@@ -77,4 +84,9 @@ enum E1000_INVM_STRUCTURE_TYPE {
|
||||
(ID_LED_DEF1_DEF2 << 4) | \
|
||||
(ID_LED_DEF1_DEF2))
|
||||
|
||||
/* NVM offset defaults for I211 devices */
|
||||
#define NVM_INIT_CTRL_2_DEFAULT_I211 0X7243
|
||||
#define NVM_INIT_CTRL_4_DEFAULT_I211 0x00C1
|
||||
#define NVM_LED_1_CFG_DEFAULT_I211 0x0184
|
||||
#define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -59,12 +59,8 @@
|
||||
#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 */
|
||||
/* FW established a valid mode */
|
||||
#define E1000_ICH_FWSM_FW_VALID 0x00008000
|
||||
#define E1000_ICH_FWSM_PCIM2PCI 0x01000000 /* ME PCIm-to-PCI active */
|
||||
@@ -72,23 +68,12 @@
|
||||
|
||||
#define E1000_ICH_MNG_IAMT_MODE 0x2
|
||||
|
||||
#define E1000_FWSM_PROXY_MODE 0x00000008 /* FW is in proxy mode */
|
||||
#define E1000_FWSM_MEMC 0x00000010 /* ME Messaging capable */
|
||||
#define E1000_FWSM_WLOCK_MAC_MASK 0x0380
|
||||
#define E1000_FWSM_WLOCK_MAC_SHIFT 7
|
||||
|
||||
/* Shared Receive Address Registers */
|
||||
#define E1000_SHRAL(_i) (0x05438 + ((_i) * 8))
|
||||
#define E1000_SHRAH(_i) (0x0543C + ((_i) * 8))
|
||||
#define E1000_SHRAH_AV 0x80000000 /* Addr Valid bit */
|
||||
#define E1000_SHRAH_MAV 0x40000000 /* Multicast Addr Valid bit */
|
||||
|
||||
#define E1000_H2ME 0x05B50 /* Host to ME */
|
||||
#define E1000_H2ME_LSECREQ 0x00000001 /* Linksec Request */
|
||||
#define E1000_H2ME_LSECA 0x00000002 /* Linksec Active */
|
||||
#define E1000_H2ME_LSECSF 0x00000004 /* Linksec Failed */
|
||||
#define E1000_H2ME_LSECD 0x00000008 /* Linksec Disabled */
|
||||
#define E1000_H2ME_SLCAPD 0x00000010 /* Start LCAPD */
|
||||
#define E1000_H2ME_IPV4_ARP_EN 0x00000020 /* Arp Offload enable bit */
|
||||
#define E1000_H2ME_IPV6_NS_EN 0x00000040 /* NS Offload enable bit */
|
||||
#define E1000_SHRAL_PCH_LPT(_i) (0x05408 + ((_i) * 8))
|
||||
#define E1000_SHRAH_PCH_LPT(_i) (0x0540C + ((_i) * 8))
|
||||
|
||||
#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
|
||||
(ID_LED_OFF1_OFF2 << 8) | \
|
||||
@@ -105,27 +90,30 @@
|
||||
#define E1000_FEXTNVM_SW_CONFIG 1
|
||||
#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M */
|
||||
|
||||
#define E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK 0x0C000000
|
||||
#define E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC 0x08000000
|
||||
|
||||
#define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7
|
||||
#define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7
|
||||
#define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3
|
||||
|
||||
#define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100
|
||||
|
||||
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
|
||||
|
||||
#define E1000_ICH_RAR_ENTRIES 7
|
||||
#define E1000_PCH2_RAR_ENTRIES 5 /* RAR[0], SHRA[0-3] */
|
||||
#define E1000_PCH_LPT_RAR_ENTRIES 12 /* RAR[0], SHRA[0-10] */
|
||||
|
||||
#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
|
||||
|
||||
/* PHY Wakeup Registers and defines */
|
||||
#define BM_PORT_GEN_CFG PHY_REG(BM_PORT_CTRL_PAGE, 17)
|
||||
@@ -138,14 +126,6 @@
|
||||
#define BM_RAR_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2)))
|
||||
#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2)))
|
||||
#define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1)))
|
||||
#define BM_IPAV (BM_PHY_REG(BM_WUC_PAGE, 64))
|
||||
#define BM_IP4AT_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 82 + ((_i) * 2)))
|
||||
#define BM_IP4AT_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 83 + ((_i) * 2)))
|
||||
|
||||
#define BM_SHRAL_LOWER(_i) (BM_PHY_REG(BM_WUC_PAGE, 44 + ((_i) * 4)))
|
||||
#define BM_SHRAL_UPPER(_i) (BM_PHY_REG(BM_WUC_PAGE, 45 + ((_i) * 4)))
|
||||
#define BM_SHRAH_LOWER(_i) (BM_PHY_REG(BM_WUC_PAGE, 46 + ((_i) * 4)))
|
||||
#define BM_SHRAH_UPPER(_i) (BM_PHY_REG(BM_WUC_PAGE, 47 + ((_i) * 4)))
|
||||
|
||||
#define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */
|
||||
#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */
|
||||
@@ -177,28 +157,28 @@
|
||||
|
||||
#define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */
|
||||
|
||||
/*
|
||||
* For ICH, the name used for NVM word 17h is LED1 Config.
|
||||
* For PCH, the word was re-named to OEM Config.
|
||||
*/
|
||||
#define E1000_NVM_LED1_CONFIG 0x17 /* NVM LED1/LPLU Config Word */
|
||||
#define E1000_NVM_LED1_CONFIG_LPLU_NONDOA 0x0400 /* NVM LPLU in non-D0a Bit */
|
||||
#define E1000_NVM_OEM_CONFIG E1000_NVM_LED1_CONFIG
|
||||
#define E1000_NVM_OEM_CONFIG_LPLU_NONDOA E1000_NVM_LED1_CONFIG_LPLU_NONDOA
|
||||
|
||||
#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
|
||||
#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
|
||||
|
||||
/* SMBus Control Phy Register */
|
||||
#define CV_SMB_CTRL PHY_REG(769, 23)
|
||||
#define CV_SMB_CTRL_FORCE_SMBUS 0x0001
|
||||
|
||||
/* SMBus Address Phy Register */
|
||||
#define HV_SMB_ADDR PHY_REG(768, 26)
|
||||
#define HV_SMB_ADDR_MASK 0x007F
|
||||
#define HV_SMB_ADDR_PEC_EN 0x0200
|
||||
#define HV_SMB_ADDR_VALID 0x0080
|
||||
#define HV_SMB_ADDR_FREQ_MASK 0x1100
|
||||
#define HV_SMB_ADDR_FREQ_LOW_SHIFT 8
|
||||
#define HV_SMB_ADDR_FREQ_HIGH_SHIFT 12
|
||||
|
||||
/* Strapping Option Register - RO */
|
||||
#define E1000_STRAP 0x0000C
|
||||
#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
|
||||
#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17
|
||||
#define E1000_STRAP_SMT_FREQ_MASK 0x00003000
|
||||
#define E1000_STRAP_SMT_FREQ_SHIFT 12
|
||||
|
||||
/* OEM Bits Phy Register */
|
||||
#define HV_OEM_BITS PHY_REG(768, 25)
|
||||
@@ -206,8 +186,6 @@
|
||||
#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */
|
||||
#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
|
||||
|
||||
#define LCD_CFG_PHY_ADDR_BIT 0x0020 /* Phy addr bit from LCD Config word */
|
||||
|
||||
/* KMRN Mode Control */
|
||||
#define HV_KMRN_MODE_CTRL PHY_REG(769, 16)
|
||||
#define HV_KMRN_MDIO_SLOW 0x0400
|
||||
@@ -219,47 +197,73 @@
|
||||
|
||||
/* PHY Power Management Control */
|
||||
#define HV_PM_CTRL PHY_REG(770, 17)
|
||||
#define HV_PM_CTRL_PLL_STOP_IN_K1_GIGA 0x100
|
||||
|
||||
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */
|
||||
|
||||
/* PHY Low Power Idle Control */
|
||||
#define I82579_LPI_CTRL PHY_REG(772, 20)
|
||||
#define I82579_LPI_CTRL_100_ENABLE 0x2000
|
||||
#define I82579_LPI_CTRL_1000_ENABLE 0x4000
|
||||
#define I82579_LPI_CTRL_ENABLE_MASK 0x6000
|
||||
#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80
|
||||
|
||||
/* EMI Registers */
|
||||
/* Extended Management Interface (EMI) Registers */
|
||||
#define I82579_EMI_ADDR 0x10
|
||||
#define I82579_EMI_DATA 0x11
|
||||
#define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */
|
||||
#define I82579_MSE_THRESHOLD 0x084F /* Mean Square Error Threshold */
|
||||
#define I82579_MSE_THRESHOLD 0x084F /* 82579 Mean Square Error Threshold */
|
||||
#define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */
|
||||
#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */
|
||||
#define I82579_RX_CONFIG 0x3412 /* Receive configuration */
|
||||
#define I82579_EEE_PCS_STATUS 0x182D /* IEEE MMD Register 3.1 >> 8 */
|
||||
#define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */
|
||||
#define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */
|
||||
#define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */
|
||||
#define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE supported */
|
||||
#define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE supported */
|
||||
#define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */
|
||||
#define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */
|
||||
#define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */
|
||||
#define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */
|
||||
|
||||
/*
|
||||
* 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)
|
||||
#define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */
|
||||
#define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */
|
||||
|
||||
/* Additional interrupt register bit definitions */
|
||||
#define E1000_ICR_LSECPNC 0x00004000 /* PN threshold - client */
|
||||
#define E1000_IMS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */
|
||||
#define E1000_ICS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */
|
||||
|
||||
/* Security Processing bit Indication */
|
||||
#define E1000_RXDEXT_LINKSEC_STATUS_LSECH 0x01000000
|
||||
#define E1000_RXDEXT_LINKSEC_ERROR_BIT_MASK 0x60000000
|
||||
#define E1000_RXDEXT_LINKSEC_ERROR_NO_SA_MATCH 0x20000000
|
||||
#define E1000_RXDEXT_LINKSEC_ERROR_REPLAY_ERROR 0x40000000
|
||||
#define E1000_RXDEXT_LINKSEC_ERROR_BAD_SIG 0x60000000
|
||||
/* Intel Rapid Start Technology Support */
|
||||
#define I217_PROXY_CTRL BM_PHY_REG(BM_WUC_PAGE, 70)
|
||||
#define I217_PROXY_CTRL_AUTO_DISABLE 0x0080
|
||||
#define I217_SxCTRL PHY_REG(BM_PORT_CTRL_PAGE, 28)
|
||||
#define I217_SxCTRL_ENABLE_LPI_RESET 0x1000
|
||||
#define I217_CGFREG PHY_REG(772, 29)
|
||||
#define I217_CGFREG_ENABLE_MTA_RESET 0x0002
|
||||
#define I217_MEMPWR PHY_REG(772, 26)
|
||||
#define I217_MEMPWR_DISABLE_SMB_RELEASE 0x0010
|
||||
|
||||
/* Receive Address Initial CRC Calculation */
|
||||
#define E1000_PCH_RAICC(_n) (0x05F50 + ((_n) * 4))
|
||||
|
||||
/* Latency Tolerance Reporting */
|
||||
#define E1000_LTRV 0x000F8
|
||||
#define E1000_LTRV_VALUE_MASK 0x000003FF
|
||||
#define E1000_LTRV_SCALE_MAX 5
|
||||
#define E1000_LTRV_SCALE_FACTOR 5
|
||||
#define E1000_LTRV_SCALE_SHIFT 10
|
||||
#define E1000_LTRV_SCALE_MASK 0x00001C00
|
||||
#define E1000_LTRV_REQ_SHIFT 15
|
||||
#define E1000_LTRV_NOSNOOP_SHIFT 16
|
||||
#define E1000_LTRV_SEND (1 << 30)
|
||||
|
||||
/* Proprietary Latency Tolerance Reporting PCI Capability */
|
||||
#define E1000_PCI_LTR_CAP_LPT 0xA8
|
||||
|
||||
/* OBFF Control & Threshold Defines */
|
||||
#define E1000_SVCR_OFF_EN 0x00000001
|
||||
#define E1000_SVCR_OFF_MASKINT 0x00001000
|
||||
#define E1000_SVCR_OFF_TIMER_MASK 0xFFFF0000
|
||||
#define E1000_SVCR_OFF_TIMER_SHIFT 16
|
||||
#define E1000_SVT_OFF_HWM_MASK 0x0000001F
|
||||
|
||||
void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
|
||||
bool state);
|
||||
void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
|
||||
@@ -269,4 +273,5 @@ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw);
|
||||
s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
|
||||
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw);
|
||||
s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
|
||||
#endif
|
||||
s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data);
|
||||
#endif /* _E1000_ICH8LAN_H_ */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -70,12 +70,9 @@ void e1000_init_mac_ops_generic(struct e1000_hw *hw)
|
||||
mac->ops.setup_link = e1000_null_ops_generic;
|
||||
mac->ops.get_link_up_info = e1000_null_link_info;
|
||||
mac->ops.check_for_link = e1000_null_ops_generic;
|
||||
mac->ops.wait_autoneg = e1000_wait_autoneg_generic;
|
||||
mac->ops.set_obff_timer = e1000_null_set_obff_timer;
|
||||
/* Management */
|
||||
mac->ops.check_mng_mode = e1000_null_mng_mode;
|
||||
mac->ops.mng_host_if_write = e1000_mng_host_if_write_generic;
|
||||
mac->ops.mng_write_cmd_header = e1000_mng_write_cmd_header_generic;
|
||||
mac->ops.mng_enable_host_if = e1000_mng_enable_host_if_generic;
|
||||
/* VLAN, MC, etc. */
|
||||
mac->ops.update_mc_addr_list = e1000_null_update_mc;
|
||||
mac->ops.clear_vfta = e1000_null_mac_generic;
|
||||
@@ -118,8 +115,7 @@ s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d)
|
||||
* e1000_null_mng_mode - No-op function, return FALSE
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
bool e1000_null_mng_mode(struct e1000_hw *hw)
|
||||
{
|
||||
bool e1000_null_mng_mode(struct e1000_hw *hw) {
|
||||
DEBUGFUNC("e1000_null_mng_mode");
|
||||
return FALSE;
|
||||
}
|
||||
@@ -154,6 +150,16 @@ void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a)
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_null_set_obff_timer - No-op function, return 0
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
s32 e1000_null_set_obff_timer(struct e1000_hw *hw, u32 a)
|
||||
{
|
||||
DEBUGFUNC("e1000_null_set_obff_timer");
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_bus_info_pci_generic - Get PCI(x) bus information
|
||||
* @hw: pointer to the HW structure
|
||||
@@ -268,8 +274,7 @@ static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw)
|
||||
struct e1000_bus_info *bus = &hw->bus;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* The status register reports the correct function number
|
||||
/* The status register reports the correct function number
|
||||
* for the device regardless of function swap state.
|
||||
*/
|
||||
reg = E1000_READ_REG(hw, E1000_STATUS);
|
||||
@@ -389,7 +394,7 @@ void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count)
|
||||
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
|
||||
{
|
||||
u32 i;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 ret_val;
|
||||
u16 offset, nvm_alt_mac_addr_offset, nvm_data;
|
||||
u8 alt_mac_addr[ETH_ADDR_LEN];
|
||||
|
||||
@@ -403,8 +408,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
|
||||
if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573))
|
||||
return E1000_SUCCESS;
|
||||
|
||||
/*
|
||||
* Alternate MAC address is handled by the option ROM for 82580
|
||||
/* Alternate MAC address is handled by the option ROM for 82580
|
||||
* and newer. SW support not required.
|
||||
*/
|
||||
if (hw->mac.type >= e1000_82580)
|
||||
@@ -447,8 +451,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a valid alternate MAC address, and we want to treat it the
|
||||
/* We have a valid alternate MAC address, and we want to treat it the
|
||||
* same as the normal permanent MAC address stored by the HW into the
|
||||
* RAR. Do this by mapping this address into RAR0.
|
||||
*/
|
||||
@@ -472,8 +475,7 @@ static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
|
||||
|
||||
DEBUGFUNC("e1000_rar_set_generic");
|
||||
|
||||
/*
|
||||
* HW expects these in little endian so we reverse the byte order
|
||||
/* HW expects these in little endian so we reverse the byte order
|
||||
* from network order (big endian) to little endian
|
||||
*/
|
||||
rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
|
||||
@@ -485,8 +487,7 @@ static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
|
||||
if (rar_low || rar_high)
|
||||
rar_high |= E1000_RAH_AV;
|
||||
|
||||
/*
|
||||
* Some bridges will combine consecutive 32-bit writes into
|
||||
/* Some bridges will combine consecutive 32-bit writes into
|
||||
* a single burst write, which will malfunction on some parts.
|
||||
* The flushes avoid this.
|
||||
*/
|
||||
@@ -514,15 +515,13 @@ u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr)
|
||||
/* Register count multiplied by bits per register */
|
||||
hash_mask = (hw->mac.mta_reg_count * 32) - 1;
|
||||
|
||||
/*
|
||||
* For a mc_filter_type of 0, bit_shift is the number of left-shifts
|
||||
/* For a mc_filter_type of 0, bit_shift is the number of left-shifts
|
||||
* where 0xFF would still fall within the hash mask.
|
||||
*/
|
||||
while (hash_mask >> bit_shift != 0xFF)
|
||||
bit_shift++;
|
||||
|
||||
/*
|
||||
* The portion of the address that is used for the hash table
|
||||
/* The portion of the address that is used for the hash table
|
||||
* is determined by the mc_filter_type setting.
|
||||
* The algorithm is such that there is a total of 8 bits of shifting.
|
||||
* The bit_shift for a mc_filter_type of 0 represents the number of
|
||||
@@ -707,8 +706,7 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_check_for_copper_link");
|
||||
|
||||
/*
|
||||
* We only want to go out to the PHY registers to see if Auto-Neg
|
||||
/* We only want to go out to the PHY registers to see if Auto-Neg
|
||||
* has completed and/or if our link status has changed. The
|
||||
* get_link_status flag is set upon receiving a Link Status
|
||||
* Change or Rx Sequence Error interrupt.
|
||||
@@ -716,8 +714,7 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw)
|
||||
if (!mac->get_link_status)
|
||||
return E1000_SUCCESS;
|
||||
|
||||
/*
|
||||
* First we want to see if the MII Status Register reports
|
||||
/* First we want to see if the MII Status Register reports
|
||||
* link. If so, then we want to get the current speed/duplex
|
||||
* of the PHY.
|
||||
*/
|
||||
@@ -730,28 +727,24 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw)
|
||||
|
||||
mac->get_link_status = FALSE;
|
||||
|
||||
/*
|
||||
* Check if there was DownShift, must be checked
|
||||
/* Check if there was DownShift, must be checked
|
||||
* immediately after link-up
|
||||
*/
|
||||
e1000_check_downshift_generic(hw);
|
||||
|
||||
/*
|
||||
* If we are forcing speed/duplex, then we simply return since
|
||||
/* If we are forcing speed/duplex, then we simply return since
|
||||
* we have already determined whether we have link or not.
|
||||
*/
|
||||
if (!mac->autoneg)
|
||||
return -E1000_ERR_CONFIG;
|
||||
|
||||
/*
|
||||
* Auto-Neg is enabled. Auto Speed Detection takes care
|
||||
/* Auto-Neg is enabled. Auto Speed Detection takes care
|
||||
* of MAC speed/duplex configuration. So we only need to
|
||||
* configure Collision Distance in the MAC.
|
||||
*/
|
||||
mac->ops.config_collision_dist(hw);
|
||||
|
||||
/*
|
||||
* Configure Flow Control now that Auto-Neg has completed.
|
||||
/* Configure Flow Control now that Auto-Neg has completed.
|
||||
* First, we need to restore the desired flow control
|
||||
* settings because we may have had to re-autoneg with a
|
||||
* different link partner.
|
||||
@@ -784,8 +777,7 @@ s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw)
|
||||
status = E1000_READ_REG(hw, E1000_STATUS);
|
||||
rxcw = E1000_READ_REG(hw, E1000_RXCW);
|
||||
|
||||
/*
|
||||
* If we don't have link (auto-negotiation failed or link partner
|
||||
/* If we don't have link (auto-negotiation failed or link partner
|
||||
* cannot auto-negotiate), the cable is plugged in (we have signal),
|
||||
* and our link partner is not trying to auto-negotiate with us (we
|
||||
* are receiving idles or data), we need to force link up. We also
|
||||
@@ -816,8 +808,7 @@ s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw)
|
||||
return ret_val;
|
||||
}
|
||||
} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
|
||||
/*
|
||||
* If we are forcing link and we are receiving /C/ ordered
|
||||
/* If we are forcing link and we are receiving /C/ ordered
|
||||
* sets, re-enable auto-negotiation in the TXCW register
|
||||
* and disable forced link in the Device Control register
|
||||
* in an attempt to auto-negotiate with our link partner.
|
||||
@@ -853,8 +844,7 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
|
||||
status = E1000_READ_REG(hw, E1000_STATUS);
|
||||
rxcw = E1000_READ_REG(hw, E1000_RXCW);
|
||||
|
||||
/*
|
||||
* If we don't have link (auto-negotiation failed or link partner
|
||||
/* If we don't have link (auto-negotiation failed or link partner
|
||||
* cannot auto-negotiate), and our link partner is not trying to
|
||||
* auto-negotiate with us (we are receiving idles or data),
|
||||
* we need to force link up. We also need to give auto-negotiation
|
||||
@@ -883,8 +873,7 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
|
||||
return ret_val;
|
||||
}
|
||||
} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
|
||||
/*
|
||||
* If we are forcing link and we are receiving /C/ ordered
|
||||
/* If we are forcing link and we are receiving /C/ ordered
|
||||
* sets, re-enable auto-negotiation in the TXCW register
|
||||
* and disable forced link in the Device Control register
|
||||
* in an attempt to auto-negotiate with our link partner.
|
||||
@@ -895,8 +884,7 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
|
||||
|
||||
mac->serdes_has_link = TRUE;
|
||||
} else if (!(E1000_TXCW_ANE & E1000_READ_REG(hw, E1000_TXCW))) {
|
||||
/*
|
||||
* If we force link for non-auto-negotiation switch, check
|
||||
/* If we force link for non-auto-negotiation switch, check
|
||||
* link status based on MAC synchronization for internal
|
||||
* serdes media type.
|
||||
*/
|
||||
@@ -955,8 +943,7 @@ s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_set_default_fc_generic");
|
||||
|
||||
/*
|
||||
* Read and store word 0x0F of the EEPROM. This word contains bits
|
||||
/* Read and store word 0x0F of the EEPROM. This word contains bits
|
||||
* that determine the hardware's default PAUSE (flow control) mode,
|
||||
* a bit that determines whether the HW defaults to enabling or
|
||||
* disabling auto-negotiation, and the direction of the
|
||||
@@ -998,15 +985,13 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_setup_link_generic");
|
||||
|
||||
/*
|
||||
* In the case of the phy reset being blocked, we already have a link.
|
||||
/* In the case of the phy reset being blocked, we already have a link.
|
||||
* We do not need to set it up again.
|
||||
*/
|
||||
if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
|
||||
return E1000_SUCCESS;
|
||||
|
||||
/*
|
||||
* If requested flow control is set to default, set flow control
|
||||
/* If requested flow control is set to default, set flow control
|
||||
* based on the EEPROM flow control settings.
|
||||
*/
|
||||
if (hw->fc.requested_mode == e1000_fc_default) {
|
||||
@@ -1015,8 +1000,7 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save off the requested flow control mode for use later. Depending
|
||||
/* Save off the requested flow control mode for use later. Depending
|
||||
* on the link partner's capabilities, we may or may not use this mode.
|
||||
*/
|
||||
hw->fc.current_mode = hw->fc.requested_mode;
|
||||
@@ -1029,8 +1013,7 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* Initialize the flow control address, type, and PAUSE timer
|
||||
/* 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.
|
||||
@@ -1059,8 +1042,7 @@ s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_commit_fc_settings_generic");
|
||||
|
||||
/*
|
||||
* Check for a software override of the flow control settings, and
|
||||
/* Check for a software override of the flow control settings, and
|
||||
* setup the device accordingly. If auto-negotiation is enabled, then
|
||||
* software will have to set the "PAUSE" bits to the correct value in
|
||||
* the Transmit Config Word Register (TXCW) and re-start auto-
|
||||
@@ -1082,8 +1064,7 @@ s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
|
||||
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
|
||||
break;
|
||||
case e1000_fc_rx_pause:
|
||||
/*
|
||||
* Rx Flow control is enabled and Tx Flow control is disabled
|
||||
/* Rx Flow control is enabled and Tx Flow control is disabled
|
||||
* by a software over-ride. Since there really isn't a way to
|
||||
* advertise that we are capable of Rx Pause ONLY, we will
|
||||
* advertise that we support both symmetric and asymmetric Rx
|
||||
@@ -1093,15 +1074,13 @@ s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
|
||||
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
|
||||
break;
|
||||
case e1000_fc_tx_pause:
|
||||
/*
|
||||
* Tx Flow control is enabled, and Rx Flow control is disabled,
|
||||
/* Tx Flow control is enabled, and Rx Flow control is disabled,
|
||||
* by a software over-ride.
|
||||
*/
|
||||
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
|
||||
break;
|
||||
case e1000_fc_full:
|
||||
/*
|
||||
* Flow control (both Rx and Tx) is enabled by a software
|
||||
/* Flow control (both Rx and Tx) is enabled by a software
|
||||
* over-ride.
|
||||
*/
|
||||
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
|
||||
@@ -1133,8 +1112,7 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_poll_fiber_serdes_link_generic");
|
||||
|
||||
/*
|
||||
* If we have a signal (the cable is plugged in, or assumed TRUE for
|
||||
/* If we have a signal (the cable is plugged in, or assumed TRUE for
|
||||
* serdes media) then poll for a "Link-Up" indication in the Device
|
||||
* Status Register. Time-out if a link isn't seen in 500 milliseconds
|
||||
* seconds (Auto-negotiation should complete in less than 500
|
||||
@@ -1149,8 +1127,7 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
|
||||
if (i == FIBER_LINK_UP_LIMIT) {
|
||||
DEBUGOUT("Never got a valid link from auto-neg!!!\n");
|
||||
mac->autoneg_failed = TRUE;
|
||||
/*
|
||||
* AutoNeg failed to achieve a link, so we'll call
|
||||
/* AutoNeg failed to achieve a link, so we'll call
|
||||
* mac->check_for_link. This routine will force the
|
||||
* link up if we detect a signal. This will allow us to
|
||||
* communicate with non-autonegotiating link partners.
|
||||
@@ -1194,8 +1171,7 @@ s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* Since auto-negotiation is enabled, take the link out of reset (the
|
||||
/* Since auto-negotiation is enabled, take the link out of reset (the
|
||||
* link will be in reset, because we previously reset the chip). This
|
||||
* will restart auto-negotiation. If auto-negotiation is successful
|
||||
* then the link-up status bit will be set and the flow control enable
|
||||
@@ -1207,8 +1183,7 @@ s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw)
|
||||
E1000_WRITE_FLUSH(hw);
|
||||
msec_delay(1);
|
||||
|
||||
/*
|
||||
* For these adapters, the SW definable pin 1 is set when the optics
|
||||
/* For these adapters, the SW definable pin 1 is set when the optics
|
||||
* detect a signal. If we have a signal, then poll for a "Link-Up"
|
||||
* indication.
|
||||
*/
|
||||
@@ -1258,16 +1233,14 @@ s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_set_fc_watermarks_generic");
|
||||
|
||||
/*
|
||||
* Set the flow control receive threshold registers. Normally,
|
||||
/* Set the flow control receive threshold registers. Normally,
|
||||
* these registers will be set to a default threshold that may be
|
||||
* adjusted later by the driver's runtime code. However, if the
|
||||
* ability to transmit pause frames is not enabled, then these
|
||||
* registers will be set to 0.
|
||||
*/
|
||||
if (hw->fc.current_mode & e1000_fc_tx_pause) {
|
||||
/*
|
||||
* We need to set up the Receive Threshold high and low water
|
||||
/* We need to set up the Receive Threshold high and low water
|
||||
* marks as well as (optionally) enabling the transmission of
|
||||
* XON frames.
|
||||
*/
|
||||
@@ -1301,8 +1274,7 @@ s32 e1000_force_mac_fc_generic(struct e1000_hw *hw)
|
||||
|
||||
ctrl = E1000_READ_REG(hw, E1000_CTRL);
|
||||
|
||||
/*
|
||||
* Because we didn't get link via the internal auto-negotiation
|
||||
/* Because we didn't get link via the internal auto-negotiation
|
||||
* mechanism (we either forced link or we got link via PHY
|
||||
* auto-neg), we have to manually enable/disable transmit an
|
||||
* receive flow control.
|
||||
@@ -1360,13 +1332,13 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;
|
||||
u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
|
||||
u16 speed, duplex;
|
||||
|
||||
DEBUGFUNC("e1000_config_fc_after_link_up_generic");
|
||||
|
||||
/*
|
||||
* Check for the case where we have fiber media and auto-neg failed
|
||||
/* Check for the case where we have fiber media and auto-neg failed
|
||||
* so we had to force link. In this case, we need to force the
|
||||
* configuration of the MAC to match the "fc" parameter.
|
||||
*/
|
||||
@@ -1384,15 +1356,13 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for the case where we have copper media and auto-neg is
|
||||
/* Check for the case where we have copper media and auto-neg is
|
||||
* enabled. In this case, we need to check and see if Auto-Neg
|
||||
* has completed, and if so, how the PHY and link partner has
|
||||
* flow control configured.
|
||||
*/
|
||||
if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
|
||||
/*
|
||||
* Read the MII Status Register and check to see if AutoNeg
|
||||
/* Read the MII Status Register and check to see if AutoNeg
|
||||
* has completed. We read this twice because this reg has
|
||||
* some "sticky" (latched) bits.
|
||||
*/
|
||||
@@ -1408,8 +1378,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* The AutoNeg process has completed, so we now need to
|
||||
/* The AutoNeg process has completed, so we now need to
|
||||
* read both the Auto Negotiation Advertisement
|
||||
* Register (Address 4) and the Auto_Negotiation Base
|
||||
* Page Ability Register (Address 5) to determine how
|
||||
@@ -1424,8 +1393,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* Two bits in the Auto Negotiation Advertisement Register
|
||||
/* Two bits in the Auto Negotiation Advertisement Register
|
||||
* (Address 4) and two bits in the Auto Negotiation Base
|
||||
* Page Ability Register (Address 5) determine flow control
|
||||
* for both the PHY and the link partner. The following
|
||||
@@ -1460,8 +1428,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
|
||||
*/
|
||||
if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
|
||||
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
|
||||
/*
|
||||
* Now we need to check if the user selected Rx ONLY
|
||||
/* Now we need to check if the user selected Rx ONLY
|
||||
* of pause frames. In this case, we had to advertise
|
||||
* FULL flow control because we could not advertise Rx
|
||||
* ONLY. Hence, we must now check to see if we need to
|
||||
@@ -1475,8 +1442,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
|
||||
DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* For receiving PAUSE frames ONLY.
|
||||
/* For receiving PAUSE frames ONLY.
|
||||
*
|
||||
* LOCAL DEVICE | LINK PARTNER
|
||||
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
|
||||
@@ -1490,8 +1456,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
|
||||
hw->fc.current_mode = e1000_fc_tx_pause;
|
||||
DEBUGOUT("Flow Control = Tx PAUSE frames only.\n");
|
||||
}
|
||||
/*
|
||||
* For transmitting PAUSE frames ONLY.
|
||||
/* For transmitting PAUSE frames ONLY.
|
||||
*
|
||||
* LOCAL DEVICE | LINK PARTNER
|
||||
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
|
||||
@@ -1505,16 +1470,14 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
|
||||
hw->fc.current_mode = e1000_fc_rx_pause;
|
||||
DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
|
||||
} else {
|
||||
/*
|
||||
* Per the IEEE spec, at this point flow control
|
||||
/* Per the IEEE spec, at this point flow control
|
||||
* should be disabled.
|
||||
*/
|
||||
hw->fc.current_mode = e1000_fc_none;
|
||||
DEBUGOUT("Flow Control = NONE.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we need to do one last check... If we auto-
|
||||
/* Now we need to do one last check... If we auto-
|
||||
* negotiated to HALF DUPLEX, flow control should not be
|
||||
* enabled per IEEE 802.3 spec.
|
||||
*/
|
||||
@@ -1527,8 +1490,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
|
||||
if (duplex == HALF_DUPLEX)
|
||||
hw->fc.current_mode = e1000_fc_none;
|
||||
|
||||
/*
|
||||
* Now we call a subroutine to actually force the MAC
|
||||
/* Now we call a subroutine to actually force the MAC
|
||||
* controller to use the correct flow control settings.
|
||||
*/
|
||||
ret_val = e1000_force_mac_fc_generic(hw);
|
||||
@@ -1538,6 +1500,130 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for the case where we have SerDes media and auto-neg is
|
||||
* enabled. In this case, we need to check and see if Auto-Neg
|
||||
* has completed, and if so, how the PHY and link partner has
|
||||
* flow control configured.
|
||||
*/
|
||||
if ((hw->phy.media_type == e1000_media_type_internal_serdes) &&
|
||||
mac->autoneg) {
|
||||
/* Read the PCS_LSTS and check to see if AutoNeg
|
||||
* has completed.
|
||||
*/
|
||||
pcs_status_reg = E1000_READ_REG(hw, E1000_PCS_LSTAT);
|
||||
|
||||
if (!(pcs_status_reg & E1000_PCS_LSTS_AN_COMPLETE)) {
|
||||
DEBUGOUT("PCS Auto Neg has not completed.\n");
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* The AutoNeg process has completed, so we now need to
|
||||
* read both the Auto Negotiation Advertisement
|
||||
* Register (PCS_ANADV) and the Auto_Negotiation Base
|
||||
* Page Ability Register (PCS_LPAB) to determine how
|
||||
* flow control was negotiated.
|
||||
*/
|
||||
pcs_adv_reg = E1000_READ_REG(hw, E1000_PCS_ANADV);
|
||||
pcs_lp_ability_reg = E1000_READ_REG(hw, E1000_PCS_LPAB);
|
||||
|
||||
/* Two bits in the Auto Negotiation Advertisement Register
|
||||
* (PCS_ANADV) and two bits in the Auto Negotiation Base
|
||||
* Page Ability Register (PCS_LPAB) determine flow control
|
||||
* for both the PHY and the link partner. The following
|
||||
* table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
|
||||
* 1999, describes these PAUSE resolution bits and how flow
|
||||
* control is determined based upon these settings.
|
||||
* NOTE: DC = Don't Care
|
||||
*
|
||||
* LOCAL DEVICE | LINK PARTNER
|
||||
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
|
||||
*-------|---------|-------|---------|--------------------
|
||||
* 0 | 0 | DC | DC | e1000_fc_none
|
||||
* 0 | 1 | 0 | DC | e1000_fc_none
|
||||
* 0 | 1 | 1 | 0 | e1000_fc_none
|
||||
* 0 | 1 | 1 | 1 | e1000_fc_tx_pause
|
||||
* 1 | 0 | 0 | DC | e1000_fc_none
|
||||
* 1 | DC | 1 | DC | e1000_fc_full
|
||||
* 1 | 1 | 0 | 0 | e1000_fc_none
|
||||
* 1 | 1 | 0 | 1 | e1000_fc_rx_pause
|
||||
*
|
||||
* Are both PAUSE bits set to 1? If so, this implies
|
||||
* Symmetric Flow Control is enabled at both ends. The
|
||||
* ASM_DIR bits are irrelevant per the spec.
|
||||
*
|
||||
* For Symmetric Flow Control:
|
||||
*
|
||||
* LOCAL DEVICE | LINK PARTNER
|
||||
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
|
||||
*-------|---------|-------|---------|--------------------
|
||||
* 1 | DC | 1 | DC | e1000_fc_full
|
||||
*
|
||||
*/
|
||||
if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
|
||||
(pcs_lp_ability_reg & E1000_TXCW_PAUSE)) {
|
||||
/* Now we need to check if the user selected Rx ONLY
|
||||
* of pause frames. In this case, we had to advertise
|
||||
* FULL flow control because we could not advertise Rx
|
||||
* ONLY. Hence, we must now check to see if we need to
|
||||
* turn OFF the TRANSMISSION of PAUSE frames.
|
||||
*/
|
||||
if (hw->fc.requested_mode == e1000_fc_full) {
|
||||
hw->fc.current_mode = e1000_fc_full;
|
||||
DEBUGOUT("Flow Control = FULL.\n");
|
||||
} else {
|
||||
hw->fc.current_mode = e1000_fc_rx_pause;
|
||||
DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
|
||||
}
|
||||
}
|
||||
/* For receiving PAUSE frames ONLY.
|
||||
*
|
||||
* LOCAL DEVICE | LINK PARTNER
|
||||
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
|
||||
*-------|---------|-------|---------|--------------------
|
||||
* 0 | 1 | 1 | 1 | e1000_fc_tx_pause
|
||||
*/
|
||||
else if (!(pcs_adv_reg & E1000_TXCW_PAUSE) &&
|
||||
(pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
|
||||
(pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
|
||||
(pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
|
||||
hw->fc.current_mode = e1000_fc_tx_pause;
|
||||
DEBUGOUT("Flow Control = Tx PAUSE frames only.\n");
|
||||
}
|
||||
/* For transmitting PAUSE frames ONLY.
|
||||
*
|
||||
* LOCAL DEVICE | LINK PARTNER
|
||||
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
|
||||
*-------|---------|-------|---------|--------------------
|
||||
* 1 | 1 | 0 | 1 | e1000_fc_rx_pause
|
||||
*/
|
||||
else if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
|
||||
(pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
|
||||
!(pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
|
||||
(pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
|
||||
hw->fc.current_mode = e1000_fc_rx_pause;
|
||||
DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
|
||||
} else {
|
||||
/* Per the IEEE spec, at this point flow control
|
||||
* should be disabled.
|
||||
*/
|
||||
hw->fc.current_mode = e1000_fc_none;
|
||||
DEBUGOUT("Flow Control = NONE.\n");
|
||||
}
|
||||
|
||||
/* Now we call a subroutine to actually force the MAC
|
||||
* controller to use the correct flow control settings.
|
||||
*/
|
||||
pcs_ctrl_reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
|
||||
pcs_ctrl_reg |= E1000_PCS_LCTL_FORCE_FCTRL;
|
||||
E1000_WRITE_REG(hw, E1000_PCS_LCTL, pcs_ctrl_reg);
|
||||
|
||||
ret_val = e1000_force_mac_fc_generic(hw);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("Error forcing flow control settings\n");
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1854,16 +1940,28 @@ s32 e1000_blink_led_generic(struct e1000_hw *hw)
|
||||
ledctl_blink = E1000_LEDCTL_LED0_BLINK |
|
||||
(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
|
||||
} else {
|
||||
/*
|
||||
* set the blink bit for each LED that's "on" (0x0E)
|
||||
* in ledctl_mode2
|
||||
/* Set the blink bit for each LED that's "on" (0x0E)
|
||||
* (or "off" if inverted) in ledctl_mode2. The blink
|
||||
* logic in hardware only works when mode is set to "on"
|
||||
* so it must be changed accordingly when the mode is
|
||||
* "off" and inverted.
|
||||
*/
|
||||
ledctl_blink = hw->mac.ledctl_mode2;
|
||||
for (i = 0; i < 4; i++)
|
||||
if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
|
||||
E1000_LEDCTL_MODE_LED_ON)
|
||||
ledctl_blink |= (E1000_LEDCTL_LED0_BLINK <<
|
||||
(i * 8));
|
||||
for (i = 0; i < 32; i += 8) {
|
||||
u32 mode = (hw->mac.ledctl_mode2 >> i) &
|
||||
E1000_LEDCTL_LED0_MODE_MASK;
|
||||
u32 led_default = hw->mac.ledctl_default >> i;
|
||||
|
||||
if ((!(led_default & E1000_LEDCTL_LED0_IVRT) &&
|
||||
(mode == E1000_LEDCTL_MODE_LED_ON)) ||
|
||||
((led_default & E1000_LEDCTL_LED0_IVRT) &&
|
||||
(mode == E1000_LEDCTL_MODE_LED_OFF))) {
|
||||
ledctl_blink &=
|
||||
~(E1000_LEDCTL_LED0_MODE_MASK << i);
|
||||
ledctl_blink |= (E1000_LEDCTL_LED0_BLINK |
|
||||
E1000_LEDCTL_MODE_LED_ON) << i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_LEDCTL, ledctl_blink);
|
||||
@@ -2082,6 +2180,20 @@ static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw)
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_validate_mdi_setting_crossover_generic - Verify MDI/MDIx settings
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Validate the MDI/MDIx setting, allowing for auto-crossover during forced
|
||||
* operation.
|
||||
**/
|
||||
s32 e1000_validate_mdi_setting_crossover_generic(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_validate_mdi_setting_crossover_generic");
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_write_8bit_ctrl_reg_generic - Write a 8bit CTRL register
|
||||
* @hw: pointer to the HW structure
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -35,10 +35,6 @@
|
||||
#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'
|
||||
*/
|
||||
void e1000_init_mac_ops_generic(struct e1000_hw *hw);
|
||||
void e1000_null_mac_generic(struct e1000_hw *hw);
|
||||
s32 e1000_null_ops_generic(struct e1000_hw *hw);
|
||||
@@ -47,6 +43,7 @@ bool e1000_null_mng_mode(struct e1000_hw *hw);
|
||||
void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a);
|
||||
void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);
|
||||
void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a);
|
||||
s32 e1000_null_set_obff_timer(struct e1000_hw *hw, u32 a);
|
||||
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);
|
||||
@@ -77,6 +74,7 @@ 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_crossover_generic(struct e1000_hw *hw);
|
||||
s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg,
|
||||
u32 offset, u8 data);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -145,11 +145,10 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
|
||||
return hw->mac.tx_pkt_filtering;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we can't read from the host interface for whatever
|
||||
/* If we can't read from the host interface for whatever
|
||||
* reason, disable filtering.
|
||||
*/
|
||||
ret_val = hw->mac.ops.mng_enable_host_if(hw);
|
||||
ret_val = e1000_mng_enable_host_if_generic(hw);
|
||||
if (ret_val != E1000_SUCCESS) {
|
||||
hw->mac.tx_pkt_filtering = FALSE;
|
||||
return hw->mac.tx_pkt_filtering;
|
||||
@@ -165,8 +164,7 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
|
||||
hdr->checksum = 0;
|
||||
csum = e1000_calculate_checksum((u8 *)hdr,
|
||||
E1000_MNG_DHCP_COOKIE_LENGTH);
|
||||
/*
|
||||
* If either the checksums or signature don't match, then
|
||||
/* 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.
|
||||
*/
|
||||
@@ -259,8 +257,7 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
|
||||
/* Calculate length in DWORDs */
|
||||
length >>= 2;
|
||||
|
||||
/*
|
||||
* The device driver writes the relevant command block into the
|
||||
/* The device driver writes the relevant command block into the
|
||||
* ram area.
|
||||
*/
|
||||
for (i = 0; i < length; i++) {
|
||||
@@ -312,18 +309,18 @@ s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
|
||||
hdr.checksum = 0;
|
||||
|
||||
/* Enable the host interface */
|
||||
ret_val = hw->mac.ops.mng_enable_host_if(hw);
|
||||
ret_val = e1000_mng_enable_host_if_generic(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* Populate the host interface with the contents of "buffer". */
|
||||
ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
|
||||
sizeof(hdr), &(hdr.checksum));
|
||||
ret_val = e1000_mng_host_if_write_generic(hw, buffer, length,
|
||||
sizeof(hdr), &(hdr.checksum));
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* Write the manageability command header */
|
||||
ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
|
||||
ret_val = e1000_mng_write_cmd_header_generic(hw, &hdr);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
@@ -424,8 +421,7 @@ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
|
||||
/* Calculate length in DWORDs */
|
||||
length >>= 2;
|
||||
|
||||
/*
|
||||
* The device driver writes the relevant command block
|
||||
/* The device driver writes the relevant command block
|
||||
* into the ram area.
|
||||
*/
|
||||
for (i = 0; i < length; i++)
|
||||
@@ -537,8 +533,7 @@ s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
|
||||
/* Calculate length in DWORDs */
|
||||
length >>= 2;
|
||||
|
||||
/*
|
||||
* The device driver writes the relevant FW code block
|
||||
/* The device driver writes the relevant FW code block
|
||||
* into the ram area in DWORDs via 1kB ram addressing window.
|
||||
*/
|
||||
for (i = 0; i < length; i++) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -227,7 +227,6 @@ 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");
|
||||
|
||||
@@ -237,15 +236,13 @@ s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
|
||||
else
|
||||
reg = E1000_READ_REG(hw, E1000_EEWR);
|
||||
|
||||
if (reg & E1000_NVM_RW_REG_DONE) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
break;
|
||||
}
|
||||
if (reg & E1000_NVM_RW_REG_DONE)
|
||||
return E1000_SUCCESS;
|
||||
|
||||
usec_delay(5);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,7 +257,6 @@ 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");
|
||||
|
||||
@@ -279,10 +275,10 @@ s32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
|
||||
eecd &= ~E1000_EECD_REQ;
|
||||
E1000_WRITE_REG(hw, E1000_EECD, eecd);
|
||||
DEBUGOUT("Could not acquire NVM grant\n");
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -381,7 +377,6 @@ 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;
|
||||
u8 spi_stat_reg;
|
||||
|
||||
DEBUGFUNC("e1000_ready_nvm_eeprom");
|
||||
@@ -402,8 +397,7 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
|
||||
E1000_WRITE_FLUSH(hw);
|
||||
usec_delay(1);
|
||||
|
||||
/*
|
||||
* Read "Status Register" repeatedly until the LSB is cleared.
|
||||
/* 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.
|
||||
@@ -422,13 +416,11 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
|
||||
|
||||
if (!timeout) {
|
||||
DEBUGOUT("SPI NVM Status error\n");
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
goto out;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -450,20 +442,18 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
|
||||
|
||||
DEBUGFUNC("e1000_read_nvm_spi");
|
||||
|
||||
/*
|
||||
* A check for invalid values: offset too large, too many words,
|
||||
/* 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;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
ret_val = nvm->ops.acquire(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
ret_val = e1000_ready_nvm_eeprom(hw);
|
||||
if (ret_val)
|
||||
@@ -478,8 +468,7 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
|
||||
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 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
|
||||
*/
|
||||
@@ -491,7 +480,6 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
|
||||
release:
|
||||
nvm->ops.release(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -514,20 +502,18 @@ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
|
||||
DEBUGFUNC("e1000_read_nvm_microwire");
|
||||
|
||||
/*
|
||||
* A check for invalid values: offset too large, too many words,
|
||||
/* 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;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
ret_val = nvm->ops.acquire(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
ret_val = e1000_ready_nvm_eeprom(hw);
|
||||
if (ret_val)
|
||||
@@ -539,8 +525,7 @@ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
e1000_shift_out_eec_bits(hw, (u16)(offset + i),
|
||||
nvm->address_bits);
|
||||
|
||||
/*
|
||||
* Read the data. For microwire, each word requires the
|
||||
/* Read the data. For microwire, each word requires the
|
||||
* overhead of setup and tear-down.
|
||||
*/
|
||||
data[i] = e1000_shift_in_eec_bits(hw, 16);
|
||||
@@ -550,7 +535,6 @@ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
release:
|
||||
nvm->ops.release(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -571,15 +555,13 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
|
||||
|
||||
DEBUGFUNC("e1000_read_nvm_eerd");
|
||||
|
||||
/*
|
||||
* A check for invalid values: offset too large, too many words,
|
||||
/* A check for invalid values: offset too large, too many words,
|
||||
* too many words for the offset, 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;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
for (i = 0; i < words; i++) {
|
||||
@@ -595,7 +577,6 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
|
||||
E1000_NVM_RW_REG_DATA);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -614,32 +595,32 @@ out:
|
||||
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;
|
||||
s32 ret_val = -E1000_ERR_NVM;
|
||||
u16 widx = 0;
|
||||
|
||||
DEBUGFUNC("e1000_write_nvm_spi");
|
||||
|
||||
/*
|
||||
* A check for invalid values: offset too large, too many words,
|
||||
/* 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;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
ret_val = nvm->ops.acquire(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
while (widx < words) {
|
||||
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
|
||||
|
||||
ret_val = e1000_ready_nvm_eeprom(hw);
|
||||
ret_val = nvm->ops.acquire(hw);
|
||||
if (ret_val)
|
||||
goto release;
|
||||
return ret_val;
|
||||
|
||||
ret_val = e1000_ready_nvm_eeprom(hw);
|
||||
if (ret_val) {
|
||||
nvm->ops.release(hw);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
e1000_standby_nvm(hw);
|
||||
|
||||
@@ -649,8 +630,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
|
||||
|
||||
e1000_standby_nvm(hw);
|
||||
|
||||
/*
|
||||
* Some SPI eeproms use the 8th address bit embedded in the
|
||||
/* Some SPI eeproms use the 8th address bit embedded in the
|
||||
* opcode
|
||||
*/
|
||||
if ((nvm->address_bits == 8) && (offset >= 128))
|
||||
@@ -673,13 +653,10 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
|
||||
break;
|
||||
}
|
||||
}
|
||||
msec_delay(10);
|
||||
nvm->ops.release(hw);
|
||||
}
|
||||
|
||||
msec_delay(10);
|
||||
release:
|
||||
nvm->ops.release(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -706,20 +683,18 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
|
||||
DEBUGFUNC("e1000_write_nvm_microwire");
|
||||
|
||||
/*
|
||||
* A check for invalid values: offset too large, too many words,
|
||||
/* 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;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
ret_val = nvm->ops.acquire(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
return ret_val;
|
||||
|
||||
ret_val = e1000_ready_nvm_eeprom(hw);
|
||||
if (ret_val)
|
||||
@@ -769,7 +744,6 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
release:
|
||||
nvm->ops.release(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -795,32 +769,30 @@ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
|
||||
|
||||
if (pba_num == NULL) {
|
||||
DEBUGOUT("PBA string buffer was null\n");
|
||||
ret_val = E1000_ERR_INVALID_ARGUMENT;
|
||||
goto out;
|
||||
return -E1000_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* if nvm_data is not ptr guard the PBA must be in legacy format which
|
||||
/* if nvm_data is not ptr guard the PBA must be in legacy format which
|
||||
* means pba_ptr is actually our second data word for the PBA number
|
||||
* and we can decode it into an ascii string
|
||||
*/
|
||||
if (nvm_data != NVM_PBA_PTR_GUARD) {
|
||||
DEBUGOUT("NVM PBA number is not stored as string\n");
|
||||
|
||||
/* we will need 11 characters to store the PBA */
|
||||
if (pba_num_size < 11) {
|
||||
/* make sure callers buffer is big enough to store the PBA */
|
||||
if (pba_num_size < E1000_PBANUM_LENGTH) {
|
||||
DEBUGOUT("PBA string buffer too small\n");
|
||||
return E1000_ERR_NO_SPACE;
|
||||
}
|
||||
@@ -848,25 +820,23 @@ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
|
||||
pba_num[offset] += 'A' - 0xA;
|
||||
}
|
||||
|
||||
goto out;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
if (length == 0xFFFF || length == 0) {
|
||||
DEBUGOUT("NVM PBA number section invalid length\n");
|
||||
ret_val = E1000_ERR_NVM_PBA_SECTION;
|
||||
goto out;
|
||||
return -E1000_ERR_NVM_PBA_SECTION;
|
||||
}
|
||||
/* check if pba_num buffer is big enough */
|
||||
if (pba_num_size < (((u32)length * 2) - 1)) {
|
||||
DEBUGOUT("PBA string buffer too small\n");
|
||||
ret_val = E1000_ERR_NO_SPACE;
|
||||
goto out;
|
||||
return -E1000_ERR_NO_SPACE;
|
||||
}
|
||||
|
||||
/* trim pba length from start of string */
|
||||
@@ -877,15 +847,14 @@ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
|
||||
ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
pba_num[offset * 2] = (u8)(nvm_data >> 8);
|
||||
pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
|
||||
}
|
||||
pba_num[offset * 2] = '\0';
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -907,48 +876,233 @@ s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size)
|
||||
|
||||
if (pba_num_size == NULL) {
|
||||
DEBUGOUT("PBA buffer size was null\n");
|
||||
ret_val = E1000_ERR_INVALID_ARGUMENT;
|
||||
goto out;
|
||||
return -E1000_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* if data is not ptr guard the PBA must be in legacy format */
|
||||
if (nvm_data != NVM_PBA_PTR_GUARD) {
|
||||
*pba_num_size = 11;
|
||||
goto out;
|
||||
*pba_num_size = E1000_PBANUM_LENGTH;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
if (length == 0xFFFF || length == 0) {
|
||||
DEBUGOUT("NVM PBA number section invalid length\n");
|
||||
ret_val = E1000_ERR_NVM_PBA_SECTION;
|
||||
goto out;
|
||||
return -E1000_ERR_NVM_PBA_SECTION;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert from length in u16 values to u8 chars, add 1 for NULL,
|
||||
/* Convert from length in u16 values to u8 chars, add 1 for NULL,
|
||||
* and subtract 2 because length field is included in length.
|
||||
*/
|
||||
*pba_num_size = ((u32)length * 2) - 1;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* e1000_read_pba_raw
|
||||
* @hw: pointer to the HW structure
|
||||
* @eeprom_buf: optional pointer to EEPROM image
|
||||
* @eeprom_buf_size: size of EEPROM image in words
|
||||
* @max_pba_block_size: PBA block size limit
|
||||
* @pba: pointer to output PBA structure
|
||||
*
|
||||
* Reads PBA from EEPROM image when eeprom_buf is not NULL.
|
||||
* Reads PBA from physical EEPROM device when eeprom_buf is NULL.
|
||||
*
|
||||
**/
|
||||
s32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
|
||||
u32 eeprom_buf_size, u16 max_pba_block_size,
|
||||
struct e1000_pba *pba)
|
||||
{
|
||||
s32 ret_val;
|
||||
u16 pba_block_size;
|
||||
|
||||
if (pba == NULL)
|
||||
return -E1000_ERR_PARAM;
|
||||
|
||||
if (eeprom_buf == NULL) {
|
||||
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2,
|
||||
&pba->word[0]);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
} else {
|
||||
if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
|
||||
pba->word[0] = eeprom_buf[NVM_PBA_OFFSET_0];
|
||||
pba->word[1] = eeprom_buf[NVM_PBA_OFFSET_1];
|
||||
} else {
|
||||
return -E1000_ERR_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
if (pba->word[0] == NVM_PBA_PTR_GUARD) {
|
||||
if (pba->pba_block == NULL)
|
||||
return -E1000_ERR_PARAM;
|
||||
|
||||
ret_val = e1000_get_pba_block_size(hw, eeprom_buf,
|
||||
eeprom_buf_size,
|
||||
&pba_block_size);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
if (pba_block_size > max_pba_block_size)
|
||||
return -E1000_ERR_PARAM;
|
||||
|
||||
if (eeprom_buf == NULL) {
|
||||
ret_val = e1000_read_nvm(hw, pba->word[1],
|
||||
pba_block_size,
|
||||
pba->pba_block);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
} else {
|
||||
if (eeprom_buf_size > (u32)(pba->word[1] +
|
||||
pba->pba_block[0])) {
|
||||
memcpy(pba->pba_block,
|
||||
&eeprom_buf[pba->word[1]],
|
||||
pba_block_size * sizeof(u16));
|
||||
} else {
|
||||
return -E1000_ERR_PARAM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_write_pba_raw
|
||||
* @hw: pointer to the HW structure
|
||||
* @eeprom_buf: optional pointer to EEPROM image
|
||||
* @eeprom_buf_size: size of EEPROM image in words
|
||||
* @pba: pointer to PBA structure
|
||||
*
|
||||
* Writes PBA to EEPROM image when eeprom_buf is not NULL.
|
||||
* Writes PBA to physical EEPROM device when eeprom_buf is NULL.
|
||||
*
|
||||
**/
|
||||
s32 e1000_write_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
|
||||
u32 eeprom_buf_size, struct e1000_pba *pba)
|
||||
{
|
||||
s32 ret_val;
|
||||
|
||||
if (pba == NULL)
|
||||
return -E1000_ERR_PARAM;
|
||||
|
||||
if (eeprom_buf == NULL) {
|
||||
ret_val = e1000_write_nvm(hw, NVM_PBA_OFFSET_0, 2,
|
||||
&pba->word[0]);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
} else {
|
||||
if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
|
||||
eeprom_buf[NVM_PBA_OFFSET_0] = pba->word[0];
|
||||
eeprom_buf[NVM_PBA_OFFSET_1] = pba->word[1];
|
||||
} else {
|
||||
return -E1000_ERR_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
if (pba->word[0] == NVM_PBA_PTR_GUARD) {
|
||||
if (pba->pba_block == NULL)
|
||||
return -E1000_ERR_PARAM;
|
||||
|
||||
if (eeprom_buf == NULL) {
|
||||
ret_val = e1000_write_nvm(hw, pba->word[1],
|
||||
pba->pba_block[0],
|
||||
pba->pba_block);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
} else {
|
||||
if (eeprom_buf_size > (u32)(pba->word[1] +
|
||||
pba->pba_block[0])) {
|
||||
memcpy(&eeprom_buf[pba->word[1]],
|
||||
pba->pba_block,
|
||||
pba->pba_block[0] * sizeof(u16));
|
||||
} else {
|
||||
return -E1000_ERR_PARAM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_pba_block_size
|
||||
* @hw: pointer to the HW structure
|
||||
* @eeprom_buf: optional pointer to EEPROM image
|
||||
* @eeprom_buf_size: size of EEPROM image in words
|
||||
* @pba_data_size: pointer to output variable
|
||||
*
|
||||
* Returns the size of the PBA block in words. Function operates on EEPROM
|
||||
* image if the eeprom_buf pointer is not NULL otherwise it accesses physical
|
||||
* EEPROM device.
|
||||
*
|
||||
**/
|
||||
s32 e1000_get_pba_block_size(struct e1000_hw *hw, u16 *eeprom_buf,
|
||||
u32 eeprom_buf_size, u16 *pba_block_size)
|
||||
{
|
||||
s32 ret_val;
|
||||
u16 pba_word[2];
|
||||
u16 length;
|
||||
|
||||
DEBUGFUNC("e1000_get_pba_block_size");
|
||||
|
||||
if (eeprom_buf == NULL) {
|
||||
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2, &pba_word[0]);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
} else {
|
||||
if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
|
||||
pba_word[0] = eeprom_buf[NVM_PBA_OFFSET_0];
|
||||
pba_word[1] = eeprom_buf[NVM_PBA_OFFSET_1];
|
||||
} else {
|
||||
return -E1000_ERR_PARAM;
|
||||
}
|
||||
}
|
||||
|
||||
if (pba_word[0] == NVM_PBA_PTR_GUARD) {
|
||||
if (eeprom_buf == NULL) {
|
||||
ret_val = e1000_read_nvm(hw, pba_word[1] + 0, 1,
|
||||
&length);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
} else {
|
||||
if (eeprom_buf_size > pba_word[1])
|
||||
length = eeprom_buf[pba_word[1] + 0];
|
||||
else
|
||||
return -E1000_ERR_PARAM;
|
||||
}
|
||||
|
||||
if (length == 0xFFFF || length == 0)
|
||||
return -E1000_ERR_NVM_PBA_SECTION;
|
||||
} else {
|
||||
/* PBA number in legacy format, there is no PBA Block. */
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if (pba_block_size != NULL)
|
||||
*pba_block_size = length;
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -989,7 +1143,7 @@ s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
|
||||
**/
|
||||
s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 ret_val;
|
||||
u16 checksum = 0;
|
||||
u16 i, nvm_data;
|
||||
|
||||
@@ -999,19 +1153,17 @@ s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
|
||||
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
checksum += nvm_data;
|
||||
}
|
||||
|
||||
if (checksum != (u16) NVM_SUM) {
|
||||
DEBUGOUT("NVM Checksum Invalid\n");
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
goto out;
|
||||
return -E1000_ERR_NVM;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1034,7 +1186,7 @@ s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
|
||||
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error while updating checksum.\n");
|
||||
goto out;
|
||||
return ret_val;
|
||||
}
|
||||
checksum += nvm_data;
|
||||
}
|
||||
@@ -1043,7 +1195,6 @@ s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
DEBUGOUT("NVM Write Error while updating checksum.\n");
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -1067,3 +1218,4 @@ static void e1000_reload_nvm_generic(struct e1000_hw *hw)
|
||||
E1000_WRITE_FLUSH(hw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -35,6 +35,14 @@
|
||||
#ifndef _E1000_NVM_H_
|
||||
#define _E1000_NVM_H_
|
||||
|
||||
#if !defined(NO_READ_PBA_RAW) || !defined(NO_WRITE_PBA_RAW)
|
||||
struct e1000_pba {
|
||||
u16 word[2];
|
||||
u16 *pba_block;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
void e1000_init_nvm_ops_generic(struct e1000_hw *hw);
|
||||
s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c);
|
||||
void e1000_null_nvm_generic(struct e1000_hw *hw);
|
||||
@@ -47,6 +55,13 @@ s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
|
||||
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
|
||||
u32 pba_num_size);
|
||||
s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size);
|
||||
s32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
|
||||
u32 eeprom_buf_size, u16 max_pba_block_size,
|
||||
struct e1000_pba *pba);
|
||||
s32 e1000_write_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
|
||||
u32 eeprom_buf_size, struct e1000_pba *pba);
|
||||
s32 e1000_get_pba_block_size(struct e1000_hw *hw, u16 *eeprom_buf,
|
||||
u32 eeprom_buf_size, u16 *pba_block_size);
|
||||
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);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2010, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -66,7 +66,8 @@
|
||||
#define MSGOUT(S, A, B) printf(S "\n", A, B)
|
||||
#define DEBUGFUNC(F) DEBUGOUT(F);
|
||||
#define DEBUGOUT(S) do {} while (0)
|
||||
#define DEBUGOUT1(S,A) do {} while (0)
|
||||
/* This define is needed or shared code will not build */
|
||||
#define DEBUGOUT1(S,A) if (0) printf(S,A);
|
||||
#define DEBUGOUT2(S,A,B) do {} while (0)
|
||||
#define DEBUGOUT3(S,A,B,C) do {} while (0)
|
||||
#define DEBUGOUT7(S,A,B,C,D,E,F,G) do {} while (0)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#include "e1000_api.h"
|
||||
|
||||
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
|
||||
static s32 e1000_wait_autoneg(struct e1000_hw *hw);
|
||||
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
|
||||
u16 *data, bool read, bool page_set);
|
||||
static u32 e1000_get_phy_addr_for_hv_page(u32 page);
|
||||
@@ -173,8 +173,10 @@ s32 e1000_read_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset,
|
||||
* @data: data value to write
|
||||
*
|
||||
**/
|
||||
s32 e1000_write_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset,
|
||||
u8 dev_addr, u8 data)
|
||||
s32 e1000_write_i2c_byte_null(struct e1000_hw *hw,
|
||||
u8 byte_offset,
|
||||
u8 dev_addr,
|
||||
u8 data)
|
||||
{
|
||||
DEBUGFUNC("e1000_write_i2c_byte_null");
|
||||
return E1000_SUCCESS;
|
||||
@@ -285,8 +287,7 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
return -E1000_ERR_PARAM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up Op-code, Phy Address, and register offset in the MDI
|
||||
/* Set up Op-code, Phy Address, and register offset in the MDI
|
||||
* Control register. The MAC will take care of interfacing with the
|
||||
* PHY to retrieve the desired data.
|
||||
*/
|
||||
@@ -296,8 +297,7 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_MDIC, mdic);
|
||||
|
||||
/*
|
||||
* Poll the ready bit to see if the MDI read completed
|
||||
/* Poll the ready bit to see if the MDI read completed
|
||||
* Increasing the time out as testing showed failures with
|
||||
* the lower time out
|
||||
*/
|
||||
@@ -315,10 +315,15 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
DEBUGOUT("MDI Error\n");
|
||||
return -E1000_ERR_PHY;
|
||||
}
|
||||
if (((mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT) != offset) {
|
||||
DEBUGOUT2("MDI Read offset error - requested %d, returned %d\n",
|
||||
offset,
|
||||
(mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
|
||||
return -E1000_ERR_PHY;
|
||||
}
|
||||
*data = (u16) mdic;
|
||||
|
||||
/*
|
||||
* Allow some time after each MDIC transaction to avoid
|
||||
/* Allow some time after each MDIC transaction to avoid
|
||||
* reading duplicate data in the next MDIC transaction.
|
||||
*/
|
||||
if (hw->mac.type == e1000_pch2lan)
|
||||
@@ -347,8 +352,7 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
return -E1000_ERR_PARAM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up Op-code, Phy Address, and register offset in the MDI
|
||||
/* Set up Op-code, Phy Address, and register offset in the MDI
|
||||
* Control register. The MAC will take care of interfacing with the
|
||||
* PHY to retrieve the desired data.
|
||||
*/
|
||||
@@ -359,8 +363,7 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_MDIC, mdic);
|
||||
|
||||
/*
|
||||
* Poll the ready bit to see if the MDI read completed
|
||||
/* Poll the ready bit to see if the MDI read completed
|
||||
* Increasing the time out as testing showed failures with
|
||||
* the lower time out
|
||||
*/
|
||||
@@ -378,9 +381,14 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
DEBUGOUT("MDI Error\n");
|
||||
return -E1000_ERR_PHY;
|
||||
}
|
||||
if (((mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT) != offset) {
|
||||
DEBUGOUT2("MDI Write offset error - requested %d, returned %d\n",
|
||||
offset,
|
||||
(mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
|
||||
return -E1000_ERR_PHY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow some time after each MDIC transaction to avoid
|
||||
/* Allow some time after each MDIC transaction to avoid
|
||||
* reading duplicate data in the next MDIC transaction.
|
||||
*/
|
||||
if (hw->mac.type == e1000_pch2lan)
|
||||
@@ -405,8 +413,7 @@ s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
|
||||
DEBUGFUNC("e1000_read_phy_reg_i2c");
|
||||
|
||||
/*
|
||||
* Set up Op-code, Phy Address, and register address in the I2CCMD
|
||||
/* Set up Op-code, Phy Address, and register address in the I2CCMD
|
||||
* register. The MAC will take care of interfacing with the
|
||||
* PHY to retrieve the desired data.
|
||||
*/
|
||||
@@ -464,8 +471,7 @@ s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
/* Swap the data bytes for the I2C interface */
|
||||
phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
|
||||
|
||||
/*
|
||||
* Set up Op-code, Phy Address, and register address in the I2CCMD
|
||||
/* Set up Op-code, Phy Address, and register address in the I2CCMD
|
||||
* register. The MAC will take care of interfacing with the
|
||||
* PHY to retrieve the desired data.
|
||||
*/
|
||||
@@ -521,8 +527,7 @@ s32 e1000_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data)
|
||||
return -E1000_ERR_PHY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up Op-code, EEPROM Address,in the I2CCMD
|
||||
/* Set up Op-code, EEPROM Address,in the I2CCMD
|
||||
* register. The MAC will take care of interfacing with the
|
||||
* EEPROM to retrieve the desired data.
|
||||
*/
|
||||
@@ -576,14 +581,12 @@ s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data)
|
||||
DEBUGOUT("I2CCMD command address exceeds upper limit\n");
|
||||
return -E1000_ERR_PHY;
|
||||
}
|
||||
/*
|
||||
* The programming interface is 16 bits wide
|
||||
/* The programming interface is 16 bits wide
|
||||
* so we need to read the whole word first
|
||||
* then update appropriate byte lane and write
|
||||
* the updated word back.
|
||||
*/
|
||||
/*
|
||||
* Set up Op-code, EEPROM Address,in the I2CCMD
|
||||
/* Set up Op-code, EEPROM Address,in the I2CCMD
|
||||
* register. The MAC will take care of interfacing
|
||||
* with an EEPROM to write the data given.
|
||||
*/
|
||||
@@ -593,8 +596,7 @@ s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data)
|
||||
E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
|
||||
for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
|
||||
usec_delay(50);
|
||||
/*
|
||||
* Poll the ready bit to see if lastly
|
||||
/* Poll the ready bit to see if lastly
|
||||
* launched I2C operation completed
|
||||
*/
|
||||
i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD);
|
||||
@@ -602,8 +604,7 @@ s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data)
|
||||
/* Check if this is READ or WRITE phase */
|
||||
if ((i2ccmd & E1000_I2CCMD_OPCODE_READ) ==
|
||||
E1000_I2CCMD_OPCODE_READ) {
|
||||
/*
|
||||
* Write the selected byte
|
||||
/* Write the selected byte
|
||||
* lane and update whole word
|
||||
*/
|
||||
data_local = i2ccmd & 0xFF00;
|
||||
@@ -1053,12 +1054,16 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable CRS on Tx. This must be set for half-duplex operation. */
|
||||
/* Enable CRS on Tx. This must be set for half-duplex operation.
|
||||
* Not required on some PHYs.
|
||||
*/
|
||||
ret_val = hw->phy.ops.read_reg(hw, I82577_CFG_REG, &phy_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
|
||||
if ((hw->phy.type != e1000_phy_82579) &&
|
||||
(hw->phy.type != e1000_phy_i217))
|
||||
phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
|
||||
|
||||
/* Enable downshift */
|
||||
phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
|
||||
@@ -1072,8 +1077,7 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
phy_data &= ~I82577_PHY_CTRL2_MDIX_CFG_MASK;
|
||||
/*
|
||||
* Options:
|
||||
/* Options:
|
||||
* 0 - Auto (default)
|
||||
* 1 - MDI mode
|
||||
* 2 - MDI-X mode
|
||||
@@ -1121,8 +1125,7 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
|
||||
if (phy->type != e1000_phy_bm)
|
||||
phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
|
||||
|
||||
/*
|
||||
* Options:
|
||||
/* Options:
|
||||
* MDI/MDI-X = 0 (default)
|
||||
* 0 - Auto for all speeds
|
||||
* 1 - MDI mode
|
||||
@@ -1147,8 +1150,7 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Options:
|
||||
/* Options:
|
||||
* disable_polarity_correction = 0 (default)
|
||||
* Automatic Correction for Reversed Cable Polarity
|
||||
* 0 - Disabled
|
||||
@@ -1185,8 +1187,7 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
|
||||
if ((phy->type == e1000_phy_m88) &&
|
||||
(phy->revision < E1000_REVISION_4) &&
|
||||
(phy->id != BME1000_E_PHY_ID_R2)) {
|
||||
/*
|
||||
* Force TX_CLK in the Extended PHY Specific Control Register
|
||||
/* Force TX_CLK in the Extended PHY Specific Control Register
|
||||
* to 25MHz clock.
|
||||
*/
|
||||
ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
|
||||
@@ -1278,8 +1279,7 @@ s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* Options:
|
||||
/* Options:
|
||||
* MDI/MDI-X = 0 (default)
|
||||
* 0 - Auto for all speeds
|
||||
* 1 - MDI mode
|
||||
@@ -1307,8 +1307,7 @@ s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Options:
|
||||
/* Options:
|
||||
* disable_polarity_correction = 0 (default)
|
||||
* Automatic Correction for Reversed Cable Polarity
|
||||
* 0 - Disabled
|
||||
@@ -1359,14 +1358,12 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait 100ms for MAC to configure PHY from NVM settings, to avoid
|
||||
/* Wait 100ms for MAC to configure PHY from NVM settings, to avoid
|
||||
* timeout issues when LFS is enabled.
|
||||
*/
|
||||
msec_delay(100);
|
||||
|
||||
/*
|
||||
* The NVM settings will configure LPLU in D3 for
|
||||
/* The NVM settings will configure LPLU in D3 for
|
||||
* non-IGP1 PHYs.
|
||||
*/
|
||||
if (phy->type == e1000_phy_igp) {
|
||||
@@ -1411,8 +1408,7 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw)
|
||||
|
||||
/* set auto-master slave resolution settings */
|
||||
if (hw->mac.autoneg) {
|
||||
/*
|
||||
* when autonegotiation advertisement is only 1000Mbps then we
|
||||
/* when autonegotiation advertisement is only 1000Mbps then we
|
||||
* should disable SmartSpeed and enable Auto MasterSlave
|
||||
* resolution as hardware default.
|
||||
*/
|
||||
@@ -1481,16 +1477,14 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to parse both autoneg_advertised and fc and set up
|
||||
/* Need to parse both autoneg_advertised and fc and set up
|
||||
* the appropriate PHY registers. First we will parse for
|
||||
* autoneg_advertised software override. Since we can advertise
|
||||
* a plethora of combinations, we need to check each bit
|
||||
* individually.
|
||||
*/
|
||||
|
||||
/*
|
||||
* First we clear all the 10/100 mb speed bits in the Auto-Neg
|
||||
/* First we clear all the 10/100 mb speed bits in the Auto-Neg
|
||||
* Advertisement Register (Address 4) and the 1000 mb speed bits in
|
||||
* the 1000Base-T Control Register (Address 9).
|
||||
*/
|
||||
@@ -1536,8 +1530,7 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
|
||||
mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for a software override of the flow control settings, and
|
||||
/* Check for a software override of the flow control settings, and
|
||||
* setup the PHY advertisement registers accordingly. If
|
||||
* auto-negotiation is enabled, then software will have to set the
|
||||
* "PAUSE" bits to the correct value in the Auto-Negotiation
|
||||
@@ -1556,15 +1549,13 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
|
||||
*/
|
||||
switch (hw->fc.current_mode) {
|
||||
case e1000_fc_none:
|
||||
/*
|
||||
* Flow control (Rx & Tx) is completely disabled by a
|
||||
/* Flow control (Rx & Tx) is completely disabled by a
|
||||
* software over-ride.
|
||||
*/
|
||||
mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
|
||||
break;
|
||||
case e1000_fc_rx_pause:
|
||||
/*
|
||||
* Rx Flow control is enabled, and Tx Flow control is
|
||||
/* Rx Flow control is enabled, and Tx Flow control is
|
||||
* disabled, by a software over-ride.
|
||||
*
|
||||
* Since there really isn't a way to advertise that we are
|
||||
@@ -1576,16 +1567,14 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
|
||||
mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
|
||||
break;
|
||||
case e1000_fc_tx_pause:
|
||||
/*
|
||||
* Tx Flow control is enabled, and Rx Flow control is
|
||||
/* Tx Flow control is enabled, and Rx Flow control is
|
||||
* disabled, by a software over-ride.
|
||||
*/
|
||||
mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
|
||||
mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
|
||||
break;
|
||||
case e1000_fc_full:
|
||||
/*
|
||||
* Flow control (both Rx and Tx) is enabled by a software
|
||||
/* Flow control (both Rx and Tx) is enabled by a software
|
||||
* over-ride.
|
||||
*/
|
||||
mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
|
||||
@@ -1625,14 +1614,12 @@ s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_copper_link_autoneg");
|
||||
|
||||
/*
|
||||
* Perform some bounds checking on the autoneg advertisement
|
||||
/* Perform some bounds checking on the autoneg advertisement
|
||||
* parameter.
|
||||
*/
|
||||
phy->autoneg_advertised &= phy->autoneg_mask;
|
||||
|
||||
/*
|
||||
* If autoneg_advertised is zero, we assume it was not defaulted
|
||||
/* If autoneg_advertised is zero, we assume it was not defaulted
|
||||
* by the calling code so we set to advertise full capability.
|
||||
*/
|
||||
if (!phy->autoneg_advertised)
|
||||
@@ -1646,8 +1633,7 @@ s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
|
||||
}
|
||||
DEBUGOUT("Restarting Auto-Neg\n");
|
||||
|
||||
/*
|
||||
* Restart auto-negotiation by setting the Auto Neg Enable bit and
|
||||
/* Restart auto-negotiation by setting the Auto Neg Enable bit and
|
||||
* the Auto Neg Restart bit in the PHY control register.
|
||||
*/
|
||||
ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
|
||||
@@ -1659,12 +1645,11 @@ s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* Does the user want to wait for Auto-Neg to complete here, or
|
||||
/* Does the user want to wait for Auto-Neg to complete here, or
|
||||
* check at a later time (for example, callback routine).
|
||||
*/
|
||||
if (phy->autoneg_wait_to_complete) {
|
||||
ret_val = hw->mac.ops.wait_autoneg(hw);
|
||||
ret_val = e1000_wait_autoneg(hw);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("Error while waiting for autoneg to complete\n");
|
||||
return ret_val;
|
||||
@@ -1693,16 +1678,14 @@ s32 e1000_setup_copper_link_generic(struct e1000_hw *hw)
|
||||
DEBUGFUNC("e1000_setup_copper_link_generic");
|
||||
|
||||
if (hw->mac.autoneg) {
|
||||
/*
|
||||
* Setup autoneg and flow control advertisement and perform
|
||||
/* Setup autoneg and flow control advertisement and perform
|
||||
* autonegotiation.
|
||||
*/
|
||||
ret_val = e1000_copper_link_autoneg(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
} else {
|
||||
/*
|
||||
* PHY will be set to 10H, 10F, 100H or 100F
|
||||
/* PHY will be set to 10H, 10F, 100H or 100F
|
||||
* depending on user settings.
|
||||
*/
|
||||
DEBUGOUT("Forcing Speed and Duplex\n");
|
||||
@@ -1713,8 +1696,7 @@ s32 e1000_setup_copper_link_generic(struct e1000_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check link status. Wait up to 100 microseconds for link to become
|
||||
/* Check link status. Wait up to 100 microseconds for link to become
|
||||
* valid.
|
||||
*/
|
||||
ret_val = e1000_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
|
||||
@@ -1760,8 +1742,7 @@ s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* Clear Auto-Crossover to force MDI manually. IGP requires MDI
|
||||
/* Clear Auto-Crossover to force MDI manually. IGP requires MDI
|
||||
* forced whenever speed and duplex are forced.
|
||||
*/
|
||||
ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
|
||||
@@ -1817,18 +1798,22 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_phy_force_speed_duplex_m88");
|
||||
|
||||
/*
|
||||
* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
|
||||
* forced whenever speed and duplex are forced.
|
||||
*/
|
||||
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
/* I210 and I211 devices support Auto-Crossover in forced operation. */
|
||||
if (phy->type != e1000_phy_i210) {
|
||||
/* Clear Auto-Crossover to force MDI manually. M88E1000
|
||||
* requires MDI forced whenever speed and duplex are forced.
|
||||
*/
|
||||
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL,
|
||||
&phy_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
|
||||
ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
|
||||
ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
|
||||
phy_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data);
|
||||
|
||||
@@ -1874,8 +1859,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
|
||||
if (!reset_dsp) {
|
||||
DEBUGOUT("Link taking longer than expected.\n");
|
||||
} else {
|
||||
/*
|
||||
* We didn't get link.
|
||||
/* We didn't get link.
|
||||
* Reset the DSP and cross our fingers.
|
||||
*/
|
||||
ret_val = phy->ops.write_reg(hw,
|
||||
@@ -1909,8 +1893,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* Resetting the phy means we need to re-force TX_CLK in the
|
||||
/* Resetting the phy means we need to re-force TX_CLK in the
|
||||
* Extended PHY Specific Control Register to 25MHz clock from
|
||||
* the reset value of 2.5MHz.
|
||||
*/
|
||||
@@ -1919,8 +1902,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* In addition, we must re-enable CRS on Tx for both half and full
|
||||
/* In addition, we must re-enable CRS on Tx for both half and full
|
||||
* duplex.
|
||||
*/
|
||||
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
|
||||
@@ -2045,11 +2027,10 @@ void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
|
||||
if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
|
||||
ctrl |= E1000_CTRL_SPD_100;
|
||||
*phy_ctrl |= MII_CR_SPEED_100;
|
||||
*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10);
|
||||
*phy_ctrl &= ~MII_CR_SPEED_1000;
|
||||
DEBUGOUT("Forcing 100mb\n");
|
||||
} else {
|
||||
ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
|
||||
*phy_ctrl |= MII_CR_SPEED_10;
|
||||
*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
|
||||
DEBUGOUT("Forcing 10mb\n");
|
||||
}
|
||||
@@ -2094,8 +2075,7 @@ s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active)
|
||||
data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
/*
|
||||
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
|
||||
/* LPLU and SmartSpeed are mutually exclusive. LPLU is used
|
||||
* during Dx states where the power conservation is most
|
||||
* important. During driver activity we should enable
|
||||
* SmartSpeed, so performance is maintained.
|
||||
@@ -2238,8 +2218,7 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_check_polarity_igp");
|
||||
|
||||
/*
|
||||
* Polarity is determined based on the speed of
|
||||
/* Polarity is determined based on the speed of
|
||||
* our connection.
|
||||
*/
|
||||
ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
|
||||
@@ -2251,8 +2230,7 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw)
|
||||
offset = IGP01E1000_PHY_PCS_INIT_REG;
|
||||
mask = IGP01E1000_PHY_POLARITY_MASK;
|
||||
} else {
|
||||
/*
|
||||
* This really only applies to 10Mbps since
|
||||
/* This really only applies to 10Mbps since
|
||||
* there is no polarity for 100Mbps (always 0).
|
||||
*/
|
||||
offset = IGP01E1000_PHY_PORT_STATUS;
|
||||
@@ -2283,8 +2261,7 @@ s32 e1000_check_polarity_ife(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_check_polarity_ife");
|
||||
|
||||
/*
|
||||
* Polarity is determined based on the reversal feature being enabled.
|
||||
/* Polarity is determined based on the reversal feature being enabled.
|
||||
*/
|
||||
if (phy->polarity_correction) {
|
||||
offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
|
||||
@@ -2305,18 +2282,18 @@ s32 e1000_check_polarity_ife(struct e1000_hw *hw)
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_wait_autoneg_generic - Wait for auto-neg completion
|
||||
* e1000_wait_autoneg - Wait for auto-neg completion
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Waits for auto-negotiation to complete or for the auto-negotiation time
|
||||
* limit to expire, which ever happens first.
|
||||
**/
|
||||
s32 e1000_wait_autoneg_generic(struct e1000_hw *hw)
|
||||
static s32 e1000_wait_autoneg(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 i, phy_status;
|
||||
|
||||
DEBUGFUNC("e1000_wait_autoneg_generic");
|
||||
DEBUGFUNC("e1000_wait_autoneg");
|
||||
|
||||
if (!hw->phy.ops.read_reg)
|
||||
return E1000_SUCCESS;
|
||||
@@ -2334,8 +2311,7 @@ s32 e1000_wait_autoneg_generic(struct e1000_hw *hw)
|
||||
msec_delay(100);
|
||||
}
|
||||
|
||||
/*
|
||||
* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
|
||||
/* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
|
||||
* has completed.
|
||||
*/
|
||||
return ret_val;
|
||||
@@ -2362,15 +2338,13 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
|
||||
return E1000_SUCCESS;
|
||||
|
||||
for (i = 0; i < iterations; i++) {
|
||||
/*
|
||||
* Some PHYs require the PHY_STATUS register to be read
|
||||
/* Some PHYs require the PHY_STATUS register to be read
|
||||
* twice due to the link bit being sticky. No harm doing
|
||||
* it across the board.
|
||||
*/
|
||||
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
|
||||
if (ret_val)
|
||||
/*
|
||||
* If the first read fails, another entity may have
|
||||
/* If the first read fails, another entity may have
|
||||
* ownership of the resources, wait and try again to
|
||||
* see if they have relinquished the resources yet.
|
||||
*/
|
||||
@@ -2436,7 +2410,8 @@ s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 phy_data, phy_data2, index, default_page, is_cm;
|
||||
u16 phy_data, phy_data2, is_cm;
|
||||
u16 index, default_page;
|
||||
|
||||
DEBUGFUNC("e1000_get_cable_length_m88_gen2");
|
||||
|
||||
@@ -2574,8 +2549,7 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* Getting bits 15:9, which represent the combination of
|
||||
/* Getting bits 15:9, which represent the combination of
|
||||
* coarse and fine gain values. The result is a number
|
||||
* that can be put into the lookup table to obtain the
|
||||
* approximate cable length.
|
||||
@@ -2961,15 +2935,13 @@ s32 e1000_phy_init_script_igp3(struct e1000_hw *hw)
|
||||
hw->phy.ops.write_reg(hw, 0x1796, 0x0008);
|
||||
/* Change cg_icount + enable integbp for channels BCD */
|
||||
hw->phy.ops.write_reg(hw, 0x1798, 0xD008);
|
||||
/*
|
||||
* Change cg_icount + enable integbp + change prop_factor_master
|
||||
/* Change cg_icount + enable integbp + change prop_factor_master
|
||||
* to 8 for channel A
|
||||
*/
|
||||
hw->phy.ops.write_reg(hw, 0x1898, 0xD918);
|
||||
/* Disable AHT in Slave mode on channel A */
|
||||
hw->phy.ops.write_reg(hw, 0x187A, 0x0800);
|
||||
/*
|
||||
* Enable LPLU and disable AN to 1000 in non-D0a states,
|
||||
/* Enable LPLU and disable AN to 1000 in non-D0a states,
|
||||
* Enable SPD+B2B
|
||||
*/
|
||||
hw->phy.ops.write_reg(hw, 0x0019, 0x008D);
|
||||
@@ -3030,6 +3002,9 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
|
||||
case I82579_E_PHY_ID:
|
||||
phy_type = e1000_phy_82579;
|
||||
break;
|
||||
case I217_E_PHY_ID:
|
||||
phy_type = e1000_phy_i217;
|
||||
break;
|
||||
case I82580_I_PHY_ID:
|
||||
phy_type = e1000_phy_82580;
|
||||
break;
|
||||
@@ -3067,8 +3042,7 @@ s32 e1000_determine_phy_address(struct e1000_hw *hw)
|
||||
e1000_get_phy_id(hw);
|
||||
phy_type = e1000_get_phy_type_from_id(hw->phy.id);
|
||||
|
||||
/*
|
||||
* If phy_type is valid, break - we found our
|
||||
/* If phy_type is valid, break - we found our
|
||||
* PHY address
|
||||
*/
|
||||
if (phy_type != e1000_phy_unknown)
|
||||
@@ -3130,8 +3104,7 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
if (offset > MAX_PHY_MULTI_PAGE_REG) {
|
||||
u32 page_shift, page_select;
|
||||
|
||||
/*
|
||||
* Page select is register 31 for phy address 1 and 22 for
|
||||
/* Page select is register 31 for phy address 1 and 22 for
|
||||
* phy address 2 and 3. Page select is shifted only for
|
||||
* phy address 1.
|
||||
*/
|
||||
@@ -3191,8 +3164,7 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
if (offset > MAX_PHY_MULTI_PAGE_REG) {
|
||||
u32 page_shift, page_select;
|
||||
|
||||
/*
|
||||
* Page select is register 31 for phy address 1 and 22 for
|
||||
/* Page select is register 31 for phy address 1 and 22 for
|
||||
* phy address 2 and 3. Page select is shifted only for
|
||||
* phy address 1.
|
||||
*/
|
||||
@@ -3249,7 +3221,6 @@ s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
hw->phy.addr = 1;
|
||||
|
||||
if (offset > MAX_PHY_MULTI_PAGE_REG) {
|
||||
|
||||
/* Page is shifted left, PHY expects (page x 32) */
|
||||
ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
|
||||
page);
|
||||
@@ -3346,8 +3317,7 @@ s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable both PHY wakeup mode and Wakeup register page writes.
|
||||
/* Enable both PHY wakeup mode and Wakeup register page writes.
|
||||
* Prevent a power state change by disabling ME and Host PHY wakeup.
|
||||
*/
|
||||
temp = *phy_reg;
|
||||
@@ -3361,8 +3331,7 @@ s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Select Host Wakeup Registers page - caller now able to write
|
||||
/* Select Host Wakeup Registers page - caller now able to write
|
||||
* registers on the Wakeup registers page
|
||||
*/
|
||||
return e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT));
|
||||
@@ -3381,7 +3350,7 @@ s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
|
||||
**/
|
||||
s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_disable_phy_wakeup_reg_access_bm");
|
||||
|
||||
@@ -3434,6 +3403,7 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
|
||||
{
|
||||
s32 ret_val;
|
||||
u16 reg = BM_PHY_REG_NUM(offset);
|
||||
u16 page = BM_PHY_REG_PAGE(offset);
|
||||
u16 phy_reg = 0;
|
||||
|
||||
DEBUGFUNC("e1000_access_phy_wakeup_reg_bm");
|
||||
@@ -3687,8 +3657,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
|
||||
if (page == HV_INTC_FC_PAGE_START)
|
||||
page = 0;
|
||||
|
||||
/*
|
||||
* Workaround MDIO accesses being disabled after entering IEEE
|
||||
/* Workaround MDIO accesses being disabled after entering IEEE
|
||||
* Power Down (when bit 11 of the PHY Control register is set)
|
||||
*/
|
||||
if ((hw->phy.type == e1000_phy_82578) &&
|
||||
@@ -3801,8 +3770,8 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
|
||||
u16 *data, bool read)
|
||||
{
|
||||
s32 ret_val;
|
||||
u32 addr_reg = 0;
|
||||
u32 data_reg = 0;
|
||||
u32 addr_reg;
|
||||
u32 data_reg;
|
||||
|
||||
DEBUGFUNC("e1000_access_phy_debug_regs_hv");
|
||||
|
||||
@@ -3875,8 +3844,8 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
|
||||
|
||||
/* flush the packets in the fifo buffer */
|
||||
ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL,
|
||||
HV_MUX_DATA_CTRL_GEN_TO_MAC |
|
||||
HV_MUX_DATA_CTRL_FORCE_SPEED);
|
||||
(HV_MUX_DATA_CTRL_GEN_TO_MAC |
|
||||
HV_MUX_DATA_CTRL_FORCE_SPEED));
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
@@ -4044,7 +4013,7 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
|
||||
I82577_DSTATUS_CABLE_LENGTH_SHIFT;
|
||||
|
||||
if (length == E1000_CABLE_LENGTH_UNDEFINED)
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
return -E1000_ERR_PHY;
|
||||
|
||||
phy->cable_length = length;
|
||||
|
||||
@@ -4113,3 +4082,4 @@ release:
|
||||
hw->phy.ops.release(hw);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -78,13 +78,11 @@ s32 e1000_read_phy_reg_igp_locked(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, bool 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_kmrn_reg_locked(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_igp_locked(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, bool *success);
|
||||
s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
|
||||
@@ -127,7 +125,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
#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 BM_PHY_PAGE_SELECT 22 /* Page Select for BM */
|
||||
@@ -147,7 +144,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
|
||||
/* BM/HV Specific Registers */
|
||||
#define BM_PORT_CTRL_PAGE 769
|
||||
#define BM_PCIE_PAGE 770
|
||||
#define BM_WUC_PAGE 800
|
||||
#define BM_WUC_ADDRESS_OPCODE 0x11
|
||||
#define BM_WUC_DATA_OPCODE 0x12
|
||||
@@ -188,7 +184,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
#define I82577_PHY_STATUS2_MDIX 0x0800
|
||||
#define I82577_PHY_STATUS2_SPEED_MASK 0x0300
|
||||
#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
|
||||
#define I82577_PHY_STATUS2_SPEED_100MBPS 0x0100
|
||||
|
||||
/* I82577 PHY Control 2 */
|
||||
#define I82577_PHY_CTRL2_MANUAL_MDIX 0x0200
|
||||
@@ -204,14 +199,13 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */
|
||||
#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */
|
||||
#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */
|
||||
#define E1000_82580_PM_GO_LINKD 0x0020 /* Go Link Disconnect */
|
||||
|
||||
/* BM PHY Copper Specific Control 1 */
|
||||
#define BM_CS_CTRL1 16
|
||||
#define BM_CS_CTRL1_ENERGY_DETECT 0x0300 /* Enable Energy Detect */
|
||||
|
||||
/* BM PHY Copper Specific Status */
|
||||
#define BM_CS_STATUS 17
|
||||
#define BM_CS_STATUS_ENERGY_DETECT 0x0010 /* Energy Detect Status */
|
||||
#define BM_CS_STATUS_LINK_UP 0x0400
|
||||
#define BM_CS_STATUS_RESOLVED 0x0800
|
||||
#define BM_CS_STATUS_SPEED_MASK 0xC000
|
||||
@@ -257,9 +251,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
#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
|
||||
@@ -272,7 +263,7 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
#define E1000_KMRNCTRLSTA_IBIST_DISABLE 0x0200 /* Kumeran IBIST Disable */
|
||||
#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
|
||||
#define E1000_KMRNCTRLSTA_K1_CONFIG 0x7
|
||||
#define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002
|
||||
#define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 /* enable K1 */
|
||||
#define E1000_KMRNCTRLSTA_HD_CTRL 0x10 /* Kumeran HD Control */
|
||||
|
||||
#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
|
||||
@@ -286,7 +277,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
/* 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -55,9 +55,11 @@
|
||||
#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_FEXT 0x0002C /* Future Extended - RW */
|
||||
#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
|
||||
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
|
||||
#define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */
|
||||
#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
|
||||
#define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */
|
||||
#define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - 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 */
|
||||
@@ -70,6 +72,7 @@
|
||||
#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */
|
||||
#define E1000_SVCR 0x000F0
|
||||
#define E1000_SVT 0x000F4
|
||||
#define E1000_LPIC 0x000FC /* Low Power IDLE control */
|
||||
#define E1000_RCTL 0x00100 /* Rx Control - RW */
|
||||
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
|
||||
#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
|
||||
@@ -97,6 +100,7 @@
|
||||
#define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */
|
||||
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
|
||||
#define E1000_PBS 0x01008 /* Packet Buffer Size */
|
||||
#define E1000_PBECCSTS 0x0100C /* Packet Buffer ECC Status - RW */
|
||||
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
|
||||
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
|
||||
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
|
||||
@@ -129,7 +133,11 @@
|
||||
#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_RDFPCQ(_n) (0x02430 + (0x4 * (_n)))
|
||||
#define E1000_RDFH 0x02410 /* Rx Data FIFO Head - RW */
|
||||
#define E1000_RDFT 0x02418 /* Rx Data FIFO Tail - RW */
|
||||
#define E1000_RDFHS 0x02420 /* Rx Data FIFO Head Saved - RW */
|
||||
#define E1000_RDFTS 0x02428 /* Rx Data FIFO Tail Saved - RW */
|
||||
#define E1000_RDFPC 0x02430 /* Rx Data FIFO Packet Count - RW */
|
||||
#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */
|
||||
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
|
||||
/* Split and Replication Rx Control - RW */
|
||||
@@ -200,8 +208,7 @@
|
||||
/* Queues packet buffer size masks where _n can be 0-3 and _s 0-63 [kB] */
|
||||
#define E1000_I210_TXPBS_SIZE(_n, _s) ((_s) << (6 * _n))
|
||||
|
||||
/*
|
||||
* Convenience macros
|
||||
/* Convenience macros
|
||||
*
|
||||
* Note: "_n" is the queue number of the register to be written to.
|
||||
*
|
||||
@@ -413,8 +420,7 @@
|
||||
#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n)))
|
||||
#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* Rx SAs - RW */
|
||||
#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* Rx SAs - RW */
|
||||
/*
|
||||
* LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
|
||||
/* LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
|
||||
* key - RW.
|
||||
*/
|
||||
#define E1000_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m)))
|
||||
@@ -454,7 +460,6 @@
|
||||
#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 Pg - RW */
|
||||
#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Pkt Cnt - 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*/
|
||||
@@ -489,7 +494,6 @@
|
||||
|
||||
|
||||
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
|
||||
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
|
||||
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
|
||||
/* Management Decision Filters */
|
||||
#define E1000_MDEF(_n) (0x05890 + (4 * (_n)))
|
||||
@@ -522,15 +526,6 @@
|
||||
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate INTR Ext*/
|
||||
#define E1000_IMIRVP 0x05AC0 /* Immediate INT Rx VLAN Priority -RW */
|
||||
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Alloc Reg -RW */
|
||||
/* MSI-X Table entry addr low reg - RW */
|
||||
#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10))
|
||||
/* MSI-X Table entry addr upper reg - RW */
|
||||
#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10))
|
||||
/* MSI-X Table entry message reg - RW */
|
||||
#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10))
|
||||
/* MSI-X Table entry vector ctrl reg - RW */
|
||||
#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10))
|
||||
#define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */
|
||||
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */
|
||||
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */
|
||||
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
|
||||
@@ -580,8 +575,12 @@
|
||||
#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
|
||||
#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
|
||||
#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
|
||||
#define E1000_TIMADJL 0x0B60C /* Time sync time adjustment offset Low - RW */
|
||||
#define E1000_TIMADJH 0x0B610 /* Time sync time adjustment offset High - RW */
|
||||
#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
|
||||
#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */
|
||||
#define E1000_TSICR 0x0B66C /* Interrupt Cause Register */
|
||||
#define E1000_TSIM 0x0B674 /* Interrupt Mask Register */
|
||||
#define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - RW */
|
||||
#define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */
|
||||
|
||||
@@ -671,8 +670,6 @@
|
||||
#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */
|
||||
#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */
|
||||
|
||||
#define E1000_LTRMINV 0x5BB0 /* LTR Minimum Value */
|
||||
#define E1000_LTRMAXV 0x5BB4 /* LTR Maximum Value */
|
||||
#define E1000_DOBFFCTL 0x3F24 /* DMA OBFF Control Register */
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,10 +32,11 @@
|
||||
******************************************************************************/
|
||||
/*$FreeBSD$*/
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
#include "opt_device_polling.h"
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
#include "opt_device_polling.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -431,6 +431,7 @@ struct adapter {
|
||||
struct em_int_delay_info tx_abs_int_delay;
|
||||
struct em_int_delay_info rx_int_delay;
|
||||
struct em_int_delay_info rx_abs_int_delay;
|
||||
struct em_int_delay_info tx_itr;
|
||||
|
||||
/* Misc stats maintained by the driver */
|
||||
unsigned long dropped_pkts;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
Copyright (c) 2001-2013, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -33,16 +33,17 @@
|
||||
/*$FreeBSD$*/
|
||||
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
#include "opt_device_polling.h"
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
#include "opt_device_polling.h"
|
||||
#include "opt_altq.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
#include <sys/buf_ring.h>
|
||||
#endif
|
||||
#include <sys/bus.h>
|
||||
@@ -100,7 +101,7 @@ int igb_display_debug_stats = 0;
|
||||
/*********************************************************************
|
||||
* Driver version:
|
||||
*********************************************************************/
|
||||
char igb_driver_version[] = "version - 2.3.4";
|
||||
char igb_driver_version[] = "version - 2.3.10";
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
@@ -179,10 +180,9 @@ static int igb_detach(device_t);
|
||||
static int igb_shutdown(device_t);
|
||||
static int igb_suspend(device_t);
|
||||
static int igb_resume(device_t);
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
static int igb_mq_start(struct ifnet *, struct mbuf *);
|
||||
static int igb_mq_start_locked(struct ifnet *,
|
||||
struct tx_ring *, struct mbuf *);
|
||||
static int igb_mq_start_locked(struct ifnet *, struct tx_ring *);
|
||||
static void igb_qflush(struct ifnet *);
|
||||
static void igb_deferred_mq_start(void *, int);
|
||||
#else
|
||||
@@ -295,7 +295,7 @@ static device_method_t igb_methods[] = {
|
||||
DEVMETHOD(device_shutdown, igb_shutdown),
|
||||
DEVMETHOD(device_suspend, igb_suspend),
|
||||
DEVMETHOD(device_resume, igb_resume),
|
||||
{0, 0}
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t igb_driver = {
|
||||
@@ -351,6 +351,16 @@ TUNABLE_INT("hw.igb.max_interrupt_rate", &igb_max_interrupt_rate);
|
||||
SYSCTL_INT(_hw_igb, OID_AUTO, max_interrupt_rate, CTLFLAG_RDTUN,
|
||||
&igb_max_interrupt_rate, 0, "Maximum interrupts per second");
|
||||
|
||||
#if __FreeBSD_version >= 800000
|
||||
/*
|
||||
** Tuneable number of buffers in the buf-ring (drbr_xxx)
|
||||
*/
|
||||
static int igb_buf_ring_size = IGB_BR_SIZE;
|
||||
TUNABLE_INT("hw.igb.buf_ring_size", &igb_buf_ring_size);
|
||||
SYSCTL_INT(_hw_igb, OID_AUTO, buf_ring_size, CTLFLAG_RDTUN,
|
||||
&igb_buf_ring_size, 0, "Size of the bufring");
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Header split causes the packet header to
|
||||
** be dma'd to a seperate mbuf from the payload.
|
||||
@@ -365,8 +375,9 @@ SYSCTL_INT(_hw_igb, OID_AUTO, header_split, CTLFLAG_RDTUN, &igb_header_split, 0,
|
||||
"Enable receive mbuf header split");
|
||||
|
||||
/*
|
||||
** This will autoconfigure based on
|
||||
** the number of CPUs if left at 0.
|
||||
** This will autoconfigure based on the
|
||||
** number of CPUs and max supported
|
||||
** MSIX messages if left at 0.
|
||||
*/
|
||||
static int igb_num_queues = 0;
|
||||
TUNABLE_INT("hw.igb.num_queues", &igb_num_queues);
|
||||
@@ -841,11 +852,11 @@ igb_resume(device_t dev)
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING) && adapter->link_active) {
|
||||
for (int i = 0; i < adapter->num_queues; i++, txr++) {
|
||||
IGB_TX_LOCK(txr);
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
/* Process the stack queue only if not depleted */
|
||||
if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) &&
|
||||
!drbr_empty(ifp, txr->br))
|
||||
igb_mq_start_locked(ifp, txr, NULL);
|
||||
igb_mq_start_locked(ifp, txr);
|
||||
#else
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
igb_start_locked(txr, ifp);
|
||||
@@ -859,7 +870,7 @@ igb_resume(device_t dev)
|
||||
}
|
||||
|
||||
|
||||
#if __FreeBSD_version < 800000
|
||||
#ifdef IGB_LEGACY_TX
|
||||
|
||||
/*********************************************************************
|
||||
* Transmit entry point
|
||||
@@ -937,10 +948,11 @@ igb_start(struct ifnet *ifp)
|
||||
return;
|
||||
}
|
||||
|
||||
#else /* __FreeBSD_version >= 800000 */
|
||||
#else /* ~IGB_LEGACY_TX */
|
||||
|
||||
/*
|
||||
** Multiqueue Transmit driver
|
||||
** Multiqueue Transmit Entry:
|
||||
** quick turnaround to the stack
|
||||
**
|
||||
*/
|
||||
static int
|
||||
@@ -956,23 +968,23 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
|
||||
i = m->m_pkthdr.flowid % adapter->num_queues;
|
||||
else
|
||||
i = curcpu % adapter->num_queues;
|
||||
|
||||
txr = &adapter->tx_rings[i];
|
||||
que = &adapter->queues[i];
|
||||
if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) &&
|
||||
IGB_TX_TRYLOCK(txr)) {
|
||||
err = igb_mq_start_locked(ifp, txr, m);
|
||||
|
||||
err = drbr_enqueue(ifp, txr->br, m);
|
||||
if (err)
|
||||
return (err);
|
||||
if (IGB_TX_TRYLOCK(txr)) {
|
||||
err = igb_mq_start_locked(ifp, txr);
|
||||
IGB_TX_UNLOCK(txr);
|
||||
} else {
|
||||
err = drbr_enqueue(ifp, txr->br, m);
|
||||
} else
|
||||
taskqueue_enqueue(que->tq, &txr->txq_task);
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
|
||||
igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr)
|
||||
{
|
||||
struct adapter *adapter = txr->adapter;
|
||||
struct mbuf *next;
|
||||
@@ -981,36 +993,35 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
|
||||
IGB_TX_LOCK_ASSERT(txr);
|
||||
|
||||
if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) ||
|
||||
(txr->queue_status == IGB_QUEUE_DEPLETED) ||
|
||||
adapter->link_active == 0) {
|
||||
if (m != NULL)
|
||||
err = drbr_enqueue(ifp, txr->br, m);
|
||||
return (err);
|
||||
}
|
||||
adapter->link_active == 0)
|
||||
return (ENETDOWN);
|
||||
|
||||
enq = 0;
|
||||
if (m == NULL) {
|
||||
next = drbr_dequeue(ifp, txr->br);
|
||||
} else if (drbr_needs_enqueue(ifp, txr->br)) {
|
||||
if ((err = drbr_enqueue(ifp, txr->br, m)) != 0)
|
||||
return (err);
|
||||
next = drbr_dequeue(ifp, txr->br);
|
||||
} else
|
||||
next = m;
|
||||
|
||||
/* Process the queue */
|
||||
while (next != NULL) {
|
||||
while ((next = drbr_peek(ifp, txr->br)) != NULL) {
|
||||
if ((err = igb_xmit(txr, &next)) != 0) {
|
||||
if (next != NULL)
|
||||
err = drbr_enqueue(ifp, txr->br, next);
|
||||
if (next == NULL) {
|
||||
/* It was freed, move forward */
|
||||
drbr_advance(ifp, txr->br);
|
||||
} else {
|
||||
/*
|
||||
* Still have one left, it may not be
|
||||
* the same since the transmit function
|
||||
* may have changed it.
|
||||
*/
|
||||
drbr_putback(ifp, txr->br, next);
|
||||
}
|
||||
break;
|
||||
}
|
||||
drbr_advance(ifp, txr->br);
|
||||
enq++;
|
||||
drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags);
|
||||
ifp->if_obytes += next->m_pkthdr.len;
|
||||
if (next->m_flags & M_MCAST)
|
||||
ifp->if_omcasts++;
|
||||
ETHER_BPF_MTAP(ifp, next);
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
break;
|
||||
next = drbr_dequeue(ifp, txr->br);
|
||||
}
|
||||
if (enq > 0) {
|
||||
/* Set the watchdog */
|
||||
@@ -1036,7 +1047,7 @@ igb_deferred_mq_start(void *arg, int pending)
|
||||
|
||||
IGB_TX_LOCK(txr);
|
||||
if (!drbr_empty(ifp, txr->br))
|
||||
igb_mq_start_locked(ifp, txr, NULL);
|
||||
igb_mq_start_locked(ifp, txr);
|
||||
IGB_TX_UNLOCK(txr);
|
||||
}
|
||||
|
||||
@@ -1058,7 +1069,7 @@ igb_qflush(struct ifnet *ifp)
|
||||
}
|
||||
if_qflush(ifp);
|
||||
}
|
||||
#endif /* __FreeBSD_version >= 800000 */
|
||||
#endif /* ~IGB_LEGACY_TX */
|
||||
|
||||
/*********************************************************************
|
||||
* Ioctl entry point
|
||||
@@ -1384,11 +1395,11 @@ igb_handle_que(void *context, int pending)
|
||||
|
||||
IGB_TX_LOCK(txr);
|
||||
igb_txeof(txr);
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
/* Process the stack queue only if not depleted */
|
||||
if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) &&
|
||||
!drbr_empty(ifp, txr->br))
|
||||
igb_mq_start_locked(ifp, txr, NULL);
|
||||
igb_mq_start_locked(ifp, txr);
|
||||
#else
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
igb_start_locked(txr, ifp);
|
||||
@@ -1435,11 +1446,11 @@ igb_handle_link_locked(struct adapter *adapter)
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && adapter->link_active) {
|
||||
for (int i = 0; i < adapter->num_queues; i++, txr++) {
|
||||
IGB_TX_LOCK(txr);
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
/* Process the stack queue only if not depleted */
|
||||
if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) &&
|
||||
!drbr_empty(ifp, txr->br))
|
||||
igb_mq_start_locked(ifp, txr, NULL);
|
||||
igb_mq_start_locked(ifp, txr);
|
||||
#else
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
igb_start_locked(txr, ifp);
|
||||
@@ -1494,12 +1505,6 @@ igb_irq_fast(void *arg)
|
||||
}
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
/*********************************************************************
|
||||
*
|
||||
* Legacy polling routine : if using this code you MUST be sure that
|
||||
* multiqueue is not defined, ie, set igb_num_queues to 1.
|
||||
*
|
||||
*********************************************************************/
|
||||
#if __FreeBSD_version >= 800000
|
||||
#define POLL_RETURN_COUNT(a) (a)
|
||||
static int
|
||||
@@ -1510,8 +1515,8 @@ static void
|
||||
igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
{
|
||||
struct adapter *adapter = ifp->if_softc;
|
||||
struct igb_queue *que = adapter->queues;
|
||||
struct tx_ring *txr = adapter->tx_rings;
|
||||
struct igb_queue *que;
|
||||
struct tx_ring *txr;
|
||||
u32 reg_icr, rx_done = 0;
|
||||
u32 loop = IGB_MAX_LOOP;
|
||||
bool more;
|
||||
@@ -1533,20 +1538,26 @@ igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
}
|
||||
IGB_CORE_UNLOCK(adapter);
|
||||
|
||||
igb_rxeof(que, count, &rx_done);
|
||||
for (int i = 0; i < adapter->num_queues; i++) {
|
||||
que = &adapter->queues[i];
|
||||
txr = que->txr;
|
||||
|
||||
IGB_TX_LOCK(txr);
|
||||
do {
|
||||
more = igb_txeof(txr);
|
||||
} while (loop-- && more);
|
||||
#if __FreeBSD_version >= 800000
|
||||
if (!drbr_empty(ifp, txr->br))
|
||||
igb_mq_start_locked(ifp, txr, NULL);
|
||||
igb_rxeof(que, count, &rx_done);
|
||||
|
||||
IGB_TX_LOCK(txr);
|
||||
do {
|
||||
more = igb_txeof(txr);
|
||||
} while (loop-- && more);
|
||||
#ifndef IGB_LEGACY_TX
|
||||
if (!drbr_empty(ifp, txr->br))
|
||||
igb_mq_start_locked(ifp, txr);
|
||||
#else
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
igb_start_locked(txr, ifp);
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
igb_start_locked(txr, ifp);
|
||||
#endif
|
||||
IGB_TX_UNLOCK(txr);
|
||||
IGB_TX_UNLOCK(txr);
|
||||
}
|
||||
|
||||
return POLL_RETURN_COUNT(rx_done);
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
@@ -1567,16 +1578,20 @@ igb_msix_que(void *arg)
|
||||
u32 newitr = 0;
|
||||
bool more_rx;
|
||||
|
||||
/* Ignore spurious interrupts */
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
return;
|
||||
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_EIMC, que->eims);
|
||||
++que->irqs;
|
||||
|
||||
IGB_TX_LOCK(txr);
|
||||
igb_txeof(txr);
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
/* Process the stack queue only if not depleted */
|
||||
if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) &&
|
||||
!drbr_empty(ifp, txr->br))
|
||||
igb_mq_start_locked(ifp, txr, NULL);
|
||||
igb_mq_start_locked(ifp, txr);
|
||||
#else
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
igb_start_locked(txr, ifp);
|
||||
@@ -1685,7 +1700,6 @@ static void
|
||||
igb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
|
||||
{
|
||||
struct adapter *adapter = ifp->if_softc;
|
||||
u_char fiber_type = IFM_1000_SX;
|
||||
|
||||
INIT_DEBUGOUT("igb_media_status: begin");
|
||||
|
||||
@@ -1702,26 +1716,31 @@ igb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
|
||||
|
||||
ifmr->ifm_status |= IFM_ACTIVE;
|
||||
|
||||
if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
|
||||
(adapter->hw.phy.media_type == e1000_media_type_internal_serdes))
|
||||
ifmr->ifm_active |= fiber_type | IFM_FDX;
|
||||
else {
|
||||
switch (adapter->link_speed) {
|
||||
case 10:
|
||||
ifmr->ifm_active |= IFM_10_T;
|
||||
break;
|
||||
case 100:
|
||||
ifmr->ifm_active |= IFM_100_TX;
|
||||
break;
|
||||
case 1000:
|
||||
ifmr->ifm_active |= IFM_1000_T;
|
||||
break;
|
||||
}
|
||||
if (adapter->link_duplex == FULL_DUPLEX)
|
||||
ifmr->ifm_active |= IFM_FDX;
|
||||
switch (adapter->link_speed) {
|
||||
case 10:
|
||||
ifmr->ifm_active |= IFM_10_T;
|
||||
break;
|
||||
case 100:
|
||||
/*
|
||||
** Support for 100Mb SFP - these are Fiber
|
||||
** but the media type appears as serdes
|
||||
*/
|
||||
if (adapter->hw.phy.media_type ==
|
||||
e1000_media_type_internal_serdes)
|
||||
ifmr->ifm_active |= IFM_100_FX;
|
||||
else
|
||||
ifmr->ifm_active |= IFM_HDX;
|
||||
ifmr->ifm_active |= IFM_100_TX;
|
||||
break;
|
||||
case 1000:
|
||||
ifmr->ifm_active |= IFM_1000_T;
|
||||
break;
|
||||
}
|
||||
|
||||
if (adapter->link_duplex == FULL_DUPLEX)
|
||||
ifmr->ifm_active |= IFM_FDX;
|
||||
else
|
||||
ifmr->ifm_active |= IFM_HDX;
|
||||
|
||||
IGB_CORE_UNLOCK(adapter);
|
||||
}
|
||||
|
||||
@@ -1834,7 +1853,7 @@ retry:
|
||||
if (do_tso || (m_head->m_next != NULL &&
|
||||
m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD)) {
|
||||
if (M_WRITABLE(*m_headp) == 0) {
|
||||
m_head = m_dup(*m_headp, M_DONTWAIT);
|
||||
m_head = m_dup(*m_headp, M_NOWAIT);
|
||||
m_freem(*m_headp);
|
||||
if (m_head == NULL) {
|
||||
*m_headp = NULL;
|
||||
@@ -1939,7 +1958,7 @@ retry:
|
||||
if (error == EFBIG && remap) {
|
||||
struct mbuf *m;
|
||||
|
||||
m = m_defrag(*m_headp, M_DONTWAIT);
|
||||
m = m_defrag(*m_headp, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
adapter->mbuf_defrag_failed++;
|
||||
m_freem(*m_headp);
|
||||
@@ -2088,7 +2107,9 @@ static void
|
||||
igb_disable_promisc(struct adapter *adapter)
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
u32 reg;
|
||||
int mcnt = 0;
|
||||
|
||||
if (adapter->vf_ifp) {
|
||||
e1000_promisc_set_vf(hw, e1000_promisc_disabled);
|
||||
@@ -2096,7 +2117,31 @@ igb_disable_promisc(struct adapter *adapter)
|
||||
}
|
||||
reg = E1000_READ_REG(hw, E1000_RCTL);
|
||||
reg &= (~E1000_RCTL_UPE);
|
||||
reg &= (~E1000_RCTL_MPE);
|
||||
if (ifp->if_flags & IFF_ALLMULTI)
|
||||
mcnt = MAX_NUM_MULTICAST_ADDRESSES;
|
||||
else {
|
||||
struct ifmultiaddr *ifma;
|
||||
#if __FreeBSD_version < 800000
|
||||
IF_ADDR_LOCK(ifp);
|
||||
#else
|
||||
if_maddr_rlock(ifp);
|
||||
#endif
|
||||
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
|
||||
if (ifma->ifma_addr->sa_family != AF_LINK)
|
||||
continue;
|
||||
if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
|
||||
break;
|
||||
mcnt++;
|
||||
}
|
||||
#if __FreeBSD_version < 800000
|
||||
IF_ADDR_UNLOCK(ifp);
|
||||
#else
|
||||
if_maddr_runlock(ifp);
|
||||
#endif
|
||||
}
|
||||
/* Don't disable if in MAX groups */
|
||||
if (mcnt < MAX_NUM_MULTICAST_ADDRESSES)
|
||||
reg &= (~E1000_RCTL_MPE);
|
||||
E1000_WRITE_REG(hw, E1000_RCTL, reg);
|
||||
}
|
||||
|
||||
@@ -2224,11 +2269,13 @@ timeout:
|
||||
static void
|
||||
igb_update_link_status(struct adapter *adapter)
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
device_t dev = adapter->dev;
|
||||
struct tx_ring *txr = adapter->tx_rings;
|
||||
u32 link_check, thstat, ctrl;
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
struct e1000_fc_info *fc = &hw->fc;
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
device_t dev = adapter->dev;
|
||||
struct tx_ring *txr = adapter->tx_rings;
|
||||
u32 link_check, thstat, ctrl;
|
||||
char *flowctl = NULL;
|
||||
|
||||
link_check = thstat = ctrl = 0;
|
||||
|
||||
@@ -2266,15 +2313,33 @@ igb_update_link_status(struct adapter *adapter)
|
||||
ctrl = E1000_READ_REG(hw, E1000_CTRL_EXT);
|
||||
}
|
||||
|
||||
/* Get the flow control for display */
|
||||
switch (fc->current_mode) {
|
||||
case e1000_fc_rx_pause:
|
||||
flowctl = "RX";
|
||||
break;
|
||||
case e1000_fc_tx_pause:
|
||||
flowctl = "TX";
|
||||
break;
|
||||
case e1000_fc_full:
|
||||
flowctl = "Full";
|
||||
break;
|
||||
case e1000_fc_none:
|
||||
default:
|
||||
flowctl = "None";
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now we check if a transition has happened */
|
||||
if (link_check && (adapter->link_active == 0)) {
|
||||
e1000_get_speed_and_duplex(&adapter->hw,
|
||||
&adapter->link_speed, &adapter->link_duplex);
|
||||
if (bootverbose)
|
||||
device_printf(dev, "Link is up %d Mbps %s\n",
|
||||
device_printf(dev, "Link is up %d Mbps %s,"
|
||||
" Flow Control: %s\n",
|
||||
adapter->link_speed,
|
||||
((adapter->link_duplex == FULL_DUPLEX) ?
|
||||
"Full Duplex" : "Half Duplex"));
|
||||
"Full Duplex" : "Half Duplex"), flowctl);
|
||||
adapter->link_active = 1;
|
||||
ifp->if_baudrate = adapter->link_speed * 1000000;
|
||||
if ((ctrl & E1000_CTRL_EXT_LINK_MODE_GMII) &&
|
||||
@@ -2351,16 +2416,8 @@ igb_identify_hardware(struct adapter *adapter)
|
||||
device_t dev = adapter->dev;
|
||||
|
||||
/* Make sure our PCI config space has the necessary stuff set */
|
||||
pci_enable_busmaster(dev);
|
||||
adapter->hw.bus.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||
if (!((adapter->hw.bus.pci_cmd_word & PCIM_CMD_BUSMASTEREN) &&
|
||||
(adapter->hw.bus.pci_cmd_word & PCIM_CMD_MEMEN))) {
|
||||
INIT_DEBUGOUT("Memory Access and/or Bus Master "
|
||||
"bits were not set!\n");
|
||||
adapter->hw.bus.pci_cmd_word |=
|
||||
(PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
|
||||
pci_write_config(dev, PCIR_COMMAND,
|
||||
adapter->hw.bus.pci_cmd_word, 2);
|
||||
}
|
||||
|
||||
/* Save off the information about this board */
|
||||
adapter->hw.vendor_id = pci_get_vendor(dev);
|
||||
@@ -2420,7 +2477,6 @@ igb_allocate_legacy(struct adapter *adapter)
|
||||
{
|
||||
device_t dev = adapter->dev;
|
||||
struct igb_queue *que = adapter->queues;
|
||||
struct tx_ring *txr = adapter->tx_rings;
|
||||
int error, rid = 0;
|
||||
|
||||
/* Turn off all interrupts */
|
||||
@@ -2439,8 +2495,8 @@ igb_allocate_legacy(struct adapter *adapter)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version >= 800000
|
||||
TASK_INIT(&txr->txq_task, 0, igb_deferred_mq_start, txr);
|
||||
#ifndef IGB_LEGACY_TX
|
||||
TASK_INIT(&que->txr->txq_task, 0, igb_deferred_mq_start, que->txr);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -2522,9 +2578,8 @@ igb_allocate_msix(struct adapter *adapter)
|
||||
"Bound queue %d to cpu %d\n",
|
||||
i,igb_last_bind_cpu);
|
||||
igb_last_bind_cpu = CPU_NEXT(igb_last_bind_cpu);
|
||||
igb_last_bind_cpu = igb_last_bind_cpu % mp_ncpus;
|
||||
}
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
TASK_INIT(&que->txr->txq_task, 0, igb_deferred_mq_start,
|
||||
que->txr);
|
||||
#endif
|
||||
@@ -2750,7 +2805,7 @@ igb_free_pci_resources(struct adapter *adapter)
|
||||
|
||||
for (int i = 0; i < adapter->num_queues; i++, que++) {
|
||||
if (que->tq != NULL) {
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
taskqueue_drain(que->tq, &que->txr->txq_task);
|
||||
#endif
|
||||
taskqueue_drain(que->tq, &que->que_task);
|
||||
@@ -2785,24 +2840,19 @@ igb_setup_msix(struct adapter *adapter)
|
||||
goto msi;
|
||||
|
||||
/* First try MSI/X */
|
||||
msgs = pci_msix_count(dev);
|
||||
if (msgs == 0)
|
||||
goto msi;
|
||||
rid = PCIR_BAR(IGB_MSIX_BAR);
|
||||
adapter->msix_mem = bus_alloc_resource_any(dev,
|
||||
SYS_RES_MEMORY, &rid, RF_ACTIVE);
|
||||
if (!adapter->msix_mem) {
|
||||
if (adapter->msix_mem == NULL) {
|
||||
/* May not be enabled */
|
||||
device_printf(adapter->dev,
|
||||
"Unable to map MSIX table \n");
|
||||
goto msi;
|
||||
}
|
||||
|
||||
msgs = pci_msix_count(dev);
|
||||
if (msgs == 0) { /* system has msix disabled */
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
PCIR_BAR(IGB_MSIX_BAR), adapter->msix_mem);
|
||||
adapter->msix_mem = NULL;
|
||||
goto msi;
|
||||
}
|
||||
|
||||
/* Figure out a reasonable auto config value */
|
||||
queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus;
|
||||
|
||||
@@ -2845,20 +2895,32 @@ igb_setup_msix(struct adapter *adapter)
|
||||
"MSIX Configuration Problem, "
|
||||
"%d vectors configured, but %d queues wanted!\n",
|
||||
msgs, want);
|
||||
return (0);
|
||||
goto msi;
|
||||
}
|
||||
if ((msgs) && pci_alloc_msix(dev, &msgs) == 0) {
|
||||
if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) {
|
||||
device_printf(adapter->dev,
|
||||
"Using MSIX interrupts with %d vectors\n", msgs);
|
||||
adapter->num_queues = queues;
|
||||
return (msgs);
|
||||
}
|
||||
/*
|
||||
** If MSIX alloc failed or provided us with
|
||||
** less than needed, free and fall through to MSI
|
||||
*/
|
||||
pci_release_msi(dev);
|
||||
|
||||
msi:
|
||||
msgs = pci_msi_count(dev);
|
||||
if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0) {
|
||||
device_printf(adapter->dev," Using MSI interrupt\n");
|
||||
if (adapter->msix_mem != NULL) {
|
||||
bus_release_resource(dev, SYS_RES_MEMORY,
|
||||
PCIR_BAR(IGB_MSIX_BAR), adapter->msix_mem);
|
||||
adapter->msix_mem = NULL;
|
||||
}
|
||||
msgs = 1;
|
||||
if (pci_alloc_msi(dev, &msgs) == 0) {
|
||||
device_printf(adapter->dev," Using an MSI interrupt\n");
|
||||
return (msgs);
|
||||
}
|
||||
device_printf(adapter->dev," Using a Legacy interrupt\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -3060,7 +3122,7 @@ igb_setup_interface(device_t dev, struct adapter *adapter)
|
||||
ifp->if_softc = adapter;
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||
ifp->if_ioctl = igb_ioctl;
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
ifp->if_transmit = igb_mq_start;
|
||||
ifp->if_qflush = igb_qflush;
|
||||
#else
|
||||
@@ -3304,9 +3366,9 @@ igb_allocate_queues(struct adapter *adapter)
|
||||
error = ENOMEM;
|
||||
goto err_tx_desc;
|
||||
}
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
/* Allocate a buf ring */
|
||||
txr->br = buf_ring_alloc(IGB_BR_SIZE, M_DEVBUF,
|
||||
txr->br = buf_ring_alloc(igb_buf_ring_size, M_DEVBUF,
|
||||
M_WAITOK, &txr->tx_mtx);
|
||||
#endif
|
||||
}
|
||||
@@ -3365,7 +3427,7 @@ err_tx_desc:
|
||||
igb_dma_free(adapter, &txr->txdma);
|
||||
free(adapter->rx_rings, M_DEVBUF);
|
||||
rx_fail:
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
buf_ring_free(txr->br, M_DEVBUF);
|
||||
#endif
|
||||
free(adapter->tx_rings, M_DEVBUF);
|
||||
@@ -3623,7 +3685,7 @@ igb_free_transmit_buffers(struct tx_ring *txr)
|
||||
tx_buffer->map = NULL;
|
||||
}
|
||||
}
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
if (txr->br != NULL)
|
||||
buf_ring_free(txr->br, M_DEVBUF);
|
||||
#endif
|
||||
@@ -3845,17 +3907,9 @@ igb_txeof(struct tx_ring *txr)
|
||||
IGB_TX_LOCK_ASSERT(txr);
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
if (ifp->if_capenable & IFCAP_NETMAP) {
|
||||
struct netmap_adapter *na = NA(ifp);
|
||||
|
||||
selwakeuppri(&na->tx_rings[txr->me].si, PI_NET);
|
||||
IGB_TX_UNLOCK(txr);
|
||||
IGB_CORE_LOCK(adapter);
|
||||
selwakeuppri(&na->tx_si, PI_NET);
|
||||
IGB_CORE_UNLOCK(adapter);
|
||||
IGB_TX_LOCK(txr);
|
||||
return FALSE;
|
||||
}
|
||||
if (netmap_tx_irq(ifp, txr->me |
|
||||
(NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
|
||||
return (FALSE);
|
||||
#endif /* DEV_NETMAP */
|
||||
if (txr->tx_avail == adapter->num_tx_desc) {
|
||||
txr->queue_status = IGB_QUEUE_IDLE;
|
||||
@@ -3988,7 +4042,7 @@ igb_refresh_mbufs(struct rx_ring *rxr, int limit)
|
||||
if (rxr->hdr_split == FALSE)
|
||||
goto no_split;
|
||||
if (rxbuf->m_head == NULL) {
|
||||
mh = m_gethdr(M_DONTWAIT, MT_DATA);
|
||||
mh = m_gethdr(M_NOWAIT, MT_DATA);
|
||||
if (mh == NULL)
|
||||
goto update;
|
||||
} else
|
||||
@@ -4014,7 +4068,7 @@ igb_refresh_mbufs(struct rx_ring *rxr, int limit)
|
||||
htole64(hseg[0].ds_addr);
|
||||
no_split:
|
||||
if (rxbuf->m_pack == NULL) {
|
||||
mp = m_getjcl(M_DONTWAIT, MT_DATA,
|
||||
mp = m_getjcl(M_NOWAIT, MT_DATA,
|
||||
M_PKTHDR, adapter->rx_mbuf_sz);
|
||||
if (mp == NULL)
|
||||
goto update;
|
||||
@@ -4230,7 +4284,7 @@ igb_setup_receive_ring(struct rx_ring *rxr)
|
||||
goto skip_head;
|
||||
|
||||
/* First the header */
|
||||
rxbuf->m_head = m_gethdr(M_DONTWAIT, MT_DATA);
|
||||
rxbuf->m_head = m_gethdr(M_NOWAIT, MT_DATA);
|
||||
if (rxbuf->m_head == NULL) {
|
||||
error = ENOBUFS;
|
||||
goto fail;
|
||||
@@ -4252,7 +4306,7 @@ igb_setup_receive_ring(struct rx_ring *rxr)
|
||||
|
||||
skip_head:
|
||||
/* Now the payload cluster */
|
||||
rxbuf->m_pack = m_getjcl(M_DONTWAIT, MT_DATA,
|
||||
rxbuf->m_pack = m_getjcl(M_NOWAIT, MT_DATA,
|
||||
M_PKTHDR, adapter->rx_mbuf_sz);
|
||||
if (rxbuf->m_pack == NULL) {
|
||||
error = ENOBUFS;
|
||||
@@ -4335,8 +4389,8 @@ fail:
|
||||
* the rings that completed, the failing case will have
|
||||
* cleaned up for itself. 'i' is the endpoint.
|
||||
*/
|
||||
for (int j = 0; j > i; ++j) {
|
||||
rxr = &adapter->rx_rings[i];
|
||||
for (int j = 0; j < i; ++j) {
|
||||
rxr = &adapter->rx_rings[j];
|
||||
IGB_RX_LOCK(rxr);
|
||||
igb_free_receive_ring(rxr);
|
||||
IGB_RX_UNLOCK(rxr);
|
||||
@@ -4709,17 +4763,8 @@ igb_rxeof(struct igb_queue *que, int count, int *done)
|
||||
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
if (ifp->if_capenable & IFCAP_NETMAP) {
|
||||
struct netmap_adapter *na = NA(ifp);
|
||||
|
||||
na->rx_rings[rxr->me].nr_kflags |= NKR_PENDINTR;
|
||||
selwakeuppri(&na->rx_rings[rxr->me].si, PI_NET);
|
||||
IGB_RX_UNLOCK(rxr);
|
||||
IGB_CORE_LOCK(adapter);
|
||||
selwakeuppri(&na->rx_si, PI_NET);
|
||||
IGB_CORE_UNLOCK(adapter);
|
||||
return (0);
|
||||
}
|
||||
if (netmap_rx_irq(ifp, rxr->me | NETMAP_LOCKED_ENTER, &processed))
|
||||
return (FALSE);
|
||||
#endif /* DEV_NETMAP */
|
||||
|
||||
/* Main clean loop */
|
||||
@@ -4752,7 +4797,7 @@ igb_rxeof(struct igb_queue *que, int count, int *done)
|
||||
/* Make sure all segments of a bad packet are discarded */
|
||||
if (((staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) != 0) ||
|
||||
(rxr->discard)) {
|
||||
ifp->if_ierrors++;
|
||||
adapter->dropped_pkts++;
|
||||
++rxr->rx_discarded;
|
||||
if (!eop) /* Catch subsequent segs */
|
||||
rxr->discard = TRUE;
|
||||
@@ -4844,7 +4889,7 @@ igb_rxeof(struct igb_queue *que, int count, int *done)
|
||||
rxr->fmp->m_pkthdr.ether_vtag = vtag;
|
||||
rxr->fmp->m_flags |= M_VLANTAG;
|
||||
}
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
rxr->fmp->m_pkthdr.flowid = que->msix;
|
||||
rxr->fmp->m_flags |= M_FLOWID;
|
||||
#endif
|
||||
@@ -4894,7 +4939,7 @@ next_desc:
|
||||
}
|
||||
|
||||
if (done != NULL)
|
||||
*done = rxdone;
|
||||
*done += rxdone;
|
||||
|
||||
IGB_RX_UNLOCK(rxr);
|
||||
return ((staterr & E1000_RXD_STAT_DD) ? TRUE : FALSE);
|
||||
|
||||
@@ -297,11 +297,11 @@ struct tx_ring {
|
||||
u32 next_to_clean;
|
||||
volatile u16 tx_avail;
|
||||
struct igb_tx_buffer *tx_buffers;
|
||||
#if __FreeBSD_version >= 800000
|
||||
#ifndef IGB_LEGACY_TX
|
||||
struct buf_ring *br;
|
||||
struct task txq_task;
|
||||
#endif
|
||||
bus_dma_tag_t txtag;
|
||||
struct task txq_task;
|
||||
|
||||
u32 bytes;
|
||||
u32 packets;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -32,10 +32,11 @@
|
||||
******************************************************************************/
|
||||
/*$FreeBSD$*/
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
#include "opt_device_polling.h"
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
#include "opt_device_polling.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
@@ -87,7 +88,7 @@
|
||||
/*********************************************************************
|
||||
* Legacy Em Driver version:
|
||||
*********************************************************************/
|
||||
char lem_driver_version[] = "1.0.4";
|
||||
char lem_driver_version[] = "1.0.6";
|
||||
|
||||
/*********************************************************************
|
||||
* PCI Device ID Table
|
||||
@@ -241,15 +242,12 @@ static void lem_enable_wakeup(device_t);
|
||||
static int lem_enable_phy_wakeup(struct adapter *);
|
||||
static void lem_led_func(void *, int);
|
||||
|
||||
#ifdef EM_LEGACY_IRQ
|
||||
static void lem_intr(void *);
|
||||
#else /* FAST IRQ */
|
||||
static int lem_irq_fast(void *);
|
||||
static void lem_handle_rxtx(void *context, int pending);
|
||||
static void lem_handle_link(void *context, int pending);
|
||||
static void lem_add_rx_process_limit(struct adapter *, const char *,
|
||||
const char *, int *, int);
|
||||
#endif /* ~EM_LEGACY_IRQ */
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
static poll_handler_t lem_poll;
|
||||
@@ -267,7 +265,7 @@ static device_method_t lem_methods[] = {
|
||||
DEVMETHOD(device_shutdown, lem_shutdown),
|
||||
DEVMETHOD(device_suspend, lem_suspend),
|
||||
DEVMETHOD(device_resume, lem_resume),
|
||||
{0, 0}
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
#ifndef __HAIKU__
|
||||
@@ -295,6 +293,9 @@ MODULE_DEPEND(lem, ether, 1, 1, 1);
|
||||
#define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000)
|
||||
#define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024)
|
||||
|
||||
#define MAX_INTS_PER_SEC 8000
|
||||
#define DEFAULT_ITR (1000000000/(MAX_INTS_PER_SEC * 256))
|
||||
|
||||
static int lem_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV);
|
||||
static int lem_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR);
|
||||
static int lem_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV);
|
||||
@@ -315,11 +316,13 @@ TUNABLE_INT("hw.em.txd", &lem_txd);
|
||||
TUNABLE_INT("hw.em.smart_pwr_down", &lem_smart_pwr_down);
|
||||
TUNABLE_INT("hw.em.sbp", &lem_debug_sbp);
|
||||
|
||||
#ifndef EM_LEGACY_IRQ
|
||||
/* Interrupt style - default to fast */
|
||||
static int lem_use_legacy_irq = 0;
|
||||
TUNABLE_INT("hw.em.use_legacy_irq", &lem_use_legacy_irq);
|
||||
|
||||
/* How many packets rxeof tries to clean at a time */
|
||||
static int lem_rx_process_limit = 100;
|
||||
TUNABLE_INT("hw.em.rx_process_limit", &lem_rx_process_limit);
|
||||
#endif
|
||||
|
||||
/* Flow control setting - default to FULL */
|
||||
static int lem_fc_setting = e1000_fc_full;
|
||||
@@ -461,14 +464,17 @@ lem_attach(device_t dev)
|
||||
&adapter->tx_abs_int_delay,
|
||||
E1000_REGISTER(&adapter->hw, E1000_TADV),
|
||||
lem_tx_abs_int_delay_dflt);
|
||||
lem_add_int_delay_sysctl(adapter, "itr",
|
||||
"interrupt delay limit in usecs/4",
|
||||
&adapter->tx_itr,
|
||||
E1000_REGISTER(&adapter->hw, E1000_ITR),
|
||||
DEFAULT_ITR);
|
||||
}
|
||||
|
||||
#ifndef EM_LEGACY_IRQ
|
||||
/* Sysctls for limiting the amount of work done in the taskqueue */
|
||||
lem_add_rx_process_limit(adapter, "rx_processing_limit",
|
||||
"max number of rx packets to process", &adapter->rx_process_limit,
|
||||
lem_rx_process_limit);
|
||||
#endif
|
||||
|
||||
/* Sysctl for setting the interface flow control */
|
||||
lem_set_flow_cntrl(adapter, "flow_control",
|
||||
@@ -1214,22 +1220,6 @@ lem_init_locked(struct adapter *adapter)
|
||||
callout_reset(&adapter->timer, hz, lem_local_timer, adapter);
|
||||
e1000_clear_hw_cntrs_base_generic(&adapter->hw);
|
||||
|
||||
/* MSI/X configuration for 82574 */
|
||||
if (adapter->hw.mac.type == e1000_82574) {
|
||||
int tmp;
|
||||
tmp = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
|
||||
tmp |= E1000_CTRL_EXT_PBA_CLR;
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, tmp);
|
||||
/*
|
||||
** Set the IVAR - interrupt vector routing.
|
||||
** Each nibble represents a vector, high bit
|
||||
** is enable, other 3 bits are the MSIX table
|
||||
** entry, we map RXQ0 to 0, TXQ0 to 1, and
|
||||
** Link (other) to 2, hence the magic number.
|
||||
*/
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_IVAR, 0x800A0908);
|
||||
}
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
/*
|
||||
* Only enable interrupts if we are not polling, make sure
|
||||
@@ -1298,7 +1288,6 @@ lem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
#ifdef EM_LEGACY_IRQ
|
||||
/*********************************************************************
|
||||
*
|
||||
* Legacy Interrupt Service routine
|
||||
@@ -1312,7 +1301,8 @@ lem_intr(void *arg)
|
||||
u32 reg_icr;
|
||||
|
||||
|
||||
if (ifp->if_capenable & IFCAP_POLLING)
|
||||
if ((ifp->if_capenable & IFCAP_POLLING) ||
|
||||
((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0))
|
||||
return;
|
||||
|
||||
EM_CORE_LOCK(adapter);
|
||||
@@ -1320,11 +1310,10 @@ lem_intr(void *arg)
|
||||
if (reg_icr & E1000_ICR_RXO)
|
||||
adapter->rx_overruns++;
|
||||
|
||||
if ((reg_icr == 0xffffffff) || (reg_icr == 0))
|
||||
goto out;
|
||||
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
goto out;
|
||||
if ((reg_icr == 0xffffffff) || (reg_icr == 0)) {
|
||||
EM_CORE_UNLOCK(adapter);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
|
||||
callout_stop(&adapter->timer);
|
||||
@@ -1334,23 +1323,22 @@ lem_intr(void *arg)
|
||||
lem_tx_purge(adapter);
|
||||
callout_reset(&adapter->timer, hz,
|
||||
lem_local_timer, adapter);
|
||||
goto out;
|
||||
EM_CORE_UNLOCK(adapter);
|
||||
return;
|
||||
}
|
||||
|
||||
EM_TX_LOCK(adapter);
|
||||
EM_CORE_UNLOCK(adapter);
|
||||
lem_rxeof(adapter, -1, NULL);
|
||||
|
||||
EM_TX_LOCK(adapter);
|
||||
lem_txeof(adapter);
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
|
||||
!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
lem_start_locked(ifp);
|
||||
EM_TX_UNLOCK(adapter);
|
||||
|
||||
out:
|
||||
EM_CORE_UNLOCK(adapter);
|
||||
return;
|
||||
}
|
||||
|
||||
#else /* EM_FAST_IRQ, then fast interrupt routines only */
|
||||
|
||||
static void
|
||||
lem_handle_link(void *context, int pending)
|
||||
@@ -1380,12 +1368,16 @@ lem_handle_rxtx(void *context, int pending)
|
||||
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
lem_rxeof(adapter, adapter->rx_process_limit, NULL);
|
||||
bool more = lem_rxeof(adapter, adapter->rx_process_limit, NULL);
|
||||
EM_TX_LOCK(adapter);
|
||||
lem_txeof(adapter);
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
lem_start_locked(ifp);
|
||||
EM_TX_UNLOCK(adapter);
|
||||
if (more) {
|
||||
taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
@@ -1434,7 +1426,6 @@ lem_irq_fast(void *arg)
|
||||
adapter->rx_overruns++;
|
||||
return FILTER_HANDLED;
|
||||
}
|
||||
#endif /* ~EM_LEGACY_IRQ */
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
@@ -1610,7 +1601,7 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp)
|
||||
if (error == EFBIG) {
|
||||
struct mbuf *m;
|
||||
|
||||
m = m_defrag(*m_headp, M_DONTWAIT);
|
||||
m = m_defrag(*m_headp, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
adapter->mbuf_alloc_failed++;
|
||||
m_freem(*m_headp);
|
||||
@@ -1900,12 +1891,37 @@ lem_set_promisc(struct adapter *adapter)
|
||||
static void
|
||||
lem_disable_promisc(struct adapter *adapter)
|
||||
{
|
||||
u32 reg_rctl;
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
u32 reg_rctl;
|
||||
int mcnt = 0;
|
||||
|
||||
reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
|
||||
|
||||
reg_rctl &= (~E1000_RCTL_UPE);
|
||||
reg_rctl &= (~E1000_RCTL_MPE);
|
||||
if (ifp->if_flags & IFF_ALLMULTI)
|
||||
mcnt = MAX_NUM_MULTICAST_ADDRESSES;
|
||||
else {
|
||||
struct ifmultiaddr *ifma;
|
||||
#if __FreeBSD_version < 800000
|
||||
IF_ADDR_LOCK(ifp);
|
||||
#else
|
||||
if_maddr_rlock(ifp);
|
||||
#endif
|
||||
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
|
||||
if (ifma->ifma_addr->sa_family != AF_LINK)
|
||||
continue;
|
||||
if (mcnt == MAX_NUM_MULTICAST_ADDRESSES)
|
||||
break;
|
||||
mcnt++;
|
||||
}
|
||||
#if __FreeBSD_version < 800000
|
||||
IF_ADDR_UNLOCK(ifp);
|
||||
#else
|
||||
if_maddr_runlock(ifp);
|
||||
#endif
|
||||
}
|
||||
/* Don't disable if in MAX groups */
|
||||
if (mcnt < MAX_NUM_MULTICAST_ADDRESSES)
|
||||
reg_rctl &= (~E1000_RCTL_MPE);
|
||||
reg_rctl &= (~E1000_RCTL_SBP);
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
|
||||
}
|
||||
@@ -2125,16 +2141,8 @@ lem_identify_hardware(struct adapter *adapter)
|
||||
device_t dev = adapter->dev;
|
||||
|
||||
/* Make sure our PCI config space has the necessary stuff set */
|
||||
pci_enable_busmaster(dev);
|
||||
adapter->hw.bus.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||
if (!((adapter->hw.bus.pci_cmd_word & PCIM_CMD_BUSMASTEREN) &&
|
||||
(adapter->hw.bus.pci_cmd_word & PCIM_CMD_MEMEN))) {
|
||||
device_printf(dev, "Memory Access and/or Bus Master bits "
|
||||
"were not set!\n");
|
||||
adapter->hw.bus.pci_cmd_word |=
|
||||
(PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
|
||||
pci_write_config(dev, PCIR_COMMAND,
|
||||
adapter->hw.bus.pci_cmd_word, 2);
|
||||
}
|
||||
|
||||
/* Save off the information about this board */
|
||||
adapter->hw.vendor_id = pci_get_vendor(dev);
|
||||
@@ -2231,19 +2239,21 @@ lem_allocate_irq(struct adapter *adapter)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
#ifdef EM_LEGACY_IRQ
|
||||
/* We do Legacy setup */
|
||||
if ((error = bus_setup_intr(dev, adapter->res[0],
|
||||
INTR_TYPE_NET | INTR_MPSAFE, NULL, lem_intr, adapter,
|
||||
&adapter->tag[0])) != 0) {
|
||||
device_printf(dev, "Failed to register interrupt handler");
|
||||
return (error);
|
||||
/* Do Legacy setup? */
|
||||
if (lem_use_legacy_irq) {
|
||||
if ((error = bus_setup_intr(dev, adapter->res[0],
|
||||
INTR_TYPE_NET | INTR_MPSAFE, NULL, lem_intr, adapter,
|
||||
&adapter->tag[0])) != 0) {
|
||||
device_printf(dev,
|
||||
"Failed to register interrupt handler");
|
||||
return (error);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#else /* FAST_IRQ */
|
||||
/*
|
||||
* Try allocating a fast interrupt and the associated deferred
|
||||
* processing contexts.
|
||||
* Use a Fast interrupt and the associated
|
||||
* deferred processing contexts.
|
||||
*/
|
||||
TASK_INIT(&adapter->rxtx_task, 0, lem_handle_rxtx, adapter);
|
||||
TASK_INIT(&adapter->link_task, 0, lem_handle_link, adapter);
|
||||
@@ -2260,7 +2270,6 @@ lem_allocate_irq(struct adapter *adapter)
|
||||
adapter->tq = NULL;
|
||||
return (error);
|
||||
}
|
||||
#endif /* EM_LEGACY_IRQ */
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -2608,7 +2617,6 @@ lem_dma_free(struct adapter *adapter, struct em_dma_alloc *dma)
|
||||
static int
|
||||
lem_allocate_transmit_structures(struct adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
device_t dev = adapter->dev;
|
||||
struct em_buffer *tx_buffer;
|
||||
int error;
|
||||
@@ -2641,7 +2649,7 @@ lem_allocate_transmit_structures(struct adapter *adapter)
|
||||
}
|
||||
|
||||
/* Create the descriptor buffer dma maps */
|
||||
for (i = 0; i < adapter->num_tx_desc; i++) {
|
||||
for (int i = 0; i < adapter->num_tx_desc; i++) {
|
||||
tx_buffer = &adapter->tx_buffer_area[i];
|
||||
error = bus_dmamap_create(adapter->txtag, 0, &tx_buffer->map);
|
||||
if (error != 0) {
|
||||
@@ -2665,7 +2673,6 @@ fail:
|
||||
static void
|
||||
lem_setup_transmit_structures(struct adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
struct em_buffer *tx_buffer;
|
||||
#ifdef DEV_NETMAP
|
||||
/* we are already locked */
|
||||
@@ -2678,7 +2685,7 @@ lem_setup_transmit_structures(struct adapter *adapter)
|
||||
(sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc);
|
||||
|
||||
/* Free any existing TX buffers */
|
||||
for (i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
|
||||
for (int i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) {
|
||||
tx_buffer = &adapter->tx_buffer_area[i];
|
||||
bus_dmamap_sync(adapter->txtag, tx_buffer->map,
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
@@ -2794,8 +2801,7 @@ lem_free_transmit_structures(struct adapter *adapter)
|
||||
INIT_DEBUGOUT("free_transmit_structures: begin");
|
||||
|
||||
if (adapter->tx_buffer_area != NULL) {
|
||||
int i;
|
||||
for (i = 0; i < adapter->num_tx_desc; i++) {
|
||||
for (int i = 0; i < adapter->num_tx_desc; i++) {
|
||||
tx_buffer = &adapter->tx_buffer_area[i];
|
||||
if (tx_buffer->m_head != NULL) {
|
||||
bus_dmamap_sync(adapter->txtag, tx_buffer->map,
|
||||
@@ -3003,10 +3009,8 @@ lem_txeof(struct adapter *adapter)
|
||||
EM_TX_LOCK_ASSERT(adapter);
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
if (ifp->if_capenable & IFCAP_NETMAP) {
|
||||
selwakeuppri(&NA(ifp)->tx_rings[0].si, PI_NET);
|
||||
if (netmap_tx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
|
||||
return;
|
||||
}
|
||||
#endif /* DEV_NETMAP */
|
||||
if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
|
||||
return;
|
||||
@@ -3123,7 +3127,7 @@ lem_get_buf(struct adapter *adapter, int i)
|
||||
struct em_buffer *rx_buffer;
|
||||
int error, nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL) {
|
||||
adapter->mbuf_cluster_failed++;
|
||||
return (ENOBUFS);
|
||||
@@ -3294,13 +3298,10 @@ lem_setup_receive_structures(struct adapter *adapter)
|
||||
* Enable receive unit.
|
||||
*
|
||||
**********************************************************************/
|
||||
#define MAX_INTS_PER_SEC 8000
|
||||
#define DEFAULT_ITR 1000000000/(MAX_INTS_PER_SEC * 256)
|
||||
|
||||
static void
|
||||
lem_initialize_receive_unit(struct adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
u64 bus_addr;
|
||||
u32 rctl, rxcsum;
|
||||
@@ -3324,20 +3325,6 @@ lem_initialize_receive_unit(struct adapter *adapter)
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_ITR, DEFAULT_ITR);
|
||||
}
|
||||
|
||||
/*
|
||||
** When using MSIX interrupts we need to throttle
|
||||
** using the EITR register (82574 only)
|
||||
*/
|
||||
if (adapter->msix)
|
||||
for (i = 0; i < 4; i++)
|
||||
E1000_WRITE_REG(&adapter->hw,
|
||||
E1000_EITR_82574(i), DEFAULT_ITR);
|
||||
|
||||
/* Disable accelerated ackknowledge */
|
||||
if (adapter->hw.mac.type == e1000_82574)
|
||||
E1000_WRITE_REG(&adapter->hw,
|
||||
E1000_RFCTL, E1000_RFCTL_ACK_DIS);
|
||||
|
||||
/* Setup the Base and Length of the Rx Descriptor Ring */
|
||||
bus_addr = adapter->rxdma.dma_paddr;
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(0),
|
||||
@@ -3401,19 +3388,13 @@ lem_initialize_receive_unit(struct adapter *adapter)
|
||||
* Tail Descriptor Pointers
|
||||
*/
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0);
|
||||
rctl = adapter->num_rx_desc - 1; /* default RDT value */
|
||||
#ifdef DEV_NETMAP
|
||||
/* preserve buffers already made available to clients */
|
||||
if (ifp->if_capenable & IFCAP_NETMAP) {
|
||||
struct netmap_adapter *na = NA(adapter->ifp);
|
||||
struct netmap_kring *kring = &na->rx_rings[0];
|
||||
int t = na->num_rx_desc - 1 - kring->nr_hwavail;
|
||||
|
||||
if (t >= na->num_rx_desc)
|
||||
t -= na->num_rx_desc;
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), t);
|
||||
} else
|
||||
if (ifp->if_capenable & IFCAP_NETMAP)
|
||||
rctl -= NA(adapter->ifp)->rx_rings[0].nr_hwavail;
|
||||
#endif /* DEV_NETMAP */
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), adapter->num_rx_desc - 1);
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), rctl);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -3497,13 +3478,8 @@ lem_rxeof(struct adapter *adapter, int count, int *done)
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
if (ifp->if_capenable & IFCAP_NETMAP) {
|
||||
struct netmap_adapter *na = NA(ifp);
|
||||
na->rx_rings[0].nr_kflags |= NKR_PENDINTR;
|
||||
selwakeuppri(&na->rx_rings[0].si, PI_NET);
|
||||
EM_RX_UNLOCK(adapter);
|
||||
return (0);
|
||||
}
|
||||
if (netmap_rx_irq(ifp, 0 | NETMAP_LOCKED_ENTER, &rx_sent))
|
||||
return (FALSE);
|
||||
#endif /* DEV_NETMAP */
|
||||
|
||||
if (!((current_desc->status) & E1000_RXD_STAT_DD)) {
|
||||
@@ -3620,7 +3596,7 @@ skip:
|
||||
adapter->lmp = NULL;
|
||||
}
|
||||
} else {
|
||||
ifp->if_ierrors++;
|
||||
adapter->dropped_pkts++;
|
||||
discard:
|
||||
/* Reuse loaded DMA map and just update mbuf chain */
|
||||
mp = adapter->rx_buffer_area[i].m_head;
|
||||
@@ -3696,7 +3672,7 @@ lem_fixup_rx(struct adapter *adapter)
|
||||
bcopy(m->m_data, m->m_data + ETHER_HDR_LEN, m->m_len);
|
||||
m->m_data += ETHER_HDR_LEN;
|
||||
} else {
|
||||
MGETHDR(n, M_DONTWAIT, MT_DATA);
|
||||
MGETHDR(n, M_NOWAIT, MT_DATA);
|
||||
if (n != NULL) {
|
||||
bcopy(m->m_data, n->m_data, ETHER_HDR_LEN);
|
||||
m->m_data += ETHER_HDR_LEN;
|
||||
@@ -3815,7 +3791,6 @@ lem_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
|
||||
static void
|
||||
lem_setup_vlan_hw_support(struct adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 reg;
|
||||
|
||||
@@ -3832,7 +3807,7 @@ lem_setup_vlan_hw_support(struct adapter *adapter)
|
||||
** A soft reset zero's out the VFTA, so
|
||||
** we need to repopulate it now.
|
||||
*/
|
||||
for (i = 0; i < EM_VFTA_SIZE; i++)
|
||||
for (int i = 0; i < EM_VFTA_SIZE; i++)
|
||||
if (adapter->shadow_vfta[i] != 0)
|
||||
E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
|
||||
i, adapter->shadow_vfta[i]);
|
||||
@@ -3846,10 +3821,6 @@ lem_setup_vlan_hw_support(struct adapter *adapter)
|
||||
reg &= ~E1000_RCTL_CFIEN;
|
||||
reg |= E1000_RCTL_VFE;
|
||||
E1000_WRITE_REG(hw, E1000_RCTL, reg);
|
||||
|
||||
/* Update the frame size */
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RLPML,
|
||||
adapter->max_frame_size + VLAN_TAG_SIZE);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3858,10 +3829,6 @@ lem_enable_intr(struct adapter *adapter)
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 ims_mask = IMS_ENABLE_MASK;
|
||||
|
||||
if (adapter->msix) {
|
||||
E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK);
|
||||
ims_mask |= EM_MSIX_MASK;
|
||||
}
|
||||
E1000_WRITE_REG(hw, E1000_IMS, ims_mask);
|
||||
}
|
||||
|
||||
@@ -3870,9 +3837,7 @@ lem_disable_intr(struct adapter *adapter)
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
|
||||
if (adapter->msix)
|
||||
E1000_WRITE_REG(hw, EM_EIAC, 0);
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
|
||||
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4097,13 +4062,12 @@ lem_enable_wakeup(device_t dev)
|
||||
static int
|
||||
lem_enable_phy_wakeup(struct adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 mreg, ret = 0;
|
||||
u16 preg;
|
||||
|
||||
/* copy MAC RARs to PHY RARs */
|
||||
for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
|
||||
for (int i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
|
||||
mreg = E1000_READ_REG(hw, E1000_RAL(i));
|
||||
e1000_write_phy_reg(hw, BM_RAR_L(i), (u16)(mreg & 0xFFFF));
|
||||
e1000_write_phy_reg(hw, BM_RAR_M(i),
|
||||
@@ -4115,7 +4079,7 @@ lem_enable_phy_wakeup(struct adapter *adapter)
|
||||
}
|
||||
|
||||
/* copy MAC MTA to PHY MTA */
|
||||
for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
|
||||
for (int i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
|
||||
mreg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
|
||||
e1000_write_phy_reg(hw, BM_MTA(i), (u16)(mreg & 0xFFFF));
|
||||
e1000_write_phy_reg(hw, BM_MTA(i) + 1,
|
||||
@@ -4661,6 +4625,8 @@ lem_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
|
||||
return (EINVAL);
|
||||
info->value = usecs;
|
||||
ticks = EM_USECS_TO_TICKS(usecs);
|
||||
if (info->offset == E1000_ITR) /* units are 256ns here */
|
||||
ticks *= 4;
|
||||
|
||||
adapter = info->adapter;
|
||||
|
||||
@@ -4709,7 +4675,6 @@ lem_set_flow_cntrl(struct adapter *adapter, const char *name,
|
||||
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
|
||||
}
|
||||
|
||||
#ifndef EM_LEGACY_IRQ
|
||||
static void
|
||||
lem_add_rx_process_limit(struct adapter *adapter, const char *name,
|
||||
const char *description, int *limit, int value)
|
||||
@@ -4719,4 +4684,3 @@ lem_add_rx_process_limit(struct adapter *adapter, const char *name,
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
|
||||
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -365,6 +365,7 @@ struct adapter {
|
||||
struct em_int_delay_info tx_abs_int_delay;
|
||||
struct em_int_delay_info rx_int_delay;
|
||||
struct em_int_delay_info rx_abs_int_delay;
|
||||
struct em_int_delay_info tx_itr;
|
||||
|
||||
/*
|
||||
* Transmit definitions
|
||||
|
||||
@@ -778,7 +778,7 @@ jme_attach(device_t dev)
|
||||
/* Set max allowable DMA size. */
|
||||
if (pci_find_cap(dev, PCIY_EXPRESS, &i) == 0) {
|
||||
sc->jme_flags |= JME_FLAG_PCIE;
|
||||
burst = pci_read_config(dev, i + PCIR_EXPRESS_DEVICE_CTL, 2);
|
||||
burst = pci_read_config(dev, i + PCIER_DEVICE_CTL, 2);
|
||||
if (bootverbose) {
|
||||
device_printf(dev, "Read request size : %d bytes.\n",
|
||||
128 << ((burst >> 12) & 0x07));
|
||||
@@ -1712,7 +1712,7 @@ jme_encap(struct jme_softc *sc, struct mbuf **m_head)
|
||||
|
||||
if (M_WRITABLE(*m_head) == 0) {
|
||||
/* Get a writable copy. */
|
||||
m = m_dup(*m_head, M_DONTWAIT);
|
||||
m = m_dup(*m_head, M_NOWAIT);
|
||||
m_freem(*m_head);
|
||||
if (m == NULL) {
|
||||
*m_head = NULL;
|
||||
@@ -1774,7 +1774,7 @@ jme_encap(struct jme_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->jme_cdata.jme_tx_tag,
|
||||
txd->tx_dmamap, *m_head, txsegs, &nsegs, 0);
|
||||
if (error == EFBIG) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, JME_MAXTXSEGS);
|
||||
m = m_collapse(*m_head, M_NOWAIT, JME_MAXTXSEGS);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -3181,7 +3181,7 @@ jme_newbuf(struct jme_softc *sc, struct jme_rxdesc *rxd)
|
||||
bus_dmamap_t map;
|
||||
int nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
/*
|
||||
|
||||
@@ -162,7 +162,7 @@ TUNABLE_INT("hw.msk.jumbo_disable", &jumbo_disable);
|
||||
/*
|
||||
* Devices supported by this driver.
|
||||
*/
|
||||
static struct msk_product {
|
||||
static const struct msk_product {
|
||||
uint16_t msk_vendorid;
|
||||
uint16_t msk_deviceid;
|
||||
const char *msk_name;
|
||||
@@ -257,6 +257,7 @@ static int mskc_shutdown(device_t);
|
||||
static int mskc_setup_rambuffer(struct msk_softc *);
|
||||
static int mskc_suspend(device_t);
|
||||
static int mskc_resume(device_t);
|
||||
static bus_dma_tag_t mskc_get_dma_tag(device_t, device_t);
|
||||
static void mskc_reset(struct msk_softc *);
|
||||
|
||||
static int msk_probe(device_t);
|
||||
@@ -334,6 +335,8 @@ static device_method_t mskc_methods[] = {
|
||||
DEVMETHOD(device_resume, mskc_resume),
|
||||
DEVMETHOD(device_shutdown, mskc_shutdown),
|
||||
|
||||
DEVMETHOD(bus_get_dma_tag, mskc_get_dma_tag),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
@@ -368,9 +371,9 @@ static driver_t msk_driver = {
|
||||
|
||||
static devclass_t msk_devclass;
|
||||
|
||||
DRIVER_MODULE(mskc, pci, mskc_driver, mskc_devclass, 0, 0);
|
||||
DRIVER_MODULE(msk, mskc, msk_driver, msk_devclass, 0, 0);
|
||||
DRIVER_MODULE(miibus, msk, miibus_driver, miibus_devclass, 0, 0);
|
||||
DRIVER_MODULE(mskc, pci, mskc_driver, mskc_devclass, NULL, NULL);
|
||||
DRIVER_MODULE(msk, mskc, msk_driver, msk_devclass, NULL, NULL);
|
||||
DRIVER_MODULE(miibus, msk, miibus_driver, miibus_devclass, NULL, NULL);
|
||||
|
||||
static struct resource_spec msk_res_spec_io[] = {
|
||||
{ SYS_RES_IOPORT, PCIR_BAR(1), RF_ACTIVE },
|
||||
@@ -648,8 +651,8 @@ msk_rx_fill(struct msk_if_softc *sc_if, int jumbo)
|
||||
if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 &&
|
||||
(sc_if->msk_ifp->if_capenable & IFCAP_RXCSUM) != 0) {
|
||||
/* Wait until controller executes OP_TCPSTART command. */
|
||||
for (i = 10; i > 0; i--) {
|
||||
DELAY(10);
|
||||
for (i = 100; i > 0; i--) {
|
||||
DELAY(100);
|
||||
idx = CSR_READ_2(sc_if->msk_softc,
|
||||
Y2_PREF_Q_ADDR(sc_if->msk_rxq,
|
||||
PREF_UNIT_GET_IDX_REG));
|
||||
@@ -897,7 +900,7 @@ msk_newbuf(struct msk_if_softc *sc_if, int idx)
|
||||
bus_dmamap_t map;
|
||||
int nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
|
||||
@@ -955,7 +958,7 @@ msk_jumbo_newbuf(struct msk_if_softc *sc_if, int idx)
|
||||
bus_dmamap_t map;
|
||||
int nsegs;
|
||||
|
||||
m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
if ((m->m_flags & M_EXT) == 0) {
|
||||
@@ -1180,15 +1183,14 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
static int
|
||||
mskc_probe(device_t dev)
|
||||
{
|
||||
struct msk_product *mp;
|
||||
const struct msk_product *mp;
|
||||
uint16_t vendor, devid;
|
||||
int i;
|
||||
|
||||
vendor = pci_get_vendor(dev);
|
||||
devid = pci_get_device(dev);
|
||||
mp = msk_products;
|
||||
for (i = 0; i < sizeof(msk_products)/sizeof(msk_products[0]);
|
||||
i++, mp++) {
|
||||
for (i = 0; i < nitems(msk_products); i++, mp++) {
|
||||
if (vendor == mp->msk_vendorid && devid == mp->msk_deviceid) {
|
||||
device_set_desc(dev, mp->msk_name);
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
@@ -1696,6 +1698,12 @@ msk_attach(device_t dev)
|
||||
ifp->if_capabilities |= IFCAP_VLAN_HWCSUM;
|
||||
}
|
||||
ifp->if_capenable = ifp->if_capabilities;
|
||||
/*
|
||||
* Disable RX checksum offloading on controllers that don't use
|
||||
* new descriptor format but give chance to enable it.
|
||||
*/
|
||||
if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0)
|
||||
ifp->if_capenable &= ~IFCAP_RXCSUM;
|
||||
|
||||
/*
|
||||
* Tell the upper layer(s) we support long frames.
|
||||
@@ -2113,6 +2121,13 @@ mskc_detach(device_t dev)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bus_dma_tag_t
|
||||
mskc_get_dma_tag(device_t bus, device_t child __unused)
|
||||
{
|
||||
|
||||
return (bus_get_dma_tag(bus));
|
||||
}
|
||||
|
||||
struct msk_dmamap_arg {
|
||||
bus_addr_t msk_busaddr;
|
||||
};
|
||||
@@ -2658,7 +2673,7 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
|
||||
|
||||
if (M_WRITABLE(m) == 0) {
|
||||
/* Get a writable copy. */
|
||||
m = m_dup(*m_head, M_DONTWAIT);
|
||||
m = m_dup(*m_head, M_NOWAIT);
|
||||
m_freem(*m_head);
|
||||
if (m == NULL) {
|
||||
*m_head = NULL;
|
||||
@@ -2737,7 +2752,7 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc_if->msk_cdata.msk_tx_tag, map,
|
||||
*m_head, txsegs, &nseg, BUS_DMA_NOWAIT);
|
||||
if (error == EFBIG) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, MSK_MAXTXSEGS);
|
||||
m = m_collapse(*m_head, M_NOWAIT, MSK_MAXTXSEGS);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
|
||||
@@ -1976,7 +1976,7 @@ nfe_newbuf(struct nfe_softc *sc, int idx)
|
||||
bus_dmamap_t map;
|
||||
int nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
|
||||
@@ -2032,7 +2032,7 @@ nfe_jnewbuf(struct nfe_softc *sc, int idx)
|
||||
bus_dmamap_t map;
|
||||
int nsegs;
|
||||
|
||||
m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
if ((m->m_flags & M_EXT) == 0) {
|
||||
@@ -2401,7 +2401,7 @@ nfe_encap(struct nfe_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->txq.tx_data_tag, map, *m_head, segs,
|
||||
&nsegs, BUS_DMA_NOWAIT);
|
||||
if (error == EFBIG) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, NFE_MAX_SCATTER);
|
||||
m = m_collapse(*m_head, M_NOWAIT, NFE_MAX_SCATTER);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
|
||||
@@ -394,7 +394,7 @@ lance_get(struct lance_softc *sc, int boff, int totlen)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
MGETHDR(m0, M_DONTWAIT, MT_DATA);
|
||||
MGETHDR(m0, M_NOWAIT, MT_DATA);
|
||||
if (m0 == NULL)
|
||||
return (NULL);
|
||||
m0->m_pkthdr.rcvif = ifp;
|
||||
@@ -404,7 +404,7 @@ lance_get(struct lance_softc *sc, int boff, int totlen)
|
||||
|
||||
while (totlen > 0) {
|
||||
if (totlen >= MINCLSIZE) {
|
||||
MCLGET(m, M_DONTWAIT);
|
||||
MCLGET(m, M_NOWAIT);
|
||||
if ((m->m_flags & M_EXT) == 0)
|
||||
goto bad;
|
||||
len = MCLBYTES;
|
||||
@@ -423,7 +423,7 @@ lance_get(struct lance_softc *sc, int boff, int totlen)
|
||||
|
||||
totlen -= len;
|
||||
if (totlen > 0) {
|
||||
MGET(newm, M_DONTWAIT, MT_DATA);
|
||||
MGET(newm, M_NOWAIT, MT_DATA);
|
||||
if (newm == 0)
|
||||
goto bad;
|
||||
len = MLEN;
|
||||
|
||||
@@ -1034,7 +1034,7 @@ vte_encap(struct vte_softc *sc, struct mbuf **m_head)
|
||||
if (M_WRITABLE(m) == 0) {
|
||||
if (m->m_next != NULL || padlen > 0) {
|
||||
/* Get a writable copy. */
|
||||
m = m_dup(*m_head, M_DONTWAIT);
|
||||
m = m_dup(*m_head, M_NOWAIT);
|
||||
/* Release original mbuf chains. */
|
||||
m_freem(*m_head);
|
||||
if (m == NULL) {
|
||||
@@ -1046,7 +1046,7 @@ vte_encap(struct vte_softc *sc, struct mbuf **m_head)
|
||||
}
|
||||
|
||||
if (m->m_next != NULL) {
|
||||
m = m_defrag(*m_head, M_DONTWAIT);
|
||||
m = m_defrag(*m_head, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -1057,7 +1057,7 @@ vte_encap(struct vte_softc *sc, struct mbuf **m_head)
|
||||
|
||||
if (padlen > 0) {
|
||||
if (M_TRAILINGSPACE(m) < padlen) {
|
||||
m = m_defrag(*m_head, M_DONTWAIT);
|
||||
m = m_defrag(*m_head, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -1422,7 +1422,7 @@ vte_newbuf(struct vte_softc *sc, struct vte_rxdesc *rxd)
|
||||
bus_dmamap_t map;
|
||||
int nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
m->m_len = m->m_pkthdr.len = MCLBYTES;
|
||||
@@ -1870,7 +1870,7 @@ vte_init_tx_ring(struct vte_softc *sc)
|
||||
/* Pre-allocate TX mbufs for deep copy. */
|
||||
if (tx_deep_copy != 0) {
|
||||
for (i = 0; i < VTE_TX_RING_CNT; i++) {
|
||||
sc->vte_cdata.vte_txmbufs[i] = m_getcl(M_DONTWAIT,
|
||||
sc->vte_cdata.vte_txmbufs[i] = m_getcl(M_NOWAIT,
|
||||
MT_DATA, M_PKTHDR);
|
||||
if (sc->vte_cdata.vte_txmbufs[i] == NULL)
|
||||
return (ENOBUFS);
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/rlphy.c,v 1.32.2.5.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* driver for RealTek 8139 internal PHYs
|
||||
@@ -66,7 +66,7 @@ static device_method_t rlphy_methods[] = {
|
||||
DEVMETHOD(device_attach, rlphy_attach),
|
||||
DEVMETHOD(device_detach, mii_phy_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
{ 0, 0 }
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static devclass_t rlphy_devclass;
|
||||
|
||||
@@ -488,7 +488,7 @@ rgephy_load_dspcode(struct mii_softc *sc)
|
||||
static void
|
||||
rgephy_reset(struct mii_softc *sc)
|
||||
{
|
||||
uint16_t ssr;
|
||||
uint16_t pcr, ssr;
|
||||
|
||||
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev == 3) {
|
||||
/* RTL8211C(L) */
|
||||
@@ -499,6 +499,15 @@ rgephy_reset(struct mii_softc *sc)
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->mii_mpd_rev >= 2) {
|
||||
pcr = PHY_READ(sc, RGEPHY_MII_PCR);
|
||||
if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) {
|
||||
pcr &= ~RGEPHY_PCR_MDI_MASK;
|
||||
pcr |= RGEPHY_PCR_MDIX_AUTO;
|
||||
PHY_WRITE(sc, RGEPHY_MII_PCR, pcr);
|
||||
}
|
||||
}
|
||||
|
||||
mii_phy_reset(sc);
|
||||
DELAY(1000);
|
||||
rgephy_load_dspcode(sc);
|
||||
|
||||
@@ -137,6 +137,17 @@
|
||||
#define RGEPHY_EXTSTS_T_FD_CAP 0x2000 /* 1000base-T FD capable */
|
||||
#define RGEPHY_EXTSTS_T_HD_CAP 0x1000 /* 1000base-T HD capable */
|
||||
|
||||
/* RTL8211B(L)/RTL8211C(L) */
|
||||
#define RGEPHY_MII_PCR 0x10 /* PHY Specific control register */
|
||||
#define RGEPHY_PCR_ASSERT_CRS 0x0800
|
||||
#define RGEPHY_PCR_FORCE_LINK 0x0400
|
||||
#define RGEPHY_PCR_MDI_MASK 0x0060
|
||||
#define RGEPHY_PCR_MDIX_AUTO 0x0040
|
||||
#define RGEPHY_PCR_MDIX_MANUAL 0x0020
|
||||
#define RGEPHY_PCR_MDI_MANUAL 0x0000
|
||||
#define RGEPHY_PCR_CLK125_DIS 0x0010
|
||||
#define RGEPHY_PCR_JABBER_DIS 0x0001
|
||||
|
||||
/* RTL8211B(L)/RTL8211C(L) */
|
||||
#define RGEPHY_MII_SSR 0x11 /* PHY Specific status register */
|
||||
#define RGEPHY_SSR_S1000 0x8000 /* 1000Mbps */
|
||||
|
||||
@@ -171,7 +171,7 @@ TUNABLE_INT("hw.re.prefer_iomap", &prefer_iomap);
|
||||
/*
|
||||
* Various supported device vendors/types and their names.
|
||||
*/
|
||||
static const struct rl_type const re_devs[] = {
|
||||
static const struct rl_type re_devs[] = {
|
||||
{ DLINK_VENDORID, DLINK_DEVICEID_528T, 0,
|
||||
"D-Link DGE-528(T) Gigabit Ethernet Adapter" },
|
||||
{ DLINK_VENDORID, DLINK_DEVICEID_530T_REVC, 0,
|
||||
@@ -194,7 +194,7 @@ static const struct rl_type const re_devs[] = {
|
||||
"US Robotics 997902 (RTL8169S) Gigabit Ethernet" }
|
||||
};
|
||||
|
||||
static const struct rl_hwrev const re_hwrevs[] = {
|
||||
static const struct rl_hwrev re_hwrevs[] = {
|
||||
{ RL_HWREV_8139, RL_8139, "", RL_MTU },
|
||||
{ RL_HWREV_8139A, RL_8139, "A", RL_MTU },
|
||||
{ RL_HWREV_8139AG, RL_8139, "A-G", RL_MTU },
|
||||
@@ -758,7 +758,7 @@ re_diag(struct rl_softc *sc)
|
||||
u_int8_t src[] = { 0x00, 'w', 'o', 'r', 'l', 'd' };
|
||||
|
||||
/* Allocate a single mbuf */
|
||||
MGETHDR(m0, M_DONTWAIT, MT_DATA);
|
||||
MGETHDR(m0, M_NOWAIT, MT_DATA);
|
||||
if (m0 == NULL)
|
||||
return (ENOBUFS);
|
||||
|
||||
@@ -1343,14 +1343,14 @@ re_attach(device_t dev)
|
||||
/* Disable ASPM L0S/L1. */
|
||||
if (sc->rl_expcap != 0) {
|
||||
cap = pci_read_config(dev, sc->rl_expcap +
|
||||
PCIR_EXPRESS_LINK_CAP, 2);
|
||||
if ((cap & PCIM_LINK_CAP_ASPM) != 0) {
|
||||
PCIER_LINK_CAP, 2);
|
||||
if ((cap & PCIEM_LINK_CAP_ASPM) != 0) {
|
||||
ctl = pci_read_config(dev, sc->rl_expcap +
|
||||
PCIR_EXPRESS_LINK_CTL, 2);
|
||||
PCIER_LINK_CTL, 2);
|
||||
if ((ctl & 0x0003) != 0) {
|
||||
ctl &= ~0x0003;
|
||||
pci_write_config(dev, sc->rl_expcap +
|
||||
PCIR_EXPRESS_LINK_CTL, ctl, 2);
|
||||
PCIER_LINK_CTL, ctl, 2);
|
||||
device_printf(dev, "ASPM disabled\n");
|
||||
}
|
||||
} else
|
||||
@@ -1587,7 +1587,8 @@ re_attach(device_t dev)
|
||||
* packet has IP options so disable TX IP checksum offloading.
|
||||
*/
|
||||
if (sc->rl_hwrev->rl_rev == RL_HWREV_8168C ||
|
||||
sc->rl_hwrev->rl_rev == RL_HWREV_8168C_SPIN2)
|
||||
sc->rl_hwrev->rl_rev == RL_HWREV_8168C_SPIN2 ||
|
||||
sc->rl_hwrev->rl_rev == RL_HWREV_8168CP)
|
||||
ifp->if_hwassist = CSUM_TCP | CSUM_UDP;
|
||||
else
|
||||
ifp->if_hwassist = CSUM_IP | CSUM_TCP | CSUM_UDP;
|
||||
@@ -1753,8 +1754,12 @@ re_detach(device_t dev)
|
||||
bus_teardown_intr(dev, sc->rl_irq[0], sc->rl_intrhand[0]);
|
||||
sc->rl_intrhand[0] = NULL;
|
||||
}
|
||||
if (ifp != NULL)
|
||||
if (ifp != NULL) {
|
||||
#ifdef DEV_NETMAP
|
||||
netmap_detach(ifp);
|
||||
#endif /* DEV_NETMAP */
|
||||
if_free(ifp);
|
||||
}
|
||||
if ((sc->rl_flags & (RL_FLAG_MSI | RL_FLAG_MSIX)) == 0)
|
||||
rid = 0;
|
||||
else
|
||||
@@ -1843,9 +1848,6 @@ re_detach(device_t dev)
|
||||
bus_dma_tag_destroy(sc->rl_ldata.rl_stag);
|
||||
}
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
netmap_detach(ifp);
|
||||
#endif /* DEV_NETMAP */
|
||||
if (sc->rl_parent_tag)
|
||||
bus_dma_tag_destroy(sc->rl_parent_tag);
|
||||
|
||||
@@ -1885,7 +1887,7 @@ re_newbuf(struct rl_softc *sc, int idx)
|
||||
uint32_t cmdstat;
|
||||
int error, nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
|
||||
@@ -1949,7 +1951,7 @@ re_jumbo_newbuf(struct rl_softc *sc, int idx)
|
||||
uint32_t cmdstat;
|
||||
int error, nsegs;
|
||||
|
||||
m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
m->m_len = m->m_pkthdr.len = MJUM9BYTES;
|
||||
@@ -2110,11 +2112,9 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
|
||||
|
||||
ifp = sc->rl_ifp;
|
||||
#ifdef DEV_NETMAP
|
||||
if (ifp->if_capenable & IFCAP_NETMAP) {
|
||||
NA(ifp)->rx_rings->nr_kflags |= NKR_PENDINTR;
|
||||
selwakeuppri(&NA(ifp)->rx_rings->si, PI_NET);
|
||||
if (netmap_rx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT),
|
||||
&rx_npkts))
|
||||
return 0;
|
||||
}
|
||||
#endif /* DEV_NETMAP */
|
||||
if (ifp->if_mtu > RL_MTU && (sc->rl_flags & RL_FLAG_JUMBOV2) != 0)
|
||||
jumbo = 1;
|
||||
@@ -2358,10 +2358,8 @@ re_txeof(struct rl_softc *sc)
|
||||
|
||||
ifp = sc->rl_ifp;
|
||||
#ifdef DEV_NETMAP
|
||||
if (ifp->if_capenable & IFCAP_NETMAP) {
|
||||
selwakeuppri(&NA(ifp)->tx_rings[0].si, PI_NET);
|
||||
if (netmap_tx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
|
||||
return;
|
||||
}
|
||||
#endif /* DEV_NETMAP */
|
||||
/* Invalidate the TX descriptor list */
|
||||
bus_dmamap_sync(sc->rl_ldata.rl_tx_list_tag,
|
||||
@@ -2699,7 +2697,7 @@ re_encap(struct rl_softc *sc, struct mbuf **m_head)
|
||||
padlen = RL_MIN_FRAMELEN - (*m_head)->m_pkthdr.len;
|
||||
if (M_WRITABLE(*m_head) == 0) {
|
||||
/* Get a writable copy. */
|
||||
m_new = m_dup(*m_head, M_DONTWAIT);
|
||||
m_new = m_dup(*m_head, M_NOWAIT);
|
||||
m_freem(*m_head);
|
||||
if (m_new == NULL) {
|
||||
*m_head = NULL;
|
||||
@@ -2709,7 +2707,7 @@ re_encap(struct rl_softc *sc, struct mbuf **m_head)
|
||||
}
|
||||
if ((*m_head)->m_next != NULL ||
|
||||
M_TRAILINGSPACE(*m_head) < padlen) {
|
||||
m_new = m_defrag(*m_head, M_DONTWAIT);
|
||||
m_new = m_defrag(*m_head, M_NOWAIT);
|
||||
if (m_new == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -2733,7 +2731,7 @@ re_encap(struct rl_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->rl_ldata.rl_tx_mtag, txd->tx_dmamap,
|
||||
*m_head, segs, &nsegs, BUS_DMA_NOWAIT);
|
||||
if (error == EFBIG) {
|
||||
m_new = m_collapse(*m_head, M_DONTWAIT, RL_NTXSEGS);
|
||||
m_new = m_collapse(*m_head, M_NOWAIT, RL_NTXSEGS);
|
||||
if (m_new == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -3418,7 +3416,8 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) {
|
||||
rev = sc->rl_hwrev->rl_rev;
|
||||
if (rev == RL_HWREV_8168C ||
|
||||
rev == RL_HWREV_8168C_SPIN2)
|
||||
rev == RL_HWREV_8168C_SPIN2 ||
|
||||
rev == RL_HWREV_8168CP)
|
||||
ifp->if_hwassist |= CSUM_TCP | CSUM_UDP;
|
||||
else
|
||||
ifp->if_hwassist |= RE_CSUM_FEATURES;
|
||||
|
||||
@@ -143,7 +143,7 @@ static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif
|
||||
|
||||
static struct sk_type sk_devs[] = {
|
||||
static const struct sk_type sk_devs[] = {
|
||||
{
|
||||
VENDORID_SK,
|
||||
DEVICEID_SK_V1,
|
||||
@@ -193,6 +193,7 @@ static int skc_detach(device_t);
|
||||
static int skc_shutdown(device_t);
|
||||
static int skc_suspend(device_t);
|
||||
static int skc_resume(device_t);
|
||||
static bus_dma_tag_t skc_get_dma_tag(device_t, device_t);
|
||||
static int sk_detach(device_t);
|
||||
static int sk_probe(device_t);
|
||||
static int sk_attach(device_t);
|
||||
@@ -300,6 +301,8 @@ static device_method_t skc_methods[] = {
|
||||
DEVMETHOD(device_resume, skc_resume),
|
||||
DEVMETHOD(device_shutdown, skc_shutdown),
|
||||
|
||||
DEVMETHOD(bus_get_dma_tag, skc_get_dma_tag),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
@@ -334,9 +337,9 @@ static driver_t sk_driver = {
|
||||
|
||||
static devclass_t sk_devclass;
|
||||
|
||||
DRIVER_MODULE(skc, pci, skc_driver, skc_devclass, 0, 0);
|
||||
DRIVER_MODULE(sk, skc, sk_driver, sk_devclass, 0, 0);
|
||||
DRIVER_MODULE(miibus, sk, miibus_driver, miibus_devclass, 0, 0);
|
||||
DRIVER_MODULE(skc, pci, skc_driver, skc_devclass, NULL, NULL);
|
||||
DRIVER_MODULE(sk, skc, sk_driver, sk_devclass, NULL, NULL);
|
||||
DRIVER_MODULE(miibus, sk, miibus_driver, miibus_devclass, NULL, NULL);
|
||||
|
||||
static struct resource_spec sk_res_spec_io[] = {
|
||||
{ SYS_RES_IOPORT, PCIR_BAR(1), RF_ACTIVE },
|
||||
@@ -982,7 +985,7 @@ sk_newbuf(sc_if, idx)
|
||||
bus_dmamap_t map;
|
||||
int nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
m->m_len = m->m_pkthdr.len = MCLBYTES;
|
||||
@@ -1027,7 +1030,7 @@ sk_jumbo_newbuf(sc_if, idx)
|
||||
bus_dmamap_t map;
|
||||
int nsegs;
|
||||
|
||||
m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUM9BYTES);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
if ((m->m_flags & M_EXT) == 0) {
|
||||
@@ -1203,7 +1206,7 @@ static int
|
||||
skc_probe(dev)
|
||||
device_t dev;
|
||||
{
|
||||
struct sk_type *t = sk_devs;
|
||||
const struct sk_type *t = sk_devs;
|
||||
|
||||
while(t->sk_name != NULL) {
|
||||
if ((pci_get_vendor(dev) == t->sk_vid) &&
|
||||
@@ -1906,6 +1909,13 @@ skc_detach(dev)
|
||||
return(0);
|
||||
}
|
||||
|
||||
static bus_dma_tag_t
|
||||
skc_get_dma_tag(device_t bus, device_t child __unused)
|
||||
{
|
||||
|
||||
return (bus_get_dma_tag(bus));
|
||||
}
|
||||
|
||||
struct sk_dmamap_arg {
|
||||
bus_addr_t sk_busaddr;
|
||||
};
|
||||
@@ -2411,7 +2421,7 @@ sk_encap(sc_if, m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc_if->sk_cdata.sk_tx_tag,
|
||||
txd->tx_dmamap, *m_head, txsegs, &nseg, 0);
|
||||
if (error == EFBIG) {
|
||||
m = m_defrag(*m_head, M_DONTWAIT);
|
||||
m = m_defrag(*m_head, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -3221,7 +3231,7 @@ sk_init_xmac(sc_if)
|
||||
struct sk_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
u_int16_t eaddr[(ETHER_ADDR_LEN+1)/2];
|
||||
struct sk_bcom_hack bhack[] = {
|
||||
static const struct sk_bcom_hack bhack[] = {
|
||||
{ 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 },
|
||||
{ 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 },
|
||||
{ 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 },
|
||||
|
||||
@@ -1289,7 +1289,7 @@
|
||||
struct sk_type {
|
||||
u_int16_t sk_vid;
|
||||
u_int16_t sk_did;
|
||||
char *sk_name;
|
||||
const char *sk_name;
|
||||
};
|
||||
|
||||
#define SK_ADDR_LO(x) ((u_int64_t) (x) & 0xffffffff)
|
||||
@@ -1450,7 +1450,9 @@ struct sk_softc {
|
||||
u_int32_t sk_pmd; /* physical media type */
|
||||
u_int32_t sk_coppertype;
|
||||
u_int32_t sk_intrmask;
|
||||
#ifdef __HAIKU__
|
||||
u_int32_t sk_intstatus;
|
||||
#endif
|
||||
int sk_int_mod;
|
||||
int sk_int_ticks;
|
||||
int sk_suspended;
|
||||
|
||||
@@ -119,7 +119,7 @@ static const struct vr_type {
|
||||
u_int16_t vr_did;
|
||||
int vr_quirks;
|
||||
const char *vr_name;
|
||||
} const vr_devs[] = {
|
||||
} vr_devs[] = {
|
||||
{ VIA_VENDORID, VIA_DEVICEID_RHINE,
|
||||
VR_Q_NEEDALIGN,
|
||||
"VIA VT3043 Rhine I 10/100BaseTX" },
|
||||
@@ -199,7 +199,7 @@ static const struct vr_tx_threshold_table {
|
||||
int tx_cfg;
|
||||
int bcr_cfg;
|
||||
int value;
|
||||
} const vr_tx_threshold_tables[] = {
|
||||
} vr_tx_threshold_tables[] = {
|
||||
{ VR_TXTHRESH_64BYTES, VR_BCR1_TXTHRESH64BYTES, 64 },
|
||||
{ VR_TXTHRESH_128BYTES, VR_BCR1_TXTHRESH128BYTES, 128 },
|
||||
{ VR_TXTHRESH_256BYTES, VR_BCR1_TXTHRESH256BYTES, 256 },
|
||||
@@ -1245,7 +1245,7 @@ vr_newbuf(struct vr_softc *sc, int idx)
|
||||
bus_dmamap_t map;
|
||||
int nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
m->m_len = m->m_pkthdr.len = MCLBYTES;
|
||||
@@ -1806,7 +1806,7 @@ vr_encap(struct vr_softc *sc, struct mbuf **m_head)
|
||||
* to copy, just do it all the time.
|
||||
*/
|
||||
if ((sc->vr_quirks & VR_Q_NEEDALIGN) != 0) {
|
||||
m = m_defrag(*m_head, M_DONTWAIT);
|
||||
m = m_defrag(*m_head, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -1825,7 +1825,7 @@ vr_encap(struct vr_softc *sc, struct mbuf **m_head)
|
||||
padlen = VR_MIN_FRAMELEN - m->m_pkthdr.len;
|
||||
if (M_WRITABLE(m) == 0) {
|
||||
/* Get a writable copy. */
|
||||
m = m_dup(*m_head, M_DONTWAIT);
|
||||
m = m_dup(*m_head, M_NOWAIT);
|
||||
m_freem(*m_head);
|
||||
if (m == NULL) {
|
||||
*m_head = NULL;
|
||||
@@ -1834,7 +1834,7 @@ vr_encap(struct vr_softc *sc, struct mbuf **m_head)
|
||||
*m_head = m;
|
||||
}
|
||||
if (m->m_next != NULL || M_TRAILINGSPACE(m) < padlen) {
|
||||
m = m_defrag(m, M_DONTWAIT);
|
||||
m = m_defrag(m, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -1856,7 +1856,7 @@ vr_encap(struct vr_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->vr_cdata.vr_tx_tag, txd->tx_dmamap,
|
||||
*m_head, txsegs, &nsegs, BUS_DMA_NOWAIT);
|
||||
if (error == EFBIG) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, VR_MAXFRAGS);
|
||||
m = m_collapse(*m_head, M_NOWAIT, VR_MAXFRAGS);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
|
||||
@@ -1239,7 +1239,7 @@ vge_newbuf(struct vge_softc *sc, int prod)
|
||||
bus_dmamap_t map;
|
||||
int i, nsegs;
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (ENOBUFS);
|
||||
/*
|
||||
@@ -1827,7 +1827,7 @@ vge_encap(struct vge_softc *sc, struct mbuf **m_head)
|
||||
padlen = VGE_MIN_FRAMELEN - m->m_pkthdr.len;
|
||||
if (M_WRITABLE(m) == 0) {
|
||||
/* Get a writable copy. */
|
||||
m = m_dup(*m_head, M_DONTWAIT);
|
||||
m = m_dup(*m_head, M_NOWAIT);
|
||||
m_freem(*m_head);
|
||||
if (m == NULL) {
|
||||
*m_head = NULL;
|
||||
@@ -1836,7 +1836,7 @@ vge_encap(struct vge_softc *sc, struct mbuf **m_head)
|
||||
*m_head = m;
|
||||
}
|
||||
if (M_TRAILINGSPACE(m) < padlen) {
|
||||
m = m_defrag(m, M_DONTWAIT);
|
||||
m = m_defrag(m, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
@@ -1858,7 +1858,7 @@ vge_encap(struct vge_softc *sc, struct mbuf **m_head)
|
||||
error = bus_dmamap_load_mbuf_sg(sc->vge_cdata.vge_tx_tag,
|
||||
txd->tx_dmamap, *m_head, txsegs, &nsegs, 0);
|
||||
if (error == EFBIG) {
|
||||
m = m_collapse(*m_head, M_DONTWAIT, VGE_MAXTXSEGS);
|
||||
m = m_collapse(*m_head, M_NOWAIT, VGE_MAXTXSEGS);
|
||||
if (m == NULL) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
|
||||
@@ -203,7 +203,8 @@ static char an_conf_cache[256];
|
||||
|
||||
/* sysctl vars */
|
||||
|
||||
SYSCTL_NODE(_hw, OID_AUTO, an, CTLFLAG_RD, 0, "Wireless driver parameters");
|
||||
static SYSCTL_NODE(_hw, OID_AUTO, an, CTLFLAG_RD, 0,
|
||||
"Wireless driver parameters");
|
||||
|
||||
/* XXX violate ethernet/netgraph callback hooks */
|
||||
extern void (*ng_ether_attach_p)(struct ifnet *ifp);
|
||||
@@ -946,12 +947,12 @@ an_rxeof(struct an_softc *sc)
|
||||
/* dump raw 802.11 packet to bpf and skip ip stack */
|
||||
BPF_TAP(ifp, bpf_buf, len);
|
||||
} else {
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
MGETHDR(m, M_NOWAIT, MT_DATA);
|
||||
if (m == NULL) {
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
MCLGET(m, M_DONTWAIT);
|
||||
MCLGET(m, M_NOWAIT);
|
||||
if (!(m->m_flags & M_EXT)) {
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
@@ -1037,12 +1038,12 @@ an_rxeof(struct an_softc *sc)
|
||||
if (an_rx_desc.an_done && !an_rx_desc.an_valid) {
|
||||
buf = sc->an_rx_buffer[count].an_dma_vaddr;
|
||||
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
MGETHDR(m, M_NOWAIT, MT_DATA);
|
||||
if (m == NULL) {
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
}
|
||||
MCLGET(m, M_DONTWAIT);
|
||||
MCLGET(m, M_NOWAIT);
|
||||
if (!(m->m_flags & M_EXT)) {
|
||||
m_freem(m);
|
||||
ifp->if_ierrors++;
|
||||
|
||||
@@ -141,7 +141,6 @@ static int
|
||||
an_attach_pci(dev)
|
||||
device_t dev;
|
||||
{
|
||||
u_int32_t command;
|
||||
struct an_softc *sc;
|
||||
int flags, error = 0;
|
||||
|
||||
@@ -153,19 +152,6 @@ an_attach_pci(dev)
|
||||
sc->mpi350 = 1;
|
||||
sc->port_rid = PCIR_BAR(0);
|
||||
} else {
|
||||
/*
|
||||
* Map control/status registers.
|
||||
*/
|
||||
command = pci_read_config(dev, PCIR_COMMAND, 4);
|
||||
command |= PCIM_CMD_PORTEN;
|
||||
pci_write_config(dev, PCIR_COMMAND, command, 4);
|
||||
command = pci_read_config(dev, PCIR_COMMAND, 4);
|
||||
|
||||
if (!(command & PCIM_CMD_PORTEN)) {
|
||||
device_printf(dev, "failed to enable I/O ports!\n");
|
||||
error = ENXIO;
|
||||
goto fail;
|
||||
}
|
||||
sc->port_rid = AN_PCI_LOIO;
|
||||
}
|
||||
error = an_alloc_port(dev, sc->port_rid, 1);
|
||||
|
||||
@@ -76,7 +76,8 @@ extern void DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...);
|
||||
|
||||
/* NB: put this here instead of the driver to avoid circular references */
|
||||
SYSCTL_NODE(_hw, OID_AUTO, ath, CTLFLAG_RD, 0, "Atheros driver parameters");
|
||||
SYSCTL_NODE(_hw_ath, OID_AUTO, hal, CTLFLAG_RD, 0, "Atheros HAL parameters");
|
||||
static SYSCTL_NODE(_hw_ath, OID_AUTO, hal, CTLFLAG_RD, 0,
|
||||
"Atheros HAL parameters");
|
||||
|
||||
#ifdef AH_DEBUG
|
||||
int ath_hal_debug = 0;
|
||||
@@ -85,7 +86,7 @@ SYSCTL_INT(_hw_ath_hal, OID_AUTO, debug, CTLFLAG_RW, &ath_hal_debug,
|
||||
TUNABLE_INT("hw.ath.hal.debug", &ath_hal_debug);
|
||||
#endif /* AH_DEBUG */
|
||||
|
||||
MALLOC_DEFINE(M_ATH_HAL, "ath_hal", "ath hal data");
|
||||
static MALLOC_DEFINE(M_ATH_HAL, "ath_hal", "ath hal data");
|
||||
|
||||
void*
|
||||
ath_hal_malloc(size_t size)
|
||||
|
||||
@@ -298,12 +298,12 @@ ath_hal_v4kEepromAttach(struct ath_hal *ah)
|
||||
"%s Error reading Eeprom MAGIC\n", __func__);
|
||||
return HAL_EEREAD;
|
||||
}
|
||||
}
|
||||
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s Eeprom Magic = 0x%x\n",
|
||||
__func__, magic);
|
||||
if (magic != AR5416_EEPROM_MAGIC) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "Bad magic number\n");
|
||||
return HAL_EEMAGIC;
|
||||
HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s Eeprom Magic = 0x%x\n",
|
||||
__func__, magic);
|
||||
if (magic != AR5416_EEPROM_MAGIC) {
|
||||
HALDEBUG(ah, HAL_DEBUG_ANY, "Bad magic number\n");
|
||||
return HAL_EEMAGIC;
|
||||
}
|
||||
}
|
||||
|
||||
ee = ath_hal_malloc(sizeof(HAL_EEPROM_v4k));
|
||||
|
||||
@@ -143,7 +143,7 @@ typedef struct RfHalFuncs {
|
||||
int16_t *minPower, int16_t *maxPower,
|
||||
const struct ieee80211_channel *, uint16_t *rfXpdGain);
|
||||
HAL_BOOL (*getChannelMaxMinPower)(struct ath_hal *ah,
|
||||
const const struct ieee80211_channel *,
|
||||
const struct ieee80211_channel *,
|
||||
int16_t *maxPow, int16_t *minPow);
|
||||
int16_t (*getNfAdjust)(struct ath_hal *, const HAL_CHANNEL_INTERNAL*);
|
||||
} RF_HAL_FUNCS;
|
||||
|
||||
-5
@@ -342,11 +342,6 @@ ar5416AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5,
|
||||
AR_PHY_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]);
|
||||
|
||||
/* Only set the ext channel cycpwr_thr1 field for ht/40 */
|
||||
if (IEEE80211_IS_CHAN_HT40(AH_PRIVATE(ah)->ah_curchan))
|
||||
OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
|
||||
AR_PHY_EXT_TIMING5_CYCPWR_THR1, params->cycPwrThr1[level]);
|
||||
|
||||
if (level > aniState->spurImmunityLevel)
|
||||
ahp->ah_stats.ast_ani_spurup++;
|
||||
else if (level < aniState->spurImmunityLevel)
|
||||
|
||||
@@ -258,7 +258,7 @@ static int ath_bstuck_threshold = 4; /* max missed beacons */
|
||||
SYSCTL_INT(_hw_ath, OID_AUTO, bstuck, CTLFLAG_RW, &ath_bstuck_threshold,
|
||||
0, "max missed beacon xmits before chip reset");
|
||||
|
||||
MALLOC_DEFINE(M_ATHDEV, "athdev", "ath driver dma buffers");
|
||||
static MALLOC_DEFINE(M_ATHDEV, "athdev", "ath driver dma buffers");
|
||||
|
||||
#define HAL_MODE_HT20 (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20)
|
||||
#define HAL_MODE_HT40 \
|
||||
|
||||
@@ -195,7 +195,7 @@ ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
|
||||
*/
|
||||
if (bf->bf_nseg > ATH_TXDESC) { /* too many desc's, linearize */
|
||||
sc->sc_stats.ast_tx_linear++;
|
||||
m = m_collapse(m0, M_DONTWAIT, ATH_TXDESC);
|
||||
m = m_collapse(m0, M_NOWAIT, ATH_TXDESC);
|
||||
if (m == NULL) {
|
||||
ath_freetx(m0);
|
||||
sc->sc_stats.ast_tx_nombuf++;
|
||||
|
||||
@@ -2539,7 +2539,7 @@ bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init)
|
||||
|
||||
KASSERT(buf_idx < BWI_RX_NDESC, ("buf_idx %d", buf_idx));
|
||||
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
|
||||
@@ -3020,7 +3020,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
|
||||
/*
|
||||
* Setup the embedded TX header
|
||||
*/
|
||||
M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
|
||||
M_PREPEND(m, sizeof(*hdr), M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
if_printf(ifp, "%s: prepend TX header failed\n", __func__);
|
||||
return ENOBUFS;
|
||||
@@ -3079,7 +3079,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
|
||||
if (error) { /* error == EFBIG */
|
||||
struct mbuf *m_new;
|
||||
|
||||
m_new = m_defrag(m, M_DONTWAIT);
|
||||
m_new = m_defrag(m, M_NOWAIT);
|
||||
if (m_new == NULL) {
|
||||
if_printf(ifp, "%s: can't defrag TX buffer\n",
|
||||
__func__);
|
||||
@@ -3200,7 +3200,7 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m,
|
||||
/*
|
||||
* Setup the embedded TX header
|
||||
*/
|
||||
M_PREPEND(m, sizeof(*hdr), M_DONTWAIT);
|
||||
M_PREPEND(m, sizeof(*hdr), M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
if_printf(ifp, "%s: prepend TX header failed\n", __func__);
|
||||
return ENOBUFS;
|
||||
@@ -3254,7 +3254,7 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m,
|
||||
__func__, error);
|
||||
goto back;
|
||||
}
|
||||
m_new = m_defrag(m, M_DONTWAIT);
|
||||
m_new = m_defrag(m, M_NOWAIT);
|
||||
if (m_new == NULL) {
|
||||
if_printf(ifp, "%s: can't defrag TX buffer\n",
|
||||
__func__);
|
||||
|
||||
@@ -709,7 +709,7 @@ ipw_dma_alloc(struct ipw_softc *sc)
|
||||
sbuf = &sc->rx_sbuf_list[i];
|
||||
sbd->bd = &sc->rbd_list[i];
|
||||
|
||||
sbuf->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
sbuf->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (sbuf->m == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not allocate rx mbuf\n");
|
||||
@@ -1207,7 +1207,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status,
|
||||
* drop the received packet and reuse the old mbuf. In the unlikely
|
||||
* case that the old mbuf can't be reloaded either, explicitly panic.
|
||||
*/
|
||||
mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (mnew == NULL) {
|
||||
ifp->if_ierrors++;
|
||||
return;
|
||||
@@ -1661,7 +1661,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
return error;
|
||||
}
|
||||
if (error != 0) {
|
||||
mnew = m_defrag(m0, M_DONTWAIT);
|
||||
mnew = m_defrag(m0, M_NOWAIT);
|
||||
if (mnew == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not defragment mbuf\n");
|
||||
|
||||
@@ -987,7 +987,7 @@ wpi_alloc_rx_ring(struct wpi_softc *sc, struct wpi_rx_ring *ring)
|
||||
__func__, error);
|
||||
goto fail;
|
||||
}
|
||||
m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
|
||||
if (m == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: could not allocate rx mbuf\n", __func__);
|
||||
@@ -1491,7 +1491,7 @@ wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc,
|
||||
}
|
||||
|
||||
/* XXX don't need mbuf, just dma buffer */
|
||||
mnew = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
|
||||
mnew = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
|
||||
if (mnew == NULL) {
|
||||
DPRINTFN(WPI_DEBUG_RX, ("%s: no mbuf to restock ring\n",
|
||||
__func__));
|
||||
@@ -1978,7 +1978,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
|
||||
}
|
||||
if (error != 0) {
|
||||
/* XXX use m_collapse */
|
||||
mnew = m_defrag(m0, M_DONTWAIT);
|
||||
mnew = m_defrag(m0, M_NOWAIT);
|
||||
if (mnew == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not defragment mbuf\n");
|
||||
@@ -2578,7 +2578,7 @@ wpi_scan(struct wpi_softc *sc)
|
||||
desc = &ring->desc[ring->cur];
|
||||
data = &ring->data[ring->cur];
|
||||
|
||||
data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
data->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (data->m == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not allocate mbuf for scan command\n");
|
||||
|
||||
@@ -89,7 +89,6 @@ static const struct iwn_ident iwn_ident_table[] = {
|
||||
{ 0x8086, 0x008b, "Intel Centrino Wireless-N 1030" },
|
||||
{ 0x8086, 0x0090, "Intel Centrino Advanced-N 6230" },
|
||||
{ 0x8086, 0x0091, "Intel Centrino Advanced-N 6230" },
|
||||
{ 0x8086, 0x088e, "Intel Centrino Advanced-N 6235" },
|
||||
{ 0x8086, 0x0885, "Intel Centrino Wireless-N + WiMAX 6150" },
|
||||
{ 0x8086, 0x0886, "Intel Centrino Wireless-N + WiMAX 6150" },
|
||||
{ 0x8086, 0x0896, "Intel Centrino Wireless-N 130" },
|
||||
@@ -456,12 +455,12 @@ iwn_attach(device_t dev)
|
||||
pci_write_config(dev, 0x41, 0, 1);
|
||||
|
||||
/* Hardware bug workaround. */
|
||||
reg = pci_read_config(dev, PCIR_COMMAND, 1);
|
||||
reg = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||
if (reg & PCIM_CMD_INTxDIS) {
|
||||
DPRINTF(sc, IWN_DEBUG_RESET, "%s: PCIe INTx Disable set\n",
|
||||
__func__);
|
||||
reg &= ~PCIM_CMD_INTxDIS;
|
||||
pci_write_config(dev, PCIR_COMMAND, reg, 1);
|
||||
pci_write_config(dev, PCIR_COMMAND, reg, 2);
|
||||
}
|
||||
|
||||
/* Enable bus-mastering. */
|
||||
@@ -1376,7 +1375,7 @@ iwn_alloc_rx_ring(struct iwn_softc *sc, struct iwn_rx_ring *ring)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
data->m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR,
|
||||
data->m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
|
||||
IWN_RBUF_SIZE);
|
||||
if (data->m == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
@@ -2333,7 +2332,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
|
||||
return;
|
||||
}
|
||||
|
||||
m1 = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, IWN_RBUF_SIZE);
|
||||
m1 = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, IWN_RBUF_SIZE);
|
||||
if (m1 == NULL) {
|
||||
DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
|
||||
__func__);
|
||||
@@ -3543,7 +3542,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
|
||||
return error;
|
||||
}
|
||||
/* Too many DMA segments, linearize mbuf. */
|
||||
m1 = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
|
||||
m1 = m_collapse(m, M_NOWAIT, IWN_MAX_SCATTER);
|
||||
if (m1 == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: could not defrag mbuf\n", __func__);
|
||||
@@ -3747,7 +3746,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m,
|
||||
return error;
|
||||
}
|
||||
/* Too many DMA segments, linearize mbuf. */
|
||||
m1 = m_collapse(m, M_DONTWAIT, IWN_MAX_SCATTER);
|
||||
m1 = m_collapse(m, M_NOWAIT, IWN_MAX_SCATTER);
|
||||
if (m1 == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"%s: could not defrag mbuf\n", __func__);
|
||||
@@ -3980,7 +3979,7 @@ iwn_cmd(struct iwn_softc *sc, int code, const void *buf, int size, int async)
|
||||
/* Command is too large to fit in a descriptor. */
|
||||
if (totlen > MCLBYTES)
|
||||
return EINVAL;
|
||||
m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
|
||||
if (m == NULL)
|
||||
return ENOMEM;
|
||||
cmd = mtod(m, struct iwn_tx_cmd *);
|
||||
|
||||
@@ -123,7 +123,7 @@ enum {
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
MALLOC_DEFINE(M_MALODEV, "malodev", "malo driver dma buffers");
|
||||
static MALLOC_DEFINE(M_MALODEV, "malodev", "malo driver dma buffers");
|
||||
|
||||
static struct ieee80211vap *malo_vap_create(struct ieee80211com *,
|
||||
const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
|
||||
@@ -854,7 +854,7 @@ malo_tx_dmasetup(struct malo_softc *sc, struct malo_txbuf *bf, struct mbuf *m0)
|
||||
*/
|
||||
if (error == EFBIG) { /* too many desc's, linearize */
|
||||
sc->malo_stats.mst_tx_linear++;
|
||||
m = m_defrag(m0, M_DONTWAIT);
|
||||
m = m_defrag(m0, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
m_freem(m0);
|
||||
sc->malo_stats.mst_tx_nombuf++;
|
||||
@@ -1396,7 +1396,7 @@ malo_getrxmbuf(struct malo_softc *sc, struct malo_rxbuf *bf)
|
||||
int error;
|
||||
|
||||
/* XXX don't need mbuf, just dma buffer */
|
||||
m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE);
|
||||
if (m == NULL) {
|
||||
sc->malo_stats.mst_rx_nombuf++; /* XXX */
|
||||
return NULL;
|
||||
|
||||
@@ -79,7 +79,7 @@ struct malo_pci_softc {
|
||||
* Tunable variables.
|
||||
*/
|
||||
SYSCTL_DECL(_hw_malo);
|
||||
SYSCTL_NODE(_hw_malo, OID_AUTO, pci, CTLFLAG_RD, 0,
|
||||
static SYSCTL_NODE(_hw_malo, OID_AUTO, pci, CTLFLAG_RD, 0,
|
||||
"Marvell 88W8335 driver PCI parameters");
|
||||
|
||||
static int msi_disable = 0; /* MSI disabled */
|
||||
|
||||
@@ -262,7 +262,7 @@ static void mwl_printtxbuf(const struct mwl_txbuf *bf, u_int qnum, u_int ix);
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
MALLOC_DEFINE(M_MWLDEV, "mwldev", "mwl driver dma buffers");
|
||||
static MALLOC_DEFINE(M_MWLDEV, "mwldev", "mwl driver dma buffers");
|
||||
|
||||
/*
|
||||
* Each packet has fixed front matter: a 2-byte length
|
||||
@@ -2807,7 +2807,7 @@ mwl_rx_proc(void *arg, int npending)
|
||||
* be a net loss. The tradeoff might be system
|
||||
* dependent (cache architecture is important).
|
||||
*/
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
MGETHDR(m, M_NOWAIT, MT_DATA);
|
||||
if (m == NULL) {
|
||||
DPRINTF(sc, MWL_DEBUG_ANY,
|
||||
"%s: no rx mbuf\n", __func__);
|
||||
@@ -3084,9 +3084,9 @@ mwl_tx_dmasetup(struct mwl_softc *sc, struct mwl_txbuf *bf, struct mbuf *m0)
|
||||
if (error == EFBIG) { /* too many desc's, linearize */
|
||||
sc->sc_stats.mst_tx_linear++;
|
||||
#if MWL_TXDESC > 1
|
||||
m = m_collapse(m0, M_DONTWAIT, MWL_TXDESC);
|
||||
m = m_collapse(m0, M_NOWAIT, MWL_TXDESC);
|
||||
#else
|
||||
m = m_defrag(m0, M_DONTWAIT);
|
||||
m = m_defrag(m0, M_NOWAIT);
|
||||
#endif
|
||||
if (m == NULL) {
|
||||
m_freem(m0);
|
||||
|
||||
@@ -120,29 +120,6 @@ mwl_pci_probe(device_t dev)
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
mwl_pci_setup(device_t dev)
|
||||
{
|
||||
u_int32_t cmd;
|
||||
|
||||
/*
|
||||
* Enable memory mapping and bus mastering.
|
||||
*/
|
||||
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
|
||||
cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
|
||||
pci_write_config(dev, PCIR_COMMAND, cmd, 4);
|
||||
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
|
||||
if ((cmd & PCIM_CMD_MEMEN) == 0) {
|
||||
device_printf(dev, "failed to enable memory mapping\n");
|
||||
return 0;
|
||||
}
|
||||
if ((cmd & PCIM_CMD_BUSMASTEREN) == 0) {
|
||||
device_printf(dev, "failed to enable bus mastering\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
mwl_pci_attach(device_t dev)
|
||||
{
|
||||
@@ -152,11 +129,8 @@ mwl_pci_attach(device_t dev)
|
||||
|
||||
sc->sc_dev = dev;
|
||||
|
||||
/*
|
||||
* Enable memory mapping and bus mastering.
|
||||
*/
|
||||
if (!mwl_pci_setup(dev))
|
||||
return 0;
|
||||
pci_enable_busmaster(dev);
|
||||
|
||||
/*
|
||||
* Setup memory-mapping of PCI registers.
|
||||
*/
|
||||
@@ -285,8 +259,7 @@ mwl_pci_resume(device_t dev)
|
||||
{
|
||||
struct mwl_pci_softc *psc = device_get_softc(dev);
|
||||
|
||||
if (!mwl_pci_setup(dev))
|
||||
return ENXIO;
|
||||
pci_enable_busmaster(dev);
|
||||
|
||||
mwl_resume(&psc->sc_sc);
|
||||
|
||||
|
||||
@@ -190,7 +190,8 @@ static void dumpresult(struct mwl_hal_priv *, int showresult);
|
||||
#endif /* MWLHAL_DEBUG */
|
||||
|
||||
SYSCTL_DECL(_hw_mwl);
|
||||
SYSCTL_NODE(_hw_mwl, OID_AUTO, hal, CTLFLAG_RD, 0, "Marvell HAL parameters");
|
||||
static SYSCTL_NODE(_hw_mwl, OID_AUTO, hal, CTLFLAG_RD, 0,
|
||||
"Marvell HAL parameters");
|
||||
|
||||
static __inline void
|
||||
MWL_HAL_LOCK(struct mwl_hal_priv *mh)
|
||||
|
||||
@@ -673,7 +673,7 @@ rt2560_alloc_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
data->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (data->m == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not allocate rx mbuf\n");
|
||||
@@ -1160,7 +1160,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
|
||||
* mbuf. In the unlikely case that the old mbuf can't be
|
||||
* reloaded either, explicitly panic.
|
||||
*/
|
||||
mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (mnew == NULL) {
|
||||
ifp->if_ierrors++;
|
||||
goto skip;
|
||||
@@ -1846,7 +1846,7 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
|
||||
return error;
|
||||
}
|
||||
if (error != 0) {
|
||||
mnew = m_defrag(m0, M_DONTWAIT);
|
||||
mnew = m_defrag(m0, M_NOWAIT);
|
||||
if (mnew == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not defragment mbuf\n");
|
||||
|
||||
@@ -682,7 +682,7 @@ rt2661_alloc_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
data->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (data->m == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not allocate rx mbuf\n");
|
||||
@@ -1030,7 +1030,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
|
||||
* mbuf. In the unlikely case that the old mbuf can't be
|
||||
* reloaded either, explicitly panic.
|
||||
*/
|
||||
mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (mnew == NULL) {
|
||||
ifp->if_ierrors++;
|
||||
goto skip;
|
||||
@@ -1536,7 +1536,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
|
||||
return error;
|
||||
}
|
||||
if (error != 0) {
|
||||
mnew = m_defrag(m0, M_DONTWAIT);
|
||||
mnew = m_defrag(m0, M_NOWAIT);
|
||||
if (mnew == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not defragment mbuf\n");
|
||||
|
||||
@@ -743,7 +743,7 @@ rt2860_alloc_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
data->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (data->m == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not allocate rx mbuf\n");
|
||||
@@ -1237,7 +1237,7 @@ rt2860_rx_intr(struct rt2860_softc *sc)
|
||||
}
|
||||
#endif
|
||||
|
||||
m1 = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m1 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (__predict_false(m1 == NULL)) {
|
||||
ifp->if_ierrors++;
|
||||
goto skip;
|
||||
@@ -1629,7 +1629,7 @@ rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
|
||||
}
|
||||
}
|
||||
if (__predict_false(error != 0)) {
|
||||
m1 = m_defrag(m, M_DONTWAIT);
|
||||
m1 = m_defrag(m, M_NOWAIT);
|
||||
if (m1 == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not defragment mbuf\n");
|
||||
@@ -1881,7 +1881,7 @@ rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m,
|
||||
}
|
||||
}
|
||||
if (__predict_false(error != 0)) {
|
||||
m1 = m_defrag(m, M_DONTWAIT);
|
||||
m1 = m_defrag(m, M_NOWAIT);
|
||||
if (m1 == NULL) {
|
||||
device_printf(sc->sc_dev,
|
||||
"could not defragment mbuf\n");
|
||||
|
||||
@@ -166,7 +166,8 @@ wi_write_val(struct wi_softc *sc, int rid, u_int16_t val)
|
||||
return wi_write_rid(sc, rid, &val, sizeof(val));
|
||||
}
|
||||
|
||||
SYSCTL_NODE(_hw, OID_AUTO, wi, CTLFLAG_RD, 0, "Wireless driver parameters");
|
||||
static SYSCTL_NODE(_hw, OID_AUTO, wi, CTLFLAG_RD, 0,
|
||||
"Wireless driver parameters");
|
||||
|
||||
static struct timeval lasttxerror; /* time of last tx error msg */
|
||||
static int curtxeps; /* current tx error msgs/sec */
|
||||
@@ -1359,9 +1360,9 @@ wi_rx_intr(struct wi_softc *sc)
|
||||
}
|
||||
|
||||
if (off + len > MHLEN)
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
else
|
||||
m = m_gethdr(M_DONTWAIT, MT_DATA);
|
||||
m = m_gethdr(M_NOWAIT, MT_DATA);
|
||||
if (m == NULL) {
|
||||
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
|
||||
ifp->if_ierrors++;
|
||||
|
||||
@@ -137,23 +137,13 @@ static int
|
||||
wi_pci_attach(device_t dev)
|
||||
{
|
||||
struct wi_softc *sc;
|
||||
u_int32_t command, wanted;
|
||||
u_int32_t command;
|
||||
u_int16_t reg;
|
||||
int error;
|
||||
int timeout;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
command = pci_read_config(dev, PCIR_COMMAND, 4);
|
||||
wanted = PCIM_CMD_PORTEN|PCIM_CMD_MEMEN;
|
||||
command |= wanted;
|
||||
pci_write_config(dev, PCIR_COMMAND, command, 4);
|
||||
command = pci_read_config(dev, PCIR_COMMAND, 4);
|
||||
if ((command & wanted) != wanted) {
|
||||
device_printf(dev, "wi_pci_attach() failed to enable pci!\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) {
|
||||
error = wi_alloc(dev, WI_PCI_IORES);
|
||||
if (error)
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#define PCIM_CMD_BACKTOBACK 0x0200
|
||||
#define PCIM_CMD_INTxDIS 0x0400
|
||||
#define PCIR_STATUS 0x06
|
||||
#define PCIM_STATUS_INTxSTATE 0x0008
|
||||
#define PCIM_STATUS_CAPPRESENT 0x0010
|
||||
#define PCIM_STATUS_66CAPABLE 0x0020
|
||||
#define PCIM_STATUS_BACKTOBACK 0x0080
|
||||
@@ -134,11 +135,22 @@
|
||||
#define PCIZ_VC 0x0002 /* Virtual Channel */
|
||||
#define PCIZ_SERNUM 0x0003 /* Device Serial Number */
|
||||
#define PCIZ_PWRBDGT 0x0004 /* Power Budgeting */
|
||||
#define PCIZ_RCLINK_DCL 0x0005 /* Root Complex Link Declaration */
|
||||
#define PCIZ_RCLINK_CTL 0x0006 /* Root Complex Internal Link Control */
|
||||
#define PCIZ_RCEC_ASSOC 0x0007 /* Root Complex Event Collector Association */
|
||||
#define PCIZ_MFVC 0x0008 /* Multi-Function Virtual Channel */
|
||||
#define PCIZ_RCRB 0x000a /* RCRB Header */
|
||||
#define PCIZ_VENDOR 0x000b /* Vendor Unique */
|
||||
#define PCIZ_ACS 0x000d /* Access Control Services */
|
||||
#define PCIZ_ARI 0x000e /* Alternative Routing-ID Interpretation */
|
||||
#define PCIZ_ATS 0x000f /* Address Translation Services */
|
||||
#define PCIZ_SRIOV 0x0010 /* Single Root IO Virtualization */
|
||||
#define PCIZ_MULTICAST 0x0012 /* Multicast */
|
||||
#define PCIZ_RESIZE_BAR 0x0015 /* Resizable BAR */
|
||||
#define PCIZ_DPA 0x0016 /* Dynamic Power Allocation */
|
||||
#define PCIZ_TPH_REQ 0x0017 /* TPH Requester */
|
||||
#define PCIZ_LTR 0x0018 /* Latency Tolerance Reporting */
|
||||
#define PCIZ_SEC_PCIE 0x0019 /* Secondary PCI Express */
|
||||
|
||||
/* config registers for header type 0 devices */
|
||||
|
||||
@@ -263,6 +275,9 @@
|
||||
#define PCIS_STORAGE_SATA 0x06
|
||||
#define PCIP_STORAGE_SATA_AHCI_1_0 0x01
|
||||
#define PCIS_STORAGE_SAS 0x07
|
||||
#define PCIS_STORAGE_NVM 0x08
|
||||
#define PCIP_STORAGE_NVM_NVMHCI_1_0 0x01
|
||||
#define PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0 0x02
|
||||
#define PCIS_STORAGE_OTHER 0x80
|
||||
|
||||
#define PCIC_NETWORK 0x02
|
||||
@@ -597,6 +612,10 @@
|
||||
#define PCIM_HTCAP_VCSET 0xb800 /* 10111 */
|
||||
#define PCIM_HTCAP_RETRY_MODE 0xc000 /* 11000 */
|
||||
#define PCIM_HTCAP_X86_ENCODING 0xc800 /* 11001 */
|
||||
#define PCIM_HTCAP_GEN3 0xd000 /* 11010 */
|
||||
#define PCIM_HTCAP_FLE 0xd800 /* 11011 */
|
||||
#define PCIM_HTCAP_PM 0xe000 /* 11100 */
|
||||
#define PCIM_HTCAP_HIGH_NODE_COUNT 0xe800 /* 11101 */
|
||||
|
||||
/* HT MSI Mapping Capability definitions. */
|
||||
#define PCIM_HTCMD_MSI_ENABLE 0x0001
|
||||
@@ -617,56 +636,258 @@
|
||||
#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_TYPE_PCIE_BRIDGE 0x0080
|
||||
#define PCIM_EXP_TYPE_ROOT_INT_EP 0x0090
|
||||
#define PCIM_EXP_TYPE_ROOT_EC 0x00a0
|
||||
#define PCIM_EXP_FLAGS_SLOT 0x0100
|
||||
#define PCIM_EXP_FLAGS_IRQ 0x3e00
|
||||
#define PCIR_EXPRESS_DEVICE_CAP 0x4
|
||||
#define PCIM_EXP_CAP_MAX_PAYLOAD 0x0007
|
||||
#define PCIR_EXPRESS_DEVICE_CTL 0x8
|
||||
#define PCIM_EXP_CTL_NFER_ENABLE 0x0002
|
||||
#define PCIM_EXP_CTL_FER_ENABLE 0x0004
|
||||
#define PCIM_EXP_CTL_URR_ENABLE 0x0008
|
||||
#define PCIM_EXP_CTL_RELAXED_ORD_ENABLE 0x0010
|
||||
#define PCIM_EXP_CTL_MAX_PAYLOAD 0x00e0
|
||||
#define PCIM_EXP_CTL_NOSNOOP_ENABLE 0x0800
|
||||
#define PCIM_EXP_CTL_MAX_READ_REQUEST 0x7000
|
||||
#define PCIR_EXPRESS_DEVICE_STA 0xa
|
||||
#define PCIM_EXP_STA_CORRECTABLE_ERROR 0x0001
|
||||
#define PCIM_EXP_STA_NON_FATAL_ERROR 0x0002
|
||||
#define PCIM_EXP_STA_FATAL_ERROR 0x0004
|
||||
#define PCIM_EXP_STA_UNSUPPORTED_REQ 0x0008
|
||||
#define PCIM_EXP_STA_AUX_POWER 0x0010
|
||||
#define PCIM_EXP_STA_TRANSACTION_PND 0x0020
|
||||
#define PCIR_EXPRESS_LINK_CAP 0xc
|
||||
#define PCIM_LINK_CAP_MAX_SPEED 0x0000000f
|
||||
#define PCIM_LINK_CAP_MAX_WIDTH 0x000003f0
|
||||
#define PCIM_LINK_CAP_ASPM 0x00000c00
|
||||
#define PCIM_LINK_CAP_L0S_EXIT 0x00007000
|
||||
#define PCIM_LINK_CAP_L1_EXIT 0x00038000
|
||||
#define PCIM_LINK_CAP_PORT 0xff000000
|
||||
#define PCIR_EXPRESS_LINK_CTL 0x10
|
||||
#define PCIR_EXPRESS_LINK_STA 0x12
|
||||
#define PCIM_LINK_STA_SPEED 0x000f
|
||||
#define PCIM_LINK_STA_WIDTH 0x03f0
|
||||
#define PCIM_LINK_STA_TRAINING_ERROR 0x0400
|
||||
#define PCIM_LINK_STA_TRAINING 0x0800
|
||||
#define PCIM_LINK_STA_SLOT_CLOCK 0x1000
|
||||
#define PCIR_EXPRESS_SLOT_CAP 0x14
|
||||
#define PCIR_EXPRESS_SLOT_CTL 0x18
|
||||
#define PCIR_EXPRESS_SLOT_STA 0x1a
|
||||
#define PCIR_EXPRESS_ROOT_CTL 0x1c
|
||||
#define PCIR_EXPRESS_ROOT_STA 0x20
|
||||
#define PCIER_FLAGS 0x2
|
||||
#define PCIEM_FLAGS_VERSION 0x000F
|
||||
#define PCIEM_FLAGS_TYPE 0x00F0
|
||||
#define PCIEM_TYPE_ENDPOINT 0x0000
|
||||
#define PCIEM_TYPE_LEGACY_ENDPOINT 0x0010
|
||||
#define PCIEM_TYPE_ROOT_PORT 0x0040
|
||||
#define PCIEM_TYPE_UPSTREAM_PORT 0x0050
|
||||
#define PCIEM_TYPE_DOWNSTREAM_PORT 0x0060
|
||||
#define PCIEM_TYPE_PCI_BRIDGE 0x0070
|
||||
#define PCIEM_TYPE_PCIE_BRIDGE 0x0080
|
||||
#define PCIEM_TYPE_ROOT_INT_EP 0x0090
|
||||
#define PCIEM_TYPE_ROOT_EC 0x00a0
|
||||
#define PCIEM_FLAGS_SLOT 0x0100
|
||||
#define PCIEM_FLAGS_IRQ 0x3e00
|
||||
#define PCIER_DEVICE_CAP 0x4
|
||||
#define PCIEM_CAP_MAX_PAYLOAD 0x00000007
|
||||
#define PCIEM_CAP_PHANTHOM_FUNCS 0x00000018
|
||||
#define PCIEM_CAP_EXT_TAG_FIELD 0x00000020
|
||||
#define PCIEM_CAP_L0S_LATENCY 0x000001c0
|
||||
#define PCIEM_CAP_L1_LATENCY 0x00000e00
|
||||
#define PCIEM_CAP_ROLE_ERR_RPT 0x00008000
|
||||
#define PCIEM_CAP_SLOT_PWR_LIM_VAL 0x03fc0000
|
||||
#define PCIEM_CAP_SLOT_PWR_LIM_SCALE 0x0c000000
|
||||
#define PCIEM_CAP_FLR 0x10000000
|
||||
#define PCIER_DEVICE_CTL 0x8
|
||||
#define PCIEM_CTL_COR_ENABLE 0x0001
|
||||
#define PCIEM_CTL_NFER_ENABLE 0x0002
|
||||
#define PCIEM_CTL_FER_ENABLE 0x0004
|
||||
#define PCIEM_CTL_URR_ENABLE 0x0008
|
||||
#define PCIEM_CTL_RELAXED_ORD_ENABLE 0x0010
|
||||
#define PCIEM_CTL_MAX_PAYLOAD 0x00e0
|
||||
#define PCIEM_CTL_EXT_TAG_FIELD 0x0100
|
||||
#define PCIEM_CTL_PHANTHOM_FUNCS 0x0200
|
||||
#define PCIEM_CTL_AUX_POWER_PM 0x0400
|
||||
#define PCIEM_CTL_NOSNOOP_ENABLE 0x0800
|
||||
#define PCIEM_CTL_MAX_READ_REQUEST 0x7000
|
||||
#define PCIEM_CTL_BRDG_CFG_RETRY 0x8000 /* PCI-E - PCI/PCI-X bridges */
|
||||
#define PCIEM_CTL_INITIATE_FLR 0x8000 /* FLR capable endpoints */
|
||||
#define PCIER_DEVICE_STA 0xa
|
||||
#define PCIEM_STA_CORRECTABLE_ERROR 0x0001
|
||||
#define PCIEM_STA_NON_FATAL_ERROR 0x0002
|
||||
#define PCIEM_STA_FATAL_ERROR 0x0004
|
||||
#define PCIEM_STA_UNSUPPORTED_REQ 0x0008
|
||||
#define PCIEM_STA_AUX_POWER 0x0010
|
||||
#define PCIEM_STA_TRANSACTION_PND 0x0020
|
||||
#define PCIER_LINK_CAP 0xc
|
||||
#define PCIEM_LINK_CAP_MAX_SPEED 0x0000000f
|
||||
#define PCIEM_LINK_CAP_MAX_WIDTH 0x000003f0
|
||||
#define PCIEM_LINK_CAP_ASPM 0x00000c00
|
||||
#define PCIEM_LINK_CAP_L0S_EXIT 0x00007000
|
||||
#define PCIEM_LINK_CAP_L1_EXIT 0x00038000
|
||||
#define PCIEM_LINK_CAP_CLOCK_PM 0x00040000
|
||||
#define PCIEM_LINK_CAP_SURPRISE_DOWN 0x00080000
|
||||
#define PCIEM_LINK_CAP_DL_ACTIVE 0x00100000
|
||||
#define PCIEM_LINK_CAP_LINK_BW_NOTIFY 0x00200000
|
||||
#define PCIEM_LINK_CAP_ASPM_COMPLIANCE 0x00400000
|
||||
#define PCIEM_LINK_CAP_PORT 0xff000000
|
||||
#define PCIER_LINK_CTL 0x10
|
||||
#define PCIEM_LINK_CTL_ASPMC_DIS 0x0000
|
||||
#define PCIEM_LINK_CTL_ASPMC_L0S 0x0001
|
||||
#define PCIEM_LINK_CTL_ASPMC_L1 0x0002
|
||||
#define PCIEM_LINK_CTL_ASPMC 0x0003
|
||||
#define PCIEM_LINK_CTL_RCB 0x0008
|
||||
#define PCIEM_LINK_CTL_LINK_DIS 0x0010
|
||||
#define PCIEM_LINK_CTL_RETRAIN_LINK 0x0020
|
||||
#define PCIEM_LINK_CTL_COMMON_CLOCK 0x0040
|
||||
#define PCIEM_LINK_CTL_EXTENDED_SYNC 0x0080
|
||||
#define PCIEM_LINK_CTL_ECPM 0x0100
|
||||
#define PCIEM_LINK_CTL_HAWD 0x0200
|
||||
#define PCIEM_LINK_CTL_LBMIE 0x0400
|
||||
#define PCIEM_LINK_CTL_LABIE 0x0800
|
||||
#define PCIER_LINK_STA 0x12
|
||||
#define PCIEM_LINK_STA_SPEED 0x000f
|
||||
#define PCIEM_LINK_STA_WIDTH 0x03f0
|
||||
#define PCIEM_LINK_STA_TRAINING_ERROR 0x0400
|
||||
#define PCIEM_LINK_STA_TRAINING 0x0800
|
||||
#define PCIEM_LINK_STA_SLOT_CLOCK 0x1000
|
||||
#define PCIEM_LINK_STA_DL_ACTIVE 0x2000
|
||||
#define PCIEM_LINK_STA_LINK_BW_MGMT 0x4000
|
||||
#define PCIEM_LINK_STA_LINK_AUTO_BW 0x8000
|
||||
#define PCIER_SLOT_CAP 0x14
|
||||
#define PCIEM_SLOT_CAP_APB 0x00000001
|
||||
#define PCIEM_SLOT_CAP_PCP 0x00000002
|
||||
#define PCIEM_SLOT_CAP_MRLSP 0x00000004
|
||||
#define PCIEM_SLOT_CAP_AIP 0x00000008
|
||||
#define PCIEM_SLOT_CAP_PIP 0x00000010
|
||||
#define PCIEM_SLOT_CAP_HPS 0x00000020
|
||||
#define PCIEM_SLOT_CAP_HPC 0x00000040
|
||||
#define PCIEM_SLOT_CAP_SPLV 0x00007f80
|
||||
#define PCIEM_SLOT_CAP_SPLS 0x00018000
|
||||
#define PCIEM_SLOT_CAP_EIP 0x00020000
|
||||
#define PCIEM_SLOT_CAP_NCCS 0x00040000
|
||||
#define PCIEM_SLOT_CAP_PSN 0xfff80000
|
||||
#define PCIER_SLOT_CTL 0x18
|
||||
#define PCIEM_SLOT_CTL_ABPE 0x0001
|
||||
#define PCIEM_SLOT_CTL_PFDE 0x0002
|
||||
#define PCIEM_SLOT_CTL_MRLSCE 0x0004
|
||||
#define PCIEM_SLOT_CTL_PDCE 0x0008
|
||||
#define PCIEM_SLOT_CTL_CCIE 0x0010
|
||||
#define PCIEM_SLOT_CTL_HPIE 0x0020
|
||||
#define PCIEM_SLOT_CTL_AIC 0x00c0
|
||||
#define PCIEM_SLOT_CTL_PIC 0x0300
|
||||
#define PCIEM_SLOT_CTL_PCC 0x0400
|
||||
#define PCIEM_SLOT_CTL_EIC 0x0800
|
||||
#define PCIEM_SLOT_CTL_DLLSCE 0x1000
|
||||
#define PCIER_SLOT_STA 0x1a
|
||||
#define PCIEM_SLOT_STA_ABP 0x0001
|
||||
#define PCIEM_SLOT_STA_PFD 0x0002
|
||||
#define PCIEM_SLOT_STA_MRLSC 0x0004
|
||||
#define PCIEM_SLOT_STA_PDC 0x0008
|
||||
#define PCIEM_SLOT_STA_CC 0x0010
|
||||
#define PCIEM_SLOT_STA_MRLSS 0x0020
|
||||
#define PCIEM_SLOT_STA_PDS 0x0040
|
||||
#define PCIEM_SLOT_STA_EIS 0x0080
|
||||
#define PCIEM_SLOT_STA_DLLSC 0x0100
|
||||
#define PCIER_ROOT_CTL 0x1c
|
||||
#define PCIER_ROOT_CAP 0x1e
|
||||
#define PCIER_ROOT_STA 0x20
|
||||
#define PCIER_DEVICE_CAP2 0x24
|
||||
#define PCIER_DEVICE_CTL2 0x28
|
||||
#define PCIEM_CTL2_COMP_TIMEOUT_VAL 0x000f
|
||||
#define PCIEM_CTL2_COMP_TIMEOUT_DIS 0x0010
|
||||
#define PCIEM_CTL2_ARI 0x0020
|
||||
#define PCIEM_CTL2_ATOMIC_REQ_ENABLE 0x0040
|
||||
#define PCIEM_CTL2_ATOMIC_EGR_BLOCK 0x0080
|
||||
#define PCIEM_CTL2_ID_ORDERED_REQ_EN 0x0100
|
||||
#define PCIEM_CTL2_ID_ORDERED_CMP_EN 0x0200
|
||||
#define PCIEM_CTL2_LTR_ENABLE 0x0400
|
||||
#define PCIEM_CTL2_OBFF 0x6000
|
||||
#define PCIEM_OBFF_DISABLE 0x0000
|
||||
#define PCIEM_OBFF_MSGA_ENABLE 0x2000
|
||||
#define PCIEM_OBFF_MSGB_ENABLE 0x4000
|
||||
#define PCIEM_OBFF_WAKE_ENABLE 0x6000
|
||||
#define PCIEM_CTL2_END2END_TLP 0x8000
|
||||
#define PCIER_DEVICE_STA2 0x2a
|
||||
#define PCIER_LINK_CAP2 0x2c
|
||||
#define PCIER_LINK_CTL2 0x30
|
||||
#define PCIER_LINK_STA2 0x32
|
||||
#define PCIER_SLOT_CAP2 0x34
|
||||
#define PCIER_SLOT_CTL2 0x38
|
||||
#define PCIER_SLOT_STA2 0x3a
|
||||
|
||||
/* Old compatibility definitions for PCI Express registers */
|
||||
#define PCIR_EXPRESS_FLAGS PCIER_FLAGS
|
||||
#define PCIM_EXP_FLAGS_VERSION PCIEM_FLAGS_VERSION
|
||||
#define PCIM_EXP_FLAGS_TYPE PCIEM_FLAGS_TYPE
|
||||
#define PCIM_EXP_TYPE_ENDPOINT PCIEM_TYPE_ENDPOINT
|
||||
#define PCIM_EXP_TYPE_LEGACY_ENDPOINT PCIEM_TYPE_LEGACY_ENDPOINT
|
||||
#define PCIM_EXP_TYPE_ROOT_PORT PCIEM_TYPE_ROOT_PORT
|
||||
#define PCIM_EXP_TYPE_UPSTREAM_PORT PCIEM_TYPE_UPSTREAM_PORT
|
||||
#define PCIM_EXP_TYPE_DOWNSTREAM_PORT PCIEM_TYPE_DOWNSTREAM_PORT
|
||||
#define PCIM_EXP_TYPE_PCI_BRIDGE PCIEM_TYPE_PCI_BRIDGE
|
||||
#define PCIM_EXP_TYPE_PCIE_BRIDGE PCIEM_TYPE_PCIE_BRIDGE
|
||||
#define PCIM_EXP_TYPE_ROOT_INT_EP PCIEM_TYPE_ROOT_INT_EP
|
||||
#define PCIM_EXP_TYPE_ROOT_EC PCIEM_TYPE_ROOT_EC
|
||||
#define PCIM_EXP_FLAGS_SLOT PCIEM_FLAGS_SLOT
|
||||
#define PCIM_EXP_FLAGS_IRQ PCIEM_FLAGS_IRQ
|
||||
#define PCIR_EXPRESS_DEVICE_CAP PCIER_DEVICE_CAP
|
||||
#define PCIM_EXP_CAP_MAX_PAYLOAD PCIEM_CAP_MAX_PAYLOAD
|
||||
#define PCIM_EXP_CAP_PHANTHOM_FUNCS PCIEM_CAP_PHANTHOM_FUNCS
|
||||
#define PCIM_EXP_CAP_EXT_TAG_FIELD PCIEM_CAP_EXT_TAG_FIELD
|
||||
#define PCIM_EXP_CAP_L0S_LATENCY PCIEM_CAP_L0S_LATENCY
|
||||
#define PCIM_EXP_CAP_L1_LATENCY PCIEM_CAP_L1_LATENCY
|
||||
#define PCIM_EXP_CAP_ROLE_ERR_RPT PCIEM_CAP_ROLE_ERR_RPT
|
||||
#define PCIM_EXP_CAP_SLOT_PWR_LIM_VAL PCIEM_CAP_SLOT_PWR_LIM_VAL
|
||||
#define PCIM_EXP_CAP_SLOT_PWR_LIM_SCALE PCIEM_CAP_SLOT_PWR_LIM_SCALE
|
||||
#define PCIM_EXP_CAP_FLR PCIEM_CAP_FLR
|
||||
#define PCIR_EXPRESS_DEVICE_CTL PCIER_DEVICE_CTL
|
||||
#define PCIM_EXP_CTL_COR_ENABLE PCIEM_CTL_COR_ENABLE
|
||||
#define PCIM_EXP_CTL_NFER_ENABLE PCIEM_CTL_NFER_ENABLE
|
||||
#define PCIM_EXP_CTL_FER_ENABLE PCIEM_CTL_FER_ENABLE
|
||||
#define PCIM_EXP_CTL_URR_ENABLE PCIEM_CTL_URR_ENABLE
|
||||
#define PCIM_EXP_CTL_RELAXED_ORD_ENABLE PCIEM_CTL_RELAXED_ORD_ENABLE
|
||||
#define PCIM_EXP_CTL_MAX_PAYLOAD PCIEM_CTL_MAX_PAYLOAD
|
||||
#define PCIM_EXP_CTL_EXT_TAG_FIELD PCIEM_CTL_EXT_TAG_FIELD
|
||||
#define PCIM_EXP_CTL_PHANTHOM_FUNCS PCIEM_CTL_PHANTHOM_FUNCS
|
||||
#define PCIM_EXP_CTL_AUX_POWER_PM PCIEM_CTL_AUX_POWER_PM
|
||||
#define PCIM_EXP_CTL_NOSNOOP_ENABLE PCIEM_CTL_NOSNOOP_ENABLE
|
||||
#define PCIM_EXP_CTL_MAX_READ_REQUEST PCIEM_CTL_MAX_READ_REQUEST
|
||||
#define PCIM_EXP_CTL_BRDG_CFG_RETRY PCIEM_CTL_BRDG_CFG_RETRY
|
||||
#define PCIM_EXP_CTL_INITIATE_FLR PCIEM_CTL_INITIATE_FLR
|
||||
#define PCIR_EXPRESS_DEVICE_STA PCIER_DEVICE_STA
|
||||
#define PCIM_EXP_STA_CORRECTABLE_ERROR PCIEM_STA_CORRECTABLE_ERROR
|
||||
#define PCIM_EXP_STA_NON_FATAL_ERROR PCIEM_STA_NON_FATAL_ERROR
|
||||
#define PCIM_EXP_STA_FATAL_ERROR PCIEM_STA_FATAL_ERROR
|
||||
#define PCIM_EXP_STA_UNSUPPORTED_REQ PCIEM_STA_UNSUPPORTED_REQ
|
||||
#define PCIM_EXP_STA_AUX_POWER PCIEM_STA_AUX_POWER
|
||||
#define PCIM_EXP_STA_TRANSACTION_PND PCIEM_STA_TRANSACTION_PND
|
||||
#define PCIR_EXPRESS_LINK_CAP PCIER_LINK_CAP
|
||||
#define PCIM_LINK_CAP_MAX_SPEED PCIEM_LINK_CAP_MAX_SPEED
|
||||
#define PCIM_LINK_CAP_MAX_WIDTH PCIEM_LINK_CAP_MAX_WIDTH
|
||||
#define PCIM_LINK_CAP_ASPM PCIEM_LINK_CAP_ASPM
|
||||
#define PCIM_LINK_CAP_L0S_EXIT PCIEM_LINK_CAP_L0S_EXIT
|
||||
#define PCIM_LINK_CAP_L1_EXIT PCIEM_LINK_CAP_L1_EXIT
|
||||
#define PCIM_LINK_CAP_CLOCK_PM PCIEM_LINK_CAP_CLOCK_PM
|
||||
#define PCIM_LINK_CAP_SURPRISE_DOWN PCIEM_LINK_CAP_SURPRISE_DOWN
|
||||
#define PCIM_LINK_CAP_DL_ACTIVE PCIEM_LINK_CAP_DL_ACTIVE
|
||||
#define PCIM_LINK_CAP_LINK_BW_NOTIFY PCIEM_LINK_CAP_LINK_BW_NOTIFY
|
||||
#define PCIM_LINK_CAP_ASPM_COMPLIANCE PCIEM_LINK_CAP_ASPM_COMPLIANCE
|
||||
#define PCIM_LINK_CAP_PORT PCIEM_LINK_CAP_PORT
|
||||
#define PCIR_EXPRESS_LINK_CTL PCIER_LINK_CTL
|
||||
#define PCIM_EXP_LINK_CTL_ASPMC_DIS PCIEM_LINK_CTL_ASPMC_DIS
|
||||
#define PCIM_EXP_LINK_CTL_ASPMC_L0S PCIEM_LINK_CTL_ASPMC_L0S
|
||||
#define PCIM_EXP_LINK_CTL_ASPMC_L1 PCIEM_LINK_CTL_ASPMC_L1
|
||||
#define PCIM_EXP_LINK_CTL_ASPMC PCIEM_LINK_CTL_ASPMC
|
||||
#define PCIM_EXP_LINK_CTL_RCB PCIEM_LINK_CTL_RCB
|
||||
#define PCIM_EXP_LINK_CTL_LINK_DIS PCIEM_LINK_CTL_LINK_DIS
|
||||
#define PCIM_EXP_LINK_CTL_RETRAIN_LINK PCIEM_LINK_CTL_RETRAIN_LINK
|
||||
#define PCIM_EXP_LINK_CTL_COMMON_CLOCK PCIEM_LINK_CTL_COMMON_CLOCK
|
||||
#define PCIM_EXP_LINK_CTL_EXTENDED_SYNC PCIEM_LINK_CTL_EXTENDED_SYNC
|
||||
#define PCIM_EXP_LINK_CTL_ECPM PCIEM_LINK_CTL_ECPM
|
||||
#define PCIM_EXP_LINK_CTL_HAWD PCIEM_LINK_CTL_HAWD
|
||||
#define PCIM_EXP_LINK_CTL_LBMIE PCIEM_LINK_CTL_LBMIE
|
||||
#define PCIM_EXP_LINK_CTL_LABIE PCIEM_LINK_CTL_LABIE
|
||||
#define PCIR_EXPRESS_LINK_STA PCIER_LINK_STA
|
||||
#define PCIM_LINK_STA_SPEED PCIEM_LINK_STA_SPEED
|
||||
#define PCIM_LINK_STA_WIDTH PCIEM_LINK_STA_WIDTH
|
||||
#define PCIM_LINK_STA_TRAINING_ERROR PCIEM_LINK_STA_TRAINING_ERROR
|
||||
#define PCIM_LINK_STA_TRAINING PCIEM_LINK_STA_TRAINING
|
||||
#define PCIM_LINK_STA_SLOT_CLOCK PCIEM_LINK_STA_SLOT_CLOCK
|
||||
#define PCIM_LINK_STA_DL_ACTIVE PCIEM_LINK_STA_DL_ACTIVE
|
||||
#define PCIM_LINK_STA_LINK_BW_MGMT PCIEM_LINK_STA_LINK_BW_MGMT
|
||||
#define PCIM_LINK_STA_LINK_AUTO_BW PCIEM_LINK_STA_LINK_AUTO_BW
|
||||
#define PCIR_EXPRESS_SLOT_CAP PCIER_SLOT_CAP
|
||||
#define PCIR_EXPRESS_SLOT_CTL PCIER_SLOT_CTL
|
||||
#define PCIR_EXPRESS_SLOT_STA PCIER_SLOT_STA
|
||||
#define PCIR_EXPRESS_ROOT_CTL PCIER_ROOT_CTL
|
||||
#define PCIR_EXPRESS_ROOT_CAP PCIER_ROOT_CAP
|
||||
#define PCIR_EXPRESS_ROOT_STA PCIER_ROOT_STA
|
||||
#define PCIR_EXPRESS_DEVICE_CAP2 PCIER_DEVICE_CAP2
|
||||
#define PCIR_EXPRESS_DEVICE_CTL2 PCIER_DEVICE_CTL2
|
||||
#define PCIM_EXP_CTL2_COMP_TIMEOUT_VAL PCIEM_CTL2_COMP_TIMEOUT_VAL
|
||||
#define PCIM_EXP_CTL2_COMP_TIMEOUT_DIS PCIEM_CTL2_COMP_TIMEOUT_DIS
|
||||
#define PCIM_EXP_CTL2_ARI PCIEM_CTL2_ARI
|
||||
#define PCIM_EXP_CTL2_ATOMIC_REQ_ENABLE PCIEM_CTL2_ATOMIC_REQ_ENABLE
|
||||
#define PCIM_EXP_CTL2_ATOMIC_EGR_BLOCK PCIEM_CTL2_ATOMIC_EGR_BLOCK
|
||||
#define PCIM_EXP_CTL2_ID_ORDERED_REQ_EN PCIEM_CTL2_ID_ORDERED_REQ_EN
|
||||
#define PCIM_EXP_CTL2_ID_ORDERED_CMP_EN PCIEM_CTL2_ID_ORDERED_CMP_EN
|
||||
#define PCIM_EXP_CTL2_LTR_ENABLE PCIEM_CTL2_LTR_ENABLE
|
||||
#define PCIM_EXP_CTL2_OBFF PCIEM_CTL2_OBFF
|
||||
#define PCIM_EXP_OBFF_DISABLE PCIEM_OBFF_DISABLE
|
||||
#define PCIM_EXP_OBFF_MSGA_ENABLE PCIEM_OBFF_MSGA_ENABLE
|
||||
#define PCIM_EXP_OBFF_MSGB_ENABLE PCIEM_OBFF_MSGB_ENABLE
|
||||
#define PCIM_EXP_OBFF_WAKE_ENABLE PCIEM_OBFF_WAKE_ENABLE
|
||||
#define PCIM_EXP_CTL2_END2END_TLP PCIEM_CTL2_END2END_TLP
|
||||
#define PCIR_EXPRESS_DEVICE_STA2 PCIER_DEVICE_STA2
|
||||
#define PCIR_EXPRESS_LINK_CAP2 PCIER_LINK_CAP2
|
||||
#define PCIR_EXPRESS_LINK_CTL2 PCIER_LINK_CTL2
|
||||
#define PCIR_EXPRESS_LINK_STA2 PCIER_LINK_STA2
|
||||
#define PCIR_EXPRESS_SLOT_CAP2 PCIER_SLOT_CAP2
|
||||
#define PCIR_EXPRESS_SLOT_CTL2 PCIER_SLOT_CTL2
|
||||
#define PCIR_EXPRESS_SLOT_STA2 PCIER_SLOT_STA2
|
||||
|
||||
/* MSI-X definitions */
|
||||
#define PCIR_MSIX_CTRL 0x2
|
||||
@@ -697,6 +918,7 @@
|
||||
#define PCIR_AER_UC_STATUS 0x04
|
||||
#define PCIM_AER_UC_TRAINING_ERROR 0x00000001
|
||||
#define PCIM_AER_UC_DL_PROTOCOL_ERROR 0x00000010
|
||||
#define PCIM_AER_UC_SURPRISE_LINK_DOWN 0x00000020
|
||||
#define PCIM_AER_UC_POISONED_TLP 0x00001000
|
||||
#define PCIM_AER_UC_FC_PROTOCOL_ERROR 0x00002000
|
||||
#define PCIM_AER_UC_COMPLETION_TIMEOUT 0x00004000
|
||||
@@ -707,6 +929,10 @@
|
||||
#define PCIM_AER_UC_ECRC_ERROR 0x00080000
|
||||
#define PCIM_AER_UC_UNSUPPORTED_REQUEST 0x00100000
|
||||
#define PCIM_AER_UC_ACS_VIOLATION 0x00200000
|
||||
#define PCIM_AER_UC_INTERNAL_ERROR 0x00400000
|
||||
#define PCIM_AER_UC_MC_BLOCKED_TLP 0x00800000
|
||||
#define PCIM_AER_UC_ATOMIC_EGRESS_BLK 0x01000000
|
||||
#define PCIM_AER_UC_TLP_PREFIX_BLOCKED 0x02000000
|
||||
#define PCIR_AER_UC_MASK 0x08 /* Shares bits with UC_STATUS */
|
||||
#define PCIR_AER_UC_SEVERITY 0x0c /* Shares bits with UC_STATUS */
|
||||
#define PCIR_AER_COR_STATUS 0x10
|
||||
@@ -715,6 +941,9 @@
|
||||
#define PCIM_AER_COR_BAD_DLLP 0x00000080
|
||||
#define PCIM_AER_COR_REPLAY_ROLLOVER 0x00000100
|
||||
#define PCIM_AER_COR_REPLAY_TIMEOUT 0x00001000
|
||||
#define PCIM_AER_COR_ADVISORY_NF_ERROR 0x00002000
|
||||
#define PCIM_AER_COR_INTERNAL_ERROR 0x00004000
|
||||
#define PCIM_AER_COR_HEADER_LOG_OVFLOW 0x00008000
|
||||
#define PCIR_AER_COR_MASK 0x14 /* Shares bits with COR_STATUS */
|
||||
#define PCIR_AER_CAP_CONTROL 0x18
|
||||
#define PCIM_AER_FIRST_ERROR_PTR 0x0000001f
|
||||
@@ -722,6 +951,9 @@
|
||||
#define PCIM_AER_ECRC_GEN_ENABLE 0x00000040
|
||||
#define PCIM_AER_ECRC_CHECK_CAPABLE 0x00000080
|
||||
#define PCIM_AER_ECRC_CHECK_ENABLE 0x00000100
|
||||
#define PCIM_AER_MULT_HDR_CAPABLE 0x00000200
|
||||
#define PCIM_AER_MULT_HDR_ENABLE 0x00000400
|
||||
#define PCIM_AER_TLP_PREFIX_LOG_PRESENT 0x00000800
|
||||
#define PCIR_AER_HEADER_LOG 0x1c
|
||||
#define PCIR_AER_ROOTERR_CMD 0x2c /* Only for root complex ports */
|
||||
#define PCIM_AER_ROOTERR_COR_ENABLE 0x00000001
|
||||
@@ -738,6 +970,7 @@
|
||||
#define PCIM_AER_ROOTERR_INT_MESSAGE 0xf8000000
|
||||
#define PCIR_AER_COR_SOURCE_ID 0x34 /* Only for root complex ports */
|
||||
#define PCIR_AER_ERR_SOURCE_ID 0x36 /* Only for root complex ports */
|
||||
#define PCIR_AER_TLP_PREFIX_LOG 0x38 /* Only for TLP prefix functions */
|
||||
|
||||
/* Virtual Channel definitions */
|
||||
#define PCIR_VC_CAP1 0x04
|
||||
|
||||
Reference in New Issue
Block a user