MFC r200538,200540-200541,200543,200545,200548

r200538:
  Introduce vge_flags member in softc. The vge_flags member will
  record device specific bits. Remove vge_link and use vge_flags.
  While here, move clearing link state before mii_mediachg() as
  mii_mediachg() may affect link state.

r200540:
  Save PHY address by reading VGE_MIICFG register. For PCIe
  controllers(VT613x), we assume the PHY address is 1.
  Use the saved PHY address in MII register access routines and
  remove accessing VGE_MIICFG register.
  While I'm here save PCI express capability register which will be
  used in near future.

r200541:
  Add MSI support for VT613x controllers.

r200543:
  Increase output queue size from 64 to 255.

r200545:
  We don't have to reload EEPROM in vge_reset(). Because vge_reset()
  is called in vge_init_lock(), vge(4) always used to reload EEPROM.
  Also add more comment why vge(4) clears VGE_CHIPCFG0_PACPI bit.
  While I'm here add missing new line in vge_reset().

r200548:
  Sort function prototyes.
This commit is contained in:
Pyun YongHyeon 2010-01-08 22:26:24 +00:00
parent ef22705259
commit b79a3f6583
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/stable/8/; revision=201840
2 changed files with 114 additions and 82 deletions

View File

@ -127,6 +127,10 @@ MODULE_DEPEND(vge, miibus, 1, 1, 1);
#define VGE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
/* Tunables */
static int msi_disable = 0;
TUNABLE_INT("hw.vge.msi_disable", &msi_disable);
/*
* Various supported device vendors/types and their names.
*/
@ -136,56 +140,52 @@ static struct vge_type vge_devs[] = {
{ 0, 0, NULL }
};
static int vge_probe (device_t);
static int vge_attach (device_t);
static int vge_detach (device_t);
static int vge_encap (struct vge_softc *, struct mbuf **);
static void vge_dmamap_cb (void *, bus_dma_segment_t *, int, int);
static int vge_dma_alloc (struct vge_softc *);
static void vge_dma_free (struct vge_softc *);
static void vge_discard_rxbuf (struct vge_softc *, int);
static int vge_newbuf (struct vge_softc *, int);
static int vge_rx_list_init (struct vge_softc *);
static int vge_tx_list_init (struct vge_softc *);
static void vge_freebufs (struct vge_softc *);
#ifndef __NO_STRICT_ALIGNMENT
static __inline void vge_fixup_rx
(struct mbuf *);
#endif
static int vge_rxeof (struct vge_softc *, int);
static void vge_txeof (struct vge_softc *);
static void vge_intr (void *);
static void vge_tick (void *);
static void vge_start (struct ifnet *);
static void vge_start_locked (struct ifnet *);
static int vge_ioctl (struct ifnet *, u_long, caddr_t);
static void vge_init (void *);
static void vge_init_locked (struct vge_softc *);
static void vge_stop (struct vge_softc *);
static void vge_watchdog (void *);
static int vge_suspend (device_t);
static int vge_resume (device_t);
static int vge_shutdown (device_t);
static int vge_ifmedia_upd (struct ifnet *);
static void vge_ifmedia_sts (struct ifnet *, struct ifmediareq *);
static int vge_attach(device_t);
static int vge_detach(device_t);
static int vge_probe(device_t);
static int vge_resume(device_t);
static int vge_shutdown(device_t);
static int vge_suspend(device_t);
static void vge_cam_clear(struct vge_softc *);
static int vge_cam_set(struct vge_softc *, uint8_t *);
static void vge_discard_rxbuf(struct vge_softc *, int);
static int vge_dma_alloc(struct vge_softc *);
static void vge_dma_free(struct vge_softc *);
static void vge_dmamap_cb(void *, bus_dma_segment_t *, int, int);
#ifdef VGE_EEPROM
static void vge_eeprom_getword (struct vge_softc *, int, uint16_t *);
static void vge_eeprom_getword(struct vge_softc *, int, uint16_t *);
#endif
static void vge_read_eeprom (struct vge_softc *, caddr_t, int, int, int);
static void vge_miipoll_start (struct vge_softc *);
static void vge_miipoll_stop (struct vge_softc *);
static int vge_miibus_readreg (device_t, int, int);
static int vge_miibus_writereg (device_t, int, int, int);
static void vge_miibus_statchg (device_t);
static void vge_cam_clear (struct vge_softc *);
static int vge_cam_set (struct vge_softc *, uint8_t *);
static void vge_setmulti (struct vge_softc *);
static void vge_reset (struct vge_softc *);
static int vge_encap(struct vge_softc *, struct mbuf **);
#ifndef __NO_STRICT_ALIGNMENT
static __inline void
vge_fixup_rx(struct mbuf *);
#endif
static void vge_freebufs(struct vge_softc *);
static void vge_ifmedia_sts(struct ifnet *, struct ifmediareq *);
static int vge_ifmedia_upd(struct ifnet *);
static void vge_init(void *);
static void vge_init_locked(struct vge_softc *);
static void vge_intr(void *);
static int vge_ioctl(struct ifnet *, u_long, caddr_t);
static int vge_miibus_readreg(device_t, int, int);
static void vge_miibus_statchg(device_t);
static int vge_miibus_writereg(device_t, int, int, int);
static void vge_miipoll_start(struct vge_softc *);
static void vge_miipoll_stop(struct vge_softc *);
static int vge_newbuf(struct vge_softc *, int);
static void vge_read_eeprom(struct vge_softc *, caddr_t, int, int, int);
static void vge_reset(struct vge_softc *);
static int vge_rx_list_init(struct vge_softc *);
static int vge_rxeof(struct vge_softc *, int);
static void vge_setmulti(struct vge_softc *);
static void vge_start(struct ifnet *);
static void vge_start_locked(struct ifnet *);
static void vge_stop(struct vge_softc *);
static void vge_tick(void *);
static int vge_tx_list_init(struct vge_softc *);
static void vge_txeof(struct vge_softc *);
static void vge_watchdog(void *);
static device_method_t vge_methods[] = {
/* Device interface */
@ -353,7 +353,7 @@ vge_miibus_readreg(device_t dev, int phy, int reg)
sc = device_get_softc(dev);
if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
if (phy != sc->vge_phyaddr)
return (0);
vge_miipoll_stop(sc);
@ -389,7 +389,7 @@ vge_miibus_writereg(device_t dev, int phy, int reg, int data)
sc = device_get_softc(dev);
if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F))
if (phy != sc->vge_phyaddr)
return (0);
vge_miipoll_stop(sc);
@ -582,27 +582,12 @@ vge_reset(struct vge_softc *sc)
}
if (i == VGE_TIMEOUT) {
device_printf(sc->vge_dev, "soft reset timed out");
device_printf(sc->vge_dev, "soft reset timed out\n");
CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_STOP_FORCE);
DELAY(2000);
}
DELAY(5000);
CSR_SETBIT_1(sc, VGE_EECSR, VGE_EECSR_RELOAD);
for (i = 0; i < VGE_TIMEOUT; i++) {
DELAY(5);
if ((CSR_READ_1(sc, VGE_EECSR) & VGE_EECSR_RELOAD) == 0)
break;
}
if (i == VGE_TIMEOUT) {
device_printf(sc->vge_dev, "EEPROM reload timed out\n");
return;
}
CSR_CLRBIT_1(sc, VGE_CHIPCFG0, VGE_CHIPCFG0_PACPI);
}
/*
@ -954,7 +939,7 @@ vge_attach(device_t dev)
u_char eaddr[ETHER_ADDR_LEN];
struct vge_softc *sc;
struct ifnet *ifp;
int error = 0, rid;
int error = 0, cap, i, msic, rid;
sc = device_get_softc(dev);
sc->vge_dev = dev;
@ -978,11 +963,28 @@ vge_attach(device_t dev)
goto fail;
}
/* Allocate interrupt */
if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) == 0) {
sc->vge_flags |= VGE_FLAG_PCIE;
sc->vge_expcap = cap;
}
rid = 0;
sc->vge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
msic = pci_msi_count(dev);
if (msi_disable == 0 && msic > 0) {
msic = 1;
if (pci_alloc_msi(dev, &msic) == 0) {
if (msic == 1) {
sc->vge_flags |= VGE_FLAG_MSI;
device_printf(dev, "Using %d MSI message\n",
msic);
rid = 1;
} else
pci_release_msi(dev);
}
}
/* Allocate interrupt */
sc->vge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
((sc->vge_flags & VGE_FLAG_MSI) ? 0 : RF_SHAREABLE) | RF_ACTIVE);
if (sc->vge_irq == NULL) {
device_printf(dev, "couldn't map interrupt\n");
error = ENXIO;
@ -991,12 +993,37 @@ vge_attach(device_t dev)
/* Reset the adapter. */
vge_reset(sc);
/* Reload EEPROM. */
CSR_WRITE_1(sc, VGE_EECSR, VGE_EECSR_RELOAD);
for (i = 0; i < VGE_TIMEOUT; i++) {
DELAY(5);
if ((CSR_READ_1(sc, VGE_EECSR) & VGE_EECSR_RELOAD) == 0)
break;
}
if (i == VGE_TIMEOUT)
device_printf(dev, "EEPROM reload timed out\n");
/*
* Clear PACPI as EEPROM reload will set the bit. Otherwise
* MAC will receive magic packet which in turn confuses
* controller.
*/
CSR_CLRBIT_1(sc, VGE_CHIPCFG0, VGE_CHIPCFG0_PACPI);
/*
* Get station address from the EEPROM.
*/
vge_read_eeprom(sc, (caddr_t)eaddr, VGE_EE_EADDR, 3, 0);
/*
* Save configured PHY address.
* It seems the PHY address of PCIe controllers just
* reflects media jump strapping status so we assume the
* internal PHY address of PCIe controller is at 1.
*/
if ((sc->vge_flags & VGE_FLAG_PCIE) != 0)
sc->vge_phyaddr = 1;
else
sc->vge_phyaddr = CSR_READ_1(sc, VGE_MIICFG) &
VGE_MIICFG_PHYADDR;
error = vge_dma_alloc(sc);
if (error)
goto fail;
@ -1030,8 +1057,8 @@ vge_attach(device_t dev)
ifp->if_capabilities |= IFCAP_POLLING;
#endif
ifp->if_init = vge_init;
IFQ_SET_MAXLEN(&ifp->if_snd, VGE_IFQ_MAXLEN);
ifp->if_snd.ifq_drv_maxlen = VGE_IFQ_MAXLEN;
IFQ_SET_MAXLEN(&ifp->if_snd, VGE_TX_DESC_CNT - 1);
ifp->if_snd.ifq_drv_maxlen = VGE_TX_DESC_CNT - 1;
IFQ_SET_READY(&ifp->if_snd);
/*
@ -1093,7 +1120,10 @@ vge_detach(device_t dev)
if (sc->vge_intrhand)
bus_teardown_intr(dev, sc->vge_irq, sc->vge_intrhand);
if (sc->vge_irq)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vge_irq);
bus_release_resource(dev, SYS_RES_IRQ,
sc->vge_flags & VGE_FLAG_MSI ? 1 : 0, sc->vge_irq);
if (sc->vge_flags & VGE_FLAG_MSI)
pci_release_msi(dev);
if (sc->vge_res)
bus_release_resource(dev, SYS_RES_MEMORY,
PCIR_BAR(1), sc->vge_res);
@ -1577,16 +1607,16 @@ vge_tick(void *xsc)
mii = device_get_softc(sc->vge_miibus);
mii_tick(mii);
if (sc->vge_link) {
if ((sc->vge_flags & VGE_FLAG_LINK) != 0) {
if (!(mii->mii_media_status & IFM_ACTIVE)) {
sc->vge_link = 0;
sc->vge_flags &= ~VGE_FLAG_LINK;
if_link_state_change(sc->vge_ifp,
LINK_STATE_DOWN);
}
} else {
if (mii->mii_media_status & IFM_ACTIVE &&
IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
sc->vge_link = 1;
sc->vge_flags |= VGE_FLAG_LINK;
if_link_state_change(sc->vge_ifp,
LINK_STATE_UP);
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
@ -1868,7 +1898,7 @@ vge_start_locked(struct ifnet *ifp)
VGE_LOCK_ASSERT(sc);
if (sc->vge_link == 0 ||
if ((sc->vge_flags & VGE_FLAG_LINK) == 0 ||
(ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING)
return;
@ -2107,13 +2137,12 @@ vge_init_locked(struct vge_softc *sc)
CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
}
sc->vge_flags &= ~VGE_FLAG_LINK;
mii_mediachg(mii);
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
callout_reset(&sc->vge_watchdog, hz, vge_watchdog, sc);
sc->vge_link = 0;
}
/*

View File

@ -34,8 +34,6 @@
#define VGE_JUMBO_MTU 9000
#define VGE_IFQ_MAXLEN 64
#define VGE_TX_DESC_CNT 256
#define VGE_RX_DESC_CNT 252 /* Must be a multiple of 4!! */
#define VGE_TX_RING_ALIGN 64
@ -141,7 +139,12 @@ struct vge_softc {
device_t vge_miibus;
uint8_t vge_type;
int vge_if_flags;
int vge_link;
int vge_phyaddr;
int vge_flags;
#define VGE_FLAG_PCIE 0x0001
#define VGE_FLAG_MSI 0x0002
#define VGE_FLAG_LINK 0x8000
int vge_expcap;
int vge_camidx;
struct mtx vge_mtx;
struct callout vge_watchdog;