|
@@ -2080,6 +2080,50 @@ static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
|
|
|
return ret_val;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * ixgbe_reset_pipeline_82599 - perform pipeline reset
|
|
|
+ *
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ *
|
|
|
+ * Reset pipeline by asserting Restart_AN together with LMS change to ensure
|
|
|
+ * full pipeline reset. Note - We must hold the SW/FW semaphore before writing
|
|
|
+ * to AUTOC, so this function assumes the semaphore is held.
|
|
|
+ **/
|
|
|
+s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
|
|
|
+{
|
|
|
+ s32 i, autoc_reg, ret_val;
|
|
|
+ s32 anlp1_reg = 0;
|
|
|
+
|
|
|
+ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
|
|
+ autoc_reg |= IXGBE_AUTOC_AN_RESTART;
|
|
|
+
|
|
|
+ /* Write AUTOC register with toggled LMS[2] bit and Restart_AN */
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg ^ IXGBE_AUTOC_LMS_1G_AN);
|
|
|
+
|
|
|
+ /* Wait for AN to leave state 0 */
|
|
|
+ for (i = 0; i < 10; i++) {
|
|
|
+ usleep_range(4000, 8000);
|
|
|
+ anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
|
|
|
+ if (anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) {
|
|
|
+ hw_dbg(hw, "auto negotiation not completed\n");
|
|
|
+ ret_val = IXGBE_ERR_RESET_FAILED;
|
|
|
+ goto reset_pipeline_out;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret_val = 0;
|
|
|
+
|
|
|
+reset_pipeline_out:
|
|
|
+ /* Write AUTOC register with original LMS field and Restart_AN */
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
|
|
|
+ IXGBE_WRITE_FLUSH(hw);
|
|
|
+
|
|
|
+ return ret_val;
|
|
|
+}
|
|
|
+
|
|
|
static struct ixgbe_mac_operations mac_ops_82599 = {
|
|
|
.init_hw = &ixgbe_init_hw_generic,
|
|
|
.reset_hw = &ixgbe_reset_hw_82599,
|