diff options
author | Dan Nowlin <dan.nowlin@intel.com> | 2018-08-09 09:29:46 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2018-08-28 13:17:06 -0400 |
commit | ff2b13213a6a0baca105bc3bc724225f0adde1f8 (patch) | |
tree | e901e8059aede73686b1e0b8d3387657cfde8b05 /drivers/net/ethernet/intel/ice/ice_common.c | |
parent | b36c598c999c628130f6743dc2362585360de65c (diff) |
ice: Update request resource command to latest specification
Align Request Resource Ownership AQ command (0x0008) to the latest
specification. This includes:
- Correcting the resource IDs for the Global Cfg and Change locks.
- new enum ICE_CHANGE_LOCK_RES_ID
- new enum ICE_GLOBAL_CFG_LOCK_RES_ID
- Altering the flow for Global Config Lock to allow only the first PF to
download the package.
Signed-off-by: Dan Nowlin <dan.nowlin@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Tony Brelinski <tonyx.brelinski@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_common.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_common.c | 75 |
1 files changed, 58 insertions, 17 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index b315655eab27..2a1e13576ce2 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c | |||
@@ -967,7 +967,22 @@ enum ice_status ice_aq_q_shutdown(struct ice_hw *hw, bool unloading) | |||
967 | * @timeout: the maximum time in ms that the driver may hold the resource | 967 | * @timeout: the maximum time in ms that the driver may hold the resource |
968 | * @cd: pointer to command details structure or NULL | 968 | * @cd: pointer to command details structure or NULL |
969 | * | 969 | * |
970 | * requests common resource using the admin queue commands (0x0008) | 970 | * Requests common resource using the admin queue commands (0x0008). |
971 | * When attempting to acquire the Global Config Lock, the driver can | ||
972 | * learn of three states: | ||
973 | * 1) ICE_SUCCESS - acquired lock, and can perform download package | ||
974 | * 2) ICE_ERR_AQ_ERROR - did not get lock, driver should fail to load | ||
975 | * 3) ICE_ERR_AQ_NO_WORK - did not get lock, but another driver has | ||
976 | * successfully downloaded the package; the driver does | ||
977 | * not have to download the package and can continue | ||
978 | * loading | ||
979 | * | ||
980 | * Note that if the caller is in an acquire lock, perform action, release lock | ||
981 | * phase of operation, it is possible that the FW may detect a timeout and issue | ||
982 | * a CORER. In this case, the driver will receive a CORER interrupt and will | ||
983 | * have to determine its cause. The calling thread that is handling this flow | ||
984 | * will likely get an error propagated back to it indicating the Download | ||
985 | * Package, Update Package or the Release Resource AQ commands timed out. | ||
971 | */ | 986 | */ |
972 | static enum ice_status | 987 | static enum ice_status |
973 | ice_aq_req_res(struct ice_hw *hw, enum ice_aq_res_ids res, | 988 | ice_aq_req_res(struct ice_hw *hw, enum ice_aq_res_ids res, |
@@ -985,13 +1000,43 @@ ice_aq_req_res(struct ice_hw *hw, enum ice_aq_res_ids res, | |||
985 | cmd_resp->res_id = cpu_to_le16(res); | 1000 | cmd_resp->res_id = cpu_to_le16(res); |
986 | cmd_resp->access_type = cpu_to_le16(access); | 1001 | cmd_resp->access_type = cpu_to_le16(access); |
987 | cmd_resp->res_number = cpu_to_le32(sdp_number); | 1002 | cmd_resp->res_number = cpu_to_le32(sdp_number); |
1003 | cmd_resp->timeout = cpu_to_le32(*timeout); | ||
1004 | *timeout = 0; | ||
988 | 1005 | ||
989 | status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); | 1006 | status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); |
1007 | |||
990 | /* The completion specifies the maximum time in ms that the driver | 1008 | /* The completion specifies the maximum time in ms that the driver |
991 | * may hold the resource in the Timeout field. | 1009 | * may hold the resource in the Timeout field. |
992 | * If the resource is held by someone else, the command completes with | 1010 | */ |
993 | * busy return value and the timeout field indicates the maximum time | 1011 | |
994 | * the current owner of the resource has to free it. | 1012 | /* Global config lock response utilizes an additional status field. |
1013 | * | ||
1014 | * If the Global config lock resource is held by some other driver, the | ||
1015 | * command completes with ICE_AQ_RES_GLBL_IN_PROG in the status field | ||
1016 | * and the timeout field indicates the maximum time the current owner | ||
1017 | * of the resource has to free it. | ||
1018 | */ | ||
1019 | if (res == ICE_GLOBAL_CFG_LOCK_RES_ID) { | ||
1020 | if (le16_to_cpu(cmd_resp->status) == ICE_AQ_RES_GLBL_SUCCESS) { | ||
1021 | *timeout = le32_to_cpu(cmd_resp->timeout); | ||
1022 | return 0; | ||
1023 | } else if (le16_to_cpu(cmd_resp->status) == | ||
1024 | ICE_AQ_RES_GLBL_IN_PROG) { | ||
1025 | *timeout = le32_to_cpu(cmd_resp->timeout); | ||
1026 | return ICE_ERR_AQ_ERROR; | ||
1027 | } else if (le16_to_cpu(cmd_resp->status) == | ||
1028 | ICE_AQ_RES_GLBL_DONE) { | ||
1029 | return ICE_ERR_AQ_NO_WORK; | ||
1030 | } | ||
1031 | |||
1032 | /* invalid FW response, force a timeout immediately */ | ||
1033 | *timeout = 0; | ||
1034 | return ICE_ERR_AQ_ERROR; | ||
1035 | } | ||
1036 | |||
1037 | /* If the resource is held by some other driver, the command completes | ||
1038 | * with a busy return value and the timeout field indicates the maximum | ||
1039 | * time the current owner of the resource has to free it. | ||
995 | */ | 1040 | */ |
996 | if (!status || hw->adminq.sq_last_status == ICE_AQ_RC_EBUSY) | 1041 | if (!status || hw->adminq.sq_last_status == ICE_AQ_RC_EBUSY) |
997 | *timeout = le32_to_cpu(cmd_resp->timeout); | 1042 | *timeout = le32_to_cpu(cmd_resp->timeout); |
@@ -1030,30 +1075,28 @@ ice_aq_release_res(struct ice_hw *hw, enum ice_aq_res_ids res, u8 sdp_number, | |||
1030 | * @hw: pointer to the HW structure | 1075 | * @hw: pointer to the HW structure |
1031 | * @res: resource id | 1076 | * @res: resource id |
1032 | * @access: access type (read or write) | 1077 | * @access: access type (read or write) |
1078 | * @timeout: timeout in milliseconds | ||
1033 | * | 1079 | * |
1034 | * This function will attempt to acquire the ownership of a resource. | 1080 | * This function will attempt to acquire the ownership of a resource. |
1035 | */ | 1081 | */ |
1036 | enum ice_status | 1082 | enum ice_status |
1037 | ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res, | 1083 | ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res, |
1038 | enum ice_aq_res_access_type access) | 1084 | enum ice_aq_res_access_type access, u32 timeout) |
1039 | { | 1085 | { |
1040 | #define ICE_RES_POLLING_DELAY_MS 10 | 1086 | #define ICE_RES_POLLING_DELAY_MS 10 |
1041 | u32 delay = ICE_RES_POLLING_DELAY_MS; | 1087 | u32 delay = ICE_RES_POLLING_DELAY_MS; |
1088 | u32 time_left = timeout; | ||
1042 | enum ice_status status; | 1089 | enum ice_status status; |
1043 | u32 time_left = 0; | ||
1044 | u32 timeout; | ||
1045 | 1090 | ||
1046 | status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL); | 1091 | status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL); |
1047 | 1092 | ||
1048 | /* An admin queue return code of ICE_AQ_RC_EEXIST means that another | 1093 | /* A return code of ICE_ERR_AQ_NO_WORK means that another driver has |
1049 | * driver has previously acquired the resource and performed any | 1094 | * previously acquired the resource and performed any necessary updates; |
1050 | * necessary updates; in this case the caller does not obtain the | 1095 | * in this case the caller does not obtain the resource and has no |
1051 | * resource and has no further work to do. | 1096 | * further work to do. |
1052 | */ | 1097 | */ |
1053 | if (hw->adminq.sq_last_status == ICE_AQ_RC_EEXIST) { | 1098 | if (status == ICE_ERR_AQ_NO_WORK) |
1054 | status = ICE_ERR_AQ_NO_WORK; | ||
1055 | goto ice_acquire_res_exit; | 1099 | goto ice_acquire_res_exit; |
1056 | } | ||
1057 | 1100 | ||
1058 | if (status) | 1101 | if (status) |
1059 | ice_debug(hw, ICE_DBG_RES, | 1102 | ice_debug(hw, ICE_DBG_RES, |
@@ -1066,11 +1109,9 @@ ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res, | |||
1066 | timeout = (timeout > delay) ? timeout - delay : 0; | 1109 | timeout = (timeout > delay) ? timeout - delay : 0; |
1067 | status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL); | 1110 | status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL); |
1068 | 1111 | ||
1069 | if (hw->adminq.sq_last_status == ICE_AQ_RC_EEXIST) { | 1112 | if (status == ICE_ERR_AQ_NO_WORK) |
1070 | /* lock free, but no work to do */ | 1113 | /* lock free, but no work to do */ |
1071 | status = ICE_ERR_AQ_NO_WORK; | ||
1072 | break; | 1114 | break; |
1073 | } | ||
1074 | 1115 | ||
1075 | if (!status) | 1116 | if (!status) |
1076 | /* lock acquired */ | 1117 | /* lock acquired */ |