Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/igc/if_igc.c
Show First 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | |||||
static int igc_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid); | static int igc_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid); | ||||
static int igc_if_tx_queue_intr_enable(if_ctx_t ctx, uint16_t txqid); | static int igc_if_tx_queue_intr_enable(if_ctx_t ctx, uint16_t txqid); | ||||
static void igc_if_multi_set(if_ctx_t ctx); | static void igc_if_multi_set(if_ctx_t ctx); | ||||
static void igc_if_update_admin_status(if_ctx_t ctx); | static void igc_if_update_admin_status(if_ctx_t ctx); | ||||
static void igc_if_debug(if_ctx_t ctx); | static void igc_if_debug(if_ctx_t ctx); | ||||
static void igc_update_stats_counters(struct igc_adapter *); | static void igc_update_stats_counters(struct igc_adapter *); | ||||
static void igc_add_hw_stats(struct igc_adapter *adapter); | static void igc_add_hw_stats(struct igc_adapter *adapter); | ||||
static int igc_if_set_promisc(if_ctx_t ctx, int flags); | static int igc_if_set_promisc(if_ctx_t ctx, int flags); | ||||
static bool igc_if_vlan_filter_capable(struct igc_adapter *); | |||||
static bool igc_if_vlan_filter_used(struct igc_adapter *); | |||||
static void igc_if_vlan_filter_enable(struct igc_adapter *); | |||||
static void igc_if_vlan_filter_disable(struct igc_adapter *); | |||||
static void igc_if_vlan_filter_write(struct igc_adapter *); | |||||
static void igc_setup_vlan_hw_support(struct igc_adapter *); | static void igc_setup_vlan_hw_support(struct igc_adapter *); | ||||
static int igc_sysctl_nvm_info(SYSCTL_HANDLER_ARGS); | static int igc_sysctl_nvm_info(SYSCTL_HANDLER_ARGS); | ||||
static void igc_print_nvm_info(struct igc_adapter *); | static void igc_print_nvm_info(struct igc_adapter *); | ||||
static int igc_sysctl_debug_info(SYSCTL_HANDLER_ARGS); | static int igc_sysctl_debug_info(SYSCTL_HANDLER_ARGS); | ||||
static int igc_get_rs(SYSCTL_HANDLER_ARGS); | static int igc_get_rs(SYSCTL_HANDLER_ARGS); | ||||
static void igc_print_debug_info(struct igc_adapter *); | static void igc_print_debug_info(struct igc_adapter *); | ||||
static int igc_is_valid_ether_addr(u8 *); | static int igc_is_valid_ether_addr(u8 *); | ||||
static int igc_sysctl_int_delay(SYSCTL_HANDLER_ARGS); | static int igc_sysctl_int_delay(SYSCTL_HANDLER_ARGS); | ||||
▲ Show 20 Lines • Show All 711 Lines • ▼ Show 20 Lines | igc_if_init(if_ctx_t ctx) | ||||
igc_initialize_transmit_unit(ctx); | igc_initialize_transmit_unit(ctx); | ||||
/* Setup Multicast table */ | /* Setup Multicast table */ | ||||
igc_if_multi_set(ctx); | igc_if_multi_set(ctx); | ||||
adapter->rx_mbuf_sz = iflib_get_rx_mbuf_sz(ctx); | adapter->rx_mbuf_sz = iflib_get_rx_mbuf_sz(ctx); | ||||
igc_initialize_receive_unit(ctx); | igc_initialize_receive_unit(ctx); | ||||
/* Use real VLAN Filter support? */ | /* Set up VLAN support and filter */ | ||||
if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING) { | |||||
if (if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER) | |||||
/* Use real VLAN Filter support */ | |||||
igc_setup_vlan_hw_support(adapter); | igc_setup_vlan_hw_support(adapter); | ||||
else { | |||||
u32 ctrl; | |||||
ctrl = IGC_READ_REG(&adapter->hw, IGC_CTRL); | |||||
ctrl |= IGC_CTRL_VME; | |||||
IGC_WRITE_REG(&adapter->hw, IGC_CTRL, ctrl); | |||||
} | |||||
} | |||||
/* Don't lose promiscuous settings */ | /* Don't lose promiscuous settings */ | ||||
igc_if_set_promisc(ctx, IFF_PROMISC); | igc_if_set_promisc(ctx, IFF_PROMISC); | ||||
igc_clear_hw_cntrs_base_generic(&adapter->hw); | igc_clear_hw_cntrs_base_generic(&adapter->hw); | ||||
if (adapter->intr_type == IFLIB_INTR_MSIX) /* Set up queue routing */ | if (adapter->intr_type == IFLIB_INTR_MSIX) /* Set up queue routing */ | ||||
igc_configure_queues(adapter); | igc_configure_queues(adapter); | ||||
▲ Show 20 Lines • Show All 240 Lines • ▼ Show 20 Lines | igc_if_set_promisc(if_ctx_t ctx, int flags) | ||||
/* Don't disable if in MAX groups */ | /* Don't disable if in MAX groups */ | ||||
if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) | if (mcnt < MAX_NUM_MULTICAST_ADDRESSES) | ||||
reg_rctl &= (~IGC_RCTL_MPE); | reg_rctl &= (~IGC_RCTL_MPE); | ||||
IGC_WRITE_REG(&adapter->hw, IGC_RCTL, reg_rctl); | IGC_WRITE_REG(&adapter->hw, IGC_RCTL, reg_rctl); | ||||
if (flags & IFF_PROMISC) { | if (flags & IFF_PROMISC) { | ||||
reg_rctl |= (IGC_RCTL_UPE | IGC_RCTL_MPE); | reg_rctl |= (IGC_RCTL_UPE | IGC_RCTL_MPE); | ||||
igc_if_vlan_filter_disable(adapter); | |||||
/* Turn this on if you want to see bad packets */ | /* Turn this on if you want to see bad packets */ | ||||
if (igc_debug_sbp) | if (igc_debug_sbp) | ||||
reg_rctl |= IGC_RCTL_SBP; | reg_rctl |= IGC_RCTL_SBP; | ||||
IGC_WRITE_REG(&adapter->hw, IGC_RCTL, reg_rctl); | IGC_WRITE_REG(&adapter->hw, IGC_RCTL, reg_rctl); | ||||
} else if (flags & IFF_ALLMULTI) { | } else { | ||||
if (flags & IFF_ALLMULTI) { | |||||
reg_rctl |= IGC_RCTL_MPE; | reg_rctl |= IGC_RCTL_MPE; | ||||
reg_rctl &= ~IGC_RCTL_UPE; | reg_rctl &= ~IGC_RCTL_UPE; | ||||
IGC_WRITE_REG(&adapter->hw, IGC_RCTL, reg_rctl); | IGC_WRITE_REG(&adapter->hw, IGC_RCTL, reg_rctl); | ||||
} | } | ||||
if (igc_if_vlan_filter_used(adapter)) | |||||
igc_if_vlan_filter_enable(adapter); | |||||
} | |||||
return (0); | return (0); | ||||
} | } | ||||
static u_int | static u_int | ||||
igc_copy_maddr(void *arg, struct sockaddr_dl *sdl, u_int idx) | igc_copy_maddr(void *arg, struct sockaddr_dl *sdl, u_int idx) | ||||
{ | { | ||||
u8 *mta = arg; | u8 *mta = arg; | ||||
▲ Show 20 Lines • Show All 1,010 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct igc_adapter *adapter = iflib_get_softc(ctx); | struct igc_adapter *adapter = iflib_get_softc(ctx); | ||||
u32 index, bit; | u32 index, bit; | ||||
index = (vtag >> 5) & 0x7F; | index = (vtag >> 5) & 0x7F; | ||||
bit = vtag & 0x1F; | bit = vtag & 0x1F; | ||||
adapter->shadow_vfta[index] |= (1 << bit); | adapter->shadow_vfta[index] |= (1 << bit); | ||||
++adapter->num_vlans; | ++adapter->num_vlans; | ||||
igc_if_vlan_filter_write(adapter); | |||||
} | } | ||||
static void | static void | ||||
igc_if_vlan_unregister(if_ctx_t ctx, u16 vtag) | igc_if_vlan_unregister(if_ctx_t ctx, u16 vtag) | ||||
{ | { | ||||
struct igc_adapter *adapter = iflib_get_softc(ctx); | struct igc_adapter *adapter = iflib_get_softc(ctx); | ||||
u32 index, bit; | u32 index, bit; | ||||
index = (vtag >> 5) & 0x7F; | index = (vtag >> 5) & 0x7F; | ||||
bit = vtag & 0x1F; | bit = vtag & 0x1F; | ||||
adapter->shadow_vfta[index] &= ~(1 << bit); | adapter->shadow_vfta[index] &= ~(1 << bit); | ||||
--adapter->num_vlans; | --adapter->num_vlans; | ||||
igc_if_vlan_filter_write(adapter); | |||||
} | } | ||||
static bool | |||||
igc_if_vlan_filter_capable(struct igc_adapter *adapter) | |||||
{ | |||||
if_softc_ctx_t scctx = adapter->shared; | |||||
if ((scctx->isc_capenable & IFCAP_VLAN_HWFILTER) && | |||||
!igc_disable_crc_stripping) | |||||
return (true); | |||||
return (false); | |||||
} | |||||
static bool | |||||
igc_if_vlan_filter_used(struct igc_adapter *adapter) | |||||
{ | |||||
if (!igc_if_vlan_filter_capable(adapter)) | |||||
return (false); | |||||
for (int i = 0; i < IGC_VFTA_SIZE; i++) | |||||
if (adapter->shadow_vfta[i] != 0) | |||||
return (true); | |||||
return (false); | |||||
} | |||||
static void | static void | ||||
igc_if_vlan_filter_enable(struct igc_adapter *adapter) | |||||
{ | |||||
struct igc_hw *hw = &adapter->hw; | |||||
u32 reg; | |||||
reg = IGC_READ_REG(hw, IGC_RCTL); | |||||
reg &= ~IGC_RCTL_CFIEN; | |||||
reg |= IGC_RCTL_VFE; | |||||
IGC_WRITE_REG(hw, IGC_RCTL, reg); | |||||
} | |||||
static void | |||||
igc_if_vlan_filter_disable(struct igc_adapter *adapter) | |||||
{ | |||||
struct igc_hw *hw = &adapter->hw; | |||||
u32 reg; | |||||
reg = IGC_READ_REG(hw, IGC_RCTL); | |||||
reg &= ~(IGC_RCTL_VFE | IGC_RCTL_CFIEN); | |||||
IGC_WRITE_REG(hw, IGC_RCTL, reg); | |||||
} | |||||
static void | |||||
igc_if_vlan_filter_write(struct igc_adapter *adapter) | |||||
{ | |||||
struct igc_hw *hw = &adapter->hw; | |||||
for (int i = 0; i < IGC_VFTA_SIZE; i++) | |||||
if (adapter->shadow_vfta[i] != 0) { | |||||
igc_write_vfta(hw, i, adapter->shadow_vfta[i]); | |||||
} | |||||
} | |||||
static void | |||||
igc_setup_vlan_hw_support(struct igc_adapter *adapter) | igc_setup_vlan_hw_support(struct igc_adapter *adapter) | ||||
{ | { | ||||
if_softc_ctx_t scctx = adapter->shared; | |||||
struct igc_hw *hw = &adapter->hw; | struct igc_hw *hw = &adapter->hw; | ||||
u32 reg; | u32 reg; | ||||
/* | if (scctx->isc_capenable & IFCAP_VLAN_HWTAGGING && | ||||
* We get here thru init_locked, meaning | !igc_disable_crc_stripping) { | ||||
* a soft reset, this has already cleared | reg = IGC_READ_REG(hw, IGC_CTRL); | ||||
* the VFTA and other state, so if there | reg |= IGC_CTRL_VME; | ||||
* have been no vlan's registered do nothing. | IGC_WRITE_REG(hw, IGC_CTRL, reg); | ||||
*/ | } else { | ||||
if (adapter->num_vlans == 0) | reg = IGC_READ_REG(hw, IGC_CTRL); | ||||
reg &= ~IGC_CTRL_VME; | |||||
IGC_WRITE_REG(hw, IGC_CTRL, reg); | |||||
} | |||||
/* If we aren't doing HW filtering, we're done */ | |||||
if (!igc_if_vlan_filter_capable(adapter)) { | |||||
igc_if_vlan_filter_disable(adapter); | |||||
return; | return; | ||||
} | |||||
/* | /* | ||||
* A soft reset zero's out the VFTA, so | * A soft reset zero's out the VFTA, so | ||||
* we need to repopulate it now. | * we need to repopulate it now. | ||||
*/ | */ | ||||
for (int i = 0; i < IGC_VFTA_SIZE; i++) | igc_if_vlan_filter_write(adapter); | ||||
if (adapter->shadow_vfta[i] != 0) | |||||
IGC_WRITE_REG_ARRAY(hw, IGC_VFTA, | |||||
i, adapter->shadow_vfta[i]); | |||||
reg = IGC_READ_REG(hw, IGC_CTRL); | |||||
reg |= IGC_CTRL_VME; | |||||
IGC_WRITE_REG(hw, IGC_CTRL, reg); | |||||
/* Enable the Filter Table */ | /* Enable the Filter Table */ | ||||
reg = IGC_READ_REG(hw, IGC_RCTL); | igc_if_vlan_filter_enable(adapter); | ||||
reg &= ~IGC_RCTL_CFIEN; | |||||
reg |= IGC_RCTL_VFE; | |||||
IGC_WRITE_REG(hw, IGC_RCTL, reg); | |||||
} | } | ||||
static void | static void | ||||
igc_if_intr_enable(if_ctx_t ctx) | igc_if_intr_enable(if_ctx_t ctx) | ||||
{ | { | ||||
struct igc_adapter *adapter = iflib_get_softc(ctx); | struct igc_adapter *adapter = iflib_get_softc(ctx); | ||||
struct igc_hw *hw = &adapter->hw; | struct igc_hw *hw = &adapter->hw; | ||||
u32 mask; | u32 mask; | ||||
▲ Show 20 Lines • Show All 259 Lines • ▼ Show 20 Lines | |||||
* | * | ||||
* @returns true if iflib needs to reinit the interface | * @returns true if iflib needs to reinit the interface | ||||
*/ | */ | ||||
static bool | static bool | ||||
igc_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) | igc_if_needs_restart(if_ctx_t ctx __unused, enum iflib_restart_event event) | ||||
{ | { | ||||
switch (event) { | switch (event) { | ||||
case IFLIB_RESTART_VLAN_CONFIG: | case IFLIB_RESTART_VLAN_CONFIG: | ||||
return (false); | |||||
default: | default: | ||||
return (true); | return (true); | ||||
} | } | ||||
} | } | ||||
/* Export a single 32-bit register via a read-only sysctl. */ | /* Export a single 32-bit register via a read-only sysctl. */ | ||||
static int | static int | ||||
igc_sysctl_reg_handler(SYSCTL_HANDLER_ARGS) | igc_sysctl_reg_handler(SYSCTL_HANDLER_ARGS) | ||||
▲ Show 20 Lines • Show All 505 Lines • Show Last 20 Lines |