aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_common.h2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_ethtool.c51
-rw-r--r--drivers/net/ethernet/intel/ice/ice_nvm.c81
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);
29void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res); 29void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res);
30enum ice_status ice_init_nvm(struct ice_hw *hw); 30enum ice_status ice_init_nvm(struct ice_hw *hw);
31enum ice_status ice_read_sr_buf(struct ice_hw *hw, u16 offset, u16 *words,
32 u16 *data);
31enum ice_status 33enum ice_status
32ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq, 34ice_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
206static 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
214static int
215ice_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);
250out:
251 devm_kfree(dev, buf);
252 return ret;
253}
254
206static void ice_get_strings(struct net_device *netdev, u32 stringset, u8 *data) 255static 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 */
138static enum ice_status
139ice_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
178read_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 */
305enum ice_status
306ice_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}