Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 Intel Corporation
3 : : */
4 : :
5 : : #include "ixgbe_type.h"
6 : : #include "ixgbe_e610.h"
7 : : #include "ixgbe_x550.h"
8 : : #include "ixgbe_common.h"
9 : : #include "ixgbe_phy.h"
10 : : #include "ixgbe_api.h"
11 : :
12 : : /**
13 : : * ixgbe_init_aci - initialization routine for Admin Command Interface
14 : : * @hw: pointer to the hardware structure
15 : : *
16 : : * Initialize the ACI lock.
17 : : */
18 : 0 : void ixgbe_init_aci(struct ixgbe_hw *hw)
19 : : {
20 : 0 : ixgbe_init_lock(&hw->aci.lock);
21 : 0 : }
22 : :
23 : : /**
24 : : * ixgbe_shutdown_aci - shutdown routine for Admin Command Interface
25 : : * @hw: pointer to the hardware structure
26 : : *
27 : : * Destroy the ACI lock.
28 : : */
29 : 0 : void ixgbe_shutdown_aci(struct ixgbe_hw *hw)
30 : : {
31 : 0 : ixgbe_destroy_lock(&hw->aci.lock);
32 : 0 : }
33 : :
34 : : /**
35 : : * ixgbe_should_retry_aci_send_cmd_execute - decide if ACI command should
36 : : * be resent
37 : : * @opcode: ACI opcode
38 : : *
39 : : * Check if ACI command should be sent again depending on the provided opcode.
40 : : *
41 : : * Return: true if the sending command routine should be repeated,
42 : : * otherwise false.
43 : : */
44 : : STATIC bool ixgbe_should_retry_aci_send_cmd_execute(u16 opcode)
45 : : {
46 : :
47 : 0 : switch (opcode) {
48 : : case ixgbe_aci_opc_disable_rxen:
49 : : case ixgbe_aci_opc_get_phy_caps:
50 : : case ixgbe_aci_opc_get_link_status:
51 : : case ixgbe_aci_opc_get_link_topo:
52 : : return true;
53 : : }
54 : :
55 : 0 : return false;
56 : : }
57 : :
58 : : /**
59 : : * ixgbe_aci_send_cmd_execute - execute sending FW Admin Command to FW Admin
60 : : * Command Interface
61 : : * @hw: pointer to the HW struct
62 : : * @desc: descriptor describing the command
63 : : * @buf: buffer to use for indirect commands (NULL for direct commands)
64 : : * @buf_size: size of buffer for indirect commands (0 for direct commands)
65 : : *
66 : : * Admin Command is sent using CSR by setting descriptor and buffer in specific
67 : : * registers.
68 : : *
69 : : * Return: the exit code of the operation.
70 : : * * - IXGBE_SUCCESS - success.
71 : : * * - IXGBE_ERR_ACI_DISABLED - CSR mechanism is not enabled.
72 : : * * - IXGBE_ERR_ACI_BUSY - CSR mechanism is busy.
73 : : * * - IXGBE_ERR_PARAM - buf_size is too big or
74 : : * invalid argument buf or buf_size.
75 : : * * - IXGBE_ERR_ACI_TIMEOUT - Admin Command X command timeout.
76 : : * * - IXGBE_ERR_ACI_ERROR - Admin Command X invalid state of HICR register or
77 : : * Admin Command failed because of bad opcode was returned or
78 : : * Admin Command failed with error Y.
79 : : */
80 : : STATIC s32
81 : 0 : ixgbe_aci_send_cmd_execute(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
82 : : void *buf, u16 buf_size)
83 : : {
84 : : u32 hicr = 0, tmp_buf_size = 0, i = 0;
85 : : u32 *raw_desc = (u32 *)desc;
86 : : s32 status = IXGBE_SUCCESS;
87 : : bool valid_buf = false;
88 : : u32 *tmp_buf = NULL;
89 : : u16 opcode = 0;
90 : :
91 : : do {
92 : 0 : hw->aci.last_status = IXGBE_ACI_RC_OK;
93 : :
94 : : /* It's necessary to check if mechanism is enabled */
95 : 0 : hicr = IXGBE_READ_REG(hw, PF_HICR);
96 [ # # ]: 0 : if (!(hicr & PF_HICR_EN)) {
97 : : status = IXGBE_ERR_ACI_DISABLED;
98 : : break;
99 : : }
100 [ # # ]: 0 : if (hicr & PF_HICR_C) {
101 : 0 : hw->aci.last_status = IXGBE_ACI_RC_EBUSY;
102 : : status = IXGBE_ERR_ACI_BUSY;
103 : : break;
104 : : }
105 : 0 : opcode = desc->opcode;
106 : :
107 [ # # ]: 0 : if (buf_size > IXGBE_ACI_MAX_BUFFER_SIZE) {
108 : : status = IXGBE_ERR_PARAM;
109 : : break;
110 : : }
111 : :
112 [ # # ]: 0 : if (buf)
113 : 0 : desc->flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_BUF);
114 : :
115 : : /* Check if buf and buf_size are proper params */
116 [ # # ]: 0 : if (desc->flags & IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_BUF)) {
117 [ # # ]: 0 : if ((buf && buf_size == 0) ||
118 : : (buf == NULL && buf_size)) {
119 : : status = IXGBE_ERR_PARAM;
120 : : break;
121 : : }
122 [ # # ]: 0 : if (buf && buf_size)
123 : : valid_buf = true;
124 : : }
125 : :
126 : : if (valid_buf == true) {
127 [ # # ]: 0 : if (buf_size % 4 == 0)
128 : 0 : tmp_buf_size = buf_size;
129 : : else
130 : 0 : tmp_buf_size = (buf_size & (u16)(~0x03)) + 4;
131 : :
132 : 0 : tmp_buf = (u32*)ixgbe_malloc(hw, tmp_buf_size);
133 [ # # ]: 0 : if (!tmp_buf)
134 : : return IXGBE_ERR_OUT_OF_MEM;
135 : :
136 : : /* tmp_buf will be firstly filled with 0xFF and after
137 : : * that the content of buf will be written into it.
138 : : * This approach lets us use valid buf_size and
139 : : * prevents us from reading past buf area
140 : : * when buf_size mod 4 not equal to 0.
141 : : */
142 : : memset(tmp_buf, 0xFF, tmp_buf_size);
143 [ # # ]: 0 : memcpy(tmp_buf, buf, buf_size);
144 : :
145 [ # # ]: 0 : if (tmp_buf_size > IXGBE_ACI_LG_BUF)
146 : 0 : desc->flags |=
147 : : IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_LB);
148 : :
149 : 0 : desc->datalen = IXGBE_CPU_TO_LE16(buf_size);
150 : :
151 [ # # ]: 0 : if (desc->flags & IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD)) {
152 [ # # ]: 0 : for (i = 0; i < tmp_buf_size / 4; i++) {
153 : 0 : IXGBE_WRITE_REG(hw, PF_HIBA(i),
154 : : IXGBE_LE32_TO_CPU(tmp_buf[i]));
155 : : }
156 : : }
157 : : }
158 : :
159 : : /* Descriptor is written to specific registers */
160 [ # # ]: 0 : for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++)
161 : 0 : IXGBE_WRITE_REG(hw, PF_HIDA(i),
162 : : IXGBE_LE32_TO_CPU(raw_desc[i]));
163 : :
164 : : /* SW has to set PF_HICR.C bit and clear PF_HICR.SV and
165 : : * PF_HICR_EV
166 : : */
167 : 0 : hicr = IXGBE_READ_REG(hw, PF_HICR);
168 : 0 : hicr = (hicr | PF_HICR_C) & ~(PF_HICR_SV | PF_HICR_EV);
169 : 0 : IXGBE_WRITE_REG(hw, PF_HICR, hicr);
170 : :
171 : : /* Wait for sync Admin Command response */
172 [ # # ]: 0 : for (i = 0; i < IXGBE_ACI_SYNC_RESPONSE_TIMEOUT; i += 1) {
173 : 0 : hicr = IXGBE_READ_REG(hw, PF_HICR);
174 [ # # ]: 0 : if ((hicr & PF_HICR_SV) || !(hicr & PF_HICR_C))
175 : : break;
176 : :
177 : 0 : msec_delay(1);
178 : : }
179 : :
180 : : /* Wait for async Admin Command response */
181 [ # # ]: 0 : if ((hicr & PF_HICR_SV) && (hicr & PF_HICR_C)) {
182 [ # # ]: 0 : for (i = 0; i < IXGBE_ACI_ASYNC_RESPONSE_TIMEOUT;
183 : 0 : i += 1) {
184 : 0 : hicr = IXGBE_READ_REG(hw, PF_HICR);
185 [ # # ]: 0 : if ((hicr & PF_HICR_EV) || !(hicr & PF_HICR_C))
186 : : break;
187 : :
188 : 0 : msec_delay(1);
189 : : }
190 : : }
191 : :
192 : : /* Read sync Admin Command response */
193 [ # # ]: 0 : if ((hicr & PF_HICR_SV)) {
194 [ # # ]: 0 : for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++) {
195 : 0 : raw_desc[i] = IXGBE_READ_REG(hw, PF_HIDA(i));
196 : : raw_desc[i] = IXGBE_CPU_TO_LE32(raw_desc[i]);
197 : : }
198 : : }
199 : :
200 : : /* Read async Admin Command response */
201 [ # # ]: 0 : if ((hicr & PF_HICR_EV) && !(hicr & PF_HICR_C)) {
202 [ # # ]: 0 : for (i = 0; i < IXGBE_ACI_DESC_SIZE_IN_DWORDS; i++) {
203 : 0 : raw_desc[i] = IXGBE_READ_REG(hw, PF_HIDA_2(i));
204 : : raw_desc[i] = IXGBE_CPU_TO_LE32(raw_desc[i]);
205 : : }
206 : : }
207 : :
208 : : /* Handle timeout and invalid state of HICR register */
209 [ # # ]: 0 : if (hicr & PF_HICR_C) {
210 : : status = IXGBE_ERR_ACI_TIMEOUT;
211 : : break;
212 [ # # ]: 0 : } else if (!(hicr & PF_HICR_SV) && !(hicr & PF_HICR_EV)) {
213 : : status = IXGBE_ERR_ACI_ERROR;
214 : : break;
215 : : }
216 : :
217 : : /* For every command other than 0x0014 treat opcode mismatch
218 : : * as an error. Response to 0x0014 command read from HIDA_2
219 : : * is a descriptor of an event which is expected to contain
220 : : * different opcode than the command.
221 : : */
222 [ # # # # ]: 0 : if (desc->opcode != opcode &&
223 : : opcode != IXGBE_CPU_TO_LE16(ixgbe_aci_opc_get_fw_event)) {
224 : : status = IXGBE_ERR_ACI_ERROR;
225 : : break;
226 : : }
227 : :
228 [ # # ]: 0 : if (desc->retval != IXGBE_ACI_RC_OK) {
229 : 0 : hw->aci.last_status = (enum ixgbe_aci_err)desc->retval;
230 : : status = IXGBE_ERR_ACI_ERROR;
231 : 0 : break;
232 : : }
233 : :
234 : : /* Write a response values to a buf */
235 [ # # # # ]: 0 : if (valid_buf && (desc->flags &
236 : : IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_BUF))) {
237 [ # # ]: 0 : for (i = 0; i < tmp_buf_size / 4; i++) {
238 : 0 : tmp_buf[i] = IXGBE_READ_REG(hw, PF_HIBA(i));
239 : : tmp_buf[i] = IXGBE_CPU_TO_LE32(tmp_buf[i]);
240 : : }
241 : 0 : memcpy(buf, tmp_buf, buf_size);
242 : : }
243 : : } while (0);
244 : :
245 [ # # ]: 0 : if (tmp_buf)
246 : 0 : ixgbe_free(hw, tmp_buf);
247 : :
248 : : return status;
249 : : }
250 : :
251 : : /**
252 : : * ixgbe_aci_send_cmd - send FW Admin Command to FW Admin Command Interface
253 : : * @hw: pointer to the HW struct
254 : : * @desc: descriptor describing the command
255 : : * @buf: buffer to use for indirect commands (NULL for direct commands)
256 : : * @buf_size: size of buffer for indirect commands (0 for direct commands)
257 : : *
258 : : * Helper function to send FW Admin Commands to the FW Admin Command Interface.
259 : : *
260 : : * Retry sending the FW Admin Command multiple times to the FW ACI
261 : : * if the EBUSY Admin Command error is returned.
262 : : *
263 : : * Return: the exit code of the operation.
264 : : */
265 : 0 : s32 ixgbe_aci_send_cmd(struct ixgbe_hw *hw, struct ixgbe_aci_desc *desc,
266 : : void *buf, u16 buf_size)
267 : : {
268 : : struct ixgbe_aci_desc desc_cpy;
269 : : enum ixgbe_aci_err last_status;
270 : : bool is_cmd_for_retry;
271 : : u8 *buf_cpy = NULL;
272 : : s32 status;
273 : : u16 opcode;
274 : : u8 idx = 0;
275 : :
276 [ # # ]: 0 : opcode = IXGBE_LE16_TO_CPU(desc->opcode);
277 : : is_cmd_for_retry = ixgbe_should_retry_aci_send_cmd_execute(opcode);
278 : : memset(&desc_cpy, 0, sizeof(desc_cpy));
279 : :
280 [ # # ]: 0 : if (is_cmd_for_retry) {
281 [ # # ]: 0 : if (buf) {
282 : 0 : buf_cpy = (u8 *)ixgbe_malloc(hw, buf_size);
283 [ # # ]: 0 : if (!buf_cpy)
284 : : return IXGBE_ERR_OUT_OF_MEM;
285 : : }
286 : : memcpy(&desc_cpy, desc, sizeof(desc_cpy));
287 : : }
288 : :
289 : : do {
290 : 0 : ixgbe_acquire_lock(&hw->aci.lock);
291 : 0 : status = ixgbe_aci_send_cmd_execute(hw, desc, buf, buf_size);
292 : 0 : last_status = hw->aci.last_status;
293 : 0 : ixgbe_release_lock(&hw->aci.lock);
294 : :
295 [ # # # # ]: 0 : if (!is_cmd_for_retry || status == IXGBE_SUCCESS ||
296 : : last_status != IXGBE_ACI_RC_EBUSY)
297 : : break;
298 : :
299 [ # # ]: 0 : if (buf)
300 : 0 : memcpy(buf, buf_cpy, buf_size);
301 : : memcpy(desc, &desc_cpy, sizeof(desc_cpy));
302 : :
303 : 0 : msec_delay(IXGBE_ACI_SEND_DELAY_TIME_MS);
304 [ # # ]: 0 : } while (++idx < IXGBE_ACI_SEND_MAX_EXECUTE);
305 : :
306 [ # # ]: 0 : if (buf_cpy)
307 : 0 : ixgbe_free(hw, buf_cpy);
308 : :
309 : : return status;
310 : : }
311 : :
312 : : /**
313 : : * ixgbe_aci_check_event_pending - check if there are any pending events
314 : : * @hw: pointer to the HW struct
315 : : *
316 : : * Determine if there are any pending events.
317 : : *
318 : : * Return: true if there are any currently pending events
319 : : * otherwise false.
320 : : */
321 : 0 : bool ixgbe_aci_check_event_pending(struct ixgbe_hw *hw)
322 : : {
323 : : u32 ep_bit_mask;
324 : : u32 fwsts;
325 : :
326 [ # # ]: 0 : ep_bit_mask = hw->bus.func ? GL_FWSTS_EP_PF1 : GL_FWSTS_EP_PF0;
327 : :
328 : : /* Check state of Event Pending (EP) bit */
329 : 0 : fwsts = IXGBE_READ_REG(hw, GL_FWSTS);
330 : 0 : return (fwsts & ep_bit_mask) ? true : false;
331 : : }
332 : :
333 : : /**
334 : : * ixgbe_aci_get_event - get an event from ACI
335 : : * @hw: pointer to the HW struct
336 : : * @e: event information structure
337 : : * @pending: optional flag signaling that there are more pending events
338 : : *
339 : : * Obtain an event from ACI and return its content
340 : : * through 'e' using ACI command (0x0014).
341 : : * Provide information if there are more events
342 : : * to retrieve through 'pending'.
343 : : *
344 : : * Return: the exit code of the operation.
345 : : */
346 : 0 : s32 ixgbe_aci_get_event(struct ixgbe_hw *hw, struct ixgbe_aci_event *e,
347 : : bool *pending)
348 : : {
349 : : struct ixgbe_aci_desc desc;
350 : : s32 status;
351 : :
352 [ # # # # : 0 : if (!e || (!e->msg_buf && e->buf_len) || (e->msg_buf && !e->buf_len))
# # # # #
# ]
353 : : return IXGBE_ERR_PARAM;
354 : :
355 : 0 : ixgbe_acquire_lock(&hw->aci.lock);
356 : :
357 : : /* Check if there are any events pending */
358 [ # # ]: 0 : if (!ixgbe_aci_check_event_pending(hw)) {
359 : : status = IXGBE_ERR_ACI_NO_EVENTS;
360 : 0 : goto aci_get_event_exit;
361 : : }
362 : :
363 : : /* Obtain pending event */
364 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_fw_event);
365 : 0 : status = ixgbe_aci_send_cmd_execute(hw, &desc, e->msg_buf, e->buf_len);
366 [ # # ]: 0 : if (status)
367 : 0 : goto aci_get_event_exit;
368 : :
369 : : /* Returned 0x0014 opcode indicates that no event was obtained */
370 [ # # ]: 0 : if (desc.opcode == IXGBE_CPU_TO_LE16(ixgbe_aci_opc_get_fw_event)) {
371 : : status = IXGBE_ERR_ACI_NO_EVENTS;
372 : 0 : goto aci_get_event_exit;
373 : : }
374 : :
375 : : /* Determine size of event data */
376 : 0 : e->msg_len = MIN_T(u16, IXGBE_LE16_TO_CPU(desc.datalen), e->buf_len);
377 : : /* Write event descriptor to event info structure */
378 [ # # ]: 0 : memcpy(&e->desc, &desc, sizeof(e->desc));
379 : :
380 : : /* Check if there are any further events pending */
381 [ # # ]: 0 : if (pending) {
382 : 0 : *pending = ixgbe_aci_check_event_pending(hw);
383 : : }
384 : :
385 : 0 : aci_get_event_exit:
386 : 0 : ixgbe_release_lock(&hw->aci.lock);
387 : :
388 : 0 : return status;
389 : : }
390 : :
391 : : /**
392 : : * ixgbe_fill_dflt_direct_cmd_desc - fill ACI descriptor with default values.
393 : : * @desc: pointer to the temp descriptor (non DMA mem)
394 : : * @opcode: the opcode can be used to decide which flags to turn off or on
395 : : *
396 : : * Helper function to fill the descriptor desc with default values
397 : : * and the provided opcode.
398 : : */
399 : 0 : void ixgbe_fill_dflt_direct_cmd_desc(struct ixgbe_aci_desc *desc, u16 opcode)
400 : : {
401 : : /* zero out the desc */
402 : : memset(desc, 0, sizeof(*desc));
403 : 0 : desc->opcode = IXGBE_CPU_TO_LE16(opcode);
404 : 0 : desc->flags = IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_SI);
405 : 0 : }
406 : :
407 : : /**
408 : : * ixgbe_aci_get_fw_ver - get the firmware version
409 : : * @hw: pointer to the HW struct
410 : : *
411 : : * Get the firmware version using ACI command (0x0001).
412 : : *
413 : : * Return: the exit code of the operation.
414 : : */
415 : 0 : s32 ixgbe_aci_get_fw_ver(struct ixgbe_hw *hw)
416 : : {
417 : : struct ixgbe_aci_cmd_get_ver *resp;
418 : : struct ixgbe_aci_desc desc;
419 : : s32 status;
420 : :
421 : : resp = &desc.params.get_ver;
422 : :
423 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_ver);
424 : :
425 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
426 : :
427 [ # # ]: 0 : if (!status) {
428 : 0 : hw->fw_branch = resp->fw_branch;
429 : 0 : hw->fw_maj_ver = resp->fw_major;
430 : 0 : hw->fw_min_ver = resp->fw_minor;
431 : 0 : hw->fw_patch = resp->fw_patch;
432 : 0 : hw->fw_build = IXGBE_LE32_TO_CPU(resp->fw_build);
433 : 0 : hw->api_branch = resp->api_branch;
434 : 0 : hw->api_maj_ver = resp->api_major;
435 : 0 : hw->api_min_ver = resp->api_minor;
436 : 0 : hw->api_patch = resp->api_patch;
437 : : }
438 : :
439 : 0 : return status;
440 : : }
441 : :
442 : : /**
443 : : * ixgbe_aci_send_driver_ver - send the driver version to firmware
444 : : * @hw: pointer to the HW struct
445 : : * @dv: driver's major, minor version
446 : : *
447 : : * Send the driver version to the firmware
448 : : * using the ACI command (0x0002).
449 : : *
450 : : * Return: the exit code of the operation.
451 : : * Returns IXGBE_ERR_PARAM, if dv is NULL.
452 : : */
453 : 0 : s32 ixgbe_aci_send_driver_ver(struct ixgbe_hw *hw, struct ixgbe_driver_ver *dv)
454 : : {
455 : : struct ixgbe_aci_cmd_driver_ver *cmd;
456 : : struct ixgbe_aci_desc desc;
457 : : u16 len;
458 : :
459 : : cmd = &desc.params.driver_ver;
460 : :
461 [ # # ]: 0 : if (!dv)
462 : : return IXGBE_ERR_PARAM;
463 : :
464 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_driver_ver);
465 : :
466 : 0 : desc.flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD);
467 : 0 : cmd->major_ver = dv->major_ver;
468 : 0 : cmd->minor_ver = dv->minor_ver;
469 : 0 : cmd->build_ver = dv->build_ver;
470 : 0 : cmd->subbuild_ver = dv->subbuild_ver;
471 : :
472 : : len = 0;
473 : 0 : while (len < sizeof(dv->driver_string) &&
474 [ # # # # : 0 : IS_ASCII(dv->driver_string[len]) && dv->driver_string[len])
# # ]
475 : 0 : len++;
476 : :
477 : 0 : return ixgbe_aci_send_cmd(hw, &desc, dv->driver_string, len);
478 : : }
479 : :
480 : : /**
481 : : * ixgbe_aci_req_res - request a common resource
482 : : * @hw: pointer to the HW struct
483 : : * @res: resource ID
484 : : * @access: access type
485 : : * @sdp_number: resource number
486 : : * @timeout: the maximum time in ms that the driver may hold the resource
487 : : *
488 : : * Requests a common resource using the ACI command (0x0008).
489 : : * Specifies the maximum time the driver may hold the resource.
490 : : * If the requested resource is currently occupied by some other driver,
491 : : * a busy return value is returned and the timeout field value indicates the
492 : : * maximum time the current owner has to free it.
493 : : *
494 : : * Return: the exit code of the operation.
495 : : */
496 : : static s32
497 : 0 : ixgbe_aci_req_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res,
498 : : enum ixgbe_aci_res_access_type access, u8 sdp_number,
499 : : u32 *timeout)
500 : : {
501 : : struct ixgbe_aci_cmd_req_res *cmd_resp;
502 : : struct ixgbe_aci_desc desc;
503 : : s32 status;
504 : :
505 : : cmd_resp = &desc.params.res_owner;
506 : :
507 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_req_res);
508 : :
509 : 0 : cmd_resp->res_id = IXGBE_CPU_TO_LE16(res);
510 : 0 : cmd_resp->access_type = IXGBE_CPU_TO_LE16(access);
511 : 0 : cmd_resp->res_number = IXGBE_CPU_TO_LE32(sdp_number);
512 : 0 : cmd_resp->timeout = IXGBE_CPU_TO_LE32(*timeout);
513 : 0 : *timeout = 0;
514 : :
515 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
516 : :
517 : : /* The completion specifies the maximum time in ms that the driver
518 : : * may hold the resource in the Timeout field.
519 : : */
520 : :
521 : : /* If the resource is held by some other driver, the command completes
522 : : * with a busy return value and the timeout field indicates the maximum
523 : : * time the current owner of the resource has to free it.
524 : : */
525 [ # # # # ]: 0 : if (!status || hw->aci.last_status == IXGBE_ACI_RC_EBUSY)
526 : 0 : *timeout = IXGBE_LE32_TO_CPU(cmd_resp->timeout);
527 : :
528 : 0 : return status;
529 : : }
530 : :
531 : : /**
532 : : * ixgbe_aci_release_res - release a common resource using ACI
533 : : * @hw: pointer to the HW struct
534 : : * @res: resource ID
535 : : * @sdp_number: resource number
536 : : *
537 : : * Release a common resource using ACI command (0x0009).
538 : : *
539 : : * Return: the exit code of the operation.
540 : : */
541 : : static s32
542 : 0 : ixgbe_aci_release_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res,
543 : : u8 sdp_number)
544 : : {
545 : : struct ixgbe_aci_cmd_req_res *cmd;
546 : : struct ixgbe_aci_desc desc;
547 : :
548 : : cmd = &desc.params.res_owner;
549 : :
550 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_release_res);
551 : :
552 : 0 : cmd->res_id = IXGBE_CPU_TO_LE16(res);
553 : 0 : cmd->res_number = IXGBE_CPU_TO_LE32(sdp_number);
554 : :
555 : 0 : return ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
556 : : }
557 : :
558 : : /**
559 : : * ixgbe_acquire_res - acquire the ownership of a resource
560 : : * @hw: pointer to the HW structure
561 : : * @res: resource ID
562 : : * @access: access type (read or write)
563 : : * @timeout: timeout in milliseconds
564 : : *
565 : : * Make an attempt to acquire the ownership of a resource using
566 : : * the ixgbe_aci_req_res to utilize ACI.
567 : : * In case if some other driver has previously acquired the resource and
568 : : * performed any necessary updates, the IXGBE_ERR_ACI_NO_WORK is returned,
569 : : * and the caller does not obtain the resource and has no further work to do.
570 : : * If needed, the function will poll until the current lock owner timeouts.
571 : : *
572 : : * Return: the exit code of the operation.
573 : : */
574 : 0 : s32 ixgbe_acquire_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res,
575 : : enum ixgbe_aci_res_access_type access, u32 timeout)
576 : : {
577 : : #define IXGBE_RES_POLLING_DELAY_MS 10
578 : : u32 delay = IXGBE_RES_POLLING_DELAY_MS;
579 : 0 : u32 res_timeout = timeout;
580 : : u32 retry_timeout = 0;
581 : : s32 status;
582 : :
583 : 0 : status = ixgbe_aci_req_res(hw, res, access, 0, &res_timeout);
584 : :
585 : : /* A return code of IXGBE_ERR_ACI_NO_WORK means that another driver has
586 : : * previously acquired the resource and performed any necessary updates;
587 : : * in this case the caller does not obtain the resource and has no
588 : : * further work to do.
589 : : */
590 [ # # ]: 0 : if (status == IXGBE_ERR_ACI_NO_WORK)
591 : 0 : goto ixgbe_acquire_res_exit;
592 : :
593 : : /* If necessary, poll until the current lock owner timeouts.
594 : : * Set retry_timeout to the timeout value reported by the FW in the
595 : : * response to the "Request Resource Ownership" (0x0008) Admin Command
596 : : * as it indicates the maximum time the current owner of the resource
597 : : * is allowed to hold it.
598 : : */
599 : 0 : retry_timeout = res_timeout;
600 [ # # # # ]: 0 : while (status && retry_timeout && res_timeout) {
601 : 0 : msec_delay(delay);
602 : : retry_timeout = (retry_timeout > delay) ?
603 [ # # ]: 0 : retry_timeout - delay : 0;
604 : 0 : status = ixgbe_aci_req_res(hw, res, access, 0, &res_timeout);
605 : :
606 [ # # ]: 0 : if (status == IXGBE_ERR_ACI_NO_WORK)
607 : : /* lock free, but no work to do */
608 : : break;
609 : :
610 [ # # ]: 0 : if (!status)
611 : : /* lock acquired */
612 : : break;
613 : : }
614 : :
615 : 0 : ixgbe_acquire_res_exit:
616 : 0 : return status;
617 : : }
618 : :
619 : : /**
620 : : * ixgbe_release_res - release a common resource
621 : : * @hw: pointer to the HW structure
622 : : * @res: resource ID
623 : : *
624 : : * Release a common resource using ixgbe_aci_release_res.
625 : : */
626 : 0 : void ixgbe_release_res(struct ixgbe_hw *hw, enum ixgbe_aci_res_ids res)
627 : : {
628 : : u32 total_delay = 0;
629 : : s32 status;
630 : :
631 : 0 : status = ixgbe_aci_release_res(hw, res, 0);
632 : :
633 : : /* There are some rare cases when trying to release the resource
634 : : * results in an admin command timeout, so handle them correctly.
635 : : */
636 : 0 : while ((status == IXGBE_ERR_ACI_TIMEOUT) &&
637 [ # # ]: 0 : (total_delay < IXGBE_ACI_RELEASE_RES_TIMEOUT)) {
638 : 0 : msec_delay(1);
639 : 0 : status = ixgbe_aci_release_res(hw, res, 0);
640 : 0 : total_delay++;
641 : : }
642 : 0 : }
643 : :
644 : : /**
645 : : * ixgbe_parse_common_caps - Parse common device/function capabilities
646 : : * @hw: pointer to the HW struct
647 : : * @caps: pointer to common capabilities structure
648 : : * @elem: the capability element to parse
649 : : * @prefix: message prefix for tracing capabilities
650 : : *
651 : : * Given a capability element, extract relevant details into the common
652 : : * capability structure.
653 : : *
654 : : * Return: true if the capability matches one of the common capability ids,
655 : : * false otherwise.
656 : : */
657 : : static bool
658 : 0 : ixgbe_parse_common_caps(struct ixgbe_hw *hw, struct ixgbe_hw_common_caps *caps,
659 : : struct ixgbe_aci_cmd_list_caps_elem *elem,
660 : : const char *prefix)
661 : : {
662 : 0 : u32 logical_id = IXGBE_LE32_TO_CPU(elem->logical_id);
663 : 0 : u32 phys_id = IXGBE_LE32_TO_CPU(elem->phys_id);
664 : 0 : u32 number = IXGBE_LE32_TO_CPU(elem->number);
665 : 0 : u16 cap = IXGBE_LE16_TO_CPU(elem->cap);
666 : : bool found = true;
667 : :
668 : : UNREFERENCED_1PARAMETER(hw);
669 : :
670 [ # # # # : 0 : switch (cap) {
# # # # #
# # # # #
# # ]
671 : 0 : case IXGBE_ACI_CAPS_VALID_FUNCTIONS:
672 : 0 : caps->valid_functions = number;
673 : 0 : break;
674 : 0 : case IXGBE_ACI_CAPS_SRIOV:
675 : 0 : caps->sr_iov_1_1 = (number == 1);
676 : 0 : break;
677 : 0 : case IXGBE_ACI_CAPS_VMDQ:
678 : 0 : caps->vmdq = (number == 1);
679 : 0 : break;
680 : 0 : case IXGBE_ACI_CAPS_DCB:
681 : 0 : caps->dcb = (number == 1);
682 : 0 : caps->active_tc_bitmap = logical_id;
683 : 0 : caps->maxtc = phys_id;
684 : 0 : break;
685 : 0 : case IXGBE_ACI_CAPS_RSS:
686 : 0 : caps->rss_table_size = number;
687 : 0 : caps->rss_table_entry_width = logical_id;
688 : 0 : break;
689 : 0 : case IXGBE_ACI_CAPS_RXQS:
690 : 0 : caps->num_rxq = number;
691 : 0 : caps->rxq_first_id = phys_id;
692 : 0 : break;
693 : 0 : case IXGBE_ACI_CAPS_TXQS:
694 : 0 : caps->num_txq = number;
695 : 0 : caps->txq_first_id = phys_id;
696 : 0 : break;
697 : 0 : case IXGBE_ACI_CAPS_MSIX:
698 : 0 : caps->num_msix_vectors = number;
699 : 0 : caps->msix_vector_first_id = phys_id;
700 : 0 : break;
701 : : case IXGBE_ACI_CAPS_NVM_VER:
702 : : break;
703 : 0 : case IXGBE_ACI_CAPS_NVM_MGMT:
704 : 0 : caps->sec_rev_disabled =
705 : : (number & IXGBE_NVM_MGMT_SEC_REV_DISABLED) ?
706 : 0 : true : false;
707 : 0 : caps->update_disabled =
708 : : (number & IXGBE_NVM_MGMT_UPDATE_DISABLED) ?
709 : 0 : true : false;
710 : 0 : caps->nvm_unified_update =
711 : : (number & IXGBE_NVM_MGMT_UNIFIED_UPD_SUPPORT) ?
712 : 0 : true : false;
713 : 0 : caps->netlist_auth =
714 : : (number & IXGBE_NVM_MGMT_NETLIST_AUTH_SUPPORT) ?
715 : 0 : true : false;
716 : 0 : break;
717 : 0 : case IXGBE_ACI_CAPS_MAX_MTU:
718 : 0 : caps->max_mtu = number;
719 : 0 : break;
720 : 0 : case IXGBE_ACI_CAPS_PCIE_RESET_AVOIDANCE:
721 : 0 : caps->pcie_reset_avoidance = (number > 0);
722 : 0 : break;
723 : 0 : case IXGBE_ACI_CAPS_POST_UPDATE_RESET_RESTRICT:
724 : 0 : caps->reset_restrict_support = (number == 1);
725 : 0 : break;
726 : 0 : case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG0:
727 : : case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG1:
728 : : case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG2:
729 : : case IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG3:
730 : : {
731 : 0 : u8 index = cap - IXGBE_ACI_CAPS_EXT_TOPO_DEV_IMG0;
732 : :
733 : 0 : caps->ext_topo_dev_img_ver_high[index] = number;
734 : 0 : caps->ext_topo_dev_img_ver_low[index] = logical_id;
735 : 0 : caps->ext_topo_dev_img_part_num[index] =
736 : 0 : (phys_id & IXGBE_EXT_TOPO_DEV_IMG_PART_NUM_M) >>
737 : : IXGBE_EXT_TOPO_DEV_IMG_PART_NUM_S;
738 : 0 : caps->ext_topo_dev_img_load_en[index] =
739 : 0 : (phys_id & IXGBE_EXT_TOPO_DEV_IMG_LOAD_EN) != 0;
740 : 0 : caps->ext_topo_dev_img_prog_en[index] =
741 : 0 : (phys_id & IXGBE_EXT_TOPO_DEV_IMG_PROG_EN) != 0;
742 : 0 : break;
743 : : }
744 : :
745 : 0 : case IXGBE_ACI_CAPS_NEXT_CLUSTER_ID:
746 : 0 : caps->next_cluster_id_support = (number == 1);
747 : 0 : DEBUGOUT2("%s: next_cluster_id_support = %d\n",
748 : : prefix, caps->next_cluster_id_support);
749 : 0 : break;
750 : 0 : default:
751 : : /* Not one of the recognized common capabilities */
752 : : found = false;
753 : : }
754 : :
755 : 0 : return found;
756 : : }
757 : :
758 : : /**
759 : : * ixgbe_hweight8 - count set bits among the 8 lowest bits
760 : : * @w: variable storing set bits to count
761 : : *
762 : : * Return: the number of set bits among the 8 lowest bits in the provided value.
763 : : */
764 : : static u8 ixgbe_hweight8(u32 w)
765 : : {
766 : : u8 hweight = 0, i;
767 : :
768 [ # # ]: 0 : for (i = 0; i < 8; i++)
769 [ # # ]: 0 : if (w & (1 << i))
770 : 0 : hweight++;
771 : :
772 : : return hweight;
773 : : }
774 : :
775 : : /**
776 : : * ixgbe_hweight32 - count set bits among the 32 lowest bits
777 : : * @w: variable storing set bits to count
778 : : *
779 : : * Return: the number of set bits among the 32 lowest bits in the
780 : : * provided value.
781 : : */
782 : : static u8 ixgbe_hweight32(u32 w)
783 : : {
784 : : u32 bitMask = 0x1, i;
785 : : u8 bitCnt = 0;
786 : :
787 [ # # ]: 0 : for (i = 0; i < 32; i++)
788 : : {
789 [ # # ]: 0 : if (w & bitMask)
790 : 0 : bitCnt++;
791 : :
792 : 0 : bitMask = bitMask << 0x1;
793 : : }
794 : :
795 : : return bitCnt;
796 : : }
797 : :
798 : : /**
799 : : * ixgbe_func_id_to_logical_id - map from function id to logical pf id
800 : : * @active_function_bitmap: active function bitmap
801 : : * @pf_id: function number of device
802 : : *
803 : : * Return: the logical id of a function mapped by the provided pf_id.
804 : : */
805 : : static int ixgbe_func_id_to_logical_id(u32 active_function_bitmap, u8 pf_id)
806 : : {
807 : : u8 logical_id = 0;
808 : : u8 i;
809 : :
810 [ # # ]: 0 : for (i = 0; i < pf_id; i++)
811 [ # # ]: 0 : if (active_function_bitmap & BIT(i))
812 : 0 : logical_id++;
813 : :
814 : : return logical_id;
815 : : }
816 : :
817 : : /**
818 : : * ixgbe_parse_valid_functions_cap - Parse IXGBE_ACI_CAPS_VALID_FUNCTIONS caps
819 : : * @hw: pointer to the HW struct
820 : : * @dev_p: pointer to device capabilities structure
821 : : * @cap: capability element to parse
822 : : *
823 : : * Parse IXGBE_ACI_CAPS_VALID_FUNCTIONS for device capabilities.
824 : : */
825 : : static void
826 : : ixgbe_parse_valid_functions_cap(struct ixgbe_hw *hw,
827 : : struct ixgbe_hw_dev_caps *dev_p,
828 : : struct ixgbe_aci_cmd_list_caps_elem *cap)
829 : : {
830 : 0 : u32 number = IXGBE_LE32_TO_CPU(cap->number);
831 : :
832 : : UNREFERENCED_1PARAMETER(hw);
833 : :
834 : 0 : dev_p->num_funcs = ixgbe_hweight32(number);
835 : :
836 : 0 : hw->logical_pf_id = ixgbe_func_id_to_logical_id(number, hw->pf_id);
837 : 0 : }
838 : :
839 : : /**
840 : : * ixgbe_parse_vf_dev_caps - Parse IXGBE_ACI_CAPS_VF device caps
841 : : * @hw: pointer to the HW struct
842 : : * @dev_p: pointer to device capabilities structure
843 : : * @cap: capability element to parse
844 : : *
845 : : * Parse IXGBE_ACI_CAPS_VF for device capabilities.
846 : : */
847 : : static void ixgbe_parse_vf_dev_caps(struct ixgbe_hw *hw,
848 : : struct ixgbe_hw_dev_caps *dev_p,
849 : : struct ixgbe_aci_cmd_list_caps_elem *cap)
850 : : {
851 : 0 : u32 number = IXGBE_LE32_TO_CPU(cap->number);
852 : :
853 : : UNREFERENCED_1PARAMETER(hw);
854 : :
855 : 0 : dev_p->num_vfs_exposed = number;
856 : 0 : }
857 : :
858 : : /**
859 : : * ixgbe_parse_vsi_dev_caps - Parse IXGBE_ACI_CAPS_VSI device caps
860 : : * @hw: pointer to the HW struct
861 : : * @dev_p: pointer to device capabilities structure
862 : : * @cap: capability element to parse
863 : : *
864 : : * Parse IXGBE_ACI_CAPS_VSI for device capabilities.
865 : : */
866 : : static void ixgbe_parse_vsi_dev_caps(struct ixgbe_hw *hw,
867 : : struct ixgbe_hw_dev_caps *dev_p,
868 : : struct ixgbe_aci_cmd_list_caps_elem *cap)
869 : : {
870 : 0 : u32 number = IXGBE_LE32_TO_CPU(cap->number);
871 : :
872 : : UNREFERENCED_1PARAMETER(hw);
873 : :
874 : 0 : dev_p->num_vsi_allocd_to_host = number;
875 : 0 : }
876 : :
877 : : /**
878 : : * ixgbe_parse_1588_dev_caps - Parse IXGBE_ACI_CAPS_1588 device caps
879 : : * @hw: pointer to the HW struct
880 : : * @dev_p: pointer to device capabilities structure
881 : : * @cap: capability element to parse
882 : : *
883 : : * Parse IXGBE_ACI_CAPS_1588 for device capabilities.
884 : : */
885 : 0 : static void ixgbe_parse_1588_dev_caps(struct ixgbe_hw *hw,
886 : : struct ixgbe_hw_dev_caps *dev_p,
887 : : struct ixgbe_aci_cmd_list_caps_elem *cap)
888 : : {
889 : : struct ixgbe_ts_dev_info *info = &dev_p->ts_dev_info;
890 : 0 : u32 logical_id = IXGBE_LE32_TO_CPU(cap->logical_id);
891 : 0 : u32 phys_id = IXGBE_LE32_TO_CPU(cap->phys_id);
892 : 0 : u32 number = IXGBE_LE32_TO_CPU(cap->number);
893 : :
894 : : UNREFERENCED_1PARAMETER(hw);
895 : :
896 : 0 : info->ena = ((number & IXGBE_TS_DEV_ENA_M) != 0);
897 : 0 : dev_p->common_cap.ieee_1588 = info->ena;
898 : :
899 : 0 : info->tmr0_owner = number & IXGBE_TS_TMR0_OWNR_M;
900 : 0 : info->tmr0_owned = ((number & IXGBE_TS_TMR0_OWND_M) != 0);
901 : 0 : info->tmr0_ena = ((number & IXGBE_TS_TMR0_ENA_M) != 0);
902 : :
903 : 0 : info->tmr1_owner = (number & IXGBE_TS_TMR1_OWNR_M) >>
904 : : IXGBE_TS_TMR1_OWNR_S;
905 : 0 : info->tmr1_owned = ((number & IXGBE_TS_TMR1_OWND_M) != 0);
906 : 0 : info->tmr1_ena = ((number & IXGBE_TS_TMR1_ENA_M) != 0);
907 : :
908 : 0 : info->ena_ports = logical_id;
909 : 0 : info->tmr_own_map = phys_id;
910 : :
911 : 0 : }
912 : :
913 : : /**
914 : : * ixgbe_parse_fdir_dev_caps - Parse IXGBE_ACI_CAPS_FD device caps
915 : : * @hw: pointer to the HW struct
916 : : * @dev_p: pointer to device capabilities structure
917 : : * @cap: capability element to parse
918 : : *
919 : : * Parse IXGBE_ACI_CAPS_FD for device capabilities.
920 : : */
921 : : static void ixgbe_parse_fdir_dev_caps(struct ixgbe_hw *hw,
922 : : struct ixgbe_hw_dev_caps *dev_p,
923 : : struct ixgbe_aci_cmd_list_caps_elem *cap)
924 : : {
925 : 0 : u32 number = IXGBE_LE32_TO_CPU(cap->number);
926 : :
927 : : UNREFERENCED_1PARAMETER(hw);
928 : :
929 : 0 : dev_p->num_flow_director_fltr = number;
930 : 0 : }
931 : :
932 : : /**
933 : : * ixgbe_parse_dev_caps - Parse device capabilities
934 : : * @hw: pointer to the HW struct
935 : : * @dev_p: pointer to device capabilities structure
936 : : * @buf: buffer containing the device capability records
937 : : * @cap_count: the number of capabilities
938 : : *
939 : : * Helper device to parse device (0x000B) capabilities list. For
940 : : * capabilities shared between device and function, this relies on
941 : : * ixgbe_parse_common_caps.
942 : : *
943 : : * Loop through the list of provided capabilities and extract the relevant
944 : : * data into the device capabilities structured.
945 : : */
946 : 0 : static void ixgbe_parse_dev_caps(struct ixgbe_hw *hw,
947 : : struct ixgbe_hw_dev_caps *dev_p,
948 : : void *buf, u32 cap_count)
949 : : {
950 : : struct ixgbe_aci_cmd_list_caps_elem *cap_resp;
951 : : u32 i;
952 : :
953 : : cap_resp = (struct ixgbe_aci_cmd_list_caps_elem *)buf;
954 : :
955 : : memset(dev_p, 0, sizeof(*dev_p));
956 : :
957 [ # # ]: 0 : for (i = 0; i < cap_count; i++) {
958 : 0 : u16 cap = IXGBE_LE16_TO_CPU(cap_resp[i].cap);
959 : : bool found;
960 : :
961 : 0 : found = ixgbe_parse_common_caps(hw, &dev_p->common_cap,
962 : : &cap_resp[i], "dev caps");
963 : :
964 [ # # # # : 0 : switch (cap) {
# # ]
965 : 0 : case IXGBE_ACI_CAPS_VALID_FUNCTIONS:
966 : : ixgbe_parse_valid_functions_cap(hw, dev_p,
967 : : &cap_resp[i]);
968 : : break;
969 : 0 : case IXGBE_ACI_CAPS_VF:
970 : : ixgbe_parse_vf_dev_caps(hw, dev_p, &cap_resp[i]);
971 : : break;
972 : 0 : case IXGBE_ACI_CAPS_VSI:
973 : : ixgbe_parse_vsi_dev_caps(hw, dev_p, &cap_resp[i]);
974 : : break;
975 : 0 : case IXGBE_ACI_CAPS_1588:
976 : 0 : ixgbe_parse_1588_dev_caps(hw, dev_p, &cap_resp[i]);
977 : 0 : break;
978 : 0 : case IXGBE_ACI_CAPS_FD:
979 : : ixgbe_parse_fdir_dev_caps(hw, dev_p, &cap_resp[i]);
980 : : break;
981 : : default:
982 : : /* Don't list common capabilities as unknown */
983 : : if (!found)
984 : : break;
985 : : }
986 : : }
987 : :
988 : 0 : }
989 : :
990 : : /**
991 : : * ixgbe_parse_vf_func_caps - Parse IXGBE_ACI_CAPS_VF function caps
992 : : * @hw: pointer to the HW struct
993 : : * @func_p: pointer to function capabilities structure
994 : : * @cap: pointer to the capability element to parse
995 : : *
996 : : * Extract function capabilities for IXGBE_ACI_CAPS_VF.
997 : : */
998 : : static void ixgbe_parse_vf_func_caps(struct ixgbe_hw *hw,
999 : : struct ixgbe_hw_func_caps *func_p,
1000 : : struct ixgbe_aci_cmd_list_caps_elem *cap)
1001 : : {
1002 : 0 : u32 logical_id = IXGBE_LE32_TO_CPU(cap->logical_id);
1003 : 0 : u32 number = IXGBE_LE32_TO_CPU(cap->number);
1004 : :
1005 : : UNREFERENCED_1PARAMETER(hw);
1006 : :
1007 : 0 : func_p->num_allocd_vfs = number;
1008 : 0 : func_p->vf_base_id = logical_id;
1009 : 0 : }
1010 : :
1011 : : /**
1012 : : * ixgbe_get_num_per_func - determine number of resources per PF
1013 : : * @hw: pointer to the HW structure
1014 : : * @max: value to be evenly split between each PF
1015 : : *
1016 : : * Determine the number of valid functions by going through the bitmap returned
1017 : : * from parsing capabilities and use this to calculate the number of resources
1018 : : * per PF based on the max value passed in.
1019 : : *
1020 : : * Return: the number of resources per PF or 0, if no PH are available.
1021 : : */
1022 : : static u32 ixgbe_get_num_per_func(struct ixgbe_hw *hw, u32 max)
1023 : : {
1024 : : u8 funcs;
1025 : :
1026 : : #define IXGBE_CAPS_VALID_FUNCS_M 0xFF
1027 : 0 : funcs = ixgbe_hweight8(hw->dev_caps.common_cap.valid_functions &
1028 : : IXGBE_CAPS_VALID_FUNCS_M);
1029 : :
1030 [ # # ]: 0 : if (!funcs)
1031 : : return 0;
1032 : :
1033 : 0 : return max / funcs;
1034 : : }
1035 : :
1036 : : /**
1037 : : * ixgbe_parse_vsi_func_caps - Parse IXGBE_ACI_CAPS_VSI function caps
1038 : : * @hw: pointer to the HW struct
1039 : : * @func_p: pointer to function capabilities structure
1040 : : * @cap: pointer to the capability element to parse
1041 : : *
1042 : : * Extract function capabilities for IXGBE_ACI_CAPS_VSI.
1043 : : */
1044 : : static void ixgbe_parse_vsi_func_caps(struct ixgbe_hw *hw,
1045 : : struct ixgbe_hw_func_caps *func_p,
1046 : : struct ixgbe_aci_cmd_list_caps_elem *cap)
1047 : : {
1048 : 0 : func_p->guar_num_vsi = ixgbe_get_num_per_func(hw, IXGBE_MAX_VSI);
1049 : 0 : }
1050 : :
1051 : : /**
1052 : : * ixgbe_parse_1588_func_caps - Parse IXGBE_ACI_CAPS_1588 function caps
1053 : : * @hw: pointer to the HW struct
1054 : : * @func_p: pointer to function capabilities structure
1055 : : * @cap: pointer to the capability element to parse
1056 : : *
1057 : : * Extract function capabilities for IXGBE_ACI_CAPS_1588.
1058 : : */
1059 : 0 : static void ixgbe_parse_1588_func_caps(struct ixgbe_hw *hw,
1060 : : struct ixgbe_hw_func_caps *func_p,
1061 : : struct ixgbe_aci_cmd_list_caps_elem *cap)
1062 : : {
1063 : : struct ixgbe_ts_func_info *info = &func_p->ts_func_info;
1064 : 0 : u32 number = IXGBE_LE32_TO_CPU(cap->number);
1065 : :
1066 : : UNREFERENCED_1PARAMETER(hw);
1067 : :
1068 : 0 : info->ena = ((number & IXGBE_TS_FUNC_ENA_M) != 0);
1069 : 0 : func_p->common_cap.ieee_1588 = info->ena;
1070 : :
1071 : 0 : info->src_tmr_owned = ((number & IXGBE_TS_SRC_TMR_OWND_M) != 0);
1072 : 0 : info->tmr_ena = ((number & IXGBE_TS_TMR_ENA_M) != 0);
1073 : 0 : info->tmr_index_owned = ((number & IXGBE_TS_TMR_IDX_OWND_M) != 0);
1074 : 0 : info->tmr_index_assoc = ((number & IXGBE_TS_TMR_IDX_ASSOC_M) != 0);
1075 : :
1076 : 0 : info->clk_freq = (number & IXGBE_TS_CLK_FREQ_M) >> IXGBE_TS_CLK_FREQ_S;
1077 : 0 : info->clk_src = ((number & IXGBE_TS_CLK_SRC_M) != 0);
1078 : :
1079 [ # # ]: 0 : if (info->clk_freq < NUM_IXGBE_TIME_REF_FREQ) {
1080 : 0 : info->time_ref = (enum ixgbe_time_ref_freq)info->clk_freq;
1081 : : } else {
1082 : : /* Unknown clock frequency, so assume a (probably incorrect)
1083 : : * default to avoid out-of-bounds look ups of frequency
1084 : : * related information.
1085 : : */
1086 : 0 : info->time_ref = IXGBE_TIME_REF_FREQ_25_000;
1087 : : }
1088 : :
1089 : 0 : }
1090 : : /**
1091 : : * ixgbe_parse_func_caps - Parse function capabilities
1092 : : * @hw: pointer to the HW struct
1093 : : * @func_p: pointer to function capabilities structure
1094 : : * @buf: buffer containing the function capability records
1095 : : * @cap_count: the number of capabilities
1096 : : *
1097 : : * Helper function to parse function (0x000A) capabilities list. For
1098 : : * capabilities shared between device and function, this relies on
1099 : : * ixgbe_parse_common_caps.
1100 : : *
1101 : : * Loop through the list of provided capabilities and extract the relevant
1102 : : * data into the function capabilities structured.
1103 : : */
1104 : 0 : static void ixgbe_parse_func_caps(struct ixgbe_hw *hw,
1105 : : struct ixgbe_hw_func_caps *func_p,
1106 : : void *buf, u32 cap_count)
1107 : : {
1108 : : struct ixgbe_aci_cmd_list_caps_elem *cap_resp;
1109 : : u32 i;
1110 : :
1111 : : cap_resp = (struct ixgbe_aci_cmd_list_caps_elem *)buf;
1112 : :
1113 : : memset(func_p, 0, sizeof(*func_p));
1114 : :
1115 [ # # ]: 0 : for (i = 0; i < cap_count; i++) {
1116 : 0 : u16 cap = IXGBE_LE16_TO_CPU(cap_resp[i].cap);
1117 : :
1118 : 0 : ixgbe_parse_common_caps(hw, &func_p->common_cap,
1119 : : &cap_resp[i], "func caps");
1120 : :
1121 [ # # # # ]: 0 : switch (cap) {
1122 : 0 : case IXGBE_ACI_CAPS_VF:
1123 : : ixgbe_parse_vf_func_caps(hw, func_p, &cap_resp[i]);
1124 : : break;
1125 : 0 : case IXGBE_ACI_CAPS_VSI:
1126 : : ixgbe_parse_vsi_func_caps(hw, func_p, &cap_resp[i]);
1127 : : break;
1128 : 0 : case IXGBE_ACI_CAPS_1588:
1129 : 0 : ixgbe_parse_1588_func_caps(hw, func_p, &cap_resp[i]);
1130 : 0 : break;
1131 : : default:
1132 : : /* Don't list common capabilities as unknown */
1133 : : break;
1134 : : }
1135 : : }
1136 : :
1137 : 0 : }
1138 : :
1139 : : /**
1140 : : * ixgbe_aci_list_caps - query function/device capabilities
1141 : : * @hw: pointer to the HW struct
1142 : : * @buf: a buffer to hold the capabilities
1143 : : * @buf_size: size of the buffer
1144 : : * @cap_count: if not NULL, set to the number of capabilities reported
1145 : : * @opc: capabilities type to discover, device or function
1146 : : *
1147 : : * Get the function (0x000A) or device (0x000B) capabilities description from
1148 : : * firmware and store it in the buffer.
1149 : : *
1150 : : * If the cap_count pointer is not NULL, then it is set to the number of
1151 : : * capabilities firmware will report. Note that if the buffer size is too
1152 : : * small, it is possible the command will return IXGBE_ERR_OUT_OF_MEM. The
1153 : : * cap_count will still be updated in this case. It is recommended that the
1154 : : * buffer size be set to IXGBE_ACI_MAX_BUFFER_SIZE (the largest possible
1155 : : * buffer that firmware could return) to avoid this.
1156 : : *
1157 : : * Return: the exit code of the operation.
1158 : : * Exit code of IXGBE_ERR_OUT_OF_MEM means the buffer size is too small.
1159 : : */
1160 : 0 : s32 ixgbe_aci_list_caps(struct ixgbe_hw *hw, void *buf, u16 buf_size,
1161 : : u32 *cap_count, enum ixgbe_aci_opc opc)
1162 : : {
1163 : : struct ixgbe_aci_cmd_list_caps *cmd;
1164 : : struct ixgbe_aci_desc desc;
1165 : : s32 status;
1166 : :
1167 : : cmd = &desc.params.get_cap;
1168 : :
1169 [ # # ]: 0 : if (opc != ixgbe_aci_opc_list_func_caps &&
1170 : : opc != ixgbe_aci_opc_list_dev_caps)
1171 : : return IXGBE_ERR_PARAM;
1172 : :
1173 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, opc);
1174 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, buf, buf_size);
1175 : :
1176 [ # # ]: 0 : if (cap_count)
1177 : 0 : *cap_count = IXGBE_LE32_TO_CPU(cmd->count);
1178 : :
1179 : : return status;
1180 : : }
1181 : :
1182 : : /**
1183 : : * ixgbe_discover_dev_caps - Read and extract device capabilities
1184 : : * @hw: pointer to the hardware structure
1185 : : * @dev_caps: pointer to device capabilities structure
1186 : : *
1187 : : * Read the device capabilities and extract them into the dev_caps structure
1188 : : * for later use.
1189 : : *
1190 : : * Return: the exit code of the operation.
1191 : : */
1192 : 0 : s32 ixgbe_discover_dev_caps(struct ixgbe_hw *hw,
1193 : : struct ixgbe_hw_dev_caps *dev_caps)
1194 : : {
1195 : 0 : u32 status, cap_count = 0;
1196 : : u8 *cbuf = NULL;
1197 : :
1198 : 0 : cbuf = (u8*)ixgbe_malloc(hw, IXGBE_ACI_MAX_BUFFER_SIZE);
1199 [ # # ]: 0 : if (!cbuf)
1200 : : return IXGBE_ERR_OUT_OF_MEM;
1201 : : /* Although the driver doesn't know the number of capabilities the
1202 : : * device will return, we can simply send a 4KB buffer, the maximum
1203 : : * possible size that firmware can return.
1204 : : */
1205 : 0 : cap_count = IXGBE_ACI_MAX_BUFFER_SIZE /
1206 : : sizeof(struct ixgbe_aci_cmd_list_caps_elem);
1207 : :
1208 : 0 : status = ixgbe_aci_list_caps(hw, cbuf, IXGBE_ACI_MAX_BUFFER_SIZE,
1209 : : &cap_count,
1210 : : ixgbe_aci_opc_list_dev_caps);
1211 [ # # ]: 0 : if (!status)
1212 : 0 : ixgbe_parse_dev_caps(hw, dev_caps, cbuf, cap_count);
1213 : :
1214 : : if (cbuf)
1215 : 0 : ixgbe_free(hw, cbuf);
1216 : :
1217 : 0 : return status;
1218 : : }
1219 : :
1220 : : /**
1221 : : * ixgbe_discover_func_caps - Read and extract function capabilities
1222 : : * @hw: pointer to the hardware structure
1223 : : * @func_caps: pointer to function capabilities structure
1224 : : *
1225 : : * Read the function capabilities and extract them into the func_caps structure
1226 : : * for later use.
1227 : : *
1228 : : * Return: the exit code of the operation.
1229 : : */
1230 : 0 : s32 ixgbe_discover_func_caps(struct ixgbe_hw *hw,
1231 : : struct ixgbe_hw_func_caps *func_caps)
1232 : : {
1233 : 0 : u32 cap_count = 0;
1234 : : u8 *cbuf = NULL;
1235 : : s32 status;
1236 : :
1237 : 0 : cbuf = (u8*)ixgbe_malloc(hw, IXGBE_ACI_MAX_BUFFER_SIZE);
1238 [ # # ]: 0 : if(!cbuf)
1239 : : return IXGBE_ERR_OUT_OF_MEM;
1240 : : /* Although the driver doesn't know the number of capabilities the
1241 : : * device will return, we can simply send a 4KB buffer, the maximum
1242 : : * possible size that firmware can return.
1243 : : */
1244 : 0 : cap_count = IXGBE_ACI_MAX_BUFFER_SIZE /
1245 : : sizeof(struct ixgbe_aci_cmd_list_caps_elem);
1246 : :
1247 : 0 : status = ixgbe_aci_list_caps(hw, cbuf, IXGBE_ACI_MAX_BUFFER_SIZE,
1248 : : &cap_count,
1249 : : ixgbe_aci_opc_list_func_caps);
1250 [ # # ]: 0 : if (!status)
1251 : 0 : ixgbe_parse_func_caps(hw, func_caps, cbuf, cap_count);
1252 : :
1253 : : if (cbuf)
1254 : 0 : ixgbe_free(hw, cbuf);
1255 : :
1256 : 0 : return status;
1257 : : }
1258 : :
1259 : : /**
1260 : : * ixgbe_get_caps - get info about the HW
1261 : : * @hw: pointer to the hardware structure
1262 : : *
1263 : : * Retrieve both device and function capabilities.
1264 : : *
1265 : : * Return: the exit code of the operation.
1266 : : */
1267 : 0 : s32 ixgbe_get_caps(struct ixgbe_hw *hw)
1268 : : {
1269 : : s32 status;
1270 : :
1271 : 0 : status = ixgbe_discover_dev_caps(hw, &hw->dev_caps);
1272 [ # # ]: 0 : if (status)
1273 : : return status;
1274 : :
1275 : 0 : return ixgbe_discover_func_caps(hw, &hw->func_caps);
1276 : : }
1277 : :
1278 : : /**
1279 : : * ixgbe_aci_disable_rxen - disable RX
1280 : : * @hw: pointer to the HW struct
1281 : : *
1282 : : * Request a safe disable of Receive Enable using ACI command (0x000C).
1283 : : *
1284 : : * Return: the exit code of the operation.
1285 : : */
1286 : 0 : s32 ixgbe_aci_disable_rxen(struct ixgbe_hw *hw)
1287 : : {
1288 : : struct ixgbe_aci_cmd_disable_rxen *cmd;
1289 : : struct ixgbe_aci_desc desc;
1290 : :
1291 : : UNREFERENCED_1PARAMETER(hw);
1292 : :
1293 : : cmd = &desc.params.disable_rxen;
1294 : :
1295 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_disable_rxen);
1296 : :
1297 : 0 : cmd->lport_num = (u8)hw->bus.func;
1298 : :
1299 : 0 : return ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
1300 : : }
1301 : :
1302 : : /**
1303 : : * ixgbe_aci_get_phy_caps - returns PHY capabilities
1304 : : * @hw: pointer to the HW struct
1305 : : * @qual_mods: report qualified modules
1306 : : * @report_mode: report mode capabilities
1307 : : * @pcaps: structure for PHY capabilities to be filled
1308 : : *
1309 : : * Returns the various PHY capabilities supported on the Port
1310 : : * using ACI command (0x0600).
1311 : : *
1312 : : * Return: the exit code of the operation.
1313 : : */
1314 : 0 : s32 ixgbe_aci_get_phy_caps(struct ixgbe_hw *hw, bool qual_mods, u8 report_mode,
1315 : : struct ixgbe_aci_cmd_get_phy_caps_data *pcaps)
1316 : : {
1317 : : struct ixgbe_aci_cmd_get_phy_caps *cmd;
1318 : : u16 pcaps_size = sizeof(*pcaps);
1319 : : struct ixgbe_aci_desc desc;
1320 : : s32 status;
1321 : :
1322 : : cmd = &desc.params.get_phy;
1323 : :
1324 [ # # # # ]: 0 : if (!pcaps || (report_mode & ~IXGBE_ACI_REPORT_MODE_M))
1325 : : return IXGBE_ERR_PARAM;
1326 : :
1327 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_phy_caps);
1328 : :
1329 [ # # ]: 0 : if (qual_mods)
1330 : 0 : cmd->param0 |= IXGBE_CPU_TO_LE16(IXGBE_ACI_GET_PHY_RQM);
1331 : :
1332 : 0 : cmd->param0 |= IXGBE_CPU_TO_LE16(report_mode);
1333 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, pcaps, pcaps_size);
1334 : :
1335 : 0 : if (status == IXGBE_SUCCESS &&
1336 [ # # ]: 0 : report_mode == IXGBE_ACI_REPORT_TOPO_CAP_MEDIA) {
1337 : 0 : hw->phy.phy_type_low = IXGBE_LE64_TO_CPU(pcaps->phy_type_low);
1338 : 0 : hw->phy.phy_type_high = IXGBE_LE64_TO_CPU(pcaps->phy_type_high);
1339 : 0 : memcpy(hw->link.link_info.module_type, &pcaps->module_type,
1340 : : sizeof(hw->link.link_info.module_type));
1341 : : }
1342 : :
1343 : : return status;
1344 : : }
1345 : :
1346 : : /**
1347 : : * ixgbe_phy_caps_equals_cfg - check if capabilities match the PHY config
1348 : : * @phy_caps: PHY capabilities
1349 : : * @phy_cfg: PHY configuration
1350 : : *
1351 : : * Helper function to determine if PHY capabilities match PHY
1352 : : * configuration
1353 : : *
1354 : : * Return: true if PHY capabilities match PHY configuration.
1355 : : */
1356 : : bool
1357 : 0 : ixgbe_phy_caps_equals_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *phy_caps,
1358 : : struct ixgbe_aci_cmd_set_phy_cfg_data *phy_cfg)
1359 : : {
1360 : : u8 caps_mask, cfg_mask;
1361 : :
1362 [ # # ]: 0 : if (!phy_caps || !phy_cfg)
1363 : : return false;
1364 : :
1365 : : /* These bits are not common between capabilities and configuration.
1366 : : * Do not use them to determine equality.
1367 : : */
1368 : : caps_mask = IXGBE_ACI_PHY_CAPS_MASK & ~(IXGBE_ACI_PHY_AN_MODE |
1369 : : IXGBE_ACI_PHY_EN_MOD_QUAL);
1370 : : cfg_mask = IXGBE_ACI_PHY_ENA_VALID_MASK &
1371 : : ~IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT;
1372 : :
1373 [ # # ]: 0 : if (phy_caps->phy_type_low != phy_cfg->phy_type_low ||
1374 [ # # ]: 0 : phy_caps->phy_type_high != phy_cfg->phy_type_high ||
1375 [ # # ]: 0 : ((phy_caps->caps & caps_mask) != (phy_cfg->caps & cfg_mask)) ||
1376 [ # # ]: 0 : phy_caps->low_power_ctrl_an != phy_cfg->low_power_ctrl_an ||
1377 : 0 : phy_caps->eee_cap != phy_cfg->eee_cap ||
1378 [ # # ]: 0 : phy_caps->eeer_value != phy_cfg->eeer_value ||
1379 [ # # ]: 0 : phy_caps->link_fec_options != phy_cfg->link_fec_opt)
1380 : 0 : return false;
1381 : :
1382 : : return true;
1383 : : }
1384 : :
1385 : : /**
1386 : : * ixgbe_copy_phy_caps_to_cfg - Copy PHY ability data to configuration data
1387 : : * @caps: PHY ability structure to copy data from
1388 : : * @cfg: PHY configuration structure to copy data to
1389 : : *
1390 : : * Helper function to copy data from PHY capabilities data structure
1391 : : * to PHY configuration data structure
1392 : : */
1393 : 0 : void ixgbe_copy_phy_caps_to_cfg(struct ixgbe_aci_cmd_get_phy_caps_data *caps,
1394 : : struct ixgbe_aci_cmd_set_phy_cfg_data *cfg)
1395 : : {
1396 [ # # ]: 0 : if (!caps || !cfg)
1397 : : return;
1398 : :
1399 : : memset(cfg, 0, sizeof(*cfg));
1400 : 0 : cfg->phy_type_low = caps->phy_type_low;
1401 : 0 : cfg->phy_type_high = caps->phy_type_high;
1402 : 0 : cfg->caps = caps->caps;
1403 : 0 : cfg->low_power_ctrl_an = caps->low_power_ctrl_an;
1404 : 0 : cfg->eee_cap = caps->eee_cap;
1405 : 0 : cfg->eeer_value = caps->eeer_value;
1406 : 0 : cfg->link_fec_opt = caps->link_fec_options;
1407 : 0 : cfg->module_compliance_enforcement =
1408 : 0 : caps->module_compliance_enforcement;
1409 : : }
1410 : :
1411 : : /**
1412 : : * ixgbe_aci_set_phy_cfg - set PHY configuration
1413 : : * @hw: pointer to the HW struct
1414 : : * @cfg: structure with PHY configuration data to be set
1415 : : *
1416 : : * Set the various PHY configuration parameters supported on the Port
1417 : : * using ACI command (0x0601).
1418 : : * One or more of the Set PHY config parameters may be ignored in an MFP
1419 : : * mode as the PF may not have the privilege to set some of the PHY Config
1420 : : * parameters.
1421 : : *
1422 : : * Return: the exit code of the operation.
1423 : : */
1424 : 0 : s32 ixgbe_aci_set_phy_cfg(struct ixgbe_hw *hw,
1425 : : struct ixgbe_aci_cmd_set_phy_cfg_data *cfg)
1426 : : {
1427 : : struct ixgbe_aci_desc desc;
1428 : : s32 status;
1429 : :
1430 [ # # ]: 0 : if (!cfg)
1431 : : return IXGBE_ERR_PARAM;
1432 : :
1433 : : /* Ensure that only valid bits of cfg->caps can be turned on. */
1434 [ # # ]: 0 : if (cfg->caps & ~IXGBE_ACI_PHY_ENA_VALID_MASK) {
1435 : 0 : cfg->caps &= IXGBE_ACI_PHY_ENA_VALID_MASK;
1436 : : }
1437 : :
1438 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_phy_cfg);
1439 : 0 : desc.flags |= IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD);
1440 : :
1441 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, cfg, sizeof(*cfg));
1442 : :
1443 [ # # ]: 0 : if (!status)
1444 : 0 : hw->phy.curr_user_phy_cfg = *cfg;
1445 : :
1446 : : return status;
1447 : : }
1448 : :
1449 : : /**
1450 : : * ixgbe_aci_set_link_restart_an - set up link and restart AN
1451 : : * @hw: pointer to the HW struct
1452 : : * @ena_link: if true: enable link, if false: disable link
1453 : : *
1454 : : * Function sets up the link and restarts the Auto-Negotiation over the link.
1455 : : *
1456 : : * Return: the exit code of the operation.
1457 : : */
1458 : 0 : s32 ixgbe_aci_set_link_restart_an(struct ixgbe_hw *hw, bool ena_link)
1459 : : {
1460 : : struct ixgbe_aci_cmd_restart_an *cmd;
1461 : : struct ixgbe_aci_desc desc;
1462 : :
1463 : : cmd = &desc.params.restart_an;
1464 : :
1465 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_restart_an);
1466 : :
1467 : 0 : cmd->cmd_flags = IXGBE_ACI_RESTART_AN_LINK_RESTART;
1468 [ # # ]: 0 : if (ena_link)
1469 : 0 : cmd->cmd_flags |= IXGBE_ACI_RESTART_AN_LINK_ENABLE;
1470 : : else
1471 : : cmd->cmd_flags &= ~IXGBE_ACI_RESTART_AN_LINK_ENABLE;
1472 : :
1473 : 0 : return ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
1474 : : }
1475 : :
1476 : : /**
1477 : : * ixgbe_is_media_cage_present - check if media cage is present
1478 : : * @hw: pointer to the HW struct
1479 : : *
1480 : : * Identify presence of media cage using the ACI command (0x06E0).
1481 : : *
1482 : : * Return: true if media cage is present, else false. If no cage, then
1483 : : * media type is backplane or BASE-T.
1484 : : */
1485 : 0 : static bool ixgbe_is_media_cage_present(struct ixgbe_hw *hw)
1486 : : {
1487 : : struct ixgbe_aci_cmd_get_link_topo *cmd;
1488 : : struct ixgbe_aci_desc desc;
1489 : :
1490 : : cmd = &desc.params.get_link_topo;
1491 : :
1492 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_topo);
1493 : :
1494 : : cmd->addr.topo_params.node_type_ctx =
1495 : : (IXGBE_ACI_LINK_TOPO_NODE_CTX_PORT <<
1496 : : IXGBE_ACI_LINK_TOPO_NODE_CTX_S);
1497 : :
1498 : : /* set node type */
1499 : 0 : cmd->addr.topo_params.node_type_ctx |=
1500 : : (IXGBE_ACI_LINK_TOPO_NODE_TYPE_M &
1501 : : IXGBE_ACI_LINK_TOPO_NODE_TYPE_CAGE);
1502 : :
1503 : : /* Node type cage can be used to determine if cage is present. If AQC
1504 : : * returns error (ENOENT), then no cage present. If no cage present then
1505 : : * connection type is backplane or BASE-T.
1506 : : */
1507 : 0 : return ixgbe_aci_get_netlist_node(hw, cmd, NULL, NULL);
1508 : : }
1509 : :
1510 : : /**
1511 : : * ixgbe_get_media_type_from_phy_type - Gets media type based on phy type
1512 : : * @hw: pointer to the HW struct
1513 : : *
1514 : : * Try to identify the media type based on the phy type.
1515 : : * If more than one media type, the ixgbe_media_type_unknown is returned.
1516 : : * First, phy_type_low is checked, then phy_type_high.
1517 : : * If none are identified, the ixgbe_media_type_unknown is returned
1518 : : *
1519 : : * Return: type of a media based on phy type in form of enum.
1520 : : */
1521 : : static enum ixgbe_media_type
1522 : 0 : ixgbe_get_media_type_from_phy_type(struct ixgbe_hw *hw)
1523 : : {
1524 : : struct ixgbe_link_status *hw_link_info;
1525 : :
1526 [ # # ]: 0 : if (!hw)
1527 : : return ixgbe_media_type_unknown;
1528 : :
1529 : : hw_link_info = &hw->link.link_info;
1530 [ # # # # ]: 0 : if (hw_link_info->phy_type_low && hw_link_info->phy_type_high)
1531 : : /* If more than one media type is selected, report unknown */
1532 : : return ixgbe_media_type_unknown;
1533 : :
1534 [ # # ]: 0 : if (hw_link_info->phy_type_low) {
1535 : : /* 1G SGMII is a special case where some DA cable PHYs
1536 : : * may show this as an option when it really shouldn't
1537 : : * be since SGMII is meant to be between a MAC and a PHY
1538 : : * in a backplane. Try to detect this case and handle it
1539 : : */
1540 [ # # ]: 0 : if (hw_link_info->phy_type_low == IXGBE_PHY_TYPE_LOW_1G_SGMII &&
1541 : 0 : (hw_link_info->module_type[IXGBE_ACI_MOD_TYPE_IDENT] ==
1542 [ # # ]: 0 : IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE ||
1543 : : hw_link_info->module_type[IXGBE_ACI_MOD_TYPE_IDENT] ==
1544 : : IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE))
1545 : : return ixgbe_media_type_da;
1546 : :
1547 [ # # # # : 0 : switch (hw_link_info->phy_type_low) {
# # # ]
1548 : 0 : case IXGBE_PHY_TYPE_LOW_1000BASE_SX:
1549 : : case IXGBE_PHY_TYPE_LOW_1000BASE_LX:
1550 : : case IXGBE_PHY_TYPE_LOW_10GBASE_SR:
1551 : : case IXGBE_PHY_TYPE_LOW_10GBASE_LR:
1552 : : case IXGBE_PHY_TYPE_LOW_25GBASE_SR:
1553 : : case IXGBE_PHY_TYPE_LOW_25GBASE_LR:
1554 : 0 : return ixgbe_media_type_fiber;
1555 : 0 : case IXGBE_PHY_TYPE_LOW_10G_SFI_AOC_ACC:
1556 : : case IXGBE_PHY_TYPE_LOW_25G_AUI_AOC_ACC:
1557 : 0 : return ixgbe_media_type_fiber;
1558 : 0 : case IXGBE_PHY_TYPE_LOW_100BASE_TX:
1559 : : case IXGBE_PHY_TYPE_LOW_1000BASE_T:
1560 : : case IXGBE_PHY_TYPE_LOW_2500BASE_T:
1561 : : case IXGBE_PHY_TYPE_LOW_5GBASE_T:
1562 : : case IXGBE_PHY_TYPE_LOW_10GBASE_T:
1563 : : case IXGBE_PHY_TYPE_LOW_25GBASE_T:
1564 : 0 : return ixgbe_media_type_copper;
1565 : 0 : case IXGBE_PHY_TYPE_LOW_10G_SFI_DA:
1566 : : case IXGBE_PHY_TYPE_LOW_25GBASE_CR:
1567 : : case IXGBE_PHY_TYPE_LOW_25GBASE_CR_S:
1568 : : case IXGBE_PHY_TYPE_LOW_25GBASE_CR1:
1569 : 0 : return ixgbe_media_type_da;
1570 : 0 : case IXGBE_PHY_TYPE_LOW_25G_AUI_C2C:
1571 [ # # ]: 0 : if (ixgbe_is_media_cage_present(hw))
1572 : : return ixgbe_media_type_aui;
1573 : 0 : return ixgbe_media_type_backplane;
1574 : 0 : case IXGBE_PHY_TYPE_LOW_1000BASE_KX:
1575 : : case IXGBE_PHY_TYPE_LOW_2500BASE_KX:
1576 : : case IXGBE_PHY_TYPE_LOW_2500BASE_X:
1577 : : case IXGBE_PHY_TYPE_LOW_5GBASE_KR:
1578 : : case IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1:
1579 : : case IXGBE_PHY_TYPE_LOW_10G_SFI_C2C:
1580 : : case IXGBE_PHY_TYPE_LOW_25GBASE_KR:
1581 : : case IXGBE_PHY_TYPE_LOW_25GBASE_KR1:
1582 : : case IXGBE_PHY_TYPE_LOW_25GBASE_KR_S:
1583 : 0 : return ixgbe_media_type_backplane;
1584 : : }
1585 : : } else {
1586 [ # # ]: 0 : switch (hw_link_info->phy_type_high) {
1587 : 0 : case IXGBE_PHY_TYPE_HIGH_10BASE_T:
1588 : 0 : return ixgbe_media_type_copper;
1589 : : }
1590 : : }
1591 : : return ixgbe_media_type_unknown;
1592 : : }
1593 : :
1594 : : /**
1595 : : * ixgbe_update_link_info - update status of the HW network link
1596 : : * @hw: pointer to the HW struct
1597 : : *
1598 : : * Update the status of the HW network link.
1599 : : *
1600 : : * Return: the exit code of the operation.
1601 : : */
1602 : 0 : s32 ixgbe_update_link_info(struct ixgbe_hw *hw)
1603 : : {
1604 : : struct ixgbe_aci_cmd_get_phy_caps_data *pcaps;
1605 : : struct ixgbe_link_status *li;
1606 : : s32 status;
1607 : :
1608 [ # # ]: 0 : if (!hw)
1609 : : return IXGBE_ERR_PARAM;
1610 : :
1611 : : li = &hw->link.link_info;
1612 : :
1613 : 0 : status = ixgbe_aci_get_link_info(hw, true, NULL);
1614 [ # # ]: 0 : if (status)
1615 : : return status;
1616 : :
1617 [ # # ]: 0 : if (li->link_info & IXGBE_ACI_MEDIA_AVAILABLE) {
1618 : : pcaps = (struct ixgbe_aci_cmd_get_phy_caps_data *)
1619 : 0 : ixgbe_malloc(hw, sizeof(*pcaps));
1620 [ # # ]: 0 : if (!pcaps)
1621 : : return IXGBE_ERR_OUT_OF_MEM;
1622 : :
1623 : 0 : status = ixgbe_aci_get_phy_caps(hw, false,
1624 : : IXGBE_ACI_REPORT_TOPO_CAP_MEDIA,
1625 : : pcaps);
1626 : :
1627 [ # # ]: 0 : if (status == IXGBE_SUCCESS)
1628 : 0 : memcpy(li->module_type, &pcaps->module_type,
1629 : : sizeof(li->module_type));
1630 : :
1631 : 0 : ixgbe_free(hw, pcaps);
1632 : : }
1633 : :
1634 : : return status;
1635 : : }
1636 : :
1637 : : /**
1638 : : * ixgbe_get_link_status - get status of the HW network link
1639 : : * @hw: pointer to the HW struct
1640 : : * @link_up: pointer to bool (true/false = linkup/linkdown)
1641 : : *
1642 : : * Variable link_up is true if link is up, false if link is down.
1643 : : * The variable link_up is invalid if status is non zero. As a
1644 : : * result of this call, link status reporting becomes enabled
1645 : : *
1646 : : * Return: the exit code of the operation.
1647 : : */
1648 : 0 : s32 ixgbe_get_link_status(struct ixgbe_hw *hw, bool *link_up)
1649 : : {
1650 : : s32 status = IXGBE_SUCCESS;
1651 : :
1652 [ # # ]: 0 : if (!hw || !link_up)
1653 : : return IXGBE_ERR_PARAM;
1654 : :
1655 [ # # ]: 0 : if (hw->link.get_link_info) {
1656 : 0 : status = ixgbe_update_link_info(hw);
1657 [ # # ]: 0 : if (status) {
1658 : : return status;
1659 : : }
1660 : : }
1661 : :
1662 : 0 : *link_up = hw->link.link_info.link_info & IXGBE_ACI_LINK_UP;
1663 : :
1664 : 0 : return status;
1665 : : }
1666 : :
1667 : : /**
1668 : : * ixgbe_aci_get_link_info - get the link status
1669 : : * @hw: pointer to the HW struct
1670 : : * @ena_lse: enable/disable LinkStatusEvent reporting
1671 : : * @link: pointer to link status structure - optional
1672 : : *
1673 : : * Get the current Link Status using ACI command (0x607).
1674 : : * The current link can be optionally provided to update
1675 : : * the status.
1676 : : *
1677 : : * Return: the link status of the adapter.
1678 : : */
1679 : 0 : s32 ixgbe_aci_get_link_info(struct ixgbe_hw *hw, bool ena_lse,
1680 : : struct ixgbe_link_status *link)
1681 : : {
1682 : 0 : struct ixgbe_aci_cmd_get_link_status_data link_data = { 0 };
1683 : : struct ixgbe_aci_cmd_get_link_status *resp;
1684 : : struct ixgbe_link_status *li_old, *li;
1685 : : struct ixgbe_fc_info *hw_fc_info;
1686 : : struct ixgbe_aci_desc desc;
1687 : : bool tx_pause, rx_pause;
1688 : : u8 cmd_flags;
1689 : : s32 status;
1690 : :
1691 [ # # ]: 0 : if (!hw)
1692 : : return IXGBE_ERR_PARAM;
1693 : :
1694 : : li_old = &hw->link.link_info_old;
1695 : : li = &hw->link.link_info;
1696 : : hw_fc_info = &hw->fc;
1697 : :
1698 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_status);
1699 [ # # ]: 0 : cmd_flags = (ena_lse) ? IXGBE_ACI_LSE_ENA : IXGBE_ACI_LSE_DIS;
1700 : : resp = &desc.params.get_link_status;
1701 : 0 : resp->cmd_flags = cmd_flags;
1702 : :
1703 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, &link_data, sizeof(link_data));
1704 : :
1705 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
1706 : : return status;
1707 : :
1708 : : /* save off old link status information */
1709 : 0 : *li_old = *li;
1710 : :
1711 : : /* update current link status information */
1712 : 0 : li->link_speed = IXGBE_LE16_TO_CPU(link_data.link_speed);
1713 : 0 : li->phy_type_low = IXGBE_LE64_TO_CPU(link_data.phy_type_low);
1714 : 0 : li->phy_type_high = IXGBE_LE64_TO_CPU(link_data.phy_type_high);
1715 : 0 : li->link_info = link_data.link_info;
1716 : 0 : li->link_cfg_err = link_data.link_cfg_err;
1717 : 0 : li->an_info = link_data.an_info;
1718 : 0 : li->ext_info = link_data.ext_info;
1719 : 0 : li->max_frame_size = IXGBE_LE16_TO_CPU(link_data.max_frame_size);
1720 : 0 : li->fec_info = link_data.cfg & IXGBE_ACI_FEC_MASK;
1721 : 0 : li->topo_media_conflict = link_data.topo_media_conflict;
1722 : 0 : li->pacing = link_data.cfg & (IXGBE_ACI_CFG_PACING_M |
1723 : : IXGBE_ACI_CFG_PACING_TYPE_M);
1724 : :
1725 : : /* update fc info */
1726 : 0 : tx_pause = !!(link_data.an_info & IXGBE_ACI_LINK_PAUSE_TX);
1727 : 0 : rx_pause = !!(link_data.an_info & IXGBE_ACI_LINK_PAUSE_RX);
1728 [ # # ]: 0 : if (tx_pause && rx_pause)
1729 : 0 : hw_fc_info->current_mode = ixgbe_fc_full;
1730 [ # # ]: 0 : else if (tx_pause)
1731 : 0 : hw_fc_info->current_mode = ixgbe_fc_tx_pause;
1732 [ # # ]: 0 : else if (rx_pause)
1733 : 0 : hw_fc_info->current_mode = ixgbe_fc_rx_pause;
1734 : : else
1735 : 0 : hw_fc_info->current_mode = ixgbe_fc_none;
1736 : :
1737 : 0 : li->lse_ena = !!(resp->cmd_flags & IXGBE_ACI_LSE_IS_ENABLED);
1738 : :
1739 : : /* save link status information */
1740 [ # # ]: 0 : if (link)
1741 : 0 : *link = *li;
1742 : :
1743 : : /* flag cleared so calling functions don't call AQ again */
1744 : 0 : hw->link.get_link_info = false;
1745 : :
1746 : 0 : return IXGBE_SUCCESS;
1747 : : }
1748 : :
1749 : : /**
1750 : : * ixgbe_aci_set_event_mask - set event mask
1751 : : * @hw: pointer to the HW struct
1752 : : * @port_num: port number of the physical function
1753 : : * @mask: event mask to be set
1754 : : *
1755 : : * Set the event mask using ACI command (0x0613).
1756 : : *
1757 : : * Return: the exit code of the operation.
1758 : : */
1759 : 0 : s32 ixgbe_aci_set_event_mask(struct ixgbe_hw *hw, u8 port_num, u16 mask)
1760 : : {
1761 : : struct ixgbe_aci_cmd_set_event_mask *cmd;
1762 : : struct ixgbe_aci_desc desc;
1763 : :
1764 : : cmd = &desc.params.set_event_mask;
1765 : :
1766 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_event_mask);
1767 : :
1768 : 0 : cmd->event_mask = IXGBE_CPU_TO_LE16(mask);
1769 : 0 : return ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
1770 : : }
1771 : :
1772 : : /**
1773 : : * ixgbe_configure_lse - enable/disable link status events
1774 : : * @hw: pointer to the HW struct
1775 : : * @activate: bool value deciding if lse should be enabled nor disabled
1776 : : * @mask: event mask to be set; a set bit means deactivation of the
1777 : : * corresponding event
1778 : : *
1779 : : * Set the event mask and then enable or disable link status events
1780 : : *
1781 : : * Return: the exit code of the operation.
1782 : : */
1783 : 0 : s32 ixgbe_configure_lse(struct ixgbe_hw *hw, bool activate, u16 mask)
1784 : : {
1785 : : s32 rc;
1786 : :
1787 : 0 : rc = ixgbe_aci_set_event_mask(hw, (u8)hw->bus.func, mask);
1788 [ # # ]: 0 : if (rc) {
1789 : : return rc;
1790 : : }
1791 : :
1792 : : /* Enabling link status events generation by fw */
1793 : 0 : rc = ixgbe_aci_get_link_info(hw, activate, NULL);
1794 [ # # ]: 0 : if (rc) {
1795 : 0 : return rc;
1796 : : }
1797 : : return IXGBE_SUCCESS;
1798 : : }
1799 : :
1800 : : /**
1801 : : * ixgbe_aci_get_netlist_node - get a node handle
1802 : : * @hw: pointer to the hw struct
1803 : : * @cmd: get_link_topo AQ structure
1804 : : * @node_part_number: output node part number if node found
1805 : : * @node_handle: output node handle parameter if node found
1806 : : *
1807 : : * Get the netlist node and assigns it to
1808 : : * the provided handle using ACI command (0x06E0).
1809 : : *
1810 : : * Return: the exit code of the operation.
1811 : : */
1812 : 0 : s32 ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw,
1813 : : struct ixgbe_aci_cmd_get_link_topo *cmd,
1814 : : u8 *node_part_number, u16 *node_handle)
1815 : : {
1816 : : struct ixgbe_aci_desc desc;
1817 : :
1818 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_topo);
1819 : 0 : desc.params.get_link_topo = *cmd;
1820 : :
1821 [ # # ]: 0 : if (ixgbe_aci_send_cmd(hw, &desc, NULL, 0))
1822 : : return IXGBE_ERR_NOT_SUPPORTED;
1823 : :
1824 [ # # ]: 0 : if (node_handle)
1825 : 0 : *node_handle =
1826 : 0 : IXGBE_LE16_TO_CPU(desc.params.get_link_topo.addr.handle);
1827 [ # # ]: 0 : if (node_part_number)
1828 : 0 : *node_part_number = desc.params.get_link_topo.node_part_num;
1829 : :
1830 : : return IXGBE_SUCCESS;
1831 : : }
1832 : :
1833 : : /**
1834 : : * ixgbe_aci_get_netlist_node_pin - get a node pin handle
1835 : : * @hw: pointer to the hw struct
1836 : : * @cmd: get_link_topo_pin AQ structure
1837 : : * @node_handle: output node handle parameter if node found
1838 : : *
1839 : : * Get the netlist node pin and assign it to
1840 : : * the provided handle using ACI command (0x06E1).
1841 : : *
1842 : : * Return: the exit code of the operation.
1843 : : */
1844 : 0 : s32 ixgbe_aci_get_netlist_node_pin(struct ixgbe_hw *hw,
1845 : : struct ixgbe_aci_cmd_get_link_topo_pin *cmd,
1846 : : u16 *node_handle)
1847 : : {
1848 : : struct ixgbe_aci_desc desc;
1849 : :
1850 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_topo_pin);
1851 : 0 : desc.params.get_link_topo_pin = *cmd;
1852 : :
1853 [ # # ]: 0 : if (ixgbe_aci_send_cmd(hw, &desc, NULL, 0))
1854 : : return IXGBE_ERR_NOT_SUPPORTED;
1855 : :
1856 [ # # ]: 0 : if (node_handle)
1857 : 0 : *node_handle =
1858 : 0 : IXGBE_LE16_TO_CPU(desc.params.get_link_topo_pin.addr.handle);
1859 : :
1860 : : return IXGBE_SUCCESS;
1861 : : }
1862 : :
1863 : : /**
1864 : : * ixgbe_find_netlist_node - find a node handle
1865 : : * @hw: pointer to the hw struct
1866 : : * @node_type_ctx: type of netlist node to look for
1867 : : * @node_part_number: node part number to look for
1868 : : * @node_handle: output parameter if node found - optional
1869 : : *
1870 : : * Find and return the node handle for a given node type and part number in the
1871 : : * netlist. When found IXGBE_SUCCESS is returned, IXGBE_ERR_NOT_SUPPORTED
1872 : : * otherwise. If @node_handle provided, it would be set to found node handle.
1873 : : *
1874 : : * Return: the exit code of the operation.
1875 : : */
1876 : 0 : s32 ixgbe_find_netlist_node(struct ixgbe_hw *hw, u8 node_type_ctx,
1877 : : u8 node_part_number, u16 *node_handle)
1878 : : {
1879 : : struct ixgbe_aci_cmd_get_link_topo cmd;
1880 : : u8 rec_node_part_number;
1881 : : u16 rec_node_handle;
1882 : : s32 status;
1883 : : u8 idx;
1884 : :
1885 [ # # ]: 0 : for (idx = 0; idx < IXGBE_MAX_NETLIST_SIZE; idx++) {
1886 : : memset(&cmd, 0, sizeof(cmd));
1887 : :
1888 : 0 : cmd.addr.topo_params.node_type_ctx =
1889 : : (node_type_ctx << IXGBE_ACI_LINK_TOPO_NODE_TYPE_S);
1890 : 0 : cmd.addr.topo_params.index = idx;
1891 : :
1892 : 0 : status = ixgbe_aci_get_netlist_node(hw, &cmd,
1893 : : &rec_node_part_number,
1894 : : &rec_node_handle);
1895 [ # # ]: 0 : if (status)
1896 : 0 : return status;
1897 : :
1898 [ # # ]: 0 : if (rec_node_part_number == node_part_number) {
1899 [ # # ]: 0 : if (node_handle)
1900 : 0 : *node_handle = rec_node_handle;
1901 : 0 : return IXGBE_SUCCESS;
1902 : : }
1903 : : }
1904 : :
1905 : : return IXGBE_ERR_NOT_SUPPORTED;
1906 : : }
1907 : :
1908 : : /**
1909 : : * ixgbe_aci_read_i2c - read I2C register value
1910 : : * @hw: pointer to the hw struct
1911 : : * @topo_addr: topology address for a device to communicate with
1912 : : * @bus_addr: 7-bit I2C bus address
1913 : : * @addr: I2C memory address (I2C offset) with up to 16 bits
1914 : : * @params: I2C parameters: bit [7] - Repeated start,
1915 : : * bits [6:5] data offset size,
1916 : : * bit [4] - I2C address type, bits [3:0] - data size
1917 : : * to read (0-16 bytes)
1918 : : * @data: pointer to data (0 to 16 bytes) to be read from the I2C device
1919 : : *
1920 : : * Read the value of the I2C pin register using ACI command (0x06E2).
1921 : : *
1922 : : * Return: the exit code of the operation.
1923 : : */
1924 : 0 : s32 ixgbe_aci_read_i2c(struct ixgbe_hw *hw,
1925 : : struct ixgbe_aci_cmd_link_topo_addr topo_addr,
1926 : : u16 bus_addr, __le16 addr, u8 params, u8 *data)
1927 : : {
1928 : 0 : struct ixgbe_aci_desc desc = { 0 };
1929 : : struct ixgbe_aci_cmd_i2c *cmd;
1930 : : u8 data_size;
1931 : : s32 status;
1932 : :
1933 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_read_i2c);
1934 : : cmd = &desc.params.read_write_i2c;
1935 : :
1936 [ # # ]: 0 : if (!data)
1937 : : return IXGBE_ERR_PARAM;
1938 : :
1939 : 0 : data_size = (params & IXGBE_ACI_I2C_DATA_SIZE_M) >>
1940 : : IXGBE_ACI_I2C_DATA_SIZE_S;
1941 : :
1942 : 0 : cmd->i2c_bus_addr = IXGBE_CPU_TO_LE16(bus_addr);
1943 : 0 : cmd->topo_addr = topo_addr;
1944 : 0 : cmd->i2c_params = params;
1945 : 0 : cmd->i2c_addr = addr;
1946 : :
1947 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
1948 [ # # ]: 0 : if (!status) {
1949 : : struct ixgbe_aci_cmd_read_i2c_resp *resp;
1950 : : u8 i;
1951 : :
1952 : : resp = &desc.params.read_i2c_resp;
1953 [ # # ]: 0 : for (i = 0; i < data_size; i++) {
1954 : 0 : *data = resp->i2c_data[i];
1955 : 0 : data++;
1956 : : }
1957 : : }
1958 : :
1959 : : return status;
1960 : : }
1961 : :
1962 : : /**
1963 : : * ixgbe_aci_write_i2c - write a value to I2C register
1964 : : * @hw: pointer to the hw struct
1965 : : * @topo_addr: topology address for a device to communicate with
1966 : : * @bus_addr: 7-bit I2C bus address
1967 : : * @addr: I2C memory address (I2C offset) with up to 16 bits
1968 : : * @params: I2C parameters: bit [4] - I2C address type, bits [3:0] - data size
1969 : : * to write (0-7 bytes)
1970 : : * @data: pointer to data (0 to 4 bytes) to be written to the I2C device
1971 : : *
1972 : : * Write a value to the I2C pin register using ACI command (0x06E3).
1973 : : *
1974 : : * Return: the exit code of the operation.
1975 : : */
1976 : 0 : s32 ixgbe_aci_write_i2c(struct ixgbe_hw *hw,
1977 : : struct ixgbe_aci_cmd_link_topo_addr topo_addr,
1978 : : u16 bus_addr, __le16 addr, u8 params, u8 *data)
1979 : : {
1980 : 0 : struct ixgbe_aci_desc desc = { 0 };
1981 : : struct ixgbe_aci_cmd_i2c *cmd;
1982 : : u8 i, data_size;
1983 : :
1984 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_write_i2c);
1985 : : cmd = &desc.params.read_write_i2c;
1986 : :
1987 : 0 : data_size = (params & IXGBE_ACI_I2C_DATA_SIZE_M) >>
1988 : : IXGBE_ACI_I2C_DATA_SIZE_S;
1989 : :
1990 : : /* data_size limited to 4 */
1991 [ # # ]: 0 : if (data_size > 4)
1992 : : return IXGBE_ERR_PARAM;
1993 : :
1994 : 0 : cmd->i2c_bus_addr = IXGBE_CPU_TO_LE16(bus_addr);
1995 : 0 : cmd->topo_addr = topo_addr;
1996 : 0 : cmd->i2c_params = params;
1997 : 0 : cmd->i2c_addr = addr;
1998 : :
1999 [ # # ]: 0 : for (i = 0; i < data_size; i++) {
2000 : 0 : cmd->i2c_data[i] = *data;
2001 : 0 : data++;
2002 : : }
2003 : :
2004 : 0 : return ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
2005 : : }
2006 : :
2007 : : /**
2008 : : * ixgbe_aci_set_gpio - set GPIO pin state
2009 : : * @hw: pointer to the hw struct
2010 : : * @gpio_ctrl_handle: GPIO controller node handle
2011 : : * @pin_idx: IO Number of the GPIO that needs to be set
2012 : : * @value: SW provide IO value to set in the LSB
2013 : : *
2014 : : * Set the GPIO pin state that is a part of the topology
2015 : : * using ACI command (0x06EC).
2016 : : *
2017 : : * Return: the exit code of the operation.
2018 : : */
2019 : 0 : s32 ixgbe_aci_set_gpio(struct ixgbe_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx,
2020 : : bool value)
2021 : : {
2022 : : struct ixgbe_aci_cmd_gpio *cmd;
2023 : : struct ixgbe_aci_desc desc;
2024 : :
2025 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_set_gpio);
2026 : : cmd = &desc.params.read_write_gpio;
2027 : 0 : cmd->gpio_ctrl_handle = IXGBE_CPU_TO_LE16(gpio_ctrl_handle);
2028 : 0 : cmd->gpio_num = pin_idx;
2029 : 0 : cmd->gpio_val = value ? 1 : 0;
2030 : :
2031 : 0 : return ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
2032 : : }
2033 : :
2034 : : /**
2035 : : * ixgbe_aci_get_gpio - get GPIO pin state
2036 : : * @hw: pointer to the hw struct
2037 : : * @gpio_ctrl_handle: GPIO controller node handle
2038 : : * @pin_idx: IO Number of the GPIO that needs to be set
2039 : : * @value: IO value read
2040 : : *
2041 : : * Get the value of a GPIO signal which is part of the topology
2042 : : * using ACI command (0x06ED).
2043 : : *
2044 : : * Return: the exit code of the operation.
2045 : : */
2046 : 0 : s32 ixgbe_aci_get_gpio(struct ixgbe_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx,
2047 : : bool *value)
2048 : : {
2049 : : struct ixgbe_aci_cmd_gpio *cmd;
2050 : : struct ixgbe_aci_desc desc;
2051 : : s32 status;
2052 : :
2053 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_gpio);
2054 : : cmd = &desc.params.read_write_gpio;
2055 : 0 : cmd->gpio_ctrl_handle = IXGBE_CPU_TO_LE16(gpio_ctrl_handle);
2056 : 0 : cmd->gpio_num = pin_idx;
2057 : :
2058 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
2059 [ # # ]: 0 : if (status)
2060 : : return status;
2061 : :
2062 : 0 : *value = !!cmd->gpio_val;
2063 : 0 : return IXGBE_SUCCESS;
2064 : : }
2065 : :
2066 : : /**
2067 : : * ixgbe_aci_sff_eeprom - read/write SFF EEPROM
2068 : : * @hw: pointer to the HW struct
2069 : : * @lport: bits [7:0] = logical port, bit [8] = logical port valid
2070 : : * @bus_addr: I2C bus address of the eeprom (typically 0xA0, 0=topo default)
2071 : : * @mem_addr: I2C offset. lower 8 bits for address, 8 upper bits zero padding.
2072 : : * @page: QSFP page
2073 : : * @page_bank_ctrl: configuration of SFF/CMIS paging and banking control
2074 : : * @data: pointer to data buffer to be read/written to the I2C device.
2075 : : * @length: 1-16 for read, 1 for write.
2076 : : * @write: 0 read, 1 for write.
2077 : : *
2078 : : * Read/write SFF EEPROM using ACI command (0x06EE).
2079 : : *
2080 : : * Return: the exit code of the operation.
2081 : : */
2082 : 0 : s32 ixgbe_aci_sff_eeprom(struct ixgbe_hw *hw, u16 lport, u8 bus_addr,
2083 : : u16 mem_addr, u8 page, u8 page_bank_ctrl, u8 *data,
2084 : : u8 length, bool write)
2085 : : {
2086 : : struct ixgbe_aci_cmd_sff_eeprom *cmd;
2087 : : struct ixgbe_aci_desc desc;
2088 : : s32 status;
2089 : :
2090 [ # # # # ]: 0 : if (!data || (mem_addr & 0xff00))
2091 : : return IXGBE_ERR_PARAM;
2092 : :
2093 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_sff_eeprom);
2094 : : cmd = &desc.params.read_write_sff_param;
2095 : 0 : desc.flags = IXGBE_CPU_TO_LE16(IXGBE_ACI_FLAG_RD);
2096 : 0 : cmd->lport_num = (u8)(lport & 0xff);
2097 : 0 : cmd->lport_num_valid = (u8)((lport >> 8) & 0x01);
2098 : 0 : cmd->i2c_bus_addr = IXGBE_CPU_TO_LE16(((bus_addr >> 1) &
2099 : : IXGBE_ACI_SFF_I2CBUS_7BIT_M) |
2100 : : ((page_bank_ctrl <<
2101 : : IXGBE_ACI_SFF_PAGE_BANK_CTRL_S) &
2102 : : IXGBE_ACI_SFF_PAGE_BANK_CTRL_M));
2103 : 0 : cmd->i2c_offset = IXGBE_CPU_TO_LE16(mem_addr & 0xff);
2104 : 0 : cmd->module_page = page;
2105 [ # # ]: 0 : if (write)
2106 : 0 : cmd->i2c_bus_addr |= IXGBE_CPU_TO_LE16(IXGBE_ACI_SFF_IS_WRITE);
2107 : :
2108 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, data, length);
2109 : 0 : return status;
2110 : : }
2111 : :
2112 : : /**
2113 : : * ixgbe_aci_prog_topo_dev_nvm - program Topology Device NVM
2114 : : * @hw: pointer to the hardware structure
2115 : : * @topo_params: pointer to structure storing topology parameters for a device
2116 : : *
2117 : : * Program Topology Device NVM using ACI command (0x06F2).
2118 : : *
2119 : : * Return: the exit code of the operation.
2120 : : */
2121 : 0 : s32 ixgbe_aci_prog_topo_dev_nvm(struct ixgbe_hw *hw,
2122 : : struct ixgbe_aci_cmd_link_topo_params *topo_params)
2123 : : {
2124 : : struct ixgbe_aci_cmd_prog_topo_dev_nvm *cmd;
2125 : : struct ixgbe_aci_desc desc;
2126 : :
2127 : : cmd = &desc.params.prog_topo_dev_nvm;
2128 : :
2129 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_prog_topo_dev_nvm);
2130 : :
2131 : : memcpy(&cmd->topo_params, topo_params, sizeof(*topo_params));
2132 : :
2133 : 0 : return ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
2134 : : }
2135 : :
2136 : : /**
2137 : : * ixgbe_aci_read_topo_dev_nvm - read Topology Device NVM
2138 : : * @hw: pointer to the hardware structure
2139 : : * @topo_params: pointer to structure storing topology parameters for a device
2140 : : * @start_address: byte offset in the topology device NVM
2141 : : * @data: pointer to data buffer
2142 : : * @data_size: number of bytes to be read from the topology device NVM
2143 : : * Read Topology Device NVM (0x06F3)
2144 : : *
2145 : : * Read Topology of Device NVM using ACI command (0x06F3).
2146 : : *
2147 : : * Return: the exit code of the operation.
2148 : : */
2149 : 0 : s32 ixgbe_aci_read_topo_dev_nvm(struct ixgbe_hw *hw,
2150 : : struct ixgbe_aci_cmd_link_topo_params *topo_params,
2151 : : u32 start_address, u8 *data, u8 data_size)
2152 : : {
2153 : : struct ixgbe_aci_cmd_read_topo_dev_nvm *cmd;
2154 : : struct ixgbe_aci_desc desc;
2155 : : s32 status;
2156 : :
2157 [ # # # # ]: 0 : if (!data || data_size == 0 ||
2158 : : data_size > IXGBE_ACI_READ_TOPO_DEV_NVM_DATA_READ_SIZE)
2159 : : return IXGBE_ERR_PARAM;
2160 : :
2161 : : cmd = &desc.params.read_topo_dev_nvm;
2162 : :
2163 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_read_topo_dev_nvm);
2164 : :
2165 : 0 : desc.datalen = IXGBE_CPU_TO_LE16(data_size);
2166 : : memcpy(&cmd->topo_params, topo_params, sizeof(*topo_params));
2167 : 0 : cmd->start_address = IXGBE_CPU_TO_LE32(start_address);
2168 : :
2169 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
2170 [ # # ]: 0 : if (status)
2171 : : return status;
2172 : :
2173 : 0 : memcpy(data, cmd->data_read, data_size);
2174 : :
2175 : 0 : return IXGBE_SUCCESS;
2176 : : }
2177 : :
2178 : : /**
2179 : : * ixgbe_acquire_nvm - Generic request for acquiring the NVM ownership
2180 : : * @hw: pointer to the HW structure
2181 : : * @access: NVM access type (read or write)
2182 : : *
2183 : : * Request NVM ownership.
2184 : : *
2185 : : * Return: the exit code of the operation.
2186 : : */
2187 : 0 : s32 ixgbe_acquire_nvm(struct ixgbe_hw *hw,
2188 : : enum ixgbe_aci_res_access_type access)
2189 : : {
2190 : : u32 fla;
2191 : :
2192 : : /* Skip if we are in blank NVM programming mode */
2193 : 0 : fla = IXGBE_READ_REG(hw, GLNVM_FLA);
2194 [ # # ]: 0 : if ((fla & GLNVM_FLA_LOCKED_M) == 0)
2195 : : return IXGBE_SUCCESS;
2196 : :
2197 : 0 : return ixgbe_acquire_res(hw, IXGBE_NVM_RES_ID, access,
2198 : : IXGBE_NVM_TIMEOUT);
2199 : : }
2200 : :
2201 : : /**
2202 : : * ixgbe_release_nvm - Generic request for releasing the NVM ownership
2203 : : * @hw: pointer to the HW structure
2204 : : *
2205 : : * Release NVM ownership.
2206 : : */
2207 : 0 : void ixgbe_release_nvm(struct ixgbe_hw *hw)
2208 : : {
2209 : : u32 fla;
2210 : :
2211 : : /* Skip if we are in blank NVM programming mode */
2212 : 0 : fla = IXGBE_READ_REG(hw, GLNVM_FLA);
2213 [ # # ]: 0 : if ((fla & GLNVM_FLA_LOCKED_M) == 0)
2214 : : return;
2215 : :
2216 : 0 : ixgbe_release_res(hw, IXGBE_NVM_RES_ID);
2217 : : }
2218 : :
2219 : :
2220 : : /**
2221 : : * ixgbe_aci_read_nvm - read NVM
2222 : : * @hw: pointer to the HW struct
2223 : : * @module_typeid: module pointer location in words from the NVM beginning
2224 : : * @offset: byte offset from the module beginning
2225 : : * @length: length of the section to be read (in bytes from the offset)
2226 : : * @data: command buffer (size [bytes] = length)
2227 : : * @last_command: tells if this is the last command in a series
2228 : : * @read_shadow_ram: tell if this is a shadow RAM read
2229 : : *
2230 : : * Read the NVM using ACI command (0x0701).
2231 : : *
2232 : : * Return: the exit code of the operation.
2233 : : */
2234 : 0 : s32 ixgbe_aci_read_nvm(struct ixgbe_hw *hw, u16 module_typeid, u32 offset,
2235 : : u16 length, void *data, bool last_command,
2236 : : bool read_shadow_ram)
2237 : : {
2238 : : struct ixgbe_aci_desc desc;
2239 : : struct ixgbe_aci_cmd_nvm *cmd;
2240 : :
2241 : : cmd = &desc.params.nvm;
2242 : :
2243 [ # # ]: 0 : if (offset > IXGBE_ACI_NVM_MAX_OFFSET)
2244 : : return IXGBE_ERR_PARAM;
2245 : :
2246 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_read);
2247 : :
2248 [ # # ]: 0 : if (!read_shadow_ram && module_typeid == IXGBE_ACI_NVM_START_POINT)
2249 : 0 : cmd->cmd_flags |= IXGBE_ACI_NVM_FLASH_ONLY;
2250 : :
2251 : : /* If this is the last command in a series, set the proper flag. */
2252 [ # # ]: 0 : if (last_command)
2253 : 0 : cmd->cmd_flags |= IXGBE_ACI_NVM_LAST_CMD;
2254 : 0 : cmd->module_typeid = IXGBE_CPU_TO_LE16(module_typeid);
2255 : 0 : cmd->offset_low = IXGBE_CPU_TO_LE16(offset & 0xFFFF);
2256 : 0 : cmd->offset_high = (offset >> 16) & 0xFF;
2257 : 0 : cmd->length = IXGBE_CPU_TO_LE16(length);
2258 : :
2259 : 0 : return ixgbe_aci_send_cmd(hw, &desc, data, length);
2260 : : }
2261 : :
2262 : : /**
2263 : : * ixgbe_nvm_validate_checksum - validate checksum
2264 : : * @hw: pointer to the HW struct
2265 : : *
2266 : : * Verify NVM PFA checksum validity using ACI command (0x0706).
2267 : : * If the checksum verification failed, IXGBE_ERR_NVM_CHECKSUM is returned.
2268 : : * The function acquires and then releases the NVM ownership.
2269 : : *
2270 : : * Return: the exit code of the operation.
2271 : : */
2272 : 0 : s32 ixgbe_nvm_validate_checksum(struct ixgbe_hw *hw)
2273 : : {
2274 : : struct ixgbe_aci_cmd_nvm_checksum *cmd;
2275 : : struct ixgbe_aci_desc desc;
2276 : : s32 status;
2277 : :
2278 : 0 : status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ);
2279 [ # # ]: 0 : if (status)
2280 : : return status;
2281 : :
2282 : : cmd = &desc.params.nvm_checksum;
2283 : :
2284 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_checksum);
2285 : 0 : cmd->flags = IXGBE_ACI_NVM_CHECKSUM_VERIFY;
2286 : :
2287 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
2288 : :
2289 : 0 : ixgbe_release_nvm(hw);
2290 : :
2291 [ # # ]: 0 : if (!status)
2292 [ # # ]: 0 : if (IXGBE_LE16_TO_CPU(cmd->checksum) !=
2293 : : IXGBE_ACI_NVM_CHECKSUM_CORRECT) {
2294 : 0 : ERROR_REPORT1(IXGBE_ERROR_INVALID_STATE,
2295 : : "Invalid Shadow Ram checksum");
2296 : : status = IXGBE_ERR_NVM_CHECKSUM;
2297 : : }
2298 : :
2299 : : return status;
2300 : : }
2301 : :
2302 : : /**
2303 : : * ixgbe_nvm_recalculate_checksum - recalculate checksum
2304 : : * @hw: pointer to the HW struct
2305 : : *
2306 : : * Recalculate NVM PFA checksum using ACI command (0x0706).
2307 : : * The function acquires and then releases the NVM ownership.
2308 : : *
2309 : : * Return: the exit code of the operation.
2310 : : */
2311 : 0 : s32 ixgbe_nvm_recalculate_checksum(struct ixgbe_hw *hw)
2312 : : {
2313 : : struct ixgbe_aci_cmd_nvm_checksum *cmd;
2314 : : struct ixgbe_aci_desc desc;
2315 : : s32 status;
2316 : :
2317 : 0 : status = ixgbe_acquire_nvm(hw, IXGBE_RES_WRITE);
2318 [ # # ]: 0 : if (status)
2319 : : return status;
2320 : :
2321 : : cmd = &desc.params.nvm_checksum;
2322 : :
2323 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_checksum);
2324 : 0 : cmd->flags = IXGBE_ACI_NVM_CHECKSUM_RECALC;
2325 : :
2326 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
2327 : :
2328 : 0 : ixgbe_release_nvm(hw);
2329 : :
2330 : 0 : return status;
2331 : : }
2332 : :
2333 : : /**
2334 : : * ixgbe_get_flash_bank_offset - Get offset into requested flash bank
2335 : : * @hw: pointer to the HW structure
2336 : : * @bank: whether to read from the active or inactive flash bank
2337 : : * @module: the module to read from
2338 : : *
2339 : : * Based on the module, lookup the module offset from the beginning of the
2340 : : * flash.
2341 : : *
2342 : : * Return: the flash offset. Note that a value of zero is invalid and must be
2343 : : * treated as an error.
2344 : : */
2345 : 0 : static u32 ixgbe_get_flash_bank_offset(struct ixgbe_hw *hw,
2346 : : enum ixgbe_bank_select bank,
2347 : : u16 module)
2348 : : {
2349 : : struct ixgbe_bank_info *banks = &hw->flash.banks;
2350 : : enum ixgbe_flash_bank active_bank;
2351 : : bool second_bank_active;
2352 : : u32 offset, size;
2353 : :
2354 [ # # # # ]: 0 : switch (module) {
2355 : 0 : case E610_SR_1ST_NVM_BANK_PTR:
2356 : 0 : offset = banks->nvm_ptr;
2357 : 0 : size = banks->nvm_size;
2358 : 0 : active_bank = banks->nvm_bank;
2359 : 0 : break;
2360 : 0 : case E610_SR_1ST_OROM_BANK_PTR:
2361 : 0 : offset = banks->orom_ptr;
2362 : 0 : size = banks->orom_size;
2363 : 0 : active_bank = banks->orom_bank;
2364 : 0 : break;
2365 : 0 : case E610_SR_NETLIST_BANK_PTR:
2366 : 0 : offset = banks->netlist_ptr;
2367 : 0 : size = banks->netlist_size;
2368 : 0 : active_bank = banks->netlist_bank;
2369 : 0 : break;
2370 : : default:
2371 : : return 0;
2372 : : }
2373 : :
2374 [ # # # ]: 0 : switch (active_bank) {
2375 : : case IXGBE_1ST_FLASH_BANK:
2376 : : second_bank_active = false;
2377 : : break;
2378 : 0 : case IXGBE_2ND_FLASH_BANK:
2379 : : second_bank_active = true;
2380 : 0 : break;
2381 : : default:
2382 : : return 0;
2383 : : }
2384 : :
2385 : : /* The second flash bank is stored immediately following the first
2386 : : * bank. Based on whether the 1st or 2nd bank is active, and whether
2387 : : * we want the active or inactive bank, calculate the desired offset.
2388 : : */
2389 [ # # # ]: 0 : switch (bank) {
2390 : 0 : case IXGBE_ACTIVE_FLASH_BANK:
2391 [ # # ]: 0 : return offset + (second_bank_active ? size : 0);
2392 : 0 : case IXGBE_INACTIVE_FLASH_BANK:
2393 [ # # ]: 0 : return offset + (second_bank_active ? 0 : size);
2394 : : }
2395 : :
2396 : : return 0;
2397 : : }
2398 : :
2399 : : /**
2400 : : * ixgbe_read_flash_module - Read a word from one of the main NVM modules
2401 : : * @hw: pointer to the HW structure
2402 : : * @bank: which bank of the module to read
2403 : : * @module: the module to read
2404 : : * @offset: the offset into the module in bytes
2405 : : * @data: storage for the word read from the flash
2406 : : * @length: bytes of data to read
2407 : : *
2408 : : * Read data from the specified flash module. The bank parameter indicates
2409 : : * whether or not to read from the active bank or the inactive bank of that
2410 : : * module.
2411 : : *
2412 : : * The word will be read using flat NVM access, and relies on the
2413 : : * hw->flash.banks data being setup by ixgbe_determine_active_flash_banks()
2414 : : * during initialization.
2415 : : *
2416 : : * Return: the exit code of the operation.
2417 : : */
2418 : 0 : static s32 ixgbe_read_flash_module(struct ixgbe_hw *hw,
2419 : : enum ixgbe_bank_select bank,
2420 : : u16 module, u32 offset, u8 *data, u32 length)
2421 : : {
2422 : : s32 status;
2423 : : u32 start;
2424 : :
2425 : 0 : start = ixgbe_get_flash_bank_offset(hw, bank, module);
2426 [ # # ]: 0 : if (!start) {
2427 : : return IXGBE_ERR_PARAM;
2428 : : }
2429 : :
2430 : 0 : status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ);
2431 [ # # ]: 0 : if (status)
2432 : : return status;
2433 : :
2434 : 0 : status = ixgbe_read_flat_nvm(hw, start + offset, &length, data, false);
2435 : :
2436 : 0 : ixgbe_release_nvm(hw);
2437 : :
2438 : 0 : return status;
2439 : : }
2440 : :
2441 : : /**
2442 : : * ixgbe_read_nvm_module - Read from the active main NVM module
2443 : : * @hw: pointer to the HW structure
2444 : : * @bank: whether to read from active or inactive NVM module
2445 : : * @offset: offset into the NVM module to read, in words
2446 : : * @data: storage for returned word value
2447 : : *
2448 : : * Read the specified word from the active NVM module. This includes the CSS
2449 : : * header at the start of the NVM module.
2450 : : *
2451 : : * Return: the exit code of the operation.
2452 : : */
2453 : : static s32 ixgbe_read_nvm_module(struct ixgbe_hw *hw,
2454 : : enum ixgbe_bank_select bank,
2455 : : u32 offset, u16 *data)
2456 : : {
2457 : : __le16 data_local;
2458 : : s32 status;
2459 : :
2460 : 0 : status = ixgbe_read_flash_module(hw, bank, E610_SR_1ST_NVM_BANK_PTR,
2461 : : offset * sizeof(u16),
2462 : : (u8 *)&data_local,
2463 : : sizeof(u16));
2464 [ # # # # : 0 : if (!status)
# # # # #
# ]
2465 : 0 : *data = IXGBE_LE16_TO_CPU(data_local);
2466 : :
2467 : : return status;
2468 : : }
2469 : :
2470 : : /**
2471 : : * ixgbe_get_nvm_css_hdr_len - Read the CSS header length from the
2472 : : * NVM CSS header
2473 : : * @hw: pointer to the HW struct
2474 : : * @bank: whether to read from the active or inactive flash bank
2475 : : * @hdr_len: storage for header length in words
2476 : : *
2477 : : * Read the CSS header length from the NVM CSS header and add the
2478 : : * Authentication header size, and then convert to words.
2479 : : *
2480 : : * Return: the exit code of the operation.
2481 : : */
2482 : 0 : static s32 ixgbe_get_nvm_css_hdr_len(struct ixgbe_hw *hw,
2483 : : enum ixgbe_bank_select bank,
2484 : : u32 *hdr_len)
2485 : : {
2486 : : u16 hdr_len_l, hdr_len_h;
2487 : : u32 hdr_len_dword;
2488 : : s32 status;
2489 : :
2490 : : status = ixgbe_read_nvm_module(hw, bank, IXGBE_NVM_CSS_HDR_LEN_L,
2491 : : &hdr_len_l);
2492 [ # # ]: 0 : if (status)
2493 : : return status;
2494 : :
2495 : : status = ixgbe_read_nvm_module(hw, bank, IXGBE_NVM_CSS_HDR_LEN_H,
2496 : : &hdr_len_h);
2497 [ # # ]: 0 : if (status)
2498 : : return status;
2499 : :
2500 : : /* CSS header length is in DWORD, so convert to words and add
2501 : : * authentication header size
2502 : : */
2503 : 0 : hdr_len_dword = hdr_len_h << 16 | hdr_len_l;
2504 : 0 : *hdr_len = (hdr_len_dword * 2) + IXGBE_NVM_AUTH_HEADER_LEN;
2505 : :
2506 : 0 : return IXGBE_SUCCESS;
2507 : : }
2508 : :
2509 : : /**
2510 : : * ixgbe_read_nvm_sr_copy - Read a word from the Shadow RAM copy in the NVM bank
2511 : : * @hw: pointer to the HW structure
2512 : : * @bank: whether to read from the active or inactive NVM module
2513 : : * @offset: offset into the Shadow RAM copy to read, in words
2514 : : * @data: storage for returned word value
2515 : : *
2516 : : * Read the specified word from the copy of the Shadow RAM found in the
2517 : : * specified NVM module.
2518 : : *
2519 : : * Return: the exit code of the operation.
2520 : : */
2521 : 0 : static s32 ixgbe_read_nvm_sr_copy(struct ixgbe_hw *hw,
2522 : : enum ixgbe_bank_select bank,
2523 : : u32 offset, u16 *data)
2524 : : {
2525 : : u32 hdr_len;
2526 : : s32 status;
2527 : :
2528 : 0 : status = ixgbe_get_nvm_css_hdr_len(hw, bank, &hdr_len);
2529 [ # # ]: 0 : if (status)
2530 : : return status;
2531 : :
2532 : 0 : hdr_len = ROUND_UP(hdr_len, 32);
2533 : :
2534 : 0 : return ixgbe_read_nvm_module(hw, bank, hdr_len + offset, data);
2535 : : }
2536 : :
2537 : : /**
2538 : : * ixgbe_get_nvm_srev - Read the security revision from the NVM CSS header
2539 : : * @hw: pointer to the HW struct
2540 : : * @bank: whether to read from the active or inactive flash bank
2541 : : * @srev: storage for security revision
2542 : : *
2543 : : * Read the security revision out of the CSS header of the active NVM module
2544 : : * bank.
2545 : : *
2546 : : * Return: the exit code of the operation.
2547 : : */
2548 : 0 : static s32 ixgbe_get_nvm_srev(struct ixgbe_hw *hw,
2549 : : enum ixgbe_bank_select bank, u32 *srev)
2550 : : {
2551 : : u16 srev_l, srev_h;
2552 : : s32 status;
2553 : :
2554 : : status = ixgbe_read_nvm_module(hw, bank, IXGBE_NVM_CSS_SREV_L, &srev_l);
2555 [ # # ]: 0 : if (status)
2556 : : return status;
2557 : :
2558 : : status = ixgbe_read_nvm_module(hw, bank, IXGBE_NVM_CSS_SREV_H, &srev_h);
2559 [ # # ]: 0 : if (status)
2560 : : return status;
2561 : :
2562 : 0 : *srev = srev_h << 16 | srev_l;
2563 : :
2564 : 0 : return IXGBE_SUCCESS;
2565 : : }
2566 : :
2567 : : /**
2568 : : * ixgbe_get_nvm_ver_info - Read NVM version information
2569 : : * @hw: pointer to the HW struct
2570 : : * @bank: whether to read from the active or inactive flash bank
2571 : : * @nvm: pointer to NVM info structure
2572 : : *
2573 : : * Read the NVM EETRACK ID and map version of the main NVM image bank, filling
2574 : : * in the nvm info structure.
2575 : : *
2576 : : * Return: the exit code of the operation.
2577 : : */
2578 : 0 : static s32 ixgbe_get_nvm_ver_info(struct ixgbe_hw *hw,
2579 : : enum ixgbe_bank_select bank,
2580 : : struct ixgbe_nvm_info *nvm)
2581 : : {
2582 : : u16 eetrack_lo, eetrack_hi, ver;
2583 : : s32 status;
2584 : :
2585 : 0 : status = ixgbe_read_nvm_sr_copy(hw, bank,
2586 : : E610_SR_NVM_DEV_STARTER_VER, &ver);
2587 [ # # ]: 0 : if (status) {
2588 : : return status;
2589 : : }
2590 : :
2591 : 0 : nvm->major = (ver & E610_NVM_VER_HI_MASK) >> E610_NVM_VER_HI_SHIFT;
2592 : 0 : nvm->minor = (ver & E610_NVM_VER_LO_MASK) >> E610_NVM_VER_LO_SHIFT;
2593 : :
2594 : 0 : status = ixgbe_read_nvm_sr_copy(hw, bank, E610_SR_NVM_EETRACK_LO,
2595 : : &eetrack_lo);
2596 [ # # ]: 0 : if (status) {
2597 : : return status;
2598 : : }
2599 : 0 : status = ixgbe_read_nvm_sr_copy(hw, bank, E610_SR_NVM_EETRACK_HI,
2600 : : &eetrack_hi);
2601 [ # # ]: 0 : if (status) {
2602 : : return status;
2603 : : }
2604 : :
2605 : 0 : nvm->eetrack = (eetrack_hi << 16) | eetrack_lo;
2606 : :
2607 : 0 : status = ixgbe_get_nvm_srev(hw, bank, &nvm->srev);
2608 : :
2609 : 0 : return IXGBE_SUCCESS;
2610 : : }
2611 : :
2612 : : /**
2613 : : * ixgbe_get_inactive_nvm_ver - Read Option ROM version from the inactive bank
2614 : : * @hw: pointer to the HW structure
2615 : : * @nvm: storage for Option ROM version information
2616 : : *
2617 : : * Reads the NVM EETRACK ID, Map version, and security revision of the
2618 : : * inactive NVM bank. Used to access version data for a pending update that
2619 : : * has not yet been activated.
2620 : : *
2621 : : * Return: the exit code of the operation.
2622 : : */
2623 : 0 : s32 ixgbe_get_inactive_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm)
2624 : : {
2625 : 0 : return ixgbe_get_nvm_ver_info(hw, IXGBE_INACTIVE_FLASH_BANK, nvm);
2626 : : }
2627 : :
2628 : : /**
2629 : : * ixgbe_get_active_nvm_ver - Read Option ROM version from the active bank
2630 : : * @hw: pointer to the HW structure
2631 : : * @nvm: storage for Option ROM version information
2632 : : *
2633 : : * Reads the NVM EETRACK ID, Map version, and security revision of the
2634 : : * active NVM bank.
2635 : : *
2636 : : * Return: the exit code of the operation.
2637 : : */
2638 : 0 : s32 ixgbe_get_active_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm)
2639 : : {
2640 : 0 : return ixgbe_get_nvm_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK, nvm);
2641 : : }
2642 : :
2643 : : /**
2644 : : * ixgbe_read_sr_pointer - Read the value of a Shadow RAM pointer word
2645 : : * @hw: pointer to the HW structure
2646 : : * @offset: the word offset of the Shadow RAM word to read
2647 : : * @pointer: pointer value read from Shadow RAM
2648 : : *
2649 : : * Read the given Shadow RAM word, and convert it to a pointer value specified
2650 : : * in bytes. This function assumes the specified offset is a valid pointer
2651 : : * word.
2652 : : *
2653 : : * Each pointer word specifies whether it is stored in word size or 4KB
2654 : : * sector size by using the highest bit. The reported pointer value will be in
2655 : : * bytes, intended for flat NVM reads.
2656 : : *
2657 : : * Return: the exit code of the operation.
2658 : : */
2659 : 0 : static s32 ixgbe_read_sr_pointer(struct ixgbe_hw *hw, u16 offset, u32 *pointer)
2660 : : {
2661 : : s32 status;
2662 : : u16 value;
2663 : :
2664 : 0 : status = ixgbe_read_ee_aci_E610(hw, offset, &value);
2665 [ # # ]: 0 : if (status)
2666 : : return status;
2667 : :
2668 : : /* Determine if the pointer is in 4KB or word units */
2669 [ # # ]: 0 : if (value & IXGBE_SR_NVM_PTR_4KB_UNITS)
2670 : 0 : *pointer = (value & ~IXGBE_SR_NVM_PTR_4KB_UNITS) * 4 * 1024;
2671 : : else
2672 : 0 : *pointer = value * 2;
2673 : :
2674 : : return IXGBE_SUCCESS;
2675 : : }
2676 : :
2677 : : /**
2678 : : * ixgbe_read_sr_area_size - Read an area size from a Shadow RAM word
2679 : : * @hw: pointer to the HW structure
2680 : : * @offset: the word offset of the Shadow RAM to read
2681 : : * @size: size value read from the Shadow RAM
2682 : : *
2683 : : * Read the given Shadow RAM word, and convert it to an area size value
2684 : : * specified in bytes. This function assumes the specified offset is a valid
2685 : : * area size word.
2686 : : *
2687 : : * Each area size word is specified in 4KB sector units. This function reports
2688 : : * the size in bytes, intended for flat NVM reads.
2689 : : *
2690 : : * Return: the exit code of the operation.
2691 : : */
2692 : : static s32 ixgbe_read_sr_area_size(struct ixgbe_hw *hw, u16 offset, u32 *size)
2693 : : {
2694 : : s32 status;
2695 : : u16 value;
2696 : :
2697 : 0 : status = ixgbe_read_ee_aci_E610(hw, offset, &value);
2698 [ # # # # : 0 : if (status)
# # ]
2699 : : return status;
2700 : :
2701 : : /* Area sizes are always specified in 4KB units */
2702 : 0 : *size = value * 4 * 1024;
2703 : :
2704 : : return IXGBE_SUCCESS;
2705 : : }
2706 : :
2707 : : /**
2708 : : * ixgbe_discover_flash_size - Discover the available flash size.
2709 : : * @hw: pointer to the HW struct
2710 : : *
2711 : : * The device flash could be up to 16MB in size. However, it is possible that
2712 : : * the actual size is smaller. Use bisection to determine the accessible size
2713 : : * of flash memory.
2714 : : *
2715 : : * Return: the exit code of the operation.
2716 : : */
2717 : 0 : static s32 ixgbe_discover_flash_size(struct ixgbe_hw *hw)
2718 : : {
2719 : : u32 min_size = 0, max_size = IXGBE_ACI_NVM_MAX_OFFSET + 1;
2720 : : s32 status;
2721 : :
2722 : 0 : status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ);
2723 [ # # ]: 0 : if (status)
2724 : : return status;
2725 : :
2726 [ # # ]: 0 : while ((max_size - min_size) > 1) {
2727 : 0 : u32 offset = (max_size + min_size) / 2;
2728 : 0 : u32 len = 1;
2729 : : u8 data;
2730 : :
2731 : 0 : status = ixgbe_read_flat_nvm(hw, offset, &len, &data, false);
2732 [ # # ]: 0 : if (status == IXGBE_ERR_ACI_ERROR &&
2733 [ # # ]: 0 : hw->aci.last_status == IXGBE_ACI_RC_EINVAL) {
2734 : : status = IXGBE_SUCCESS;
2735 : : max_size = offset;
2736 [ # # ]: 0 : } else if (!status) {
2737 : : min_size = offset;
2738 : : } else {
2739 : : /* an unexpected error occurred */
2740 : 0 : goto err_read_flat_nvm;
2741 : : }
2742 : : }
2743 : :
2744 : 0 : hw->flash.flash_size = max_size;
2745 : :
2746 : 0 : err_read_flat_nvm:
2747 : 0 : ixgbe_release_nvm(hw);
2748 : :
2749 : 0 : return status;
2750 : : }
2751 : :
2752 : : /**
2753 : : * ixgbe_determine_active_flash_banks - Discover active bank for each module
2754 : : * @hw: pointer to the HW struct
2755 : : *
2756 : : * Read the Shadow RAM control word and determine which banks are active for
2757 : : * the NVM, OROM, and Netlist modules. Also read and calculate the associated
2758 : : * pointer and size. These values are then cached into the ixgbe_flash_info
2759 : : * structure for later use in order to calculate the correct offset to read
2760 : : * from the active module.
2761 : : *
2762 : : * Return: the exit code of the operation.
2763 : : */
2764 : 0 : static s32 ixgbe_determine_active_flash_banks(struct ixgbe_hw *hw)
2765 : : {
2766 : : struct ixgbe_bank_info *banks = &hw->flash.banks;
2767 : : u16 ctrl_word;
2768 : : s32 status;
2769 : :
2770 : 0 : status = ixgbe_read_ee_aci_E610(hw, E610_SR_NVM_CTRL_WORD, &ctrl_word);
2771 [ # # ]: 0 : if (status) {
2772 : : return status;
2773 : : }
2774 : :
2775 : : /* Check that the control word indicates validity */
2776 [ # # ]: 0 : if ((ctrl_word & IXGBE_SR_CTRL_WORD_1_M) >> IXGBE_SR_CTRL_WORD_1_S !=
2777 : : IXGBE_SR_CTRL_WORD_VALID) {
2778 : : return IXGBE_ERR_CONFIG;
2779 : : }
2780 : :
2781 [ # # ]: 0 : if (!(ctrl_word & IXGBE_SR_CTRL_WORD_NVM_BANK))
2782 : 0 : banks->nvm_bank = IXGBE_1ST_FLASH_BANK;
2783 : : else
2784 : 0 : banks->nvm_bank = IXGBE_2ND_FLASH_BANK;
2785 : :
2786 [ # # ]: 0 : if (!(ctrl_word & IXGBE_SR_CTRL_WORD_OROM_BANK))
2787 : 0 : banks->orom_bank = IXGBE_1ST_FLASH_BANK;
2788 : : else
2789 : 0 : banks->orom_bank = IXGBE_2ND_FLASH_BANK;
2790 : :
2791 [ # # ]: 0 : if (!(ctrl_word & IXGBE_SR_CTRL_WORD_NETLIST_BANK))
2792 : 0 : banks->netlist_bank = IXGBE_1ST_FLASH_BANK;
2793 : : else
2794 : 0 : banks->netlist_bank = IXGBE_2ND_FLASH_BANK;
2795 : :
2796 : 0 : status = ixgbe_read_sr_pointer(hw, E610_SR_1ST_NVM_BANK_PTR,
2797 : : &banks->nvm_ptr);
2798 [ # # ]: 0 : if (status) {
2799 : : return status;
2800 : : }
2801 : :
2802 : : status = ixgbe_read_sr_area_size(hw, E610_SR_NVM_BANK_SIZE,
2803 : : &banks->nvm_size);
2804 : : if (status) {
2805 : 0 : return status;
2806 : : }
2807 : :
2808 : 0 : status = ixgbe_read_sr_pointer(hw, E610_SR_1ST_OROM_BANK_PTR,
2809 : : &banks->orom_ptr);
2810 [ # # ]: 0 : if (status) {
2811 : : return status;
2812 : : }
2813 : :
2814 : : status = ixgbe_read_sr_area_size(hw, E610_SR_OROM_BANK_SIZE,
2815 : : &banks->orom_size);
2816 : : if (status) {
2817 : 0 : return status;
2818 : : }
2819 : :
2820 : 0 : status = ixgbe_read_sr_pointer(hw, E610_SR_NETLIST_BANK_PTR,
2821 : : &banks->netlist_ptr);
2822 [ # # ]: 0 : if (status) {
2823 : : return status;
2824 : : }
2825 : :
2826 : : status = ixgbe_read_sr_area_size(hw, E610_SR_NETLIST_BANK_SIZE,
2827 : : &banks->netlist_size);
2828 : : if (status) {
2829 : 0 : return status;
2830 : : }
2831 : :
2832 : : return IXGBE_SUCCESS;
2833 : : }
2834 : :
2835 : : /**
2836 : : * ixgbe_init_nvm - initializes NVM setting
2837 : : * @hw: pointer to the HW struct
2838 : : *
2839 : : * Read and populate NVM settings such as Shadow RAM size,
2840 : : * max_timeout, and blank_nvm_mode
2841 : : *
2842 : : * Return: the exit code of the operation.
2843 : : */
2844 : 0 : s32 ixgbe_init_nvm(struct ixgbe_hw *hw)
2845 : : {
2846 : : struct ixgbe_flash_info *flash = &hw->flash;
2847 : : u32 fla, gens_stat, status;
2848 : : u8 sr_size;
2849 : :
2850 : : /* The SR size is stored regardless of the NVM programming mode
2851 : : * as the blank mode may be used in the factory line.
2852 : : */
2853 : 0 : gens_stat = IXGBE_READ_REG(hw, GLNVM_GENS);
2854 : 0 : sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >> GLNVM_GENS_SR_SIZE_S;
2855 : :
2856 : : /* Switching to words (sr_size contains power of 2) */
2857 : 0 : flash->sr_words = BIT(sr_size) * IXGBE_SR_WORDS_IN_1KB;
2858 : :
2859 : : /* Check if we are in the normal or blank NVM programming mode */
2860 : 0 : fla = IXGBE_READ_REG(hw, GLNVM_FLA);
2861 [ # # ]: 0 : if (fla & GLNVM_FLA_LOCKED_M) { /* Normal programming mode */
2862 : 0 : flash->blank_nvm_mode = false;
2863 : : } else {
2864 : : /* Blank programming mode */
2865 : 0 : flash->blank_nvm_mode = true;
2866 : 0 : return IXGBE_ERR_NVM_BLANK_MODE;
2867 : : }
2868 : :
2869 : 0 : status = ixgbe_discover_flash_size(hw);
2870 [ # # ]: 0 : if (status) {
2871 : : return status;
2872 : : }
2873 : :
2874 : 0 : status = ixgbe_determine_active_flash_banks(hw);
2875 [ # # ]: 0 : if (status) {
2876 : : return status;
2877 : : }
2878 : :
2879 : 0 : status = ixgbe_get_nvm_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK,
2880 : : &flash->nvm);
2881 [ # # ]: 0 : if (status) {
2882 : 0 : return status;
2883 : : }
2884 : :
2885 : : return IXGBE_SUCCESS;
2886 : : }
2887 : :
2888 : : /**
2889 : : * ixgbe_sanitize_operate - Clear the user data
2890 : : * @hw: pointer to the HW struct
2891 : : *
2892 : : * Clear user data from NVM using ACI command (0x070C).
2893 : : *
2894 : : * Return: the exit code of the operation.
2895 : : */
2896 : 0 : s32 ixgbe_sanitize_operate(struct ixgbe_hw *hw)
2897 : : {
2898 : : s32 status;
2899 : : u8 values;
2900 : :
2901 : : u8 cmd_flags = IXGBE_ACI_SANITIZE_REQ_OPERATE |
2902 : : IXGBE_ACI_SANITIZE_OPERATE_SUBJECT_CLEAR;
2903 : :
2904 : 0 : status = ixgbe_sanitize_nvm(hw, cmd_flags, &values);
2905 [ # # ]: 0 : if (status)
2906 : : return status;
2907 [ # # ]: 0 : if ((!(values & IXGBE_ACI_SANITIZE_OPERATE_HOST_CLEAN_DONE) &&
2908 [ # # ]: 0 : !(values & IXGBE_ACI_SANITIZE_OPERATE_BMC_CLEAN_DONE)) ||
2909 : : ((values & IXGBE_ACI_SANITIZE_OPERATE_HOST_CLEAN_DONE) &&
2910 [ # # ]: 0 : !(values & IXGBE_ACI_SANITIZE_OPERATE_HOST_CLEAN_SUCCESS)) ||
2911 : : ((values & IXGBE_ACI_SANITIZE_OPERATE_BMC_CLEAN_DONE) &&
2912 : : !(values & IXGBE_ACI_SANITIZE_OPERATE_BMC_CLEAN_SUCCESS)))
2913 : 0 : return IXGBE_ERR_ACI_ERROR;
2914 : :
2915 : : return IXGBE_SUCCESS;
2916 : : }
2917 : :
2918 : : /**
2919 : : * ixgbe_sanitize_nvm - Sanitize NVM
2920 : : * @hw: pointer to the HW struct
2921 : : * @cmd_flags: flag to the ACI command
2922 : : * @values: values returned from the command
2923 : : *
2924 : : * Sanitize NVM using ACI command (0x070C).
2925 : : *
2926 : : * Return: the exit code of the operation.
2927 : : */
2928 : 0 : s32 ixgbe_sanitize_nvm(struct ixgbe_hw *hw, u8 cmd_flags, u8 *values)
2929 : : {
2930 : : struct ixgbe_aci_desc desc;
2931 : : struct ixgbe_aci_cmd_nvm_sanitization *cmd;
2932 : : s32 status;
2933 : :
2934 : : cmd = &desc.params.nvm_sanitization;
2935 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_nvm_sanitization);
2936 : 0 : cmd->cmd_flags = cmd_flags;
2937 : :
2938 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
2939 [ # # ]: 0 : if (values)
2940 : 0 : *values = cmd->values;
2941 : :
2942 : 0 : return status;
2943 : : }
2944 : :
2945 : : /**
2946 : : * ixgbe_read_sr_word_aci - Reads Shadow RAM via ACI
2947 : : * @hw: pointer to the HW structure
2948 : : * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
2949 : : * @data: word read from the Shadow RAM
2950 : : *
2951 : : * Reads one 16 bit word from the Shadow RAM using ixgbe_read_flat_nvm.
2952 : : *
2953 : : * Return: the exit code of the operation.
2954 : : */
2955 : 0 : s32 ixgbe_read_sr_word_aci(struct ixgbe_hw *hw, u16 offset, u16 *data)
2956 : : {
2957 : 0 : u32 bytes = sizeof(u16);
2958 : : __le16 data_local;
2959 : : s32 status;
2960 : :
2961 : 0 : status = ixgbe_read_flat_nvm(hw, offset * sizeof(u16), &bytes,
2962 : : (u8 *)&data_local, true);
2963 [ # # ]: 0 : if (status)
2964 : : return status;
2965 : :
2966 : 0 : *data = IXGBE_LE16_TO_CPU(data_local);
2967 : 0 : return IXGBE_SUCCESS;
2968 : : }
2969 : :
2970 : : /**
2971 : : * ixgbe_read_sr_buf_aci - Reads Shadow RAM buf via ACI
2972 : : * @hw: pointer to the HW structure
2973 : : * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
2974 : : * @words: (in) number of words to read; (out) number of words actually read
2975 : : * @data: words read from the Shadow RAM
2976 : : *
2977 : : * Reads 16 bit words (data buf) from the Shadow RAM. Ownership of the NVM is
2978 : : * taken before reading the buffer and later released.
2979 : : *
2980 : : * Return: the exit code of the operation.
2981 : : */
2982 : 0 : s32 ixgbe_read_sr_buf_aci(struct ixgbe_hw *hw, u16 offset, u16 *words,
2983 : : u16 *data)
2984 : : {
2985 : 0 : u32 bytes = *words * 2, i;
2986 : : s32 status;
2987 : :
2988 : 0 : status = ixgbe_read_flat_nvm(hw, offset * 2, &bytes, (u8 *)data, true);
2989 : :
2990 : 0 : *words = bytes / 2;
2991 : :
2992 : : for (i = 0; i < *words; i++)
2993 : : data[i] = IXGBE_LE16_TO_CPU(((__le16 *)data)[i]);
2994 : :
2995 : 0 : return status;
2996 : : }
2997 : :
2998 : : /**
2999 : : * ixgbe_read_flat_nvm - Read portion of NVM by flat offset
3000 : : * @hw: pointer to the HW struct
3001 : : * @offset: offset from beginning of NVM
3002 : : * @length: (in) number of bytes to read; (out) number of bytes actually read
3003 : : * @data: buffer to return data in (sized to fit the specified length)
3004 : : * @read_shadow_ram: if true, read from shadow RAM instead of NVM
3005 : : *
3006 : : * Reads a portion of the NVM, as a flat memory space. This function correctly
3007 : : * breaks read requests across Shadow RAM sectors, prevents Shadow RAM size
3008 : : * from being exceeded in case of Shadow RAM read requests and ensures that no
3009 : : * single read request exceeds the maximum 4KB read for a single admin command.
3010 : : *
3011 : : * Returns a status code on failure. Note that the data pointer may be
3012 : : * partially updated if some reads succeed before a failure.
3013 : : *
3014 : : * Return: the exit code of the operation.
3015 : : */
3016 : 0 : s32 ixgbe_read_flat_nvm(struct ixgbe_hw *hw, u32 offset, u32 *length,
3017 : : u8 *data, bool read_shadow_ram)
3018 : : {
3019 : 0 : u32 inlen = *length;
3020 : : u32 bytes_read = 0;
3021 : : bool last_cmd;
3022 : : s32 status;
3023 : :
3024 : 0 : *length = 0;
3025 : :
3026 : : /* Verify the length of the read if this is for the Shadow RAM */
3027 [ # # ]: 0 : if (read_shadow_ram && ((offset + inlen) >
3028 [ # # ]: 0 : (hw->eeprom.word_size * 2u))) {
3029 : : return IXGBE_ERR_PARAM;
3030 : : }
3031 : :
3032 : : do {
3033 : : u32 read_size, sector_offset;
3034 : :
3035 : : /* ixgbe_aci_read_nvm cannot read more than 4KB at a time.
3036 : : * Additionally, a read from the Shadow RAM may not cross over
3037 : : * a sector boundary. Conveniently, the sector size is also 4KB.
3038 : : */
3039 : 0 : sector_offset = offset % IXGBE_ACI_MAX_BUFFER_SIZE;
3040 : 0 : read_size = MIN_T(u32,
3041 : : IXGBE_ACI_MAX_BUFFER_SIZE - sector_offset,
3042 : : inlen - bytes_read);
3043 : :
3044 : 0 : last_cmd = !(bytes_read + read_size < inlen);
3045 : :
3046 : : /* ixgbe_aci_read_nvm takes the length as a u16. Our read_size
3047 : : * is calculated using a u32, but the IXGBE_ACI_MAX_BUFFER_SIZE
3048 : : * maximum size guarantees that it will fit within the 2 bytes.
3049 : : */
3050 : 0 : status = ixgbe_aci_read_nvm(hw, IXGBE_ACI_NVM_START_POINT,
3051 : : offset, (u16)read_size,
3052 : 0 : data + bytes_read, last_cmd,
3053 : : read_shadow_ram);
3054 [ # # ]: 0 : if (status)
3055 : : break;
3056 : :
3057 : : bytes_read += read_size;
3058 : 0 : offset += read_size;
3059 [ # # ]: 0 : } while (!last_cmd);
3060 : :
3061 : 0 : *length = bytes_read;
3062 : 0 : return status;
3063 : : }
3064 : :
3065 : : /**
3066 : : * ixgbe_aci_alternate_write - write to alternate structure
3067 : : * @hw: pointer to the hardware structure
3068 : : * @reg_addr0: address of first dword to be written
3069 : : * @reg_val0: value to be written under 'reg_addr0'
3070 : : * @reg_addr1: address of second dword to be written
3071 : : * @reg_val1: value to be written under 'reg_addr1'
3072 : : *
3073 : : * Write one or two dwords to alternate structure using ACI command (0x0900).
3074 : : * Fields are indicated by 'reg_addr0' and 'reg_addr1' register numbers.
3075 : : *
3076 : : * Return: 0 on success and error code on failure.
3077 : : */
3078 : 0 : s32 ixgbe_aci_alternate_write(struct ixgbe_hw *hw, u32 reg_addr0,
3079 : : u32 reg_val0, u32 reg_addr1, u32 reg_val1)
3080 : : {
3081 : : struct ixgbe_aci_cmd_read_write_alt_direct *cmd;
3082 : : struct ixgbe_aci_desc desc;
3083 : : s32 status;
3084 : :
3085 : : cmd = &desc.params.read_write_alt_direct;
3086 : :
3087 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_write_alt_direct);
3088 : 0 : cmd->dword0_addr = IXGBE_CPU_TO_LE32(reg_addr0);
3089 : 0 : cmd->dword1_addr = IXGBE_CPU_TO_LE32(reg_addr1);
3090 : 0 : cmd->dword0_value = IXGBE_CPU_TO_LE32(reg_val0);
3091 : 0 : cmd->dword1_value = IXGBE_CPU_TO_LE32(reg_val1);
3092 : :
3093 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
3094 : :
3095 : 0 : return status;
3096 : : }
3097 : :
3098 : : /**
3099 : : * ixgbe_aci_alternate_read - read from alternate structure
3100 : : * @hw: pointer to the hardware structure
3101 : : * @reg_addr0: address of first dword to be read
3102 : : * @reg_val0: pointer for data read from 'reg_addr0'
3103 : : * @reg_addr1: address of second dword to be read
3104 : : * @reg_val1: pointer for data read from 'reg_addr1'
3105 : : *
3106 : : * Read one or two dwords from alternate structure using ACI command (0x0902).
3107 : : * Fields are indicated by 'reg_addr0' and 'reg_addr1' register numbers.
3108 : : * If 'reg_val1' pointer is not passed then only register at 'reg_addr0'
3109 : : * is read.
3110 : : *
3111 : : * Return: 0 on success and error code on failure.
3112 : : */
3113 : 0 : s32 ixgbe_aci_alternate_read(struct ixgbe_hw *hw, u32 reg_addr0,
3114 : : u32 *reg_val0, u32 reg_addr1, u32 *reg_val1)
3115 : : {
3116 : : struct ixgbe_aci_cmd_read_write_alt_direct *cmd;
3117 : : struct ixgbe_aci_desc desc;
3118 : : s32 status;
3119 : :
3120 : : cmd = &desc.params.read_write_alt_direct;
3121 : :
3122 [ # # ]: 0 : if (!reg_val0)
3123 : : return IXGBE_ERR_PARAM;
3124 : :
3125 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_read_alt_direct);
3126 : 0 : cmd->dword0_addr = IXGBE_CPU_TO_LE32(reg_addr0);
3127 : 0 : cmd->dword1_addr = IXGBE_CPU_TO_LE32(reg_addr1);
3128 : :
3129 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
3130 : :
3131 [ # # ]: 0 : if (status == IXGBE_SUCCESS) {
3132 : 0 : *reg_val0 = IXGBE_LE32_TO_CPU(cmd->dword0_value);
3133 : :
3134 [ # # ]: 0 : if (reg_val1)
3135 : 0 : *reg_val1 = IXGBE_LE32_TO_CPU(cmd->dword1_value);
3136 : : }
3137 : :
3138 : : return status;
3139 : : }
3140 : :
3141 : : /**
3142 : : * ixgbe_aci_alternate_write_done - check if writing to alternate structure
3143 : : * is done
3144 : : * @hw: pointer to the HW structure.
3145 : : * @bios_mode: indicates whether the command is executed by UEFI or legacy BIOS
3146 : : * @reset_needed: indicates the SW should trigger GLOBAL reset
3147 : : *
3148 : : * Indicates to the FW that alternate structures have been changed.
3149 : : *
3150 : : * Return: 0 on success and error code on failure.
3151 : : */
3152 : 0 : s32 ixgbe_aci_alternate_write_done(struct ixgbe_hw *hw, u8 bios_mode,
3153 : : bool *reset_needed)
3154 : : {
3155 : : struct ixgbe_aci_cmd_done_alt_write *cmd;
3156 : : struct ixgbe_aci_desc desc;
3157 : : s32 status;
3158 : :
3159 : : cmd = &desc.params.done_alt_write;
3160 : :
3161 [ # # ]: 0 : if (!reset_needed)
3162 : : return IXGBE_ERR_PARAM;
3163 : :
3164 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_done_alt_write);
3165 : 0 : cmd->flags = bios_mode;
3166 : :
3167 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
3168 [ # # ]: 0 : if (!status)
3169 : 0 : *reset_needed = (IXGBE_LE16_TO_CPU(cmd->flags) &
3170 : 0 : IXGBE_ACI_RESP_RESET_NEEDED) != 0;
3171 : :
3172 : : return status;
3173 : : }
3174 : :
3175 : : /**
3176 : : * ixgbe_aci_alternate_clear - clear alternate structure
3177 : : * @hw: pointer to the HW structure.
3178 : : *
3179 : : * Clear the alternate structures of the port from which the function
3180 : : * is called.
3181 : : *
3182 : : * Return: 0 on success and error code on failure.
3183 : : */
3184 : 0 : s32 ixgbe_aci_alternate_clear(struct ixgbe_hw *hw)
3185 : : {
3186 : : struct ixgbe_aci_desc desc;
3187 : : s32 status;
3188 : :
3189 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc,
3190 : : ixgbe_aci_opc_clear_port_alt_write);
3191 : :
3192 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, NULL, 0);
3193 : :
3194 : 0 : return status;
3195 : : }
3196 : :
3197 : : /**
3198 : : * ixgbe_aci_get_internal_data - get internal FW/HW data
3199 : : * @hw: pointer to the hardware structure
3200 : : * @cluster_id: specific cluster to dump
3201 : : * @table_id: table ID within cluster
3202 : : * @start: index of line in the block to read
3203 : : * @buf: dump buffer
3204 : : * @buf_size: dump buffer size
3205 : : * @ret_buf_size: return buffer size (returned by FW)
3206 : : * @ret_next_cluster: next cluster to read (returned by FW)
3207 : : * @ret_next_table: next block to read (returned by FW)
3208 : : * @ret_next_index: next index to read (returned by FW)
3209 : : *
3210 : : * Get internal FW/HW data using ACI command (0xFF08) for debug purposes.
3211 : : *
3212 : : * Return: the exit code of the operation.
3213 : : */
3214 : 0 : s32 ixgbe_aci_get_internal_data(struct ixgbe_hw *hw, u16 cluster_id,
3215 : : u16 table_id, u32 start, void *buf,
3216 : : u16 buf_size, u16 *ret_buf_size,
3217 : : u16 *ret_next_cluster, u16 *ret_next_table,
3218 : : u32 *ret_next_index)
3219 : : {
3220 : : struct ixgbe_aci_cmd_debug_dump_internals *cmd;
3221 : : struct ixgbe_aci_desc desc;
3222 : : s32 status;
3223 : :
3224 : : cmd = &desc.params.debug_dump;
3225 : :
3226 [ # # ]: 0 : if (buf_size == 0 || !buf)
3227 : : return IXGBE_ERR_PARAM;
3228 : :
3229 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc,
3230 : : ixgbe_aci_opc_debug_dump_internals);
3231 : :
3232 : 0 : cmd->cluster_id = IXGBE_CPU_TO_LE16(cluster_id);
3233 : 0 : cmd->table_id = IXGBE_CPU_TO_LE16(table_id);
3234 : 0 : cmd->idx = IXGBE_CPU_TO_LE32(start);
3235 : :
3236 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, buf, buf_size);
3237 : :
3238 [ # # ]: 0 : if (!status) {
3239 [ # # ]: 0 : if (ret_buf_size)
3240 : 0 : *ret_buf_size = IXGBE_LE16_TO_CPU(desc.datalen);
3241 [ # # ]: 0 : if (ret_next_cluster)
3242 : 0 : *ret_next_cluster = IXGBE_LE16_TO_CPU(cmd->cluster_id);
3243 [ # # ]: 0 : if (ret_next_table)
3244 : 0 : *ret_next_table = IXGBE_LE16_TO_CPU(cmd->table_id);
3245 [ # # ]: 0 : if (ret_next_index)
3246 : 0 : *ret_next_index = IXGBE_LE32_TO_CPU(cmd->idx);
3247 : : }
3248 : :
3249 : : return status;
3250 : : }
3251 : :
3252 : : /**
3253 : : * ixgbe_validate_nvm_rw_reg - Check that an NVM access request is valid
3254 : : * @cmd: NVM access command structure
3255 : : *
3256 : : * Validates that an NVM access structure is request to read or write a valid
3257 : : * register offset. First validates that the module and flags are correct, and
3258 : : * then ensures that the register offset is one of the accepted registers.
3259 : : *
3260 : : * Return: 0 if the register access is valid, out of range error code otherwise.
3261 : : */
3262 : : static s32
3263 : 0 : ixgbe_validate_nvm_rw_reg(struct ixgbe_nvm_access_cmd *cmd)
3264 : : {
3265 : : u16 i;
3266 : :
3267 [ # # ]: 0 : switch (cmd->offset) {
3268 : : case GL_HICR:
3269 : : case GL_HICR_EN: /* Note, this register is read only */
3270 : : case GL_FWSTS:
3271 : : case GL_MNG_FWSM:
3272 : : case GLNVM_GENS:
3273 : : case GLNVM_FLA:
3274 : : case GL_FWRESETCNT:
3275 : : return 0;
3276 : : default:
3277 : : break;
3278 : : }
3279 : :
3280 [ # # ]: 0 : for (i = 0; i <= GL_HIDA_MAX_INDEX; i++)
3281 [ # # ]: 0 : if (cmd->offset == (u32)GL_HIDA(i))
3282 : : return 0;
3283 : :
3284 [ # # ]: 0 : for (i = 0; i <= GL_HIBA_MAX_INDEX; i++)
3285 [ # # ]: 0 : if (cmd->offset == (u32)GL_HIBA(i))
3286 : : return 0;
3287 : :
3288 : : /* All other register offsets are not valid */
3289 : : return IXGBE_ERR_OUT_OF_RANGE;
3290 : : }
3291 : :
3292 : : /**
3293 : : * ixgbe_nvm_access_read - Handle an NVM read request
3294 : : * @hw: pointer to the HW struct
3295 : : * @cmd: NVM access command to process
3296 : : * @data: storage for the register value read
3297 : : *
3298 : : * Process an NVM access request to read a register.
3299 : : *
3300 : : * Return: 0 if the register read is valid and successful,
3301 : : * out of range error code otherwise.
3302 : : */
3303 : 0 : static s32 ixgbe_nvm_access_read(struct ixgbe_hw *hw,
3304 : : struct ixgbe_nvm_access_cmd *cmd,
3305 : : struct ixgbe_nvm_access_data *data)
3306 : : {
3307 : : s32 status;
3308 : :
3309 : : /* Always initialize the output data, even on failure */
3310 [ # # ]: 0 : memset(&data->regval, 0, cmd->data_size);
3311 : :
3312 : : /* Make sure this is a valid read/write access request */
3313 : 0 : status = ixgbe_validate_nvm_rw_reg(cmd);
3314 [ # # ]: 0 : if (status)
3315 : : return status;
3316 : :
3317 : 0 : DEBUGOUT1("NVM access: reading register %08x\n", cmd->offset);
3318 : :
3319 : : /* Read the register and store the contents in the data field */
3320 : 0 : data->regval = IXGBE_READ_REG(hw, cmd->offset);
3321 : :
3322 : 0 : return 0;
3323 : : }
3324 : :
3325 : : /**
3326 : : * ixgbe_nvm_access_write - Handle an NVM write request
3327 : : * @hw: pointer to the HW struct
3328 : : * @cmd: NVM access command to process
3329 : : * @data: NVM access data to write
3330 : : *
3331 : : * Process an NVM access request to write a register.
3332 : : *
3333 : : * Return: 0 if the register write is valid and successful,
3334 : : * out of range error code otherwise.
3335 : : */
3336 : 0 : static s32 ixgbe_nvm_access_write(struct ixgbe_hw *hw,
3337 : : struct ixgbe_nvm_access_cmd *cmd,
3338 : : struct ixgbe_nvm_access_data *data)
3339 : : {
3340 : : s32 status;
3341 : :
3342 : : /* Make sure this is a valid read/write access request */
3343 : 0 : status = ixgbe_validate_nvm_rw_reg(cmd);
3344 [ # # ]: 0 : if (status)
3345 : : return status;
3346 : :
3347 : : /* Reject requests to write to read-only registers */
3348 [ # # ]: 0 : switch (cmd->offset) {
3349 : : case GL_HICR_EN:
3350 : : return IXGBE_ERR_OUT_OF_RANGE;
3351 : : default:
3352 : : break;
3353 : : }
3354 : :
3355 : 0 : DEBUGOUT2("NVM access: writing register %08x with value %08x\n",
3356 : : cmd->offset, data->regval);
3357 : :
3358 : : /* Write the data field to the specified register */
3359 : 0 : IXGBE_WRITE_REG(hw, cmd->offset, data->regval);
3360 : :
3361 : 0 : return 0;
3362 : : }
3363 : :
3364 : : /**
3365 : : * ixgbe_handle_nvm_access - Handle an NVM access request
3366 : : * @hw: pointer to the HW struct
3367 : : * @cmd: NVM access command info
3368 : : * @data: pointer to read or return data
3369 : : *
3370 : : * Process an NVM access request. Read the command structure information and
3371 : : * determine if it is valid. If not, report an error indicating the command
3372 : : * was invalid.
3373 : : *
3374 : : * For valid commands, perform the necessary function, copying the data into
3375 : : * the provided data buffer.
3376 : : *
3377 : : * Return: 0 if the nvm access request is valid and successful,
3378 : : * error code otherwise.
3379 : : */
3380 : 0 : s32 ixgbe_handle_nvm_access(struct ixgbe_hw *hw,
3381 : : struct ixgbe_nvm_access_cmd *cmd,
3382 : : struct ixgbe_nvm_access_data *data)
3383 : : {
3384 [ # # # ]: 0 : switch (cmd->command) {
3385 : 0 : case IXGBE_NVM_CMD_READ:
3386 : 0 : return ixgbe_nvm_access_read(hw, cmd, data);
3387 : 0 : case IXGBE_NVM_CMD_WRITE:
3388 : 0 : return ixgbe_nvm_access_write(hw, cmd, data);
3389 : : default:
3390 : : return IXGBE_ERR_PARAM;
3391 : : }
3392 : : }
3393 : :
3394 : : /**
3395 : : * ixgbe_init_ops_E610 - Inits func ptrs and MAC type
3396 : : * @hw: pointer to hardware structure
3397 : : *
3398 : : * Initialize the function pointers and assign the MAC type for E610.
3399 : : * Does not touch the hardware.
3400 : : *
3401 : : * Return: the exit code of the operation.
3402 : : */
3403 : 0 : s32 ixgbe_init_ops_E610(struct ixgbe_hw *hw)
3404 : : {
3405 : : struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
3406 : : struct ixgbe_mac_info *mac = &hw->mac;
3407 : : struct ixgbe_phy_info *phy = &hw->phy;
3408 : : s32 ret_val;
3409 : :
3410 : 0 : ret_val = ixgbe_init_ops_X550(hw);
3411 : : /* TODO Additional ops overrides for e610 to go here */
3412 : :
3413 : : /* MAC */
3414 : 0 : mac->ops.reset_hw = ixgbe_reset_hw_E610;
3415 : 0 : mac->ops.start_hw = ixgbe_start_hw_E610;
3416 : 0 : mac->ops.get_media_type = ixgbe_get_media_type_E610;
3417 : 0 : mac->ops.get_supported_physical_layer =
3418 : : ixgbe_get_supported_physical_layer_E610;
3419 : 0 : mac->ops.get_san_mac_addr = NULL;
3420 : 0 : mac->ops.set_san_mac_addr = NULL;
3421 : 0 : mac->ops.get_wwn_prefix = NULL;
3422 : 0 : mac->ops.setup_link = ixgbe_setup_link_E610;
3423 : 0 : mac->ops.check_link = ixgbe_check_link_E610;
3424 : 0 : mac->ops.get_link_capabilities = ixgbe_get_link_capabilities_E610;
3425 : 0 : mac->ops.setup_fc = ixgbe_setup_fc_E610;
3426 : 0 : mac->ops.fc_autoneg = ixgbe_fc_autoneg_E610;
3427 : 0 : mac->ops.set_fw_drv_ver = ixgbe_set_fw_drv_ver_E610;
3428 : 0 : mac->ops.disable_rx = ixgbe_disable_rx_E610;
3429 : 0 : mac->ops.setup_eee = ixgbe_setup_eee_E610;
3430 : 0 : mac->ops.fw_recovery_mode = ixgbe_fw_recovery_mode_E610;
3431 : 0 : mac->ops.get_fw_tsam_mode = ixgbe_get_fw_tsam_mode_E610;
3432 : 0 : mac->ops.get_fw_version = ixgbe_aci_get_fw_ver;
3433 : 0 : mac->ops.get_nvm_version = ixgbe_get_active_nvm_ver;
3434 : 0 : mac->ops.get_thermal_sensor_data = NULL;
3435 : 0 : mac->ops.init_thermal_sensor_thresh = NULL;
3436 : :
3437 : : /* PHY */
3438 : 0 : phy->ops.init = ixgbe_init_phy_ops_E610;
3439 : 0 : phy->ops.identify = ixgbe_identify_phy_E610;
3440 : 0 : phy->eee_speeds_supported = IXGBE_LINK_SPEED_10_FULL |
3441 : : IXGBE_LINK_SPEED_100_FULL |
3442 : : IXGBE_LINK_SPEED_1GB_FULL;
3443 : 0 : phy->eee_speeds_advertised = phy->eee_speeds_supported;
3444 : :
3445 : : /* Additional ops overrides for e610 to go here */
3446 : 0 : eeprom->ops.init_params = ixgbe_init_eeprom_params_E610;
3447 : 0 : eeprom->ops.read = ixgbe_read_ee_aci_E610;
3448 : 0 : eeprom->ops.read_buffer = ixgbe_read_ee_aci_buffer_E610;
3449 : 0 : eeprom->ops.write = NULL;
3450 : 0 : eeprom->ops.write_buffer = NULL;
3451 : 0 : eeprom->ops.calc_checksum = ixgbe_calc_eeprom_checksum_E610;
3452 : 0 : eeprom->ops.update_checksum = NULL;
3453 : 0 : eeprom->ops.validate_checksum = ixgbe_validate_eeprom_checksum_E610;
3454 : 0 : eeprom->ops.read_pba_string = ixgbe_read_pba_string_E610;
3455 : :
3456 : : /* Initialize bus function number */
3457 : 0 : hw->mac.ops.set_lan_id(hw);
3458 : :
3459 : 0 : return ret_val;
3460 : : }
3461 : :
3462 : : /**
3463 : : * ixgbe_reset_hw_E610 - Perform hardware reset
3464 : : * @hw: pointer to hardware structure
3465 : : *
3466 : : * Resets the hardware by resetting the transmit and receive units, masks
3467 : : * and clears all interrupts, and perform a reset.
3468 : : *
3469 : : * Return: the exit code of the operation.
3470 : : */
3471 : 0 : s32 ixgbe_reset_hw_E610(struct ixgbe_hw *hw)
3472 : : {
3473 : 0 : u32 swfw_mask = hw->phy.phy_semaphore_mask;
3474 : : u32 ctrl, i;
3475 : : s32 status;
3476 : :
3477 : 0 : DEBUGFUNC("ixgbe_reset_hw_E610");
3478 : :
3479 : : /* Call adapter stop to disable tx/rx and clear interrupts */
3480 : 0 : status = hw->mac.ops.stop_adapter(hw);
3481 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
3482 : 0 : goto reset_hw_out;
3483 : :
3484 : : /* flush pending Tx transactions */
3485 : 0 : ixgbe_clear_tx_pending(hw);
3486 : :
3487 : 0 : status = hw->phy.ops.init(hw);
3488 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
3489 : 0 : DEBUGOUT1("Failed to initialize PHY ops, STATUS = %d\n",
3490 : : status);
3491 : 0 : mac_reset_top:
3492 : 0 : status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
3493 [ # # ]: 0 : if (status != IXGBE_SUCCESS) {
3494 : 0 : ERROR_REPORT2(IXGBE_ERROR_CAUTION,
3495 : : "semaphore failed with %d", status);
3496 : 0 : return IXGBE_ERR_SWFW_SYNC;
3497 : : }
3498 : : ctrl = IXGBE_CTRL_RST;
3499 : 0 : ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
3500 : 0 : IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
3501 : 0 : IXGBE_WRITE_FLUSH(hw);
3502 : 0 : hw->mac.ops.release_swfw_sync(hw, swfw_mask);
3503 : :
3504 : : /* Poll for reset bit to self-clear indicating reset is complete */
3505 [ # # ]: 0 : for (i = 0; i < 10; i++) {
3506 : 0 : usec_delay(1);
3507 : 0 : ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
3508 [ # # ]: 0 : if (!(ctrl & IXGBE_CTRL_RST_MASK))
3509 : : break;
3510 : : }
3511 : :
3512 [ # # ]: 0 : if (ctrl & IXGBE_CTRL_RST_MASK) {
3513 : : status = IXGBE_ERR_RESET_FAILED;
3514 : 0 : ERROR_REPORT1(IXGBE_ERROR_POLLING,
3515 : : "Reset polling failed to complete.\n");
3516 : : }
3517 : 0 : msec_delay(100);
3518 : :
3519 : : /*
3520 : : * Double resets are required for recovery from certain error
3521 : : * conditions. Between resets, it is necessary to stall to allow time
3522 : : * for any pending HW events to complete.
3523 : : */
3524 [ # # ]: 0 : if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
3525 : 0 : hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
3526 : 0 : goto mac_reset_top;
3527 : : }
3528 : :
3529 : : /* Set the Rx packet buffer size. */
3530 : 0 : IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0), 384 << IXGBE_RXPBSIZE_SHIFT);
3531 : :
3532 : : /* Store the permanent mac address */
3533 : 0 : hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
3534 : :
3535 : : /*
3536 : : * Store MAC address from RAR0, clear receive address registers, and
3537 : : * clear the multicast table. Also reset num_rar_entries to 128,
3538 : : * since we modify this value when programming the SAN MAC address.
3539 : : */
3540 : 0 : hw->mac.num_rar_entries = 128;
3541 : 0 : hw->mac.ops.init_rx_addrs(hw);
3542 : :
3543 : : reset_hw_out:
3544 : : return status;
3545 : : }
3546 : :
3547 : : /**
3548 : : * ixgbe_start_hw_E610 - Prepare hardware for Tx/Rx
3549 : : * @hw: pointer to hardware structure
3550 : : *
3551 : : * Gets firmware version and if API version matches it
3552 : : * starts the hardware using the generic start_hw function
3553 : : * and the generation start_hw function.
3554 : : * Then performs revision-specific operations, if any.
3555 : : **/
3556 : 0 : s32 ixgbe_start_hw_E610(struct ixgbe_hw *hw)
3557 : : {
3558 : : s32 ret_val = IXGBE_SUCCESS;
3559 : :
3560 : 0 : ret_val = hw->mac.ops.get_fw_version(hw);
3561 [ # # ]: 0 : if (ret_val)
3562 : 0 : goto out;
3563 : :
3564 : 0 : ret_val = ixgbe_start_hw_generic(hw);
3565 [ # # ]: 0 : if (ret_val != IXGBE_SUCCESS)
3566 : 0 : goto out;
3567 : :
3568 : 0 : ixgbe_start_hw_gen2(hw);
3569 : :
3570 : 0 : out:
3571 : 0 : return ret_val;
3572 : : }
3573 : :
3574 : : /**
3575 : : * ixgbe_get_media_type_E610 - Gets media type
3576 : : * @hw: pointer to the HW struct
3577 : : *
3578 : : * In order to get the media type, the function gets PHY
3579 : : * capabilities and later on use them to identify the PHY type
3580 : : * checking phy_type_high and phy_type_low.
3581 : : *
3582 : : * Return: the type of media in form of ixgbe_media_type enum
3583 : : * or ixgbe_media_type_unknown in case of an error.
3584 : : */
3585 : 0 : enum ixgbe_media_type ixgbe_get_media_type_E610(struct ixgbe_hw *hw)
3586 : : {
3587 : : struct ixgbe_aci_cmd_get_phy_caps_data pcaps;
3588 : : u64 phy_mask = 0;
3589 : : s32 rc;
3590 : : u8 i;
3591 : :
3592 : 0 : rc = ixgbe_update_link_info(hw);
3593 [ # # ]: 0 : if (rc) {
3594 : : return ixgbe_media_type_unknown;
3595 : : }
3596 : :
3597 : : /* If there is no link but PHY (dongle) is available SW should use
3598 : : * Get PHY Caps admin command instead of Get Link Status, find most
3599 : : * significant bit that is set in PHY types reported by the command
3600 : : * and use it to discover media type.
3601 : : */
3602 [ # # ]: 0 : if (!(hw->link.link_info.link_info & IXGBE_ACI_LINK_UP) &&
3603 : : (hw->link.link_info.link_info & IXGBE_ACI_MEDIA_AVAILABLE)) {
3604 : : /* Get PHY Capabilities */
3605 : 0 : rc = ixgbe_aci_get_phy_caps(hw, false,
3606 : : IXGBE_ACI_REPORT_TOPO_CAP_MEDIA,
3607 : : &pcaps);
3608 [ # # ]: 0 : if (rc) {
3609 : : return ixgbe_media_type_unknown;
3610 : : }
3611 : :
3612 : : /* Check if there is some bit set in phy_type_high */
3613 [ # # ]: 0 : for (i = 64; i > 0; i--) {
3614 : 0 : phy_mask = (u64)((u64)1 << (i - 1));
3615 [ # # ]: 0 : if ((pcaps.phy_type_high & phy_mask) != 0) {
3616 : : /* If any bit is set treat it as PHY type */
3617 : 0 : hw->link.link_info.phy_type_high = phy_mask;
3618 : 0 : hw->link.link_info.phy_type_low = 0;
3619 : 0 : break;
3620 : : }
3621 : : phy_mask = 0;
3622 : : }
3623 : :
3624 : : /* If nothing found in phy_type_high search in phy_type_low */
3625 [ # # ]: 0 : if (phy_mask == 0) {
3626 [ # # ]: 0 : for (i = 64; i > 0; i--) {
3627 : 0 : phy_mask = (u64)((u64)1 << (i - 1));
3628 [ # # ]: 0 : if ((pcaps.phy_type_low & phy_mask) != 0) {
3629 : : /* If any bit is set treat it as PHY type */
3630 : 0 : hw->link.link_info.phy_type_high = 0;
3631 : 0 : hw->link.link_info.phy_type_low = phy_mask;
3632 : 0 : break;
3633 : : }
3634 : : }
3635 : : }
3636 : :
3637 : : }
3638 : :
3639 : : /* Based on link status or search above try to discover media type */
3640 : 0 : hw->phy.media_type = ixgbe_get_media_type_from_phy_type(hw);
3641 : :
3642 : 0 : return hw->phy.media_type;
3643 : : }
3644 : :
3645 : : /**
3646 : : * ixgbe_get_supported_physical_layer_E610 - Returns physical layer type
3647 : : * @hw: pointer to hardware structure
3648 : : *
3649 : : * Determines physical layer capabilities of the current configuration.
3650 : : *
3651 : : * Return: the exit code of the operation.
3652 : : **/
3653 : 0 : u64 ixgbe_get_supported_physical_layer_E610(struct ixgbe_hw *hw)
3654 : : {
3655 : : u64 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
3656 : : struct ixgbe_aci_cmd_get_phy_caps_data pcaps;
3657 : : u64 phy_type;
3658 : : s32 rc;
3659 : :
3660 : 0 : rc = ixgbe_aci_get_phy_caps(hw, false, IXGBE_ACI_REPORT_TOPO_CAP_MEDIA,
3661 : : &pcaps);
3662 [ # # ]: 0 : if (rc)
3663 : : return IXGBE_PHYSICAL_LAYER_UNKNOWN;
3664 : :
3665 : 0 : phy_type = IXGBE_LE64_TO_CPU(pcaps.phy_type_low);
3666 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_10GBASE_T)
3667 : : physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
3668 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_1000BASE_T)
3669 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
3670 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_100BASE_TX)
3671 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
3672 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_10GBASE_LR)
3673 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_LR;
3674 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_10GBASE_SR)
3675 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_SR;
3676 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_1000BASE_KX)
3677 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
3678 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1)
3679 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR;
3680 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_1000BASE_SX)
3681 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_SX;
3682 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_2500BASE_KX)
3683 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_2500BASE_KX;
3684 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_2500BASE_T)
3685 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_2500BASE_T;
3686 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_LOW_5GBASE_T)
3687 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_5000BASE_T;
3688 : :
3689 : 0 : phy_type = IXGBE_LE64_TO_CPU(pcaps.phy_type_high);
3690 [ # # ]: 0 : if(phy_type & IXGBE_PHY_TYPE_HIGH_10BASE_T)
3691 : 0 : physical_layer |= IXGBE_PHYSICAL_LAYER_10BASE_T;
3692 : :
3693 : : return physical_layer;
3694 : : }
3695 : :
3696 : : /**
3697 : : * ixgbe_setup_link_E610 - Set up link
3698 : : * @hw: pointer to hardware structure
3699 : : * @speed: new link speed
3700 : : * @autoneg_wait: true when waiting for completion is needed
3701 : : *
3702 : : * Set up the link with the specified speed.
3703 : : *
3704 : : * Return: the exit code of the operation.
3705 : : */
3706 : 0 : s32 ixgbe_setup_link_E610(struct ixgbe_hw *hw, ixgbe_link_speed speed,
3707 : : bool autoneg_wait)
3708 : : {
3709 : :
3710 : : /* Simply request FW to perform proper PHY setup */
3711 : 0 : return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait);
3712 : : }
3713 : :
3714 : : /**
3715 : : * ixgbe_check_link_E610 - Determine link and speed status
3716 : : * @hw: pointer to hardware structure
3717 : : * @speed: pointer to link speed
3718 : : * @link_up: true when link is up
3719 : : * @link_up_wait_to_complete: bool used to wait for link up or not
3720 : : *
3721 : : * Determine if the link is up and the current link speed
3722 : : * using ACI command (0x0607).
3723 : : *
3724 : : * Return: the exit code of the operation.
3725 : : */
3726 : 0 : s32 ixgbe_check_link_E610(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
3727 : : bool *link_up, bool link_up_wait_to_complete)
3728 : : {
3729 : : s32 rc;
3730 : : u32 i;
3731 : :
3732 [ # # ]: 0 : if (!speed || !link_up)
3733 : : return IXGBE_ERR_PARAM;
3734 : :
3735 : : /* Set get_link_info flag to ensure that fresh
3736 : : * link information will be obtained from FW
3737 : : * by sending Get Link Status admin command. */
3738 : 0 : hw->link.get_link_info = true;
3739 : :
3740 : : /* Update link information in adapter context. */
3741 : 0 : rc = ixgbe_get_link_status(hw, link_up);
3742 [ # # ]: 0 : if (rc)
3743 : : return rc;
3744 : :
3745 : : /* Wait for link up if it was requested. */
3746 [ # # # # ]: 0 : if (link_up_wait_to_complete && *link_up == false) {
3747 [ # # ]: 0 : for (i = 0; i < hw->mac.max_link_up_time; i++) {
3748 : 0 : msec_delay(100);
3749 : 0 : hw->link.get_link_info = true;
3750 : 0 : rc = ixgbe_get_link_status(hw, link_up);
3751 [ # # ]: 0 : if (rc)
3752 : 0 : return rc;
3753 [ # # ]: 0 : if (*link_up)
3754 : : break;
3755 : : }
3756 : : }
3757 : :
3758 : : /* Use link information in adapter context updated by the call
3759 : : * to ixgbe_get_link_status() to determine current link speed.
3760 : : * Link speed information is valid only when link up was
3761 : : * reported by FW. */
3762 [ # # ]: 0 : if (*link_up) {
3763 [ # # # # : 0 : switch (hw->link.link_info.link_speed) {
# # # ]
3764 : 0 : case IXGBE_ACI_LINK_SPEED_10MB:
3765 : 0 : *speed = IXGBE_LINK_SPEED_10_FULL;
3766 : 0 : break;
3767 : 0 : case IXGBE_ACI_LINK_SPEED_100MB:
3768 : 0 : *speed = IXGBE_LINK_SPEED_100_FULL;
3769 : 0 : break;
3770 : 0 : case IXGBE_ACI_LINK_SPEED_1000MB:
3771 : 0 : *speed = IXGBE_LINK_SPEED_1GB_FULL;
3772 : 0 : break;
3773 : 0 : case IXGBE_ACI_LINK_SPEED_2500MB:
3774 : 0 : *speed = IXGBE_LINK_SPEED_2_5GB_FULL;
3775 : 0 : break;
3776 : 0 : case IXGBE_ACI_LINK_SPEED_5GB:
3777 : 0 : *speed = IXGBE_LINK_SPEED_5GB_FULL;
3778 : 0 : break;
3779 : 0 : case IXGBE_ACI_LINK_SPEED_10GB:
3780 : 0 : *speed = IXGBE_LINK_SPEED_10GB_FULL;
3781 : 0 : break;
3782 : 0 : default:
3783 : 0 : *speed = IXGBE_LINK_SPEED_UNKNOWN;
3784 : 0 : break;
3785 : : }
3786 : : } else {
3787 : 0 : *speed = IXGBE_LINK_SPEED_UNKNOWN;
3788 : : }
3789 : :
3790 : : return IXGBE_SUCCESS;
3791 : : }
3792 : :
3793 : : /**
3794 : : * ixgbe_get_link_capabilities_E610 - Determine link capabilities
3795 : : * @hw: pointer to hardware structure
3796 : : * @speed: pointer to link speed
3797 : : * @autoneg: true when autoneg or autotry is enabled
3798 : : *
3799 : : * Determine speed and AN parameters of a link.
3800 : : *
3801 : : * Return: the exit code of the operation.
3802 : : */
3803 : 0 : s32 ixgbe_get_link_capabilities_E610(struct ixgbe_hw *hw,
3804 : : ixgbe_link_speed *speed,
3805 : : bool *autoneg)
3806 : : {
3807 : :
3808 [ # # ]: 0 : if (!speed || !autoneg)
3809 : : return IXGBE_ERR_PARAM;
3810 : :
3811 : 0 : *autoneg = true;
3812 : 0 : *speed = hw->phy.speeds_supported;
3813 : :
3814 : 0 : return IXGBE_SUCCESS;
3815 : : }
3816 : :
3817 : : /**
3818 : : * ixgbe_cfg_phy_fc - Configure PHY Flow Control (FC) data based on FC mode
3819 : : * @hw: pointer to hardware structure
3820 : : * @cfg: PHY configuration data to set FC mode
3821 : : * @req_mode: FC mode to configure
3822 : : *
3823 : : * Configures PHY Flow Control according to the provided configuration.
3824 : : *
3825 : : * Return: the exit code of the operation.
3826 : : */
3827 : 0 : s32 ixgbe_cfg_phy_fc(struct ixgbe_hw *hw,
3828 : : struct ixgbe_aci_cmd_set_phy_cfg_data *cfg,
3829 : : enum ixgbe_fc_mode req_mode)
3830 : : {
3831 : : struct ixgbe_aci_cmd_get_phy_caps_data* pcaps = NULL;
3832 : : s32 status = IXGBE_SUCCESS;
3833 : : u8 pause_mask = 0x0;
3834 : :
3835 [ # # ]: 0 : if (!cfg)
3836 : : return IXGBE_ERR_PARAM;
3837 : :
3838 [ # # # # : 0 : switch (req_mode) {
# ]
3839 : 0 : case ixgbe_fc_auto:
3840 : : {
3841 : : pcaps = (struct ixgbe_aci_cmd_get_phy_caps_data *)
3842 : 0 : ixgbe_malloc(hw, sizeof(*pcaps));
3843 [ # # ]: 0 : if (!pcaps) {
3844 : : status = IXGBE_ERR_OUT_OF_MEM;
3845 : 0 : goto out;
3846 : : }
3847 : :
3848 : : /* Query the value of FC that both the NIC and the attached
3849 : : * media can do. */
3850 : 0 : status = ixgbe_aci_get_phy_caps(hw, false,
3851 : : IXGBE_ACI_REPORT_TOPO_CAP_MEDIA, pcaps);
3852 [ # # ]: 0 : if (status)
3853 : 0 : goto out;
3854 : :
3855 : 0 : pause_mask |= pcaps->caps & IXGBE_ACI_PHY_EN_TX_LINK_PAUSE;
3856 : 0 : pause_mask |= pcaps->caps & IXGBE_ACI_PHY_EN_RX_LINK_PAUSE;
3857 : :
3858 : 0 : break;
3859 : : }
3860 : 0 : case ixgbe_fc_full:
3861 : : pause_mask |= IXGBE_ACI_PHY_EN_TX_LINK_PAUSE;
3862 : : pause_mask |= IXGBE_ACI_PHY_EN_RX_LINK_PAUSE;
3863 : 0 : break;
3864 : 0 : case ixgbe_fc_rx_pause:
3865 : : pause_mask |= IXGBE_ACI_PHY_EN_RX_LINK_PAUSE;
3866 : 0 : break;
3867 : 0 : case ixgbe_fc_tx_pause:
3868 : : pause_mask |= IXGBE_ACI_PHY_EN_TX_LINK_PAUSE;
3869 : 0 : break;
3870 : : default:
3871 : : break;
3872 : : }
3873 : :
3874 : : /* clear the old pause settings */
3875 : 0 : cfg->caps &= ~(IXGBE_ACI_PHY_EN_TX_LINK_PAUSE |
3876 : : IXGBE_ACI_PHY_EN_RX_LINK_PAUSE);
3877 : :
3878 : : /* set the new capabilities */
3879 : 0 : cfg->caps |= pause_mask;
3880 : :
3881 : 0 : out:
3882 [ # # ]: 0 : if (pcaps)
3883 : 0 : ixgbe_free(hw, pcaps);
3884 : : return status;
3885 : : }
3886 : :
3887 : : /**
3888 : : * ixgbe_setup_fc_E610 - Set up flow control
3889 : : * @hw: pointer to hardware structure
3890 : : *
3891 : : * Set up flow control. This has to be done during init time.
3892 : : *
3893 : : * Return: the exit code of the operation.
3894 : : */
3895 : 0 : s32 ixgbe_setup_fc_E610(struct ixgbe_hw *hw)
3896 : : {
3897 : 0 : struct ixgbe_aci_cmd_get_phy_caps_data pcaps = { 0 };
3898 : 0 : struct ixgbe_aci_cmd_set_phy_cfg_data cfg = { 0 };
3899 : : s32 status;
3900 : :
3901 : : /* Get the current PHY config */
3902 : 0 : status = ixgbe_aci_get_phy_caps(hw, false,
3903 : : IXGBE_ACI_REPORT_ACTIVE_CFG, &pcaps);
3904 [ # # ]: 0 : if (status)
3905 : : return status;
3906 : :
3907 : 0 : ixgbe_copy_phy_caps_to_cfg(&pcaps, &cfg);
3908 : :
3909 : : /* Configure the set PHY data */
3910 : 0 : status = ixgbe_cfg_phy_fc(hw, &cfg, hw->fc.requested_mode);
3911 [ # # ]: 0 : if (status)
3912 : : return status;
3913 : :
3914 : : /* If the capabilities have changed, then set the new config */
3915 [ # # ]: 0 : if (cfg.caps != pcaps.caps) {
3916 : 0 : cfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT;
3917 : :
3918 : 0 : status = ixgbe_aci_set_phy_cfg(hw, &cfg);
3919 [ # # ]: 0 : if (status)
3920 : 0 : return status;
3921 : : }
3922 : :
3923 : : return status;
3924 : : }
3925 : :
3926 : : /**
3927 : : * ixgbe_fc_autoneg_E610 - Configure flow control
3928 : : * @hw: pointer to hardware structure
3929 : : *
3930 : : * Configure Flow Control.
3931 : : */
3932 : 0 : void ixgbe_fc_autoneg_E610(struct ixgbe_hw *hw)
3933 : : {
3934 : : s32 status;
3935 : :
3936 : : /* Get current link status.
3937 : : * Current FC mode will be stored in the hw context. */
3938 : 0 : status = ixgbe_aci_get_link_info(hw, false, NULL);
3939 [ # # ]: 0 : if (status) {
3940 : 0 : goto out;
3941 : : }
3942 : :
3943 : : /* Check if the link is up */
3944 [ # # ]: 0 : if (!(hw->link.link_info.link_info & IXGBE_ACI_LINK_UP)) {
3945 : : status = IXGBE_ERR_FC_NOT_NEGOTIATED;
3946 : 0 : goto out;
3947 : : }
3948 : :
3949 : : /* Check if auto-negotiation has completed */
3950 [ # # ]: 0 : if (!(hw->link.link_info.an_info & IXGBE_ACI_AN_COMPLETED)) {
3951 : : status = IXGBE_ERR_FC_NOT_NEGOTIATED;
3952 : 0 : goto out;
3953 : : }
3954 : :
3955 : 0 : out:
3956 [ # # ]: 0 : if (status == IXGBE_SUCCESS) {
3957 : 0 : hw->fc.fc_was_autonegged = true;
3958 : : } else {
3959 : 0 : hw->fc.fc_was_autonegged = false;
3960 : 0 : hw->fc.current_mode = hw->fc.requested_mode;
3961 : : }
3962 : 0 : }
3963 : :
3964 : : /**
3965 : : * ixgbe_set_fw_drv_ver_E610 - Send driver version to FW
3966 : : * @hw: pointer to the HW structure
3967 : : * @maj: driver version major number
3968 : : * @minor: driver version minor number
3969 : : * @build: driver version build number
3970 : : * @sub: driver version sub build number
3971 : : * @len: length of driver_ver string
3972 : : * @driver_ver: driver string
3973 : : *
3974 : : * Send driver version number to Firmware using ACI command (0x0002).
3975 : : *
3976 : : * Return: the exit code of the operation.
3977 : : * IXGBE_SUCCESS - OK
3978 : : * IXGBE_ERR_PARAM - incorrect parameters were given
3979 : : * IXGBE_ERR_ACI_ERROR - encountered an error during sending the command
3980 : : * IXGBE_ERR_ACI_TIMEOUT - a timeout occurred
3981 : : * IXGBE_ERR_OUT_OF_MEM - ran out of memory
3982 : : */
3983 : 0 : s32 ixgbe_set_fw_drv_ver_E610(struct ixgbe_hw *hw, u8 maj, u8 minor, u8 build,
3984 : : u8 sub, u16 len, const char *driver_ver)
3985 : : {
3986 : 0 : size_t limited_len = min(len, (u16)IXGBE_DRV_VER_STR_LEN_E610);
3987 : : struct ixgbe_driver_ver dv;
3988 : :
3989 : 0 : DEBUGFUNC("ixgbe_set_fw_drv_ver_E610");
3990 : :
3991 [ # # ]: 0 : if (!len || !driver_ver)
3992 : : return IXGBE_ERR_PARAM;
3993 : :
3994 : 0 : dv.major_ver = maj;
3995 : 0 : dv.minor_ver = minor;
3996 : 0 : dv.build_ver = build;
3997 : 0 : dv.subbuild_ver = sub;
3998 : :
3999 : : memset(dv.driver_string, 0, IXGBE_DRV_VER_STR_LEN_E610);
4000 : : memcpy(dv.driver_string, driver_ver, limited_len);
4001 : :
4002 : 0 : return ixgbe_aci_send_driver_ver(hw, &dv);
4003 : : }
4004 : :
4005 : : /**
4006 : : * ixgbe_disable_rx_E610 - Disable RX unit
4007 : : * @hw: pointer to hardware structure
4008 : : *
4009 : : * Disable RX DMA unit on E610 with use of ACI command (0x000C).
4010 : : *
4011 : : * Return: the exit code of the operation.
4012 : : */
4013 : 0 : void ixgbe_disable_rx_E610(struct ixgbe_hw *hw)
4014 : : {
4015 : : u32 rxctrl;
4016 : :
4017 : 0 : DEBUGFUNC("ixgbe_disable_rx_E610");
4018 : :
4019 : 0 : rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
4020 [ # # ]: 0 : if (rxctrl & IXGBE_RXCTRL_RXEN) {
4021 : : u32 pfdtxgswc;
4022 : : s32 status;
4023 : :
4024 : 0 : pfdtxgswc = IXGBE_READ_REG(hw, IXGBE_PFDTXGSWC);
4025 [ # # ]: 0 : if (pfdtxgswc & IXGBE_PFDTXGSWC_VT_LBEN) {
4026 : 0 : pfdtxgswc &= ~IXGBE_PFDTXGSWC_VT_LBEN;
4027 : 0 : IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, pfdtxgswc);
4028 : 0 : hw->mac.set_lben = true;
4029 : : } else {
4030 : 0 : hw->mac.set_lben = false;
4031 : : }
4032 : :
4033 : 0 : status = ixgbe_aci_disable_rxen(hw);
4034 : :
4035 : : /* If we fail - disable RX using register write */
4036 [ # # ]: 0 : if (status) {
4037 : 0 : rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
4038 [ # # ]: 0 : if (rxctrl & IXGBE_RXCTRL_RXEN) {
4039 : 0 : rxctrl &= ~IXGBE_RXCTRL_RXEN;
4040 : 0 : IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl);
4041 : : }
4042 : : }
4043 : : }
4044 : 0 : }
4045 : :
4046 : : /**
4047 : : * ixgbe_setup_eee_E610 - Enable/disable EEE support
4048 : : * @hw: pointer to the HW structure
4049 : : * @enable_eee: boolean flag to enable EEE
4050 : : *
4051 : : * Enables/disable EEE based on enable_eee flag.
4052 : : *
4053 : : * Return: the exit code of the operation.
4054 : : */
4055 : 0 : s32 ixgbe_setup_eee_E610(struct ixgbe_hw *hw, bool enable_eee)
4056 : : {
4057 : 0 : struct ixgbe_aci_cmd_get_phy_caps_data phy_caps = { 0 };
4058 : 0 : struct ixgbe_aci_cmd_set_phy_cfg_data phy_cfg = { 0 };
4059 : : u16 eee_cap = 0;
4060 : : s32 status;
4061 : :
4062 : 0 : status = ixgbe_aci_get_phy_caps(hw, false,
4063 : : IXGBE_ACI_REPORT_ACTIVE_CFG, &phy_caps);
4064 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
4065 : : return status;
4066 : :
4067 : 0 : ixgbe_copy_phy_caps_to_cfg(&phy_caps, &phy_cfg);
4068 : :
4069 : 0 : phy_cfg.caps |= IXGBE_ACI_PHY_ENA_LINK;
4070 : 0 : phy_cfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT;
4071 : :
4072 [ # # ]: 0 : if (enable_eee) {
4073 [ # # ]: 0 : if (phy_caps.phy_type_low & IXGBE_PHY_TYPE_LOW_100BASE_TX)
4074 : : eee_cap |= IXGBE_ACI_PHY_EEE_EN_100BASE_TX;
4075 [ # # ]: 0 : if (phy_caps.phy_type_low & IXGBE_PHY_TYPE_LOW_1000BASE_T)
4076 : 0 : eee_cap |= IXGBE_ACI_PHY_EEE_EN_1000BASE_T;
4077 [ # # ]: 0 : if (phy_caps.phy_type_low & IXGBE_PHY_TYPE_LOW_1000BASE_KX)
4078 : 0 : eee_cap |= IXGBE_ACI_PHY_EEE_EN_1000BASE_KX;
4079 [ # # ]: 0 : if (phy_caps.phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_T)
4080 : 0 : eee_cap |= IXGBE_ACI_PHY_EEE_EN_10GBASE_T;
4081 [ # # ]: 0 : if (phy_caps.phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1)
4082 : 0 : eee_cap |= IXGBE_ACI_PHY_EEE_EN_10GBASE_KR;
4083 : 0 : if (phy_caps.phy_type_low & IXGBE_PHY_TYPE_LOW_25GBASE_KR ||
4084 [ # # ]: 0 : phy_caps.phy_type_low & IXGBE_PHY_TYPE_LOW_25GBASE_KR_S ||
4085 : : phy_caps.phy_type_low & IXGBE_PHY_TYPE_LOW_25GBASE_KR1)
4086 : 0 : eee_cap |= IXGBE_ACI_PHY_EEE_EN_25GBASE_KR;
4087 : :
4088 [ # # ]: 0 : if (phy_caps.phy_type_high & IXGBE_PHY_TYPE_HIGH_10BASE_T)
4089 : 0 : eee_cap |= IXGBE_ACI_PHY_EEE_EN_10BASE_T;
4090 : : }
4091 : :
4092 : : /* Set EEE capability for particular PHY types */
4093 : 0 : phy_cfg.eee_cap = IXGBE_CPU_TO_LE16(eee_cap);
4094 : :
4095 : 0 : status = ixgbe_aci_set_phy_cfg(hw, &phy_cfg);
4096 : :
4097 : 0 : return status;
4098 : : }
4099 : :
4100 : : /**
4101 : : * ixgbe_fw_recovery_mode_E610 - Check FW NVM recovery mode
4102 : : * @hw: pointer to hardware structure
4103 : : *
4104 : : * Checks FW NVM recovery mode by
4105 : : * reading the value of the dedicated register.
4106 : : *
4107 : : * Return: true if FW is in recovery mode, otherwise false.
4108 : : */
4109 : 0 : bool ixgbe_fw_recovery_mode_E610(struct ixgbe_hw *hw)
4110 : : {
4111 : 0 : u32 fwsm = IXGBE_READ_REG(hw, GL_MNG_FWSM);
4112 : :
4113 : 0 : return !!(fwsm & GL_MNG_FWSM_FW_MODES_RECOVERY_M);
4114 : : }
4115 : :
4116 : : /**
4117 : : * ixgbe_get_fw_tsam_mode_E610 - Check FW NVM Thermal Sensor Autonomous Mode
4118 : : * @hw: pointer to hardware structure
4119 : : *
4120 : : * Checks Thermal Sensor Autonomous Mode by reading the
4121 : : * value of the dedicated register.
4122 : : *
4123 : : * Return: true if FW is in TSAM, otherwise false.
4124 : : */
4125 : 0 : bool ixgbe_get_fw_tsam_mode_E610(struct ixgbe_hw *hw)
4126 : : {
4127 : 0 : u32 fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM_X550EM_a);
4128 : :
4129 : 0 : return !!(fwsm & IXGBE_FWSM_TS_ENABLED);
4130 : : }
4131 : :
4132 : : /**
4133 : : * ixgbe_init_phy_ops_E610 - PHY specific init
4134 : : * @hw: pointer to hardware structure
4135 : : *
4136 : : * Initialize any function pointers that were not able to be
4137 : : * set during init_shared_code because the PHY type was not known.
4138 : : *
4139 : : * Return: the exit code of the operation.
4140 : : */
4141 : 0 : s32 ixgbe_init_phy_ops_E610(struct ixgbe_hw *hw)
4142 : : {
4143 : : struct ixgbe_mac_info *mac = &hw->mac;
4144 : : struct ixgbe_phy_info *phy = &hw->phy;
4145 : : s32 ret_val;
4146 : :
4147 : 0 : phy->ops.identify_sfp = ixgbe_identify_module_E610;
4148 : 0 : phy->ops.read_reg = NULL; /* PHY reg access is not required */
4149 : 0 : phy->ops.write_reg = NULL;
4150 : 0 : phy->ops.read_reg_mdi = NULL;
4151 : 0 : phy->ops.write_reg_mdi = NULL;
4152 : 0 : phy->ops.setup_link = ixgbe_setup_phy_link_E610;
4153 : 0 : phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_E610;
4154 : 0 : phy->ops.read_i2c_byte = NULL; /* disabled for E610 */
4155 : 0 : phy->ops.write_i2c_byte = NULL; /* disabled for E610 */
4156 : 0 : phy->ops.read_i2c_sff8472 = ixgbe_read_i2c_sff8472_E610;
4157 : 0 : phy->ops.read_i2c_eeprom = ixgbe_read_i2c_eeprom_E610;
4158 : 0 : phy->ops.write_i2c_eeprom = ixgbe_write_i2c_eeprom_E610;
4159 : 0 : phy->ops.i2c_bus_clear = NULL; /* do not use generic implementation */
4160 : 0 : phy->ops.check_overtemp = ixgbe_check_overtemp_E610;
4161 [ # # ]: 0 : if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper)
4162 : 0 : phy->ops.set_phy_power = ixgbe_set_phy_power_E610;
4163 : : else
4164 : 0 : phy->ops.set_phy_power = NULL;
4165 : 0 : phy->ops.enter_lplu = ixgbe_enter_lplu_E610;
4166 : 0 : phy->ops.handle_lasi = NULL; /* no implementation for E610 */
4167 : 0 : phy->ops.read_i2c_byte_unlocked = NULL; /* disabled for E610 */
4168 : 0 : phy->ops.write_i2c_byte_unlocked = NULL; /* disabled for E610 */
4169 : :
4170 : : /* TODO: Set functions pointers based on device ID */
4171 : :
4172 : : /* Identify the PHY */
4173 : 0 : ret_val = phy->ops.identify(hw);
4174 : : if (ret_val != IXGBE_SUCCESS)
4175 : : return ret_val;
4176 : :
4177 : : /* TODO: Set functions pointers based on PHY type */
4178 : :
4179 : : return ret_val;
4180 : : }
4181 : :
4182 : : /**
4183 : : * ixgbe_identify_phy_E610 - Identify PHY
4184 : : * @hw: pointer to hardware structure
4185 : : *
4186 : : * Determine PHY type, supported speeds and PHY ID.
4187 : : *
4188 : : * Return: the exit code of the operation.
4189 : : */
4190 : 0 : s32 ixgbe_identify_phy_E610(struct ixgbe_hw *hw)
4191 : : {
4192 : : struct ixgbe_aci_cmd_get_phy_caps_data pcaps;
4193 : : s32 rc;
4194 : :
4195 : : /* Set PHY type */
4196 : 0 : hw->phy.type = ixgbe_phy_fw;
4197 : :
4198 : 0 : rc = ixgbe_aci_get_phy_caps(hw, false, IXGBE_ACI_REPORT_TOPO_CAP_MEDIA,
4199 : : &pcaps);
4200 [ # # ]: 0 : if (rc)
4201 : : return rc;
4202 : :
4203 [ # # ]: 0 : if (!(pcaps.module_compliance_enforcement &
4204 : : IXGBE_ACI_MOD_ENFORCE_STRICT_MODE)) {
4205 : : /* Handle lenient mode */
4206 : 0 : rc = ixgbe_aci_get_phy_caps(hw, false,
4207 : : IXGBE_ACI_REPORT_TOPO_CAP_NO_MEDIA,
4208 : : &pcaps);
4209 [ # # ]: 0 : if (rc)
4210 : : return rc;
4211 : : }
4212 : :
4213 : : /* Determine supported speeds */
4214 : 0 : hw->phy.speeds_supported = IXGBE_LINK_SPEED_UNKNOWN;
4215 : :
4216 [ # # ]: 0 : if (pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_10BASE_T ||
4217 : : pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_10M_SGMII)
4218 : 0 : hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10_FULL;
4219 [ # # ]: 0 : if (pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_100BASE_TX ||
4220 : 0 : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_100M_SGMII ||
4221 [ # # ]: 0 : pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_100M_USXGMII)
4222 : 0 : hw->phy.speeds_supported |= IXGBE_LINK_SPEED_100_FULL;
4223 : 0 : if (pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_1000BASE_T ||
4224 : : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_1000BASE_SX ||
4225 : : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_1000BASE_LX ||
4226 [ # # ]: 0 : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_1000BASE_KX ||
4227 : 0 : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_1G_SGMII ||
4228 [ # # ]: 0 : pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_1G_USXGMII)
4229 : 0 : hw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL;
4230 : 0 : if (pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_T ||
4231 [ # # ]: 0 : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_X ||
4232 : : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_2500BASE_KX ||
4233 [ # # ]: 0 : pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_2500M_SGMII ||
4234 : : pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_2500M_USXGMII)
4235 : 0 : hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL;
4236 [ # # ]: 0 : if (pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_5GBASE_T ||
4237 : 0 : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_5GBASE_KR ||
4238 [ # # ]: 0 : pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_5G_USXGMII)
4239 : 0 : hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL;
4240 : 0 : if (pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_T ||
4241 : : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10G_SFI_DA ||
4242 : : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_SR ||
4243 : : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_LR ||
4244 : : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1 ||
4245 [ # # ]: 0 : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10G_SFI_AOC_ACC ||
4246 : 0 : pcaps.phy_type_low & IXGBE_PHY_TYPE_LOW_10G_SFI_C2C ||
4247 [ # # ]: 0 : pcaps.phy_type_high & IXGBE_PHY_TYPE_HIGH_10G_USXGMII)
4248 : 0 : hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL;
4249 : :
4250 : : /* Initialize autoneg speeds */
4251 [ # # ]: 0 : if (!hw->phy.autoneg_advertised)
4252 : 0 : hw->phy.autoneg_advertised = hw->phy.speeds_supported;
4253 : :
4254 : : /* Set PHY ID */
4255 : 0 : memcpy(&hw->phy.id, pcaps.phy_id_oui, sizeof(u32));
4256 : :
4257 : 0 : return IXGBE_SUCCESS;
4258 : : }
4259 : :
4260 : : /**
4261 : : * ixgbe_identify_module_E610 - Identify SFP module type
4262 : : * @hw: pointer to hardware structure
4263 : : *
4264 : : * Identify the SFP module type.
4265 : : *
4266 : : * Return: the exit code of the operation.
4267 : : */
4268 : 0 : s32 ixgbe_identify_module_E610(struct ixgbe_hw *hw)
4269 : : {
4270 : : bool media_available;
4271 : : u8 module_type;
4272 : : s32 rc;
4273 : :
4274 : 0 : rc = ixgbe_update_link_info(hw);
4275 [ # # ]: 0 : if (rc)
4276 : 0 : goto err;
4277 : :
4278 : : media_available =
4279 : 0 : (hw->link.link_info.link_info &
4280 : 0 : IXGBE_ACI_MEDIA_AVAILABLE) ? true : false;
4281 : :
4282 [ # # ]: 0 : if (media_available) {
4283 : 0 : hw->phy.sfp_type = ixgbe_sfp_type_unknown;
4284 : :
4285 : : /* Get module type from hw context updated by ixgbe_update_link_info() */
4286 : 0 : module_type = hw->link.link_info.module_type[IXGBE_ACI_MOD_TYPE_IDENT];
4287 : :
4288 [ # # ]: 0 : if ((module_type & IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE) ||
4289 : : (module_type & IXGBE_ACI_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE)) {
4290 : 0 : hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
4291 [ # # ]: 0 : } else if (module_type & IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_SR) {
4292 : 0 : hw->phy.sfp_type = ixgbe_sfp_type_sr;
4293 [ # # ]: 0 : } else if ((module_type & IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_LR) ||
4294 : : (module_type & IXGBE_ACI_MOD_TYPE_BYTE1_10G_BASE_LRM)) {
4295 : 0 : hw->phy.sfp_type = ixgbe_sfp_type_lr;
4296 : : }
4297 : : rc = IXGBE_SUCCESS;
4298 : : } else {
4299 : 0 : hw->phy.sfp_type = ixgbe_sfp_type_not_present;
4300 : : rc = IXGBE_ERR_SFP_NOT_PRESENT;
4301 : : }
4302 : 0 : err:
4303 : 0 : return rc;
4304 : : }
4305 : :
4306 : : /**
4307 : : * ixgbe_setup_phy_link_E610 - Sets up firmware-controlled PHYs
4308 : : * @hw: pointer to hardware structure
4309 : : *
4310 : : * Set the parameters for the firmware-controlled PHYs.
4311 : : *
4312 : : * Return: the exit code of the operation.
4313 : : */
4314 : 0 : s32 ixgbe_setup_phy_link_E610(struct ixgbe_hw *hw)
4315 : : {
4316 : : struct ixgbe_aci_cmd_get_phy_caps_data pcaps;
4317 : : struct ixgbe_aci_cmd_set_phy_cfg_data pcfg;
4318 : : u8 rmode = IXGBE_ACI_REPORT_TOPO_CAP_MEDIA;
4319 : : u64 sup_phy_type_low, sup_phy_type_high;
4320 : : s32 rc;
4321 : :
4322 : 0 : rc = ixgbe_aci_get_link_info(hw, false, NULL);
4323 [ # # ]: 0 : if (rc) {
4324 : 0 : goto err;
4325 : : }
4326 : :
4327 : : /* If media is not available get default config */
4328 [ # # ]: 0 : if (!(hw->link.link_info.link_info & IXGBE_ACI_MEDIA_AVAILABLE))
4329 : : rmode = IXGBE_ACI_REPORT_DFLT_CFG;
4330 : :
4331 : 0 : rc = ixgbe_aci_get_phy_caps(hw, false, rmode, &pcaps);
4332 [ # # ]: 0 : if (rc) {
4333 : 0 : goto err;
4334 : : }
4335 : :
4336 : 0 : sup_phy_type_low = pcaps.phy_type_low;
4337 : 0 : sup_phy_type_high = pcaps.phy_type_high;
4338 : :
4339 : : /* Get Active configuration to avoid unintended changes */
4340 : 0 : rc = ixgbe_aci_get_phy_caps(hw, false, IXGBE_ACI_REPORT_ACTIVE_CFG,
4341 : : &pcaps);
4342 [ # # ]: 0 : if (rc) {
4343 : 0 : goto err;
4344 : : }
4345 : 0 : ixgbe_copy_phy_caps_to_cfg(&pcaps, &pcfg);
4346 : :
4347 : : /* Set default PHY types for a given speed */
4348 : 0 : pcfg.phy_type_low = 0;
4349 : 0 : pcfg.phy_type_high = 0;
4350 : :
4351 [ # # ]: 0 : if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10_FULL) {
4352 : : pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_10BASE_T;
4353 : 0 : pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_10M_SGMII;
4354 : : }
4355 [ # # ]: 0 : if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL) {
4356 : : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_100BASE_TX;
4357 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_100M_SGMII;
4358 : 0 : pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_100M_USXGMII;
4359 : : }
4360 [ # # ]: 0 : if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL) {
4361 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_1000BASE_T;
4362 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_1000BASE_SX;
4363 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_1000BASE_LX;
4364 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_1000BASE_KX;
4365 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_1G_SGMII;
4366 : 0 : pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_1G_USXGMII;
4367 : : }
4368 [ # # ]: 0 : if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL) {
4369 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_2500BASE_T;
4370 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_2500BASE_X;
4371 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_2500BASE_KX;
4372 : 0 : pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_2500M_SGMII;
4373 : 0 : pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_2500M_USXGMII;
4374 : : }
4375 [ # # ]: 0 : if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_5GB_FULL) {
4376 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_5GBASE_T;
4377 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_5GBASE_KR;
4378 : 0 : pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_5G_USXGMII;
4379 : : }
4380 [ # # ]: 0 : if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) {
4381 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10GBASE_T;
4382 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10G_SFI_DA;
4383 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10GBASE_SR;
4384 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10GBASE_LR;
4385 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10GBASE_KR_CR1;
4386 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10G_SFI_AOC_ACC;
4387 : 0 : pcfg.phy_type_low |= IXGBE_PHY_TYPE_LOW_10G_SFI_C2C;
4388 : 0 : pcfg.phy_type_high |= IXGBE_PHY_TYPE_HIGH_10G_USXGMII;
4389 : : }
4390 : :
4391 : : /* Mask the set values to avoid requesting unsupported link types */
4392 : 0 : pcfg.phy_type_low &= sup_phy_type_low;
4393 : 0 : pcfg.phy_type_high &= sup_phy_type_high;
4394 : :
4395 [ # # ]: 0 : if (pcfg.phy_type_high != pcaps.phy_type_high ||
4396 [ # # ]: 0 : pcfg.phy_type_low != pcaps.phy_type_low ||
4397 [ # # ]: 0 : pcfg.caps != pcaps.caps) {
4398 : 0 : pcfg.caps |= IXGBE_ACI_PHY_ENA_LINK;
4399 : 0 : pcfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT;
4400 : :
4401 : 0 : rc = ixgbe_aci_set_phy_cfg(hw, &pcfg);
4402 : : }
4403 : :
4404 : 0 : err:
4405 : 0 : return rc;
4406 : : }
4407 : :
4408 : : /**
4409 : : * ixgbe_get_phy_firmware_version_E610 - Gets the PHY Firmware Version
4410 : : * @hw: pointer to hardware structure
4411 : : * @firmware_version: pointer to the PHY Firmware Version
4412 : : *
4413 : : * Determines PHY FW version based on response to Get PHY Capabilities
4414 : : * admin command (0x0600).
4415 : : *
4416 : : * Return: the exit code of the operation.
4417 : : */
4418 : 0 : s32 ixgbe_get_phy_firmware_version_E610(struct ixgbe_hw *hw,
4419 : : u16 *firmware_version)
4420 : : {
4421 : : struct ixgbe_aci_cmd_get_phy_caps_data pcaps;
4422 : : s32 status;
4423 : :
4424 [ # # ]: 0 : if (!firmware_version)
4425 : : return IXGBE_ERR_PARAM;
4426 : :
4427 : 0 : status = ixgbe_aci_get_phy_caps(hw, false,
4428 : : IXGBE_ACI_REPORT_ACTIVE_CFG,
4429 : : &pcaps);
4430 [ # # ]: 0 : if (status)
4431 : : return status;
4432 : :
4433 : : /* TODO: determine which bytes of the 8-byte phy_fw_ver
4434 : : * field should be written to the 2-byte firmware_version
4435 : : * output argument. */
4436 : : memcpy(firmware_version, pcaps.phy_fw_ver, sizeof(u16));
4437 : :
4438 : 0 : return IXGBE_SUCCESS;
4439 : : }
4440 : :
4441 : : /**
4442 : : * ixgbe_read_i2c_sff8472_E610 - Reads 8 bit word over I2C interface
4443 : : * @hw: pointer to hardware structure
4444 : : * @byte_offset: byte offset at address 0xA2
4445 : : * @sff8472_data: value read
4446 : : *
4447 : : * Performs byte read operation from SFP module's SFF-8472 data over I2C.
4448 : : *
4449 : : * Return: the exit code of the operation.
4450 : : **/
4451 : 0 : s32 ixgbe_read_i2c_sff8472_E610(struct ixgbe_hw *hw, u8 byte_offset,
4452 : : u8 *sff8472_data)
4453 : : {
4454 : 0 : return ixgbe_aci_sff_eeprom(hw, 0, IXGBE_I2C_EEPROM_DEV_ADDR2,
4455 : : byte_offset, 0,
4456 : : IXGBE_ACI_SFF_NO_PAGE_BANK_UPDATE,
4457 : : sff8472_data, 1, false);
4458 : : }
4459 : :
4460 : : /**
4461 : : * ixgbe_read_i2c_eeprom_E610 - Reads 8 bit EEPROM word over I2C interface
4462 : : * @hw: pointer to hardware structure
4463 : : * @byte_offset: EEPROM byte offset to read
4464 : : * @eeprom_data: value read
4465 : : *
4466 : : * Performs byte read operation from SFP module's EEPROM over I2C interface.
4467 : : *
4468 : : * Return: the exit code of the operation.
4469 : : **/
4470 : 0 : s32 ixgbe_read_i2c_eeprom_E610(struct ixgbe_hw *hw, u8 byte_offset,
4471 : : u8 *eeprom_data)
4472 : : {
4473 : 0 : return ixgbe_aci_sff_eeprom(hw, 0, IXGBE_I2C_EEPROM_DEV_ADDR,
4474 : : byte_offset, 0,
4475 : : IXGBE_ACI_SFF_NO_PAGE_BANK_UPDATE,
4476 : : eeprom_data, 1, false);
4477 : : }
4478 : :
4479 : : /**
4480 : : * ixgbe_write_i2c_eeprom_E610 - Writes 8 bit EEPROM word over I2C interface
4481 : : * @hw: pointer to hardware structure
4482 : : * @byte_offset: EEPROM byte offset to write
4483 : : * @eeprom_data: value to write
4484 : : *
4485 : : * Performs byte write operation to SFP module's EEPROM over I2C interface.
4486 : : *
4487 : : * Return: the exit code of the operation.
4488 : : **/
4489 : 0 : s32 ixgbe_write_i2c_eeprom_E610(struct ixgbe_hw *hw, u8 byte_offset,
4490 : : u8 eeprom_data)
4491 : : {
4492 : 0 : return ixgbe_aci_sff_eeprom(hw, 0, IXGBE_I2C_EEPROM_DEV_ADDR,
4493 : : byte_offset, 0,
4494 : : IXGBE_ACI_SFF_NO_PAGE_BANK_UPDATE,
4495 : : &eeprom_data, 1, true);
4496 : : }
4497 : :
4498 : : /**
4499 : : * ixgbe_check_overtemp_E610 - Check firmware-controlled PHYs for overtemp
4500 : : * @hw: pointer to hardware structure
4501 : : *
4502 : : * Get the link status and check if the PHY temperature alarm detected.
4503 : : *
4504 : : * Return: the exit code of the operation.
4505 : : */
4506 : 0 : s32 ixgbe_check_overtemp_E610(struct ixgbe_hw *hw)
4507 : : {
4508 : 0 : struct ixgbe_aci_cmd_get_link_status_data link_data = { 0 };
4509 : : struct ixgbe_aci_cmd_get_link_status *resp;
4510 : : struct ixgbe_aci_desc desc;
4511 : : s32 status = IXGBE_SUCCESS;
4512 : :
4513 [ # # ]: 0 : if (!hw)
4514 : : return IXGBE_ERR_PARAM;
4515 : :
4516 : 0 : ixgbe_fill_dflt_direct_cmd_desc(&desc, ixgbe_aci_opc_get_link_status);
4517 : : resp = &desc.params.get_link_status;
4518 : 0 : resp->cmd_flags = IXGBE_CPU_TO_LE16(IXGBE_ACI_LSE_NOP);
4519 : :
4520 : 0 : status = ixgbe_aci_send_cmd(hw, &desc, &link_data, sizeof(link_data));
4521 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
4522 : : return status;
4523 : :
4524 [ # # ]: 0 : if (link_data.ext_info & IXGBE_ACI_LINK_PHY_TEMP_ALARM) {
4525 : 0 : ERROR_REPORT1(IXGBE_ERROR_CAUTION,
4526 : : "PHY Temperature Alarm detected");
4527 : : status = IXGBE_ERR_OVERTEMP;
4528 : : }
4529 : :
4530 : : return status;
4531 : : }
4532 : :
4533 : : /**
4534 : : * ixgbe_set_phy_power_E610 - Control power for copper PHY
4535 : : * @hw: pointer to hardware structure
4536 : : * @on: true for on, false for off
4537 : : *
4538 : : * Set the power on/off of the PHY
4539 : : * by getting its capabilities and setting the appropriate
4540 : : * configuration parameters.
4541 : : *
4542 : : * Return: the exit code of the operation.
4543 : : */
4544 : 0 : s32 ixgbe_set_phy_power_E610(struct ixgbe_hw *hw, bool on)
4545 : : {
4546 : 0 : struct ixgbe_aci_cmd_get_phy_caps_data phy_caps = { 0 };
4547 : 0 : struct ixgbe_aci_cmd_set_phy_cfg_data phy_cfg = { 0 };
4548 : : s32 status;
4549 : :
4550 : 0 : status = ixgbe_aci_get_phy_caps(hw, false,
4551 : : IXGBE_ACI_REPORT_ACTIVE_CFG, &phy_caps);
4552 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
4553 : : return status;
4554 : :
4555 : 0 : ixgbe_copy_phy_caps_to_cfg(&phy_caps, &phy_cfg);
4556 : :
4557 [ # # ]: 0 : if (on) {
4558 : 0 : phy_cfg.caps &= ~IXGBE_ACI_PHY_ENA_LOW_POWER;
4559 : : } else {
4560 : 0 : phy_cfg.caps |= IXGBE_ACI_PHY_ENA_LOW_POWER;
4561 : : }
4562 : :
4563 : : /* PHY is already in requested power mode */
4564 [ # # ]: 0 : if (phy_caps.caps == phy_cfg.caps)
4565 : : return IXGBE_SUCCESS;
4566 : :
4567 : 0 : phy_cfg.caps |= IXGBE_ACI_PHY_ENA_LINK;
4568 : 0 : phy_cfg.caps |= IXGBE_ACI_PHY_ENA_AUTO_LINK_UPDT;
4569 : :
4570 : 0 : status = ixgbe_aci_set_phy_cfg(hw, &phy_cfg);
4571 : :
4572 : 0 : return status;
4573 : : }
4574 : :
4575 : : /**
4576 : : * ixgbe_enter_lplu_E610 - Transition to low power states
4577 : : * @hw: pointer to hardware structure
4578 : : *
4579 : : * Configures Low Power Link Up on transition to low power states
4580 : : * (from D0 to non-D0). Link is required to enter LPLU so avoid resetting the
4581 : : * X557 PHY immediately prior to entering LPLU.
4582 : : *
4583 : : * Return: the exit code of the operation.
4584 : : */
4585 : 0 : s32 ixgbe_enter_lplu_E610(struct ixgbe_hw *hw)
4586 : : {
4587 : 0 : struct ixgbe_aci_cmd_get_phy_caps_data phy_caps = { 0 };
4588 : 0 : struct ixgbe_aci_cmd_set_phy_cfg_data phy_cfg = { 0 };
4589 : : s32 status;
4590 : :
4591 : 0 : status = ixgbe_aci_get_phy_caps(hw, false,
4592 : : IXGBE_ACI_REPORT_ACTIVE_CFG, &phy_caps);
4593 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
4594 : : return status;
4595 : :
4596 : 0 : ixgbe_copy_phy_caps_to_cfg(&phy_caps, &phy_cfg);
4597 : :
4598 : 0 : phy_cfg.low_power_ctrl_an |= IXGBE_ACI_PHY_EN_D3COLD_LOW_POWER_AUTONEG;
4599 : :
4600 : 0 : status = ixgbe_aci_set_phy_cfg(hw, &phy_cfg);
4601 : :
4602 : 0 : return status;
4603 : : }
4604 : :
4605 : : /**
4606 : : * ixgbe_init_eeprom_params_E610 - Initialize EEPROM params
4607 : : * @hw: pointer to hardware structure
4608 : : *
4609 : : * Initializes the EEPROM parameters ixgbe_eeprom_info within the
4610 : : * ixgbe_hw struct in order to set up EEPROM access.
4611 : : *
4612 : : * Return: the exit code of the operation.
4613 : : */
4614 : 0 : s32 ixgbe_init_eeprom_params_E610(struct ixgbe_hw *hw)
4615 : : {
4616 : : struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
4617 : : u32 gens_stat;
4618 : : u8 sr_size;
4619 : :
4620 [ # # ]: 0 : if (eeprom->type == ixgbe_eeprom_uninitialized) {
4621 : 0 : eeprom->type = ixgbe_flash;
4622 : :
4623 : 0 : gens_stat = IXGBE_READ_REG(hw, GLNVM_GENS);
4624 : 0 : sr_size = (gens_stat & GLNVM_GENS_SR_SIZE_M) >>
4625 : : GLNVM_GENS_SR_SIZE_S;
4626 : :
4627 : : /* Switching to words (sr_size contains power of 2) */
4628 : 0 : eeprom->word_size = BIT(sr_size) * IXGBE_SR_WORDS_IN_1KB;
4629 : :
4630 : 0 : DEBUGOUT2("Eeprom params: type = %d, size = %d\n",
4631 : : eeprom->type, eeprom->word_size);
4632 : : }
4633 : :
4634 : 0 : return IXGBE_SUCCESS;
4635 : : }
4636 : :
4637 : : /**
4638 : : * ixgbe_read_ee_aci_E610 - Read EEPROM word using the admin command.
4639 : : * @hw: pointer to hardware structure
4640 : : * @offset: offset of word in the EEPROM to read
4641 : : * @data: word read from the EEPROM
4642 : : *
4643 : : * Reads a 16 bit word from the EEPROM using the ACI.
4644 : : * If the EEPROM params are not initialized, the function
4645 : : * initialize them before proceeding with reading.
4646 : : * The function acquires and then releases the NVM ownership.
4647 : : *
4648 : : * Return: the exit code of the operation.
4649 : : */
4650 : 0 : s32 ixgbe_read_ee_aci_E610(struct ixgbe_hw *hw, u16 offset, u16 *data)
4651 : : {
4652 : : s32 status;
4653 : :
4654 [ # # ]: 0 : if (hw->eeprom.type == ixgbe_eeprom_uninitialized) {
4655 : 0 : status = ixgbe_init_eeprom_params(hw);
4656 [ # # ]: 0 : if (status)
4657 : : return status;
4658 : : }
4659 : :
4660 : 0 : status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ);
4661 [ # # ]: 0 : if (status)
4662 : : return status;
4663 : :
4664 : 0 : status = ixgbe_read_sr_word_aci(hw, offset, data);
4665 : 0 : ixgbe_release_nvm(hw);
4666 : :
4667 : 0 : return status;
4668 : : }
4669 : :
4670 : : /**
4671 : : * ixgbe_read_ee_aci_buffer_E610- Read EEPROM word(s) using admin commands.
4672 : : * @hw: pointer to hardware structure
4673 : : * @offset: offset of word in the EEPROM to read
4674 : : * @words: number of words
4675 : : * @data: word(s) read from the EEPROM
4676 : : *
4677 : : * Reads a 16 bit word(s) from the EEPROM using the ACI.
4678 : : * If the EEPROM params are not initialized, the function
4679 : : * initialize them before proceeding with reading.
4680 : : * The function acquires and then releases the NVM ownership.
4681 : : *
4682 : : * Return: the exit code of the operation.
4683 : : */
4684 : 0 : s32 ixgbe_read_ee_aci_buffer_E610(struct ixgbe_hw *hw, u16 offset,
4685 : : u16 words, u16 *data)
4686 : : {
4687 : : s32 status;
4688 : :
4689 [ # # ]: 0 : if (hw->eeprom.type == ixgbe_eeprom_uninitialized) {
4690 : 0 : status = ixgbe_init_eeprom_params(hw);
4691 [ # # ]: 0 : if (status)
4692 : : return status;
4693 : : }
4694 : :
4695 : 0 : status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ);
4696 [ # # ]: 0 : if (status)
4697 : : return status;
4698 : :
4699 : 0 : status = ixgbe_read_sr_buf_aci(hw, offset, &words, data);
4700 : 0 : ixgbe_release_nvm(hw);
4701 : :
4702 : 0 : return status;
4703 : : }
4704 : :
4705 : : /**
4706 : : * ixgbe_calc_eeprom_checksum_E610 - Calculates and returns the checksum
4707 : : * @hw: pointer to hardware structure
4708 : : *
4709 : : * Calculate SW Checksum that covers the whole 64kB shadow RAM
4710 : : * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD
4711 : : * is customer specific and unknown. Therefore, this function skips all maximum
4712 : : * possible size of VPD (1kB).
4713 : : * If the EEPROM params are not initialized, the function
4714 : : * initializes them before proceeding.
4715 : : * The function acquires and then releases the NVM ownership.
4716 : : *
4717 : : * Return: the negative error code on error, or the 16-bit checksum
4718 : : */
4719 : 0 : s32 ixgbe_calc_eeprom_checksum_E610(struct ixgbe_hw *hw)
4720 : : {
4721 : : bool nvm_acquired = false;
4722 : 0 : u16 pcie_alt_module = 0;
4723 : : u16 checksum_local = 0;
4724 : : u16 checksum = 0;
4725 : : u16 vpd_module;
4726 : : void *vmem;
4727 : : s32 status;
4728 : : u16 *data;
4729 : : u16 i;
4730 : :
4731 [ # # ]: 0 : if (hw->eeprom.type == ixgbe_eeprom_uninitialized) {
4732 : 0 : status = ixgbe_init_eeprom_params(hw);
4733 [ # # ]: 0 : if (status)
4734 : : return status;
4735 : : }
4736 : :
4737 : 0 : vmem = ixgbe_calloc(hw, IXGBE_SR_SECTOR_SIZE_IN_WORDS, sizeof(u16));
4738 [ # # ]: 0 : if (!vmem)
4739 : : return IXGBE_ERR_OUT_OF_MEM;
4740 : : data = (u16 *)vmem;
4741 : 0 : status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ);
4742 [ # # ]: 0 : if (status)
4743 : 0 : goto ixgbe_calc_sr_checksum_exit;
4744 : : nvm_acquired = true;
4745 : :
4746 : : /* read pointer to VPD area */
4747 : 0 : status = ixgbe_read_sr_word_aci(hw, E610_SR_VPD_PTR, &vpd_module);
4748 [ # # ]: 0 : if (status)
4749 : 0 : goto ixgbe_calc_sr_checksum_exit;
4750 : :
4751 : : /* read pointer to PCIe Alt Auto-load module */
4752 : 0 : status = ixgbe_read_sr_word_aci(hw, E610_SR_PCIE_ALT_AUTO_LOAD_PTR,
4753 : : &pcie_alt_module);
4754 [ # # ]: 0 : if (status)
4755 : 0 : goto ixgbe_calc_sr_checksum_exit;
4756 : :
4757 : : /* Calculate SW checksum that covers the whole 64kB shadow RAM
4758 : : * except the VPD and PCIe ALT Auto-load modules
4759 : : */
4760 [ # # ]: 0 : for (i = 0; i < hw->eeprom.word_size; i++) {
4761 : : /* Read SR page */
4762 [ # # ]: 0 : if ((i % IXGBE_SR_SECTOR_SIZE_IN_WORDS) == 0) {
4763 : 0 : u16 words = IXGBE_SR_SECTOR_SIZE_IN_WORDS;
4764 : :
4765 : 0 : status = ixgbe_read_sr_buf_aci(hw, i, &words, data);
4766 [ # # ]: 0 : if (status != IXGBE_SUCCESS)
4767 : 0 : goto ixgbe_calc_sr_checksum_exit;
4768 : : }
4769 : :
4770 : : /* Skip Checksum word */
4771 [ # # ]: 0 : if (i == E610_SR_SW_CHECKSUM_WORD)
4772 : 0 : continue;
4773 : : /* Skip VPD module (convert byte size to word count) */
4774 [ # # ]: 0 : if (i >= (u32)vpd_module &&
4775 [ # # ]: 0 : i < ((u32)vpd_module + E610_SR_VPD_SIZE_WORDS))
4776 : 0 : continue;
4777 : : /* Skip PCIe ALT module (convert byte size to word count) */
4778 [ # # ]: 0 : if (i >= (u32)pcie_alt_module &&
4779 [ # # ]: 0 : i < ((u32)pcie_alt_module + E610_SR_PCIE_ALT_SIZE_WORDS))
4780 : 0 : continue;
4781 : :
4782 : 0 : checksum_local += data[i % IXGBE_SR_SECTOR_SIZE_IN_WORDS];
4783 : : }
4784 : :
4785 : 0 : checksum = (u16)IXGBE_SR_SW_CHECKSUM_BASE - checksum_local;
4786 : :
4787 : 0 : ixgbe_calc_sr_checksum_exit:
4788 [ # # ]: 0 : if(nvm_acquired)
4789 : 0 : ixgbe_release_nvm(hw);
4790 : 0 : ixgbe_free(hw, vmem);
4791 : :
4792 [ # # ]: 0 : if(!status)
4793 : 0 : return (s32)checksum;
4794 : : else
4795 : : return status;
4796 : : }
4797 : :
4798 : : /**
4799 : : * ixgbe_validate_eeprom_checksum_E610 - Validate EEPROM checksum
4800 : : * @hw: pointer to hardware structure
4801 : : * @checksum_val: calculated checksum
4802 : : *
4803 : : * Performs checksum calculation and validates the EEPROM checksum. If the
4804 : : * caller does not need checksum_val, the value can be NULL.
4805 : : * If the EEPROM params are not initialized, the function
4806 : : * initialize them before proceeding.
4807 : : * The function acquires and then releases the NVM ownership.
4808 : : *
4809 : : * Return: the exit code of the operation.
4810 : : */
4811 : 0 : s32 ixgbe_validate_eeprom_checksum_E610(struct ixgbe_hw *hw, u16 *checksum_val)
4812 : : {
4813 : : u32 status;
4814 : :
4815 [ # # ]: 0 : if (hw->eeprom.type == ixgbe_eeprom_uninitialized) {
4816 : 0 : status = ixgbe_init_eeprom_params(hw);
4817 [ # # ]: 0 : if (status)
4818 : : return status;
4819 : : }
4820 : :
4821 : 0 : status = ixgbe_nvm_validate_checksum(hw);
4822 : :
4823 [ # # ]: 0 : if (status)
4824 : : return status;
4825 : :
4826 [ # # ]: 0 : if (checksum_val) {
4827 : : u16 tmp_checksum;
4828 : 0 : status = ixgbe_acquire_nvm(hw, IXGBE_RES_READ);
4829 [ # # ]: 0 : if (status)
4830 : 0 : return status;
4831 : :
4832 : 0 : status = ixgbe_read_sr_word_aci(hw, E610_SR_SW_CHECKSUM_WORD,
4833 : : &tmp_checksum);
4834 : 0 : ixgbe_release_nvm(hw);
4835 : :
4836 [ # # ]: 0 : if (!status)
4837 : 0 : *checksum_val = tmp_checksum;
4838 : : }
4839 : :
4840 : 0 : return status;
4841 : : }
4842 : :
4843 : : /**
4844 : : * ixgbe_get_pfa_module_tlv - Reads sub module TLV from NVM PFA
4845 : : * @hw: pointer to hardware structure
4846 : : * @module_tlv: pointer to module TLV to return
4847 : : * @module_tlv_len: pointer to module TLV length to return
4848 : : * @module_type: module type requested
4849 : : *
4850 : : * Finds the requested sub module TLV type from the Preserved Field
4851 : : * Area (PFA) and returns the TLV pointer and length. The caller can
4852 : : * use these to read the variable length TLV value.
4853 : : *
4854 : : * Return: the exit code of the operation.
4855 : : */
4856 : 0 : STATIC s32 ixgbe_get_pfa_module_tlv(struct ixgbe_hw *hw, u16 *module_tlv,
4857 : : u16 *module_tlv_len, u16 module_type)
4858 : : {
4859 : : u16 pfa_len, pfa_ptr, pfa_end_ptr;
4860 : : u16 next_tlv;
4861 : : s32 status;
4862 : :
4863 : 0 : status = ixgbe_read_ee_aci_E610(hw, E610_SR_PFA_PTR, &pfa_ptr);
4864 [ # # ]: 0 : if (status != IXGBE_SUCCESS) {
4865 : : return status;
4866 : : }
4867 : 0 : status = ixgbe_read_ee_aci_E610(hw, pfa_ptr, &pfa_len);
4868 [ # # ]: 0 : if (status != IXGBE_SUCCESS) {
4869 : : return status;
4870 : : }
4871 : : /* Starting with first TLV after PFA length, iterate through the list
4872 : : * of TLVs to find the requested one.
4873 : : */
4874 : 0 : next_tlv = pfa_ptr + 1;
4875 : 0 : pfa_end_ptr = pfa_ptr + pfa_len;
4876 [ # # ]: 0 : while (next_tlv < pfa_end_ptr) {
4877 : : u16 tlv_sub_module_type, tlv_len;
4878 : :
4879 : : /* Read TLV type */
4880 : 0 : status = ixgbe_read_ee_aci_E610(hw, next_tlv,
4881 : : &tlv_sub_module_type);
4882 [ # # ]: 0 : if (status != IXGBE_SUCCESS) {
4883 : : break;
4884 : : }
4885 : : /* Read TLV length */
4886 : 0 : status = ixgbe_read_ee_aci_E610(hw, next_tlv + 1, &tlv_len);
4887 [ # # ]: 0 : if (status != IXGBE_SUCCESS) {
4888 : : break;
4889 : : }
4890 [ # # ]: 0 : if (tlv_sub_module_type == module_type) {
4891 [ # # ]: 0 : if (tlv_len) {
4892 : 0 : *module_tlv = next_tlv;
4893 : 0 : *module_tlv_len = tlv_len;
4894 : 0 : return IXGBE_SUCCESS;
4895 : : }
4896 : : return IXGBE_ERR_INVAL_SIZE;
4897 : : }
4898 : : /* Check next TLV, i.e. current TLV pointer + length + 2 words
4899 : : * (for current TLV's type and length)
4900 : : */
4901 : 0 : next_tlv = next_tlv + tlv_len + 2;
4902 : : }
4903 : : /* Module does not exist */
4904 : : return IXGBE_ERR_DOES_NOT_EXIST;
4905 : : }
4906 : :
4907 : : /**
4908 : : * ixgbe_read_pba_string_E610 - Reads part number string from NVM
4909 : : * @hw: pointer to hardware structure
4910 : : * @pba_num: stores the part number string from the NVM
4911 : : * @pba_num_size: part number string buffer length
4912 : : *
4913 : : * Reads the part number string from the NVM.
4914 : : *
4915 : : * Return: the exit code of the operation.
4916 : : */
4917 : 0 : s32 ixgbe_read_pba_string_E610(struct ixgbe_hw *hw, u8 *pba_num,
4918 : : u32 pba_num_size)
4919 : : {
4920 : : u16 pba_tlv, pba_tlv_len;
4921 : : u16 pba_word, pba_size;
4922 : : s32 status;
4923 : : u16 i;
4924 : :
4925 : 0 : status = ixgbe_get_pfa_module_tlv(hw, &pba_tlv, &pba_tlv_len,
4926 : : E610_SR_PBA_BLOCK_PTR);
4927 [ # # ]: 0 : if (status != IXGBE_SUCCESS) {
4928 : : return status;
4929 : : }
4930 : :
4931 : : /* pba_size is the next word */
4932 : 0 : status = ixgbe_read_ee_aci_E610(hw, (pba_tlv + 2), &pba_size);
4933 [ # # ]: 0 : if (status != IXGBE_SUCCESS) {
4934 : : return status;
4935 : : }
4936 : :
4937 [ # # ]: 0 : if (pba_tlv_len < pba_size) {
4938 : : return IXGBE_ERR_INVAL_SIZE;
4939 : : }
4940 : :
4941 : : /* Subtract one to get PBA word count (PBA Size word is included in
4942 : : * total size)
4943 : : */
4944 : 0 : pba_size--;
4945 [ # # ]: 0 : if (pba_num_size < (((u32)pba_size * 2) + 1)) {
4946 : : return IXGBE_ERR_PARAM;
4947 : : }
4948 : :
4949 [ # # ]: 0 : for (i = 0; i < pba_size; i++) {
4950 : 0 : status = ixgbe_read_ee_aci_E610(hw, (pba_tlv + 2 + 1) + i,
4951 : : &pba_word);
4952 [ # # ]: 0 : if (status != IXGBE_SUCCESS) {
4953 : 0 : return status;
4954 : : }
4955 : :
4956 : 0 : pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
4957 : 0 : pba_num[(i * 2) + 1] = pba_word & 0xFF;
4958 : : }
4959 : 0 : pba_num[(pba_size * 2)] = '\0';
4960 : :
4961 : 0 : return status;
4962 : : }
|