Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
3 : : * Copyright(c) 2018 Synopsys, Inc. All rights reserved.
4 : : */
5 : :
6 : : #include <rte_cycles.h>
7 : : #include "axgbe_ethdev.h"
8 : : #include "axgbe_common.h"
9 : : #include "axgbe_phy.h"
10 : :
11 : : #define AXGBE_PHY_PORT_SPEED_10 BIT(0)
12 : : #define AXGBE_PHY_PORT_SPEED_100 BIT(1)
13 : : #define AXGBE_PHY_PORT_SPEED_1000 BIT(2)
14 : : #define AXGBE_PHY_PORT_SPEED_2500 BIT(3)
15 : : #define AXGBE_PHY_PORT_SPEED_10000 BIT(4)
16 : :
17 : : #define AXGBE_MUTEX_RELEASE 0x80000000
18 : :
19 : : #define AXGBE_SFP_DIRECT 7
20 : :
21 : : /* I2C target addresses */
22 : : #define AXGBE_SFP_SERIAL_ID_ADDRESS 0x50
23 : : #define AXGBE_SFP_DIAG_INFO_ADDRESS 0x51
24 : : #define AXGBE_SFP_PHY_ADDRESS 0x56
25 : : #define AXGBE_GPIO_ADDRESS_PCA9555 0x20
26 : :
27 : : /* SFP sideband signal indicators */
28 : : #define AXGBE_GPIO_NO_TX_FAULT BIT(0)
29 : : #define AXGBE_GPIO_NO_RATE_SELECT BIT(1)
30 : : #define AXGBE_GPIO_NO_MOD_ABSENT BIT(2)
31 : : #define AXGBE_GPIO_NO_RX_LOS BIT(3)
32 : :
33 : : /* Rate-change complete wait/retry count */
34 : : #define AXGBE_RATECHANGE_COUNT 500
35 : :
36 : : /* CDR delay values for KR support (in usec) */
37 : : #define AXGBE_CDR_DELAY_INIT 10000
38 : : #define AXGBE_CDR_DELAY_INC 10000
39 : : #define AXGBE_CDR_DELAY_MAX 100000
40 : :
41 : : enum axgbe_port_mode {
42 : : AXGBE_PORT_MODE_RSVD = 0,
43 : : AXGBE_PORT_MODE_BACKPLANE,
44 : : AXGBE_PORT_MODE_BACKPLANE_2500,
45 : : AXGBE_PORT_MODE_1000BASE_T,
46 : : AXGBE_PORT_MODE_1000BASE_X,
47 : : AXGBE_PORT_MODE_NBASE_T,
48 : : AXGBE_PORT_MODE_10GBASE_T,
49 : : AXGBE_PORT_MODE_10GBASE_R,
50 : : AXGBE_PORT_MODE_SFP,
51 : : AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG,
52 : : AXGBE_PORT_MODE_MAX,
53 : : };
54 : :
55 : : enum axgbe_conn_type {
56 : : AXGBE_CONN_TYPE_NONE = 0,
57 : : AXGBE_CONN_TYPE_SFP,
58 : : AXGBE_CONN_TYPE_MDIO,
59 : : AXGBE_CONN_TYPE_RSVD1,
60 : : AXGBE_CONN_TYPE_BACKPLANE,
61 : : AXGBE_CONN_TYPE_MAX,
62 : : };
63 : :
64 : : /* SFP/SFP+ related definitions */
65 : : enum axgbe_sfp_comm {
66 : : AXGBE_SFP_COMM_DIRECT = 0,
67 : : AXGBE_SFP_COMM_PCA9545,
68 : : };
69 : :
70 : : enum axgbe_sfp_cable {
71 : : AXGBE_SFP_CABLE_UNKNOWN = 0,
72 : : AXGBE_SFP_CABLE_ACTIVE,
73 : : AXGBE_SFP_CABLE_PASSIVE,
74 : : AXGBE_SFP_CABLE_FIBER,
75 : : };
76 : :
77 : : enum axgbe_sfp_base {
78 : : AXGBE_SFP_BASE_UNKNOWN = 0,
79 : : AXGBE_SFP_BASE_1000_T,
80 : : AXGBE_SFP_BASE_1000_SX,
81 : : AXGBE_SFP_BASE_1000_LX,
82 : : AXGBE_SFP_BASE_1000_CX,
83 : : AXGBE_SFP_BASE_10000_SR,
84 : : AXGBE_SFP_BASE_10000_LR,
85 : : AXGBE_SFP_BASE_10000_LRM,
86 : : AXGBE_SFP_BASE_10000_ER,
87 : : AXGBE_SFP_BASE_10000_CR,
88 : : };
89 : :
90 : : enum axgbe_sfp_speed {
91 : : AXGBE_SFP_SPEED_UNKNOWN = 0,
92 : : AXGBE_SFP_SPEED_100_1000,
93 : : AXGBE_SFP_SPEED_1000,
94 : : AXGBE_SFP_SPEED_10000,
95 : : };
96 : :
97 : : /* SFP Serial ID Base ID values relative to an offset of 0 */
98 : : #define AXGBE_SFP_BASE_ID 0
99 : : #define AXGBE_SFP_ID_SFP 0x03
100 : :
101 : : #define AXGBE_SFP_BASE_EXT_ID 1
102 : : #define AXGBE_SFP_EXT_ID_SFP 0x04
103 : :
104 : : #define AXGBE_SFP_BASE_10GBE_CC 3
105 : : #define AXGBE_SFP_BASE_10GBE_CC_SR BIT(4)
106 : : #define AXGBE_SFP_BASE_10GBE_CC_LR BIT(5)
107 : : #define AXGBE_SFP_BASE_10GBE_CC_LRM BIT(6)
108 : : #define AXGBE_SFP_BASE_10GBE_CC_ER BIT(7)
109 : :
110 : : #define AXGBE_SFP_BASE_1GBE_CC 6
111 : : #define AXGBE_SFP_BASE_1GBE_CC_SX BIT(0)
112 : : #define AXGBE_SFP_BASE_1GBE_CC_LX BIT(1)
113 : : #define AXGBE_SFP_BASE_1GBE_CC_CX BIT(2)
114 : : #define AXGBE_SFP_BASE_1GBE_CC_T BIT(3)
115 : :
116 : : #define AXGBE_SFP_BASE_CABLE 8
117 : : #define AXGBE_SFP_BASE_CABLE_PASSIVE BIT(2)
118 : : #define AXGBE_SFP_BASE_CABLE_ACTIVE BIT(3)
119 : :
120 : : #define AXGBE_SFP_BASE_BR 12
121 : : #define AXGBE_SFP_BASE_BR_1GBE_MIN 0x0a
122 : : #define AXGBE_SFP_BASE_BR_10GBE_MIN 0x64
123 : :
124 : : #define AXGBE_SFP_BASE_CU_CABLE_LEN 18
125 : :
126 : : #define AXGBE_SFP_BASE_VENDOR_NAME 20
127 : : #define AXGBE_SFP_BASE_VENDOR_NAME_LEN 16
128 : : #define AXGBE_SFP_BASE_VENDOR_PN 40
129 : : #define AXGBE_SFP_BASE_VENDOR_PN_LEN 16
130 : : #define AXGBE_SFP_BASE_VENDOR_REV 56
131 : : #define AXGBE_SFP_BASE_VENDOR_REV_LEN 4
132 : :
133 : : #define AXGBE_SFP_BASE_CC 63
134 : :
135 : : /* SFP Serial ID Extended ID values relative to an offset of 64 */
136 : : #define AXGBE_SFP_BASE_VENDOR_SN 4
137 : : #define AXGBE_SFP_BASE_VENDOR_SN_LEN 16
138 : :
139 : : #define AXGBE_SFP_EXTD_DIAG 28
140 : : #define AXGBE_SFP_EXTD_DIAG_ADDR_CHANGE BIT(2)
141 : :
142 : : #define AXGBE_SFP_EXTD_SFF_8472 30
143 : :
144 : : #define AXGBE_SFP_EXTD_CC 31
145 : :
146 : : struct axgbe_sfp_eeprom {
147 : : u8 base[64];
148 : : u8 extd[32];
149 : : u8 vendor[32];
150 : : };
151 : :
152 : : #define AXGBE_BEL_FUSE_VENDOR "BEL-FUSE"
153 : : #define AXGBE_BEL_FUSE_PARTNO "1GBT-SFP06"
154 : :
155 : : struct axgbe_sfp_ascii {
156 : : union {
157 : : char vendor[AXGBE_SFP_BASE_VENDOR_NAME_LEN + 1];
158 : : char partno[AXGBE_SFP_BASE_VENDOR_PN_LEN + 1];
159 : : char rev[AXGBE_SFP_BASE_VENDOR_REV_LEN + 1];
160 : : char serno[AXGBE_SFP_BASE_VENDOR_SN_LEN + 1];
161 : : } u;
162 : : };
163 : :
164 : : /* MDIO PHY reset types */
165 : : enum axgbe_mdio_reset {
166 : : AXGBE_MDIO_RESET_NONE = 0,
167 : : AXGBE_MDIO_RESET_I2C_GPIO,
168 : : AXGBE_MDIO_RESET_INT_GPIO,
169 : : AXGBE_MDIO_RESET_MAX,
170 : : };
171 : :
172 : : /* Re-driver related definitions */
173 : : enum axgbe_phy_redrv_if {
174 : : AXGBE_PHY_REDRV_IF_MDIO = 0,
175 : : AXGBE_PHY_REDRV_IF_I2C,
176 : : AXGBE_PHY_REDRV_IF_MAX,
177 : : };
178 : :
179 : : enum axgbe_phy_redrv_model {
180 : : AXGBE_PHY_REDRV_MODEL_4223 = 0,
181 : : AXGBE_PHY_REDRV_MODEL_4227,
182 : : AXGBE_PHY_REDRV_MODEL_MAX,
183 : : };
184 : :
185 : : enum axgbe_phy_redrv_mode {
186 : : AXGBE_PHY_REDRV_MODE_CX = 5,
187 : : AXGBE_PHY_REDRV_MODE_SR = 9,
188 : : };
189 : :
190 : : #define AXGBE_PHY_REDRV_MODE_REG 0x12b0
191 : :
192 : : /* PHY related configuration information */
193 : : struct axgbe_phy_data {
194 : : enum axgbe_port_mode port_mode;
195 : :
196 : : unsigned int port_id;
197 : :
198 : : unsigned int port_speeds;
199 : :
200 : : enum axgbe_conn_type conn_type;
201 : :
202 : : enum axgbe_mode cur_mode;
203 : : enum axgbe_mode start_mode;
204 : :
205 : : unsigned int rrc_count;
206 : :
207 : : uint8_t mdio_addr;
208 : : uint32_t phy_id;
209 : :
210 : : /* SFP Support */
211 : : enum axgbe_sfp_comm sfp_comm;
212 : : unsigned int sfp_mux_address;
213 : : unsigned int sfp_mux_channel;
214 : :
215 : : unsigned int sfp_gpio_address;
216 : : unsigned int sfp_gpio_mask;
217 : : unsigned int sfp_gpio_rx_los;
218 : : unsigned int sfp_gpio_tx_fault;
219 : : unsigned int sfp_gpio_mod_absent;
220 : : unsigned int sfp_gpio_rate_select;
221 : :
222 : : unsigned int sfp_rx_los;
223 : : unsigned int sfp_tx_fault;
224 : : unsigned int sfp_mod_absent;
225 : : unsigned int sfp_changed;
226 : : unsigned int sfp_phy_avail;
227 : : unsigned int sfp_cable_len;
228 : : enum axgbe_sfp_base sfp_base;
229 : : enum axgbe_sfp_cable sfp_cable;
230 : : enum axgbe_sfp_speed sfp_speed;
231 : : struct axgbe_sfp_eeprom sfp_eeprom;
232 : :
233 : : /* External PHY support */
234 : : enum axgbe_mdio_mode phydev_mode;
235 : : enum axgbe_mdio_reset mdio_reset;
236 : : unsigned int mdio_reset_addr;
237 : : unsigned int mdio_reset_gpio;
238 : :
239 : : /* Re-driver support */
240 : : unsigned int redrv;
241 : : unsigned int redrv_if;
242 : : unsigned int redrv_addr;
243 : : unsigned int redrv_lane;
244 : : unsigned int redrv_model;
245 : :
246 : : /* KR AN support */
247 : : unsigned int phy_cdr_notrack;
248 : : unsigned int phy_cdr_delay;
249 : : };
250 : :
251 : : static enum axgbe_an_mode axgbe_phy_an_mode(struct axgbe_port *pdata);
252 : : static void axgbe_phy_perform_ratechange(struct axgbe_port *pdata,
253 : : enum axgbe_mb_cmd cmd, enum axgbe_mb_subcmd sub_cmd);
254 : : static void axgbe_phy_rrc(struct axgbe_port *pdata);
255 : :
256 : : static int axgbe_phy_get_comm_ownership(struct axgbe_port *pdata);
257 : : static void axgbe_phy_put_comm_ownership(struct axgbe_port *pdata);
258 : : static int axgbe_get_ext_phy_link_status(struct axgbe_port *pdata,
259 : : bool *linkup);
260 : :
261 : : static int axgbe_phy_i2c_xfer(struct axgbe_port *pdata,
262 : : struct axgbe_i2c_op *i2c_op)
263 : : {
264 : 0 : return pdata->i2c_if.i2c_xfer(pdata, i2c_op);
265 : : }
266 : :
267 : 0 : static int axgbe_phy_read(struct axgbe_port *pdata, u16 reg, u16 *value)
268 : : {
269 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
270 : : int ret;
271 : :
272 : 0 : ret = axgbe_phy_get_comm_ownership(pdata);
273 [ # # ]: 0 : if (ret)
274 : : return ret;
275 : :
276 : 0 : ret = pdata->hw_if.read_ext_mii_regs_c22(pdata,
277 : 0 : phy_data->mdio_addr, reg, value);
278 [ # # ]: 0 : if (ret)
279 : 0 : PMD_DRV_LOG_LINE(ERR, "mdio read failed %s",
280 : : strerror(-ret));
281 : :
282 : : axgbe_phy_put_comm_ownership(pdata);
283 : 0 : return ret;
284 : : }
285 : :
286 : 0 : static int axgbe_phy_write(struct axgbe_port *pdata, u16 reg, u16 value)
287 : : {
288 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
289 : : int ret;
290 : 0 : ret = axgbe_phy_get_comm_ownership(pdata);
291 [ # # ]: 0 : if (ret)
292 : : return ret;
293 : :
294 : 0 : ret = pdata->hw_if.write_ext_mii_regs_c22(pdata,
295 : 0 : phy_data->mdio_addr, reg, value);
296 [ # # ]: 0 : if (ret)
297 : 0 : PMD_DRV_LOG_LINE(ERR, "mdio write failed %s",
298 : : strerror(-ret));
299 : :
300 : : axgbe_phy_put_comm_ownership(pdata);
301 : 0 : return ret;
302 : : }
303 : :
304 : 0 : static int axgbe_phy_config_advert(struct axgbe_port *pdata)
305 : : {
306 : : u16 advert;
307 : : int ret;
308 : :
309 : 0 : ret = pdata->phy_if.phy_impl.read(pdata, MII_ADVERTISE, &advert);
310 [ # # ]: 0 : if (ret) {
311 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to read ADVERTISE register");
312 : 0 : return ret;
313 : : }
314 : :
315 : 0 : advert |= ADVERTISE_FULL;
316 : 0 : advert |= ADVERTISE_PAUSE_CAP;
317 : :
318 : 0 : ret = pdata->phy_if.phy_impl.write(pdata, MII_ADVERTISE, advert);
319 [ # # ]: 0 : if (ret) {
320 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to write ADVERTISE register");
321 : 0 : return ret;
322 : : }
323 : : return 0;
324 : : }
325 : :
326 : 0 : static int axgbe_phy_set_speed(struct axgbe_port *pdata)
327 : : {
328 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
329 : : u16 bmcr;
330 : : int ret;
331 : :
332 : 0 : ret = pdata->phy_if.phy_impl.read(pdata, MII_BMCR, &bmcr);
333 [ # # ]: 0 : if (ret) {
334 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to read BMCR register");
335 : 0 : return ret;
336 : : }
337 : :
338 : 0 : bmcr &= ~(MDIO_CTRL1_SPEEDSELEXT);
339 [ # # # ]: 0 : switch (phy_data->cur_mode) {
340 : 0 : case AXGBE_MODE_SGMII_1000:
341 : 0 : bmcr |= BMCR_SPEED1000;
342 : 0 : break;
343 : 0 : case AXGBE_MODE_SGMII_100:
344 : 0 : bmcr |= BMCR_SPEED100;
345 : 0 : break;
346 : : default:
347 : : break;
348 : : }
349 : :
350 : 0 : ret = pdata->phy_if.phy_impl.write(pdata, MII_BMCR, bmcr);
351 [ # # ]: 0 : if (ret) {
352 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to write BMCR register");
353 : 0 : return ret;
354 : : }
355 : : return 0;
356 : : }
357 : :
358 : 0 : static int axgbe_phy_config_aneg(struct axgbe_port *pdata)
359 : : {
360 : : u16 bmcr;
361 : : int ret;
362 : :
363 : 0 : ret = pdata->phy_if.phy_impl.read(pdata, MII_BMCR, &bmcr);
364 [ # # ]: 0 : if (ret) {
365 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to read BMCR register");
366 : 0 : return ret;
367 : : }
368 : :
369 : 0 : bmcr &= ~(BMCR_ANENABLE);
370 [ # # ]: 0 : if (pdata->phy.autoneg == AUTONEG_ENABLE)
371 : 0 : bmcr |= BMCR_ANENABLE | BMCR_ANRESTART;
372 : :
373 : 0 : ret = pdata->phy_if.phy_impl.write(pdata, MII_BMCR, bmcr);
374 : :
375 [ # # ]: 0 : if (ret) {
376 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to write BMCR register");
377 : 0 : return ret;
378 : : }
379 : : return 0;
380 : : }
381 : :
382 : 0 : static int axgbe_phy_redrv_write(struct axgbe_port *pdata, unsigned int reg,
383 : : unsigned int val)
384 : : {
385 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
386 : : struct axgbe_i2c_op i2c_op;
387 : : uint16_t *redrv_val;
388 : : u8 redrv_data[5], csum;
389 : : unsigned int i, retry;
390 : : int ret;
391 : :
392 : : /* High byte of register contains read/write indicator */
393 : 0 : redrv_data[0] = ((reg >> 8) & 0xff) << 1;
394 : 0 : redrv_data[1] = reg & 0xff;
395 : : redrv_val = (uint16_t *)&redrv_data[2];
396 [ # # ]: 0 : *redrv_val = rte_cpu_to_be_16(val);
397 : :
398 : : /* Calculate 1 byte checksum */
399 : : csum = 0;
400 [ # # ]: 0 : for (i = 0; i < 4; i++) {
401 : 0 : csum += redrv_data[i];
402 [ # # ]: 0 : if (redrv_data[i] > csum)
403 : 0 : csum++;
404 : : }
405 : 0 : redrv_data[4] = ~csum;
406 : :
407 : : retry = 1;
408 : 0 : again1:
409 : 0 : i2c_op.cmd = AXGBE_I2C_CMD_WRITE;
410 : 0 : i2c_op.target = phy_data->redrv_addr;
411 : 0 : i2c_op.len = sizeof(redrv_data);
412 : 0 : i2c_op.buf = redrv_data;
413 : : ret = axgbe_phy_i2c_xfer(pdata, &i2c_op);
414 [ # # ]: 0 : if (ret) {
415 [ # # # # ]: 0 : if ((ret == -EAGAIN) && retry--)
416 : 0 : goto again1;
417 : :
418 : 0 : return ret;
419 : : }
420 : :
421 : : retry = 1;
422 : 0 : again2:
423 : 0 : i2c_op.cmd = AXGBE_I2C_CMD_READ;
424 : 0 : i2c_op.target = phy_data->redrv_addr;
425 : 0 : i2c_op.len = 1;
426 : 0 : i2c_op.buf = redrv_data;
427 : : ret = axgbe_phy_i2c_xfer(pdata, &i2c_op);
428 [ # # ]: 0 : if (ret) {
429 [ # # # # ]: 0 : if ((ret == -EAGAIN) && retry--)
430 : 0 : goto again2;
431 : :
432 : 0 : return ret;
433 : : }
434 : :
435 [ # # ]: 0 : if (redrv_data[0] != 0xff) {
436 : 0 : PMD_DRV_LOG_LINE(ERR, "Redriver write checksum error");
437 : : ret = -EIO;
438 : : }
439 : :
440 : : return ret;
441 : : }
442 : :
443 : 0 : static int axgbe_phy_i2c_read(struct axgbe_port *pdata, unsigned int target,
444 : : void *reg, unsigned int reg_len,
445 : : void *val, unsigned int val_len)
446 : : {
447 : : struct axgbe_i2c_op i2c_op;
448 : : int retry, ret;
449 : :
450 : : retry = 1;
451 : 0 : again1:
452 : : /* Set the specified register to read */
453 : 0 : i2c_op.cmd = AXGBE_I2C_CMD_WRITE;
454 : 0 : i2c_op.target = target;
455 : 0 : i2c_op.len = reg_len;
456 : 0 : i2c_op.buf = reg;
457 : : ret = axgbe_phy_i2c_xfer(pdata, &i2c_op);
458 [ # # ]: 0 : if (ret) {
459 [ # # # # ]: 0 : if ((ret == -EAGAIN) && retry--)
460 : 0 : goto again1;
461 : :
462 : 0 : return ret;
463 : : }
464 : :
465 : : retry = 1;
466 : 0 : again2:
467 : : /* Read the specified register */
468 : 0 : i2c_op.cmd = AXGBE_I2C_CMD_READ;
469 : 0 : i2c_op.target = target;
470 : 0 : i2c_op.len = val_len;
471 : 0 : i2c_op.buf = val;
472 : : ret = axgbe_phy_i2c_xfer(pdata, &i2c_op);
473 [ # # # # ]: 0 : if ((ret == -EAGAIN) && retry--)
474 : 0 : goto again2;
475 : :
476 : : return ret;
477 : : }
478 : :
479 : : static int axgbe_phy_sfp_put_mux(struct axgbe_port *pdata)
480 : : {
481 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
482 : : struct axgbe_i2c_op i2c_op;
483 : : uint8_t mux_channel;
484 : :
485 : 0 : if (phy_data->sfp_comm == AXGBE_SFP_COMM_DIRECT)
486 : : return 0;
487 : :
488 : : /* Select no mux channels */
489 : 0 : mux_channel = 0;
490 : 0 : i2c_op.cmd = AXGBE_I2C_CMD_WRITE;
491 : 0 : i2c_op.target = phy_data->sfp_mux_address;
492 : 0 : i2c_op.len = sizeof(mux_channel);
493 : 0 : i2c_op.buf = &mux_channel;
494 : :
495 : 0 : return axgbe_phy_i2c_xfer(pdata, &i2c_op);
496 : : }
497 : :
498 : 0 : static int axgbe_phy_sfp_get_mux(struct axgbe_port *pdata)
499 : : {
500 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
501 : : struct axgbe_i2c_op i2c_op;
502 : : u8 mux_channel;
503 : :
504 [ # # ]: 0 : if (phy_data->sfp_comm == AXGBE_SFP_COMM_DIRECT)
505 : : return 0;
506 : :
507 : : /* Select desired mux channel */
508 : 0 : mux_channel = 1 << phy_data->sfp_mux_channel;
509 : 0 : i2c_op.cmd = AXGBE_I2C_CMD_WRITE;
510 : 0 : i2c_op.target = phy_data->sfp_mux_address;
511 : 0 : i2c_op.len = sizeof(mux_channel);
512 : 0 : i2c_op.buf = &mux_channel;
513 : :
514 : 0 : return axgbe_phy_i2c_xfer(pdata, &i2c_op);
515 : : }
516 : :
517 : : static void axgbe_phy_put_comm_ownership(struct axgbe_port *pdata)
518 : : {
519 : 0 : pthread_mutex_unlock(&pdata->phy_mutex);
520 : 0 : }
521 : :
522 : 0 : static int axgbe_phy_get_comm_ownership(struct axgbe_port *pdata)
523 : : {
524 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
525 : : uint64_t timeout;
526 : : unsigned int mutex_id;
527 : :
528 : : /* The I2C and MDIO/GPIO bus is multiplexed between multiple devices,
529 : : * the driver needs to take the software mutex and then the hardware
530 : : * mutexes before being able to use the busses.
531 : : */
532 : 0 : pthread_mutex_lock(&pdata->phy_mutex);
533 : :
534 : : /* Clear the mutexes */
535 : 0 : XP_IOWRITE(pdata, XP_I2C_MUTEX, AXGBE_MUTEX_RELEASE);
536 : 0 : XP_IOWRITE(pdata, XP_MDIO_MUTEX, AXGBE_MUTEX_RELEASE);
537 : :
538 : : /* Mutex formats are the same for I2C and MDIO/GPIO */
539 : : mutex_id = 0;
540 : 0 : XP_SET_BITS(mutex_id, XP_I2C_MUTEX, ID, phy_data->port_id);
541 : 0 : XP_SET_BITS(mutex_id, XP_I2C_MUTEX, ACTIVE, 1);
542 : :
543 : 0 : timeout = rte_get_timer_cycles() + (rte_get_timer_hz() * 5);
544 [ # # ]: 0 : while (time_before(rte_get_timer_cycles(), timeout)) {
545 : : /* Must be all zeroes in order to obtain the mutex */
546 [ # # # # ]: 0 : if (XP_IOREAD(pdata, XP_I2C_MUTEX) ||
547 : 0 : XP_IOREAD(pdata, XP_MDIO_MUTEX)) {
548 : 0 : rte_delay_us(100);
549 : 0 : continue;
550 : : }
551 : :
552 : : /* Obtain the mutex */
553 : 0 : XP_IOWRITE(pdata, XP_I2C_MUTEX, mutex_id);
554 : 0 : XP_IOWRITE(pdata, XP_MDIO_MUTEX, mutex_id);
555 : :
556 : 0 : return 0;
557 : : }
558 : :
559 : 0 : pthread_mutex_unlock(&pdata->phy_mutex);
560 : :
561 : 0 : PMD_DRV_LOG_LINE(ERR, "unable to obtain hardware mutexes");
562 : :
563 : 0 : return -ETIMEDOUT;
564 : : }
565 : :
566 : 0 : static void axgbe_phy_sfp_phy_settings(struct axgbe_port *pdata)
567 : : {
568 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
569 : :
570 [ # # ]: 0 : if (phy_data->sfp_mod_absent) {
571 : : pdata->phy.speed = SPEED_UNKNOWN;
572 : 0 : pdata->phy.duplex = DUPLEX_UNKNOWN;
573 : 0 : pdata->phy.autoneg = AUTONEG_ENABLE;
574 : 0 : pdata->phy.advertising = pdata->phy.supported;
575 : : }
576 : :
577 : 0 : pdata->phy.advertising &= ~ADVERTISED_Autoneg;
578 : 0 : pdata->phy.advertising &= ~ADVERTISED_TP;
579 : 0 : pdata->phy.advertising &= ~ADVERTISED_FIBRE;
580 : 0 : pdata->phy.advertising &= ~ADVERTISED_100baseT_Full;
581 : 0 : pdata->phy.advertising &= ~ADVERTISED_1000baseT_Full;
582 : 0 : pdata->phy.advertising &= ~ADVERTISED_10000baseT_Full;
583 : 0 : pdata->phy.advertising &= ~ADVERTISED_10000baseR_FEC;
584 : :
585 [ # # ]: 0 : switch (phy_data->sfp_base) {
586 : 0 : case AXGBE_SFP_BASE_1000_T:
587 : : case AXGBE_SFP_BASE_1000_SX:
588 : : case AXGBE_SFP_BASE_1000_LX:
589 : : case AXGBE_SFP_BASE_1000_CX:
590 : 0 : pdata->phy.speed = SPEED_UNKNOWN;
591 : 0 : pdata->phy.duplex = DUPLEX_UNKNOWN;
592 : 0 : pdata->phy.autoneg = AUTONEG_ENABLE;
593 : 0 : pdata->phy.advertising |= ADVERTISED_Autoneg;
594 : 0 : break;
595 : 0 : case AXGBE_SFP_BASE_10000_SR:
596 : : case AXGBE_SFP_BASE_10000_LR:
597 : : case AXGBE_SFP_BASE_10000_LRM:
598 : : case AXGBE_SFP_BASE_10000_ER:
599 : : case AXGBE_SFP_BASE_10000_CR:
600 : : default:
601 : 0 : pdata->phy.speed = SPEED_10000;
602 : 0 : pdata->phy.duplex = DUPLEX_FULL;
603 : 0 : pdata->phy.autoneg = AUTONEG_DISABLE;
604 : 0 : break;
605 : : }
606 : :
607 [ # # ]: 0 : switch (phy_data->sfp_base) {
608 : 0 : case AXGBE_SFP_BASE_1000_T:
609 : : case AXGBE_SFP_BASE_1000_CX:
610 : : case AXGBE_SFP_BASE_10000_CR:
611 : 0 : pdata->phy.advertising |= ADVERTISED_TP;
612 : 0 : break;
613 : 0 : default:
614 : 0 : pdata->phy.advertising |= ADVERTISED_FIBRE;
615 : : }
616 : :
617 [ # # # # ]: 0 : switch (phy_data->sfp_speed) {
618 : 0 : case AXGBE_SFP_SPEED_100_1000:
619 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)
620 : 0 : pdata->phy.advertising |= ADVERTISED_10baseT_Full;
621 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100)
622 : 0 : pdata->phy.advertising |= ADVERTISED_100baseT_Full;
623 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000)
624 : 0 : pdata->phy.advertising |= ADVERTISED_1000baseT_Full;
625 : : break;
626 : 0 : case AXGBE_SFP_SPEED_1000:
627 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000)
628 : 0 : pdata->phy.advertising |= ADVERTISED_1000baseT_Full;
629 : : break;
630 : 0 : case AXGBE_SFP_SPEED_10000:
631 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000)
632 : 0 : pdata->phy.advertising |= ADVERTISED_10000baseT_Full;
633 : : break;
634 : 0 : default:
635 : : /* Choose the fastest supported speed */
636 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000)
637 : 0 : pdata->phy.advertising |= ADVERTISED_10000baseT_Full;
638 [ # # ]: 0 : else if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000)
639 : 0 : pdata->phy.advertising |= ADVERTISED_1000baseT_Full;
640 [ # # ]: 0 : else if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100)
641 : 0 : pdata->phy.advertising |= ADVERTISED_100baseT_Full;
642 [ # # ]: 0 : else if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)
643 : 0 : pdata->phy.advertising |= ADVERTISED_10baseT_Full;
644 : : }
645 : 0 : }
646 : :
647 : : static bool axgbe_phy_sfp_bit_rate(struct axgbe_sfp_eeprom *sfp_eeprom,
648 : : enum axgbe_sfp_speed sfp_speed)
649 : : {
650 : : u8 *sfp_base, min;
651 : :
652 : : sfp_base = sfp_eeprom->base;
653 : :
654 : : switch (sfp_speed) {
655 : : case AXGBE_SFP_SPEED_1000:
656 : : min = AXGBE_SFP_BASE_BR_1GBE_MIN;
657 : : break;
658 : : case AXGBE_SFP_SPEED_10000:
659 : : min = AXGBE_SFP_BASE_BR_10GBE_MIN;
660 : : break;
661 : : default:
662 : : return false;
663 : : }
664 : :
665 : 0 : return sfp_base[AXGBE_SFP_BASE_BR] >= min;
666 : : }
667 : :
668 : : static void axgbe_phy_sfp_external_phy(struct axgbe_port *pdata)
669 : : {
670 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
671 : :
672 [ # # ]: 0 : if (!phy_data->sfp_changed)
673 : : return;
674 : :
675 : 0 : phy_data->sfp_phy_avail = 0;
676 : :
677 : : if (phy_data->sfp_base != AXGBE_SFP_BASE_1000_T)
678 : : return;
679 : : }
680 : :
681 : 0 : static bool axgbe_phy_belfuse_parse_quirks(struct axgbe_port *pdata)
682 : : {
683 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
684 : : struct axgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
685 : :
686 [ # # ]: 0 : if (memcmp(&sfp_eeprom->base[AXGBE_SFP_BASE_VENDOR_NAME],
687 : : AXGBE_BEL_FUSE_VENDOR, strlen(AXGBE_BEL_FUSE_VENDOR)))
688 : : return false;
689 : : /* For Bel-Fuse, use the extra AN flag */
690 : 0 : pdata->an_again = 1;
691 : :
692 : : /* Reset PHY - wait for self-clearing reset bit to clear */
693 : 0 : pdata->phy_if.phy_impl.reset(pdata);
694 : :
695 [ # # ]: 0 : if (!memcmp(&sfp_eeprom->base[AXGBE_SFP_BASE_VENDOR_PN],
696 : : AXGBE_BEL_FUSE_PARTNO, strlen(AXGBE_BEL_FUSE_PARTNO))) {
697 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_1000_SX;
698 : 0 : phy_data->sfp_cable = AXGBE_SFP_CABLE_ACTIVE;
699 : 0 : phy_data->sfp_speed = AXGBE_SFP_SPEED_1000;
700 : 0 : return true;
701 : : }
702 : :
703 : : return false;
704 : : }
705 : :
706 : : static bool axgbe_phy_sfp_parse_quirks(struct axgbe_port *pdata)
707 : : {
708 : 0 : if (axgbe_phy_belfuse_parse_quirks(pdata))
709 : : return true;
710 : :
711 : : return false;
712 : : }
713 : :
714 : 0 : static void axgbe_phy_sfp_parse_eeprom(struct axgbe_port *pdata)
715 : : {
716 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
717 : : struct axgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
718 : : uint8_t *sfp_base;
719 : :
720 : : sfp_base = sfp_eeprom->base;
721 : :
722 [ # # ]: 0 : if (sfp_base[AXGBE_SFP_BASE_ID] != AXGBE_SFP_ID_SFP)
723 : : return;
724 : :
725 [ # # ]: 0 : if (sfp_base[AXGBE_SFP_BASE_EXT_ID] != AXGBE_SFP_EXT_ID_SFP)
726 : : return;
727 : :
728 : : axgbe_phy_sfp_parse_quirks(pdata);
729 : :
730 : : /* Assume FIBER cable unless told otherwise */
731 [ # # ]: 0 : if (sfp_base[AXGBE_SFP_BASE_CABLE] & AXGBE_SFP_BASE_CABLE_PASSIVE) {
732 : 0 : phy_data->sfp_cable = AXGBE_SFP_CABLE_PASSIVE;
733 : 0 : phy_data->sfp_cable_len = sfp_base[AXGBE_SFP_BASE_CU_CABLE_LEN];
734 [ # # ]: 0 : } else if (sfp_base[AXGBE_SFP_BASE_CABLE] & AXGBE_SFP_BASE_CABLE_ACTIVE) {
735 : 0 : phy_data->sfp_cable = AXGBE_SFP_CABLE_ACTIVE;
736 : : } else {
737 : 0 : phy_data->sfp_cable = AXGBE_SFP_CABLE_FIBER;
738 : : }
739 : :
740 : : /* Determine the type of SFP */
741 [ # # # # ]: 0 : if (phy_data->sfp_cable != AXGBE_SFP_CABLE_FIBER &&
742 : : axgbe_phy_sfp_bit_rate(sfp_eeprom, AXGBE_SFP_SPEED_10000))
743 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_10000_CR;
744 [ # # ]: 0 : else if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] & AXGBE_SFP_BASE_10GBE_CC_SR)
745 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_10000_SR;
746 [ # # ]: 0 : else if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] & AXGBE_SFP_BASE_10GBE_CC_LR)
747 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_10000_LR;
748 [ # # ]: 0 : else if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] &
749 : : AXGBE_SFP_BASE_10GBE_CC_LRM)
750 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_10000_LRM;
751 [ # # ]: 0 : else if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] & AXGBE_SFP_BASE_10GBE_CC_ER)
752 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_10000_ER;
753 [ # # ]: 0 : else if (sfp_base[AXGBE_SFP_BASE_1GBE_CC] & AXGBE_SFP_BASE_1GBE_CC_SX)
754 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_1000_SX;
755 [ # # ]: 0 : else if (sfp_base[AXGBE_SFP_BASE_1GBE_CC] & AXGBE_SFP_BASE_1GBE_CC_LX)
756 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_1000_LX;
757 [ # # ]: 0 : else if (sfp_base[AXGBE_SFP_BASE_1GBE_CC] & AXGBE_SFP_BASE_1GBE_CC_CX)
758 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_1000_CX;
759 [ # # ]: 0 : else if (sfp_base[AXGBE_SFP_BASE_1GBE_CC] & AXGBE_SFP_BASE_1GBE_CC_T)
760 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_1000_T;
761 : :
762 [ # # # # ]: 0 : switch (phy_data->sfp_base) {
763 : 0 : case AXGBE_SFP_BASE_1000_T:
764 : 0 : phy_data->sfp_speed = AXGBE_SFP_SPEED_100_1000;
765 : 0 : break;
766 : 0 : case AXGBE_SFP_BASE_1000_SX:
767 : : case AXGBE_SFP_BASE_1000_LX:
768 : : case AXGBE_SFP_BASE_1000_CX:
769 : 0 : phy_data->sfp_speed = AXGBE_SFP_SPEED_1000;
770 : 0 : break;
771 : 0 : case AXGBE_SFP_BASE_10000_SR:
772 : : case AXGBE_SFP_BASE_10000_LR:
773 : : case AXGBE_SFP_BASE_10000_LRM:
774 : : case AXGBE_SFP_BASE_10000_ER:
775 : : case AXGBE_SFP_BASE_10000_CR:
776 : 0 : phy_data->sfp_speed = AXGBE_SFP_SPEED_10000;
777 : 0 : break;
778 : : default:
779 : : break;
780 : : }
781 : : }
782 : :
783 : : static bool axgbe_phy_sfp_verify_eeprom(uint8_t cc_in, uint8_t *buf,
784 : : unsigned int len)
785 : : {
786 : : uint8_t cc;
787 : :
788 [ # # # # ]: 0 : for (cc = 0; len; buf++, len--)
789 : 0 : cc += *buf;
790 : :
791 : : return cc == cc_in;
792 : : }
793 : :
794 : 0 : static int axgbe_phy_sfp_read_eeprom(struct axgbe_port *pdata)
795 : : {
796 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
797 : : struct axgbe_sfp_eeprom sfp_eeprom;
798 : : uint8_t eeprom_addr;
799 : : int ret;
800 : :
801 : 0 : ret = axgbe_phy_sfp_get_mux(pdata);
802 [ # # ]: 0 : if (ret) {
803 : 0 : PMD_DRV_LOG_LINE(ERR, "I2C error setting SFP MUX");
804 : 0 : return ret;
805 : : }
806 : :
807 : : /* Read the SFP serial ID eeprom */
808 : 0 : eeprom_addr = 0;
809 : 0 : ret = axgbe_phy_i2c_read(pdata, AXGBE_SFP_SERIAL_ID_ADDRESS,
810 : : &eeprom_addr, sizeof(eeprom_addr),
811 : : &sfp_eeprom, sizeof(sfp_eeprom));
812 [ # # ]: 0 : if (ret) {
813 : 0 : PMD_DRV_LOG_LINE(ERR, "I2C error reading SFP EEPROM");
814 : 0 : goto put;
815 : : }
816 : :
817 : : /* Validate the contents read */
818 [ # # ]: 0 : if (!axgbe_phy_sfp_verify_eeprom(sfp_eeprom.base[AXGBE_SFP_BASE_CC],
819 : : sfp_eeprom.base,
820 : : sizeof(sfp_eeprom.base) - 1)) {
821 : : ret = -EINVAL;
822 : 0 : goto put;
823 : : }
824 : :
825 [ # # ]: 0 : if (!axgbe_phy_sfp_verify_eeprom(sfp_eeprom.extd[AXGBE_SFP_EXTD_CC],
826 : : sfp_eeprom.extd,
827 : : sizeof(sfp_eeprom.extd) - 1)) {
828 : : ret = -EINVAL;
829 : 0 : goto put;
830 : : }
831 : :
832 : : /* Check for an added or changed SFP */
833 [ # # ]: 0 : if (memcmp(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom))) {
834 : 0 : phy_data->sfp_changed = 1;
835 : : memcpy(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom));
836 : : } else {
837 : 0 : phy_data->sfp_changed = 0;
838 : : }
839 : :
840 [ # # ]: 0 : put:
841 : : axgbe_phy_sfp_put_mux(pdata);
842 : :
843 : 0 : return ret;
844 : : }
845 : :
846 : 0 : static void axgbe_phy_sfp_signals(struct axgbe_port *pdata)
847 : : {
848 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
849 : : unsigned int gpio_input;
850 : : u8 gpio_reg, gpio_ports[2];
851 : : int ret;
852 : :
853 : : /* Read the input port registers */
854 : 0 : gpio_reg = 0;
855 : 0 : ret = axgbe_phy_i2c_read(pdata, phy_data->sfp_gpio_address,
856 : : &gpio_reg, sizeof(gpio_reg),
857 : : gpio_ports, sizeof(gpio_ports));
858 [ # # ]: 0 : if (ret) {
859 : 0 : PMD_DRV_LOG_LINE(ERR, "I2C error reading SFP GPIOs");
860 : 0 : return;
861 : : }
862 : :
863 : 0 : gpio_input = (gpio_ports[1] << 8) | gpio_ports[0];
864 : :
865 [ # # ]: 0 : if (phy_data->sfp_gpio_mask & AXGBE_GPIO_NO_MOD_ABSENT) {
866 : : /* No GPIO, just assume the module is present for now */
867 : 0 : phy_data->sfp_mod_absent = 0;
868 : : } else {
869 [ # # ]: 0 : if (!(gpio_input & (1 << phy_data->sfp_gpio_mod_absent)))
870 : 0 : phy_data->sfp_mod_absent = 0;
871 : : }
872 : :
873 [ # # ]: 0 : if (!(phy_data->sfp_gpio_mask & AXGBE_GPIO_NO_RX_LOS) &&
874 [ # # ]: 0 : (gpio_input & (1 << phy_data->sfp_gpio_rx_los)))
875 : 0 : phy_data->sfp_rx_los = 1;
876 : :
877 [ # # ]: 0 : if (!(phy_data->sfp_gpio_mask & AXGBE_GPIO_NO_TX_FAULT) &&
878 [ # # ]: 0 : (gpio_input & (1 << phy_data->sfp_gpio_tx_fault)))
879 : 0 : phy_data->sfp_tx_fault = 1;
880 : : }
881 : :
882 : : static void axgbe_phy_sfp_mod_absent(struct axgbe_port *pdata)
883 : : {
884 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
885 : :
886 : 0 : phy_data->sfp_mod_absent = 1;
887 : 0 : phy_data->sfp_phy_avail = 0;
888 : 0 : memset(&phy_data->sfp_eeprom, 0, sizeof(phy_data->sfp_eeprom));
889 : : }
890 : :
891 : : static void axgbe_phy_sfp_reset(struct axgbe_phy_data *phy_data)
892 : : {
893 : 0 : phy_data->sfp_rx_los = 0;
894 : 0 : phy_data->sfp_tx_fault = 0;
895 : 0 : phy_data->sfp_mod_absent = 1;
896 : 0 : phy_data->sfp_base = AXGBE_SFP_BASE_UNKNOWN;
897 : 0 : phy_data->sfp_cable = AXGBE_SFP_CABLE_UNKNOWN;
898 : 0 : phy_data->sfp_speed = AXGBE_SFP_SPEED_UNKNOWN;
899 : : }
900 : :
901 : 0 : static const char *axgbe_base_as_string(enum axgbe_sfp_base sfp_base)
902 : : {
903 [ # # # # : 0 : switch (sfp_base) {
# # # # #
# ]
904 : : case AXGBE_SFP_BASE_1000_T:
905 : : return "1G_T";
906 : 0 : case AXGBE_SFP_BASE_1000_SX:
907 : 0 : return "1G_SX";
908 : 0 : case AXGBE_SFP_BASE_1000_LX:
909 : 0 : return "1G_LX";
910 : 0 : case AXGBE_SFP_BASE_1000_CX:
911 : 0 : return "1G_CX";
912 : 0 : case AXGBE_SFP_BASE_10000_SR:
913 : 0 : return "10G_SR";
914 : 0 : case AXGBE_SFP_BASE_10000_LR:
915 : 0 : return "10G_LR";
916 : 0 : case AXGBE_SFP_BASE_10000_LRM:
917 : 0 : return "10G_LRM";
918 : 0 : case AXGBE_SFP_BASE_10000_ER:
919 : 0 : return "10G_ER";
920 : 0 : case AXGBE_SFP_BASE_10000_CR:
921 : 0 : return "10G_CR";
922 : 0 : default:
923 : 0 : return "Unknown";
924 : : }
925 : : }
926 : :
927 : 0 : static void axgbe_phy_sfp_detect(struct axgbe_port *pdata)
928 : : {
929 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
930 : : int ret;
931 : :
932 : : /* Clear the extra AN flag */
933 : 0 : pdata->an_again = 0;
934 : :
935 : : /* Reset the SFP signals and info */
936 : : axgbe_phy_sfp_reset(phy_data);
937 : :
938 : 0 : ret = axgbe_phy_get_comm_ownership(pdata);
939 [ # # ]: 0 : if (ret)
940 : : return;
941 : :
942 : : /* Read the SFP signals and check for module presence */
943 : 0 : axgbe_phy_sfp_signals(pdata);
944 [ # # ]: 0 : if (phy_data->sfp_mod_absent) {
945 : : axgbe_phy_sfp_mod_absent(pdata);
946 : 0 : goto put;
947 : : }
948 : :
949 : 0 : ret = axgbe_phy_sfp_read_eeprom(pdata);
950 [ # # ]: 0 : if (ret) {
951 : : /* Treat any error as if there isn't an SFP plugged in */
952 : : axgbe_phy_sfp_reset(phy_data);
953 : : axgbe_phy_sfp_mod_absent(pdata);
954 : 0 : goto put;
955 : : }
956 : :
957 : 0 : axgbe_phy_sfp_parse_eeprom(pdata);
958 : : axgbe_phy_sfp_external_phy(pdata);
959 : :
960 : 0 : PMD_DRV_LOG_LINE(DEBUG, "SFP Base: %s",
961 : : axgbe_base_as_string(phy_data->sfp_base));
962 : :
963 : 0 : put:
964 : 0 : axgbe_phy_sfp_phy_settings(pdata);
965 : : axgbe_phy_put_comm_ownership(pdata);
966 : : }
967 : :
968 : : static void axgbe_phy_phydev_flowctrl(struct axgbe_port *pdata)
969 : : {
970 : 0 : pdata->phy.tx_pause = 0;
971 : 0 : pdata->phy.rx_pause = 0;
972 : 0 : }
973 : :
974 : 0 : static enum axgbe_mode axgbe_phy_an73_redrv_outcome(struct axgbe_port *pdata)
975 : : {
976 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
977 : : enum axgbe_mode mode;
978 : : unsigned int ad_reg, lp_reg;
979 : :
980 : 0 : pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
981 : 0 : pdata->phy.lp_advertising |= ADVERTISED_Backplane;
982 : :
983 : : /* Use external PHY to determine flow control */
984 [ # # ]: 0 : if (pdata->phy.pause_autoneg)
985 : : axgbe_phy_phydev_flowctrl(pdata);
986 : :
987 : : /* Compare Advertisement and Link Partner register 2 */
988 : 0 : ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
989 : 0 : lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
990 [ # # ]: 0 : if (lp_reg & 0x80)
991 : 0 : pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full;
992 [ # # ]: 0 : if (lp_reg & 0x20)
993 : 0 : pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full;
994 : :
995 : 0 : ad_reg &= lp_reg;
996 [ # # ]: 0 : if (ad_reg & 0x80) {
997 [ # # ]: 0 : switch (phy_data->port_mode) {
998 : : case AXGBE_PORT_MODE_BACKPLANE:
999 : : case AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
1000 : : mode = AXGBE_MODE_KR;
1001 : : break;
1002 : 0 : default:
1003 : : mode = AXGBE_MODE_SFI;
1004 : 0 : break;
1005 : : }
1006 [ # # ]: 0 : } else if (ad_reg & 0x20) {
1007 [ # # # # ]: 0 : switch (phy_data->port_mode) {
1008 : : case AXGBE_PORT_MODE_BACKPLANE:
1009 : : case AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
1010 : : mode = AXGBE_MODE_KX_1000;
1011 : : break;
1012 : 0 : case AXGBE_PORT_MODE_1000BASE_X:
1013 : : mode = AXGBE_MODE_X;
1014 : 0 : break;
1015 : 0 : case AXGBE_PORT_MODE_SFP:
1016 [ # # ]: 0 : switch (phy_data->sfp_base) {
1017 : : case AXGBE_SFP_BASE_1000_T:
1018 : : mode = AXGBE_MODE_SGMII_1000;
1019 : : break;
1020 : 0 : case AXGBE_SFP_BASE_1000_SX:
1021 : : case AXGBE_SFP_BASE_1000_LX:
1022 : : case AXGBE_SFP_BASE_1000_CX:
1023 : : default:
1024 : : mode = AXGBE_MODE_X;
1025 : 0 : break;
1026 : : }
1027 : : break;
1028 : 0 : default:
1029 : : mode = AXGBE_MODE_SGMII_1000;
1030 : 0 : break;
1031 : : }
1032 : : } else {
1033 : : mode = AXGBE_MODE_UNKNOWN;
1034 : : }
1035 : :
1036 : : /* Compare Advertisement and Link Partner register 3 */
1037 : 0 : ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
1038 : 0 : lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
1039 [ # # ]: 0 : if (lp_reg & 0xc000)
1040 : 0 : pdata->phy.lp_advertising |= ADVERTISED_10000baseR_FEC;
1041 : :
1042 : 0 : return mode;
1043 : : }
1044 : :
1045 : 0 : static enum axgbe_mode axgbe_phy_an73_outcome(struct axgbe_port *pdata)
1046 : : {
1047 : : enum axgbe_mode mode;
1048 : : unsigned int ad_reg, lp_reg;
1049 : :
1050 : 0 : pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
1051 : 0 : pdata->phy.lp_advertising |= ADVERTISED_Backplane;
1052 : :
1053 : : /* Compare Advertisement and Link Partner register 1 */
1054 : 0 : ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
1055 : 0 : lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);
1056 [ # # ]: 0 : if (lp_reg & 0x400)
1057 : 0 : pdata->phy.lp_advertising |= ADVERTISED_Pause;
1058 [ # # ]: 0 : if (lp_reg & 0x800)
1059 : 0 : pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause;
1060 : :
1061 [ # # ]: 0 : if (pdata->phy.pause_autoneg) {
1062 : : /* Set flow control based on auto-negotiation result */
1063 : 0 : pdata->phy.tx_pause = 0;
1064 : 0 : pdata->phy.rx_pause = 0;
1065 : :
1066 [ # # ]: 0 : if (ad_reg & lp_reg & 0x400) {
1067 : 0 : pdata->phy.tx_pause = 1;
1068 : 0 : pdata->phy.rx_pause = 1;
1069 [ # # ]: 0 : } else if (ad_reg & lp_reg & 0x800) {
1070 [ # # ]: 0 : if (ad_reg & 0x400)
1071 : 0 : pdata->phy.rx_pause = 1;
1072 [ # # ]: 0 : else if (lp_reg & 0x400)
1073 : 0 : pdata->phy.tx_pause = 1;
1074 : : }
1075 : : }
1076 : :
1077 : : /* Compare Advertisement and Link Partner register 2 */
1078 : 0 : ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
1079 : 0 : lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
1080 [ # # ]: 0 : if (lp_reg & 0x80)
1081 : 0 : pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full;
1082 [ # # ]: 0 : if (lp_reg & 0x20)
1083 : 0 : pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full;
1084 : :
1085 : 0 : ad_reg &= lp_reg;
1086 [ # # ]: 0 : if (ad_reg & 0x80)
1087 : : mode = AXGBE_MODE_KR;
1088 [ # # ]: 0 : else if (ad_reg & 0x20)
1089 : : mode = AXGBE_MODE_KX_1000;
1090 : : else
1091 : : mode = AXGBE_MODE_UNKNOWN;
1092 : :
1093 : : /* Compare Advertisement and Link Partner register 3 */
1094 : 0 : ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
1095 : 0 : lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
1096 [ # # ]: 0 : if (lp_reg & 0xc000)
1097 : 0 : pdata->phy.lp_advertising |= ADVERTISED_10000baseR_FEC;
1098 : :
1099 : 0 : return mode;
1100 : : }
1101 : :
1102 : 0 : static enum axgbe_mode axgbe_phy_an37_sgmii_outcome(struct axgbe_port *pdata)
1103 : : {
1104 : : enum axgbe_mode mode;
1105 : :
1106 : 0 : pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
1107 : 0 : pdata->phy.lp_advertising |= ADVERTISED_1000baseT_Full;
1108 : :
1109 [ # # ]: 0 : if (pdata->phy.pause_autoneg)
1110 : : axgbe_phy_phydev_flowctrl(pdata);
1111 : :
1112 [ # # # # ]: 0 : switch (pdata->an_status & AXGBE_SGMII_AN_LINK_SPEED) {
1113 : 0 : case AXGBE_SGMII_AN_LINK_SPEED_10:
1114 [ # # ]: 0 : if (pdata->an_status & AXGBE_SGMII_AN_LINK_DUPLEX) {
1115 : 0 : pdata->phy.lp_advertising |= ADVERTISED_10baseT_Full;
1116 : : mode = AXGBE_MODE_SGMII_10;
1117 : : } else {
1118 : : mode = AXGBE_MODE_UNKNOWN;
1119 : : }
1120 : : break;
1121 : 0 : case AXGBE_SGMII_AN_LINK_SPEED_100:
1122 [ # # ]: 0 : if (pdata->an_status & AXGBE_SGMII_AN_LINK_DUPLEX) {
1123 : 0 : pdata->phy.lp_advertising |= ADVERTISED_100baseT_Full;
1124 : : mode = AXGBE_MODE_SGMII_100;
1125 : : } else {
1126 : : mode = AXGBE_MODE_UNKNOWN;
1127 : : }
1128 : : break;
1129 : 0 : case AXGBE_SGMII_AN_LINK_SPEED_1000:
1130 [ # # ]: 0 : if (pdata->an_status & AXGBE_SGMII_AN_LINK_DUPLEX) {
1131 : : pdata->phy.lp_advertising |= ADVERTISED_1000baseT_Full;
1132 : : mode = AXGBE_MODE_SGMII_1000;
1133 : : } else {
1134 : : /* Half-duplex not supported */
1135 : : mode = AXGBE_MODE_UNKNOWN;
1136 : : }
1137 : : break;
1138 : : default:
1139 : : mode = AXGBE_MODE_UNKNOWN;
1140 : : break;
1141 : : }
1142 : 0 : return mode;
1143 : : }
1144 : :
1145 : 0 : static enum axgbe_mode axgbe_phy_an_outcome(struct axgbe_port *pdata)
1146 : : {
1147 [ # # # # ]: 0 : switch (pdata->an_mode) {
1148 : 0 : case AXGBE_AN_MODE_CL73:
1149 : 0 : return axgbe_phy_an73_outcome(pdata);
1150 : 0 : case AXGBE_AN_MODE_CL73_REDRV:
1151 : 0 : return axgbe_phy_an73_redrv_outcome(pdata);
1152 : 0 : case AXGBE_AN_MODE_CL37:
1153 : : case AXGBE_AN_MODE_CL37_SGMII:
1154 : 0 : return axgbe_phy_an37_sgmii_outcome(pdata);
1155 : : default:
1156 : : return AXGBE_MODE_UNKNOWN;
1157 : : }
1158 : : }
1159 : :
1160 : 0 : static unsigned int axgbe_phy_an_advertising(struct axgbe_port *pdata)
1161 : : {
1162 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1163 : : unsigned int advertising;
1164 : :
1165 : : /* Without a re-driver, just return current advertising */
1166 [ # # ]: 0 : if (!phy_data->redrv)
1167 : 0 : return pdata->phy.advertising;
1168 : :
1169 : : /* With the KR re-driver we need to advertise a single speed */
1170 : 0 : advertising = pdata->phy.advertising;
1171 : : advertising &= ~ADVERTISED_1000baseKX_Full;
1172 : 0 : advertising &= ~ADVERTISED_10000baseKR_Full;
1173 : :
1174 [ # # # # : 0 : switch (phy_data->port_mode) {
# # # ]
1175 : 0 : case AXGBE_PORT_MODE_BACKPLANE:
1176 : : case AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
1177 : 0 : advertising |= ADVERTISED_10000baseKR_Full;
1178 : 0 : break;
1179 : 0 : case AXGBE_PORT_MODE_BACKPLANE_2500:
1180 : 0 : advertising |= ADVERTISED_1000baseKX_Full;
1181 : 0 : break;
1182 : 0 : case AXGBE_PORT_MODE_1000BASE_T:
1183 : : case AXGBE_PORT_MODE_1000BASE_X:
1184 : : case AXGBE_PORT_MODE_NBASE_T:
1185 : 0 : advertising |= ADVERTISED_1000baseKX_Full;
1186 : 0 : break;
1187 : 0 : case AXGBE_PORT_MODE_10GBASE_T:
1188 : 0 : PMD_DRV_LOG_LINE(ERR, "10GBASE_T mode is not supported");
1189 : 0 : break;
1190 : 0 : case AXGBE_PORT_MODE_10GBASE_R:
1191 : 0 : advertising |= ADVERTISED_10000baseKR_Full;
1192 : 0 : break;
1193 : 0 : case AXGBE_PORT_MODE_SFP:
1194 [ # # ]: 0 : switch (phy_data->sfp_base) {
1195 : 0 : case AXGBE_SFP_BASE_1000_T:
1196 : : case AXGBE_SFP_BASE_1000_SX:
1197 : : case AXGBE_SFP_BASE_1000_LX:
1198 : : case AXGBE_SFP_BASE_1000_CX:
1199 : 0 : advertising |= ADVERTISED_1000baseKX_Full;
1200 : 0 : break;
1201 : 0 : default:
1202 : 0 : advertising |= ADVERTISED_10000baseKR_Full;
1203 : 0 : break;
1204 : : }
1205 : : break;
1206 : 0 : default:
1207 : 0 : advertising |= ADVERTISED_10000baseKR_Full;
1208 : 0 : break;
1209 : : }
1210 : :
1211 : : return advertising;
1212 : : }
1213 : :
1214 : 0 : static int axgbe_phy_an_config(struct axgbe_port *pdata __rte_unused)
1215 : : {
1216 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1217 : : int ret;
1218 : :
1219 : : /* Auto-negotiation config is implemented only for 1000BASE-T */
1220 [ # # ]: 0 : if (phy_data->port_mode != AXGBE_PORT_MODE_1000BASE_T)
1221 : : return 0;
1222 : :
1223 : : /* Supports only Marvell M88E1512 PHY for now*/
1224 [ # # ]: 0 : if (phy_data->phy_id == M88E1512_E_PHY_ID) {
1225 : 0 : ret = axgbe_phy_config_advert(pdata);
1226 [ # # ]: 0 : if (ret) {
1227 : 0 : PMD_DRV_LOG_LINE(ERR, "PHY ADVERTISE config failed");
1228 : 0 : return ret;
1229 : : }
1230 : :
1231 : 0 : ret = axgbe_phy_set_speed(pdata);
1232 [ # # ]: 0 : if (ret) {
1233 : 0 : PMD_DRV_LOG_LINE(ERR, "PHY set speed failed");
1234 : 0 : return ret;
1235 : : }
1236 : :
1237 : 0 : ret = axgbe_phy_config_aneg(pdata);
1238 [ # # ]: 0 : if (ret) {
1239 : 0 : PMD_DRV_LOG_LINE(ERR, "PHY AN config failed");
1240 : 0 : return ret;
1241 : : }
1242 : 0 : PMD_DRV_LOG_LINE(DEBUG, "M88E1512 PHY AN config done");
1243 : : }
1244 : : return 0;
1245 : : }
1246 : :
1247 : : static enum axgbe_an_mode axgbe_phy_an_sfp_mode(struct axgbe_phy_data *phy_data)
1248 : : {
1249 [ # # # ]: 0 : switch (phy_data->sfp_base) {
1250 : : case AXGBE_SFP_BASE_1000_T:
1251 : : return AXGBE_AN_MODE_CL37_SGMII;
1252 : 0 : case AXGBE_SFP_BASE_1000_SX:
1253 : : case AXGBE_SFP_BASE_1000_LX:
1254 : : case AXGBE_SFP_BASE_1000_CX:
1255 : 0 : return AXGBE_AN_MODE_CL37;
1256 : 0 : default:
1257 : 0 : return AXGBE_AN_MODE_NONE;
1258 : : }
1259 : : }
1260 : :
1261 : 0 : static enum axgbe_an_mode axgbe_phy_an_mode(struct axgbe_port *pdata)
1262 : : {
1263 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1264 : :
1265 : : /* A KR re-driver will always require CL73 AN */
1266 [ # # ]: 0 : if (phy_data->redrv)
1267 : : return AXGBE_AN_MODE_CL73_REDRV;
1268 : :
1269 [ # # # # : 0 : switch (phy_data->port_mode) {
# # # # ]
1270 : : case AXGBE_PORT_MODE_BACKPLANE:
1271 : : return AXGBE_AN_MODE_CL73;
1272 : 0 : case AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
1273 : : case AXGBE_PORT_MODE_BACKPLANE_2500:
1274 : 0 : return AXGBE_AN_MODE_NONE;
1275 : 0 : case AXGBE_PORT_MODE_1000BASE_T:
1276 : 0 : return AXGBE_AN_MODE_CL37_SGMII;
1277 : 0 : case AXGBE_PORT_MODE_1000BASE_X:
1278 : 0 : return AXGBE_AN_MODE_CL37;
1279 : 0 : case AXGBE_PORT_MODE_NBASE_T:
1280 : 0 : return AXGBE_AN_MODE_CL37_SGMII;
1281 : : case AXGBE_PORT_MODE_10GBASE_T:
1282 : : return AXGBE_AN_MODE_CL73;
1283 : 0 : case AXGBE_PORT_MODE_10GBASE_R:
1284 : 0 : return AXGBE_AN_MODE_NONE;
1285 : : case AXGBE_PORT_MODE_SFP:
1286 : : return axgbe_phy_an_sfp_mode(phy_data);
1287 : 0 : default:
1288 : 0 : return AXGBE_AN_MODE_NONE;
1289 : : }
1290 : : }
1291 : :
1292 : : static int axgbe_phy_set_redrv_mode_mdio(struct axgbe_port *pdata,
1293 : : enum axgbe_phy_redrv_mode mode)
1294 : : {
1295 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1296 : : u16 redrv_reg, redrv_val;
1297 : :
1298 : 0 : redrv_reg = AXGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000);
1299 : : redrv_val = (u16)mode;
1300 : :
1301 : 0 : return pdata->hw_if.write_ext_mii_regs_c22(pdata,
1302 : 0 : phy_data->redrv_addr, redrv_reg, redrv_val);
1303 : : }
1304 : :
1305 : : static int axgbe_phy_set_redrv_mode_i2c(struct axgbe_port *pdata,
1306 : : enum axgbe_phy_redrv_mode mode)
1307 : : {
1308 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1309 : : unsigned int redrv_reg;
1310 : : int ret;
1311 : :
1312 : : /* Calculate the register to write */
1313 : 0 : redrv_reg = AXGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000);
1314 : :
1315 : 0 : ret = axgbe_phy_redrv_write(pdata, redrv_reg, mode);
1316 : :
1317 : 0 : return ret;
1318 : : }
1319 : :
1320 : 0 : static void axgbe_phy_set_redrv_mode(struct axgbe_port *pdata)
1321 : : {
1322 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1323 : : enum axgbe_phy_redrv_mode mode;
1324 : : int ret;
1325 : :
1326 [ # # ]: 0 : if (!phy_data->redrv)
1327 : : return;
1328 : :
1329 : : mode = AXGBE_PHY_REDRV_MODE_CX;
1330 [ # # ]: 0 : if ((phy_data->port_mode == AXGBE_PORT_MODE_SFP) &&
1331 [ # # # # ]: 0 : (phy_data->sfp_base != AXGBE_SFP_BASE_1000_CX) &&
1332 : : (phy_data->sfp_base != AXGBE_SFP_BASE_10000_CR))
1333 : : mode = AXGBE_PHY_REDRV_MODE_SR;
1334 : :
1335 : 0 : ret = axgbe_phy_get_comm_ownership(pdata);
1336 [ # # ]: 0 : if (ret)
1337 : : return;
1338 : :
1339 [ # # ]: 0 : if (phy_data->redrv_if)
1340 : : axgbe_phy_set_redrv_mode_i2c(pdata, mode);
1341 : : else
1342 : : axgbe_phy_set_redrv_mode_mdio(pdata, mode);
1343 : :
1344 : : axgbe_phy_put_comm_ownership(pdata);
1345 : : }
1346 : :
1347 : : #define MAX_RX_ADAPT_RETRIES 1
1348 : : #define XGBE_PMA_RX_VAL_SIG_MASK (XGBE_PMA_RX_SIG_DET_0_MASK | \
1349 : : XGBE_PMA_RX_VALID_0_MASK)
1350 : :
1351 : 0 : static void axgbe_set_rx_adap_mode(struct axgbe_port *pdata,
1352 : : enum axgbe_mode mode)
1353 : : {
1354 [ # # ]: 0 : if (pdata->rx_adapt_retries++ >= MAX_RX_ADAPT_RETRIES) {
1355 : 0 : pdata->rx_adapt_retries = 0;
1356 : 0 : return;
1357 : : }
1358 : :
1359 [ # # ]: 0 : axgbe_phy_perform_ratechange(pdata,
1360 : : mode == AXGBE_MODE_KR ?
1361 : : AXGBE_MB_CMD_SET_10G_KR :
1362 : : AXGBE_MB_CMD_SET_10G_SFI,
1363 : : AXGBE_MB_SUBCMD_RX_ADAP);
1364 : : }
1365 : :
1366 : 0 : static void axgbe_rx_adaptation(struct axgbe_port *pdata)
1367 : : {
1368 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1369 : : unsigned int reg;
1370 : :
1371 : : /* step 2: force PCS to send RX_ADAPT Req to PHY */
1372 : 0 : XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4,
1373 : : XGBE_PMA_RX_AD_REQ_MASK, XGBE_PMA_RX_AD_REQ_ENABLE);
1374 : :
1375 : : /* Step 3: Wait for RX_ADAPT ACK from the PHY */
1376 : : rte_delay_ms(200);
1377 : :
1378 : : /* Software polls for coefficient update command (given by local PHY) */
1379 : 0 : reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_PHY_RX_EQ_CEU);
1380 : :
1381 : : /* Clear the RX_AD_REQ bit */
1382 : 0 : XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4,
1383 : : XGBE_PMA_RX_AD_REQ_MASK, XGBE_PMA_RX_AD_REQ_DISABLE);
1384 : :
1385 : : /* Check if coefficient update command is set */
1386 [ # # ]: 0 : if ((reg & XGBE_PMA_CFF_UPDT_MASK) != XGBE_PMA_CFF_UPDT_MASK)
1387 : 0 : goto set_mode;
1388 : :
1389 : : /* Step 4: Check for Block lock */
1390 : :
1391 : : /* Link status is latched low, so read once to clear
1392 : : * and then read again to get current state
1393 : : */
1394 : 0 : reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
1395 : 0 : reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
1396 [ # # ]: 0 : if (reg & MDIO_STAT1_LSTATUS) {
1397 : : /* If the block lock is found, update the helpers
1398 : : * and declare the link up
1399 : : */
1400 : 0 : PMD_DRV_LOG_LINE(NOTICE, "Rx adaptation - Block_lock done");
1401 : 0 : pdata->rx_adapt_done = true;
1402 : 0 : pdata->mode_set = false;
1403 : 0 : return;
1404 : : }
1405 : :
1406 : 0 : set_mode:
1407 : 0 : axgbe_set_rx_adap_mode(pdata, phy_data->cur_mode);
1408 : : }
1409 : :
1410 : 0 : static void axgbe_phy_rx_adaptation(struct axgbe_port *pdata)
1411 : : {
1412 : : unsigned int reg;
1413 : :
1414 : 0 : rx_adapt_reinit:
1415 : 0 : reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_LSTS,
1416 : : XGBE_PMA_RX_VAL_SIG_MASK);
1417 : :
1418 : : /* step 1: Check for RX_VALID && LF_SIGDET */
1419 [ # # ]: 0 : if ((reg & XGBE_PMA_RX_VAL_SIG_MASK) != XGBE_PMA_RX_VAL_SIG_MASK) {
1420 : 0 : PMD_DRV_LOG_LINE(NOTICE, "RX_VALID or LF_SIGDET is unset, issue rrc");
1421 : 0 : axgbe_phy_rrc(pdata);
1422 [ # # ]: 0 : if (pdata->rx_adapt_retries++ >= MAX_RX_ADAPT_RETRIES) {
1423 : 0 : pdata->rx_adapt_retries = 0;
1424 : 0 : return;
1425 : : }
1426 : 0 : goto rx_adapt_reinit;
1427 : : }
1428 : :
1429 : : /* perform rx adaptation */
1430 : 0 : axgbe_rx_adaptation(pdata);
1431 : : }
1432 : :
1433 : 0 : static void axgbe_phy_rx_reset(struct axgbe_port *pdata)
1434 : : {
1435 : : int reg;
1436 : :
1437 : 0 : reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PCS, MDIO_PCS_DIGITAL_STAT,
1438 : : XGBE_PCS_PSEQ_STATE_MASK);
1439 [ # # ]: 0 : if (reg == XGBE_PCS_PSEQ_STATE_POWER_GOOD) {
1440 : : /* Mailbox command timed out, reset of RX block is required.
1441 : : * This can be done by asseting the reset bit and wait for
1442 : : * its compeletion.
1443 : : */
1444 : 0 : XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1,
1445 : : XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_ON);
1446 : 0 : rte_delay_us(20);
1447 : 0 : XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1,
1448 : : XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_OFF);
1449 : 0 : rte_delay_us(45);
1450 : 0 : PMD_DRV_LOG_LINE(ERR, "firmware mailbox reset performed");
1451 : : }
1452 : 0 : }
1453 : :
1454 : :
1455 : 0 : static void axgbe_phy_pll_ctrl(struct axgbe_port *pdata, bool enable)
1456 : : {
1457 : : /* PLL_CTRL feature needs to be enabled for fixed PHY modes (Non-Autoneg) only */
1458 [ # # ]: 0 : if (pdata->phy.autoneg != AUTONEG_DISABLE)
1459 : : return;
1460 : :
1461 [ # # ]: 0 : XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_MISC_CTRL0,
1462 : : XGBE_PMA_PLL_CTRL_MASK,
1463 : : enable ? XGBE_PMA_PLL_CTRL_SET
1464 : : : XGBE_PMA_PLL_CTRL_CLEAR);
1465 : :
1466 : : /* Wait for command to complete */
1467 : 0 : rte_delay_us(150);
1468 : : }
1469 : :
1470 : 0 : static void axgbe_phy_perform_ratechange(struct axgbe_port *pdata,
1471 : : enum axgbe_mb_cmd cmd, enum axgbe_mb_subcmd sub_cmd)
1472 : : {
1473 : : unsigned int s0 = 0;
1474 : : unsigned int wait;
1475 : : /* Clear the PLL so that it helps in power down sequence */
1476 : 0 : axgbe_phy_pll_ctrl(pdata, false);
1477 : :
1478 : : /* Log if a previous command did not complete */
1479 [ # # ]: 0 : if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) {
1480 : 0 : PMD_DRV_LOG_LINE(NOTICE, "firmware mailbox not ready for command");
1481 : 0 : axgbe_phy_rx_reset(pdata);
1482 : : }
1483 : :
1484 : : /* Construct the command */
1485 : 0 : XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, cmd);
1486 : 0 : XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, sub_cmd);
1487 : :
1488 : : /* Issue the command */
1489 : 0 : XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1490 : 0 : XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1491 : 0 : XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1492 : :
1493 : : /* Wait for command to complete */
1494 : : wait = AXGBE_RATECHANGE_COUNT;
1495 [ # # ]: 0 : while (wait--) {
1496 [ # # ]: 0 : if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
1497 : 0 : goto do_rx_adaptation;
1498 : 0 : rte_delay_us(1500);
1499 : : }
1500 : 0 : PMD_DRV_LOG_LINE(NOTICE, "firmware mailbox command did not complete");
1501 : : /* Reset on error */
1502 : 0 : axgbe_phy_rx_reset(pdata);
1503 : 0 : goto reenable_pll;
1504 : :
1505 : :
1506 : : do_rx_adaptation:
1507 [ # # # # ]: 0 : if (pdata->en_rx_adap && sub_cmd == AXGBE_MB_SUBCMD_RX_ADAP &&
1508 [ # # ]: 0 : (cmd == AXGBE_MB_CMD_SET_10G_KR || cmd == AXGBE_MB_CMD_SET_10G_SFI)) {
1509 : 0 : PMD_DRV_LOG_LINE(NOTICE, "Enabling RX adaptation");
1510 : 0 : pdata->mode_set = true;
1511 : 0 : axgbe_phy_rx_adaptation(pdata);
1512 : : /* return from here to avoid enabling PLL ctrl
1513 : : * during adaptation phase
1514 : : */
1515 : 0 : return;
1516 : : }
1517 : :
1518 : :
1519 : 0 : reenable_pll:
1520 : : /* Enable PLL re-initialization, not needed for PHY Power Off and RRC cmds */
1521 : 0 : if (cmd != AXGBE_MB_CMD_POWER_OFF &&
1522 [ # # ]: 0 : cmd != AXGBE_MB_CMD_RRC)
1523 : 0 : axgbe_phy_pll_ctrl(pdata, true);
1524 : : }
1525 : :
1526 : 0 : static void axgbe_phy_rrc(struct axgbe_port *pdata)
1527 : : {
1528 : :
1529 : :
1530 : : /* Receiver Reset Cycle */
1531 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_RRC, AXGBE_MB_SUBCMD_NONE);
1532 : :
1533 : 0 : PMD_DRV_LOG_LINE(DEBUG, "receiver reset complete");
1534 : 0 : }
1535 : :
1536 : 0 : static void axgbe_phy_power_off(struct axgbe_port *pdata)
1537 : : {
1538 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1539 : :
1540 : : /* Power off */
1541 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_POWER_OFF, AXGBE_MB_SUBCMD_NONE);
1542 : :
1543 : 0 : phy_data->cur_mode = AXGBE_MODE_UNKNOWN;
1544 : :
1545 : 0 : PMD_DRV_LOG_LINE(DEBUG, "phy powered off");
1546 : 0 : }
1547 : :
1548 : : static bool enable_rx_adap(struct axgbe_port *pdata, enum axgbe_mode mode)
1549 : : {
1550 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1551 : : unsigned int ver;
1552 : :
1553 : : /* Rx-Adaptation is not supported on older platforms(< 0x30H) */
1554 : 0 : ver = AXGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER);
1555 [ # # # # ]: 0 : if (ver < 0x30)
1556 : : return false;
1557 : :
1558 : : /* Re-driver models 4223 && 4227 do not support Rx-Adaptation */
1559 [ # # # # ]: 0 : if (phy_data->redrv &&
1560 [ # # # # ]: 0 : (phy_data->redrv_model == AXGBE_PHY_REDRV_MODEL_4223 ||
1561 : : phy_data->redrv_model == AXGBE_PHY_REDRV_MODEL_4227))
1562 : : return false;
1563 : :
1564 : : /* 10G KR mode with AN does not support Rx-Adaptation */
1565 : 0 : if (mode == AXGBE_MODE_KR &&
1566 [ # # ]: 0 : phy_data->port_mode != AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG)
1567 : : return false;
1568 : :
1569 : 0 : pdata->en_rx_adap = 1;
1570 : : return true;
1571 : : }
1572 : :
1573 : 0 : static void axgbe_phy_sfi_mode(struct axgbe_port *pdata)
1574 : : {
1575 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1576 : :
1577 : 0 : axgbe_phy_set_redrv_mode(pdata);
1578 : :
1579 : : /* 10G/SFI */
1580 [ # # ]: 0 : if (phy_data->sfp_cable != AXGBE_SFP_CABLE_PASSIVE) {
1581 : 0 : pdata->en_rx_adap = 0;
1582 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
1583 : : AXGBE_MB_SUBCMD_ACTIVE);
1584 : : } else if ((phy_data->sfp_cable == AXGBE_SFP_CABLE_PASSIVE) &&
1585 : : (enable_rx_adap(pdata, AXGBE_MODE_SFI))) {
1586 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
1587 : : AXGBE_MB_SUBCMD_RX_ADAP);
1588 : : } else {
1589 [ # # ]: 0 : if (phy_data->sfp_cable_len <= 1)
1590 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
1591 : : AXGBE_MB_SUBCMD_PASSIVE_1M);
1592 [ # # ]: 0 : else if (phy_data->sfp_cable_len <= 3)
1593 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
1594 : : AXGBE_MB_SUBCMD_PASSIVE_3M);
1595 : : else
1596 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
1597 : : AXGBE_MB_SUBCMD_PASSIVE_OTHER);
1598 : : }
1599 : :
1600 : 0 : phy_data->cur_mode = AXGBE_MODE_SFI;
1601 : :
1602 : 0 : PMD_DRV_LOG_LINE(DEBUG, "10GbE SFI mode set");
1603 : 0 : }
1604 : :
1605 : 0 : static void axgbe_phy_kr_mode(struct axgbe_port *pdata)
1606 : : {
1607 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1608 : :
1609 : 0 : axgbe_phy_set_redrv_mode(pdata);
1610 : :
1611 : : /* 10G/KR */
1612 : : if (enable_rx_adap(pdata, AXGBE_MODE_KR))
1613 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_KR,
1614 : : AXGBE_MB_SUBCMD_RX_ADAP);
1615 : : else
1616 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_KR,
1617 : : AXGBE_MB_SUBCMD_NONE);
1618 : 0 : phy_data->cur_mode = AXGBE_MODE_KR;
1619 : :
1620 : 0 : PMD_DRV_LOG_LINE(DEBUG, "10GbE KR mode set");
1621 : 0 : }
1622 : :
1623 : 0 : static void axgbe_phy_kx_2500_mode(struct axgbe_port *pdata)
1624 : : {
1625 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1626 : :
1627 : 0 : axgbe_phy_set_redrv_mode(pdata);
1628 : :
1629 : : /* 2.5G/KX */
1630 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_2_5G, AXGBE_MB_SUBCMD_NONE);
1631 : 0 : phy_data->cur_mode = AXGBE_MODE_KX_2500;
1632 : 0 : }
1633 : :
1634 : 0 : static void axgbe_phy_sgmii_1000_mode(struct axgbe_port *pdata)
1635 : : {
1636 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1637 : :
1638 : 0 : axgbe_phy_set_redrv_mode(pdata);
1639 : :
1640 : : /* 1G/SGMII */
1641 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_1G, AXGBE_MB_SUBCMD_1G_SGMII);
1642 : :
1643 : 0 : phy_data->cur_mode = AXGBE_MODE_SGMII_1000;
1644 : 0 : }
1645 : :
1646 : 0 : static void axgbe_phy_sgmii_100_mode(struct axgbe_port *pdata)
1647 : : {
1648 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1649 : :
1650 : 0 : axgbe_phy_set_redrv_mode(pdata);
1651 : :
1652 : : /* 100M/SGMII */
1653 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_1G, AXGBE_MB_SUBCMD_100MBITS);
1654 : :
1655 : 0 : phy_data->cur_mode = AXGBE_MODE_SGMII_100;
1656 : 0 : }
1657 : :
1658 : 0 : static void axgbe_phy_sgmii_10_mode(struct axgbe_port *pdata)
1659 : : {
1660 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1661 : :
1662 : 0 : axgbe_phy_set_redrv_mode(pdata);
1663 : :
1664 : : /* 10M/SGMII */
1665 : 0 : axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_1G, AXGBE_MB_SUBCMD_10MBITS);
1666 : :
1667 : 0 : phy_data->cur_mode = AXGBE_MODE_SGMII_10;
1668 : 0 : }
1669 : :
1670 : 0 : static enum axgbe_mode axgbe_phy_cur_mode(struct axgbe_port *pdata)
1671 : : {
1672 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1673 : :
1674 : 0 : return phy_data->cur_mode;
1675 : : }
1676 : :
1677 : : static enum axgbe_mode axgbe_phy_switch_baset_mode(struct axgbe_port *pdata)
1678 : : {
1679 : : struct axgbe_phy_data *phy_data = pdata->phy_data;
1680 : :
1681 : : /* No switching if not 10GBase-T */
1682 [ # # ]: 0 : if (phy_data->port_mode != AXGBE_PORT_MODE_10GBASE_T)
1683 : 0 : return axgbe_phy_cur_mode(pdata);
1684 : :
1685 [ # # # ]: 0 : switch (axgbe_phy_cur_mode(pdata)) {
1686 : : case AXGBE_MODE_SGMII_10:
1687 : : case AXGBE_MODE_SGMII_100:
1688 : : case AXGBE_MODE_SGMII_1000:
1689 : : return AXGBE_MODE_KR;
1690 : 0 : case AXGBE_MODE_KX_2500:
1691 : 0 : return AXGBE_MODE_SGMII_1000;
1692 : 0 : case AXGBE_MODE_KR:
1693 : : default:
1694 : 0 : return AXGBE_MODE_KX_2500;
1695 : : }
1696 : : }
1697 : :
1698 : : static enum axgbe_mode axgbe_phy_switch_bp_2500_mode(struct axgbe_port *pdata
1699 : : __rte_unused)
1700 : : {
1701 : : return AXGBE_MODE_KX_2500;
1702 : : }
1703 : :
1704 : : static enum axgbe_mode axgbe_phy_switch_bp_mode(struct axgbe_port *pdata)
1705 : : {
1706 : : /* If we are in KR switch to KX, and vice-versa */
1707 [ # # ]: 0 : switch (axgbe_phy_cur_mode(pdata)) {
1708 : : case AXGBE_MODE_KX_1000:
1709 : : return AXGBE_MODE_KR;
1710 : 0 : case AXGBE_MODE_KR:
1711 : : default:
1712 : 0 : return AXGBE_MODE_KX_1000;
1713 : : }
1714 : : }
1715 : :
1716 : 0 : static enum axgbe_mode axgbe_phy_switch_mode(struct axgbe_port *pdata)
1717 : : {
1718 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1719 : :
1720 [ # # # # : 0 : switch (phy_data->port_mode) {
# ]
1721 : : case AXGBE_PORT_MODE_BACKPLANE:
1722 : : case AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
1723 : : return axgbe_phy_switch_bp_mode(pdata);
1724 : : case AXGBE_PORT_MODE_BACKPLANE_2500:
1725 : : return axgbe_phy_switch_bp_2500_mode(pdata);
1726 : : case AXGBE_PORT_MODE_1000BASE_T:
1727 : : case AXGBE_PORT_MODE_NBASE_T:
1728 : : case AXGBE_PORT_MODE_10GBASE_T:
1729 : : return axgbe_phy_switch_baset_mode(pdata);
1730 : : case AXGBE_PORT_MODE_1000BASE_X:
1731 : : case AXGBE_PORT_MODE_10GBASE_R:
1732 : : case AXGBE_PORT_MODE_SFP:
1733 : : /* No switching, so just return current mode */
1734 : 0 : return axgbe_phy_cur_mode(pdata);
1735 : 0 : default:
1736 : 0 : return AXGBE_MODE_UNKNOWN;
1737 : : }
1738 : : }
1739 : :
1740 : : static enum axgbe_mode axgbe_phy_get_basex_mode(struct axgbe_phy_data *phy_data
1741 : : __rte_unused,
1742 : : int speed)
1743 : : {
1744 [ # # # ]: 0 : switch (speed) {
1745 : : case SPEED_1000:
1746 : : return AXGBE_MODE_X;
1747 : 0 : case SPEED_10000:
1748 : 0 : return AXGBE_MODE_KR;
1749 : 0 : default:
1750 : 0 : return AXGBE_MODE_UNKNOWN;
1751 : : }
1752 : : }
1753 : :
1754 : : static enum axgbe_mode axgbe_phy_get_baset_mode(struct axgbe_phy_data *phy_data
1755 : : __rte_unused,
1756 : : int speed)
1757 : : {
1758 [ # # # # : 0 : switch (speed) {
# ]
1759 : : case SPEED_10:
1760 : : return AXGBE_MODE_SGMII_10;
1761 : 0 : case SPEED_100:
1762 : 0 : return AXGBE_MODE_SGMII_100;
1763 : 0 : case SPEED_1000:
1764 : 0 : return AXGBE_MODE_SGMII_1000;
1765 : 0 : case SPEED_10000:
1766 : 0 : return AXGBE_MODE_KR;
1767 : 0 : default:
1768 : 0 : return AXGBE_MODE_UNKNOWN;
1769 : : }
1770 : : }
1771 : :
1772 : : static enum axgbe_mode axgbe_phy_get_sfp_mode(struct axgbe_phy_data *phy_data,
1773 : : int speed)
1774 : : {
1775 [ # # # # : 0 : switch (speed) {
# ]
1776 : : case SPEED_10:
1777 : : return AXGBE_MODE_SGMII_10;
1778 : 0 : case SPEED_100:
1779 : 0 : return AXGBE_MODE_SGMII_100;
1780 : 0 : case SPEED_1000:
1781 [ # # ]: 0 : if (phy_data->sfp_base == AXGBE_SFP_BASE_1000_T)
1782 : : return AXGBE_MODE_SGMII_1000;
1783 : : else
1784 : 0 : return AXGBE_MODE_X;
1785 : 0 : case SPEED_10000:
1786 : : case SPEED_UNKNOWN:
1787 : 0 : return AXGBE_MODE_SFI;
1788 : 0 : default:
1789 : 0 : return AXGBE_MODE_UNKNOWN;
1790 : : }
1791 : : }
1792 : :
1793 : : static enum axgbe_mode axgbe_phy_get_bp_2500_mode(int speed)
1794 : : {
1795 [ # # ]: 0 : switch (speed) {
1796 : : case SPEED_2500:
1797 : : return AXGBE_MODE_KX_2500;
1798 : 0 : default:
1799 : 0 : return AXGBE_MODE_UNKNOWN;
1800 : : }
1801 : : }
1802 : :
1803 : : static enum axgbe_mode axgbe_phy_get_bp_mode(int speed)
1804 : : {
1805 [ # # # ]: 0 : switch (speed) {
1806 : : case SPEED_1000:
1807 : : return AXGBE_MODE_KX_1000;
1808 : 0 : case SPEED_10000:
1809 : 0 : return AXGBE_MODE_KR;
1810 : 0 : default:
1811 : 0 : return AXGBE_MODE_UNKNOWN;
1812 : : }
1813 : : }
1814 : :
1815 : 0 : static enum axgbe_mode axgbe_phy_get_mode(struct axgbe_port *pdata,
1816 : : int speed)
1817 : : {
1818 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1819 : :
1820 [ # # # # : 0 : switch (phy_data->port_mode) {
# # ]
1821 : : case AXGBE_PORT_MODE_BACKPLANE:
1822 : : case AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
1823 : : return axgbe_phy_get_bp_mode(speed);
1824 : : case AXGBE_PORT_MODE_BACKPLANE_2500:
1825 : : return axgbe_phy_get_bp_2500_mode(speed);
1826 : : case AXGBE_PORT_MODE_1000BASE_T:
1827 : : case AXGBE_PORT_MODE_NBASE_T:
1828 : : case AXGBE_PORT_MODE_10GBASE_T:
1829 : : return axgbe_phy_get_baset_mode(phy_data, speed);
1830 : : case AXGBE_PORT_MODE_1000BASE_X:
1831 : : case AXGBE_PORT_MODE_10GBASE_R:
1832 : : return axgbe_phy_get_basex_mode(phy_data, speed);
1833 : : case AXGBE_PORT_MODE_SFP:
1834 : : return axgbe_phy_get_sfp_mode(phy_data, speed);
1835 : : default:
1836 : : return AXGBE_MODE_UNKNOWN;
1837 : : }
1838 : : }
1839 : :
1840 : 0 : static void axgbe_phy_set_mode(struct axgbe_port *pdata, enum axgbe_mode mode)
1841 : : {
1842 [ # # # # : 0 : switch (mode) {
# # # ]
1843 : 0 : case AXGBE_MODE_KR:
1844 : 0 : axgbe_phy_kr_mode(pdata);
1845 : 0 : break;
1846 : 0 : case AXGBE_MODE_SFI:
1847 : 0 : axgbe_phy_sfi_mode(pdata);
1848 : 0 : break;
1849 : 0 : case AXGBE_MODE_KX_2500:
1850 : 0 : axgbe_phy_kx_2500_mode(pdata);
1851 : 0 : break;
1852 : 0 : case AXGBE_MODE_SGMII_1000:
1853 : 0 : axgbe_phy_sgmii_1000_mode(pdata);
1854 : 0 : break;
1855 : 0 : case AXGBE_MODE_SGMII_100:
1856 : 0 : axgbe_phy_sgmii_100_mode(pdata);
1857 : 0 : break;
1858 : 0 : case AXGBE_MODE_SGMII_10:
1859 : 0 : axgbe_phy_sgmii_10_mode(pdata);
1860 : 0 : break;
1861 : : default:
1862 : : break;
1863 : : }
1864 : 0 : }
1865 : :
1866 : 0 : static bool axgbe_phy_check_mode(struct axgbe_port *pdata,
1867 : : enum axgbe_mode mode, u32 advert)
1868 : : {
1869 [ # # ]: 0 : if (pdata->phy.autoneg == AUTONEG_ENABLE) {
1870 [ # # ]: 0 : if (pdata->phy.advertising & advert)
1871 : 0 : return true;
1872 : : } else {
1873 : : enum axgbe_mode cur_mode;
1874 : :
1875 : 0 : cur_mode = axgbe_phy_get_mode(pdata, pdata->phy.speed);
1876 [ # # ]: 0 : if (cur_mode == mode)
1877 : 0 : return true;
1878 : : }
1879 : :
1880 : : return false;
1881 : : }
1882 : :
1883 : 0 : static bool axgbe_phy_use_basex_mode(struct axgbe_port *pdata,
1884 : : enum axgbe_mode mode)
1885 : : {
1886 [ # # # ]: 0 : switch (mode) {
1887 : 0 : case AXGBE_MODE_X:
1888 : 0 : return axgbe_phy_check_mode(pdata, mode,
1889 : : ADVERTISED_1000baseT_Full);
1890 : 0 : case AXGBE_MODE_KR:
1891 : 0 : return axgbe_phy_check_mode(pdata, mode,
1892 : : ADVERTISED_10000baseT_Full);
1893 : : default:
1894 : : return false;
1895 : : }
1896 : : }
1897 : :
1898 : 0 : static bool axgbe_phy_use_baset_mode(struct axgbe_port *pdata,
1899 : : enum axgbe_mode mode)
1900 : : {
1901 [ # # # # : 0 : switch (mode) {
# ]
1902 : 0 : case AXGBE_MODE_SGMII_10:
1903 : 0 : return axgbe_phy_check_mode(pdata, mode,
1904 : : ADVERTISED_10baseT_Full);
1905 : 0 : case AXGBE_MODE_SGMII_100:
1906 : 0 : return axgbe_phy_check_mode(pdata, mode,
1907 : : ADVERTISED_100baseT_Full);
1908 : 0 : case AXGBE_MODE_SGMII_1000:
1909 : 0 : return axgbe_phy_check_mode(pdata, mode,
1910 : : ADVERTISED_1000baseT_Full);
1911 : 0 : case AXGBE_MODE_KR:
1912 : 0 : return axgbe_phy_check_mode(pdata, mode,
1913 : : ADVERTISED_10000baseT_Full);
1914 : : default:
1915 : : return false;
1916 : : }
1917 : : }
1918 : :
1919 : 0 : static bool axgbe_phy_use_sfp_mode(struct axgbe_port *pdata,
1920 : : enum axgbe_mode mode)
1921 : : {
1922 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1923 : :
1924 [ # # # # : 0 : switch (mode) {
# # ]
1925 : 0 : case AXGBE_MODE_X:
1926 [ # # ]: 0 : if (phy_data->sfp_base == AXGBE_SFP_BASE_1000_T)
1927 : : return false;
1928 : 0 : return axgbe_phy_check_mode(pdata, mode,
1929 : : ADVERTISED_1000baseT_Full);
1930 : 0 : case AXGBE_MODE_SGMII_10:
1931 [ # # ]: 0 : if (phy_data->sfp_base != AXGBE_SFP_BASE_1000_T)
1932 : : return false;
1933 : 0 : return axgbe_phy_check_mode(pdata, mode,
1934 : : ADVERTISED_10baseT_Full);
1935 : 0 : case AXGBE_MODE_SGMII_100:
1936 [ # # ]: 0 : if (phy_data->sfp_base != AXGBE_SFP_BASE_1000_T)
1937 : : return false;
1938 : 0 : return axgbe_phy_check_mode(pdata, mode,
1939 : : ADVERTISED_100baseT_Full);
1940 : 0 : case AXGBE_MODE_SGMII_1000:
1941 [ # # ]: 0 : if (phy_data->sfp_base != AXGBE_SFP_BASE_1000_T)
1942 : : return false;
1943 : 0 : return axgbe_phy_check_mode(pdata, mode,
1944 : : ADVERTISED_1000baseT_Full);
1945 : 0 : case AXGBE_MODE_SFI:
1946 : 0 : return axgbe_phy_check_mode(pdata, mode,
1947 : : ADVERTISED_10000baseT_Full);
1948 : : default:
1949 : : return false;
1950 : : }
1951 : : }
1952 : :
1953 : : static bool axgbe_phy_use_bp_2500_mode(struct axgbe_port *pdata,
1954 : : enum axgbe_mode mode)
1955 : : {
1956 [ # # ]: 0 : switch (mode) {
1957 : 0 : case AXGBE_MODE_KX_2500:
1958 : 0 : return axgbe_phy_check_mode(pdata, mode,
1959 : : ADVERTISED_2500baseX_Full);
1960 : : default:
1961 : : return false;
1962 : : }
1963 : : }
1964 : :
1965 : 0 : static bool axgbe_phy_use_bp_mode(struct axgbe_port *pdata,
1966 : : enum axgbe_mode mode)
1967 : : {
1968 [ # # # ]: 0 : switch (mode) {
1969 : 0 : case AXGBE_MODE_KX_1000:
1970 : 0 : return axgbe_phy_check_mode(pdata, mode,
1971 : : ADVERTISED_1000baseKX_Full);
1972 : 0 : case AXGBE_MODE_KR:
1973 : 0 : return axgbe_phy_check_mode(pdata, mode,
1974 : : ADVERTISED_10000baseKR_Full);
1975 : : default:
1976 : : return false;
1977 : : }
1978 : : }
1979 : :
1980 : 0 : static bool axgbe_phy_use_mode(struct axgbe_port *pdata, enum axgbe_mode mode)
1981 : : {
1982 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
1983 : :
1984 [ # # # # : 0 : switch (phy_data->port_mode) {
# # ]
1985 : 0 : case AXGBE_PORT_MODE_BACKPLANE:
1986 : : case AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
1987 : 0 : return axgbe_phy_use_bp_mode(pdata, mode);
1988 : : case AXGBE_PORT_MODE_BACKPLANE_2500:
1989 : : return axgbe_phy_use_bp_2500_mode(pdata, mode);
1990 : 0 : case AXGBE_PORT_MODE_1000BASE_T:
1991 : : case AXGBE_PORT_MODE_NBASE_T:
1992 : : case AXGBE_PORT_MODE_10GBASE_T:
1993 : 0 : return axgbe_phy_use_baset_mode(pdata, mode);
1994 : 0 : case AXGBE_PORT_MODE_1000BASE_X:
1995 : : case AXGBE_PORT_MODE_10GBASE_R:
1996 : 0 : return axgbe_phy_use_basex_mode(pdata, mode);
1997 : 0 : case AXGBE_PORT_MODE_SFP:
1998 : 0 : return axgbe_phy_use_sfp_mode(pdata, mode);
1999 : : default:
2000 : : return false;
2001 : : }
2002 : : }
2003 : :
2004 : : /* return 0 means link down, 1 means link up */
2005 : 0 : static int axgbe_phy_link_status(struct axgbe_port *pdata, int *an_restart)
2006 : : {
2007 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2008 : : uint32_t reg;
2009 : 0 : bool ext_phy_link_up = false;
2010 : :
2011 : 0 : *an_restart = 0;
2012 : :
2013 [ # # ]: 0 : if (phy_data->port_mode == AXGBE_PORT_MODE_SFP) {
2014 : : /* Check SFP signals */
2015 : 0 : axgbe_phy_sfp_detect(pdata);
2016 : :
2017 [ # # ]: 0 : if (phy_data->sfp_changed) {
2018 : 0 : *an_restart = 1;
2019 : 0 : return 0;
2020 : : }
2021 : :
2022 [ # # # # ]: 0 : if (phy_data->sfp_mod_absent || phy_data->sfp_rx_los) {
2023 [ # # ]: 0 : if (pdata->en_rx_adap)
2024 : 0 : pdata->rx_adapt_done = false;
2025 : 0 : return 0;
2026 : : }
2027 : : }
2028 : :
2029 [ # # ]: 0 : if (phy_data->port_mode == AXGBE_PORT_MODE_1000BASE_T) {
2030 [ # # ]: 0 : if (phy_data->phy_id == M88E1512_E_PHY_ID) {
2031 [ # # ]: 0 : if (axgbe_get_ext_phy_link_status(pdata,
2032 : : &ext_phy_link_up)) {
2033 : 0 : PMD_DRV_LOG_LINE(ERR,
2034 : : "Get link status failed");
2035 : 0 : goto out;
2036 : : }
2037 : :
2038 [ # # ]: 0 : if (ext_phy_link_up) {
2039 : 0 : PMD_DRV_LOG_LINE(DEBUG,
2040 : : "M88E1512 PHY link is up");
2041 : : } else {
2042 : 0 : PMD_DRV_LOG_LINE(DEBUG,
2043 : : "M88E1512 PHY link is not up");
2044 : 0 : goto out;
2045 : : }
2046 : : }
2047 : : }
2048 : :
2049 : : /* Link status is latched low, so read once to clear
2050 : : * and then read again to get current state
2051 : : */
2052 : 0 : reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
2053 : 0 : reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
2054 : :
2055 [ # # ]: 0 : if (pdata->en_rx_adap) {
2056 : : /* if the link is available and adaptation is done,
2057 : : * declare link up
2058 : : */
2059 [ # # # # ]: 0 : if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done)
2060 : : return 1;
2061 : : /* If either link is not available or adaptation is not done,
2062 : : * retrigger the adaptation logic. (if the mode is not set,
2063 : : * then issue mailbox command first)
2064 : : */
2065 [ # # ]: 0 : if (pdata->mode_set) {
2066 : 0 : axgbe_phy_rx_adaptation(pdata);
2067 : : } else {
2068 : 0 : pdata->rx_adapt_done = false;
2069 : 0 : axgbe_phy_set_mode(pdata, phy_data->cur_mode);
2070 : : }
2071 : :
2072 : : /* check again for the link and adaptation status */
2073 : 0 : reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
2074 [ # # # # ]: 0 : if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done)
2075 : : return 1;
2076 [ # # ]: 0 : } else if (reg & MDIO_STAT1_LSTATUS)
2077 : : return 1;
2078 : :
2079 [ # # ]: 0 : if (pdata->phy.autoneg == AUTONEG_ENABLE &&
2080 [ # # ]: 0 : phy_data->port_mode == AXGBE_PORT_MODE_BACKPLANE) {
2081 [ # # ]: 0 : if (rte_bit_relaxed_get32(AXGBE_LINK_INIT, &pdata->dev_state)) {
2082 : 0 : *an_restart = 1;
2083 : : }
2084 : : }
2085 : :
2086 : : /* No link, attempt a receiver reset cycle */
2087 [ # # # # ]: 0 : if (pdata->vdata->enable_rrc && phy_data->rrc_count++) {
2088 : 0 : phy_data->rrc_count = 0;
2089 : 0 : axgbe_phy_rrc(pdata);
2090 : : }
2091 : :
2092 : 0 : out:
2093 : : return 0;
2094 : : }
2095 : :
2096 : 0 : static void axgbe_phy_sfp_gpio_setup(struct axgbe_port *pdata)
2097 : : {
2098 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2099 : :
2100 : 0 : phy_data->sfp_gpio_address = AXGBE_GPIO_ADDRESS_PCA9555 +
2101 : 0 : XP_GET_BITS(pdata->pp3, XP_PROP_3, GPIO_ADDR);
2102 : :
2103 : 0 : phy_data->sfp_gpio_mask = XP_GET_BITS(pdata->pp3, XP_PROP_3, GPIO_MASK);
2104 : :
2105 : 0 : phy_data->sfp_gpio_rx_los = XP_GET_BITS(pdata->pp3, XP_PROP_3,
2106 : : GPIO_RX_LOS);
2107 : 0 : phy_data->sfp_gpio_tx_fault = XP_GET_BITS(pdata->pp3, XP_PROP_3,
2108 : : GPIO_TX_FAULT);
2109 : 0 : phy_data->sfp_gpio_mod_absent = XP_GET_BITS(pdata->pp3, XP_PROP_3,
2110 : : GPIO_MOD_ABS);
2111 : 0 : phy_data->sfp_gpio_rate_select = XP_GET_BITS(pdata->pp3, XP_PROP_3,
2112 : : GPIO_RATE_SELECT);
2113 : 0 : }
2114 : :
2115 : : static void axgbe_phy_sfp_comm_setup(struct axgbe_port *pdata)
2116 : : {
2117 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2118 : : unsigned int mux_addr_hi, mux_addr_lo;
2119 : :
2120 : 0 : mux_addr_hi = XP_GET_BITS(pdata->pp4, XP_PROP_4, MUX_ADDR_HI);
2121 : 0 : mux_addr_lo = XP_GET_BITS(pdata->pp4, XP_PROP_4, MUX_ADDR_LO);
2122 : 0 : if (mux_addr_lo == AXGBE_SFP_DIRECT)
2123 : : return;
2124 : :
2125 : 0 : phy_data->sfp_comm = AXGBE_SFP_COMM_PCA9545;
2126 : 0 : phy_data->sfp_mux_address = (mux_addr_hi << 2) + mux_addr_lo;
2127 : 0 : phy_data->sfp_mux_channel = XP_GET_BITS(pdata->pp4, XP_PROP_4, MUX_CHAN);
2128 : : }
2129 : :
2130 [ # # ]: 0 : static void axgbe_phy_sfp_setup(struct axgbe_port *pdata)
2131 : : {
2132 : : axgbe_phy_sfp_comm_setup(pdata);
2133 : 0 : axgbe_phy_sfp_gpio_setup(pdata);
2134 : 0 : }
2135 : :
2136 : : static bool axgbe_phy_redrv_error(struct axgbe_phy_data *phy_data)
2137 : : {
2138 [ # # ]: 0 : if (!phy_data->redrv)
2139 : : return false;
2140 : :
2141 [ # # ]: 0 : if (phy_data->redrv_if >= AXGBE_PHY_REDRV_IF_MAX)
2142 : : return true;
2143 : :
2144 [ # # # ]: 0 : switch (phy_data->redrv_model) {
2145 : 0 : case AXGBE_PHY_REDRV_MODEL_4223:
2146 [ # # ]: 0 : if (phy_data->redrv_lane > 3)
2147 : : return true;
2148 : : break;
2149 : 0 : case AXGBE_PHY_REDRV_MODEL_4227:
2150 [ # # ]: 0 : if (phy_data->redrv_lane > 1)
2151 : : return true;
2152 : : break;
2153 : : default:
2154 : : return true;
2155 : : }
2156 : :
2157 : : return false;
2158 : : }
2159 : :
2160 : 0 : static int axgbe_phy_mdio_reset_setup(struct axgbe_port *pdata)
2161 : : {
2162 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2163 : :
2164 [ # # ]: 0 : if (phy_data->conn_type != AXGBE_CONN_TYPE_MDIO)
2165 : : return 0;
2166 : :
2167 : 0 : phy_data->mdio_reset = XP_GET_BITS(pdata->pp3, XP_PROP_3, MDIO_RESET);
2168 [ # # ]: 0 : switch (phy_data->mdio_reset) {
2169 : : case AXGBE_MDIO_RESET_NONE:
2170 : : case AXGBE_MDIO_RESET_I2C_GPIO:
2171 : : case AXGBE_MDIO_RESET_INT_GPIO:
2172 : : break;
2173 : 0 : default:
2174 : 0 : PMD_DRV_LOG_LINE(ERR, "unsupported MDIO reset (%#x)",
2175 : : phy_data->mdio_reset);
2176 : 0 : return -EINVAL;
2177 : : }
2178 [ # # ]: 0 : if (phy_data->mdio_reset == AXGBE_MDIO_RESET_I2C_GPIO) {
2179 : 0 : phy_data->mdio_reset_addr = AXGBE_GPIO_ADDRESS_PCA9555 +
2180 : 0 : XP_GET_BITS(pdata->pp3, XP_PROP_3,
2181 : : MDIO_RESET_I2C_ADDR);
2182 : 0 : phy_data->mdio_reset_gpio = XP_GET_BITS(pdata->pp3, XP_PROP_3,
2183 : : MDIO_RESET_I2C_GPIO);
2184 [ # # ]: 0 : } else if (phy_data->mdio_reset == AXGBE_MDIO_RESET_INT_GPIO) {
2185 : 0 : phy_data->mdio_reset_gpio = XP_GET_BITS(pdata->pp3, XP_PROP_3,
2186 : : MDIO_RESET_INT_GPIO);
2187 : : }
2188 : :
2189 : : return 0;
2190 : : }
2191 : :
2192 : 0 : static bool axgbe_phy_port_mode_mismatch(struct axgbe_port *pdata)
2193 : : {
2194 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2195 : : unsigned int ver;
2196 : :
2197 : : /* 10 Mbps speed is supported in ver 21H and ver >= 30H */
2198 : 0 : ver = AXGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER);
2199 [ # # # # ]: 0 : if ((ver < 0x30 && ver != 0x21) && phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)
2200 : : return true;
2201 : :
2202 [ # # # # : 0 : switch (phy_data->port_mode) {
# # # #
# ]
2203 : 0 : case AXGBE_PORT_MODE_BACKPLANE:
2204 : : case AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
2205 [ # # ]: 0 : if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
2206 : : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000))
2207 : 0 : return false;
2208 : : break;
2209 : 0 : case AXGBE_PORT_MODE_BACKPLANE_2500:
2210 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500)
2211 : 0 : return false;
2212 : : break;
2213 : 0 : case AXGBE_PORT_MODE_1000BASE_T:
2214 : 0 : if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) ||
2215 [ # # ]: 0 : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
2216 : : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000))
2217 : 0 : return false;
2218 : : break;
2219 : 0 : case AXGBE_PORT_MODE_1000BASE_X:
2220 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000)
2221 : 0 : return false;
2222 : : break;
2223 : 0 : case AXGBE_PORT_MODE_NBASE_T:
2224 : 0 : if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) ||
2225 : : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
2226 [ # # ]: 0 : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
2227 : : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500))
2228 : 0 : return false;
2229 : : break;
2230 : 0 : case AXGBE_PORT_MODE_10GBASE_T:
2231 : 0 : if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) ||
2232 : : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
2233 : : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
2234 [ # # ]: 0 : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500) ||
2235 : : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000))
2236 : 0 : return false;
2237 : : break;
2238 : 0 : case AXGBE_PORT_MODE_10GBASE_R:
2239 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000)
2240 : 0 : return false;
2241 : : break;
2242 : 0 : case AXGBE_PORT_MODE_SFP:
2243 : 0 : if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) ||
2244 : : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
2245 [ # # ]: 0 : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
2246 : : (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000))
2247 : 0 : return false;
2248 : : break;
2249 : : default:
2250 : : break;
2251 : : }
2252 : :
2253 : : return true;
2254 : : }
2255 : :
2256 : 0 : static bool axgbe_phy_conn_type_mismatch(struct axgbe_port *pdata)
2257 : : {
2258 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2259 : :
2260 [ # # # # ]: 0 : switch (phy_data->port_mode) {
2261 : 0 : case AXGBE_PORT_MODE_BACKPLANE:
2262 : : case AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
2263 : : case AXGBE_PORT_MODE_BACKPLANE_2500:
2264 [ # # ]: 0 : if (phy_data->conn_type == AXGBE_CONN_TYPE_BACKPLANE)
2265 : 0 : return false;
2266 : : break;
2267 : 0 : case AXGBE_PORT_MODE_1000BASE_T:
2268 : : case AXGBE_PORT_MODE_1000BASE_X:
2269 : : case AXGBE_PORT_MODE_NBASE_T:
2270 : : case AXGBE_PORT_MODE_10GBASE_T:
2271 : : case AXGBE_PORT_MODE_10GBASE_R:
2272 [ # # ]: 0 : if (phy_data->conn_type == AXGBE_CONN_TYPE_MDIO)
2273 : 0 : return false;
2274 : : break;
2275 : 0 : case AXGBE_PORT_MODE_SFP:
2276 [ # # ]: 0 : if (phy_data->conn_type == AXGBE_CONN_TYPE_SFP)
2277 : 0 : return false;
2278 : : break;
2279 : : default:
2280 : : break;
2281 : : }
2282 : :
2283 : : return true;
2284 : : }
2285 : :
2286 : : static bool axgbe_phy_port_enabled(struct axgbe_port *pdata)
2287 : : {
2288 : 0 : if (!XP_GET_BITS(pdata->pp0, XP_PROP_0, PORT_SPEEDS))
2289 : : return false;
2290 [ # # ]: 0 : if (!XP_GET_BITS(pdata->pp0, XP_PROP_0, CONN_TYPE))
2291 : : return false;
2292 : :
2293 : : return true;
2294 : : }
2295 : :
2296 : 0 : static void axgbe_phy_cdr_track(struct axgbe_port *pdata)
2297 : : {
2298 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2299 : :
2300 [ # # ]: 0 : if (!pdata->vdata->an_cdr_workaround)
2301 : : return;
2302 : :
2303 [ # # ]: 0 : if (!phy_data->phy_cdr_notrack)
2304 : : return;
2305 : :
2306 : 0 : rte_delay_us(phy_data->phy_cdr_delay + 400);
2307 : :
2308 : 0 : XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_CDR_CONTROL,
2309 : : AXGBE_PMA_CDR_TRACK_EN_MASK,
2310 : : AXGBE_PMA_CDR_TRACK_EN_ON);
2311 : :
2312 : 0 : phy_data->phy_cdr_notrack = 0;
2313 : : }
2314 : :
2315 : 0 : static void axgbe_phy_cdr_notrack(struct axgbe_port *pdata)
2316 : : {
2317 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2318 : :
2319 [ # # ]: 0 : if (!pdata->vdata->an_cdr_workaround)
2320 : : return;
2321 : :
2322 [ # # ]: 0 : if (phy_data->phy_cdr_notrack)
2323 : : return;
2324 : :
2325 : 0 : XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_CDR_CONTROL,
2326 : : AXGBE_PMA_CDR_TRACK_EN_MASK,
2327 : : AXGBE_PMA_CDR_TRACK_EN_OFF);
2328 : :
2329 : 0 : axgbe_phy_rrc(pdata);
2330 : :
2331 : 0 : phy_data->phy_cdr_notrack = 1;
2332 : : }
2333 : :
2334 : 0 : static void axgbe_phy_kr_training_post(struct axgbe_port *pdata)
2335 : : {
2336 [ # # ]: 0 : if (!pdata->cdr_track_early)
2337 : 0 : axgbe_phy_cdr_track(pdata);
2338 : 0 : }
2339 : :
2340 : 0 : static void axgbe_phy_kr_training_pre(struct axgbe_port *pdata)
2341 : : {
2342 [ # # ]: 0 : if (pdata->cdr_track_early)
2343 : 0 : axgbe_phy_cdr_track(pdata);
2344 : 0 : }
2345 : :
2346 : 0 : static void axgbe_phy_an_post(struct axgbe_port *pdata)
2347 : : {
2348 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2349 : :
2350 [ # # ]: 0 : switch (pdata->an_mode) {
2351 : 0 : case AXGBE_AN_MODE_CL73:
2352 : : case AXGBE_AN_MODE_CL73_REDRV:
2353 [ # # ]: 0 : if (phy_data->cur_mode != AXGBE_MODE_KR)
2354 : : break;
2355 : :
2356 : 0 : axgbe_phy_cdr_track(pdata);
2357 : :
2358 [ # # ]: 0 : switch (pdata->an_result) {
2359 : : case AXGBE_AN_READY:
2360 : : case AXGBE_AN_COMPLETE:
2361 : : break;
2362 : 0 : default:
2363 [ # # ]: 0 : if (phy_data->phy_cdr_delay < AXGBE_CDR_DELAY_MAX)
2364 : 0 : phy_data->phy_cdr_delay += AXGBE_CDR_DELAY_INC;
2365 : : break;
2366 : : }
2367 : : break;
2368 : : default:
2369 : : break;
2370 : : }
2371 : 0 : }
2372 : :
2373 : 0 : static void axgbe_phy_an_pre(struct axgbe_port *pdata)
2374 : : {
2375 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2376 : :
2377 [ # # ]: 0 : switch (pdata->an_mode) {
2378 : 0 : case AXGBE_AN_MODE_CL73:
2379 : : case AXGBE_AN_MODE_CL73_REDRV:
2380 [ # # ]: 0 : if (phy_data->cur_mode != AXGBE_MODE_KR)
2381 : : break;
2382 : :
2383 : 0 : axgbe_phy_cdr_notrack(pdata);
2384 : 0 : break;
2385 : : default:
2386 : : break;
2387 : : }
2388 : 0 : }
2389 : :
2390 : 0 : static void axgbe_phy_stop(struct axgbe_port *pdata)
2391 : : {
2392 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2393 : :
2394 : : /* Reset SFP data */
2395 : : axgbe_phy_sfp_reset(phy_data);
2396 : : axgbe_phy_sfp_mod_absent(pdata);
2397 : :
2398 : : /* Reset CDR support */
2399 : 0 : axgbe_phy_cdr_track(pdata);
2400 : :
2401 : : /* Power off the PHY */
2402 : 0 : axgbe_phy_power_off(pdata);
2403 : :
2404 : : /* Stop the I2C controller */
2405 : 0 : pdata->i2c_if.i2c_stop(pdata);
2406 : 0 : }
2407 : :
2408 : 0 : static int axgbe_phy_start(struct axgbe_port *pdata)
2409 : : {
2410 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2411 : : int ret;
2412 : :
2413 : : /* Start the I2C controller */
2414 : 0 : ret = pdata->i2c_if.i2c_start(pdata);
2415 [ # # ]: 0 : if (ret)
2416 : : return ret;
2417 : :
2418 : : /* Start in highest supported mode */
2419 : 0 : axgbe_phy_set_mode(pdata, phy_data->start_mode);
2420 : :
2421 : : /* Reset CDR support */
2422 : 0 : axgbe_phy_cdr_track(pdata);
2423 : :
2424 : : /* After starting the I2C controller, we can check for an SFP */
2425 [ # # ]: 0 : switch (phy_data->port_mode) {
2426 : 0 : case AXGBE_PORT_MODE_SFP:
2427 : 0 : axgbe_phy_sfp_detect(pdata);
2428 : 0 : break;
2429 : : default:
2430 : : break;
2431 : : }
2432 : 0 : pdata->phy.advertising &= axgbe_phy_an_advertising(pdata);
2433 : :
2434 : 0 : return ret;
2435 : : }
2436 : :
2437 : 0 : static int axgbe_phy_reset(struct axgbe_port *pdata)
2438 : : {
2439 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2440 : : enum axgbe_mode cur_mode;
2441 : :
2442 : : /* Reset by power cycling the PHY */
2443 : 0 : cur_mode = phy_data->cur_mode;
2444 : 0 : axgbe_phy_power_off(pdata);
2445 : : /* First time reset is done with passed unknown mode*/
2446 : 0 : axgbe_phy_set_mode(pdata, cur_mode);
2447 : 0 : return 0;
2448 : : }
2449 : :
2450 : 0 : static int axgbe_get_phy_id(struct axgbe_port *pdata)
2451 : : {
2452 : 0 : struct axgbe_phy_data *phy_data = pdata->phy_data;
2453 : : u16 phy_id_1;
2454 : : u16 phy_id_2;
2455 : : int ret;
2456 : :
2457 : 0 : ret = pdata->phy_if.phy_impl.read(pdata, MII_PHYSID1,
2458 : : &phy_id_1);
2459 [ # # ]: 0 : if (ret) {
2460 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to read PHYSID1 register");
2461 : 0 : return ret;
2462 : : }
2463 : :
2464 : 0 : ret = pdata->phy_if.phy_impl.read(pdata, MII_PHYSID2,
2465 : : &phy_id_2);
2466 [ # # ]: 0 : if (ret) {
2467 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to read PHYSID2 register");
2468 : 0 : return ret;
2469 : : }
2470 : :
2471 : 0 : phy_data->phy_id = (u32)phy_id_1 << 16;
2472 : 0 : phy_data->phy_id |= phy_id_2;
2473 : 0 : phy_data->phy_id &= AXGBE_PHY_REVISION_MASK;
2474 : :
2475 [ # # ]: 0 : if (phy_data->phy_id == AXGBE_PHY_REVISION_MASK) {
2476 : 0 : PMD_DRV_LOG_LINE(ERR, "Invalid PHY id (0x%x)",
2477 : : phy_data->phy_id);
2478 : 0 : return -EINVAL;
2479 : : }
2480 : 0 : PMD_DRV_LOG_LINE(DEBUG, "PHY id (0x%x)", phy_data->phy_id);
2481 : 0 : return 0;
2482 : : }
2483 : :
2484 : 0 : static int axgbe_phy_poll_reset(struct axgbe_port *pdata)
2485 : : {
2486 : : const uint64_t timeout_ms = 2000;
2487 : : const uint64_t interval_ms = 1;
2488 : : const uint64_t hz = rte_get_timer_hz();
2489 : : const uint64_t start = rte_get_timer_cycles();
2490 : :
2491 : 0 : u16 bmcr = 0;
2492 : : int ret;
2493 : :
2494 : 0 : for (;;) {
2495 : 0 : ret = pdata->phy_if.phy_impl.read(pdata, MII_BMCR, &bmcr);
2496 [ # # ]: 0 : if (ret) {
2497 : 0 : PMD_DRV_LOG_LINE(ERR, "PHY read BMCR failed");
2498 : 0 : return ret;
2499 : : }
2500 [ # # ]: 0 : if (!(bmcr & BMCR_RESET))
2501 : : return 0;
2502 : :
2503 : 0 : uint64_t elapsed_ms =
2504 : 0 : ((rte_get_timer_cycles() - start) * 1000) / hz;
2505 [ # # ]: 0 : if (elapsed_ms >= timeout_ms)
2506 : : break;
2507 : :
2508 : 0 : rte_delay_us_block(interval_ms * 1000);
2509 : : }
2510 : : return -ETIMEDOUT;
2511 : : }
2512 : :
2513 : :
2514 : 0 : static int axgbe_phy_soft_reset(struct axgbe_port *pdata)
2515 : : {
2516 : : int ret;
2517 : : u16 bmcr;
2518 : :
2519 : 0 : ret = pdata->phy_if.phy_impl.read(pdata, MII_BMCR, &bmcr);
2520 [ # # ]: 0 : if (ret) {
2521 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to read BMCR register");
2522 : 0 : return ret;
2523 : : }
2524 : :
2525 : 0 : bmcr |= BMCR_RESET;
2526 : :
2527 : 0 : ret = pdata->phy_if.phy_impl.write(pdata, MII_BMCR, bmcr);
2528 [ # # ]: 0 : if (ret) {
2529 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to write BMCR register");
2530 : 0 : return ret;
2531 : : }
2532 : :
2533 : 0 : ret = axgbe_phy_poll_reset(pdata);
2534 [ # # ]: 0 : if (ret) {
2535 : 0 : PMD_DRV_LOG_LINE(ERR, "Poll for PHY reset done failed");
2536 : 0 : return ret;
2537 : : }
2538 : : return 0;
2539 : : }
2540 : :
2541 : 0 : static int axgbe_m88e1512_set_page(struct axgbe_port *pdata, u16 page)
2542 : : {
2543 : : int ret;
2544 : :
2545 : 0 : ret = pdata->phy_if.phy_impl.write(pdata,
2546 : : AXGBE_M88E1512_PAGE_ADDR, page);
2547 [ # # ]: 0 : if (ret) {
2548 : 0 : PMD_DRV_LOG_LINE(ERR,
2549 : : "PHY set page failed for page 0x%x", page);
2550 : : }
2551 : 0 : return ret;
2552 : : }
2553 : :
2554 : : static const struct {
2555 : : u16 reg17, reg16;
2556 : : } errata_vals[] = {
2557 : : { 0x214b, 0x2144 },
2558 : : { 0x0c28, 0x2146 },
2559 : : { 0xb233, 0x214d },
2560 : : { 0xcc0c, 0x2159 },
2561 : : };
2562 : :
2563 : 0 : static int axgbe_m88e1512_init(struct axgbe_port *pdata)
2564 : : {
2565 : : int ret;
2566 : : u8 i;
2567 : :
2568 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Initialize M88E1512 phy");
2569 : :
2570 : : /* Switch to PHY page 0xFF */
2571 : 0 : ret = axgbe_m88e1512_set_page(pdata, 0xff);
2572 [ # # ]: 0 : if (ret)
2573 : 0 : goto err_out;
2574 : :
2575 : : /* Configure M88E1512 errata registers */
2576 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(errata_vals); i++) {
2577 : 0 : ret = pdata->phy_if.phy_impl.write(pdata,
2578 : : AXGBE_M88E1512_CFG_REG_2,
2579 : 0 : errata_vals[i].reg17);
2580 [ # # ]: 0 : if (ret) {
2581 : 0 : PMD_DRV_LOG_LINE(ERR, "Config M88E1512 errata failed");
2582 : 0 : goto err_set_copper_page;
2583 : : }
2584 : :
2585 : 0 : ret = pdata->phy_if.phy_impl.write(pdata,
2586 : : AXGBE_M88E1512_CFG_REG_1,
2587 : 0 : errata_vals[i].reg16);
2588 [ # # ]: 0 : if (ret) {
2589 : 0 : PMD_DRV_LOG_LINE(ERR, "Config M88E1512 errata failed");
2590 : 0 : goto err_set_copper_page;
2591 : : }
2592 : : }
2593 : :
2594 : : /* Switch to PHY page 0xFB */
2595 : 0 : ret = axgbe_m88e1512_set_page(pdata, 0xfb);
2596 [ # # ]: 0 : if (ret)
2597 : 0 : goto err_set_copper_page;
2598 : :
2599 : 0 : ret = pdata->phy_if.phy_impl.write(pdata,
2600 : : AXGBE_M88E1512_CFG_REG_3, 0xC00D);
2601 [ # # ]: 0 : if (ret)
2602 : 0 : goto err_set_copper_page;
2603 : :
2604 : : /* Switch to PHY copper page */
2605 : 0 : ret = axgbe_m88e1512_set_page(pdata, AXGBE_M88E1512_COPPER_PAGE);
2606 [ # # ]: 0 : if (ret)
2607 : 0 : goto err_out;
2608 : :
2609 : : /* SGMII-to-Copper mode initialization */
2610 : :
2611 : : /* Switch to PHY mode page */
2612 : 0 : ret = axgbe_m88e1512_set_page(pdata, AXGBE_M88E1512_MODE_PAGE);
2613 [ # # ]: 0 : if (ret)
2614 : 0 : goto err_set_copper_page;
2615 : :
2616 : 0 : ret = pdata->phy_if.phy_impl.write(pdata,
2617 : : AXGBE_M88E1512_MODE,
2618 : : (AXGBE_M88E1512_MODE_SW_RESET |
2619 : : AXGBE_M88E1512_MODE_SGMII_COPPER));
2620 [ # # ]: 0 : if (ret)
2621 : 0 : goto err_set_copper_page;
2622 : :
2623 : : /* Switch to PHY copper page */
2624 : 0 : ret = axgbe_m88e1512_set_page(pdata, AXGBE_M88E1512_COPPER_PAGE);
2625 [ # # ]: 0 : if (ret)
2626 : 0 : goto err_out;
2627 : :
2628 : 0 : ret = axgbe_phy_soft_reset(pdata);
2629 [ # # ]: 0 : if (ret) {
2630 : 0 : PMD_DRV_LOG_LINE(ERR, "M88E1512 PHY soft reset failed");
2631 : 0 : goto err_out;
2632 : : }
2633 : :
2634 : 0 : PMD_DRV_LOG_LINE(DEBUG, "M88E1512 phy init done");
2635 : 0 : return 0;
2636 : :
2637 : 0 : err_set_copper_page:
2638 : : /* Switch to PHY page 0 */
2639 : 0 : axgbe_m88e1512_set_page(pdata, AXGBE_M88E1512_COPPER_PAGE);
2640 : 0 : err_out:
2641 : 0 : PMD_DRV_LOG_LINE(ERR, "M88E1512 PHY initialization failed");
2642 : 0 : return ret;
2643 : : }
2644 : :
2645 : :
2646 : 0 : static int axgbe_get_ext_phy_link_status(struct axgbe_port *pdata, bool *linkup)
2647 : : {
2648 : : int ret;
2649 : : u16 bmcr;
2650 : : u16 bmsr;
2651 : :
2652 : 0 : *linkup = false;
2653 : :
2654 : 0 : ret = pdata->phy_if.phy_impl.read(pdata, MII_BMCR, &bmcr);
2655 [ # # ]: 0 : if (ret) {
2656 : 0 : PMD_DRV_LOG_LINE(ERR, "PHY read failed for BMCR register");
2657 : 0 : return ret;
2658 : : }
2659 : :
2660 : : /* Autoneg is being started, therefore disregard BMSR value and
2661 : : * report link as down.
2662 : : */
2663 [ # # ]: 0 : if (bmcr & BMCR_ANRESTART)
2664 : : return 0;
2665 : :
2666 : 0 : ret = pdata->phy_if.phy_impl.read(pdata, MII_BMSR, &bmsr);
2667 [ # # ]: 0 : if (ret) {
2668 : 0 : PMD_DRV_LOG_LINE(ERR, "PHY read failed for BMSR register");
2669 : 0 : return ret;
2670 : : }
2671 : :
2672 [ # # ]: 0 : if (bmsr & BMSR_LSTATUS)
2673 : 0 : goto done;
2674 : :
2675 : : /* Read link status */
2676 : 0 : ret = pdata->phy_if.phy_impl.read(pdata, MII_BMSR, &bmsr);
2677 [ # # ]: 0 : if (ret) {
2678 : 0 : PMD_DRV_LOG_LINE(ERR, "PHY read failed for BMSR register");
2679 : 0 : return ret;
2680 : : }
2681 : 0 : done:
2682 : 0 : *linkup = (bmsr & BMSR_LSTATUS) ? true : false;
2683 : 0 : return 0;
2684 : : }
2685 : :
2686 : :
2687 [ # # ]: 0 : static int axgbe_phy_init(struct axgbe_port *pdata)
2688 : : {
2689 : : struct axgbe_phy_data *phy_data;
2690 : : int ret;
2691 : :
2692 : : /* Check if enabled */
2693 : : if (!axgbe_phy_port_enabled(pdata)) {
2694 : 0 : PMD_DRV_LOG_LINE(ERR, "device is not enabled");
2695 : 0 : return -ENODEV;
2696 : : }
2697 : :
2698 : : /* Initialize the I2C controller */
2699 : 0 : ret = pdata->i2c_if.i2c_init(pdata);
2700 [ # # ]: 0 : if (ret)
2701 : : return ret;
2702 : :
2703 : 0 : phy_data = rte_zmalloc("phy_data memory", sizeof(*phy_data), 0);
2704 [ # # ]: 0 : if (!phy_data) {
2705 : 0 : PMD_DRV_LOG_LINE(ERR, "phy_data allocation failed");
2706 : 0 : return -ENOMEM;
2707 : : }
2708 : 0 : pdata->phy_data = phy_data;
2709 : :
2710 : 0 : phy_data->port_mode = XP_GET_BITS(pdata->pp0, XP_PROP_0, PORT_MODE);
2711 : 0 : phy_data->port_id = XP_GET_BITS(pdata->pp0, XP_PROP_0, PORT_ID);
2712 : 0 : phy_data->port_speeds = XP_GET_BITS(pdata->pp0, XP_PROP_0, PORT_SPEEDS);
2713 : 0 : phy_data->conn_type = XP_GET_BITS(pdata->pp0, XP_PROP_0, CONN_TYPE);
2714 : 0 : phy_data->mdio_addr = XP_GET_BITS(pdata->pp0, XP_PROP_0, MDIO_ADDR);
2715 : :
2716 : 0 : phy_data->redrv = XP_GET_BITS(pdata->pp4, XP_PROP_4, REDRV_PRESENT);
2717 : 0 : phy_data->redrv_if = XP_GET_BITS(pdata->pp4, XP_PROP_4, REDRV_IF);
2718 : 0 : phy_data->redrv_addr = XP_GET_BITS(pdata->pp4, XP_PROP_4, REDRV_ADDR);
2719 : 0 : phy_data->redrv_lane = XP_GET_BITS(pdata->pp4, XP_PROP_4, REDRV_LANE);
2720 : 0 : phy_data->redrv_model = XP_GET_BITS(pdata->pp4, XP_PROP_4, REDRV_MODEL);
2721 : :
2722 : : /* Validate the connection requested */
2723 [ # # ]: 0 : if (axgbe_phy_conn_type_mismatch(pdata)) {
2724 : 0 : PMD_DRV_LOG_LINE(ERR, "phy mode/connection mismatch (%#x/%#x)",
2725 : : phy_data->port_mode, phy_data->conn_type);
2726 : 0 : return -EINVAL;
2727 : : }
2728 : :
2729 : : /* Validate the mode requested */
2730 [ # # ]: 0 : if (axgbe_phy_port_mode_mismatch(pdata)) {
2731 : 0 : PMD_DRV_LOG_LINE(ERR, "phy mode/speed mismatch (%#x/%#x)",
2732 : : phy_data->port_mode, phy_data->port_speeds);
2733 : 0 : return -EINVAL;
2734 : : }
2735 : :
2736 : : /* Check for and validate MDIO reset support */
2737 : 0 : ret = axgbe_phy_mdio_reset_setup(pdata);
2738 [ # # ]: 0 : if (ret)
2739 : : return ret;
2740 : :
2741 : : /* Validate the re-driver information */
2742 : : if (axgbe_phy_redrv_error(phy_data)) {
2743 : 0 : PMD_DRV_LOG_LINE(ERR, "phy re-driver settings error");
2744 : 0 : return -EINVAL;
2745 : : }
2746 : 0 : pdata->kr_redrv = phy_data->redrv;
2747 : :
2748 : : /* Indicate current mode is unknown */
2749 : 0 : phy_data->cur_mode = AXGBE_MODE_UNKNOWN;
2750 : :
2751 : : /* Initialize supported features */
2752 : 0 : pdata->phy.supported = 0;
2753 : :
2754 [ # # # # : 0 : switch (phy_data->port_mode) {
# # # # #
# ]
2755 : : /* Backplane support */
2756 : 0 : case AXGBE_PORT_MODE_BACKPLANE:
2757 : 0 : pdata->phy.supported |= SUPPORTED_Autoneg;
2758 : : /* Fallthrough */
2759 : 0 : case AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
2760 : 0 : pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2761 : 0 : pdata->phy.supported |= SUPPORTED_Backplane;
2762 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) {
2763 : 0 : pdata->phy.supported |= SUPPORTED_1000baseKX_Full;
2764 : 0 : phy_data->start_mode = AXGBE_MODE_KX_1000;
2765 : : }
2766 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) {
2767 : 0 : pdata->phy.supported |= SUPPORTED_10000baseKR_Full;
2768 [ # # ]: 0 : if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
2769 : 0 : pdata->phy.supported |=
2770 : : SUPPORTED_10000baseR_FEC;
2771 : 0 : phy_data->start_mode = AXGBE_MODE_KR;
2772 : : }
2773 : :
2774 : 0 : phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE;
2775 : 0 : break;
2776 : 0 : case AXGBE_PORT_MODE_BACKPLANE_2500:
2777 : : pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2778 : : pdata->phy.supported |= SUPPORTED_Backplane;
2779 : 0 : pdata->phy.supported |= SUPPORTED_2500baseX_Full;
2780 : 0 : phy_data->start_mode = AXGBE_MODE_KX_2500;
2781 : :
2782 : 0 : phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE;
2783 : 0 : break;
2784 : :
2785 : : /* MDIO 1GBase-T support */
2786 : 0 : case AXGBE_PORT_MODE_1000BASE_T:
2787 : : pdata->phy.supported |= SUPPORTED_Autoneg;
2788 : : pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2789 : 0 : pdata->phy.supported |= SUPPORTED_TP;
2790 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) {
2791 : 0 : pdata->phy.supported |= SUPPORTED_10baseT_Full;
2792 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_10;
2793 : : }
2794 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
2795 : 0 : pdata->phy.supported |= SUPPORTED_100baseT_Full;
2796 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_100;
2797 : : }
2798 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) {
2799 : 0 : pdata->phy.supported |= SUPPORTED_1000baseT_Full;
2800 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_1000;
2801 : : }
2802 : :
2803 : 0 : phy_data->phydev_mode = AXGBE_MDIO_MODE_CL22;
2804 : 0 : break;
2805 : :
2806 : : /* MDIO Base-X support */
2807 : 0 : case AXGBE_PORT_MODE_1000BASE_X:
2808 : : pdata->phy.supported |= SUPPORTED_Autoneg;
2809 : : pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2810 : : pdata->phy.supported |= SUPPORTED_FIBRE;
2811 : 0 : pdata->phy.supported |= SUPPORTED_1000baseT_Full;
2812 : 0 : phy_data->start_mode = AXGBE_MODE_X;
2813 : :
2814 : 0 : phy_data->phydev_mode = AXGBE_MDIO_MODE_CL22;
2815 : 0 : break;
2816 : :
2817 : : /* MDIO NBase-T support */
2818 : 0 : case AXGBE_PORT_MODE_NBASE_T:
2819 : : pdata->phy.supported |= SUPPORTED_Autoneg;
2820 : : pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2821 : 0 : pdata->phy.supported |= SUPPORTED_TP;
2822 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) {
2823 : 0 : pdata->phy.supported |= SUPPORTED_10baseT_Full;
2824 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_10;
2825 : : }
2826 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
2827 : 0 : pdata->phy.supported |= SUPPORTED_100baseT_Full;
2828 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_100;
2829 : : }
2830 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) {
2831 : 0 : pdata->phy.supported |= SUPPORTED_1000baseT_Full;
2832 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_1000;
2833 : : }
2834 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500) {
2835 : 0 : pdata->phy.supported |= SUPPORTED_2500baseX_Full;
2836 : 0 : phy_data->start_mode = AXGBE_MODE_KX_2500;
2837 : : }
2838 : :
2839 : 0 : phy_data->phydev_mode = AXGBE_MDIO_MODE_CL45;
2840 : 0 : break;
2841 : :
2842 : : /* 10GBase-T support */
2843 : 0 : case AXGBE_PORT_MODE_10GBASE_T:
2844 : : pdata->phy.supported |= SUPPORTED_Autoneg;
2845 : : pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2846 : 0 : pdata->phy.supported |= SUPPORTED_TP;
2847 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) {
2848 : 0 : pdata->phy.supported |= SUPPORTED_10baseT_Full;
2849 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_10;
2850 : : }
2851 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
2852 : 0 : pdata->phy.supported |= SUPPORTED_100baseT_Full;
2853 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_100;
2854 : : }
2855 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) {
2856 : 0 : pdata->phy.supported |= SUPPORTED_1000baseT_Full;
2857 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_1000;
2858 : : }
2859 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500) {
2860 : 0 : pdata->phy.supported |= SUPPORTED_2500baseX_Full;
2861 : 0 : phy_data->start_mode = AXGBE_MODE_KX_2500;
2862 : : }
2863 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) {
2864 : 0 : pdata->phy.supported |= SUPPORTED_10000baseT_Full;
2865 : 0 : phy_data->start_mode = AXGBE_MODE_KR;
2866 : : }
2867 : :
2868 : 0 : phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE;
2869 : 0 : break;
2870 : :
2871 : : /* 10GBase-R support */
2872 : 0 : case AXGBE_PORT_MODE_10GBASE_R:
2873 : : pdata->phy.supported |= SUPPORTED_Autoneg;
2874 : : pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2875 : : pdata->phy.supported |= SUPPORTED_TP;
2876 : 0 : pdata->phy.supported |= SUPPORTED_10000baseT_Full;
2877 [ # # ]: 0 : if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
2878 : 0 : pdata->phy.supported |= SUPPORTED_10000baseR_FEC;
2879 : 0 : phy_data->start_mode = AXGBE_MODE_SFI;
2880 : :
2881 : 0 : phy_data->phydev_mode = AXGBE_MDIO_MODE_NONE;
2882 : 0 : break;
2883 : :
2884 : : /* SFP support */
2885 : 0 : case AXGBE_PORT_MODE_SFP:
2886 : : pdata->phy.supported |= SUPPORTED_Autoneg;
2887 : : pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2888 : : pdata->phy.supported |= SUPPORTED_TP;
2889 : 0 : pdata->phy.supported |= SUPPORTED_FIBRE;
2890 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) {
2891 : 0 : pdata->phy.supported |= SUPPORTED_10baseT_Full;
2892 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_10;
2893 : : }
2894 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
2895 : 0 : pdata->phy.supported |= SUPPORTED_100baseT_Full;
2896 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_100;
2897 : : }
2898 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) {
2899 : 0 : pdata->phy.supported |= SUPPORTED_1000baseT_Full;
2900 : 0 : phy_data->start_mode = AXGBE_MODE_SGMII_1000;
2901 : : }
2902 [ # # ]: 0 : if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) {
2903 : 0 : pdata->phy.supported |= SUPPORTED_10000baseT_Full;
2904 : 0 : phy_data->start_mode = AXGBE_MODE_SFI;
2905 [ # # ]: 0 : if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
2906 : 0 : pdata->phy.supported |=
2907 : : SUPPORTED_10000baseR_FEC;
2908 : : }
2909 : :
2910 : 0 : phy_data->phydev_mode = AXGBE_MDIO_MODE_CL22;
2911 : :
2912 : 0 : axgbe_phy_sfp_setup(pdata);
2913 : 0 : break;
2914 : : default:
2915 : : return -EINVAL;
2916 : : }
2917 : :
2918 [ # # ]: 0 : if ((phy_data->conn_type & AXGBE_CONN_TYPE_MDIO) &&
2919 [ # # ]: 0 : (phy_data->phydev_mode != AXGBE_MDIO_MODE_NONE)) {
2920 : 0 : ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->mdio_addr,
2921 : : phy_data->phydev_mode);
2922 [ # # ]: 0 : if (ret) {
2923 : 0 : PMD_DRV_LOG_LINE(ERR, "mdio port/clause not compatible (%d/%u)",
2924 : : phy_data->mdio_addr, phy_data->phydev_mode);
2925 : 0 : return -EINVAL;
2926 : : }
2927 : : }
2928 : :
2929 [ # # # # ]: 0 : if (phy_data->redrv && !phy_data->redrv_if) {
2930 : 0 : ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->redrv_addr,
2931 : : AXGBE_MDIO_MODE_CL22);
2932 [ # # ]: 0 : if (ret) {
2933 : 0 : PMD_DRV_LOG_LINE(ERR, "redriver mdio port not compatible (%u)",
2934 : : phy_data->redrv_addr);
2935 : 0 : return -EINVAL;
2936 : : }
2937 : : }
2938 : :
2939 : 0 : phy_data->phy_cdr_delay = AXGBE_CDR_DELAY_INIT;
2940 : :
2941 [ # # ]: 0 : if (phy_data->port_mode == AXGBE_PORT_MODE_1000BASE_T) {
2942 : 0 : ret = axgbe_get_phy_id(pdata);
2943 [ # # ]: 0 : if (ret) {
2944 : 0 : PMD_DRV_LOG_LINE(ERR, "failed to get PHY id");
2945 : 0 : return ret;
2946 : : }
2947 : :
2948 : 0 : PMD_DRV_LOG_LINE(DEBUG, "PHY ID = 0x%x", phy_data->phy_id);
2949 : :
2950 [ # # ]: 0 : if (phy_data->phy_id == M88E1512_E_PHY_ID) {
2951 : 0 : ret = axgbe_m88e1512_init(pdata);
2952 [ # # ]: 0 : if (ret)
2953 : 0 : return ret;
2954 : : }
2955 : : }
2956 : :
2957 : : return 0;
2958 : : }
2959 : 0 : void axgbe_init_function_ptrs_phy_v2(struct axgbe_phy_if *phy_if)
2960 : : {
2961 : : struct axgbe_phy_impl_if *phy_impl = &phy_if->phy_impl;
2962 : :
2963 : 0 : phy_impl->init = axgbe_phy_init;
2964 : 0 : phy_impl->reset = axgbe_phy_reset;
2965 : 0 : phy_impl->start = axgbe_phy_start;
2966 : 0 : phy_impl->stop = axgbe_phy_stop;
2967 : 0 : phy_impl->link_status = axgbe_phy_link_status;
2968 : 0 : phy_impl->use_mode = axgbe_phy_use_mode;
2969 : 0 : phy_impl->set_mode = axgbe_phy_set_mode;
2970 : 0 : phy_impl->get_mode = axgbe_phy_get_mode;
2971 : 0 : phy_impl->switch_mode = axgbe_phy_switch_mode;
2972 : 0 : phy_impl->cur_mode = axgbe_phy_cur_mode;
2973 : 0 : phy_impl->an_mode = axgbe_phy_an_mode;
2974 : 0 : phy_impl->an_config = axgbe_phy_an_config;
2975 : 0 : phy_impl->an_advertising = axgbe_phy_an_advertising;
2976 : 0 : phy_impl->an_outcome = axgbe_phy_an_outcome;
2977 : :
2978 : 0 : phy_impl->an_pre = axgbe_phy_an_pre;
2979 : 0 : phy_impl->an_post = axgbe_phy_an_post;
2980 : :
2981 : 0 : phy_impl->kr_training_pre = axgbe_phy_kr_training_pre;
2982 : 0 : phy_impl->kr_training_post = axgbe_phy_kr_training_post;
2983 : :
2984 : 0 : phy_impl->read = axgbe_phy_read;
2985 : 0 : phy_impl->write = axgbe_phy_write;
2986 : 0 : }
|