Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/e1000/if_em.c
Show First 20 Lines • Show All 1,286 Lines • ▼ Show 20 Lines | |||||
* consistent state. | * consistent state. | ||||
* | * | ||||
**********************************************************************/ | **********************************************************************/ | ||||
static void | static void | ||||
em_if_init(if_ctx_t ctx) | em_if_init(if_ctx_t ctx) | ||||
{ | { | ||||
struct e1000_softc *sc = iflib_get_softc(ctx); | struct e1000_softc *sc = iflib_get_softc(ctx); | ||||
if_softc_ctx_t scctx = sc->shared; | if_softc_ctx_t scctx = sc->shared; | ||||
struct ifnet *ifp = iflib_get_ifp(ctx); | if_t ifp = iflib_get_ifp(ctx); | ||||
struct em_tx_queue *tx_que; | struct em_tx_queue *tx_que; | ||||
int i; | int i; | ||||
INIT_DEBUGOUT("em_if_init: begin"); | INIT_DEBUGOUT("em_if_init: begin"); | ||||
/* Get the latest mac address, User can use a LAA */ | /* Get the latest mac address, User can use a LAA */ | ||||
bcopy(if_getlladdr(ifp), sc->hw.mac.addr, | bcopy(if_getlladdr(ifp), sc->hw.mac.addr, | ||||
ETHER_ADDR_LEN); | ETHER_ADDR_LEN); | ||||
▲ Show 20 Lines • Show All 345 Lines • ▼ Show 20 Lines | em_if_media_change(if_ctx_t ctx) | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
em_if_set_promisc(if_ctx_t ctx, int flags) | em_if_set_promisc(if_ctx_t ctx, int flags) | ||||
{ | { | ||||
struct e1000_softc *sc = iflib_get_softc(ctx); | struct e1000_softc *sc = iflib_get_softc(ctx); | ||||
struct ifnet *ifp = iflib_get_ifp(ctx); | if_t ifp = iflib_get_ifp(ctx); | ||||
u32 reg_rctl; | u32 reg_rctl; | ||||
int mcnt = 0; | int mcnt = 0; | ||||
reg_rctl = E1000_READ_REG(&sc->hw, E1000_RCTL); | reg_rctl = E1000_READ_REG(&sc->hw, E1000_RCTL); | ||||
reg_rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_UPE); | reg_rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_UPE); | ||||
if (flags & IFF_ALLMULTI) | if (flags & IFF_ALLMULTI) | ||||
mcnt = MAX_NUM_MULTICAST_ADDRESSES; | mcnt = MAX_NUM_MULTICAST_ADDRESSES; | ||||
else | else | ||||
Show All 40 Lines | |||||
* | * | ||||
* This routine is called whenever multicast address list is updated. | * This routine is called whenever multicast address list is updated. | ||||
* | * | ||||
**********************************************************************/ | **********************************************************************/ | ||||
static void | static void | ||||
em_if_multi_set(if_ctx_t ctx) | em_if_multi_set(if_ctx_t ctx) | ||||
{ | { | ||||
struct e1000_softc *sc = iflib_get_softc(ctx); | struct e1000_softc *sc = iflib_get_softc(ctx); | ||||
struct ifnet *ifp = iflib_get_ifp(ctx); | if_t ifp = iflib_get_ifp(ctx); | ||||
u8 *mta; /* Multicast array memory */ | u8 *mta; /* Multicast array memory */ | ||||
u32 reg_rctl = 0; | u32 reg_rctl = 0; | ||||
int mcnt = 0; | int mcnt = 0; | ||||
IOCTL_DEBUGOUT("em_set_multi: begin"); | IOCTL_DEBUGOUT("em_set_multi: begin"); | ||||
mta = sc->mta; | mta = sc->mta; | ||||
bzero(mta, sizeof(u8) * ETHER_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES); | bzero(mta, sizeof(u8) * ETHER_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES); | ||||
▲ Show 20 Lines • Show All 743 Lines • ▼ Show 20 Lines | |||||
* sc structure. | * sc structure. | ||||
* | * | ||||
**********************************************************************/ | **********************************************************************/ | ||||
static void | static void | ||||
em_reset(if_ctx_t ctx) | em_reset(if_ctx_t ctx) | ||||
{ | { | ||||
device_t dev = iflib_get_dev(ctx); | device_t dev = iflib_get_dev(ctx); | ||||
struct e1000_softc *sc = iflib_get_softc(ctx); | struct e1000_softc *sc = iflib_get_softc(ctx); | ||||
struct ifnet *ifp = iflib_get_ifp(ctx); | if_t ifp = iflib_get_ifp(ctx); | ||||
struct e1000_hw *hw = &sc->hw; | struct e1000_hw *hw = &sc->hw; | ||||
u32 rx_buffer_size; | u32 rx_buffer_size; | ||||
u32 pba; | u32 pba; | ||||
INIT_DEBUGOUT("em_reset: begin"); | INIT_DEBUGOUT("em_reset: begin"); | ||||
/* Let the firmware know the OS is in control */ | /* Let the firmware know the OS is in control */ | ||||
em_get_hw_control(sc); | em_get_hw_control(sc); | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | default: | ||||
/* Remaining devices assumed to have a Packet Buffer of 64K. */ | /* Remaining devices assumed to have a Packet Buffer of 64K. */ | ||||
if (hw->mac.max_frame_size > 8192) | if (hw->mac.max_frame_size > 8192) | ||||
pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ | pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ | ||||
else | else | ||||
pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */ | pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */ | ||||
} | } | ||||
/* Special needs in case of Jumbo frames */ | /* Special needs in case of Jumbo frames */ | ||||
if ((hw->mac.type == e1000_82575) && (ifp->if_mtu > ETHERMTU)) { | if ((hw->mac.type == e1000_82575) && (if_getmtu(ifp) > ETHERMTU)) { | ||||
u32 tx_space, min_tx, min_rx; | u32 tx_space, min_tx, min_rx; | ||||
pba = E1000_READ_REG(hw, E1000_PBA); | pba = E1000_READ_REG(hw, E1000_PBA); | ||||
tx_space = pba >> 16; | tx_space = pba >> 16; | ||||
pba &= 0xffff; | pba &= 0xffff; | ||||
min_tx = (hw->mac.max_frame_size + | min_tx = (hw->mac.max_frame_size + | ||||
sizeof(struct e1000_tx_desc) - ETHERNET_FCS_SIZE) * 2; | sizeof(struct e1000_tx_desc) - ETHERNET_FCS_SIZE) * 2; | ||||
min_tx = roundup2(min_tx, 1024); | min_tx = roundup2(min_tx, 1024); | ||||
min_tx >>= 10; | min_tx >>= 10; | ||||
▲ Show 20 Lines • Show All 281 Lines • ▼ Show 20 Lines | |||||
/********************************************************************* | /********************************************************************* | ||||
* | * | ||||
* Setup networking device structure and register interface media. | * Setup networking device structure and register interface media. | ||||
* | * | ||||
**********************************************************************/ | **********************************************************************/ | ||||
static int | static int | ||||
em_setup_interface(if_ctx_t ctx) | em_setup_interface(if_ctx_t ctx) | ||||
{ | { | ||||
struct ifnet *ifp = iflib_get_ifp(ctx); | if_t ifp = iflib_get_ifp(ctx); | ||||
struct e1000_softc *sc = iflib_get_softc(ctx); | struct e1000_softc *sc = iflib_get_softc(ctx); | ||||
if_softc_ctx_t scctx = sc->shared; | if_softc_ctx_t scctx = sc->shared; | ||||
INIT_DEBUGOUT("em_setup_interface: begin"); | INIT_DEBUGOUT("em_setup_interface: begin"); | ||||
/* Single Queue */ | /* Single Queue */ | ||||
if (sc->tx_num_queues == 1) { | if (sc->tx_num_queues == 1) { | ||||
if_setsendqlen(ifp, scctx->isc_ntxd[0] - 1); | if_setsendqlen(ifp, scctx->isc_ntxd[0] - 1); | ||||
▲ Show 20 Lines • Show All 288 Lines • ▼ Show 20 Lines | |||||
**********************************************************************/ | **********************************************************************/ | ||||
#define BSIZEPKT_ROUNDUP ((1<<E1000_SRRCTL_BSIZEPKT_SHIFT)-1) | #define BSIZEPKT_ROUNDUP ((1<<E1000_SRRCTL_BSIZEPKT_SHIFT)-1) | ||||
static void | static void | ||||
em_initialize_receive_unit(if_ctx_t ctx) | em_initialize_receive_unit(if_ctx_t ctx) | ||||
{ | { | ||||
struct e1000_softc *sc = iflib_get_softc(ctx); | struct e1000_softc *sc = iflib_get_softc(ctx); | ||||
if_softc_ctx_t scctx = sc->shared; | if_softc_ctx_t scctx = sc->shared; | ||||
struct ifnet *ifp = iflib_get_ifp(ctx); | if_t ifp = iflib_get_ifp(ctx); | ||||
struct e1000_hw *hw = &sc->hw; | struct e1000_hw *hw = &sc->hw; | ||||
struct em_rx_queue *que; | struct em_rx_queue *que; | ||||
int i; | int i; | ||||
uint32_t rctl, rxcsum; | uint32_t rctl, rxcsum; | ||||
INIT_DEBUGOUT("em_initialize_receive_units: begin"); | INIT_DEBUGOUT("em_initialize_receive_units: begin"); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | for (int i = 0; i < sc->rx_num_queues; i++) { | ||||
E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl); | E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl); | ||||
} | } | ||||
} else if (hw->mac.type >= igb_mac_min) { | } else if (hw->mac.type >= igb_mac_min) { | ||||
u32 psize, srrctl = 0; | u32 psize, srrctl = 0; | ||||
if (if_getmtu(ifp) > ETHERMTU) { | if (if_getmtu(ifp) > ETHERMTU) { | ||||
psize = scctx->isc_max_frame_size; | psize = scctx->isc_max_frame_size; | ||||
/* are we on a vlan? */ | /* are we on a vlan? */ | ||||
if (ifp->if_vlantrunk != NULL) | if (if_vlantrunkinuse(ifp)) | ||||
psize += VLAN_TAG_SIZE; | psize += VLAN_TAG_SIZE; | ||||
if (sc->vf_ifp) | if (sc->vf_ifp) | ||||
e1000_rlpml_set_vf(hw, psize); | e1000_rlpml_set_vf(hw, psize); | ||||
else | else | ||||
E1000_WRITE_REG(hw, E1000_RLPML, psize); | E1000_WRITE_REG(hw, E1000_RLPML, psize); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | if (hw->mac.type < em_mac_min) | ||||
em_if_intr_enable(sc->ctx); | em_if_intr_enable(sc->ctx); | ||||
} | } | ||||
static void | static void | ||||
em_setup_vlan_hw_support(if_ctx_t ctx) | em_setup_vlan_hw_support(if_ctx_t ctx) | ||||
{ | { | ||||
struct e1000_softc *sc = iflib_get_softc(ctx); | struct e1000_softc *sc = iflib_get_softc(ctx); | ||||
struct e1000_hw *hw = &sc->hw; | struct e1000_hw *hw = &sc->hw; | ||||
struct ifnet *ifp = iflib_get_ifp(ctx); | if_t ifp = iflib_get_ifp(ctx); | ||||
u32 reg; | u32 reg; | ||||
/* XXXKB: Return early if we are a VF until VF decap and filter management | /* XXXKB: Return early if we are a VF until VF decap and filter management | ||||
* is ready and tested. | * is ready and tested. | ||||
*/ | */ | ||||
if (sc->vf_ifp) | if (sc->vf_ifp) | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 618 Lines • ▼ Show 20 Lines | if (sc->hw.mac.type >= e1000_82543) { | ||||
E1000_READ_REG(&sc->hw, E1000_TSCTFC); | E1000_READ_REG(&sc->hw, E1000_TSCTFC); | ||||
} | } | ||||
} | } | ||||
static uint64_t | static uint64_t | ||||
em_if_get_counter(if_ctx_t ctx, ift_counter cnt) | em_if_get_counter(if_ctx_t ctx, ift_counter cnt) | ||||
{ | { | ||||
struct e1000_softc *sc = iflib_get_softc(ctx); | struct e1000_softc *sc = iflib_get_softc(ctx); | ||||
struct ifnet *ifp = iflib_get_ifp(ctx); | if_t ifp = iflib_get_ifp(ctx); | ||||
switch (cnt) { | switch (cnt) { | ||||
case IFCOUNTER_COLLISIONS: | case IFCOUNTER_COLLISIONS: | ||||
return (sc->stats.colc); | return (sc->stats.colc); | ||||
case IFCOUNTER_IERRORS: | case IFCOUNTER_IERRORS: | ||||
return (sc->dropped_pkts + sc->stats.rxerrc + | return (sc->dropped_pkts + sc->stats.rxerrc + | ||||
sc->stats.crcerrs + sc->stats.algnerrc + | sc->stats.crcerrs + sc->stats.algnerrc + | ||||
sc->stats.ruc + sc->stats.roc + | sc->stats.ruc + sc->stats.roc + | ||||
▲ Show 20 Lines • Show All 658 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* This routine is meant to be fluid, add whatever is | * This routine is meant to be fluid, add whatever is | ||||
* needed for debugging a problem. -jfv | * needed for debugging a problem. -jfv | ||||
*/ | */ | ||||
static void | static void | ||||
em_print_debug_info(struct e1000_softc *sc) | em_print_debug_info(struct e1000_softc *sc) | ||||
{ | { | ||||
device_t dev = iflib_get_dev(sc->ctx); | device_t dev = iflib_get_dev(sc->ctx); | ||||
struct ifnet *ifp = iflib_get_ifp(sc->ctx); | if_t ifp = iflib_get_ifp(sc->ctx); | ||||
struct tx_ring *txr = &sc->tx_queues->txr; | struct tx_ring *txr = &sc->tx_queues->txr; | ||||
struct rx_ring *rxr = &sc->rx_queues->rxr; | struct rx_ring *rxr = &sc->rx_queues->rxr; | ||||
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) | if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) | ||||
printf("Interface is RUNNING "); | printf("Interface is RUNNING "); | ||||
else | else | ||||
printf("Interface is NOT RUNNING\n"); | printf("Interface is NOT RUNNING\n"); | ||||
▲ Show 20 Lines • Show All 46 Lines • Show Last 20 Lines |