blob: 9d8c953083b4efa0c430c8b3e539625a90f4b1fb [file] [log] [blame]
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001/*
2 * AMD 10Gb Ethernet driver
3 *
4 * This file is available to you under your choice of the following two
5 * licenses:
6 *
7 * License 1: GPLv2
8 *
9 * Copyright (c) 2016 Advanced Micro Devices, Inc.
10 *
11 * This file is free software; you may copy, redistribute and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This file is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 *
24 * This file incorporates work covered by the following copyright and
25 * permission notice:
26 * The Synopsys DWC ETHER XGMAC Software Driver and documentation
27 * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
28 * Inc. unless otherwise expressly agreed to in writing between Synopsys
29 * and you.
30 *
31 * The Software IS NOT an item of Licensed Software or Licensed Product
32 * under any End User Software License Agreement or Agreement for Licensed
33 * Product with Synopsys or any supplement thereto. Permission is hereby
34 * granted, free of charge, to any person obtaining a copy of this software
35 * annotated with this license and the Software, to deal in the Software
36 * without restriction, including without limitation the rights to use,
37 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
38 * of the Software, and to permit persons to whom the Software is furnished
39 * to do so, subject to the following conditions:
40 *
41 * The above copyright notice and this permission notice shall be included
42 * in all copies or substantial portions of the Software.
43 *
44 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
45 * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
46 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47 * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
48 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
51 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
52 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
54 * THE POSSIBILITY OF SUCH DAMAGE.
55 *
56 *
57 * License 2: Modified BSD
58 *
59 * Copyright (c) 2016 Advanced Micro Devices, Inc.
60 * All rights reserved.
61 *
62 * Redistribution and use in source and binary forms, with or without
63 * modification, are permitted provided that the following conditions are met:
64 * * Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 * * Redistributions in binary form must reproduce the above copyright
67 * notice, this list of conditions and the following disclaimer in the
68 * documentation and/or other materials provided with the distribution.
69 * * Neither the name of Advanced Micro Devices, Inc. nor the
70 * names of its contributors may be used to endorse or promote products
71 * derived from this software without specific prior written permission.
72 *
73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
74 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
77 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
79 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
81 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
82 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
83 *
84 * This file incorporates work covered by the following copyright and
85 * permission notice:
86 * The Synopsys DWC ETHER XGMAC Software Driver and documentation
87 * (hereinafter "Software") is an unsupported proprietary work of Synopsys,
88 * Inc. unless otherwise expressly agreed to in writing between Synopsys
89 * and you.
90 *
91 * The Software IS NOT an item of Licensed Software or Licensed Product
92 * under any End User Software License Agreement or Agreement for Licensed
93 * Product with Synopsys or any supplement thereto. Permission is hereby
94 * granted, free of charge, to any person obtaining a copy of this software
95 * annotated with this license and the Software, to deal in the Software
96 * without restriction, including without limitation the rights to use,
97 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies
98 * of the Software, and to permit persons to whom the Software is furnished
99 * to do so, subject to the following conditions:
100 *
101 * The above copyright notice and this permission notice shall be included
102 * in all copies or substantial portions of the Software.
103 *
104 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
105 * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
106 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
107 * PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
108 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
109 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
110 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
111 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
112 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
113 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
114 * THE POSSIBILITY OF SUCH DAMAGE.
115 */
116
117#include <linux/module.h>
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -0600118#include <linux/device.h>
Lendacky, Thomas47f164d2016-11-10 17:09:55 -0600119#include <linux/kmod.h>
120#include <linux/mdio.h>
121#include <linux/phy.h>
122
123#include "xgbe.h"
124#include "xgbe-common.h"
125
126#define XGBE_PHY_PORT_SPEED_100 BIT(0)
127#define XGBE_PHY_PORT_SPEED_1000 BIT(1)
128#define XGBE_PHY_PORT_SPEED_2500 BIT(2)
129#define XGBE_PHY_PORT_SPEED_10000 BIT(3)
130
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -0600131#define XGBE_MUTEX_RELEASE 0x80000000
132
133#define XGBE_SFP_DIRECT 7
134
135/* I2C target addresses */
136#define XGBE_SFP_SERIAL_ID_ADDRESS 0x50
137#define XGBE_SFP_DIAG_INFO_ADDRESS 0x51
138#define XGBE_SFP_PHY_ADDRESS 0x56
139#define XGBE_GPIO_ADDRESS_PCA9555 0x20
140
141/* SFP sideband signal indicators */
142#define XGBE_GPIO_NO_TX_FAULT BIT(0)
143#define XGBE_GPIO_NO_RATE_SELECT BIT(1)
144#define XGBE_GPIO_NO_MOD_ABSENT BIT(2)
145#define XGBE_GPIO_NO_RX_LOS BIT(3)
146
Lendacky, Thomas47f164d2016-11-10 17:09:55 -0600147/* Rate-change complete wait/retry count */
148#define XGBE_RATECHANGE_COUNT 500
149
150enum xgbe_port_mode {
151 XGBE_PORT_MODE_RSVD = 0,
152 XGBE_PORT_MODE_BACKPLANE,
153 XGBE_PORT_MODE_BACKPLANE_2500,
154 XGBE_PORT_MODE_1000BASE_T,
155 XGBE_PORT_MODE_1000BASE_X,
156 XGBE_PORT_MODE_NBASE_T,
157 XGBE_PORT_MODE_10GBASE_T,
158 XGBE_PORT_MODE_10GBASE_R,
159 XGBE_PORT_MODE_SFP,
160 XGBE_PORT_MODE_MAX,
161};
162
163enum xgbe_conn_type {
164 XGBE_CONN_TYPE_NONE = 0,
165 XGBE_CONN_TYPE_SFP,
166 XGBE_CONN_TYPE_MDIO,
Lendacky, Thomas5a4e4c82016-11-17 08:43:37 -0600167 XGBE_CONN_TYPE_RSVD1,
Lendacky, Thomas47f164d2016-11-10 17:09:55 -0600168 XGBE_CONN_TYPE_BACKPLANE,
169 XGBE_CONN_TYPE_MAX,
170};
171
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -0600172/* SFP/SFP+ related definitions */
173enum xgbe_sfp_comm {
174 XGBE_SFP_COMM_DIRECT = 0,
175 XGBE_SFP_COMM_PCA9545,
176};
177
178enum xgbe_sfp_cable {
179 XGBE_SFP_CABLE_UNKNOWN = 0,
180 XGBE_SFP_CABLE_ACTIVE,
181 XGBE_SFP_CABLE_PASSIVE,
182};
183
184enum xgbe_sfp_base {
185 XGBE_SFP_BASE_UNKNOWN = 0,
186 XGBE_SFP_BASE_1000_T,
187 XGBE_SFP_BASE_1000_SX,
188 XGBE_SFP_BASE_1000_LX,
189 XGBE_SFP_BASE_1000_CX,
190 XGBE_SFP_BASE_10000_SR,
191 XGBE_SFP_BASE_10000_LR,
192 XGBE_SFP_BASE_10000_LRM,
193 XGBE_SFP_BASE_10000_ER,
194 XGBE_SFP_BASE_10000_CR,
195};
196
197enum xgbe_sfp_speed {
198 XGBE_SFP_SPEED_UNKNOWN = 0,
199 XGBE_SFP_SPEED_100_1000,
200 XGBE_SFP_SPEED_1000,
201 XGBE_SFP_SPEED_10000,
202};
203
204/* SFP Serial ID Base ID values relative to an offset of 0 */
205#define XGBE_SFP_BASE_ID 0
206#define XGBE_SFP_ID_SFP 0x03
207
208#define XGBE_SFP_BASE_EXT_ID 1
209#define XGBE_SFP_EXT_ID_SFP 0x04
210
211#define XGBE_SFP_BASE_10GBE_CC 3
212#define XGBE_SFP_BASE_10GBE_CC_SR BIT(4)
213#define XGBE_SFP_BASE_10GBE_CC_LR BIT(5)
214#define XGBE_SFP_BASE_10GBE_CC_LRM BIT(6)
215#define XGBE_SFP_BASE_10GBE_CC_ER BIT(7)
216
217#define XGBE_SFP_BASE_1GBE_CC 6
218#define XGBE_SFP_BASE_1GBE_CC_SX BIT(0)
219#define XGBE_SFP_BASE_1GBE_CC_LX BIT(1)
220#define XGBE_SFP_BASE_1GBE_CC_CX BIT(2)
221#define XGBE_SFP_BASE_1GBE_CC_T BIT(3)
222
223#define XGBE_SFP_BASE_CABLE 8
224#define XGBE_SFP_BASE_CABLE_PASSIVE BIT(2)
225#define XGBE_SFP_BASE_CABLE_ACTIVE BIT(3)
226
227#define XGBE_SFP_BASE_BR 12
228#define XGBE_SFP_BASE_BR_1GBE_MIN 0x0a
229#define XGBE_SFP_BASE_BR_1GBE_MAX 0x0d
230#define XGBE_SFP_BASE_BR_10GBE_MIN 0x64
231#define XGBE_SFP_BASE_BR_10GBE_MAX 0x68
232
233#define XGBE_SFP_BASE_CU_CABLE_LEN 18
234
235#define XGBE_SFP_BASE_VENDOR_NAME 20
236#define XGBE_SFP_BASE_VENDOR_NAME_LEN 16
237#define XGBE_SFP_BASE_VENDOR_PN 40
238#define XGBE_SFP_BASE_VENDOR_PN_LEN 16
239#define XGBE_SFP_BASE_VENDOR_REV 56
240#define XGBE_SFP_BASE_VENDOR_REV_LEN 4
241
242#define XGBE_SFP_BASE_CC 63
243
244/* SFP Serial ID Extended ID values relative to an offset of 64 */
245#define XGBE_SFP_BASE_VENDOR_SN 4
246#define XGBE_SFP_BASE_VENDOR_SN_LEN 16
247
248#define XGBE_SFP_EXTD_DIAG 28
249#define XGBE_SFP_EXTD_DIAG_ADDR_CHANGE BIT(2)
250
251#define XGBE_SFP_EXTD_SFF_8472 30
252
253#define XGBE_SFP_EXTD_CC 31
254
255struct xgbe_sfp_eeprom {
256 u8 base[64];
257 u8 extd[32];
258 u8 vendor[32];
259};
260
261#define XGBE_BEL_FUSE_VENDOR "BEL-FUSE "
262#define XGBE_BEL_FUSE_PARTNO "1GBT-SFP06 "
263
264struct xgbe_sfp_ascii {
265 union {
266 char vendor[XGBE_SFP_BASE_VENDOR_NAME_LEN + 1];
267 char partno[XGBE_SFP_BASE_VENDOR_PN_LEN + 1];
268 char rev[XGBE_SFP_BASE_VENDOR_REV_LEN + 1];
269 char serno[XGBE_SFP_BASE_VENDOR_SN_LEN + 1];
270 } u;
271};
272
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -0600273/* MDIO PHY reset types */
274enum xgbe_mdio_reset {
275 XGBE_MDIO_RESET_NONE = 0,
276 XGBE_MDIO_RESET_I2C_GPIO,
277 XGBE_MDIO_RESET_INT_GPIO,
278 XGBE_MDIO_RESET_MAX,
279};
280
Lendacky, Thomasd7445d12016-11-10 17:11:41 -0600281/* Re-driver related definitions */
282enum xgbe_phy_redrv_if {
283 XGBE_PHY_REDRV_IF_MDIO = 0,
284 XGBE_PHY_REDRV_IF_I2C,
285 XGBE_PHY_REDRV_IF_MAX,
286};
287
288enum xgbe_phy_redrv_model {
289 XGBE_PHY_REDRV_MODEL_4223 = 0,
290 XGBE_PHY_REDRV_MODEL_4227,
291 XGBE_PHY_REDRV_MODEL_MAX,
292};
293
294enum xgbe_phy_redrv_mode {
295 XGBE_PHY_REDRV_MODE_CX = 5,
296 XGBE_PHY_REDRV_MODE_SR = 9,
297};
298
299#define XGBE_PHY_REDRV_MODE_REG 0x12b0
300
Lendacky, Thomas47f164d2016-11-10 17:09:55 -0600301/* PHY related configuration information */
302struct xgbe_phy_data {
303 enum xgbe_port_mode port_mode;
304
305 unsigned int port_id;
306
307 unsigned int port_speeds;
308
309 enum xgbe_conn_type conn_type;
310
311 enum xgbe_mode cur_mode;
312 enum xgbe_mode start_mode;
313
314 unsigned int rrc_count;
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -0600315
316 unsigned int mdio_addr;
317
318 unsigned int comm_owned;
319
320 /* SFP Support */
321 enum xgbe_sfp_comm sfp_comm;
322 unsigned int sfp_mux_address;
323 unsigned int sfp_mux_channel;
324
325 unsigned int sfp_gpio_address;
326 unsigned int sfp_gpio_mask;
327 unsigned int sfp_gpio_rx_los;
328 unsigned int sfp_gpio_tx_fault;
329 unsigned int sfp_gpio_mod_absent;
330 unsigned int sfp_gpio_rate_select;
331
332 unsigned int sfp_rx_los;
333 unsigned int sfp_tx_fault;
334 unsigned int sfp_mod_absent;
335 unsigned int sfp_diags;
336 unsigned int sfp_changed;
337 unsigned int sfp_phy_avail;
338 unsigned int sfp_cable_len;
339 enum xgbe_sfp_base sfp_base;
340 enum xgbe_sfp_cable sfp_cable;
341 enum xgbe_sfp_speed sfp_speed;
342 struct xgbe_sfp_eeprom sfp_eeprom;
343
344 /* External PHY support */
345 enum xgbe_mdio_mode phydev_mode;
346 struct mii_bus *mii;
347 struct phy_device *phydev;
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -0600348 enum xgbe_mdio_reset mdio_reset;
349 unsigned int mdio_reset_addr;
350 unsigned int mdio_reset_gpio;
Lendacky, Thomasd7445d12016-11-10 17:11:41 -0600351
352 /* Re-driver support */
353 unsigned int redrv;
354 unsigned int redrv_if;
355 unsigned int redrv_addr;
356 unsigned int redrv_lane;
357 unsigned int redrv_model;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -0600358};
359
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -0600360/* I2C, MDIO and GPIO lines are muxed, so only one device at a time */
361static DEFINE_MUTEX(xgbe_phy_comm_lock);
362
363static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata);
364
365static int xgbe_phy_i2c_xfer(struct xgbe_prv_data *pdata,
366 struct xgbe_i2c_op *i2c_op)
367{
368 struct xgbe_phy_data *phy_data = pdata->phy_data;
369
370 /* Be sure we own the bus */
371 if (WARN_ON(!phy_data->comm_owned))
372 return -EIO;
373
374 return pdata->i2c_if.i2c_xfer(pdata, i2c_op);
375}
376
Lendacky, Thomasd7445d12016-11-10 17:11:41 -0600377static int xgbe_phy_redrv_write(struct xgbe_prv_data *pdata, unsigned int reg,
378 unsigned int val)
379{
380 struct xgbe_phy_data *phy_data = pdata->phy_data;
381 struct xgbe_i2c_op i2c_op;
382 __be16 *redrv_val;
383 u8 redrv_data[5], csum;
384 unsigned int i, retry;
385 int ret;
386
387 /* High byte of register contains read/write indicator */
388 redrv_data[0] = ((reg >> 8) & 0xff) << 1;
389 redrv_data[1] = reg & 0xff;
390 redrv_val = (__be16 *)&redrv_data[2];
391 *redrv_val = cpu_to_be16(val);
392
393 /* Calculate 1 byte checksum */
394 csum = 0;
395 for (i = 0; i < 4; i++) {
396 csum += redrv_data[i];
397 if (redrv_data[i] > csum)
398 csum++;
399 }
400 redrv_data[4] = ~csum;
401
402 retry = 1;
403again1:
404 i2c_op.cmd = XGBE_I2C_CMD_WRITE;
405 i2c_op.target = phy_data->redrv_addr;
406 i2c_op.len = sizeof(redrv_data);
407 i2c_op.buf = redrv_data;
408 ret = xgbe_phy_i2c_xfer(pdata, &i2c_op);
409 if (ret) {
410 if ((ret == -EAGAIN) && retry--)
411 goto again1;
412
413 return ret;
414 }
415
416 retry = 1;
417again2:
418 i2c_op.cmd = XGBE_I2C_CMD_READ;
419 i2c_op.target = phy_data->redrv_addr;
420 i2c_op.len = 1;
421 i2c_op.buf = redrv_data;
422 ret = xgbe_phy_i2c_xfer(pdata, &i2c_op);
423 if (ret) {
424 if ((ret == -EAGAIN) && retry--)
425 goto again2;
426
427 return ret;
428 }
429
430 if (redrv_data[0] != 0xff) {
431 netif_dbg(pdata, drv, pdata->netdev,
432 "Redriver write checksum error\n");
433 ret = -EIO;
434 }
435
436 return ret;
437}
438
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -0600439static int xgbe_phy_i2c_write(struct xgbe_prv_data *pdata, unsigned int target,
440 void *val, unsigned int val_len)
441{
442 struct xgbe_i2c_op i2c_op;
443 int retry, ret;
444
445 retry = 1;
446again:
447 /* Write the specfied register */
448 i2c_op.cmd = XGBE_I2C_CMD_WRITE;
449 i2c_op.target = target;
450 i2c_op.len = val_len;
451 i2c_op.buf = val;
452 ret = xgbe_phy_i2c_xfer(pdata, &i2c_op);
453 if ((ret == -EAGAIN) && retry--)
454 goto again;
455
456 return ret;
457}
458
459static int xgbe_phy_i2c_read(struct xgbe_prv_data *pdata, unsigned int target,
460 void *reg, unsigned int reg_len,
461 void *val, unsigned int val_len)
462{
463 struct xgbe_i2c_op i2c_op;
464 int retry, ret;
465
466 retry = 1;
467again1:
468 /* Set the specified register to read */
469 i2c_op.cmd = XGBE_I2C_CMD_WRITE;
470 i2c_op.target = target;
471 i2c_op.len = reg_len;
472 i2c_op.buf = reg;
473 ret = xgbe_phy_i2c_xfer(pdata, &i2c_op);
474 if (ret) {
475 if ((ret == -EAGAIN) && retry--)
476 goto again1;
477
478 return ret;
479 }
480
481 retry = 1;
482again2:
483 /* Read the specfied register */
484 i2c_op.cmd = XGBE_I2C_CMD_READ;
485 i2c_op.target = target;
486 i2c_op.len = val_len;
487 i2c_op.buf = val;
488 ret = xgbe_phy_i2c_xfer(pdata, &i2c_op);
489 if ((ret == -EAGAIN) && retry--)
490 goto again2;
491
492 return ret;
493}
494
495static int xgbe_phy_sfp_put_mux(struct xgbe_prv_data *pdata)
496{
497 struct xgbe_phy_data *phy_data = pdata->phy_data;
498 struct xgbe_i2c_op i2c_op;
499 u8 mux_channel;
500
501 if (phy_data->sfp_comm == XGBE_SFP_COMM_DIRECT)
502 return 0;
503
504 /* Select no mux channels */
505 mux_channel = 0;
506 i2c_op.cmd = XGBE_I2C_CMD_WRITE;
507 i2c_op.target = phy_data->sfp_mux_address;
508 i2c_op.len = sizeof(mux_channel);
509 i2c_op.buf = &mux_channel;
510
511 return xgbe_phy_i2c_xfer(pdata, &i2c_op);
512}
513
514static int xgbe_phy_sfp_get_mux(struct xgbe_prv_data *pdata)
515{
516 struct xgbe_phy_data *phy_data = pdata->phy_data;
517 struct xgbe_i2c_op i2c_op;
518 u8 mux_channel;
519
520 if (phy_data->sfp_comm == XGBE_SFP_COMM_DIRECT)
521 return 0;
522
523 /* Select desired mux channel */
524 mux_channel = 1 << phy_data->sfp_mux_channel;
525 i2c_op.cmd = XGBE_I2C_CMD_WRITE;
526 i2c_op.target = phy_data->sfp_mux_address;
527 i2c_op.len = sizeof(mux_channel);
528 i2c_op.buf = &mux_channel;
529
530 return xgbe_phy_i2c_xfer(pdata, &i2c_op);
531}
532
533static void xgbe_phy_put_comm_ownership(struct xgbe_prv_data *pdata)
534{
535 struct xgbe_phy_data *phy_data = pdata->phy_data;
536
537 phy_data->comm_owned = 0;
538
539 mutex_unlock(&xgbe_phy_comm_lock);
540}
541
542static int xgbe_phy_get_comm_ownership(struct xgbe_prv_data *pdata)
543{
544 struct xgbe_phy_data *phy_data = pdata->phy_data;
545 unsigned long timeout;
546 unsigned int mutex_id;
547
548 if (phy_data->comm_owned)
549 return 0;
550
551 /* The I2C and MDIO/GPIO bus is multiplexed between multiple devices,
552 * the driver needs to take the software mutex and then the hardware
553 * mutexes before being able to use the busses.
554 */
555 mutex_lock(&xgbe_phy_comm_lock);
556
557 /* Clear the mutexes */
558 XP_IOWRITE(pdata, XP_I2C_MUTEX, XGBE_MUTEX_RELEASE);
559 XP_IOWRITE(pdata, XP_MDIO_MUTEX, XGBE_MUTEX_RELEASE);
560
561 /* Mutex formats are the same for I2C and MDIO/GPIO */
562 mutex_id = 0;
563 XP_SET_BITS(mutex_id, XP_I2C_MUTEX, ID, phy_data->port_id);
564 XP_SET_BITS(mutex_id, XP_I2C_MUTEX, ACTIVE, 1);
565
566 timeout = jiffies + (5 * HZ);
567 while (time_before(jiffies, timeout)) {
568 /* Must be all zeroes in order to obtain the mutex */
569 if (XP_IOREAD(pdata, XP_I2C_MUTEX) ||
570 XP_IOREAD(pdata, XP_MDIO_MUTEX)) {
571 usleep_range(100, 200);
572 continue;
573 }
574
575 /* Obtain the mutex */
576 XP_IOWRITE(pdata, XP_I2C_MUTEX, mutex_id);
577 XP_IOWRITE(pdata, XP_MDIO_MUTEX, mutex_id);
578
579 phy_data->comm_owned = 1;
580 return 0;
581 }
582
583 mutex_unlock(&xgbe_phy_comm_lock);
584
585 netdev_err(pdata->netdev, "unable to obtain hardware mutexes\n");
586
587 return -ETIMEDOUT;
588}
589
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -0600590static int xgbe_phy_mdio_mii_write(struct xgbe_prv_data *pdata, int addr,
591 int reg, u16 val)
592{
593 struct xgbe_phy_data *phy_data = pdata->phy_data;
594
595 if (reg & MII_ADDR_C45) {
596 if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL45)
597 return -ENOTSUPP;
598 } else {
599 if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL22)
600 return -ENOTSUPP;
601 }
602
603 return pdata->hw_if.write_ext_mii_regs(pdata, addr, reg, val);
604}
605
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -0600606static int xgbe_phy_i2c_mii_write(struct xgbe_prv_data *pdata, int reg, u16 val)
607{
608 __be16 *mii_val;
609 u8 mii_data[3];
610 int ret;
611
612 ret = xgbe_phy_sfp_get_mux(pdata);
613 if (ret)
614 return ret;
615
616 mii_data[0] = reg & 0xff;
617 mii_val = (__be16 *)&mii_data[1];
618 *mii_val = cpu_to_be16(val);
619
620 ret = xgbe_phy_i2c_write(pdata, XGBE_SFP_PHY_ADDRESS,
621 mii_data, sizeof(mii_data));
622
623 xgbe_phy_sfp_put_mux(pdata);
624
625 return ret;
626}
627
628static int xgbe_phy_mii_write(struct mii_bus *mii, int addr, int reg, u16 val)
629{
630 struct xgbe_prv_data *pdata = mii->priv;
631 struct xgbe_phy_data *phy_data = pdata->phy_data;
632 int ret;
633
634 ret = xgbe_phy_get_comm_ownership(pdata);
635 if (ret)
636 return ret;
637
638 if (phy_data->conn_type == XGBE_CONN_TYPE_SFP)
639 ret = xgbe_phy_i2c_mii_write(pdata, reg, val);
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -0600640 else if (phy_data->conn_type & XGBE_CONN_TYPE_MDIO)
641 ret = xgbe_phy_mdio_mii_write(pdata, addr, reg, val);
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -0600642 else
643 ret = -ENOTSUPP;
644
645 xgbe_phy_put_comm_ownership(pdata);
646
647 return ret;
648}
649
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -0600650static int xgbe_phy_mdio_mii_read(struct xgbe_prv_data *pdata, int addr,
651 int reg)
652{
653 struct xgbe_phy_data *phy_data = pdata->phy_data;
654
655 if (reg & MII_ADDR_C45) {
656 if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL45)
657 return -ENOTSUPP;
658 } else {
659 if (phy_data->phydev_mode != XGBE_MDIO_MODE_CL22)
660 return -ENOTSUPP;
661 }
662
663 return pdata->hw_if.read_ext_mii_regs(pdata, addr, reg);
664}
665
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -0600666static int xgbe_phy_i2c_mii_read(struct xgbe_prv_data *pdata, int reg)
667{
668 __be16 mii_val;
669 u8 mii_reg;
670 int ret;
671
672 ret = xgbe_phy_sfp_get_mux(pdata);
673 if (ret)
674 return ret;
675
676 mii_reg = reg;
677 ret = xgbe_phy_i2c_read(pdata, XGBE_SFP_PHY_ADDRESS,
678 &mii_reg, sizeof(mii_reg),
679 &mii_val, sizeof(mii_val));
680 if (!ret)
681 ret = be16_to_cpu(mii_val);
682
683 xgbe_phy_sfp_put_mux(pdata);
684
685 return ret;
686}
687
688static int xgbe_phy_mii_read(struct mii_bus *mii, int addr, int reg)
689{
690 struct xgbe_prv_data *pdata = mii->priv;
691 struct xgbe_phy_data *phy_data = pdata->phy_data;
692 int ret;
693
694 ret = xgbe_phy_get_comm_ownership(pdata);
695 if (ret)
696 return ret;
697
698 if (phy_data->conn_type == XGBE_CONN_TYPE_SFP)
699 ret = xgbe_phy_i2c_mii_read(pdata, reg);
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -0600700 else if (phy_data->conn_type & XGBE_CONN_TYPE_MDIO)
701 ret = xgbe_phy_mdio_mii_read(pdata, addr, reg);
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -0600702 else
703 ret = -ENOTSUPP;
704
705 xgbe_phy_put_comm_ownership(pdata);
706
707 return ret;
708}
709
710static void xgbe_phy_sfp_phy_settings(struct xgbe_prv_data *pdata)
711{
712 struct xgbe_phy_data *phy_data = pdata->phy_data;
713
714 if (phy_data->sfp_mod_absent) {
715 pdata->phy.speed = SPEED_UNKNOWN;
716 pdata->phy.duplex = DUPLEX_UNKNOWN;
717 pdata->phy.autoneg = AUTONEG_ENABLE;
718 pdata->phy.advertising = pdata->phy.supported;
719 }
720
721 pdata->phy.advertising &= ~ADVERTISED_Autoneg;
722 pdata->phy.advertising &= ~ADVERTISED_TP;
723 pdata->phy.advertising &= ~ADVERTISED_FIBRE;
724 pdata->phy.advertising &= ~ADVERTISED_100baseT_Full;
725 pdata->phy.advertising &= ~ADVERTISED_1000baseT_Full;
726 pdata->phy.advertising &= ~ADVERTISED_10000baseT_Full;
727 pdata->phy.advertising &= ~ADVERTISED_10000baseR_FEC;
728
729 switch (phy_data->sfp_base) {
730 case XGBE_SFP_BASE_1000_T:
731 case XGBE_SFP_BASE_1000_SX:
732 case XGBE_SFP_BASE_1000_LX:
733 case XGBE_SFP_BASE_1000_CX:
734 pdata->phy.speed = SPEED_UNKNOWN;
735 pdata->phy.duplex = DUPLEX_UNKNOWN;
736 pdata->phy.autoneg = AUTONEG_ENABLE;
737 pdata->phy.advertising |= ADVERTISED_Autoneg;
738 break;
739 case XGBE_SFP_BASE_10000_SR:
740 case XGBE_SFP_BASE_10000_LR:
741 case XGBE_SFP_BASE_10000_LRM:
742 case XGBE_SFP_BASE_10000_ER:
743 case XGBE_SFP_BASE_10000_CR:
744 default:
745 pdata->phy.speed = SPEED_10000;
746 pdata->phy.duplex = DUPLEX_FULL;
747 pdata->phy.autoneg = AUTONEG_DISABLE;
748 break;
749 }
750
751 switch (phy_data->sfp_base) {
752 case XGBE_SFP_BASE_1000_T:
753 case XGBE_SFP_BASE_1000_CX:
754 case XGBE_SFP_BASE_10000_CR:
755 pdata->phy.advertising |= ADVERTISED_TP;
756 break;
757 default:
758 pdata->phy.advertising |= ADVERTISED_FIBRE;
759 }
760
761 switch (phy_data->sfp_speed) {
762 case XGBE_SFP_SPEED_100_1000:
763 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100)
764 pdata->phy.advertising |= ADVERTISED_100baseT_Full;
765 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
766 pdata->phy.advertising |= ADVERTISED_1000baseT_Full;
767 break;
768 case XGBE_SFP_SPEED_1000:
769 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
770 pdata->phy.advertising |= ADVERTISED_1000baseT_Full;
771 break;
772 case XGBE_SFP_SPEED_10000:
773 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000)
774 pdata->phy.advertising |= ADVERTISED_10000baseT_Full;
775 break;
776 default:
777 /* Choose the fastest supported speed */
778 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000)
779 pdata->phy.advertising |= ADVERTISED_10000baseT_Full;
780 else if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
781 pdata->phy.advertising |= ADVERTISED_1000baseT_Full;
782 else if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100)
783 pdata->phy.advertising |= ADVERTISED_100baseT_Full;
784 }
785}
786
787static bool xgbe_phy_sfp_bit_rate(struct xgbe_sfp_eeprom *sfp_eeprom,
788 enum xgbe_sfp_speed sfp_speed)
789{
790 u8 *sfp_base, min, max;
791
792 sfp_base = sfp_eeprom->base;
793
794 switch (sfp_speed) {
795 case XGBE_SFP_SPEED_1000:
796 min = XGBE_SFP_BASE_BR_1GBE_MIN;
797 max = XGBE_SFP_BASE_BR_1GBE_MAX;
798 break;
799 case XGBE_SFP_SPEED_10000:
800 min = XGBE_SFP_BASE_BR_10GBE_MIN;
801 max = XGBE_SFP_BASE_BR_10GBE_MAX;
802 break;
803 default:
804 return false;
805 }
806
807 return ((sfp_base[XGBE_SFP_BASE_BR] >= min) &&
808 (sfp_base[XGBE_SFP_BASE_BR] <= max));
809}
810
811static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata)
812{
813 struct xgbe_phy_data *phy_data = pdata->phy_data;
814
815 if (phy_data->phydev) {
816 phy_detach(phy_data->phydev);
817 phy_device_remove(phy_data->phydev);
818 phy_device_free(phy_data->phydev);
819 phy_data->phydev = NULL;
820 }
821}
822
823static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
824{
825 struct xgbe_phy_data *phy_data = pdata->phy_data;
826 unsigned int phy_id = phy_data->phydev->phy_id;
827
828 if ((phy_id & 0xfffffff0) != 0x01ff0cc0)
829 return false;
830
831 /* Enable Base-T AN */
832 phy_write(phy_data->phydev, 0x16, 0x0001);
833 phy_write(phy_data->phydev, 0x00, 0x9140);
834 phy_write(phy_data->phydev, 0x16, 0x0000);
835
836 /* Enable SGMII at 100Base-T/1000Base-T Full Duplex */
837 phy_write(phy_data->phydev, 0x1b, 0x9084);
838 phy_write(phy_data->phydev, 0x09, 0x0e00);
839 phy_write(phy_data->phydev, 0x00, 0x8140);
840 phy_write(phy_data->phydev, 0x04, 0x0d01);
841 phy_write(phy_data->phydev, 0x00, 0x9140);
842
843 phy_data->phydev->supported = PHY_GBIT_FEATURES;
844 phy_data->phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
845 phy_data->phydev->advertising = phy_data->phydev->supported;
846
847 netif_dbg(pdata, drv, pdata->netdev,
848 "Finisar PHY quirk in place\n");
849
850 return true;
851}
852
853static void xgbe_phy_external_phy_quirks(struct xgbe_prv_data *pdata)
854{
855 if (xgbe_phy_finisar_phy_quirks(pdata))
856 return;
857}
858
859static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata)
860{
861 struct xgbe_phy_data *phy_data = pdata->phy_data;
862 struct phy_device *phydev;
863 int ret;
864
865 /* If we already have a PHY, just return */
866 if (phy_data->phydev)
867 return 0;
868
869 /* Check for the use of an external PHY */
870 if (phy_data->phydev_mode == XGBE_MDIO_MODE_NONE)
871 return 0;
872
873 /* For SFP, only use an external PHY if available */
874 if ((phy_data->port_mode == XGBE_PORT_MODE_SFP) &&
875 !phy_data->sfp_phy_avail)
876 return 0;
877
878 /* Create and connect to the PHY device */
879 phydev = get_phy_device(phy_data->mii, phy_data->mdio_addr,
880 (phy_data->phydev_mode == XGBE_MDIO_MODE_CL45));
881 if (IS_ERR(phydev)) {
882 netdev_err(pdata->netdev, "get_phy_device failed\n");
883 return -ENODEV;
884 }
885 netif_dbg(pdata, drv, pdata->netdev, "external PHY id is %#010x\n",
886 phydev->phy_id);
887
888 /*TODO: If c45, add request_module based on one of the MMD ids? */
889
890 ret = phy_device_register(phydev);
891 if (ret) {
892 netdev_err(pdata->netdev, "phy_device_register failed\n");
893 phy_device_free(phydev);
894 return ret;
895 }
896
897 ret = phy_attach_direct(pdata->netdev, phydev, phydev->dev_flags,
898 PHY_INTERFACE_MODE_SGMII);
899 if (ret) {
900 netdev_err(pdata->netdev, "phy_attach_direct failed\n");
901 phy_device_remove(phydev);
902 phy_device_free(phydev);
903 return ret;
904 }
905 phy_data->phydev = phydev;
906
907 xgbe_phy_external_phy_quirks(pdata);
908 phydev->advertising &= pdata->phy.advertising;
909
910 phy_start_aneg(phy_data->phydev);
911
912 return 0;
913}
914
915static void xgbe_phy_sfp_external_phy(struct xgbe_prv_data *pdata)
916{
917 struct xgbe_phy_data *phy_data = pdata->phy_data;
918 int ret;
919
920 if (!phy_data->sfp_changed)
921 return;
922
923 phy_data->sfp_phy_avail = 0;
924
925 if (phy_data->sfp_base != XGBE_SFP_BASE_1000_T)
926 return;
927
928 /* Check access to the PHY by reading CTRL1 */
929 ret = xgbe_phy_i2c_mii_read(pdata, MII_BMCR);
930 if (ret < 0)
931 return;
932
933 /* Successfully accessed the PHY */
934 phy_data->sfp_phy_avail = 1;
935}
936
937static bool xgbe_phy_belfuse_parse_quirks(struct xgbe_prv_data *pdata)
938{
939 struct xgbe_phy_data *phy_data = pdata->phy_data;
940 struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
941
942 if (memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
943 XGBE_BEL_FUSE_VENDOR, XGBE_SFP_BASE_VENDOR_NAME_LEN))
944 return false;
945
946 if (!memcmp(&sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_PN],
947 XGBE_BEL_FUSE_PARTNO, XGBE_SFP_BASE_VENDOR_PN_LEN)) {
948 phy_data->sfp_base = XGBE_SFP_BASE_1000_SX;
949 phy_data->sfp_cable = XGBE_SFP_CABLE_ACTIVE;
950 phy_data->sfp_speed = XGBE_SFP_SPEED_1000;
951 if (phy_data->sfp_changed)
952 netif_dbg(pdata, drv, pdata->netdev,
953 "Bel-Fuse SFP quirk in place\n");
954 return true;
955 }
956
957 return false;
958}
959
960static bool xgbe_phy_sfp_parse_quirks(struct xgbe_prv_data *pdata)
961{
962 if (xgbe_phy_belfuse_parse_quirks(pdata))
963 return true;
964
965 return false;
966}
967
968static void xgbe_phy_sfp_parse_eeprom(struct xgbe_prv_data *pdata)
969{
970 struct xgbe_phy_data *phy_data = pdata->phy_data;
971 struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
972 u8 *sfp_base;
973
974 sfp_base = sfp_eeprom->base;
975
976 if (sfp_base[XGBE_SFP_BASE_ID] != XGBE_SFP_ID_SFP)
977 return;
978
979 if (sfp_base[XGBE_SFP_BASE_EXT_ID] != XGBE_SFP_EXT_ID_SFP)
980 return;
981
982 if (xgbe_phy_sfp_parse_quirks(pdata))
983 return;
984
985 /* Assume ACTIVE cable unless told it is PASSIVE */
986 if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_PASSIVE) {
987 phy_data->sfp_cable = XGBE_SFP_CABLE_PASSIVE;
988 phy_data->sfp_cable_len = sfp_base[XGBE_SFP_BASE_CU_CABLE_LEN];
989 } else {
990 phy_data->sfp_cable = XGBE_SFP_CABLE_ACTIVE;
991 }
992
993 /* Determine the type of SFP */
994 if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR)
995 phy_data->sfp_base = XGBE_SFP_BASE_10000_SR;
996 else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_LR)
997 phy_data->sfp_base = XGBE_SFP_BASE_10000_LR;
998 else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_LRM)
999 phy_data->sfp_base = XGBE_SFP_BASE_10000_LRM;
1000 else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_ER)
1001 phy_data->sfp_base = XGBE_SFP_BASE_10000_ER;
1002 else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_SX)
1003 phy_data->sfp_base = XGBE_SFP_BASE_1000_SX;
1004 else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_LX)
1005 phy_data->sfp_base = XGBE_SFP_BASE_1000_LX;
1006 else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_CX)
1007 phy_data->sfp_base = XGBE_SFP_BASE_1000_CX;
1008 else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_T)
1009 phy_data->sfp_base = XGBE_SFP_BASE_1000_T;
1010 else if ((phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE) &&
1011 xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000))
1012 phy_data->sfp_base = XGBE_SFP_BASE_10000_CR;
1013
1014 switch (phy_data->sfp_base) {
1015 case XGBE_SFP_BASE_1000_T:
1016 phy_data->sfp_speed = XGBE_SFP_SPEED_100_1000;
1017 break;
1018 case XGBE_SFP_BASE_1000_SX:
1019 case XGBE_SFP_BASE_1000_LX:
1020 case XGBE_SFP_BASE_1000_CX:
1021 phy_data->sfp_speed = XGBE_SFP_SPEED_1000;
1022 break;
1023 case XGBE_SFP_BASE_10000_SR:
1024 case XGBE_SFP_BASE_10000_LR:
1025 case XGBE_SFP_BASE_10000_LRM:
1026 case XGBE_SFP_BASE_10000_ER:
1027 case XGBE_SFP_BASE_10000_CR:
1028 phy_data->sfp_speed = XGBE_SFP_SPEED_10000;
1029 break;
1030 default:
1031 break;
1032 }
1033}
1034
1035static void xgbe_phy_sfp_eeprom_info(struct xgbe_prv_data *pdata,
1036 struct xgbe_sfp_eeprom *sfp_eeprom)
1037{
1038 struct xgbe_sfp_ascii sfp_ascii;
1039 char *sfp_data = (char *)&sfp_ascii;
1040
1041 netif_dbg(pdata, drv, pdata->netdev, "SFP detected:\n");
1042 memcpy(sfp_data, &sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_NAME],
1043 XGBE_SFP_BASE_VENDOR_NAME_LEN);
1044 sfp_data[XGBE_SFP_BASE_VENDOR_NAME_LEN] = '\0';
1045 netif_dbg(pdata, drv, pdata->netdev, " vendor: %s\n",
1046 sfp_data);
1047
1048 memcpy(sfp_data, &sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_PN],
1049 XGBE_SFP_BASE_VENDOR_PN_LEN);
1050 sfp_data[XGBE_SFP_BASE_VENDOR_PN_LEN] = '\0';
1051 netif_dbg(pdata, drv, pdata->netdev, " part number: %s\n",
1052 sfp_data);
1053
1054 memcpy(sfp_data, &sfp_eeprom->base[XGBE_SFP_BASE_VENDOR_REV],
1055 XGBE_SFP_BASE_VENDOR_REV_LEN);
1056 sfp_data[XGBE_SFP_BASE_VENDOR_REV_LEN] = '\0';
1057 netif_dbg(pdata, drv, pdata->netdev, " revision level: %s\n",
1058 sfp_data);
1059
1060 memcpy(sfp_data, &sfp_eeprom->extd[XGBE_SFP_BASE_VENDOR_SN],
1061 XGBE_SFP_BASE_VENDOR_SN_LEN);
1062 sfp_data[XGBE_SFP_BASE_VENDOR_SN_LEN] = '\0';
1063 netif_dbg(pdata, drv, pdata->netdev, " serial number: %s\n",
1064 sfp_data);
1065}
1066
1067static bool xgbe_phy_sfp_verify_eeprom(u8 cc_in, u8 *buf, unsigned int len)
1068{
1069 u8 cc;
1070
1071 for (cc = 0; len; buf++, len--)
1072 cc += *buf;
1073
1074 return (cc == cc_in) ? true : false;
1075}
1076
1077static int xgbe_phy_sfp_read_eeprom(struct xgbe_prv_data *pdata)
1078{
1079 struct xgbe_phy_data *phy_data = pdata->phy_data;
1080 struct xgbe_sfp_eeprom sfp_eeprom;
1081 u8 eeprom_addr;
1082 int ret;
1083
1084 ret = xgbe_phy_sfp_get_mux(pdata);
1085 if (ret) {
1086 netdev_err(pdata->netdev, "I2C error setting SFP MUX\n");
1087 return ret;
1088 }
1089
1090 /* Read the SFP serial ID eeprom */
1091 eeprom_addr = 0;
1092 ret = xgbe_phy_i2c_read(pdata, XGBE_SFP_SERIAL_ID_ADDRESS,
1093 &eeprom_addr, sizeof(eeprom_addr),
1094 &sfp_eeprom, sizeof(sfp_eeprom));
1095 if (ret) {
1096 netdev_err(pdata->netdev, "I2C error reading SFP EEPROM\n");
1097 goto put;
1098 }
1099
1100 /* Validate the contents read */
1101 if (!xgbe_phy_sfp_verify_eeprom(sfp_eeprom.base[XGBE_SFP_BASE_CC],
1102 sfp_eeprom.base,
1103 sizeof(sfp_eeprom.base) - 1)) {
1104 ret = -EINVAL;
1105 goto put;
1106 }
1107
1108 if (!xgbe_phy_sfp_verify_eeprom(sfp_eeprom.extd[XGBE_SFP_EXTD_CC],
1109 sfp_eeprom.extd,
1110 sizeof(sfp_eeprom.extd) - 1)) {
1111 ret = -EINVAL;
1112 goto put;
1113 }
1114
1115 /* Check for an added or changed SFP */
1116 if (memcmp(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom))) {
1117 phy_data->sfp_changed = 1;
1118
1119 if (netif_msg_drv(pdata))
1120 xgbe_phy_sfp_eeprom_info(pdata, &sfp_eeprom);
1121
1122 memcpy(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom));
1123
1124 if (sfp_eeprom.extd[XGBE_SFP_EXTD_SFF_8472]) {
1125 u8 diag_type = sfp_eeprom.extd[XGBE_SFP_EXTD_DIAG];
1126
1127 if (!(diag_type & XGBE_SFP_EXTD_DIAG_ADDR_CHANGE))
1128 phy_data->sfp_diags = 1;
1129 }
1130
1131 xgbe_phy_free_phy_device(pdata);
1132 } else {
1133 phy_data->sfp_changed = 0;
1134 }
1135
1136put:
1137 xgbe_phy_sfp_put_mux(pdata);
1138
1139 return ret;
1140}
1141
1142static void xgbe_phy_sfp_signals(struct xgbe_prv_data *pdata)
1143{
1144 struct xgbe_phy_data *phy_data = pdata->phy_data;
1145 unsigned int gpio_input;
1146 u8 gpio_reg, gpio_ports[2];
1147 int ret;
1148
1149 /* Read the input port registers */
1150 gpio_reg = 0;
1151 ret = xgbe_phy_i2c_read(pdata, phy_data->sfp_gpio_address,
1152 &gpio_reg, sizeof(gpio_reg),
1153 gpio_ports, sizeof(gpio_ports));
1154 if (ret) {
1155 netdev_err(pdata->netdev, "I2C error reading SFP GPIOs\n");
1156 return;
1157 }
1158
1159 gpio_input = (gpio_ports[1] << 8) | gpio_ports[0];
1160
1161 if (phy_data->sfp_gpio_mask & XGBE_GPIO_NO_MOD_ABSENT) {
1162 /* No GPIO, just assume the module is present for now */
1163 phy_data->sfp_mod_absent = 0;
1164 } else {
1165 if (!(gpio_input & (1 << phy_data->sfp_gpio_mod_absent)))
1166 phy_data->sfp_mod_absent = 0;
1167 }
1168
1169 if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_RX_LOS) &&
1170 (gpio_input & (1 << phy_data->sfp_gpio_rx_los)))
1171 phy_data->sfp_rx_los = 1;
1172
1173 if (!(phy_data->sfp_gpio_mask & XGBE_GPIO_NO_TX_FAULT) &&
1174 (gpio_input & (1 << phy_data->sfp_gpio_tx_fault)))
1175 phy_data->sfp_tx_fault = 1;
1176}
1177
1178static void xgbe_phy_sfp_mod_absent(struct xgbe_prv_data *pdata)
1179{
1180 struct xgbe_phy_data *phy_data = pdata->phy_data;
1181
1182 xgbe_phy_free_phy_device(pdata);
1183
1184 phy_data->sfp_mod_absent = 1;
1185 phy_data->sfp_phy_avail = 0;
1186 memset(&phy_data->sfp_eeprom, 0, sizeof(phy_data->sfp_eeprom));
1187}
1188
1189static void xgbe_phy_sfp_reset(struct xgbe_phy_data *phy_data)
1190{
1191 phy_data->sfp_rx_los = 0;
1192 phy_data->sfp_tx_fault = 0;
1193 phy_data->sfp_mod_absent = 1;
1194 phy_data->sfp_diags = 0;
1195 phy_data->sfp_base = XGBE_SFP_BASE_UNKNOWN;
1196 phy_data->sfp_cable = XGBE_SFP_CABLE_UNKNOWN;
1197 phy_data->sfp_speed = XGBE_SFP_SPEED_UNKNOWN;
1198}
1199
1200static void xgbe_phy_sfp_detect(struct xgbe_prv_data *pdata)
1201{
1202 struct xgbe_phy_data *phy_data = pdata->phy_data;
1203 int ret;
1204
1205 /* Reset the SFP signals and info */
1206 xgbe_phy_sfp_reset(phy_data);
1207
1208 ret = xgbe_phy_get_comm_ownership(pdata);
1209 if (ret)
1210 return;
1211
1212 /* Read the SFP signals and check for module presence */
1213 xgbe_phy_sfp_signals(pdata);
1214 if (phy_data->sfp_mod_absent) {
1215 xgbe_phy_sfp_mod_absent(pdata);
1216 goto put;
1217 }
1218
1219 ret = xgbe_phy_sfp_read_eeprom(pdata);
1220 if (ret) {
1221 /* Treat any error as if there isn't an SFP plugged in */
1222 xgbe_phy_sfp_reset(phy_data);
1223 xgbe_phy_sfp_mod_absent(pdata);
1224 goto put;
1225 }
1226
1227 xgbe_phy_sfp_parse_eeprom(pdata);
1228
1229 xgbe_phy_sfp_external_phy(pdata);
1230
1231put:
1232 xgbe_phy_sfp_phy_settings(pdata);
1233
1234 xgbe_phy_put_comm_ownership(pdata);
1235}
1236
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001237static void xgbe_phy_phydev_flowctrl(struct xgbe_prv_data *pdata)
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001238{
1239 struct xgbe_phy_data *phy_data = pdata->phy_data;
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001240 u16 lcl_adv = 0, rmt_adv = 0;
1241 u8 fc;
1242
1243 pdata->phy.tx_pause = 0;
1244 pdata->phy.rx_pause = 0;
1245
1246 if (!phy_data->phydev)
1247 return;
1248
1249 if (phy_data->phydev->advertising & ADVERTISED_Pause)
1250 lcl_adv |= ADVERTISE_PAUSE_CAP;
1251 if (phy_data->phydev->advertising & ADVERTISED_Asym_Pause)
1252 lcl_adv |= ADVERTISE_PAUSE_ASYM;
1253
1254 if (phy_data->phydev->pause) {
1255 pdata->phy.lp_advertising |= ADVERTISED_Pause;
1256 rmt_adv |= LPA_PAUSE_CAP;
1257 }
1258 if (phy_data->phydev->asym_pause) {
1259 pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause;
1260 rmt_adv |= LPA_PAUSE_ASYM;
1261 }
1262
1263 fc = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
1264 if (fc & FLOW_CTRL_TX)
1265 pdata->phy.tx_pause = 1;
1266 if (fc & FLOW_CTRL_RX)
1267 pdata->phy.rx_pause = 1;
1268}
1269
1270static enum xgbe_mode xgbe_phy_an37_sgmii_outcome(struct xgbe_prv_data *pdata)
1271{
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001272 enum xgbe_mode mode;
1273
1274 pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
1275 pdata->phy.lp_advertising |= ADVERTISED_TP;
1276
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001277 /* Use external PHY to determine flow control */
1278 if (pdata->phy.pause_autoneg)
1279 xgbe_phy_phydev_flowctrl(pdata);
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001280
1281 switch (pdata->an_status & XGBE_SGMII_AN_LINK_SPEED) {
1282 case XGBE_SGMII_AN_LINK_SPEED_100:
1283 if (pdata->an_status & XGBE_SGMII_AN_LINK_DUPLEX) {
1284 pdata->phy.lp_advertising |= ADVERTISED_100baseT_Full;
1285 mode = XGBE_MODE_SGMII_100;
1286 } else {
1287 /* Half-duplex not supported */
1288 pdata->phy.lp_advertising |= ADVERTISED_100baseT_Half;
1289 mode = XGBE_MODE_UNKNOWN;
1290 }
1291 break;
1292 case XGBE_SGMII_AN_LINK_SPEED_1000:
1293 if (pdata->an_status & XGBE_SGMII_AN_LINK_DUPLEX) {
1294 pdata->phy.lp_advertising |= ADVERTISED_1000baseT_Full;
1295 mode = XGBE_MODE_SGMII_1000;
1296 } else {
1297 /* Half-duplex not supported */
1298 pdata->phy.lp_advertising |= ADVERTISED_1000baseT_Half;
1299 mode = XGBE_MODE_UNKNOWN;
1300 }
1301 break;
1302 default:
1303 mode = XGBE_MODE_UNKNOWN;
1304 }
1305
1306 return mode;
1307}
1308
1309static enum xgbe_mode xgbe_phy_an37_outcome(struct xgbe_prv_data *pdata)
1310{
1311 enum xgbe_mode mode;
1312 unsigned int ad_reg, lp_reg;
1313
1314 pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
1315 pdata->phy.lp_advertising |= ADVERTISED_FIBRE;
1316
1317 /* Compare Advertisement and Link Partner register */
1318 ad_reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_ADVERTISE);
1319 lp_reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_VEND2_AN_LP_ABILITY);
1320 if (lp_reg & 0x100)
1321 pdata->phy.lp_advertising |= ADVERTISED_Pause;
1322 if (lp_reg & 0x80)
1323 pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause;
1324
1325 if (pdata->phy.pause_autoneg) {
1326 /* Set flow control based on auto-negotiation result */
1327 pdata->phy.tx_pause = 0;
1328 pdata->phy.rx_pause = 0;
1329
1330 if (ad_reg & lp_reg & 0x100) {
1331 pdata->phy.tx_pause = 1;
1332 pdata->phy.rx_pause = 1;
1333 } else if (ad_reg & lp_reg & 0x80) {
1334 if (ad_reg & 0x100)
1335 pdata->phy.rx_pause = 1;
1336 else if (lp_reg & 0x100)
1337 pdata->phy.tx_pause = 1;
1338 }
1339 }
1340
1341 if (lp_reg & 0x40)
1342 pdata->phy.lp_advertising |= ADVERTISED_1000baseT_Half;
1343 if (lp_reg & 0x20)
1344 pdata->phy.lp_advertising |= ADVERTISED_1000baseT_Full;
1345
1346 /* Half duplex is not supported */
1347 ad_reg &= lp_reg;
1348 mode = (ad_reg & 0x20) ? XGBE_MODE_X : XGBE_MODE_UNKNOWN;
1349
1350 return mode;
1351}
1352
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001353static enum xgbe_mode xgbe_phy_an73_redrv_outcome(struct xgbe_prv_data *pdata)
1354{
1355 struct xgbe_phy_data *phy_data = pdata->phy_data;
1356 enum xgbe_mode mode;
1357 unsigned int ad_reg, lp_reg;
1358
1359 pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
1360 pdata->phy.lp_advertising |= ADVERTISED_Backplane;
1361
1362 /* Use external PHY to determine flow control */
1363 if (pdata->phy.pause_autoneg)
1364 xgbe_phy_phydev_flowctrl(pdata);
1365
1366 /* Compare Advertisement and Link Partner register 2 */
1367 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
1368 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
1369 if (lp_reg & 0x80)
1370 pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full;
1371 if (lp_reg & 0x20)
1372 pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full;
1373
1374 ad_reg &= lp_reg;
1375 if (ad_reg & 0x80) {
1376 switch (phy_data->port_mode) {
1377 case XGBE_PORT_MODE_BACKPLANE:
1378 mode = XGBE_MODE_KR;
1379 break;
1380 default:
1381 mode = XGBE_MODE_SFI;
1382 break;
1383 }
1384 } else if (ad_reg & 0x20) {
1385 switch (phy_data->port_mode) {
1386 case XGBE_PORT_MODE_BACKPLANE:
1387 mode = XGBE_MODE_KX_1000;
1388 break;
1389 case XGBE_PORT_MODE_1000BASE_X:
1390 mode = XGBE_MODE_X;
1391 break;
1392 case XGBE_PORT_MODE_SFP:
1393 switch (phy_data->sfp_base) {
1394 case XGBE_SFP_BASE_1000_T:
1395 if (phy_data->phydev &&
1396 (phy_data->phydev->speed == SPEED_100))
1397 mode = XGBE_MODE_SGMII_100;
1398 else
1399 mode = XGBE_MODE_SGMII_1000;
1400 break;
1401 case XGBE_SFP_BASE_1000_SX:
1402 case XGBE_SFP_BASE_1000_LX:
1403 case XGBE_SFP_BASE_1000_CX:
1404 default:
1405 mode = XGBE_MODE_X;
1406 break;
1407 }
1408 break;
1409 default:
1410 if (phy_data->phydev &&
1411 (phy_data->phydev->speed == SPEED_100))
1412 mode = XGBE_MODE_SGMII_100;
1413 else
1414 mode = XGBE_MODE_SGMII_1000;
1415 break;
1416 }
1417 } else {
1418 mode = XGBE_MODE_UNKNOWN;
1419 }
1420
1421 /* Compare Advertisement and Link Partner register 3 */
1422 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
1423 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
1424 if (lp_reg & 0xc000)
1425 pdata->phy.lp_advertising |= ADVERTISED_10000baseR_FEC;
1426
1427 return mode;
1428}
1429
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001430static enum xgbe_mode xgbe_phy_an73_outcome(struct xgbe_prv_data *pdata)
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001431{
1432 enum xgbe_mode mode;
1433 unsigned int ad_reg, lp_reg;
1434
1435 pdata->phy.lp_advertising |= ADVERTISED_Autoneg;
1436 pdata->phy.lp_advertising |= ADVERTISED_Backplane;
1437
1438 /* Compare Advertisement and Link Partner register 1 */
1439 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
1440 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);
1441 if (lp_reg & 0x400)
1442 pdata->phy.lp_advertising |= ADVERTISED_Pause;
1443 if (lp_reg & 0x800)
1444 pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause;
1445
1446 if (pdata->phy.pause_autoneg) {
1447 /* Set flow control based on auto-negotiation result */
1448 pdata->phy.tx_pause = 0;
1449 pdata->phy.rx_pause = 0;
1450
1451 if (ad_reg & lp_reg & 0x400) {
1452 pdata->phy.tx_pause = 1;
1453 pdata->phy.rx_pause = 1;
1454 } else if (ad_reg & lp_reg & 0x800) {
1455 if (ad_reg & 0x400)
1456 pdata->phy.rx_pause = 1;
1457 else if (lp_reg & 0x400)
1458 pdata->phy.tx_pause = 1;
1459 }
1460 }
1461
1462 /* Compare Advertisement and Link Partner register 2 */
1463 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1);
1464 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 1);
1465 if (lp_reg & 0x80)
1466 pdata->phy.lp_advertising |= ADVERTISED_10000baseKR_Full;
1467 if (lp_reg & 0x20)
1468 pdata->phy.lp_advertising |= ADVERTISED_1000baseKX_Full;
1469
1470 ad_reg &= lp_reg;
1471 if (ad_reg & 0x80)
1472 mode = XGBE_MODE_KR;
1473 else if (ad_reg & 0x20)
1474 mode = XGBE_MODE_KX_1000;
1475 else
1476 mode = XGBE_MODE_UNKNOWN;
1477
1478 /* Compare Advertisement and Link Partner register 3 */
1479 ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 2);
1480 lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA + 2);
1481 if (lp_reg & 0xc000)
1482 pdata->phy.lp_advertising |= ADVERTISED_10000baseR_FEC;
1483
1484 return mode;
1485}
1486
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001487static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata)
1488{
1489 switch (pdata->an_mode) {
1490 case XGBE_AN_MODE_CL73:
1491 return xgbe_phy_an73_outcome(pdata);
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001492 case XGBE_AN_MODE_CL73_REDRV:
1493 return xgbe_phy_an73_redrv_outcome(pdata);
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001494 case XGBE_AN_MODE_CL37:
1495 return xgbe_phy_an37_outcome(pdata);
1496 case XGBE_AN_MODE_CL37_SGMII:
1497 return xgbe_phy_an37_sgmii_outcome(pdata);
1498 default:
1499 return XGBE_MODE_UNKNOWN;
1500 }
1501}
1502
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001503static unsigned int xgbe_phy_an_advertising(struct xgbe_prv_data *pdata)
1504{
1505 struct xgbe_phy_data *phy_data = pdata->phy_data;
1506 unsigned int advertising;
1507
1508 /* Without a re-driver, just return current advertising */
1509 if (!phy_data->redrv)
1510 return pdata->phy.advertising;
1511
1512 /* With the KR re-driver we need to advertise a single speed */
1513 advertising = pdata->phy.advertising;
1514 advertising &= ~ADVERTISED_1000baseKX_Full;
1515 advertising &= ~ADVERTISED_10000baseKR_Full;
1516
1517 switch (phy_data->port_mode) {
1518 case XGBE_PORT_MODE_BACKPLANE:
1519 advertising |= ADVERTISED_10000baseKR_Full;
1520 break;
1521 case XGBE_PORT_MODE_BACKPLANE_2500:
1522 advertising |= ADVERTISED_1000baseKX_Full;
1523 break;
1524 case XGBE_PORT_MODE_1000BASE_T:
1525 case XGBE_PORT_MODE_1000BASE_X:
1526 case XGBE_PORT_MODE_NBASE_T:
1527 advertising |= ADVERTISED_1000baseKX_Full;
1528 break;
1529 case XGBE_PORT_MODE_10GBASE_T:
1530 if (phy_data->phydev &&
1531 (phy_data->phydev->speed == SPEED_10000))
1532 advertising |= ADVERTISED_10000baseKR_Full;
1533 else
1534 advertising |= ADVERTISED_1000baseKX_Full;
1535 break;
1536 case XGBE_PORT_MODE_10GBASE_R:
1537 advertising |= ADVERTISED_10000baseKR_Full;
1538 break;
1539 case XGBE_PORT_MODE_SFP:
1540 switch (phy_data->sfp_base) {
1541 case XGBE_SFP_BASE_1000_T:
1542 case XGBE_SFP_BASE_1000_SX:
1543 case XGBE_SFP_BASE_1000_LX:
1544 case XGBE_SFP_BASE_1000_CX:
1545 advertising |= ADVERTISED_1000baseKX_Full;
1546 break;
1547 default:
1548 advertising |= ADVERTISED_10000baseKR_Full;
1549 break;
1550 }
1551 break;
1552 default:
1553 advertising |= ADVERTISED_10000baseKR_Full;
1554 break;
1555 }
1556
1557 return advertising;
1558}
1559
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001560static int xgbe_phy_an_config(struct xgbe_prv_data *pdata)
1561{
1562 struct xgbe_phy_data *phy_data = pdata->phy_data;
1563 int ret;
1564
1565 ret = xgbe_phy_find_phy_device(pdata);
1566 if (ret)
1567 return ret;
1568
1569 if (!phy_data->phydev)
1570 return 0;
1571
1572 phy_data->phydev->autoneg = pdata->phy.autoneg;
1573 phy_data->phydev->advertising = phy_data->phydev->supported &
1574 pdata->phy.advertising;
1575
1576 if (pdata->phy.autoneg != AUTONEG_ENABLE) {
1577 phy_data->phydev->speed = pdata->phy.speed;
1578 phy_data->phydev->duplex = pdata->phy.duplex;
1579 }
1580
1581 ret = phy_start_aneg(phy_data->phydev);
1582
1583 return ret;
1584}
1585
1586static enum xgbe_an_mode xgbe_phy_an_sfp_mode(struct xgbe_phy_data *phy_data)
1587{
1588 switch (phy_data->sfp_base) {
1589 case XGBE_SFP_BASE_1000_T:
1590 return XGBE_AN_MODE_CL37_SGMII;
1591 case XGBE_SFP_BASE_1000_SX:
1592 case XGBE_SFP_BASE_1000_LX:
1593 case XGBE_SFP_BASE_1000_CX:
1594 return XGBE_AN_MODE_CL37;
1595 default:
1596 return XGBE_AN_MODE_NONE;
1597 }
1598}
1599
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001600static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata)
1601{
1602 struct xgbe_phy_data *phy_data = pdata->phy_data;
1603
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001604 /* A KR re-driver will always require CL73 AN */
1605 if (phy_data->redrv)
1606 return XGBE_AN_MODE_CL73_REDRV;
1607
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001608 switch (phy_data->port_mode) {
1609 case XGBE_PORT_MODE_BACKPLANE:
1610 return XGBE_AN_MODE_CL73;
1611 case XGBE_PORT_MODE_BACKPLANE_2500:
1612 return XGBE_AN_MODE_NONE;
1613 case XGBE_PORT_MODE_1000BASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06001614 return XGBE_AN_MODE_CL37_SGMII;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001615 case XGBE_PORT_MODE_1000BASE_X:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06001616 return XGBE_AN_MODE_CL37;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001617 case XGBE_PORT_MODE_NBASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06001618 return XGBE_AN_MODE_CL37_SGMII;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001619 case XGBE_PORT_MODE_10GBASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06001620 return XGBE_AN_MODE_CL73;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001621 case XGBE_PORT_MODE_10GBASE_R:
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001622 return XGBE_AN_MODE_NONE;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001623 case XGBE_PORT_MODE_SFP:
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001624 return xgbe_phy_an_sfp_mode(phy_data);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001625 default:
1626 return XGBE_AN_MODE_NONE;
1627 }
1628}
1629
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001630static int xgbe_phy_set_redrv_mode_mdio(struct xgbe_prv_data *pdata,
1631 enum xgbe_phy_redrv_mode mode)
1632{
1633 struct xgbe_phy_data *phy_data = pdata->phy_data;
1634 u16 redrv_reg, redrv_val;
1635
1636 redrv_reg = XGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000);
1637 redrv_val = (u16)mode;
1638
1639 return pdata->hw_if.write_ext_mii_regs(pdata, phy_data->redrv_addr,
1640 redrv_reg, redrv_val);
1641}
1642
1643static int xgbe_phy_set_redrv_mode_i2c(struct xgbe_prv_data *pdata,
1644 enum xgbe_phy_redrv_mode mode)
1645{
1646 struct xgbe_phy_data *phy_data = pdata->phy_data;
1647 unsigned int redrv_reg;
1648 int ret;
1649
1650 /* Calculate the register to write */
1651 redrv_reg = XGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000);
1652
1653 ret = xgbe_phy_redrv_write(pdata, redrv_reg, mode);
1654
1655 return ret;
1656}
1657
1658static void xgbe_phy_set_redrv_mode(struct xgbe_prv_data *pdata)
1659{
1660 struct xgbe_phy_data *phy_data = pdata->phy_data;
1661 enum xgbe_phy_redrv_mode mode;
1662 int ret;
1663
1664 if (!phy_data->redrv)
1665 return;
1666
1667 mode = XGBE_PHY_REDRV_MODE_CX;
1668 if ((phy_data->port_mode == XGBE_PORT_MODE_SFP) &&
1669 (phy_data->sfp_base != XGBE_SFP_BASE_1000_CX) &&
1670 (phy_data->sfp_base != XGBE_SFP_BASE_10000_CR))
1671 mode = XGBE_PHY_REDRV_MODE_SR;
1672
1673 ret = xgbe_phy_get_comm_ownership(pdata);
1674 if (ret)
1675 return;
1676
1677 if (phy_data->redrv_if)
1678 xgbe_phy_set_redrv_mode_i2c(pdata, mode);
1679 else
1680 xgbe_phy_set_redrv_mode_mdio(pdata, mode);
1681
1682 xgbe_phy_put_comm_ownership(pdata);
1683}
1684
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001685static void xgbe_phy_start_ratechange(struct xgbe_prv_data *pdata)
1686{
1687 if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
1688 return;
1689
1690 /* Log if a previous command did not complete */
1691 netif_dbg(pdata, link, pdata->netdev,
1692 "firmware mailbox not ready for command\n");
1693}
1694
1695static void xgbe_phy_complete_ratechange(struct xgbe_prv_data *pdata)
1696{
1697 unsigned int wait;
1698
1699 /* Wait for command to complete */
1700 wait = XGBE_RATECHANGE_COUNT;
1701 while (wait--) {
1702 if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
1703 return;
1704
1705 usleep_range(1000, 2000);
1706 }
1707
1708 netif_dbg(pdata, link, pdata->netdev,
1709 "firmware mailbox command did not complete\n");
1710}
1711
1712static void xgbe_phy_rrc(struct xgbe_prv_data *pdata)
1713{
1714 unsigned int s0;
1715
1716 xgbe_phy_start_ratechange(pdata);
1717
1718 /* Receiver Reset Cycle */
1719 s0 = 0;
1720 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 5);
1721 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0);
1722
1723 /* Call FW to make the change */
1724 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1725 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1726 XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1727
1728 xgbe_phy_complete_ratechange(pdata);
1729
1730 netif_dbg(pdata, link, pdata->netdev, "receiver reset complete\n");
1731}
1732
1733static void xgbe_phy_power_off(struct xgbe_prv_data *pdata)
1734{
1735 struct xgbe_phy_data *phy_data = pdata->phy_data;
1736
1737 xgbe_phy_start_ratechange(pdata);
1738
1739 /* Call FW to make the change */
1740 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, 0);
1741 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1742 XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1743
1744 xgbe_phy_complete_ratechange(pdata);
1745
1746 phy_data->cur_mode = XGBE_MODE_UNKNOWN;
1747
1748 netif_dbg(pdata, link, pdata->netdev, "phy powered off\n");
1749}
1750
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001751static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata)
1752{
1753 struct xgbe_phy_data *phy_data = pdata->phy_data;
1754 unsigned int s0;
1755
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001756 xgbe_phy_set_redrv_mode(pdata);
1757
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001758 xgbe_phy_start_ratechange(pdata);
1759
1760 /* 10G/SFI */
1761 s0 = 0;
1762 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 3);
1763 if (phy_data->sfp_cable != XGBE_SFP_CABLE_PASSIVE) {
1764 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0);
1765 } else {
1766 if (phy_data->sfp_cable_len <= 1)
1767 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 1);
1768 else if (phy_data->sfp_cable_len <= 3)
1769 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 2);
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001770 else
1771 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 3);
1772 }
1773
1774 /* Call FW to make the change */
1775 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1776 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1777 XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1778
1779 xgbe_phy_complete_ratechange(pdata);
1780
1781 phy_data->cur_mode = XGBE_MODE_SFI;
1782
1783 netif_dbg(pdata, link, pdata->netdev, "10GbE SFI mode set\n");
1784}
1785
1786static void xgbe_phy_x_mode(struct xgbe_prv_data *pdata)
1787{
1788 struct xgbe_phy_data *phy_data = pdata->phy_data;
1789 unsigned int s0;
1790
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001791 xgbe_phy_set_redrv_mode(pdata);
1792
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001793 xgbe_phy_start_ratechange(pdata);
1794
1795 /* 1G/X */
1796 s0 = 0;
1797 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 1);
1798 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 3);
1799
1800 /* Call FW to make the change */
1801 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1802 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1803 XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1804
1805 xgbe_phy_complete_ratechange(pdata);
1806
1807 phy_data->cur_mode = XGBE_MODE_X;
1808
1809 netif_dbg(pdata, link, pdata->netdev, "1GbE X mode set\n");
1810}
1811
1812static void xgbe_phy_sgmii_1000_mode(struct xgbe_prv_data *pdata)
1813{
1814 struct xgbe_phy_data *phy_data = pdata->phy_data;
1815 unsigned int s0;
1816
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001817 xgbe_phy_set_redrv_mode(pdata);
1818
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001819 xgbe_phy_start_ratechange(pdata);
1820
1821 /* 1G/SGMII */
1822 s0 = 0;
1823 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 1);
1824 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 2);
1825
1826 /* Call FW to make the change */
1827 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1828 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1829 XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1830
1831 xgbe_phy_complete_ratechange(pdata);
1832
1833 phy_data->cur_mode = XGBE_MODE_SGMII_1000;
1834
1835 netif_dbg(pdata, link, pdata->netdev, "1GbE SGMII mode set\n");
1836}
1837
1838static void xgbe_phy_sgmii_100_mode(struct xgbe_prv_data *pdata)
1839{
1840 struct xgbe_phy_data *phy_data = pdata->phy_data;
1841 unsigned int s0;
1842
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001843 xgbe_phy_set_redrv_mode(pdata);
1844
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06001845 xgbe_phy_start_ratechange(pdata);
1846
1847 /* 1G/SGMII */
1848 s0 = 0;
1849 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 1);
1850 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 1);
1851
1852 /* Call FW to make the change */
1853 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1854 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1855 XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1856
1857 xgbe_phy_complete_ratechange(pdata);
1858
1859 phy_data->cur_mode = XGBE_MODE_SGMII_100;
1860
1861 netif_dbg(pdata, link, pdata->netdev, "100MbE SGMII mode set\n");
1862}
1863
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001864static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata)
1865{
1866 struct xgbe_phy_data *phy_data = pdata->phy_data;
1867 unsigned int s0;
1868
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001869 xgbe_phy_set_redrv_mode(pdata);
1870
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001871 xgbe_phy_start_ratechange(pdata);
1872
1873 /* 10G/KR */
1874 s0 = 0;
1875 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 4);
1876 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0);
1877
1878 /* Call FW to make the change */
1879 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1880 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1881 XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1882
1883 xgbe_phy_complete_ratechange(pdata);
1884
1885 phy_data->cur_mode = XGBE_MODE_KR;
1886
1887 netif_dbg(pdata, link, pdata->netdev, "10GbE KR mode set\n");
1888}
1889
1890static void xgbe_phy_kx_2500_mode(struct xgbe_prv_data *pdata)
1891{
1892 struct xgbe_phy_data *phy_data = pdata->phy_data;
1893 unsigned int s0;
1894
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001895 xgbe_phy_set_redrv_mode(pdata);
1896
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001897 xgbe_phy_start_ratechange(pdata);
1898
1899 /* 2.5G/KX */
1900 s0 = 0;
1901 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 2);
1902 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 0);
1903
1904 /* Call FW to make the change */
1905 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1906 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1907 XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1908
1909 xgbe_phy_complete_ratechange(pdata);
1910
1911 phy_data->cur_mode = XGBE_MODE_KX_2500;
1912
1913 netif_dbg(pdata, link, pdata->netdev, "2.5GbE KX mode set\n");
1914}
1915
1916static void xgbe_phy_kx_1000_mode(struct xgbe_prv_data *pdata)
1917{
1918 struct xgbe_phy_data *phy_data = pdata->phy_data;
1919 unsigned int s0;
1920
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06001921 xgbe_phy_set_redrv_mode(pdata);
1922
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001923 xgbe_phy_start_ratechange(pdata);
1924
1925 /* 1G/KX */
1926 s0 = 0;
1927 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, 1);
1928 XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, SUB_COMMAND, 3);
1929
1930 /* Call FW to make the change */
1931 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_0, s0);
1932 XP_IOWRITE(pdata, XP_DRIVER_SCRATCH_1, 0);
1933 XP_IOWRITE_BITS(pdata, XP_DRIVER_INT_REQ, REQUEST, 1);
1934
1935 xgbe_phy_complete_ratechange(pdata);
1936
1937 phy_data->cur_mode = XGBE_MODE_KX_1000;
1938
1939 netif_dbg(pdata, link, pdata->netdev, "1GbE KX mode set\n");
1940}
1941
1942static enum xgbe_mode xgbe_phy_cur_mode(struct xgbe_prv_data *pdata)
1943{
1944 struct xgbe_phy_data *phy_data = pdata->phy_data;
1945
1946 return phy_data->cur_mode;
1947}
1948
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06001949static enum xgbe_mode xgbe_phy_switch_baset_mode(struct xgbe_prv_data *pdata)
1950{
1951 struct xgbe_phy_data *phy_data = pdata->phy_data;
1952
1953 /* No switching if not 10GBase-T */
1954 if (phy_data->port_mode != XGBE_PORT_MODE_10GBASE_T)
1955 return xgbe_phy_cur_mode(pdata);
1956
1957 switch (xgbe_phy_cur_mode(pdata)) {
1958 case XGBE_MODE_SGMII_100:
1959 case XGBE_MODE_SGMII_1000:
1960 return XGBE_MODE_KR;
1961 case XGBE_MODE_KR:
1962 default:
1963 return XGBE_MODE_SGMII_1000;
1964 }
1965}
1966
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001967static enum xgbe_mode xgbe_phy_switch_bp_2500_mode(struct xgbe_prv_data *pdata)
1968{
1969 return XGBE_MODE_KX_2500;
1970}
1971
1972static enum xgbe_mode xgbe_phy_switch_bp_mode(struct xgbe_prv_data *pdata)
1973{
1974 /* If we are in KR switch to KX, and vice-versa */
1975 switch (xgbe_phy_cur_mode(pdata)) {
1976 case XGBE_MODE_KX_1000:
1977 return XGBE_MODE_KR;
1978 case XGBE_MODE_KR:
1979 default:
1980 return XGBE_MODE_KX_1000;
1981 }
1982}
1983
1984static enum xgbe_mode xgbe_phy_switch_mode(struct xgbe_prv_data *pdata)
1985{
1986 struct xgbe_phy_data *phy_data = pdata->phy_data;
1987
1988 switch (phy_data->port_mode) {
1989 case XGBE_PORT_MODE_BACKPLANE:
1990 return xgbe_phy_switch_bp_mode(pdata);
1991 case XGBE_PORT_MODE_BACKPLANE_2500:
1992 return xgbe_phy_switch_bp_2500_mode(pdata);
1993 case XGBE_PORT_MODE_1000BASE_T:
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001994 case XGBE_PORT_MODE_NBASE_T:
1995 case XGBE_PORT_MODE_10GBASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06001996 return xgbe_phy_switch_baset_mode(pdata);
1997 case XGBE_PORT_MODE_1000BASE_X:
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06001998 case XGBE_PORT_MODE_10GBASE_R:
1999 case XGBE_PORT_MODE_SFP:
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002000 /* No switching, so just return current mode */
2001 return xgbe_phy_cur_mode(pdata);
2002 default:
2003 return XGBE_MODE_UNKNOWN;
2004 }
2005}
2006
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002007static enum xgbe_mode xgbe_phy_get_basex_mode(struct xgbe_phy_data *phy_data,
2008 int speed)
2009{
2010 switch (speed) {
2011 case SPEED_1000:
2012 return XGBE_MODE_X;
2013 case SPEED_10000:
2014 return XGBE_MODE_KR;
2015 default:
2016 return XGBE_MODE_UNKNOWN;
2017 }
2018}
2019
2020static enum xgbe_mode xgbe_phy_get_baset_mode(struct xgbe_phy_data *phy_data,
2021 int speed)
2022{
2023 switch (speed) {
2024 case SPEED_100:
2025 return XGBE_MODE_SGMII_100;
2026 case SPEED_1000:
2027 return XGBE_MODE_SGMII_1000;
2028 case SPEED_10000:
2029 return XGBE_MODE_KR;
2030 default:
2031 return XGBE_MODE_UNKNOWN;
2032 }
2033}
2034
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002035static enum xgbe_mode xgbe_phy_get_sfp_mode(struct xgbe_phy_data *phy_data,
2036 int speed)
2037{
2038 switch (speed) {
2039 case SPEED_100:
2040 return XGBE_MODE_SGMII_100;
2041 case SPEED_1000:
2042 if (phy_data->sfp_base == XGBE_SFP_BASE_1000_T)
2043 return XGBE_MODE_SGMII_1000;
2044 else
2045 return XGBE_MODE_X;
2046 case SPEED_10000:
2047 case SPEED_UNKNOWN:
2048 return XGBE_MODE_SFI;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002049 default:
2050 return XGBE_MODE_UNKNOWN;
2051 }
2052}
2053
2054static enum xgbe_mode xgbe_phy_get_bp_2500_mode(int speed)
2055{
2056 switch (speed) {
2057 case SPEED_2500:
2058 return XGBE_MODE_KX_2500;
2059 default:
2060 return XGBE_MODE_UNKNOWN;
2061 }
2062}
2063
2064static enum xgbe_mode xgbe_phy_get_bp_mode(int speed)
2065{
2066 switch (speed) {
2067 case SPEED_1000:
2068 return XGBE_MODE_KX_1000;
2069 case SPEED_10000:
2070 return XGBE_MODE_KR;
2071 default:
2072 return XGBE_MODE_UNKNOWN;
2073 }
2074}
2075
2076static enum xgbe_mode xgbe_phy_get_mode(struct xgbe_prv_data *pdata,
2077 int speed)
2078{
2079 struct xgbe_phy_data *phy_data = pdata->phy_data;
2080
2081 switch (phy_data->port_mode) {
2082 case XGBE_PORT_MODE_BACKPLANE:
2083 return xgbe_phy_get_bp_mode(speed);
2084 case XGBE_PORT_MODE_BACKPLANE_2500:
2085 return xgbe_phy_get_bp_2500_mode(speed);
2086 case XGBE_PORT_MODE_1000BASE_T:
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002087 case XGBE_PORT_MODE_NBASE_T:
2088 case XGBE_PORT_MODE_10GBASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002089 return xgbe_phy_get_baset_mode(phy_data, speed);
2090 case XGBE_PORT_MODE_1000BASE_X:
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002091 case XGBE_PORT_MODE_10GBASE_R:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002092 return xgbe_phy_get_basex_mode(phy_data, speed);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002093 case XGBE_PORT_MODE_SFP:
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002094 return xgbe_phy_get_sfp_mode(phy_data, speed);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002095 default:
2096 return XGBE_MODE_UNKNOWN;
2097 }
2098}
2099
2100static void xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
2101{
2102 switch (mode) {
2103 case XGBE_MODE_KX_1000:
2104 xgbe_phy_kx_1000_mode(pdata);
2105 break;
2106 case XGBE_MODE_KX_2500:
2107 xgbe_phy_kx_2500_mode(pdata);
2108 break;
2109 case XGBE_MODE_KR:
2110 xgbe_phy_kr_mode(pdata);
2111 break;
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002112 case XGBE_MODE_SGMII_100:
2113 xgbe_phy_sgmii_100_mode(pdata);
2114 break;
2115 case XGBE_MODE_SGMII_1000:
2116 xgbe_phy_sgmii_1000_mode(pdata);
2117 break;
2118 case XGBE_MODE_X:
2119 xgbe_phy_x_mode(pdata);
2120 break;
2121 case XGBE_MODE_SFI:
2122 xgbe_phy_sfi_mode(pdata);
2123 break;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002124 default:
2125 break;
2126 }
2127}
2128
2129static bool xgbe_phy_check_mode(struct xgbe_prv_data *pdata,
2130 enum xgbe_mode mode, u32 advert)
2131{
2132 if (pdata->phy.autoneg == AUTONEG_ENABLE) {
2133 if (pdata->phy.advertising & advert)
2134 return true;
2135 } else {
2136 enum xgbe_mode cur_mode;
2137
2138 cur_mode = xgbe_phy_get_mode(pdata, pdata->phy.speed);
2139 if (cur_mode == mode)
2140 return true;
2141 }
2142
2143 return false;
2144}
2145
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002146static bool xgbe_phy_use_basex_mode(struct xgbe_prv_data *pdata,
2147 enum xgbe_mode mode)
2148{
2149 switch (mode) {
2150 case XGBE_MODE_X:
2151 return xgbe_phy_check_mode(pdata, mode,
2152 ADVERTISED_1000baseT_Full);
2153 case XGBE_MODE_KR:
2154 return xgbe_phy_check_mode(pdata, mode,
2155 ADVERTISED_10000baseT_Full);
2156 default:
2157 return false;
2158 }
2159}
2160
2161static bool xgbe_phy_use_baset_mode(struct xgbe_prv_data *pdata,
2162 enum xgbe_mode mode)
2163{
2164 switch (mode) {
2165 case XGBE_MODE_SGMII_100:
2166 return xgbe_phy_check_mode(pdata, mode,
2167 ADVERTISED_100baseT_Full);
2168 case XGBE_MODE_SGMII_1000:
2169 return xgbe_phy_check_mode(pdata, mode,
2170 ADVERTISED_1000baseT_Full);
2171 case XGBE_MODE_KR:
2172 return xgbe_phy_check_mode(pdata, mode,
2173 ADVERTISED_10000baseT_Full);
2174 default:
2175 return false;
2176 }
2177}
2178
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002179static bool xgbe_phy_use_sfp_mode(struct xgbe_prv_data *pdata,
2180 enum xgbe_mode mode)
2181{
2182 struct xgbe_phy_data *phy_data = pdata->phy_data;
2183
2184 switch (mode) {
2185 case XGBE_MODE_X:
2186 if (phy_data->sfp_base == XGBE_SFP_BASE_1000_T)
2187 return false;
2188 return xgbe_phy_check_mode(pdata, mode,
2189 ADVERTISED_1000baseT_Full);
2190 case XGBE_MODE_SGMII_100:
2191 if (phy_data->sfp_base != XGBE_SFP_BASE_1000_T)
2192 return false;
2193 return xgbe_phy_check_mode(pdata, mode,
2194 ADVERTISED_100baseT_Full);
2195 case XGBE_MODE_SGMII_1000:
2196 if (phy_data->sfp_base != XGBE_SFP_BASE_1000_T)
2197 return false;
2198 return xgbe_phy_check_mode(pdata, mode,
2199 ADVERTISED_1000baseT_Full);
2200 case XGBE_MODE_SFI:
2201 return xgbe_phy_check_mode(pdata, mode,
2202 ADVERTISED_10000baseT_Full);
2203 default:
2204 return false;
2205 }
2206}
2207
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002208static bool xgbe_phy_use_bp_2500_mode(struct xgbe_prv_data *pdata,
2209 enum xgbe_mode mode)
2210{
2211 switch (mode) {
2212 case XGBE_MODE_KX_2500:
2213 return xgbe_phy_check_mode(pdata, mode,
2214 ADVERTISED_2500baseX_Full);
2215 default:
2216 return false;
2217 }
2218}
2219
2220static bool xgbe_phy_use_bp_mode(struct xgbe_prv_data *pdata,
2221 enum xgbe_mode mode)
2222{
2223 switch (mode) {
2224 case XGBE_MODE_KX_1000:
2225 return xgbe_phy_check_mode(pdata, mode,
2226 ADVERTISED_1000baseKX_Full);
2227 case XGBE_MODE_KR:
2228 return xgbe_phy_check_mode(pdata, mode,
2229 ADVERTISED_10000baseKR_Full);
2230 default:
2231 return false;
2232 }
2233}
2234
2235static bool xgbe_phy_use_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
2236{
2237 struct xgbe_phy_data *phy_data = pdata->phy_data;
2238
2239 switch (phy_data->port_mode) {
2240 case XGBE_PORT_MODE_BACKPLANE:
2241 return xgbe_phy_use_bp_mode(pdata, mode);
2242 case XGBE_PORT_MODE_BACKPLANE_2500:
2243 return xgbe_phy_use_bp_2500_mode(pdata, mode);
2244 case XGBE_PORT_MODE_1000BASE_T:
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002245 case XGBE_PORT_MODE_NBASE_T:
2246 case XGBE_PORT_MODE_10GBASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002247 return xgbe_phy_use_baset_mode(pdata, mode);
2248 case XGBE_PORT_MODE_1000BASE_X:
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002249 case XGBE_PORT_MODE_10GBASE_R:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002250 return xgbe_phy_use_basex_mode(pdata, mode);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002251 case XGBE_PORT_MODE_SFP:
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002252 return xgbe_phy_use_sfp_mode(pdata, mode);
2253 default:
2254 return false;
2255 }
2256}
2257
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002258static bool xgbe_phy_valid_speed_basex_mode(struct xgbe_phy_data *phy_data,
2259 int speed)
2260{
2261 switch (speed) {
2262 case SPEED_1000:
2263 return (phy_data->port_mode == XGBE_PORT_MODE_1000BASE_X);
2264 case SPEED_10000:
2265 return (phy_data->port_mode == XGBE_PORT_MODE_10GBASE_R);
2266 default:
2267 return false;
2268 }
2269}
2270
2271static bool xgbe_phy_valid_speed_baset_mode(struct xgbe_phy_data *phy_data,
2272 int speed)
2273{
2274 switch (speed) {
2275 case SPEED_100:
2276 case SPEED_1000:
2277 return true;
2278 case SPEED_10000:
2279 return (phy_data->port_mode == XGBE_PORT_MODE_10GBASE_T);
2280 default:
2281 return false;
2282 }
2283}
2284
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002285static bool xgbe_phy_valid_speed_sfp_mode(struct xgbe_phy_data *phy_data,
2286 int speed)
2287{
2288 switch (speed) {
2289 case SPEED_100:
2290 return (phy_data->sfp_speed == XGBE_SFP_SPEED_100_1000);
2291 case SPEED_1000:
2292 return ((phy_data->sfp_speed == XGBE_SFP_SPEED_100_1000) ||
2293 (phy_data->sfp_speed == XGBE_SFP_SPEED_1000));
2294 case SPEED_10000:
2295 return (phy_data->sfp_speed == XGBE_SFP_SPEED_10000);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002296 default:
2297 return false;
2298 }
2299}
2300
2301static bool xgbe_phy_valid_speed_bp_2500_mode(int speed)
2302{
2303 switch (speed) {
2304 case SPEED_2500:
2305 return true;
2306 default:
2307 return false;
2308 }
2309}
2310
2311static bool xgbe_phy_valid_speed_bp_mode(int speed)
2312{
2313 switch (speed) {
2314 case SPEED_1000:
2315 case SPEED_10000:
2316 return true;
2317 default:
2318 return false;
2319 }
2320}
2321
2322static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
2323{
2324 struct xgbe_phy_data *phy_data = pdata->phy_data;
2325
2326 switch (phy_data->port_mode) {
2327 case XGBE_PORT_MODE_BACKPLANE:
2328 return xgbe_phy_valid_speed_bp_mode(speed);
2329 case XGBE_PORT_MODE_BACKPLANE_2500:
2330 return xgbe_phy_valid_speed_bp_2500_mode(speed);
2331 case XGBE_PORT_MODE_1000BASE_T:
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002332 case XGBE_PORT_MODE_NBASE_T:
2333 case XGBE_PORT_MODE_10GBASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002334 return xgbe_phy_valid_speed_baset_mode(phy_data, speed);
2335 case XGBE_PORT_MODE_1000BASE_X:
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002336 case XGBE_PORT_MODE_10GBASE_R:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002337 return xgbe_phy_valid_speed_basex_mode(phy_data, speed);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002338 case XGBE_PORT_MODE_SFP:
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002339 return xgbe_phy_valid_speed_sfp_mode(phy_data, speed);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002340 default:
2341 return false;
2342 }
2343}
2344
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002345static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002346{
2347 struct xgbe_phy_data *phy_data = pdata->phy_data;
Lendacky, Thomas8c5385c2016-11-14 16:39:16 -06002348 unsigned int reg;
2349 int ret;
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002350
2351 *an_restart = 0;
2352
2353 if (phy_data->port_mode == XGBE_PORT_MODE_SFP) {
2354 /* Check SFP signals */
2355 xgbe_phy_sfp_detect(pdata);
2356
2357 if (phy_data->sfp_changed) {
2358 *an_restart = 1;
2359 return 0;
2360 }
2361
2362 if (phy_data->sfp_mod_absent || phy_data->sfp_rx_los)
2363 return 0;
2364 }
2365
2366 if (phy_data->phydev) {
2367 /* Check external PHY */
2368 ret = phy_read_status(phy_data->phydev);
2369 if (ret < 0)
2370 return 0;
2371
2372 if ((pdata->phy.autoneg == AUTONEG_ENABLE) &&
2373 !phy_aneg_done(phy_data->phydev))
2374 return 0;
2375
2376 if (!phy_data->phydev->link)
2377 return 0;
2378 }
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002379
2380 /* Link status is latched low, so read once to clear
2381 * and then read again to get current state
2382 */
2383 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
2384 reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
2385 if (reg & MDIO_STAT1_LSTATUS)
2386 return 1;
2387
2388 /* No link, attempt a receiver reset cycle */
2389 if (phy_data->rrc_count++) {
2390 phy_data->rrc_count = 0;
2391 xgbe_phy_rrc(pdata);
2392 }
2393
2394 return 0;
2395}
2396
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002397static void xgbe_phy_sfp_gpio_setup(struct xgbe_prv_data *pdata)
2398{
2399 struct xgbe_phy_data *phy_data = pdata->phy_data;
2400 unsigned int reg;
2401
2402 reg = XP_IOREAD(pdata, XP_PROP_3);
2403
2404 phy_data->sfp_gpio_address = XGBE_GPIO_ADDRESS_PCA9555 +
2405 XP_GET_BITS(reg, XP_PROP_3, GPIO_ADDR);
2406
2407 phy_data->sfp_gpio_mask = XP_GET_BITS(reg, XP_PROP_3, GPIO_MASK);
2408
2409 phy_data->sfp_gpio_rx_los = XP_GET_BITS(reg, XP_PROP_3,
2410 GPIO_RX_LOS);
2411 phy_data->sfp_gpio_tx_fault = XP_GET_BITS(reg, XP_PROP_3,
2412 GPIO_TX_FAULT);
2413 phy_data->sfp_gpio_mod_absent = XP_GET_BITS(reg, XP_PROP_3,
2414 GPIO_MOD_ABS);
2415 phy_data->sfp_gpio_rate_select = XP_GET_BITS(reg, XP_PROP_3,
2416 GPIO_RATE_SELECT);
2417
2418 if (netif_msg_probe(pdata)) {
2419 dev_dbg(pdata->dev, "SFP: gpio_address=%#x\n",
2420 phy_data->sfp_gpio_address);
2421 dev_dbg(pdata->dev, "SFP: gpio_mask=%#x\n",
2422 phy_data->sfp_gpio_mask);
2423 dev_dbg(pdata->dev, "SFP: gpio_rx_los=%u\n",
2424 phy_data->sfp_gpio_rx_los);
2425 dev_dbg(pdata->dev, "SFP: gpio_tx_fault=%u\n",
2426 phy_data->sfp_gpio_tx_fault);
2427 dev_dbg(pdata->dev, "SFP: gpio_mod_absent=%u\n",
2428 phy_data->sfp_gpio_mod_absent);
2429 dev_dbg(pdata->dev, "SFP: gpio_rate_select=%u\n",
2430 phy_data->sfp_gpio_rate_select);
2431 }
2432}
2433
2434static void xgbe_phy_sfp_comm_setup(struct xgbe_prv_data *pdata)
2435{
2436 struct xgbe_phy_data *phy_data = pdata->phy_data;
2437 unsigned int reg, mux_addr_hi, mux_addr_lo;
2438
2439 reg = XP_IOREAD(pdata, XP_PROP_4);
2440
2441 mux_addr_hi = XP_GET_BITS(reg, XP_PROP_4, MUX_ADDR_HI);
2442 mux_addr_lo = XP_GET_BITS(reg, XP_PROP_4, MUX_ADDR_LO);
2443 if (mux_addr_lo == XGBE_SFP_DIRECT)
2444 return;
2445
2446 phy_data->sfp_comm = XGBE_SFP_COMM_PCA9545;
2447 phy_data->sfp_mux_address = (mux_addr_hi << 2) + mux_addr_lo;
2448 phy_data->sfp_mux_channel = XP_GET_BITS(reg, XP_PROP_4, MUX_CHAN);
2449
2450 if (netif_msg_probe(pdata)) {
2451 dev_dbg(pdata->dev, "SFP: mux_address=%#x\n",
2452 phy_data->sfp_mux_address);
2453 dev_dbg(pdata->dev, "SFP: mux_channel=%u\n",
2454 phy_data->sfp_mux_channel);
2455 }
2456}
2457
2458static void xgbe_phy_sfp_setup(struct xgbe_prv_data *pdata)
2459{
2460 xgbe_phy_sfp_comm_setup(pdata);
2461 xgbe_phy_sfp_gpio_setup(pdata);
2462}
2463
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002464static int xgbe_phy_int_mdio_reset(struct xgbe_prv_data *pdata)
2465{
2466 struct xgbe_phy_data *phy_data = pdata->phy_data;
2467 unsigned int ret;
2468
2469 ret = pdata->hw_if.set_gpio(pdata, phy_data->mdio_reset_gpio);
2470 if (ret)
2471 return ret;
2472
2473 ret = pdata->hw_if.clr_gpio(pdata, phy_data->mdio_reset_gpio);
2474
2475 return ret;
2476}
2477
2478static int xgbe_phy_i2c_mdio_reset(struct xgbe_prv_data *pdata)
2479{
2480 struct xgbe_phy_data *phy_data = pdata->phy_data;
2481 u8 gpio_reg, gpio_ports[2], gpio_data[3];
2482 int ret;
2483
2484 /* Read the output port registers */
2485 gpio_reg = 2;
2486 ret = xgbe_phy_i2c_read(pdata, phy_data->mdio_reset_addr,
2487 &gpio_reg, sizeof(gpio_reg),
2488 gpio_ports, sizeof(gpio_ports));
2489 if (ret)
2490 return ret;
2491
2492 /* Prepare to write the GPIO data */
2493 gpio_data[0] = 2;
2494 gpio_data[1] = gpio_ports[0];
2495 gpio_data[2] = gpio_ports[1];
2496
2497 /* Set the GPIO pin */
2498 if (phy_data->mdio_reset_gpio < 8)
2499 gpio_data[1] |= (1 << (phy_data->mdio_reset_gpio % 8));
2500 else
2501 gpio_data[2] |= (1 << (phy_data->mdio_reset_gpio % 8));
2502
2503 /* Write the output port registers */
2504 ret = xgbe_phy_i2c_write(pdata, phy_data->mdio_reset_addr,
2505 gpio_data, sizeof(gpio_data));
2506 if (ret)
2507 return ret;
2508
2509 /* Clear the GPIO pin */
2510 if (phy_data->mdio_reset_gpio < 8)
2511 gpio_data[1] &= ~(1 << (phy_data->mdio_reset_gpio % 8));
2512 else
2513 gpio_data[2] &= ~(1 << (phy_data->mdio_reset_gpio % 8));
2514
2515 /* Write the output port registers */
2516 ret = xgbe_phy_i2c_write(pdata, phy_data->mdio_reset_addr,
2517 gpio_data, sizeof(gpio_data));
2518
2519 return ret;
2520}
2521
2522static int xgbe_phy_mdio_reset(struct xgbe_prv_data *pdata)
2523{
2524 struct xgbe_phy_data *phy_data = pdata->phy_data;
2525 int ret;
2526
2527 if (phy_data->conn_type != XGBE_CONN_TYPE_MDIO)
2528 return 0;
2529
2530 ret = xgbe_phy_get_comm_ownership(pdata);
2531 if (ret)
2532 return ret;
2533
2534 if (phy_data->mdio_reset == XGBE_MDIO_RESET_I2C_GPIO)
2535 ret = xgbe_phy_i2c_mdio_reset(pdata);
2536 else if (phy_data->mdio_reset == XGBE_MDIO_RESET_INT_GPIO)
2537 ret = xgbe_phy_int_mdio_reset(pdata);
2538
2539 xgbe_phy_put_comm_ownership(pdata);
2540
2541 return ret;
2542}
2543
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06002544static bool xgbe_phy_redrv_error(struct xgbe_phy_data *phy_data)
2545{
2546 if (!phy_data->redrv)
2547 return false;
2548
2549 if (phy_data->redrv_if >= XGBE_PHY_REDRV_IF_MAX)
2550 return true;
2551
2552 switch (phy_data->redrv_model) {
2553 case XGBE_PHY_REDRV_MODEL_4223:
2554 if (phy_data->redrv_lane > 3)
2555 return true;
2556 break;
2557 case XGBE_PHY_REDRV_MODEL_4227:
2558 if (phy_data->redrv_lane > 1)
2559 return true;
2560 break;
2561 default:
2562 return true;
2563 }
2564
2565 return false;
2566}
2567
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002568static int xgbe_phy_mdio_reset_setup(struct xgbe_prv_data *pdata)
2569{
2570 struct xgbe_phy_data *phy_data = pdata->phy_data;
2571 unsigned int reg;
2572
2573 if (phy_data->conn_type != XGBE_CONN_TYPE_MDIO)
2574 return 0;
2575
2576 reg = XP_IOREAD(pdata, XP_PROP_3);
2577 phy_data->mdio_reset = XP_GET_BITS(reg, XP_PROP_3, MDIO_RESET);
2578 switch (phy_data->mdio_reset) {
2579 case XGBE_MDIO_RESET_NONE:
2580 case XGBE_MDIO_RESET_I2C_GPIO:
2581 case XGBE_MDIO_RESET_INT_GPIO:
2582 break;
2583 default:
2584 dev_err(pdata->dev, "unsupported MDIO reset (%#x)\n",
2585 phy_data->mdio_reset);
2586 return -EINVAL;
2587 }
2588
2589 if (phy_data->mdio_reset == XGBE_MDIO_RESET_I2C_GPIO) {
2590 phy_data->mdio_reset_addr = XGBE_GPIO_ADDRESS_PCA9555 +
2591 XP_GET_BITS(reg, XP_PROP_3,
2592 MDIO_RESET_I2C_ADDR);
2593 phy_data->mdio_reset_gpio = XP_GET_BITS(reg, XP_PROP_3,
2594 MDIO_RESET_I2C_GPIO);
2595 } else if (phy_data->mdio_reset == XGBE_MDIO_RESET_INT_GPIO) {
2596 phy_data->mdio_reset_gpio = XP_GET_BITS(reg, XP_PROP_3,
2597 MDIO_RESET_INT_GPIO);
2598 }
2599
2600 return 0;
2601}
2602
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002603static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata)
2604{
2605 struct xgbe_phy_data *phy_data = pdata->phy_data;
2606
2607 switch (phy_data->port_mode) {
2608 case XGBE_PORT_MODE_BACKPLANE:
2609 if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) ||
2610 (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000))
2611 return false;
2612 break;
2613 case XGBE_PORT_MODE_BACKPLANE_2500:
2614 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500)
2615 return false;
2616 break;
2617 case XGBE_PORT_MODE_1000BASE_T:
2618 if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
2619 (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000))
2620 return false;
2621 break;
2622 case XGBE_PORT_MODE_1000BASE_X:
2623 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
2624 return false;
2625 break;
2626 case XGBE_PORT_MODE_NBASE_T:
2627 if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
2628 (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) ||
2629 (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500))
2630 return false;
2631 break;
2632 case XGBE_PORT_MODE_10GBASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002633 if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
2634 (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) ||
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002635 (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000))
2636 return false;
2637 break;
2638 case XGBE_PORT_MODE_10GBASE_R:
2639 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000)
2640 return false;
2641 break;
2642 case XGBE_PORT_MODE_SFP:
2643 if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
2644 (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) ||
2645 (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000))
2646 return false;
2647 break;
2648 default:
2649 break;
2650 }
2651
2652 return true;
2653}
2654
2655static bool xgbe_phy_conn_type_mismatch(struct xgbe_prv_data *pdata)
2656{
2657 struct xgbe_phy_data *phy_data = pdata->phy_data;
2658
2659 switch (phy_data->port_mode) {
2660 case XGBE_PORT_MODE_BACKPLANE:
2661 case XGBE_PORT_MODE_BACKPLANE_2500:
2662 if (phy_data->conn_type == XGBE_CONN_TYPE_BACKPLANE)
2663 return false;
2664 break;
2665 case XGBE_PORT_MODE_1000BASE_T:
2666 case XGBE_PORT_MODE_1000BASE_X:
2667 case XGBE_PORT_MODE_NBASE_T:
2668 case XGBE_PORT_MODE_10GBASE_T:
2669 case XGBE_PORT_MODE_10GBASE_R:
2670 if (phy_data->conn_type == XGBE_CONN_TYPE_MDIO)
2671 return false;
2672 break;
2673 case XGBE_PORT_MODE_SFP:
2674 if (phy_data->conn_type == XGBE_CONN_TYPE_SFP)
2675 return false;
2676 break;
2677 default:
2678 break;
2679 }
2680
2681 return true;
2682}
2683
2684static bool xgbe_phy_port_enabled(struct xgbe_prv_data *pdata)
2685{
2686 unsigned int reg;
2687
2688 reg = XP_IOREAD(pdata, XP_PROP_0);
2689 if (!XP_GET_BITS(reg, XP_PROP_0, PORT_SPEEDS))
2690 return false;
2691 if (!XP_GET_BITS(reg, XP_PROP_0, CONN_TYPE))
2692 return false;
2693
2694 return true;
2695}
2696
2697static void xgbe_phy_stop(struct xgbe_prv_data *pdata)
2698{
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002699 struct xgbe_phy_data *phy_data = pdata->phy_data;
2700
2701 /* If we have an external PHY, free it */
2702 xgbe_phy_free_phy_device(pdata);
2703
2704 /* Reset SFP data */
2705 xgbe_phy_sfp_reset(phy_data);
2706 xgbe_phy_sfp_mod_absent(pdata);
2707
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002708 /* Power off the PHY */
2709 xgbe_phy_power_off(pdata);
Lendacky, Thomas5ab1dcd2016-11-10 17:10:36 -06002710
2711 /* Stop the I2C controller */
2712 pdata->i2c_if.i2c_stop(pdata);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002713}
2714
2715static int xgbe_phy_start(struct xgbe_prv_data *pdata)
2716{
2717 struct xgbe_phy_data *phy_data = pdata->phy_data;
Lendacky, Thomas5ab1dcd2016-11-10 17:10:36 -06002718 int ret;
2719
2720 /* Start the I2C controller */
2721 ret = pdata->i2c_if.i2c_start(pdata);
2722 if (ret)
2723 return ret;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002724
2725 /* Start in highest supported mode */
2726 xgbe_phy_set_mode(pdata, phy_data->start_mode);
2727
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002728 /* After starting the I2C controller, we can check for an SFP */
2729 switch (phy_data->port_mode) {
2730 case XGBE_PORT_MODE_SFP:
2731 xgbe_phy_sfp_detect(pdata);
2732 break;
2733 default:
2734 break;
2735 }
2736
2737 /* If we have an external PHY, start it */
2738 ret = xgbe_phy_find_phy_device(pdata);
2739 if (ret)
2740 goto err_i2c;
2741
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002742 return 0;
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002743
2744err_i2c:
2745 pdata->i2c_if.i2c_stop(pdata);
2746
2747 return ret;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002748}
2749
2750static int xgbe_phy_reset(struct xgbe_prv_data *pdata)
2751{
2752 struct xgbe_phy_data *phy_data = pdata->phy_data;
2753 enum xgbe_mode cur_mode;
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002754 int ret;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002755
2756 /* Reset by power cycling the PHY */
2757 cur_mode = phy_data->cur_mode;
2758 xgbe_phy_power_off(pdata);
2759 xgbe_phy_set_mode(pdata, cur_mode);
2760
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002761 if (!phy_data->phydev)
2762 return 0;
2763
2764 /* Reset the external PHY */
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002765 ret = xgbe_phy_mdio_reset(pdata);
2766 if (ret)
2767 return ret;
2768
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002769 return phy_init_hw(phy_data->phydev);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002770}
2771
2772static void xgbe_phy_exit(struct xgbe_prv_data *pdata)
2773{
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002774 struct xgbe_phy_data *phy_data = pdata->phy_data;
2775
2776 /* Unregister for driving external PHYs */
2777 mdiobus_unregister(phy_data->mii);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002778}
2779
2780static int xgbe_phy_init(struct xgbe_prv_data *pdata)
2781{
2782 struct xgbe_phy_data *phy_data;
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002783 struct mii_bus *mii;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002784 unsigned int reg;
Lendacky, Thomas5ab1dcd2016-11-10 17:10:36 -06002785 int ret;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002786
2787 /* Check if enabled */
2788 if (!xgbe_phy_port_enabled(pdata)) {
2789 dev_info(pdata->dev, "device is not enabled\n");
2790 return -ENODEV;
2791 }
2792
Lendacky, Thomas5ab1dcd2016-11-10 17:10:36 -06002793 /* Initialize the I2C controller */
2794 ret = pdata->i2c_if.i2c_init(pdata);
2795 if (ret)
2796 return ret;
2797
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002798 phy_data = devm_kzalloc(pdata->dev, sizeof(*phy_data), GFP_KERNEL);
2799 if (!phy_data)
2800 return -ENOMEM;
2801 pdata->phy_data = phy_data;
2802
2803 reg = XP_IOREAD(pdata, XP_PROP_0);
2804 phy_data->port_mode = XP_GET_BITS(reg, XP_PROP_0, PORT_MODE);
2805 phy_data->port_id = XP_GET_BITS(reg, XP_PROP_0, PORT_ID);
2806 phy_data->port_speeds = XP_GET_BITS(reg, XP_PROP_0, PORT_SPEEDS);
2807 phy_data->conn_type = XP_GET_BITS(reg, XP_PROP_0, CONN_TYPE);
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002808 phy_data->mdio_addr = XP_GET_BITS(reg, XP_PROP_0, MDIO_ADDR);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002809 if (netif_msg_probe(pdata)) {
2810 dev_dbg(pdata->dev, "port mode=%u\n", phy_data->port_mode);
2811 dev_dbg(pdata->dev, "port id=%u\n", phy_data->port_id);
2812 dev_dbg(pdata->dev, "port speeds=%#x\n", phy_data->port_speeds);
2813 dev_dbg(pdata->dev, "conn type=%u\n", phy_data->conn_type);
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002814 dev_dbg(pdata->dev, "mdio addr=%u\n", phy_data->mdio_addr);
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002815 }
2816
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06002817 reg = XP_IOREAD(pdata, XP_PROP_4);
2818 phy_data->redrv = XP_GET_BITS(reg, XP_PROP_4, REDRV_PRESENT);
2819 phy_data->redrv_if = XP_GET_BITS(reg, XP_PROP_4, REDRV_IF);
2820 phy_data->redrv_addr = XP_GET_BITS(reg, XP_PROP_4, REDRV_ADDR);
2821 phy_data->redrv_lane = XP_GET_BITS(reg, XP_PROP_4, REDRV_LANE);
2822 phy_data->redrv_model = XP_GET_BITS(reg, XP_PROP_4, REDRV_MODEL);
2823 if (phy_data->redrv && netif_msg_probe(pdata)) {
2824 dev_dbg(pdata->dev, "redrv present\n");
2825 dev_dbg(pdata->dev, "redrv i/f=%u\n", phy_data->redrv_if);
2826 dev_dbg(pdata->dev, "redrv addr=%#x\n", phy_data->redrv_addr);
2827 dev_dbg(pdata->dev, "redrv lane=%u\n", phy_data->redrv_lane);
2828 dev_dbg(pdata->dev, "redrv model=%u\n", phy_data->redrv_model);
2829 }
2830
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002831 /* Validate the connection requested */
2832 if (xgbe_phy_conn_type_mismatch(pdata)) {
2833 dev_err(pdata->dev, "phy mode/connection mismatch (%#x/%#x)\n",
2834 phy_data->port_mode, phy_data->conn_type);
Lendacky, Thomas5a4e4c82016-11-17 08:43:37 -06002835 return -EINVAL;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002836 }
2837
2838 /* Validate the mode requested */
2839 if (xgbe_phy_port_mode_mismatch(pdata)) {
2840 dev_err(pdata->dev, "phy mode/speed mismatch (%#x/%#x)\n",
2841 phy_data->port_mode, phy_data->port_speeds);
2842 return -EINVAL;
2843 }
2844
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002845 /* Check for and validate MDIO reset support */
2846 ret = xgbe_phy_mdio_reset_setup(pdata);
2847 if (ret)
2848 return ret;
2849
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06002850 /* Validate the re-driver information */
2851 if (xgbe_phy_redrv_error(phy_data)) {
2852 dev_err(pdata->dev, "phy re-driver settings error\n");
2853 return -EINVAL;
2854 }
2855 pdata->kr_redrv = phy_data->redrv;
2856
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002857 /* Indicate current mode is unknown */
2858 phy_data->cur_mode = XGBE_MODE_UNKNOWN;
2859
2860 /* Initialize supported features */
2861 pdata->phy.supported = 0;
2862
2863 switch (phy_data->port_mode) {
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002864 /* Backplane support */
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002865 case XGBE_PORT_MODE_BACKPLANE:
2866 pdata->phy.supported |= SUPPORTED_Autoneg;
2867 pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2868 pdata->phy.supported |= SUPPORTED_Backplane;
2869 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) {
2870 pdata->phy.supported |= SUPPORTED_1000baseKX_Full;
2871 phy_data->start_mode = XGBE_MODE_KX_1000;
2872 }
2873 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) {
2874 pdata->phy.supported |= SUPPORTED_10000baseKR_Full;
2875 if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
2876 pdata->phy.supported |=
2877 SUPPORTED_10000baseR_FEC;
2878 phy_data->start_mode = XGBE_MODE_KR;
2879 }
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002880
2881 phy_data->phydev_mode = XGBE_MDIO_MODE_NONE;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002882 break;
2883 case XGBE_PORT_MODE_BACKPLANE_2500:
2884 pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2885 pdata->phy.supported |= SUPPORTED_Backplane;
2886 pdata->phy.supported |= SUPPORTED_2500baseX_Full;
2887 phy_data->start_mode = XGBE_MODE_KX_2500;
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002888
2889 phy_data->phydev_mode = XGBE_MDIO_MODE_NONE;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002890 break;
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002891
2892 /* MDIO 1GBase-T support */
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002893 case XGBE_PORT_MODE_1000BASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002894 pdata->phy.supported |= SUPPORTED_Autoneg;
2895 pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2896 pdata->phy.supported |= SUPPORTED_TP;
2897 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) {
2898 pdata->phy.supported |= SUPPORTED_100baseT_Full;
2899 phy_data->start_mode = XGBE_MODE_SGMII_100;
2900 }
2901 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) {
2902 pdata->phy.supported |= SUPPORTED_1000baseT_Full;
2903 phy_data->start_mode = XGBE_MODE_SGMII_1000;
2904 }
2905
2906 phy_data->phydev_mode = XGBE_MDIO_MODE_CL22;
2907 break;
2908
2909 /* MDIO Base-X support */
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002910 case XGBE_PORT_MODE_1000BASE_X:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002911 pdata->phy.supported |= SUPPORTED_Autoneg;
2912 pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2913 pdata->phy.supported |= SUPPORTED_FIBRE;
2914 pdata->phy.supported |= SUPPORTED_1000baseT_Full;
2915 phy_data->start_mode = XGBE_MODE_X;
2916
2917 phy_data->phydev_mode = XGBE_MDIO_MODE_CL22;
2918 break;
2919
2920 /* MDIO NBase-T support */
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002921 case XGBE_PORT_MODE_NBASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002922 pdata->phy.supported |= SUPPORTED_Autoneg;
2923 pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2924 pdata->phy.supported |= SUPPORTED_TP;
2925 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) {
2926 pdata->phy.supported |= SUPPORTED_100baseT_Full;
2927 phy_data->start_mode = XGBE_MODE_SGMII_100;
2928 }
2929 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) {
2930 pdata->phy.supported |= SUPPORTED_1000baseT_Full;
2931 phy_data->start_mode = XGBE_MODE_SGMII_1000;
2932 }
2933 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500) {
2934 pdata->phy.supported |= SUPPORTED_2500baseX_Full;
2935 phy_data->start_mode = XGBE_MODE_KX_2500;
2936 }
2937
2938 phy_data->phydev_mode = XGBE_MDIO_MODE_CL45;
2939 break;
2940
2941 /* 10GBase-T support */
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002942 case XGBE_PORT_MODE_10GBASE_T:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002943 pdata->phy.supported |= SUPPORTED_Autoneg;
2944 pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2945 pdata->phy.supported |= SUPPORTED_TP;
2946 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) {
2947 pdata->phy.supported |= SUPPORTED_100baseT_Full;
2948 phy_data->start_mode = XGBE_MODE_SGMII_100;
2949 }
2950 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) {
2951 pdata->phy.supported |= SUPPORTED_1000baseT_Full;
2952 phy_data->start_mode = XGBE_MODE_SGMII_1000;
2953 }
2954 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) {
2955 pdata->phy.supported |= SUPPORTED_10000baseT_Full;
2956 phy_data->start_mode = XGBE_MODE_KR;
2957 }
2958
2959 phy_data->phydev_mode = XGBE_MDIO_MODE_NONE;
2960 break;
2961
2962 /* 10GBase-R support */
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002963 case XGBE_PORT_MODE_10GBASE_R:
Lendacky, Thomas732f2ab2016-11-10 17:11:14 -06002964 pdata->phy.supported |= SUPPORTED_Autoneg;
2965 pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2966 pdata->phy.supported |= SUPPORTED_TP;
2967 pdata->phy.supported |= SUPPORTED_10000baseT_Full;
2968 if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
2969 pdata->phy.supported |= SUPPORTED_10000baseR_FEC;
2970 phy_data->start_mode = XGBE_MODE_SFI;
2971
2972 phy_data->phydev_mode = XGBE_MDIO_MODE_NONE;
2973 break;
2974
2975 /* SFP support */
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06002976 case XGBE_PORT_MODE_SFP:
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06002977 pdata->phy.supported |= SUPPORTED_Autoneg;
2978 pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
2979 pdata->phy.supported |= SUPPORTED_TP;
2980 pdata->phy.supported |= SUPPORTED_FIBRE;
2981 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) {
2982 pdata->phy.supported |= SUPPORTED_100baseT_Full;
2983 phy_data->start_mode = XGBE_MODE_SGMII_100;
2984 }
2985 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) {
2986 pdata->phy.supported |= SUPPORTED_1000baseT_Full;
2987 phy_data->start_mode = XGBE_MODE_SGMII_1000;
2988 }
2989 if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) {
2990 pdata->phy.supported |= SUPPORTED_10000baseT_Full;
2991 phy_data->start_mode = XGBE_MODE_SFI;
2992 if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
2993 pdata->phy.supported |=
2994 SUPPORTED_10000baseR_FEC;
2995 }
2996
2997 phy_data->phydev_mode = XGBE_MDIO_MODE_CL22;
2998
2999 xgbe_phy_sfp_setup(pdata);
3000 break;
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06003001 default:
3002 return -EINVAL;
3003 }
3004
3005 if (netif_msg_probe(pdata))
3006 dev_dbg(pdata->dev, "phy supported=%#x\n",
3007 pdata->phy.supported);
3008
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06003009 if ((phy_data->conn_type & XGBE_CONN_TYPE_MDIO) &&
3010 (phy_data->phydev_mode != XGBE_MDIO_MODE_NONE)) {
3011 ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->mdio_addr,
3012 phy_data->phydev_mode);
3013 if (ret) {
3014 dev_err(pdata->dev,
3015 "mdio port/clause not compatible (%d/%u)\n",
3016 phy_data->mdio_addr, phy_data->phydev_mode);
3017 return -EINVAL;
3018 }
3019 }
3020
3021 if (phy_data->redrv && !phy_data->redrv_if) {
3022 ret = pdata->hw_if.set_ext_mii_mode(pdata, phy_data->redrv_addr,
3023 XGBE_MDIO_MODE_CL22);
3024 if (ret) {
3025 dev_err(pdata->dev,
3026 "redriver mdio port not compatible (%u)\n",
3027 phy_data->redrv_addr);
3028 return -EINVAL;
3029 }
3030 }
3031
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06003032 /* Register for driving external PHYs */
3033 mii = devm_mdiobus_alloc(pdata->dev);
3034 if (!mii) {
3035 dev_err(pdata->dev, "mdiobus_alloc failed\n");
3036 return -ENOMEM;
3037 }
3038
3039 mii->priv = pdata;
3040 mii->name = "amd-xgbe-mii";
3041 mii->read = xgbe_phy_mii_read;
3042 mii->write = xgbe_phy_mii_write;
3043 mii->parent = pdata->dev;
3044 mii->phy_mask = ~0;
3045 snprintf(mii->id, sizeof(mii->id), "%s", dev_name(pdata->dev));
3046 ret = mdiobus_register(mii);
3047 if (ret) {
3048 dev_err(pdata->dev, "mdiobus_register failed\n");
3049 return ret;
3050 }
3051 phy_data->mii = mii;
3052
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06003053 return 0;
3054}
3055
3056void xgbe_init_function_ptrs_phy_v2(struct xgbe_phy_if *phy_if)
3057{
3058 struct xgbe_phy_impl_if *phy_impl = &phy_if->phy_impl;
3059
3060 phy_impl->init = xgbe_phy_init;
3061 phy_impl->exit = xgbe_phy_exit;
3062
3063 phy_impl->reset = xgbe_phy_reset;
3064 phy_impl->start = xgbe_phy_start;
3065 phy_impl->stop = xgbe_phy_stop;
3066
3067 phy_impl->link_status = xgbe_phy_link_status;
3068
3069 phy_impl->valid_speed = xgbe_phy_valid_speed;
3070
3071 phy_impl->use_mode = xgbe_phy_use_mode;
3072 phy_impl->set_mode = xgbe_phy_set_mode;
3073 phy_impl->get_mode = xgbe_phy_get_mode;
3074 phy_impl->switch_mode = xgbe_phy_switch_mode;
3075 phy_impl->cur_mode = xgbe_phy_cur_mode;
3076
3077 phy_impl->an_mode = xgbe_phy_an_mode;
3078
Lendacky, Thomasabf0a1c2016-11-10 17:10:58 -06003079 phy_impl->an_config = xgbe_phy_an_config;
3080
Lendacky, Thomasd7445d12016-11-10 17:11:41 -06003081 phy_impl->an_advertising = xgbe_phy_an_advertising;
3082
Lendacky, Thomas47f164d2016-11-10 17:09:55 -06003083 phy_impl->an_outcome = xgbe_phy_an_outcome;
3084}