/** * ixgbe_set_mac_type - Sets MAC type * @hw: pointer to the HW structure * * This function sets the mac type of the adapter based on the * vendor ID and device ID stored in the hw structure. **/ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) { s32 ret_val = 0; if (hw->vendor_id != IXGBE_INTEL_VENDOR_ID) { ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, "Unsupported vendor id: %x", hw->vendor_id); return IXGBE_ERR_DEVICE_NOT_SUPPORTED; } switch (hw->device_id) { case IXGBE_DEV_ID_82598: case IXGBE_DEV_ID_82598_BX: case IXGBE_DEV_ID_82598AF_SINGLE_PORT: case IXGBE_DEV_ID_82598AF_DUAL_PORT: case IXGBE_DEV_ID_82598AT: case IXGBE_DEV_ID_82598AT2: case IXGBE_DEV_ID_82598EB_CX4: case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: case IXGBE_DEV_ID_82598_DA_DUAL_PORT: case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: case IXGBE_DEV_ID_82598EB_XF_LR: case IXGBE_DEV_ID_82598EB_SFP_LOM: hw->mac.type = ixgbe_mac_82598EB; break; case IXGBE_DEV_ID_82599_KX4: case IXGBE_DEV_ID_82599_KX4_MEZZ: case IXGBE_DEV_ID_82599_XAUI_LOM: case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: case IXGBE_DEV_ID_82599_KR: case IXGBE_DEV_ID_82599_SFP: case IXGBE_DEV_ID_82599_BACKPLANE_FCOE: case IXGBE_DEV_ID_82599_SFP_FCOE: case IXGBE_DEV_ID_82599_SFP_EM: case IXGBE_DEV_ID_82599_SFP_SF2: case IXGBE_DEV_ID_82599_SFP_SF_QP: case IXGBE_DEV_ID_82599_QSFP_SF_QP: case IXGBE_DEV_ID_82599EN_SFP: case IXGBE_DEV_ID_82599_CX4: case IXGBE_DEV_ID_82599_LS: case IXGBE_DEV_ID_82599_T3_LOM: hw->mac.type = ixgbe_mac_82599EB; break; case IXGBE_DEV_ID_X540T: case IXGBE_DEV_ID_X540T1: hw->mac.type = ixgbe_mac_X540; break; default: ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED; ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, "Unsupported device id: %x", hw->device_id); break; } hw_dbg(hw, "ixgbe_set_mac_type found mac: %d, returns: %d\n", hw->mac.type, ret_val); return ret_val; }
/** * fm10k_set_mac_type - Sets MAC type * @hw: pointer to the HW structure * * This function sets the mac type of the adapter based on the * vendor ID and device ID stored in the hw structure. **/ s32 fm10k_set_mac_type(struct fm10k_hw *hw) { s32 ret_val = FM10K_SUCCESS; DEBUGFUNC("fm10k_set_mac_type"); if (hw->vendor_id != FM10K_INTEL_VENDOR_ID) { ERROR_REPORT2(FM10K_ERROR_UNSUPPORTED, "Unsupported vendor id: %x\n", hw->vendor_id); return FM10K_ERR_DEVICE_NOT_SUPPORTED; } switch (hw->device_id) { case FM10K_DEV_ID_PF: #ifdef BOULDER_RAPIDS_HW case FM10K_DEV_ID_SDI_FM10420_QDA2: #endif /* BOULDER_RAPIDS_HW */ #ifdef ATWOOD_CHANNEL_HW case FM10K_DEV_ID_SDI_FM10420_DA2: #endif /* ATWOOD_CHANNEL_HW */ hw->mac.type = fm10k_mac_pf; break; case FM10K_DEV_ID_VF: hw->mac.type = fm10k_mac_vf; break; default: ret_val = FM10K_ERR_DEVICE_NOT_SUPPORTED; ERROR_REPORT2(FM10K_ERROR_UNSUPPORTED, "Unsupported device id: %x\n", hw->device_id); break; } DEBUGOUT2("fm10k_set_mac_type found mac: %d, returns: %d\n", hw->mac.type, ret_val); return ret_val; }
/** * ixgbe_write_mbx - Write a message to the mailbox * @hw: pointer to the HW structure * @msg: The message buffer * @size: Length of buffer * @mbx_id: id of mailbox to write * * returns SUCCESS if it successfully copied message into the buffer **/ s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; s32 ret_val = 0; if (size > mbx->size) { ret_val = IXGBE_ERR_MBX; ERROR_REPORT2(IXGBE_ERROR_ARGUMENT, "Invalid mailbox message size %d", size); } else if (mbx->ops.write) ret_val = mbx->ops.write(hw, msg, size, mbx_id); return ret_val; }
/** * ixgbe_obtain_mbx_lock_pf - obtain mailbox lock * @hw: pointer to the HW structure * @vf_number: the VF index * * return SUCCESS if we obtained the mailbox lock **/ static s32 ixgbe_obtain_mbx_lock_pf(struct ixgbe_hw *hw, u16 vf_number) { s32 ret_val = IXGBE_ERR_MBX; u32 p2v_mailbox; /* Take ownership of the buffer */ IXGBE_WRITE_REG(hw, IXGBE_PFMAILBOX(vf_number), IXGBE_PFMAILBOX_PFU); /* reserve mailbox for vf use */ p2v_mailbox = IXGBE_READ_REG(hw, IXGBE_PFMAILBOX(vf_number)); if (p2v_mailbox & IXGBE_PFMAILBOX_PFU) ret_val = 0; else ERROR_REPORT2(IXGBE_ERROR_POLLING, "Failed to obtain mailbox lock for VF%d", vf_number); return ret_val; }
/** * ixgbe_poll_for_ack - Wait for message acknowledgement * @hw: pointer to the HW structure * @mbx_id: id of mailbox to write * * returns SUCCESS if it successfully received a message acknowledgement **/ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; int countdown = mbx->timeout; if (!countdown || !mbx->ops.check_for_ack) goto out; while (countdown && mbx->ops.check_for_ack(hw, mbx_id)) { countdown--; if (!countdown) break; udelay(mbx->udelay); } if (countdown == 0) ERROR_REPORT2(IXGBE_ERROR_POLLING, "Polling for VF%d mailbox ack timedout", mbx_id); out: return countdown ? 0 : IXGBE_ERR_MBX; }
/** * ixgbe_poll_for_msg - Wait for message notification * @hw: pointer to the HW structure * @mbx_id: id of mailbox to write * * returns SUCCESS if it successfully received a message notification **/ static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; int countdown = mbx->timeout; DEBUGFUNC("ixgbe_poll_for_msg"); if (!countdown || !mbx->ops.check_for_msg) goto out; while (countdown && mbx->ops.check_for_msg(hw, mbx_id)) { countdown--; if (!countdown) break; usec_delay(mbx->usec_delay); } if (countdown == 0) ERROR_REPORT2(IXGBE_ERROR_POLLING, "Polling for VF%d mailbox message timedout", mbx_id); out: return countdown ? IXGBE_SUCCESS : IXGBE_ERR_MBX; }
/** * ixgbe_set_mac_type - Sets MAC type * @hw: pointer to the HW structure * * This function sets the mac type of the adapter based on the * vendor ID and device ID stored in the hw structure. **/ s32 ixgbe_set_mac_type(struct ixgbe_hw *hw) { s32 ret_val = IXGBE_SUCCESS; DEBUGFUNC("ixgbe_set_mac_type\n"); if (hw->vendor_id != IXGBE_INTEL_VENDOR_ID) { ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, "Unsupported vendor id: %x", hw->vendor_id); return IXGBE_ERR_DEVICE_NOT_SUPPORTED; } hw->mvals = ixgbe_mvals_base; switch (hw->device_id) { case IXGBE_DEV_ID_82598: case IXGBE_DEV_ID_82598_BX: case IXGBE_DEV_ID_82598AF_SINGLE_PORT: case IXGBE_DEV_ID_82598AF_DUAL_PORT: case IXGBE_DEV_ID_82598AT: case IXGBE_DEV_ID_82598AT2: case IXGBE_DEV_ID_82598EB_CX4: case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: case IXGBE_DEV_ID_82598_DA_DUAL_PORT: case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM: case IXGBE_DEV_ID_82598EB_XF_LR: case IXGBE_DEV_ID_82598EB_SFP_LOM: hw->mac.type = ixgbe_mac_82598EB; break; case IXGBE_DEV_ID_82599_KX4: case IXGBE_DEV_ID_82599_KX4_MEZZ: case IXGBE_DEV_ID_82599_XAUI_LOM: case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: case IXGBE_DEV_ID_82599_KR: case IXGBE_DEV_ID_82599_SFP: case IXGBE_DEV_ID_82599_BACKPLANE_FCOE: case IXGBE_DEV_ID_82599_SFP_FCOE: case IXGBE_DEV_ID_82599_SFP_EM: case IXGBE_DEV_ID_82599_SFP_SF2: case IXGBE_DEV_ID_82599_SFP_SF_QP: case IXGBE_DEV_ID_82599_QSFP_SF_QP: case IXGBE_DEV_ID_82599EN_SFP: case IXGBE_DEV_ID_82599_CX4: case IXGBE_DEV_ID_82599_BYPASS: case IXGBE_DEV_ID_82599_T3_LOM: hw->mac.type = ixgbe_mac_82599EB; break; case IXGBE_DEV_ID_82599_VF: case IXGBE_DEV_ID_82599_VF_HV: hw->mac.type = ixgbe_mac_82599_vf; break; case IXGBE_DEV_ID_X540_VF: case IXGBE_DEV_ID_X540_VF_HV: hw->mac.type = ixgbe_mac_X540_vf; hw->mvals = ixgbe_mvals_X540; break; case IXGBE_DEV_ID_X540T: case IXGBE_DEV_ID_X540T1: case IXGBE_DEV_ID_X540_BYPASS: hw->mac.type = ixgbe_mac_X540; hw->mvals = ixgbe_mvals_X540; break; case IXGBE_DEV_ID_X550T: case IXGBE_DEV_ID_X550T1: hw->mac.type = ixgbe_mac_X550; hw->mvals = ixgbe_mvals_X550; break; case IXGBE_DEV_ID_X550EM_X_KX4: case IXGBE_DEV_ID_X550EM_X_KR: case IXGBE_DEV_ID_X550EM_X_10G_T: case IXGBE_DEV_ID_X550EM_X_1G_T: case IXGBE_DEV_ID_X550EM_X_SFP: hw->mac.type = ixgbe_mac_X550EM_x; hw->mvals = ixgbe_mvals_X550EM_x; break; case IXGBE_DEV_ID_X550_VF: case IXGBE_DEV_ID_X550_VF_HV: hw->mac.type = ixgbe_mac_X550_vf; hw->mvals = ixgbe_mvals_X550; break; case IXGBE_DEV_ID_X550EM_X_VF: case IXGBE_DEV_ID_X550EM_X_VF_HV: hw->mac.type = ixgbe_mac_X550EM_x_vf; hw->mvals = ixgbe_mvals_X550EM_x; break; default: ret_val = IXGBE_ERR_DEVICE_NOT_SUPPORTED; ERROR_REPORT2(IXGBE_ERROR_UNSUPPORTED, "Unsupported device id: %x", hw->device_id); break; } DEBUGOUT2("ixgbe_set_mac_type found mac: %d, returns: %d\n", hw->mac.type, ret_val); return ret_val; }
/** * ixgbe_reset_hw_X540 - Perform hardware reset * @hw: pointer to hardware structure * * Resets the hardware by resetting the transmit and receive units, masks * and clears all interrupts, and perform a reset. **/ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) { s32 status; u32 ctrl, i; u32 swfw_mask = hw->phy.phy_semaphore_mask; DEBUGFUNC("ixgbe_reset_hw_X540"); /* Call adapter stop to disable tx/rx and clear interrupts */ status = hw->mac.ops.stop_adapter(hw); if (status != IXGBE_SUCCESS) goto reset_hw_out; /* flush pending Tx transactions */ ixgbe_clear_tx_pending(hw); mac_reset_top: status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); if (status != IXGBE_SUCCESS) { ERROR_REPORT2(IXGBE_ERROR_CAUTION, "semaphore failed with %d", status); return IXGBE_ERR_SWFW_SYNC; } ctrl = IXGBE_CTRL_RST; ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); IXGBE_WRITE_FLUSH(hw); hw->mac.ops.release_swfw_sync(hw, swfw_mask); /* Poll for reset bit to self-clear indicating reset is complete */ for (i = 0; i < 10; i++) { usec_delay(1); ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); if (!(ctrl & IXGBE_CTRL_RST_MASK)) break; } if (ctrl & IXGBE_CTRL_RST_MASK) { status = IXGBE_ERR_RESET_FAILED; ERROR_REPORT1(IXGBE_ERROR_POLLING, "Reset polling failed to complete.\n"); } msec_delay(100); /* * Double resets are required for recovery from certain error * conditions. Between resets, it is necessary to stall to allow time * for any pending HW events to complete. */ if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; goto mac_reset_top; } /* Set the Rx packet buffer size. */ IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT); /* Store the permanent mac address */ hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); /* * Store MAC address from RAR0, clear receive address registers, and * clear the multicast table. Also reset num_rar_entries to 128, * since we modify this value when programming the SAN MAC address. */ hw->mac.num_rar_entries = 128; hw->mac.ops.init_rx_addrs(hw); /* Store the permanent SAN mac address */ hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr); /* Add the SAN MAC address to the RAR only if it's a valid address */ if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) { /* Save the SAN MAC RAR index */ hw->mac.san_mac_rar_index = hw->mac.num_rar_entries - 1; hw->mac.ops.set_rar(hw, hw->mac.san_mac_rar_index, hw->mac.san_addr, 0, IXGBE_RAH_AV); /* clear VMDq pool/queue selection for this RAR */ hw->mac.ops.clear_vmdq(hw, hw->mac.san_mac_rar_index, IXGBE_CLEAR_VMDQ_ALL); /* Reserve the last RAR for the SAN MAC address */ hw->mac.num_rar_entries--; } /* Store the alternative WWNN/WWPN prefix */ hw->mac.ops.get_wwn_prefix(hw, &hw->mac.wwnn_prefix, &hw->mac.wwpn_prefix); reset_hw_out: return status; }