diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_common.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_ethtool.c | 51 | ||||
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_nvm.c | 81 |
3 files changed, 134 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h index b86cfe540045..81c1bb77a9fc 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.h +++ b/drivers/net/ethernet/intel/ice/ice_common.h | |||
| @@ -28,6 +28,8 @@ ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res, | |||
| 28 | enum ice_aq_res_access_type access, u32 timeout); | 28 | enum ice_aq_res_access_type access, u32 timeout); |
| 29 | void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res); | 29 | void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res); |
| 30 | enum ice_status ice_init_nvm(struct ice_hw *hw); | 30 | enum ice_status ice_init_nvm(struct ice_hw *hw); |
| 31 | enum ice_status ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, | ||
| 32 | u16 *data); | ||
| 31 | enum ice_status | 33 | enum ice_status |
| 32 | ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq, | 34 | ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq, |
| 33 | struct ice_aq_desc *desc, void *buf, u16 buf_size, | 35 | struct ice_aq_desc *desc, void *buf, u16 buf_size, |
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index 6facb0a7eed4..2a0bcd460d23 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c | |||
| @@ -203,6 +203,55 @@ static void ice_set_msglevel(struct net_device *netdev, u32 data) | |||
| 203 | #endif /* !CONFIG_DYNAMIC_DEBUG */ | 203 | #endif /* !CONFIG_DYNAMIC_DEBUG */ |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | static int ice_get_eeprom_len(struct net_device *netdev) | ||
| 207 | { | ||
| 208 | struct ice_netdev_priv *np = netdev_priv(netdev); | ||
| 209 | struct ice_pf *pf = np->vsi->back; | ||
| 210 | |||
| 211 | return (int)(pf->hw.nvm.sr_words * sizeof(u16)); | ||
| 212 | } | ||
| 213 | |||
| 214 | static int | ||
| 215 | ice_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, | ||
| 216 | u8 *bytes) | ||
| 217 | { | ||
| 218 | struct ice_netdev_priv *np = netdev_priv(netdev); | ||
| 219 | u16 first_word, last_word, nwords; | ||
| 220 | struct ice_vsi *vsi = np->vsi; | ||
| 221 | struct ice_pf *pf = vsi->back; | ||
| 222 | struct ice_hw *hw = &pf->hw; | ||
| 223 | enum ice_status status; | ||
| 224 | struct device *dev; | ||
| 225 | int ret = 0; | ||
| 226 | u16 *buf; | ||
| 227 | |||
| 228 | dev = &pf->pdev->dev; | ||
| 229 | |||
| 230 | eeprom->magic = hw->vendor_id | (hw->device_id << 16); | ||
| 231 | |||
| 232 | first_word = eeprom->offset >> 1; | ||
| 233 | last_word = (eeprom->offset + eeprom->len - 1) >> 1; | ||
| 234 | nwords = last_word - first_word + 1; | ||
| 235 | |||
| 236 | buf = devm_kcalloc(dev, nwords, sizeof(u16), GFP_KERNEL); | ||
| 237 | if (!buf) | ||
| 238 | return -ENOMEM; | ||
| 239 | |||
| 240 | status = ice_read_sr_buf(hw, first_word, &nwords, buf); | ||
| 241 | if (status) { | ||
| 242 | dev_err(dev, "ice_read_sr_buf failed, err %d aq_err %d\n", | ||
| 243 | status, hw->adminq.sq_last_status); | ||
| 244 | eeprom->len = sizeof(u16) * nwords; | ||
| 245 | ret = -EIO; | ||
| 246 | goto out; | ||
| 247 | } | ||
| 248 | |||
| 249 | memcpy(bytes, (u8 *)buf + (eeprom->offset & 1), eeprom->len); | ||
| 250 | out: | ||
| 251 | devm_kfree(dev, buf); | ||
| 252 | return ret; | ||
| 253 | } | ||
| 254 | |||
| 206 | static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | 255 | static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data) |
| 207 | { | 256 | { |
| 208 | struct ice_netdev_priv *np = netdev_priv(netdev); | 257 | struct ice_netdev_priv *np = netdev_priv(netdev); |
| @@ -1699,6 +1748,8 @@ static const struct ethtool_ops ice_ethtool_ops = { | |||
| 1699 | .get_msglevel = ice_get_msglevel, | 1748 | .get_msglevel = ice_get_msglevel, |
| 1700 | .set_msglevel = ice_set_msglevel, | 1749 | .set_msglevel = ice_set_msglevel, |
| 1701 | .get_link = ethtool_op_get_link, | 1750 | .get_link = ethtool_op_get_link, |
| 1751 | .get_eeprom_len = ice_get_eeprom_len, | ||
| 1752 | .get_eeprom = ice_get_eeprom, | ||
| 1702 | .get_strings = ice_get_strings, | 1753 | .get_strings = ice_get_strings, |
| 1703 | .set_phys_id = ice_set_phys_id, | 1754 | .set_phys_id = ice_set_phys_id, |
| 1704 | .get_ethtool_stats = ice_get_ethtool_stats, | 1755 | .get_ethtool_stats = ice_get_ethtool_stats, |
diff --git a/drivers/net/ethernet/intel/ice/ice_nvm.c b/drivers/net/ethernet/intel/ice/ice_nvm.c index 3274c543283c..ce64cecdae9c 100644 --- a/drivers/net/ethernet/intel/ice/ice_nvm.c +++ b/drivers/net/ethernet/intel/ice/ice_nvm.c | |||
| @@ -125,6 +125,62 @@ ice_read_sr_word_aq(struct ice_hw *hw, u16 offset, u16 *data) | |||
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | /** | 127 | /** |
| 128 | * ice_read_sr_buf_aq - Reads Shadow RAM buf via AQ | ||
| 129 | * @hw: pointer to the HW structure | ||
| 130 | * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) | ||
| 131 | * @words: (in) number of words to read; (out) number of words actually read | ||
| 132 | * @data: words read from the Shadow RAM | ||
| 133 | * | ||
| 134 | * Reads 16 bit words (data buf) from the SR using the ice_read_sr_aq | ||
| 135 | * method. Ownership of the NVM is taken before reading the buffer and later | ||
| 136 | * released. | ||
| 137 | */ | ||
| 138 | static enum ice_status | ||
| 139 | ice_read_sr_buf_aq(struct ice_hw *hw, u16 offset, u16 *words, u16 *data) | ||
| 140 | { | ||
| 141 | enum ice_status status; | ||
| 142 | bool last_cmd = false; | ||
| 143 | u16 words_read = 0; | ||
| 144 | u16 i = 0; | ||
| 145 | |||
| 146 | do { | ||
| 147 | u16 read_size, off_w; | ||
| 148 | |||
| 149 | /* Calculate number of bytes we should read in this step. | ||
| 150 | * It's not allowed to read more than one page at a time or | ||
| 151 | * to cross page boundaries. | ||
| 152 | */ | ||
| 153 | off_w = offset % ICE_SR_SECTOR_SIZE_IN_WORDS; | ||
| 154 | read_size = off_w ? | ||
| 155 | min(*words, | ||
| 156 | (u16)(ICE_SR_SECTOR_SIZE_IN_WORDS - off_w)) : | ||
| 157 | min((*words - words_read), ICE_SR_SECTOR_SIZE_IN_WORDS); | ||
| 158 | |||
| 159 | /* Check if this is last command, if so set proper flag */ | ||
| 160 | if ((words_read + read_size) >= *words) | ||
| 161 | last_cmd = true; | ||
| 162 | |||
| 163 | status = ice_read_sr_aq(hw, offset, read_size, | ||
| 164 | data + words_read, last_cmd); | ||
| 165 | if (status) | ||
| 166 | goto read_nvm_buf_aq_exit; | ||
| 167 | |||
| 168 | /* Increment counter for words already read and move offset to | ||
| 169 | * new read location | ||
| 170 | */ | ||
| 171 | words_read += read_size; | ||
| 172 | offset += read_size; | ||
| 173 | } while (words_read < *words); | ||
| 174 | |||
| 175 | for (i = 0; i < *words; i++) | ||
| 176 | data[i] = le16_to_cpu(((__le16 *)data)[i]); | ||
| 177 | |||
| 178 | read_nvm_buf_aq_exit: | ||
| 179 | *words = words_read; | ||
| 180 | return status; | ||
| 181 | } | ||
| 182 | |||
| 183 | /** | ||
| 128 | * ice_acquire_nvm - Generic request for acquiring the NVM ownership | 184 | * ice_acquire_nvm - Generic request for acquiring the NVM ownership |
| 129 | * @hw: pointer to the HW structure | 185 | * @hw: pointer to the HW structure |
| 130 | * @access: NVM access type (read or write) | 186 | * @access: NVM access type (read or write) |
| @@ -234,3 +290,28 @@ enum ice_status ice_init_nvm(struct ice_hw *hw) | |||
| 234 | 290 | ||
| 235 | return status; | 291 | return status; |
| 236 | } | 292 | } |
| 293 | |||
| 294 | /** | ||
| 295 | * ice_read_sr_buf - Reads Shadow RAM buf and acquire lock if necessary | ||
| 296 | * @hw: pointer to the HW structure | ||
| 297 | * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) | ||
| 298 | * @words: (in) number of words to read; (out) number of words actually read | ||
| 299 | * @data: words read from the Shadow RAM | ||
| 300 | * | ||
| 301 | * Reads 16 bit words (data buf) from the SR using the ice_read_nvm_buf_aq | ||
| 302 | * method. The buf read is preceded by the NVM ownership take | ||
| 303 | * and followed by the release. | ||
| 304 | */ | ||
| 305 | enum ice_status | ||
| 306 | ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words, u16 *data) | ||
| 307 | { | ||
| 308 | enum ice_status status; | ||
| 309 | |||
| 310 | status = ice_acquire_nvm(hw, ICE_RES_READ); | ||
| 311 | if (!status) { | ||
| 312 | status = ice_read_sr_buf_aq(hw, offset, words, data); | ||
| 313 | ice_release_nvm(hw); | ||
| 314 | } | ||
| 315 | |||
| 316 | return status; | ||
| 317 | } | ||
