Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ixgbe/ixgbe_common.c
Show First 20 Lines • Show All 3,110 Lines • ▼ Show 20 Lines | void ixgbe_fc_autoneg(struct ixgbe_hw *hw) | ||||
/* | /* | ||||
* AN should have completed when the cable was plugged in. | * AN should have completed when the cable was plugged in. | ||||
* Look for reasons to bail out. Bail out if: | * Look for reasons to bail out. Bail out if: | ||||
* - FC autoneg is disabled, or if | * - FC autoneg is disabled, or if | ||||
* - link is not up. | * - link is not up. | ||||
*/ | */ | ||||
if (hw->fc.disable_fc_autoneg) { | if (hw->fc.disable_fc_autoneg) { | ||||
/* TODO: This should be just an informative log */ | /* TODO: This should be just an informative log */ | ||||
ERROR_REPORT1(IXGBE_ERROR_CAUTION, | ERROR_REPORT1(IXGBE_ERROR_CAUTION, | ||||
"Flow control autoneg is disabled"); | "Flow control autoneg is disabled"); | ||||
kbowling: http://git.dpdk.org/dpdk/commit/drivers/net/ixgbe/base? | |||||
goto out; | goto out; | ||||
} | } | ||||
hw->mac.ops.check_link(hw, &speed, &link_up, false); | hw->mac.ops.check_link(hw, &speed, &link_up, false); | ||||
if (!link_up) { | if (!link_up) { | ||||
ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down"); | ERROR_REPORT1(IXGBE_ERROR_SOFTWARE, "The link is down"); | ||||
goto out; | goto out; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 677 Lines • ▼ Show 20 Lines | if (IXGBE_REMOVED(hw->hw_addr)) | ||||
goto done; | goto done; | ||||
if (!mpsar_lo && !mpsar_hi) | if (!mpsar_lo && !mpsar_hi) | ||||
goto done; | goto done; | ||||
if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { | if (vmdq == IXGBE_CLEAR_VMDQ_ALL) { | ||||
if (mpsar_lo) { | if (mpsar_lo) { | ||||
IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), 0); | ||||
mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); | mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); | ||||
Done Inline Actionskbowling: Intentional, see http://git.dpdk.org/dpdk/commit/?id=2d04b9e856125197ec8e967471426d56ab7efcf0 | |||||
} | } | ||||
if (mpsar_hi) { | if (mpsar_hi) { | ||||
IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_HI(rar), 0); | ||||
mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); | mpsar_hi = IXGBE_READ_REG(hw, IXGBE_MPSAR_HI(rar)); | ||||
} | } | ||||
} else if (vmdq < 32) { | } else if (vmdq < 32) { | ||||
mpsar_lo &= ~(1 << vmdq); | mpsar_lo &= ~(1 << vmdq); | ||||
IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); | IXGBE_WRITE_REG(hw, IXGBE_MPSAR_LO(rar), mpsar_lo); | ||||
▲ Show 20 Lines • Show All 303 Lines • ▼ Show 20 Lines | s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) | ||||
DEBUGFUNC("ixgbe_clear_vfta_generic"); | DEBUGFUNC("ixgbe_clear_vfta_generic"); | ||||
for (offset = 0; offset < hw->mac.vft_size; offset++) | for (offset = 0; offset < hw->mac.vft_size; offset++) | ||||
IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); | IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); | ||||
for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { | for (offset = 0; offset < IXGBE_VLVF_ENTRIES; offset++) { | ||||
IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); | IXGBE_WRITE_REG(hw, IXGBE_VLVF(offset), 0); | ||||
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0); | IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2), 0); | ||||
IXGBE_WRITE_REG(hw, IXGBE_VLVFB((offset * 2) + 1), 0); | IXGBE_WRITE_REG(hw, IXGBE_VLVFB(offset * 2 + 1), 0); | ||||
} | } | ||||
return IXGBE_SUCCESS; | return IXGBE_SUCCESS; | ||||
} | } | ||||
/** | /** | ||||
* ixgbe_need_crosstalk_fix - Determine if we need to do cross talk fix | * ixgbe_need_crosstalk_fix - Determine if we need to do cross talk fix | ||||
* @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
▲ Show 20 Lines • Show All 409 Lines • ▼ Show 20 Lines | for (i = 0; i < timeout; i++) { | ||||
if (!(hicr & IXGBE_HICR_C)) | if (!(hicr & IXGBE_HICR_C)) | ||||
break; | break; | ||||
msec_delay(1); | msec_delay(1); | ||||
} | } | ||||
/* For each command except "Apply Update" perform | /* For each command except "Apply Update" perform | ||||
* status checks in the HICR registry. | * status checks in the HICR registry. | ||||
*/ | */ | ||||
if ((buffer[0] & IXGBE_HOST_INTERFACE_MASK_CMD) == | if ((buffer[0] & IXGBE_HOST_INTERFACE_MASK_CMD) == | ||||
Done Inline Actionskbowling: http://git.dpdk.org/dpdk/commit/drivers/net/ixgbe/base? | |||||
IXGBE_HOST_INTERFACE_APPLY_UPDATE_CMD) | IXGBE_HOST_INTERFACE_APPLY_UPDATE_CMD) | ||||
return IXGBE_SUCCESS; | return IXGBE_SUCCESS; | ||||
/* Check command completion */ | /* Check command completion */ | ||||
if ((timeout && i == timeout) || | if ((timeout && i == timeout) || | ||||
!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) { | !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) { | ||||
ERROR_REPORT1(IXGBE_ERROR_CAUTION, | ERROR_REPORT1(IXGBE_ERROR_CAUTION, | ||||
"Command has failed with no status valid.\n"); | "Command has failed with no status valid.\n"); | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | if (!return_data) | ||||
goto rel_out; | goto rel_out; | ||||
/* Calculate length in DWORDs */ | /* Calculate length in DWORDs */ | ||||
dword_len = hdr_size >> 2; | dword_len = hdr_size >> 2; | ||||
/* first pull in the header so we know the buffer length */ | /* first pull in the header so we know the buffer length */ | ||||
for (bi = 0; bi < dword_len; bi++) { | for (bi = 0; bi < dword_len; bi++) { | ||||
buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); | buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); | ||||
IXGBE_LE32_TO_CPUS(&buffer[bi]); | IXGBE_LE32_TO_CPUS((uintptr_t)&buffer[bi]); | ||||
} | } | ||||
/* | /* | ||||
* If there is any thing in data position pull it in | * If there is any thing in data position pull it in | ||||
* Read Flash command requires reading buffer length from | * Read Flash command requires reading buffer length from | ||||
* two byes instead of one byte | * two byes instead of one byte | ||||
*/ | */ | ||||
if (resp->cmd == IXGBE_HOST_INTERFACE_FLASH_READ_CMD || | if (resp->cmd == IXGBE_HOST_INTERFACE_FLASH_READ_CMD || | ||||
resp->cmd == IXGBE_HOST_INTERFACE_SHADOW_RAM_READ_CMD) { | resp->cmd == IXGBE_HOST_INTERFACE_SHADOW_RAM_READ_CMD) { | ||||
Done Inline Actionskbowling: http://git.dpdk.org/dpdk/commit/drivers/net/ixgbe/base? | |||||
for (; bi < dword_len + 2; bi++) { | for (; bi < dword_len + 2; bi++) { | ||||
buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, | buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, | ||||
bi); | bi); | ||||
IXGBE_LE32_TO_CPUS(&buffer[bi]); | IXGBE_LE32_TO_CPUS(&buffer[bi]); | ||||
} | } | ||||
buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3) | buf_len = (((u16)(resp->cmd_or_resp.ret_status) << 3) | ||||
& 0xF00) | resp->buf_len; | & 0xF00) | resp->buf_len; | ||||
hdr_size += (2 << 2); | hdr_size += (2 << 2); | ||||
Show All 10 Lines | s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, | ||||
} | } | ||||
/* Calculate length in DWORDs, add 3 for odd lengths */ | /* Calculate length in DWORDs, add 3 for odd lengths */ | ||||
dword_len = (buf_len + 3) >> 2; | dword_len = (buf_len + 3) >> 2; | ||||
/* Pull in the rest of the buffer (bi is where we left off) */ | /* Pull in the rest of the buffer (bi is where we left off) */ | ||||
for (; bi <= dword_len; bi++) { | for (; bi <= dword_len; bi++) { | ||||
buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); | buffer[bi] = IXGBE_READ_REG_ARRAY(hw, IXGBE_FLEX_MNG, bi); | ||||
IXGBE_LE32_TO_CPUS(&buffer[bi]); | IXGBE_LE32_TO_CPUS((uintptr_t)&buffer[bi]); | ||||
} | } | ||||
rel_out: | rel_out: | ||||
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); | hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); | ||||
return status; | return status; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 171 Lines • ▼ Show 20 Lines | out: | ||||
/* Flush all writes and allow 20usec for all transactions to clear */ | /* Flush all writes and allow 20usec for all transactions to clear */ | ||||
IXGBE_WRITE_FLUSH(hw); | IXGBE_WRITE_FLUSH(hw); | ||||
usec_delay(20); | usec_delay(20); | ||||
/* restore previous register values */ | /* restore previous register values */ | ||||
IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); | IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); | ||||
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); | IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); | ||||
} | |||||
static const u8 ixgbe_emc_temp_data[4] = { | |||||
IXGBE_EMC_INTERNAL_DATA, | |||||
IXGBE_EMC_DIODE1_DATA, | |||||
IXGBE_EMC_DIODE2_DATA, | |||||
IXGBE_EMC_DIODE3_DATA | |||||
}; | |||||
static const u8 ixgbe_emc_therm_limit[4] = { | |||||
IXGBE_EMC_INTERNAL_THERM_LIMIT, | |||||
IXGBE_EMC_DIODE1_THERM_LIMIT, | |||||
IXGBE_EMC_DIODE2_THERM_LIMIT, | |||||
IXGBE_EMC_DIODE3_THERM_LIMIT | |||||
}; | |||||
/** | |||||
* ixgbe_get_thermal_sensor_data - Gathers thermal sensor data | |||||
* @hw: pointer to hardware structure | |||||
* | |||||
* Returns the thermal sensor data structure | |||||
**/ | |||||
s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw) | |||||
{ | |||||
s32 status = IXGBE_SUCCESS; | |||||
u16 ets_offset; | |||||
u16 ets_cfg; | |||||
u16 ets_sensor; | |||||
u8 num_sensors; | |||||
u8 sensor_index; | |||||
u8 sensor_location; | |||||
u8 i; | |||||
struct ixgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data; | |||||
DEBUGFUNC("ixgbe_get_thermal_sensor_data_generic"); | |||||
/* Only support thermal sensors attached to 82599 physical port 0 */ | |||||
if ((hw->mac.type != ixgbe_mac_82599EB) || | |||||
Not Done Inline ActionsThis function is only for 82599/X520 erj: This function is only for 82599/X520 | |||||
(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) { | |||||
status = IXGBE_NOT_IMPLEMENTED; | |||||
goto out; | |||||
} | |||||
status = hw->eeprom.ops.read(hw, IXGBE_ETS_CFG, &ets_offset); | |||||
if (status) | |||||
goto out; | |||||
if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF)) { | |||||
status = IXGBE_NOT_IMPLEMENTED; | |||||
goto out; | |||||
} | |||||
status = hw->eeprom.ops.read(hw, ets_offset, &ets_cfg); | |||||
if (status) | |||||
goto out; | |||||
if (((ets_cfg & IXGBE_ETS_TYPE_MASK) >> IXGBE_ETS_TYPE_SHIFT) | |||||
!= IXGBE_ETS_TYPE_EMC) { | |||||
status = IXGBE_NOT_IMPLEMENTED; | |||||
goto out; | |||||
} | |||||
num_sensors = (ets_cfg & IXGBE_ETS_NUM_SENSORS_MASK); | |||||
if (num_sensors > IXGBE_MAX_SENSORS) | |||||
num_sensors = IXGBE_MAX_SENSORS; | |||||
for (i = 0; i < num_sensors; i++) { | |||||
status = hw->eeprom.ops.read(hw, (ets_offset + 1 + i), | |||||
&ets_sensor); | |||||
if (status) | |||||
goto out; | |||||
sensor_index = ((ets_sensor & IXGBE_ETS_DATA_INDEX_MASK) >> | |||||
IXGBE_ETS_DATA_INDEX_SHIFT); | |||||
sensor_location = ((ets_sensor & IXGBE_ETS_DATA_LOC_MASK) >> | |||||
IXGBE_ETS_DATA_LOC_SHIFT); | |||||
if (sensor_location != 0) { | |||||
status = hw->phy.ops.read_i2c_byte(hw, | |||||
ixgbe_emc_temp_data[sensor_index], | |||||
IXGBE_I2C_THERMAL_SENSOR_ADDR, | |||||
&data->sensor[i].temp); | |||||
if (status) | |||||
goto out; | |||||
} | |||||
} | |||||
out: | |||||
return status; | |||||
} | |||||
/** | |||||
* ixgbe_init_thermal_sensor_thresh_generic - Inits thermal sensor thresholds | |||||
* @hw: pointer to hardware structure | |||||
* | |||||
* Inits the thermal sensor thresholds according to the NVM map | |||||
* and save off the threshold and location values into mac.thermal_sensor_data | |||||
**/ | |||||
s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw) | |||||
{ | |||||
s32 status = IXGBE_SUCCESS; | |||||
u16 offset; | |||||
u16 ets_offset; | |||||
u16 ets_cfg; | |||||
u16 ets_sensor; | |||||
u8 low_thresh_delta; | |||||
u8 num_sensors; | |||||
u8 sensor_index; | |||||
u8 sensor_location; | |||||
u8 therm_limit; | |||||
u8 i; | |||||
struct ixgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data; | |||||
DEBUGFUNC("ixgbe_init_thermal_sensor_thresh_generic"); | |||||
memset(data, 0, sizeof(struct ixgbe_thermal_sensor_data)); | |||||
/* Only support thermal sensors attached to 82599 physical port 0 */ | |||||
if ((hw->mac.type != ixgbe_mac_82599EB) || | |||||
(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) | |||||
return IXGBE_NOT_IMPLEMENTED; | |||||
offset = IXGBE_ETS_CFG; | |||||
if (hw->eeprom.ops.read(hw, offset, &ets_offset)) | |||||
goto eeprom_err; | |||||
if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF)) | |||||
return IXGBE_NOT_IMPLEMENTED; | |||||
offset = ets_offset; | |||||
if (hw->eeprom.ops.read(hw, offset, &ets_cfg)) | |||||
goto eeprom_err; | |||||
if (((ets_cfg & IXGBE_ETS_TYPE_MASK) >> IXGBE_ETS_TYPE_SHIFT) | |||||
!= IXGBE_ETS_TYPE_EMC) | |||||
return IXGBE_NOT_IMPLEMENTED; | |||||
low_thresh_delta = ((ets_cfg & IXGBE_ETS_LTHRES_DELTA_MASK) >> | |||||
IXGBE_ETS_LTHRES_DELTA_SHIFT); | |||||
num_sensors = (ets_cfg & IXGBE_ETS_NUM_SENSORS_MASK); | |||||
for (i = 0; i < num_sensors; i++) { | |||||
offset = ets_offset + 1 + i; | |||||
if (hw->eeprom.ops.read(hw, offset, &ets_sensor)) { | |||||
ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, | |||||
"eeprom read at offset %d failed", | |||||
offset); | |||||
continue; | |||||
} | |||||
sensor_index = ((ets_sensor & IXGBE_ETS_DATA_INDEX_MASK) >> | |||||
IXGBE_ETS_DATA_INDEX_SHIFT); | |||||
sensor_location = ((ets_sensor & IXGBE_ETS_DATA_LOC_MASK) >> | |||||
IXGBE_ETS_DATA_LOC_SHIFT); | |||||
therm_limit = ets_sensor & IXGBE_ETS_DATA_HTHRESH_MASK; | |||||
hw->phy.ops.write_i2c_byte(hw, | |||||
ixgbe_emc_therm_limit[sensor_index], | |||||
IXGBE_I2C_THERMAL_SENSOR_ADDR, therm_limit); | |||||
if ((i < IXGBE_MAX_SENSORS) && (sensor_location != 0)) { | |||||
data->sensor[i].location = sensor_location; | |||||
data->sensor[i].caution_thresh = therm_limit; | |||||
data->sensor[i].max_op_thresh = therm_limit - | |||||
low_thresh_delta; | |||||
} | |||||
} | |||||
return status; | |||||
eeprom_err: | |||||
ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE, | |||||
"eeprom read at offset %d failed", offset); | |||||
return IXGBE_NOT_IMPLEMENTED; | |||||
} | } | ||||
/** | /** | ||||
* ixgbe_bypass_rw_generic - Bit bang data into by_pass FW | * ixgbe_bypass_rw_generic - Bit bang data into by_pass FW | ||||
* | * | ||||
* @hw: pointer to hardware structure | * @hw: pointer to hardware structure | ||||
* @cmd: Command we send to the FW | * @cmd: Command we send to the FW | ||||
* @status: The reply from the FW | * @status: The reply from the FW | ||||
▲ Show 20 Lines • Show All 509 Lines • ▼ Show 20 Lines | status = ixgbe_setup_mac_link(hw, | ||||
autoneg_wait_to_complete); | autoneg_wait_to_complete); | ||||
if (status != IXGBE_SUCCESS) | if (status != IXGBE_SUCCESS) | ||||
return status; | return status; | ||||
/* Flap the Tx laser if it has not already been done */ | /* Flap the Tx laser if it has not already been done */ | ||||
ixgbe_flap_tx_laser(hw); | ixgbe_flap_tx_laser(hw); | ||||
/* Wait for the controller to acquire link. Per IEEE 802.3ap, | /* Wait for the controller to acquire link. Per IEEE 802.3ap, | ||||
* Section 73.10.2, we may have to wait up to 1000ms if KR is | * Section 73.10.2, we may have to wait up to 1000ms if KR is | ||||
Done Inline ActionsI don't have access to this spec. Is it 500ms or 1000ms? kbowling: I don't have access to this spec. Is it 500ms or 1000ms? | |||||
Done Inline Actionskbowling: http://git.dpdk.org/dpdk/commit/drivers/net/ixgbe/base? | |||||
Done Inline ActionsI'd trust them. erj: I'd trust them. | |||||
* attempted. 82599 uses the same timing for 10g SFI. | * attempted. 82599 uses the same timing for 10g SFI. | ||||
*/ | */ | ||||
for (i = 0; i < 10; i++) { | for (i = 0; i < 10; i++) { | ||||
/* Wait for the link partner to also set speed */ | /* Wait for the link partner to also set speed */ | ||||
msec_delay(100); | msec_delay(100); | ||||
/* If we have link, just jump out */ | /* If we have link, just jump out */ | ||||
status = ixgbe_check_link(hw, &link_speed, | status = ixgbe_check_link(hw, &link_speed, | ||||
▲ Show 20 Lines • Show All 141 Lines • Show Last 20 Lines |
http://git.dpdk.org/dpdk/commit/drivers/net/ixgbe/base?id=ab6ac48d483ef7f906b90f45182f2ddf3254d876