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