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