mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Update to igb and em:
em revision 7.0.0: - Using driver devclass, seperate legacy (pre-pcie) code into a seperate source file. This will at least help protect against regression issues. It compiles along with em, and is transparent to end use, devices in each appear to be 'emX'. When using em in a modular form this also allows the legacy stuff to be defined out. - Add tx and rx rings as in igb, in the 82574 this becomes actual multiqueue for the first time (2 queues) while in other PCIE adapters its just make code cleaner. - Add RX mbuf handling logic that matches igb, this will eliminate packet drops due to temporary mbuf shortage. igb revision 1.9.3: - Following the ixgbe code, use a new approach in what was called 'get_buf', the routine now has been made independent of rxeof, it now does the update to the engine TDT register, this design allows temporary mbuf resources to become non-critical, not requiring a packet to be discarded, instead it just returns and does not increment the tail pointer. - With the above change it was also unnecessary to keep 'spare' maps around, since we do not have the discard issue. - Performance tweaks and improvements to the code also. MFC in a week
This commit is contained in:
parent
4cc5f38e97
commit
8ec87fc514
20 changed files with 6996 additions and 2247 deletions
|
|
@ -912,6 +912,8 @@ dev/eisa/eisa_if.m standard
|
|||
dev/eisa/eisaconf.c optional eisa
|
||||
dev/e1000/if_em.c optional em inet \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/if_lem.c optional em inet \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/if_igb.c optional igb inet \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_80003es2lan.c optional em | igb \
|
||||
|
|
|
|||
|
|
@ -231,7 +231,9 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw)
|
|||
mac->rar_entry_count = E1000_RAR_ENTRIES;
|
||||
/* Set if part includes ASF firmware */
|
||||
mac->asf_firmware_present = TRUE;
|
||||
/* Set if manageability features are enabled. */
|
||||
/* FWSM register */
|
||||
mac->has_fwsm = TRUE;
|
||||
/* 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;
|
||||
|
|
|
|||
|
|
@ -313,10 +313,6 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
|||
mac->rar_entry_count = E1000_RAR_ENTRIES;
|
||||
/* Set if part includes ASF firmware */
|
||||
mac->asf_firmware_present = TRUE;
|
||||
/* Set if manageability features are enabled. */
|
||||
mac->arc_subsystem_valid =
|
||||
(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
|
||||
? TRUE : FALSE;
|
||||
/* Adaptive IFS supported */
|
||||
mac->adaptive_ifs = TRUE;
|
||||
|
||||
|
|
@ -357,6 +353,16 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
|||
mac->ops.set_lan_id = e1000_set_lan_id_single_port;
|
||||
mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
|
||||
mac->ops.led_on = e1000_led_on_generic;
|
||||
|
||||
/* FWSM register */
|
||||
mac->has_fwsm = TRUE;
|
||||
/*
|
||||
* 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;
|
||||
break;
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
|
|
@ -367,6 +373,9 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
|||
default:
|
||||
mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
|
||||
mac->ops.led_on = e1000_led_on_generic;
|
||||
|
||||
/* FWSM register */
|
||||
mac->has_fwsm = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1076,9 +1085,10 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
|
|||
/* ...for both queues. */
|
||||
switch (mac->type) {
|
||||
case e1000_82573:
|
||||
e1000_enable_tx_pkt_filtering_generic(hw);
|
||||
/* fall through */
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
e1000_enable_tx_pkt_filtering_generic(hw);
|
||||
reg_data = E1000_READ_REG(hw, E1000_GCR);
|
||||
reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
|
||||
E1000_WRITE_REG(hw, E1000_GCR, reg_data);
|
||||
|
|
@ -1364,7 +1374,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
|
|||
static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
|
||||
{
|
||||
u32 ctrl;
|
||||
s32 ret_val;
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_setup_copper_link_82571");
|
||||
|
||||
|
|
|
|||
|
|
@ -289,7 +289,9 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
|
|||
mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
|
||||
/* Set if part includes ASF firmware */
|
||||
mac->asf_firmware_present = TRUE;
|
||||
/* Set if manageability features are enabled. */
|
||||
/* FWSM register */
|
||||
mac->has_fwsm = TRUE;
|
||||
/* 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;
|
||||
|
|
@ -1435,13 +1437,12 @@ static void e1000_config_collision_dist_82575(struct e1000_hw *hw)
|
|||
static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
|
||||
if (!(phy->ops.check_reset_block))
|
||||
return;
|
||||
|
||||
/* If the management interface is not enabled, then power down */
|
||||
if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw)))
|
||||
if (!(e1000_enable_mng_pass_thru(hw) || phy->ops.check_reset_block(hw)))
|
||||
e1000_power_down_phy_copper(hw);
|
||||
|
||||
return;
|
||||
|
|
@ -1646,14 +1647,23 @@ out:
|
|||
**/
|
||||
void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
|
||||
{
|
||||
u32 dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
|
||||
u32 dtxswc;
|
||||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82576:
|
||||
dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
|
||||
if (enable)
|
||||
dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
|
||||
else
|
||||
dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
|
||||
E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
|
||||
break;
|
||||
default:
|
||||
/* Currently no other hardware supports loopback */
|
||||
break;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
|
||||
else
|
||||
dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@
|
|||
* For 82576, there are an additional set of RARs that begin at an offset
|
||||
* separate from the first set of RARs.
|
||||
*/
|
||||
#define E1000_RAR_ENTRIES_82575 16
|
||||
#define E1000_RAR_ENTRIES_82576 24
|
||||
#define E1000_RAR_ENTRIES_82575 16
|
||||
#define E1000_RAR_ENTRIES_82576 24
|
||||
#define E1000_RAR_ENTRIES_82580 24
|
||||
#define E1000_SW_SYNCH_MB 0x00000100
|
||||
#define E1000_STAT_DEV_RST_SET 0x00100000
|
||||
|
|
@ -425,6 +425,7 @@ struct e1000_adv_tx_context_desc {
|
|||
#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
|
||||
#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */
|
||||
|
||||
|
||||
#define E1000_VLVF_ARRAY_SIZE 32
|
||||
#define E1000_VLVF_VLANID_MASK 0x00000FFF
|
||||
#define E1000_VLVF_POOLSEL_SHIFT 12
|
||||
|
|
|
|||
|
|
@ -314,6 +314,11 @@
|
|||
#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
|
||||
#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
|
||||
|
||||
#define E1000_MANC2H_PORT_623 0x00000020 /* Port 0x26f */
|
||||
#define E1000_MANC2H_PORT_664 0x00000040 /* Port 0x298 */
|
||||
#define E1000_MDEF_PORT_623 0x00000800 /* Port 0x26f */
|
||||
#define E1000_MDEF_PORT_664 0x00000400 /* Port 0x298 */
|
||||
|
||||
/* Receive Control */
|
||||
#define E1000_RCTL_RST 0x00000001 /* Software reset */
|
||||
#define E1000_RCTL_EN 0x00000002 /* enable */
|
||||
|
|
@ -418,6 +423,8 @@
|
|||
* PHYRST_N pin */
|
||||
#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external
|
||||
* LINK_0 and LINK_1 pins */
|
||||
#define E1000_CTRL_LANPHYPC_OVERRIDE 0x00010000 /* SW control of LANPHYPC */
|
||||
#define E1000_CTRL_LANPHYPC_VALUE 0x00020000 /* SW value of LANPHYPC */
|
||||
#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
|
||||
#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
|
||||
#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
|
||||
|
|
@ -953,6 +960,8 @@
|
|||
#define E1000_EICS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */
|
||||
|
||||
#define E1000_EITR_ITR_INT_MASK 0x0000FFFF
|
||||
/* E1000_EITR_CNT_IGNR is only for 82576 and newer */
|
||||
#define E1000_EITR_CNT_IGNR 0x80000000 /* Don't reset counters on write */
|
||||
|
||||
/* Transmit Descriptor Control */
|
||||
#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
|
||||
|
|
@ -1380,6 +1389,9 @@
|
|||
#define PCI_HEADER_TYPE_MULTIFUNC 0x80
|
||||
#define PCIE_LINK_WIDTH_MASK 0x3F0
|
||||
#define PCIE_LINK_WIDTH_SHIFT 4
|
||||
#define PCIE_LINK_SPEED_MASK 0x0F
|
||||
#define PCIE_LINK_SPEED_2500 0x01
|
||||
#define PCIE_LINK_SPEED_5000 0x02
|
||||
#define PCIE_DEVICE_CONTROL2_16ms 0x0005
|
||||
|
||||
#ifndef ETH_ADDR_LEN
|
||||
|
|
@ -1410,7 +1422,7 @@
|
|||
#define BME1000_E_PHY_ID_R2 0x01410CB1
|
||||
#define I82577_E_PHY_ID 0x01540050
|
||||
#define I82578_E_PHY_ID 0x004DD040
|
||||
#define I82580_I_PHY_ID 0x015403A0
|
||||
#define I82580_I_PHY_ID 0x015403A0
|
||||
#define IGP04E1000_E_PHY_ID 0x02A80391
|
||||
#define M88_VENDOR 0x0141
|
||||
|
||||
|
|
@ -1507,6 +1519,7 @@
|
|||
#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
|
||||
#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */
|
||||
|
||||
|
||||
/* M88EC018 Rev 2 specific DownShift settings */
|
||||
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
|
||||
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X 0x0000
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ struct e1000_hw;
|
|||
#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
|
||||
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
|
||||
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
|
||||
|
||||
#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
|
||||
|
|
@ -682,6 +683,7 @@ struct e1000_mac_info {
|
|||
u8 forced_speed_duplex;
|
||||
|
||||
bool adaptive_ifs;
|
||||
bool has_fwsm;
|
||||
bool arc_subsystem_valid;
|
||||
bool asf_firmware_present;
|
||||
bool autoneg;
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ union ich8_hws_flash_regacc {
|
|||
static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
u32 ctrl;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
DEBUGFUNC("e1000_init_phy_params_pchlan");
|
||||
|
|
@ -199,6 +200,35 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
|
|||
phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
|
||||
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
|
||||
|
||||
if ((hw->mac.type == e1000_pchlan) &&
|
||||
(!(E1000_READ_REG(hw, E1000_FWSM) & E1000_ICH_FWSM_FW_VALID))) {
|
||||
|
||||
/*
|
||||
* The MAC-PHY interconnect may still be in SMBus mode
|
||||
* after Sx->S0. Toggle the LANPHYPC Value bit to force
|
||||
* the interconnect to PCIe mode, but only if there is no
|
||||
* firmware present otherwise firmware will have done it.
|
||||
*/
|
||||
ctrl = E1000_READ_REG(hw, E1000_CTRL);
|
||||
ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE;
|
||||
ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
|
||||
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
|
||||
usec_delay(10);
|
||||
ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
|
||||
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
|
||||
msec_delay(50);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the PHY before any acccess to it. Doing so, ensures that
|
||||
* the PHY is in a known good state before we read/write PHY registers.
|
||||
* The generic reset is sufficient here, because we haven't determined
|
||||
* the PHY type yet.
|
||||
*/
|
||||
ret_val = e1000_phy_hw_reset_generic(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
phy->id = e1000_phy_unknown;
|
||||
ret_val = e1000_get_phy_id(hw);
|
||||
if (ret_val)
|
||||
|
|
@ -225,6 +255,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
|
|||
phy->ops.get_cable_length = e1000_get_cable_length_82577;
|
||||
phy->ops.get_info = e1000_get_phy_info_82577;
|
||||
phy->ops.commit = e1000_phy_sw_reset_generic;
|
||||
break;
|
||||
case e1000_phy_82578:
|
||||
phy->ops.check_polarity = e1000_check_polarity_m88;
|
||||
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
|
||||
|
|
@ -431,8 +462,10 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
|
|||
mac->rar_entry_count--;
|
||||
/* Set if part includes ASF firmware */
|
||||
mac->asf_firmware_present = TRUE;
|
||||
/* Set if manageability features are enabled. */
|
||||
mac->arc_subsystem_valid = TRUE;
|
||||
/* FWSM register */
|
||||
mac->has_fwsm = TRUE;
|
||||
/* ARC subsystem not supported */
|
||||
mac->arc_subsystem_valid = FALSE;
|
||||
/* Adaptive IFS supported */
|
||||
mac->adaptive_ifs = TRUE;
|
||||
|
||||
|
|
@ -764,6 +797,9 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
|
|||
|
||||
DEBUGFUNC("e1000_check_reset_block_ich8lan");
|
||||
|
||||
if (hw->phy.reset_disable)
|
||||
return E1000_BLK_PHY_RESET;
|
||||
|
||||
fwsm = E1000_READ_REG(hw, E1000_FWSM);
|
||||
|
||||
return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? E1000_SUCCESS
|
||||
|
|
@ -2684,6 +2720,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
|
|||
DEBUGOUT("Auto Read Done did not complete\n");
|
||||
}
|
||||
}
|
||||
/* Dummy read to clear the phy wakeup bit after lcd reset */
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
hw->phy.ops.read_reg(hw, BM_WUC, ®);
|
||||
|
||||
|
|
@ -2857,6 +2894,14 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
|
|||
E1000_WRITE_REG(hw, E1000_STATUS, reg);
|
||||
}
|
||||
|
||||
/*
|
||||
* work-around descriptor data corruption issue during nfs v2 udp
|
||||
* traffic, just disable the nfs filtering capability
|
||||
*/
|
||||
reg = E1000_READ_REG(hw, E1000_RFCTL);
|
||||
reg |= (E1000_RFCTL_NFSW_DIS | E1000_RFCTL_NFSR_DIS);
|
||||
E1000_WRITE_REG(hw, E1000_RFCTL, reg);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -167,6 +167,9 @@
|
|||
#define HV_KMRN_MODE_CTRL PHY_REG(769, 16)
|
||||
#define HV_KMRN_MDIO_SLOW 0x0400
|
||||
|
||||
/* PHY Power Management Control */
|
||||
#define HV_PM_CTRL PHY_REG(770, 17)
|
||||
|
||||
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */
|
||||
|
||||
/*
|
||||
|
|
@ -192,7 +195,6 @@
|
|||
#define E1000_RXDEXT_LINKSEC_ERROR_REPLAY_ERROR 0x40000000
|
||||
#define E1000_RXDEXT_LINKSEC_ERROR_BAD_SIG 0x60000000
|
||||
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -225,17 +225,30 @@ s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw)
|
|||
DEBUGFUNC("e1000_get_bus_info_pcie_generic");
|
||||
|
||||
bus->type = e1000_bus_type_pci_express;
|
||||
bus->speed = e1000_bus_speed_2500;
|
||||
|
||||
ret_val = e1000_read_pcie_cap_reg(hw,
|
||||
PCIE_LINK_STATUS,
|
||||
&pcie_link_status);
|
||||
if (ret_val)
|
||||
if (ret_val) {
|
||||
bus->width = e1000_bus_width_unknown;
|
||||
else
|
||||
bus->speed = e1000_bus_speed_unknown;
|
||||
} else {
|
||||
switch (pcie_link_status & PCIE_LINK_SPEED_MASK) {
|
||||
case PCIE_LINK_SPEED_2500:
|
||||
bus->speed = e1000_bus_speed_2500;
|
||||
break;
|
||||
case PCIE_LINK_SPEED_5000:
|
||||
bus->speed = e1000_bus_speed_5000;
|
||||
break;
|
||||
default:
|
||||
bus->speed = e1000_bus_speed_unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
bus->width = (enum e1000_bus_width)((pcie_link_status &
|
||||
PCIE_LINK_WIDTH_MASK) >>
|
||||
PCIE_LINK_WIDTH_SHIFT);
|
||||
}
|
||||
|
||||
mac->ops.set_lan_id(hw);
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,12 @@ s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
|
|||
|
||||
DEBUGFUNC("e1000_mng_enable_host_if_generic");
|
||||
|
||||
if (!(hw->mac.arc_subsystem_valid)) {
|
||||
DEBUGOUT("ARC subsystem not valid.\n");
|
||||
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Check that the host interface is enabled. */
|
||||
hicr = E1000_READ_REG(hw, E1000_HICR);
|
||||
if ((hicr & E1000_HICR_EN) == 0) {
|
||||
|
|
@ -365,7 +371,7 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
|
|||
if (!(manc & E1000_MANC_RCV_TCO_EN))
|
||||
goto out;
|
||||
|
||||
if (hw->mac.arc_subsystem_valid) {
|
||||
if (hw->mac.has_fwsm) {
|
||||
fwsm = E1000_READ_REG(hw, E1000_FWSM);
|
||||
factps = E1000_READ_REG(hw, E1000_FACTPS);
|
||||
|
||||
|
|
@ -375,12 +381,23 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
|
|||
ret_val = TRUE;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if ((manc & E1000_MANC_SMBUS_EN) &&
|
||||
!(manc & E1000_MANC_ASF_EN)) {
|
||||
} else if ((hw->mac.type == e1000_82574) ||
|
||||
(hw->mac.type == e1000_82583)) {
|
||||
u16 data;
|
||||
|
||||
factps = E1000_READ_REG(hw, E1000_FACTPS);
|
||||
e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data);
|
||||
|
||||
if (!(factps & E1000_FACTPS_MNGCG) &&
|
||||
((data & E1000_NVM_INIT_CTRL2_MNGM) ==
|
||||
(e1000_mng_mode_pt << 13))) {
|
||||
ret_val = TRUE;
|
||||
goto out;
|
||||
}
|
||||
} else if ((manc & E1000_MANC_SMBUS_EN) &&
|
||||
!(manc & E1000_MANC_ASF_EN)) {
|
||||
ret_val = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
|||
|
|
@ -3402,9 +3402,7 @@ s32 e1000_check_polarity_82577(struct e1000_hw *hw)
|
|||
* e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Calls the PHY setup function to force speed and duplex. Clears the
|
||||
* auto-crossover to force MDI manually. Waits for link and returns
|
||||
* successful if link up is successful, else -E1000_ERR_PHY (-2).
|
||||
* Calls the PHY setup function to force speed and duplex.
|
||||
**/
|
||||
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
|
||||
{
|
||||
|
|
@ -3425,23 +3423,6 @@ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
|
|||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Clear Auto-Crossover to force MDI manually. 82577 requires MDI
|
||||
* forced whenever speed and duplex are forced.
|
||||
*/
|
||||
ret_val = phy->ops.read_reg(hw, I82577_PHY_CTRL_2, &phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
phy_data &= ~I82577_PHY_CTRL2_AUTO_MDIX;
|
||||
phy_data &= ~I82577_PHY_CTRL2_FORCE_MDI_MDIX;
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, I82577_PHY_CTRL_2, phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
DEBUGOUT1("I82577_PHY_CTRL_2: %X\n", phy_data);
|
||||
|
||||
usec_delay(1);
|
||||
|
||||
if (phy->autoneg_wait_to_complete) {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
|
||||
#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */
|
||||
#define E1000_SVCR 0x000F0
|
||||
#define E1000_SVT 0x000F4
|
||||
#define E1000_SVT 0x000F4
|
||||
#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 */
|
||||
|
|
@ -282,6 +282,17 @@
|
|||
#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
|
||||
#define E1000_CRC_OFFSET 0x05F50 /* CRC Offset register */
|
||||
|
||||
/* Virtualization statistical counters */
|
||||
#define E1000_PFVFGPRC(_n) (0x010010 + (0x100 * (_n)))
|
||||
#define E1000_PFVFGPTC(_n) (0x010014 + (0x100 * (_n)))
|
||||
#define E1000_PFVFGORC(_n) (0x010018 + (0x100 * (_n)))
|
||||
#define E1000_PFVFGOTC(_n) (0x010034 + (0x100 * (_n)))
|
||||
#define E1000_PFVFMPRC(_n) (0x010038 + (0x100 * (_n)))
|
||||
#define E1000_PFVFGPRLBC(_n) (0x010040 + (0x100 * (_n)))
|
||||
#define E1000_PFVFGPTLBC(_n) (0x010044 + (0x100 * (_n)))
|
||||
#define E1000_PFVFGORLBC(_n) (0x010048 + (0x100 * (_n)))
|
||||
#define E1000_PFVFGOTLBC(_n) (0x010050 + (0x100 * (_n)))
|
||||
|
||||
#define E1000_LSECTXUT 0x04300 /* LinkSec Tx Untagged Packet Count - OutPktsUntagged */
|
||||
#define E1000_LSECTXPKTE 0x04304 /* LinkSec Encrypted Tx Packets Count - OutPktsEncrypted */
|
||||
#define E1000_LSECTXPKTP 0x04308 /* LinkSec Protected Tx Packet Count - OutPktsProtected */
|
||||
|
|
@ -386,6 +397,7 @@
|
|||
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
|
||||
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
|
||||
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
|
||||
#define E1000_MDEF(_n) (0x05890 + (4 * (_n))) /* Mngmt Decision Filters */
|
||||
#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
|
||||
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
|
||||
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -52,7 +52,6 @@
|
|||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define EM_MIN_TXD 80
|
||||
#define EM_MAX_TXD_82543 256
|
||||
#define EM_MAX_TXD 4096
|
||||
#define EM_DEFAULT_TXD 1024
|
||||
|
||||
|
|
@ -70,7 +69,6 @@
|
|||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define EM_MIN_RXD 80
|
||||
#define EM_MAX_RXD_82543 256
|
||||
#define EM_MAX_RXD 4096
|
||||
#define EM_DEFAULT_RXD 1024
|
||||
|
||||
|
|
@ -144,7 +142,6 @@
|
|||
* transmit descriptors.
|
||||
*/
|
||||
#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
|
||||
#define EM_TX_OP_THRESHOLD (adapter->num_tx_desc / 32)
|
||||
|
||||
/*
|
||||
* This parameter controls whether or not autonegotation is enabled.
|
||||
|
|
@ -182,7 +179,7 @@
|
|||
#define EM_DEFAULT_PBA 0x00000030
|
||||
#define EM_SMARTSPEED_DOWNSHIFT 3
|
||||
#define EM_SMARTSPEED_MAX 15
|
||||
#define EM_MAX_INTR 10
|
||||
#define EM_MAX_LOOP 10
|
||||
|
||||
#define MAX_NUM_MULTICAST_ADDRESSES 128
|
||||
#define PCI_ANY_ID (~0U)
|
||||
|
|
@ -191,11 +188,6 @@
|
|||
#define EM_EEPROM_APME 0x400;
|
||||
#define EM_82544_APME 0x0004;
|
||||
|
||||
/* Code compatilbility between 6 and 7 */
|
||||
#ifndef ETHER_BPF_MTAP
|
||||
#define ETHER_BPF_MTAP BPF_MTAP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
|
||||
* multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
|
||||
|
|
@ -209,7 +201,6 @@
|
|||
#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
|
||||
#define EM_BAR_TYPE_MASK 0x00000001
|
||||
#define EM_BAR_TYPE_MMEM 0x00000000
|
||||
#define EM_BAR_TYPE_IO 0x00000001
|
||||
#define EM_BAR_TYPE_FLASH 0x0014
|
||||
#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK)
|
||||
#define EM_BAR_MEM_TYPE_MASK 0x00000006
|
||||
|
|
@ -237,6 +228,7 @@
|
|||
#define EM_TSO_SIZE (65535 + sizeof(struct ether_vlan_header))
|
||||
#define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */
|
||||
#define EM_MSIX_MASK 0x01F00000 /* For 82574 use */
|
||||
#define EM_MSIX_LINK 0x01000000 /* For 82574 use */
|
||||
#define ETH_ZLEN 60
|
||||
#define ETH_ADDR_LEN 6
|
||||
#define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */
|
||||
|
|
@ -249,18 +241,6 @@
|
|||
*/
|
||||
#define EM_EIAC 0x000DC
|
||||
|
||||
/* Used in for 82547 10Mb Half workaround */
|
||||
#define EM_PBA_BYTES_SHIFT 0xA
|
||||
#define EM_TX_HEAD_ADDR_SHIFT 7
|
||||
#define EM_PBA_TX_MASK 0xFFFF0000
|
||||
#define EM_FIFO_HDR 0x10
|
||||
#define EM_82547_PKT_THRESH 0x3e0
|
||||
|
||||
/* Precision Time Sync (IEEE 1588) defines */
|
||||
#define ETHERTYPE_IEEE1588 0x88F7
|
||||
#define PICOSECS_PER_TICK 20833
|
||||
#define TSYNC_PORT 319 /* UDP port for the protocol */
|
||||
|
||||
/*
|
||||
* Bus dma allocation structure used by
|
||||
* e1000_dma_malloc and e1000_dma_free.
|
||||
|
|
@ -282,12 +262,76 @@ struct em_int_delay_info {
|
|||
int value; /* Current value in usecs */
|
||||
};
|
||||
|
||||
/*
|
||||
* The transmit ring, one per tx queue
|
||||
*/
|
||||
struct tx_ring {
|
||||
struct adapter *adapter;
|
||||
struct mtx tx_mtx;
|
||||
char mtx_name[16];
|
||||
u32 me;
|
||||
u32 msix;
|
||||
u32 ims;
|
||||
bool watchdog_check;
|
||||
int watchdog_time;
|
||||
struct em_dma_alloc txdma;
|
||||
struct e1000_tx_desc *tx_base;
|
||||
struct task tx_task;
|
||||
struct taskqueue *tq;
|
||||
u32 next_avail_desc;
|
||||
u32 next_to_clean;
|
||||
struct em_buffer *tx_buffers;
|
||||
volatile u16 tx_avail;
|
||||
u32 tx_tso; /* last tx was tso */
|
||||
u16 last_hw_offload;
|
||||
#if __FreeBSD_version >= 800000
|
||||
struct buf_ring *br;
|
||||
#endif
|
||||
/* Interrupt resources */
|
||||
bus_dma_tag_t txtag;
|
||||
void *tag;
|
||||
struct resource *res;
|
||||
u64 tx_irq;
|
||||
u64 no_desc_avail;
|
||||
};
|
||||
|
||||
/*
|
||||
* The Receive ring, one per rx queue
|
||||
*/
|
||||
struct rx_ring {
|
||||
struct adapter *adapter;
|
||||
u32 me;
|
||||
u32 msix;
|
||||
u32 ims;
|
||||
struct mtx rx_mtx;
|
||||
char mtx_name[16];
|
||||
u32 payload;
|
||||
struct task rx_task;
|
||||
struct taskqueue *tq;
|
||||
struct e1000_rx_desc *rx_base;
|
||||
struct em_dma_alloc rxdma;
|
||||
unsigned int next_to_refresh;
|
||||
unsigned int next_to_check;
|
||||
struct em_buffer *rx_buffers;
|
||||
struct mbuf *fmp;
|
||||
struct mbuf *lmp;
|
||||
|
||||
/* Interrupt resources */
|
||||
void *tag;
|
||||
struct resource *res;
|
||||
bus_dma_tag_t rxtag;
|
||||
bus_dmamap_t rx_sparemap;
|
||||
|
||||
/* Soft stats */
|
||||
u64 rx_irq;
|
||||
u64 rx_packets;
|
||||
u64 rx_bytes;
|
||||
};
|
||||
|
||||
|
||||
/* Our adapter structure */
|
||||
struct adapter {
|
||||
struct ifnet *ifp;
|
||||
#if __FreeBSD_version >= 800000
|
||||
struct buf_ring *br;
|
||||
#endif
|
||||
struct e1000_hw hw;
|
||||
|
||||
/* FreeBSD operating-system-specific structures. */
|
||||
|
|
@ -296,42 +340,50 @@ struct adapter {
|
|||
|
||||
struct resource *memory;
|
||||
struct resource *flash;
|
||||
struct resource *msix;
|
||||
struct resource *msix_mem;
|
||||
|
||||
struct resource *ioport;
|
||||
int io_rid;
|
||||
|
||||
/* 82574 may use 3 int vectors */
|
||||
struct resource *res[3];
|
||||
void *tag[3];
|
||||
int rid[3];
|
||||
struct resource *res;
|
||||
void *tag;
|
||||
u32 linkvec;
|
||||
u32 ivars;
|
||||
|
||||
struct ifmedia media;
|
||||
struct callout timer;
|
||||
struct callout tx_fifo_timer;
|
||||
bool watchdog_check;
|
||||
int watchdog_time;
|
||||
int msi;
|
||||
int msix;
|
||||
int if_flags;
|
||||
int max_frame_size;
|
||||
int min_frame_size;
|
||||
struct mtx core_mtx;
|
||||
struct mtx tx_mtx;
|
||||
struct mtx rx_mtx;
|
||||
int em_insert_vlan_header;
|
||||
u32 ims;
|
||||
bool in_detach;
|
||||
|
||||
/* Task for FAST handling */
|
||||
struct task link_task;
|
||||
struct task rxtx_task;
|
||||
struct task rx_task;
|
||||
struct task tx_task;
|
||||
struct task que_task;
|
||||
struct taskqueue *tq; /* private task queue */
|
||||
|
||||
#if __FreeBSD_version >= 700029
|
||||
eventhandler_tag vlan_attach;
|
||||
eventhandler_tag vlan_detach;
|
||||
u32 num_vlans;
|
||||
#endif
|
||||
|
||||
u16 num_vlans;
|
||||
u16 num_queues;
|
||||
|
||||
/*
|
||||
* Transmit rings:
|
||||
* Allocated at run time, an array of rings.
|
||||
*/
|
||||
struct tx_ring *tx_rings;
|
||||
int num_tx_desc;
|
||||
u32 txd_cmd;
|
||||
|
||||
/*
|
||||
* Receive rings:
|
||||
* Allocated at run time, an array of rings.
|
||||
*/
|
||||
struct rx_ring *rx_rings;
|
||||
int num_rx_desc;
|
||||
u32 rx_process_limit;
|
||||
|
||||
/* Management and WOL features */
|
||||
u32 wol;
|
||||
|
|
@ -348,96 +400,26 @@ struct adapter {
|
|||
struct em_int_delay_info rx_int_delay;
|
||||
struct em_int_delay_info rx_abs_int_delay;
|
||||
|
||||
/*
|
||||
* Transmit definitions
|
||||
*
|
||||
* We have an array of num_tx_desc descriptors (handled
|
||||
* by the controller) paired with an array of tx_buffers
|
||||
* (at tx_buffer_area).
|
||||
* The index of the next available descriptor is next_avail_tx_desc.
|
||||
* The number of remaining tx_desc is num_tx_desc_avail.
|
||||
*/
|
||||
struct em_dma_alloc txdma; /* bus_dma glue for tx desc */
|
||||
struct e1000_tx_desc *tx_desc_base;
|
||||
uint32_t next_avail_tx_desc;
|
||||
uint32_t next_tx_to_clean;
|
||||
volatile uint16_t num_tx_desc_avail;
|
||||
uint16_t num_tx_desc;
|
||||
uint16_t last_hw_offload;
|
||||
uint32_t txd_cmd;
|
||||
struct em_buffer *tx_buffer_area;
|
||||
bus_dma_tag_t txtag; /* dma tag for tx */
|
||||
uint32_t tx_tso; /* last tx was tso */
|
||||
|
||||
/*
|
||||
* Receive definitions
|
||||
*
|
||||
* we have an array of num_rx_desc rx_desc (handled by the
|
||||
* controller), and paired with an array of rx_buffers
|
||||
* (at rx_buffer_area).
|
||||
* The next pair to check on receive is at offset next_rx_desc_to_check
|
||||
*/
|
||||
struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */
|
||||
struct e1000_rx_desc *rx_desc_base;
|
||||
uint32_t next_rx_desc_to_check;
|
||||
uint32_t rx_buffer_len;
|
||||
uint16_t num_rx_desc;
|
||||
int rx_process_limit;
|
||||
struct em_buffer *rx_buffer_area;
|
||||
bus_dma_tag_t rxtag;
|
||||
bus_dmamap_t rx_sparemap;
|
||||
|
||||
/*
|
||||
* First/last mbuf pointers, for
|
||||
* collecting multisegment RX packets.
|
||||
*/
|
||||
struct mbuf *fmp;
|
||||
struct mbuf *lmp;
|
||||
|
||||
/* Misc stats maintained by the driver */
|
||||
unsigned long dropped_pkts;
|
||||
unsigned long mbuf_alloc_failed;
|
||||
unsigned long mbuf_cluster_failed;
|
||||
unsigned long no_tx_desc_avail1;
|
||||
unsigned long no_tx_desc_avail2;
|
||||
unsigned long no_tx_map_avail;
|
||||
unsigned long no_tx_dma_setup;
|
||||
unsigned long watchdog_events;
|
||||
unsigned long rx_overruns;
|
||||
unsigned long rx_irq;
|
||||
unsigned long tx_irq;
|
||||
unsigned long watchdog_events;
|
||||
unsigned long link_irq;
|
||||
|
||||
/* 82547 workaround */
|
||||
uint32_t tx_fifo_size;
|
||||
uint32_t tx_fifo_head;
|
||||
uint32_t tx_fifo_head_addr;
|
||||
uint64_t tx_fifo_reset_cnt;
|
||||
uint64_t tx_fifo_wrk_cnt;
|
||||
uint32_t tx_head_addr;
|
||||
|
||||
/* For 82544 PCIX Workaround */
|
||||
boolean_t pcix_82544;
|
||||
boolean_t in_detach;
|
||||
|
||||
#ifdef EM_IEEE1588
|
||||
/* IEEE 1588 precision time support */
|
||||
struct cyclecounter cycles;
|
||||
struct nettimer clock;
|
||||
struct nettime_compare compare;
|
||||
struct hwtstamp_ctrl hwtstamp;
|
||||
#endif
|
||||
|
||||
struct e1000_hw_stats stats;
|
||||
};
|
||||
|
||||
/* ******************************************************************************
|
||||
/********************************************************************************
|
||||
* vendor_info_array
|
||||
*
|
||||
* This array contains the list of Subvendor/Subdevice IDs on which the driver
|
||||
* should load.
|
||||
*
|
||||
* ******************************************************************************/
|
||||
********************************************************************************/
|
||||
typedef struct _em_vendor_info_t {
|
||||
unsigned int vendor_id;
|
||||
unsigned int device_id;
|
||||
|
|
@ -452,19 +434,6 @@ struct em_buffer {
|
|||
bus_dmamap_t map; /* bus_dma map for packet */
|
||||
};
|
||||
|
||||
/* For 82544 PCIX Workaround */
|
||||
typedef struct _ADDRESS_LENGTH_PAIR
|
||||
{
|
||||
uint64_t address;
|
||||
uint32_t length;
|
||||
} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
|
||||
|
||||
typedef struct _DESCRIPTOR_PAIR
|
||||
{
|
||||
ADDRESS_LENGTH_PAIR descriptor[4];
|
||||
uint32_t elements;
|
||||
} DESC_ARRAY, *PDESC_ARRAY;
|
||||
|
||||
#define EM_CORE_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->core_mtx, _name, "EM Core Lock", MTX_DEF)
|
||||
#define EM_TX_LOCK_INIT(_sc, _name) \
|
||||
|
|
|
|||
|
|
@ -63,10 +63,6 @@
|
|||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
|
||||
#ifdef IGB_IEEE1588
|
||||
#include <sys/ieee1588.h>
|
||||
#endif
|
||||
|
||||
#include <net/bpf.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if.h>
|
||||
|
|
@ -102,7 +98,7 @@ int igb_display_debug_stats = 0;
|
|||
/*********************************************************************
|
||||
* Driver version:
|
||||
*********************************************************************/
|
||||
char igb_driver_version[] = "version - 1.9.1";
|
||||
char igb_driver_version[] = "version - 1.9.3";
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
|
|
@ -204,12 +200,11 @@ static void igb_disable_intr(struct adapter *);
|
|||
static void igb_update_stats_counters(struct adapter *);
|
||||
static bool igb_txeof(struct tx_ring *);
|
||||
|
||||
static __inline void igb_rx_discard(struct rx_ring *,
|
||||
union e1000_adv_rx_desc *, int);
|
||||
static __inline void igb_rx_discard(struct rx_ring *, int);
|
||||
static __inline void igb_rx_input(struct rx_ring *,
|
||||
struct ifnet *, struct mbuf *, u32);
|
||||
|
||||
static bool igb_rxeof(struct rx_ring *, int);
|
||||
static bool igb_rxeof(struct igb_queue *, int);
|
||||
static void igb_rx_checksum(u32, struct mbuf *, u32);
|
||||
static int igb_tx_ctx_setup(struct tx_ring *, struct mbuf *);
|
||||
static bool igb_tso_setup(struct tx_ring *, struct mbuf *, u32 *);
|
||||
|
|
@ -218,7 +213,7 @@ static void igb_disable_promisc(struct adapter *);
|
|||
static void igb_set_multi(struct adapter *);
|
||||
static void igb_print_hw_stats(struct adapter *);
|
||||
static void igb_update_link_status(struct adapter *);
|
||||
static int igb_get_buf(struct rx_ring *, int, u8);
|
||||
static void igb_refresh_mbufs(struct rx_ring *, int);
|
||||
|
||||
static void igb_register_vlan(void *, struct ifnet *, u16);
|
||||
static void igb_unregister_vlan(void *, struct ifnet *, u16);
|
||||
|
|
@ -814,6 +809,9 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
|
|||
/* Which queue to use */
|
||||
if ((m->m_flags & M_FLOWID) != 0)
|
||||
i = m->m_pkthdr.flowid % adapter->num_queues;
|
||||
else
|
||||
i = curcpu % adapter->num_queues;
|
||||
|
||||
txr = &adapter->tx_rings[i];
|
||||
|
||||
if (IGB_TX_TRYLOCK(txr)) {
|
||||
|
|
@ -1192,15 +1190,15 @@ igb_init(void *arg)
|
|||
static void
|
||||
igb_handle_rxtx(void *context, int pending)
|
||||
{
|
||||
struct adapter *adapter = context;
|
||||
struct tx_ring *txr = adapter->tx_rings;
|
||||
struct rx_ring *rxr = adapter->rx_rings;
|
||||
struct ifnet *ifp;
|
||||
struct igb_queue *que = context;
|
||||
struct adapter *adapter = que->adapter;
|
||||
struct tx_ring *txr = adapter->tx_rings;
|
||||
struct ifnet *ifp;
|
||||
|
||||
ifp = adapter->ifp;
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
if (igb_rxeof(rxr, adapter->rx_process_limit))
|
||||
if (igb_rxeof(que, adapter->rx_process_limit))
|
||||
taskqueue_enqueue(adapter->tq, &adapter->rxtx_task);
|
||||
IGB_TX_LOCK(txr);
|
||||
igb_txeof(txr);
|
||||
|
|
@ -1224,14 +1222,13 @@ igb_handle_que(void *context, int pending)
|
|||
struct igb_queue *que = context;
|
||||
struct adapter *adapter = que->adapter;
|
||||
struct tx_ring *txr = que->txr;
|
||||
struct rx_ring *rxr = que->rxr;
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
u32 loop = IGB_MAX_LOOP;
|
||||
bool more;
|
||||
|
||||
/* RX first */
|
||||
do {
|
||||
more = igb_rxeof(rxr, -1);
|
||||
more = igb_rxeof(que, -1);
|
||||
} while (loop-- && more);
|
||||
|
||||
if (IGB_TX_TRYLOCK(txr)) {
|
||||
|
|
@ -1388,7 +1385,7 @@ igb_msix_que(void *arg)
|
|||
more_tx = igb_txeof(txr);
|
||||
IGB_TX_UNLOCK(txr);
|
||||
|
||||
more_rx = igb_rxeof(rxr, adapter->rx_process_limit);
|
||||
more_rx = igb_rxeof(que, adapter->rx_process_limit);
|
||||
|
||||
if (igb_enable_aim == FALSE)
|
||||
goto no_calc;
|
||||
|
|
@ -1955,6 +1952,7 @@ igb_update_link_status(struct adapter *adapter)
|
|||
"Full Duplex" : "Half Duplex"));
|
||||
adapter->link_active = 1;
|
||||
ifp->if_baudrate = adapter->link_speed * 1000000;
|
||||
/* This can sleep */
|
||||
if_link_state_change(ifp, LINK_STATE_UP);
|
||||
} else if (!link_check && (adapter->link_active == 1)) {
|
||||
ifp->if_baudrate = adapter->link_speed = 0;
|
||||
|
|
@ -1962,6 +1960,7 @@ igb_update_link_status(struct adapter *adapter)
|
|||
if (bootverbose)
|
||||
device_printf(dev, "Link is Down\n");
|
||||
adapter->link_active = 0;
|
||||
/* This can sleep */
|
||||
if_link_state_change(ifp, LINK_STATE_DOWN);
|
||||
/* Turn off watchdogs */
|
||||
for (int i = 0; i < adapter->num_queues; i++, txr++)
|
||||
|
|
@ -2080,8 +2079,9 @@ igb_allocate_pci_resources(struct adapter *adapter)
|
|||
static int
|
||||
igb_allocate_legacy(struct adapter *adapter)
|
||||
{
|
||||
device_t dev = adapter->dev;
|
||||
int error, rid = 0;
|
||||
device_t dev = adapter->dev;
|
||||
struct igb_queue *que = adapter->queues;
|
||||
int error, rid = 0;
|
||||
|
||||
/* Turn off all interrupts */
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
|
||||
|
|
@ -2103,7 +2103,7 @@ igb_allocate_legacy(struct adapter *adapter)
|
|||
* Try allocating a fast interrupt and the associated deferred
|
||||
* processing contexts.
|
||||
*/
|
||||
TASK_INIT(&adapter->rxtx_task, 0, igb_handle_rxtx, adapter);
|
||||
TASK_INIT(&adapter->rxtx_task, 0, igb_handle_rxtx, que);
|
||||
/* Make tasklet for deferred link handling */
|
||||
TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter);
|
||||
adapter->tq = taskqueue_create_fast("igb_taskq", M_NOWAIT,
|
||||
|
|
@ -2433,22 +2433,19 @@ igb_setup_msix(struct adapter *adapter)
|
|||
/* Figure out a reasonable auto config value */
|
||||
queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus;
|
||||
|
||||
/* Can have max of 4 queues on 82575 */
|
||||
if (adapter->hw.mac.type == e1000_82575) {
|
||||
if (queues > 4)
|
||||
queues = 4;
|
||||
if (igb_num_queues > 4)
|
||||
igb_num_queues = 4;
|
||||
}
|
||||
/* Manual override */
|
||||
if (igb_num_queues != 0)
|
||||
queues = igb_num_queues;
|
||||
|
||||
if (igb_num_queues == 0)
|
||||
igb_num_queues = queues;
|
||||
/* Can have max of 4 queues on 82575 */
|
||||
if ((adapter->hw.mac.type == e1000_82575) && (queues > 4))
|
||||
queues = 4;
|
||||
|
||||
/*
|
||||
** One vector (RX/TX pair) per queue
|
||||
** plus an additional for Link interrupt
|
||||
*/
|
||||
want = igb_num_queues + 1;
|
||||
want = queues + 1;
|
||||
if (msgs >= want)
|
||||
msgs = want;
|
||||
else {
|
||||
|
|
@ -2461,7 +2458,7 @@ igb_setup_msix(struct adapter *adapter)
|
|||
if ((msgs) && pci_alloc_msix(dev, &msgs) == 0) {
|
||||
device_printf(adapter->dev,
|
||||
"Using MSIX interrupts with %d vectors\n", msgs);
|
||||
adapter->num_queues = igb_num_queues;
|
||||
adapter->num_queues = queues;
|
||||
return (msgs);
|
||||
}
|
||||
msi:
|
||||
|
|
@ -2922,9 +2919,7 @@ err_tx_desc:
|
|||
igb_dma_free(adapter, &txr->txdma);
|
||||
free(adapter->rx_rings, M_DEVBUF);
|
||||
rx_fail:
|
||||
#if __FreeBSD_version >= 800000
|
||||
buf_ring_free(txr->br, M_DEVBUF);
|
||||
#endif
|
||||
free(adapter->tx_rings, M_DEVBUF);
|
||||
tx_fail:
|
||||
free(adapter->queues, M_DEVBUF);
|
||||
|
|
@ -3502,111 +3497,88 @@ igb_txeof(struct tx_ring *txr)
|
|||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Setup descriptor buffer(s) from system mbuf buffer pools.
|
||||
* i - designates the ring index
|
||||
* clean - tells the function whether to update
|
||||
* the header, the packet buffer, or both.
|
||||
* Refresh mbuf buffers for RX descriptor rings
|
||||
* - now keeps its own state so discards due to resource
|
||||
* exhaustion are unnecessary, if an mbuf cannot be obtained
|
||||
* it just returns, keeping its placeholder, thus it can simply
|
||||
* be recalled to try again.
|
||||
*
|
||||
**********************************************************************/
|
||||
static int
|
||||
igb_get_buf(struct rx_ring *rxr, int i, u8 clean)
|
||||
static void
|
||||
igb_refresh_mbufs(struct rx_ring *rxr, int limit)
|
||||
{
|
||||
struct adapter *adapter = rxr->adapter;
|
||||
struct igb_rx_buf *rxbuf;
|
||||
struct mbuf *mh, *mp;
|
||||
bus_dma_segment_t hseg[1];
|
||||
bus_dma_segment_t pseg[1];
|
||||
bus_dmamap_t map;
|
||||
int nsegs, error;
|
||||
struct igb_rx_buf *rxbuf;
|
||||
struct mbuf *mh, *mp;
|
||||
int i, nsegs, error, cleaned;
|
||||
|
||||
|
||||
rxbuf = &rxr->rx_buffers[i];
|
||||
mh = mp = NULL;
|
||||
if ((clean & IGB_CLEAN_HEADER) != 0) {
|
||||
mh = m_gethdr(M_DONTWAIT, MT_DATA);
|
||||
if (mh == NULL) {
|
||||
adapter->mbuf_header_failed++;
|
||||
return (ENOBUFS);
|
||||
}
|
||||
mh->m_pkthdr.len = mh->m_len = MHLEN;
|
||||
/*
|
||||
* Because IGB_HDR_BUF size is less than MHLEN
|
||||
* and we configure controller to split headers
|
||||
* we can align mbuf on ETHER_ALIGN boundary.
|
||||
*/
|
||||
m_adj(mh, ETHER_ALIGN);
|
||||
error = bus_dmamap_load_mbuf_sg(rxr->rx_htag,
|
||||
rxr->rx_hspare_map, mh, hseg, &nsegs, 0);
|
||||
if (error != 0) {
|
||||
m_freem(mh);
|
||||
return (error);
|
||||
}
|
||||
mh->m_flags &= ~M_PKTHDR;
|
||||
}
|
||||
if ((clean & IGB_CLEAN_PAYLOAD) != 0) {
|
||||
mp = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR,
|
||||
adapter->rx_mbuf_sz);
|
||||
if (mp == NULL) {
|
||||
if (mh != NULL) {
|
||||
adapter->mbuf_packet_failed++;
|
||||
bus_dmamap_unload(rxr->rx_htag,
|
||||
rxbuf->head_map);
|
||||
mh->m_flags |= M_PKTHDR;
|
||||
m_freem(mh);
|
||||
i = rxr->next_to_refresh;
|
||||
cleaned = -1; /* Signify no completions */
|
||||
while (i != limit) {
|
||||
rxbuf = &rxr->rx_buffers[i];
|
||||
if (rxbuf->m_head == NULL) {
|
||||
mh = m_gethdr(M_DONTWAIT, MT_DATA);
|
||||
if (mh == NULL)
|
||||
goto update;
|
||||
mh->m_pkthdr.len = mh->m_len = MHLEN;
|
||||
mh->m_len = MHLEN;
|
||||
mh->m_flags |= M_PKTHDR;
|
||||
m_adj(mh, ETHER_ALIGN);
|
||||
/* Get the memory mapping */
|
||||
error = bus_dmamap_load_mbuf_sg(rxr->htag,
|
||||
rxbuf->hmap, mh, hseg, &nsegs, BUS_DMA_NOWAIT);
|
||||
if (error != 0) {
|
||||
printf("GET BUF: dmamap load"
|
||||
" failure - %d\n", error);
|
||||
m_free(mh);
|
||||
goto update;
|
||||
}
|
||||
return (ENOBUFS);
|
||||
rxbuf->m_head = mh;
|
||||
bus_dmamap_sync(rxr->htag, rxbuf->hmap,
|
||||
BUS_DMASYNC_PREREAD);
|
||||
rxr->rx_base[i].read.hdr_addr =
|
||||
htole64(hseg[0].ds_addr);
|
||||
}
|
||||
mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
|
||||
error = bus_dmamap_load_mbuf_sg(rxr->rx_ptag,
|
||||
rxr->rx_pspare_map, mp, pseg, &nsegs, 0);
|
||||
if (error != 0) {
|
||||
if (mh != NULL) {
|
||||
bus_dmamap_unload(rxr->rx_htag,
|
||||
rxbuf->head_map);
|
||||
mh->m_flags |= M_PKTHDR;
|
||||
m_freem(mh);
|
||||
|
||||
if (rxbuf->m_pack == NULL) {
|
||||
mp = m_getjcl(M_DONTWAIT, MT_DATA,
|
||||
M_PKTHDR, adapter->rx_mbuf_sz);
|
||||
if (mp == NULL)
|
||||
goto update;
|
||||
mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
|
||||
/* Get the memory mapping */
|
||||
error = bus_dmamap_load_mbuf_sg(rxr->ptag,
|
||||
rxbuf->pmap, mp, pseg, &nsegs, BUS_DMA_NOWAIT);
|
||||
if (error != 0) {
|
||||
printf("GET BUF: dmamap load"
|
||||
" failure - %d\n", error);
|
||||
m_free(mp);
|
||||
goto update;
|
||||
}
|
||||
m_freem(mp);
|
||||
return (error);
|
||||
rxbuf->m_pack = mp;
|
||||
bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
|
||||
BUS_DMASYNC_PREREAD);
|
||||
rxr->rx_base[i].read.pkt_addr =
|
||||
htole64(pseg[0].ds_addr);
|
||||
}
|
||||
mp->m_flags &= ~M_PKTHDR;
|
||||
}
|
||||
|
||||
/* Loading new DMA maps complete, unload maps for received buffers. */
|
||||
if ((clean & IGB_CLEAN_HEADER) != 0 && rxbuf->m_head != NULL) {
|
||||
bus_dmamap_sync(rxr->rx_htag, rxbuf->head_map,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
bus_dmamap_unload(rxr->rx_htag, rxbuf->head_map);
|
||||
cleaned = i;
|
||||
/* Calculate next index */
|
||||
if (++i == adapter->num_rx_desc)
|
||||
i = 0;
|
||||
/* This is the work marker for refresh */
|
||||
rxr->next_to_refresh = i;
|
||||
}
|
||||
if ((clean & IGB_CLEAN_PAYLOAD) != 0 && rxbuf->m_pack != NULL) {
|
||||
bus_dmamap_sync(rxr->rx_ptag, rxbuf->pack_map,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
bus_dmamap_unload(rxr->rx_ptag, rxbuf->pack_map);
|
||||
}
|
||||
|
||||
/* Reflect loaded dmamaps. */
|
||||
if ((clean & IGB_CLEAN_HEADER) != 0) {
|
||||
map = rxbuf->head_map;
|
||||
rxbuf->head_map = rxr->rx_hspare_map;
|
||||
rxr->rx_hspare_map = map;
|
||||
rxbuf->m_head = mh;
|
||||
bus_dmamap_sync(rxr->rx_htag, rxbuf->head_map,
|
||||
BUS_DMASYNC_PREREAD);
|
||||
rxr->rx_base[i].read.hdr_addr = htole64(hseg[0].ds_addr);
|
||||
}
|
||||
if ((clean & IGB_CLEAN_PAYLOAD) != 0) {
|
||||
map = rxbuf->pack_map;
|
||||
rxbuf->pack_map = rxr->rx_pspare_map;
|
||||
rxr->rx_pspare_map = map;
|
||||
rxbuf->m_pack = mp;
|
||||
bus_dmamap_sync(rxr->rx_ptag, rxbuf->pack_map,
|
||||
BUS_DMASYNC_PREREAD);
|
||||
rxr->rx_base[i].read.pkt_addr = htole64(pseg[0].ds_addr);
|
||||
}
|
||||
|
||||
return (0);
|
||||
update:
|
||||
if (cleaned != -1) /* If we refreshed some, bump tail */
|
||||
E1000_WRITE_REG(&adapter->hw,
|
||||
E1000_RDT(rxr->me), cleaned);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Allocate memory for rx_buffer structures. Since we use one
|
||||
|
|
@ -3643,7 +3615,7 @@ igb_allocate_receive_buffers(struct rx_ring *rxr)
|
|||
0, /* flags */
|
||||
NULL, /* lockfunc */
|
||||
NULL, /* lockfuncarg */
|
||||
&rxr->rx_htag))) {
|
||||
&rxr->htag))) {
|
||||
device_printf(dev, "Unable to create RX DMA tag\n");
|
||||
goto fail;
|
||||
}
|
||||
|
|
@ -3659,40 +3631,22 @@ igb_allocate_receive_buffers(struct rx_ring *rxr)
|
|||
0, /* flags */
|
||||
NULL, /* lockfunc */
|
||||
NULL, /* lockfuncarg */
|
||||
&rxr->rx_ptag))) {
|
||||
&rxr->ptag))) {
|
||||
device_printf(dev, "Unable to create RX payload DMA tag\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Create the spare maps (used by getbuf) */
|
||||
error = bus_dmamap_create(rxr->rx_htag, BUS_DMA_NOWAIT,
|
||||
&rxr->rx_hspare_map);
|
||||
if (error) {
|
||||
device_printf(dev,
|
||||
"%s: bus_dmamap_create header spare failed: %d\n",
|
||||
__func__, error);
|
||||
goto fail;
|
||||
}
|
||||
error = bus_dmamap_create(rxr->rx_ptag, BUS_DMA_NOWAIT,
|
||||
&rxr->rx_pspare_map);
|
||||
if (error) {
|
||||
device_printf(dev,
|
||||
"%s: bus_dmamap_create packet spare failed: %d\n",
|
||||
__func__, error);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < adapter->num_rx_desc; i++) {
|
||||
rxbuf = &rxr->rx_buffers[i];
|
||||
error = bus_dmamap_create(rxr->rx_htag,
|
||||
BUS_DMA_NOWAIT, &rxbuf->head_map);
|
||||
error = bus_dmamap_create(rxr->htag,
|
||||
BUS_DMA_NOWAIT, &rxbuf->hmap);
|
||||
if (error) {
|
||||
device_printf(dev,
|
||||
"Unable to create RX head DMA maps\n");
|
||||
goto fail;
|
||||
}
|
||||
error = bus_dmamap_create(rxr->rx_ptag,
|
||||
BUS_DMA_NOWAIT, &rxbuf->pack_map);
|
||||
error = bus_dmamap_create(rxr->ptag,
|
||||
BUS_DMA_NOWAIT, &rxbuf->pmap);
|
||||
if (error) {
|
||||
device_printf(dev,
|
||||
"Unable to create RX packet DMA maps\n");
|
||||
|
|
@ -3720,16 +3674,16 @@ igb_free_receive_ring(struct rx_ring *rxr)
|
|||
for (i = 0; i < adapter->num_rx_desc; i++) {
|
||||
rxbuf = &rxr->rx_buffers[i];
|
||||
if (rxbuf->m_head != NULL) {
|
||||
bus_dmamap_sync(rxr->rx_htag, rxbuf->head_map,
|
||||
bus_dmamap_sync(rxr->htag, rxbuf->hmap,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
bus_dmamap_unload(rxr->rx_htag, rxbuf->head_map);
|
||||
bus_dmamap_unload(rxr->htag, rxbuf->hmap);
|
||||
rxbuf->m_head->m_flags |= M_PKTHDR;
|
||||
m_freem(rxbuf->m_head);
|
||||
}
|
||||
if (rxbuf->m_pack != NULL) {
|
||||
bus_dmamap_sync(rxr->rx_ptag, rxbuf->pack_map,
|
||||
bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
bus_dmamap_unload(rxr->rx_ptag, rxbuf->pack_map);
|
||||
bus_dmamap_unload(rxr->ptag, rxbuf->pmap);
|
||||
rxbuf->m_pack->m_flags |= M_PKTHDR;
|
||||
m_freem(rxbuf->m_pack);
|
||||
}
|
||||
|
|
@ -3750,8 +3704,10 @@ igb_setup_receive_ring(struct rx_ring *rxr)
|
|||
struct adapter *adapter;
|
||||
struct ifnet *ifp;
|
||||
device_t dev;
|
||||
struct igb_rx_buf *rxbuf;
|
||||
bus_dma_segment_t pseg[1], hseg[1];
|
||||
struct lro_ctrl *lro = &rxr->lro;
|
||||
int j, rsize, error = 0;
|
||||
int rsize, nsegs, error = 0;
|
||||
|
||||
adapter = rxr->adapter;
|
||||
dev = adapter->dev;
|
||||
|
|
@ -3768,15 +3724,50 @@ igb_setup_receive_ring(struct rx_ring *rxr)
|
|||
*/
|
||||
igb_free_receive_ring(rxr);
|
||||
|
||||
/* Now replenish the ring mbufs */
|
||||
for (j = 0; j < adapter->num_rx_desc; j++) {
|
||||
if ((error = igb_get_buf(rxr, j, IGB_CLEAN_BOTH)) != 0)
|
||||
goto fail;
|
||||
}
|
||||
/* Now replenish the ring mbufs */
|
||||
for (int j = 0; j != adapter->num_rx_desc; ++j) {
|
||||
struct mbuf *mh, *mp;
|
||||
|
||||
/* Setup our descriptor indices */
|
||||
rxr->next_to_check = 0;
|
||||
rxr->last_cleaned = 0;
|
||||
rxbuf = &rxr->rx_buffers[j];
|
||||
|
||||
/* First the header */
|
||||
rxbuf->m_head = m_gethdr(M_DONTWAIT, MT_DATA);
|
||||
if (rxbuf->m_head == NULL)
|
||||
goto fail;
|
||||
m_adj(rxbuf->m_head, ETHER_ALIGN);
|
||||
mh = rxbuf->m_head;
|
||||
mh->m_len = mh->m_pkthdr.len = MHLEN;
|
||||
mh->m_flags |= M_PKTHDR;
|
||||
/* Get the memory mapping */
|
||||
error = bus_dmamap_load_mbuf_sg(rxr->htag,
|
||||
rxbuf->hmap, rxbuf->m_head, hseg,
|
||||
&nsegs, BUS_DMA_NOWAIT);
|
||||
if (error != 0) /* Nothing elegant to do here */
|
||||
goto fail;
|
||||
bus_dmamap_sync(rxr->htag,
|
||||
rxbuf->hmap, BUS_DMASYNC_PREREAD);
|
||||
/* Update descriptor */
|
||||
rxr->rx_base[j].read.hdr_addr = htole64(hseg[0].ds_addr);
|
||||
|
||||
/* Now the payload cluster */
|
||||
rxbuf->m_pack = m_getjcl(M_DONTWAIT, MT_DATA,
|
||||
M_PKTHDR, adapter->rx_mbuf_sz);
|
||||
if (rxbuf->m_pack == NULL)
|
||||
goto fail;
|
||||
mp = rxbuf->m_pack;
|
||||
mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
|
||||
/* Get the memory mapping */
|
||||
error = bus_dmamap_load_mbuf_sg(rxr->ptag,
|
||||
rxbuf->pmap, mp, pseg,
|
||||
&nsegs, BUS_DMA_NOWAIT);
|
||||
if (error != 0)
|
||||
goto fail;
|
||||
bus_dmamap_sync(rxr->ptag,
|
||||
rxbuf->pmap, BUS_DMASYNC_PREREAD);
|
||||
/* Update descriptor */
|
||||
rxr->rx_base[j].read.pkt_addr = htole64(pseg[0].ds_addr);
|
||||
}
|
||||
rxr->next_to_refresh = 0;
|
||||
rxr->lro_enabled = FALSE;
|
||||
|
||||
if (igb_header_split)
|
||||
|
|
@ -4049,47 +4040,33 @@ igb_free_receive_buffers(struct rx_ring *rxr)
|
|||
|
||||
INIT_DEBUGOUT("free_receive_structures: begin");
|
||||
|
||||
if (rxr->rx_hspare_map != NULL) {
|
||||
bus_dmamap_destroy(rxr->rx_htag, rxr->rx_hspare_map);
|
||||
rxr->rx_hspare_map = NULL;
|
||||
}
|
||||
|
||||
if (rxr->rx_hspare_map != NULL) {
|
||||
bus_dmamap_destroy(rxr->rx_ptag, rxr->rx_pspare_map);
|
||||
rxr->rx_pspare_map = NULL;
|
||||
}
|
||||
|
||||
/* Cleanup any existing buffers */
|
||||
if (rxr->rx_buffers != NULL) {
|
||||
for (i = 0; i < adapter->num_rx_desc; i++) {
|
||||
rxbuf = &rxr->rx_buffers[i];
|
||||
if (rxbuf->m_head != NULL) {
|
||||
bus_dmamap_sync(rxr->rx_htag, rxbuf->head_map,
|
||||
bus_dmamap_sync(rxr->htag, rxbuf->hmap,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
bus_dmamap_unload(rxr->rx_htag,
|
||||
rxbuf->head_map);
|
||||
bus_dmamap_unload(rxr->htag, rxbuf->hmap);
|
||||
rxbuf->m_head->m_flags |= M_PKTHDR;
|
||||
m_freem(rxbuf->m_head);
|
||||
}
|
||||
if (rxbuf->m_pack != NULL) {
|
||||
bus_dmamap_sync(rxr->rx_ptag, rxbuf->pack_map,
|
||||
bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
bus_dmamap_unload(rxr->rx_ptag,
|
||||
rxbuf->pack_map);
|
||||
bus_dmamap_unload(rxr->ptag, rxbuf->pmap);
|
||||
rxbuf->m_pack->m_flags |= M_PKTHDR;
|
||||
m_freem(rxbuf->m_pack);
|
||||
}
|
||||
rxbuf->m_head = NULL;
|
||||
rxbuf->m_pack = NULL;
|
||||
if (rxbuf->head_map != NULL) {
|
||||
bus_dmamap_destroy(rxr->rx_htag,
|
||||
rxbuf->head_map);
|
||||
rxbuf->head_map = NULL;
|
||||
if (rxbuf->hmap != NULL) {
|
||||
bus_dmamap_destroy(rxr->htag, rxbuf->hmap);
|
||||
rxbuf->hmap = NULL;
|
||||
}
|
||||
if (rxbuf->pack_map != NULL) {
|
||||
bus_dmamap_destroy(rxr->rx_ptag,
|
||||
rxbuf->pack_map);
|
||||
rxbuf->pack_map = NULL;
|
||||
if (rxbuf->pmap != NULL) {
|
||||
bus_dmamap_destroy(rxr->ptag, rxbuf->pmap);
|
||||
rxbuf->pmap = NULL;
|
||||
}
|
||||
}
|
||||
if (rxr->rx_buffers != NULL) {
|
||||
|
|
@ -4098,26 +4075,43 @@ igb_free_receive_buffers(struct rx_ring *rxr)
|
|||
}
|
||||
}
|
||||
|
||||
if (rxr->rx_htag != NULL) {
|
||||
bus_dma_tag_destroy(rxr->rx_htag);
|
||||
rxr->rx_htag = NULL;
|
||||
if (rxr->htag != NULL) {
|
||||
bus_dma_tag_destroy(rxr->htag);
|
||||
rxr->htag = NULL;
|
||||
}
|
||||
if (rxr->rx_ptag != NULL) {
|
||||
bus_dma_tag_destroy(rxr->rx_ptag);
|
||||
rxr->rx_ptag = NULL;
|
||||
if (rxr->ptag != NULL) {
|
||||
bus_dma_tag_destroy(rxr->ptag);
|
||||
rxr->ptag = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void
|
||||
igb_rx_discard(struct rx_ring *rxr, union e1000_adv_rx_desc *cur, int i)
|
||||
igb_rx_discard(struct rx_ring *rxr, int i)
|
||||
{
|
||||
struct adapter *adapter = rxr->adapter;
|
||||
struct igb_rx_buf *rbuf;
|
||||
struct mbuf *mh, *mp;
|
||||
|
||||
rbuf = &rxr->rx_buffers[i];
|
||||
if (rxr->fmp != NULL) {
|
||||
rxr->fmp->m_flags |= M_PKTHDR;
|
||||
m_freem(rxr->fmp);
|
||||
rxr->fmp = NULL;
|
||||
rxr->lmp = NULL;
|
||||
}
|
||||
|
||||
mh = rbuf->m_head;
|
||||
mp = rbuf->m_pack;
|
||||
|
||||
/* Reuse loaded DMA map and just update mbuf chain */
|
||||
mh->m_len = MHLEN;
|
||||
mh->m_flags |= M_PKTHDR;
|
||||
mh->m_next = NULL;
|
||||
|
||||
mp->m_len = mp->m_pkthdr.len = adapter->rx_mbuf_sz;
|
||||
mp->m_data = mp->m_ext.ext_buf;
|
||||
mp->m_next = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
|
|
@ -4161,28 +4155,29 @@ igb_rx_input(struct rx_ring *rxr, struct ifnet *ifp, struct mbuf *m, u32 ptype)
|
|||
* Return TRUE if more to clean, FALSE otherwise
|
||||
*********************************************************************/
|
||||
static bool
|
||||
igb_rxeof(struct rx_ring *rxr, int count)
|
||||
igb_rxeof(struct igb_queue *que, int count)
|
||||
{
|
||||
struct adapter *adapter = rxr->adapter;
|
||||
struct adapter *adapter = que->adapter;
|
||||
struct rx_ring *rxr = que->rxr;
|
||||
struct ifnet *ifp = adapter->ifp;
|
||||
struct lro_ctrl *lro = &rxr->lro;
|
||||
struct lro_entry *queued;
|
||||
int i, prog = 0;
|
||||
int i, processed = 0;
|
||||
u32 ptype, staterr = 0;
|
||||
union e1000_adv_rx_desc *cur;
|
||||
|
||||
IGB_RX_LOCK(rxr);
|
||||
/* Sync the ring. */
|
||||
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
|
||||
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
/* Main clean loop */
|
||||
for (i = rxr->next_to_check; count > 0; prog++) {
|
||||
struct mbuf *sendmp, *mh, *mp;
|
||||
u16 hlen, plen, hdr, vtag;
|
||||
bool eop = FALSE;
|
||||
u8 dopayload;
|
||||
for (i = rxr->next_to_check; count != 0;) {
|
||||
struct mbuf *sendmp, *mh, *mp;
|
||||
struct igb_rx_buf *rxbuf;
|
||||
u16 hlen, plen, hdr, vtag;
|
||||
bool eop = FALSE;
|
||||
|
||||
/* Sync the ring. */
|
||||
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
|
||||
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||
cur = &rxr->rx_base[i];
|
||||
staterr = le32toh(cur->wb.upper.status_error);
|
||||
if ((staterr & E1000_RXD_STAT_DD) == 0)
|
||||
|
|
@ -4192,8 +4187,10 @@ igb_rxeof(struct rx_ring *rxr, int count)
|
|||
count--;
|
||||
sendmp = mh = mp = NULL;
|
||||
cur->wb.upper.status_error = 0;
|
||||
rxbuf = &rxr->rx_buffers[i];
|
||||
plen = le16toh(cur->wb.upper.length);
|
||||
ptype = le32toh(cur->wb.lower.lo_dword.data) & IGB_PKTTYPE_MASK;
|
||||
vtag = le16toh(cur->wb.upper.vlan);
|
||||
hdr = le16toh(cur->wb.lower.lo_dword.hs_rss.hdr_info);
|
||||
eop = ((staterr & E1000_RXD_STAT_EOP) == E1000_RXD_STAT_EOP);
|
||||
|
||||
|
|
@ -4206,7 +4203,7 @@ igb_rxeof(struct rx_ring *rxr, int count)
|
|||
rxr->discard = TRUE;
|
||||
else
|
||||
rxr->discard = FALSE;
|
||||
igb_rx_discard(rxr, cur, i);
|
||||
igb_rx_discard(rxr, i);
|
||||
goto next_desc;
|
||||
}
|
||||
|
||||
|
|
@ -4229,7 +4226,8 @@ igb_rxeof(struct rx_ring *rxr, int count)
|
|||
/* Handle the header mbuf */
|
||||
mh = rxr->rx_buffers[i].m_head;
|
||||
mh->m_len = hlen;
|
||||
dopayload = IGB_CLEAN_HEADER;
|
||||
/* clear buf info for refresh */
|
||||
rxbuf->m_head = NULL;
|
||||
/*
|
||||
** Get the payload length, this
|
||||
** could be zero if its a small
|
||||
|
|
@ -4239,7 +4237,8 @@ igb_rxeof(struct rx_ring *rxr, int count)
|
|||
mp = rxr->rx_buffers[i].m_pack;
|
||||
mp->m_len = plen;
|
||||
mh->m_next = mp;
|
||||
dopayload = IGB_CLEAN_BOTH;
|
||||
/* clear buf info for refresh */
|
||||
rxbuf->m_pack = NULL;
|
||||
rxr->rx_split_packets++;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -4250,26 +4249,11 @@ igb_rxeof(struct rx_ring *rxr, int count)
|
|||
*/
|
||||
mh = rxr->rx_buffers[i].m_pack;
|
||||
mh->m_len = plen;
|
||||
dopayload = IGB_CLEAN_PAYLOAD;
|
||||
/* clear buf info for refresh */
|
||||
rxbuf->m_pack = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** get_buf will overwrite the writeback
|
||||
** descriptor so save the VLAN tag now.
|
||||
*/
|
||||
vtag = le16toh(cur->wb.upper.vlan);
|
||||
if (igb_get_buf(rxr, i, dopayload) != 0) {
|
||||
ifp->if_iqdrops++;
|
||||
/*
|
||||
* We've dropped a frame due to lack of resources
|
||||
* so we should drop entire multi-segmented
|
||||
* frames until we encounter EOP.
|
||||
*/
|
||||
if ((staterr & E1000_RXD_STAT_EOP) != 0)
|
||||
rxr->discard = TRUE;
|
||||
igb_rx_discard(rxr, cur, i);
|
||||
goto next_desc;
|
||||
}
|
||||
++processed; /* So we know when to refresh */
|
||||
|
||||
/* Initial frame - setup */
|
||||
if (rxr->fmp == NULL) {
|
||||
|
|
@ -4300,14 +4284,14 @@ igb_rxeof(struct rx_ring *rxr, int count)
|
|||
|
||||
if ((ifp->if_capenable & IFCAP_RXCSUM) != 0)
|
||||
igb_rx_checksum(staterr, rxr->fmp, ptype);
|
||||
/* XXX igb(4) always strips VLAN. */
|
||||
|
||||
if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0 &&
|
||||
(staterr & E1000_RXD_STAT_VP) != 0) {
|
||||
rxr->fmp->m_pkthdr.ether_vtag = vtag;
|
||||
rxr->fmp->m_flags |= M_VLANTAG;
|
||||
}
|
||||
#if __FreeBSD_version >= 800000
|
||||
rxr->fmp->m_pkthdr.flowid = curcpu;
|
||||
rxr->fmp->m_pkthdr.flowid = que->msix;
|
||||
rxr->fmp->m_flags |= M_FLOWID;
|
||||
#endif
|
||||
sendmp = rxr->fmp;
|
||||
|
|
@ -4321,31 +4305,30 @@ next_desc:
|
|||
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
|
||||
rxr->last_cleaned = i; /* For updating tail */
|
||||
|
||||
/* Advance our pointers to the next descriptor. */
|
||||
if (++i == adapter->num_rx_desc)
|
||||
i = 0;
|
||||
|
||||
/*
|
||||
** Note that we hold the RX lock thru
|
||||
** the following call so this ring's
|
||||
** next_to_check is not gonna change.
|
||||
** Send to the stack or LRO
|
||||
*/
|
||||
if (sendmp != NULL)
|
||||
igb_rx_input(rxr, ifp, sendmp, ptype);
|
||||
|
||||
/* Every 8 descriptors we go to refresh mbufs */
|
||||
if (processed == 8) {
|
||||
igb_refresh_mbufs(rxr, i);
|
||||
processed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (prog == 0) {
|
||||
IGB_RX_UNLOCK(rxr);
|
||||
return (FALSE);
|
||||
/* Catch any remainders */
|
||||
if (processed != 0) {
|
||||
igb_refresh_mbufs(rxr, i);
|
||||
processed = 0;
|
||||
}
|
||||
|
||||
rxr->next_to_check = i;
|
||||
|
||||
/* Advance the E1000's Receive Queue "Tail Pointer". */
|
||||
E1000_WRITE_REG(&adapter->hw, E1000_RDT(rxr->me), rxr->last_cleaned);
|
||||
|
||||
/*
|
||||
* Flush any outstanding LRO work
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@
|
|||
* desscriptors should meet the following condition.
|
||||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define IGB_MIN_TXD 80
|
||||
#define IGB_DEFAULT_TXD 256
|
||||
#define IGB_MIN_TXD 256
|
||||
#define IGB_DEFAULT_TXD 1024
|
||||
#define IGB_MAX_TXD 4096
|
||||
|
||||
/*
|
||||
|
|
@ -62,8 +62,8 @@
|
|||
* desscriptors should meet the following condition.
|
||||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define IGB_MIN_RXD 80
|
||||
#define IGB_DEFAULT_RXD 256
|
||||
#define IGB_MIN_RXD 256
|
||||
#define IGB_DEFAULT_RXD 1024
|
||||
#define IGB_MAX_RXD 4096
|
||||
|
||||
/*
|
||||
|
|
@ -333,13 +333,11 @@ struct rx_ring {
|
|||
bool discard;
|
||||
struct mtx rx_mtx;
|
||||
char mtx_name[16];
|
||||
u32 last_cleaned;
|
||||
u32 next_to_refresh;
|
||||
u32 next_to_check;
|
||||
struct igb_rx_buf *rx_buffers;
|
||||
bus_dma_tag_t rx_htag; /* dma tag for rx head */
|
||||
bus_dmamap_t rx_hspare_map;
|
||||
bus_dma_tag_t rx_ptag; /* dma tag for rx packet */
|
||||
bus_dmamap_t rx_pspare_map;
|
||||
bus_dma_tag_t htag; /* dma tag for rx head */
|
||||
bus_dma_tag_t ptag; /* dma tag for rx packet */
|
||||
/*
|
||||
* First/last mbuf pointers, for
|
||||
* collecting multisegment RX packets.
|
||||
|
|
@ -468,8 +466,8 @@ struct igb_tx_buffer {
|
|||
struct igb_rx_buf {
|
||||
struct mbuf *m_head;
|
||||
struct mbuf *m_pack;
|
||||
bus_dmamap_t head_map; /* bus_dma map for packet */
|
||||
bus_dmamap_t pack_map; /* bus_dma map for packet */
|
||||
bus_dmamap_t hmap; /* bus_dma map for header */
|
||||
bus_dmamap_t pmap; /* bus_dma map for packet */
|
||||
};
|
||||
|
||||
#define IGB_CORE_LOCK_INIT(_sc, _name) \
|
||||
|
|
|
|||
4680
sys/dev/e1000/if_lem.c
Normal file
4680
sys/dev/e1000/if_lem.c
Normal file
File diff suppressed because it is too large
Load diff
480
sys/dev/e1000/if_lem.h
Normal file
480
sys/dev/e1000/if_lem.h
Normal file
|
|
@ -0,0 +1,480 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2010, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
******************************************************************************/
|
||||
/*$FreeBSD$*/
|
||||
|
||||
|
||||
#ifndef _LEM_H_DEFINED_
|
||||
#define _LEM_H_DEFINED_
|
||||
|
||||
|
||||
/* Tunables */
|
||||
|
||||
/*
|
||||
* EM_TXD: Maximum number of Transmit Descriptors
|
||||
* Valid Range: 80-256 for 82542 and 82543-based adapters
|
||||
* 80-4096 for others
|
||||
* Default Value: 256
|
||||
* This value is the number of transmit descriptors allocated by the driver.
|
||||
* Increasing this value allows the driver to queue more transmits. Each
|
||||
* descriptor is 16 bytes.
|
||||
* Since TDLEN should be multiple of 128bytes, the number of transmit
|
||||
* desscriptors should meet the following condition.
|
||||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define EM_MIN_TXD 80
|
||||
#define EM_MAX_TXD_82543 256
|
||||
#define EM_MAX_TXD 4096
|
||||
#define EM_DEFAULT_TXD EM_MAX_TXD_82543
|
||||
|
||||
/*
|
||||
* EM_RXD - Maximum number of receive Descriptors
|
||||
* Valid Range: 80-256 for 82542 and 82543-based adapters
|
||||
* 80-4096 for others
|
||||
* Default Value: 256
|
||||
* This value is the number of receive descriptors allocated by the driver.
|
||||
* Increasing this value allows the driver to buffer more incoming packets.
|
||||
* Each descriptor is 16 bytes. A receive buffer is also allocated for each
|
||||
* descriptor. The maximum MTU size is 16110.
|
||||
* Since TDLEN should be multiple of 128bytes, the number of transmit
|
||||
* desscriptors should meet the following condition.
|
||||
* (num_tx_desc * sizeof(struct e1000_tx_desc)) % 128 == 0
|
||||
*/
|
||||
#define EM_MIN_RXD 80
|
||||
#define EM_MAX_RXD_82543 256
|
||||
#define EM_MAX_RXD 4096
|
||||
#define EM_DEFAULT_RXD EM_MAX_RXD_82543
|
||||
|
||||
/*
|
||||
* EM_TIDV - Transmit Interrupt Delay Value
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 64
|
||||
* This value delays the generation of transmit interrupts in units of
|
||||
* 1.024 microseconds. Transmit interrupt reduction can improve CPU
|
||||
* efficiency if properly tuned for specific network traffic. If the
|
||||
* system is reporting dropped transmits, this value may be set too high
|
||||
* causing the driver to run out of available transmit descriptors.
|
||||
*/
|
||||
#define EM_TIDV 64
|
||||
|
||||
/*
|
||||
* EM_TADV - Transmit Absolute Interrupt Delay Value
|
||||
* (Not valid for 82542/82543/82544)
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 64
|
||||
* This value, in units of 1.024 microseconds, limits the delay in which a
|
||||
* transmit interrupt is generated. Useful only if EM_TIDV is non-zero,
|
||||
* this value ensures that an interrupt is generated after the initial
|
||||
* packet is sent on the wire within the set amount of time. Proper tuning,
|
||||
* along with EM_TIDV, may improve traffic throughput in specific
|
||||
* network conditions.
|
||||
*/
|
||||
#define EM_TADV 64
|
||||
|
||||
/*
|
||||
* EM_RDTR - Receive Interrupt Delay Timer (Packet Timer)
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 0
|
||||
* This value delays the generation of receive interrupts in units of 1.024
|
||||
* microseconds. Receive interrupt reduction can improve CPU efficiency if
|
||||
* properly tuned for specific network traffic. Increasing this value adds
|
||||
* extra latency to frame reception and can end up decreasing the throughput
|
||||
* of TCP traffic. If the system is reporting dropped receives, this value
|
||||
* may be set too high, causing the driver to run out of available receive
|
||||
* descriptors.
|
||||
*
|
||||
* CAUTION: When setting EM_RDTR to a value other than 0, adapters
|
||||
* may hang (stop transmitting) under certain network conditions.
|
||||
* If this occurs a WATCHDOG message is logged in the system
|
||||
* event log. In addition, the controller is automatically reset,
|
||||
* restoring the network connection. To eliminate the potential
|
||||
* for the hang ensure that EM_RDTR is set to 0.
|
||||
*/
|
||||
#define EM_RDTR 0
|
||||
|
||||
/*
|
||||
* Receive Interrupt Absolute Delay Timer (Not valid for 82542/82543/82544)
|
||||
* Valid Range: 0-65535 (0=off)
|
||||
* Default Value: 64
|
||||
* This value, in units of 1.024 microseconds, limits the delay in which a
|
||||
* receive interrupt is generated. Useful only if EM_RDTR is non-zero,
|
||||
* this value ensures that an interrupt is generated after the initial
|
||||
* packet is received within the set amount of time. Proper tuning,
|
||||
* along with EM_RDTR, may improve traffic throughput in specific network
|
||||
* conditions.
|
||||
*/
|
||||
#define EM_RADV 64
|
||||
|
||||
/*
|
||||
* This parameter controls the max duration of transmit watchdog.
|
||||
*/
|
||||
#define EM_WATCHDOG (10 * hz)
|
||||
|
||||
/*
|
||||
* This parameter controls when the driver calls the routine to reclaim
|
||||
* transmit descriptors.
|
||||
*/
|
||||
#define EM_TX_CLEANUP_THRESHOLD (adapter->num_tx_desc / 8)
|
||||
#define EM_TX_OP_THRESHOLD (adapter->num_tx_desc / 32)
|
||||
|
||||
/*
|
||||
* This parameter controls whether or not autonegotation is enabled.
|
||||
* 0 - Disable autonegotiation
|
||||
* 1 - Enable autonegotiation
|
||||
*/
|
||||
#define DO_AUTO_NEG 1
|
||||
|
||||
/*
|
||||
* This parameter control whether or not the driver will wait for
|
||||
* autonegotiation to complete.
|
||||
* 1 - Wait for autonegotiation to complete
|
||||
* 0 - Don't wait for autonegotiation to complete
|
||||
*/
|
||||
#define WAIT_FOR_AUTO_NEG_DEFAULT 0
|
||||
|
||||
/* Tunables -- End */
|
||||
|
||||
#define AUTONEG_ADV_DEFAULT (ADVERTISE_10_HALF | ADVERTISE_10_FULL | \
|
||||
ADVERTISE_100_HALF | ADVERTISE_100_FULL | \
|
||||
ADVERTISE_1000_FULL)
|
||||
|
||||
#define AUTO_ALL_MODES 0
|
||||
|
||||
/* PHY master/slave setting */
|
||||
#define EM_MASTER_SLAVE e1000_ms_hw_default
|
||||
|
||||
/*
|
||||
* Micellaneous constants
|
||||
*/
|
||||
#define EM_VENDOR_ID 0x8086
|
||||
#define EM_FLASH 0x0014
|
||||
|
||||
#define EM_JUMBO_PBA 0x00000028
|
||||
#define EM_DEFAULT_PBA 0x00000030
|
||||
#define EM_SMARTSPEED_DOWNSHIFT 3
|
||||
#define EM_SMARTSPEED_MAX 15
|
||||
#define EM_MAX_LOOP 10
|
||||
|
||||
#define MAX_NUM_MULTICAST_ADDRESSES 128
|
||||
#define PCI_ANY_ID (~0U)
|
||||
#define ETHER_ALIGN 2
|
||||
#define EM_FC_PAUSE_TIME 0x0680
|
||||
#define EM_EEPROM_APME 0x400;
|
||||
#define EM_82544_APME 0x0004;
|
||||
|
||||
/* Code compatilbility between 6 and 7 */
|
||||
#ifndef ETHER_BPF_MTAP
|
||||
#define ETHER_BPF_MTAP BPF_MTAP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
|
||||
* multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
|
||||
* also optimize cache line size effect. H/W supports up to cache line size 128.
|
||||
*/
|
||||
#define EM_DBA_ALIGN 128
|
||||
|
||||
#define SPEED_MODE_BIT (1<<21) /* On PCI-E MACs only */
|
||||
|
||||
/* PCI Config defines */
|
||||
#define EM_BAR_TYPE(v) ((v) & EM_BAR_TYPE_MASK)
|
||||
#define EM_BAR_TYPE_MASK 0x00000001
|
||||
#define EM_BAR_TYPE_MMEM 0x00000000
|
||||
#define EM_BAR_TYPE_IO 0x00000001
|
||||
#define EM_BAR_TYPE_FLASH 0x0014
|
||||
#define EM_BAR_MEM_TYPE(v) ((v) & EM_BAR_MEM_TYPE_MASK)
|
||||
#define EM_BAR_MEM_TYPE_MASK 0x00000006
|
||||
#define EM_BAR_MEM_TYPE_32BIT 0x00000000
|
||||
#define EM_BAR_MEM_TYPE_64BIT 0x00000004
|
||||
#define EM_MSIX_BAR 3 /* On 82575 */
|
||||
|
||||
/* Defines for printing debug information */
|
||||
#define DEBUG_INIT 0
|
||||
#define DEBUG_IOCTL 0
|
||||
#define DEBUG_HW 0
|
||||
|
||||
#define INIT_DEBUGOUT(S) if (DEBUG_INIT) printf(S "\n")
|
||||
#define INIT_DEBUGOUT1(S, A) if (DEBUG_INIT) printf(S "\n", A)
|
||||
#define INIT_DEBUGOUT2(S, A, B) if (DEBUG_INIT) printf(S "\n", A, B)
|
||||
#define IOCTL_DEBUGOUT(S) if (DEBUG_IOCTL) printf(S "\n")
|
||||
#define IOCTL_DEBUGOUT1(S, A) if (DEBUG_IOCTL) printf(S "\n", A)
|
||||
#define IOCTL_DEBUGOUT2(S, A, B) if (DEBUG_IOCTL) printf(S "\n", A, B)
|
||||
#define HW_DEBUGOUT(S) if (DEBUG_HW) printf(S "\n")
|
||||
#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
|
||||
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
|
||||
|
||||
#define EM_MAX_SCATTER 64
|
||||
#define EM_VFTA_SIZE 128
|
||||
#define EM_TSO_SIZE (65535 + sizeof(struct ether_vlan_header))
|
||||
#define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */
|
||||
#define EM_MSIX_MASK 0x01F00000 /* For 82574 use */
|
||||
#define ETH_ZLEN 60
|
||||
#define ETH_ADDR_LEN 6
|
||||
#define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */
|
||||
|
||||
/*
|
||||
* 82574 has a nonstandard address for EIAC
|
||||
* and since its only used in MSIX, and in
|
||||
* the em driver only 82574 uses MSIX we can
|
||||
* solve it just using this define.
|
||||
*/
|
||||
#define EM_EIAC 0x000DC
|
||||
|
||||
/* Used in for 82547 10Mb Half workaround */
|
||||
#define EM_PBA_BYTES_SHIFT 0xA
|
||||
#define EM_TX_HEAD_ADDR_SHIFT 7
|
||||
#define EM_PBA_TX_MASK 0xFFFF0000
|
||||
#define EM_FIFO_HDR 0x10
|
||||
#define EM_82547_PKT_THRESH 0x3e0
|
||||
|
||||
/* Precision Time Sync (IEEE 1588) defines */
|
||||
#define ETHERTYPE_IEEE1588 0x88F7
|
||||
#define PICOSECS_PER_TICK 20833
|
||||
#define TSYNC_PORT 319 /* UDP port for the protocol */
|
||||
|
||||
/*
|
||||
* Bus dma allocation structure used by
|
||||
* e1000_dma_malloc and e1000_dma_free.
|
||||
*/
|
||||
struct em_dma_alloc {
|
||||
bus_addr_t dma_paddr;
|
||||
caddr_t dma_vaddr;
|
||||
bus_dma_tag_t dma_tag;
|
||||
bus_dmamap_t dma_map;
|
||||
bus_dma_segment_t dma_seg;
|
||||
int dma_nseg;
|
||||
};
|
||||
|
||||
struct adapter;
|
||||
|
||||
struct em_int_delay_info {
|
||||
struct adapter *adapter; /* Back-pointer to the adapter struct */
|
||||
int offset; /* Register offset to read/write */
|
||||
int value; /* Current value in usecs */
|
||||
};
|
||||
|
||||
/* Our adapter structure */
|
||||
struct adapter {
|
||||
struct ifnet *ifp;
|
||||
#if __FreeBSD_version >= 800000
|
||||
struct buf_ring *br;
|
||||
#endif
|
||||
struct e1000_hw hw;
|
||||
|
||||
/* FreeBSD operating-system-specific structures. */
|
||||
struct e1000_osdep osdep;
|
||||
struct device *dev;
|
||||
|
||||
struct resource *memory;
|
||||
struct resource *flash;
|
||||
struct resource *msix;
|
||||
|
||||
struct resource *ioport;
|
||||
int io_rid;
|
||||
|
||||
/* 82574 may use 3 int vectors */
|
||||
struct resource *res[3];
|
||||
void *tag[3];
|
||||
int rid[3];
|
||||
|
||||
struct ifmedia media;
|
||||
struct callout timer;
|
||||
struct callout tx_fifo_timer;
|
||||
bool watchdog_check;
|
||||
int watchdog_time;
|
||||
int msi;
|
||||
int if_flags;
|
||||
int max_frame_size;
|
||||
int min_frame_size;
|
||||
struct mtx core_mtx;
|
||||
struct mtx tx_mtx;
|
||||
struct mtx rx_mtx;
|
||||
int em_insert_vlan_header;
|
||||
|
||||
/* Task for FAST handling */
|
||||
struct task link_task;
|
||||
struct task rxtx_task;
|
||||
struct task rx_task;
|
||||
struct task tx_task;
|
||||
struct taskqueue *tq; /* private task queue */
|
||||
|
||||
#if __FreeBSD_version >= 700029
|
||||
eventhandler_tag vlan_attach;
|
||||
eventhandler_tag vlan_detach;
|
||||
u32 num_vlans;
|
||||
#endif
|
||||
|
||||
/* Management and WOL features */
|
||||
u32 wol;
|
||||
bool has_manage;
|
||||
bool has_amt;
|
||||
|
||||
/* Info about the board itself */
|
||||
uint8_t link_active;
|
||||
uint16_t link_speed;
|
||||
uint16_t link_duplex;
|
||||
uint32_t smartspeed;
|
||||
struct em_int_delay_info tx_int_delay;
|
||||
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;
|
||||
|
||||
/*
|
||||
* Transmit definitions
|
||||
*
|
||||
* We have an array of num_tx_desc descriptors (handled
|
||||
* by the controller) paired with an array of tx_buffers
|
||||
* (at tx_buffer_area).
|
||||
* The index of the next available descriptor is next_avail_tx_desc.
|
||||
* The number of remaining tx_desc is num_tx_desc_avail.
|
||||
*/
|
||||
struct em_dma_alloc txdma; /* bus_dma glue for tx desc */
|
||||
struct e1000_tx_desc *tx_desc_base;
|
||||
uint32_t next_avail_tx_desc;
|
||||
uint32_t next_tx_to_clean;
|
||||
volatile uint16_t num_tx_desc_avail;
|
||||
uint16_t num_tx_desc;
|
||||
uint16_t last_hw_offload;
|
||||
uint32_t txd_cmd;
|
||||
struct em_buffer *tx_buffer_area;
|
||||
bus_dma_tag_t txtag; /* dma tag for tx */
|
||||
uint32_t tx_tso; /* last tx was tso */
|
||||
|
||||
/*
|
||||
* Receive definitions
|
||||
*
|
||||
* we have an array of num_rx_desc rx_desc (handled by the
|
||||
* controller), and paired with an array of rx_buffers
|
||||
* (at rx_buffer_area).
|
||||
* The next pair to check on receive is at offset next_rx_desc_to_check
|
||||
*/
|
||||
struct em_dma_alloc rxdma; /* bus_dma glue for rx desc */
|
||||
struct e1000_rx_desc *rx_desc_base;
|
||||
uint32_t next_rx_desc_to_check;
|
||||
uint32_t rx_buffer_len;
|
||||
uint16_t num_rx_desc;
|
||||
int rx_process_limit;
|
||||
struct em_buffer *rx_buffer_area;
|
||||
bus_dma_tag_t rxtag;
|
||||
bus_dmamap_t rx_sparemap;
|
||||
|
||||
/*
|
||||
* First/last mbuf pointers, for
|
||||
* collecting multisegment RX packets.
|
||||
*/
|
||||
struct mbuf *fmp;
|
||||
struct mbuf *lmp;
|
||||
|
||||
/* Misc stats maintained by the driver */
|
||||
unsigned long dropped_pkts;
|
||||
unsigned long mbuf_alloc_failed;
|
||||
unsigned long mbuf_cluster_failed;
|
||||
unsigned long no_tx_desc_avail1;
|
||||
unsigned long no_tx_desc_avail2;
|
||||
unsigned long no_tx_map_avail;
|
||||
unsigned long no_tx_dma_setup;
|
||||
unsigned long watchdog_events;
|
||||
unsigned long rx_overruns;
|
||||
unsigned long rx_irq;
|
||||
unsigned long tx_irq;
|
||||
unsigned long link_irq;
|
||||
|
||||
/* 82547 workaround */
|
||||
uint32_t tx_fifo_size;
|
||||
uint32_t tx_fifo_head;
|
||||
uint32_t tx_fifo_head_addr;
|
||||
uint64_t tx_fifo_reset_cnt;
|
||||
uint64_t tx_fifo_wrk_cnt;
|
||||
uint32_t tx_head_addr;
|
||||
|
||||
/* For 82544 PCIX Workaround */
|
||||
boolean_t pcix_82544;
|
||||
boolean_t in_detach;
|
||||
|
||||
|
||||
struct e1000_hw_stats stats;
|
||||
};
|
||||
|
||||
/* ******************************************************************************
|
||||
* vendor_info_array
|
||||
*
|
||||
* This array contains the list of Subvendor/Subdevice IDs on which the driver
|
||||
* should load.
|
||||
*
|
||||
* ******************************************************************************/
|
||||
typedef struct _em_vendor_info_t {
|
||||
unsigned int vendor_id;
|
||||
unsigned int device_id;
|
||||
unsigned int subvendor_id;
|
||||
unsigned int subdevice_id;
|
||||
unsigned int index;
|
||||
} em_vendor_info_t;
|
||||
|
||||
struct em_buffer {
|
||||
int next_eop; /* Index of the desc to watch */
|
||||
struct mbuf *m_head;
|
||||
bus_dmamap_t map; /* bus_dma map for packet */
|
||||
};
|
||||
|
||||
/* For 82544 PCIX Workaround */
|
||||
typedef struct _ADDRESS_LENGTH_PAIR
|
||||
{
|
||||
uint64_t address;
|
||||
uint32_t length;
|
||||
} ADDRESS_LENGTH_PAIR, *PADDRESS_LENGTH_PAIR;
|
||||
|
||||
typedef struct _DESCRIPTOR_PAIR
|
||||
{
|
||||
ADDRESS_LENGTH_PAIR descriptor[4];
|
||||
uint32_t elements;
|
||||
} DESC_ARRAY, *PDESC_ARRAY;
|
||||
|
||||
#define EM_CORE_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->core_mtx, _name, "EM Core Lock", MTX_DEF)
|
||||
#define EM_TX_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->tx_mtx, _name, "EM TX Lock", MTX_DEF)
|
||||
#define EM_RX_LOCK_INIT(_sc, _name) \
|
||||
mtx_init(&(_sc)->rx_mtx, _name, "EM RX Lock", MTX_DEF)
|
||||
#define EM_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx)
|
||||
#define EM_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx)
|
||||
#define EM_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx)
|
||||
#define EM_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx)
|
||||
#define EM_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx)
|
||||
#define EM_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx)
|
||||
#define EM_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx)
|
||||
#define EM_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx)
|
||||
#define EM_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx)
|
||||
#define EM_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx)
|
||||
#define EM_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED)
|
||||
#define EM_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
|
||||
|
||||
#endif /* _LEM_H_DEFINED_ */
|
||||
|
|
@ -2,15 +2,19 @@
|
|||
.PATH: ${.CURDIR}/../../dev/e1000
|
||||
KMOD = if_em
|
||||
SRCS = device_if.h bus_if.h pci_if.h opt_inet.h
|
||||
SRCS += if_em.c $(SHARED_SRCS)
|
||||
SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c
|
||||
SHARED_SRCS += e1000_80003es2lan.c e1000_82542.c e1000_82541.c e1000_82543.c
|
||||
SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c e1000_osdep.c
|
||||
SHARED_SRCS += e1000_82575.c
|
||||
SRCS += $(CORE_SRC) $(LEGACY_SRC)
|
||||
SRCS += $(COMMON_SHARED) $(LEGACY_SHARED) $(PCIE_SHARED)
|
||||
CORE_SRC = if_em.c e1000_osdep.c
|
||||
# This is the Legacy, pre-PCIE source, it can be
|
||||
# undefined when using modular driver if not needed
|
||||
LEGACY_SRC += if_lem.c
|
||||
COMMON_SHARED = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c
|
||||
PCIE_SHARED = e1000_80003es2lan.c e1000_ich8lan.c e1000_82571.c e1000_82575.c
|
||||
LEGACY_SHARED = e1000_82540.c e1000_82542.c e1000_82541.c e1000_82543.c
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../dev/e1000
|
||||
CFLAGS += -I${.CURDIR}/../../dev/e1000
|
||||
|
||||
# DEVICE_POLLING gives you Legacy interrupt handling
|
||||
# DEVICE_POLLING for a non-interrupt-driven method
|
||||
#CFLAGS += -DDEVICE_POLLING
|
||||
|
||||
clean:
|
||||
|
|
|
|||
Loading…
Reference in a new issue