Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2015-2020 Beijing WangXun Technology Co., Ltd.
3 : : * Copyright(c) 2010-2017 Intel Corporation
4 : : */
5 : :
6 : : #include "txgbe_hw.h"
7 : : #include "txgbe_eeprom.h"
8 : : #include "txgbe_mng.h"
9 : : #include "txgbe_phy.h"
10 : :
11 : : static void txgbe_i2c_start(struct txgbe_hw *hw, u8 dev_addr);
12 : : static void txgbe_i2c_stop(struct txgbe_hw *hw);
13 : : static s32 txgbe_handle_bp_flow(u32 link_mode, struct txgbe_hw *hw);
14 : : static void txgbe_get_bp_ability(struct txgbe_backplane_ability *ability,
15 : : u32 link_partner, struct txgbe_hw *hw);
16 : : static s32 txgbe_check_bp_ability(struct txgbe_backplane_ability *local_ability,
17 : : struct txgbe_backplane_ability *lp_ability, struct txgbe_hw *hw);
18 : : static void txgbe_clear_bp_intr(u32 bit, u32 bit_high, struct txgbe_hw *hw);
19 : : static s32 txgbe_enable_kr_training(struct txgbe_hw *hw);
20 : : static s32 txgbe_disable_kr_training(struct txgbe_hw *hw, s32 post, s32 mode);
21 : : static s32 txgbe_check_kr_training(struct txgbe_hw *hw);
22 : : static void txgbe_read_phy_lane_tx_eq(u16 lane, struct txgbe_hw *hw,
23 : : s32 post, s32 mode);
24 : : static s32 txgbe_set_link_to_sfi(struct txgbe_hw *hw, u32 speed);
25 : :
26 : : /**
27 : : * txgbe_identify_extphy - Identify a single address for a PHY
28 : : * @hw: pointer to hardware structure
29 : : * @phy_addr: PHY address to probe
30 : : *
31 : : * Returns true if PHY found
32 : : */
33 : 0 : static bool txgbe_identify_extphy(struct txgbe_hw *hw)
34 : : {
35 : : u16 phy_addr = 0;
36 : :
37 [ # # ]: 0 : if (!txgbe_validate_phy_addr(hw, phy_addr)) {
38 : 0 : DEBUGOUT("Unable to validate PHY address 0x%04X",
39 : : phy_addr);
40 : 0 : return false;
41 : : }
42 : :
43 [ # # ]: 0 : if (txgbe_get_phy_id(hw))
44 : : return false;
45 : :
46 : 0 : hw->phy.type = txgbe_get_phy_type_from_id(hw->phy.id);
47 [ # # ]: 0 : if (hw->phy.type == txgbe_phy_unknown) {
48 : 0 : u16 ext_ability = 0;
49 : 0 : hw->phy.read_reg(hw, TXGBE_MD_PHY_EXT_ABILITY,
50 : : TXGBE_MD_DEV_PMA_PMD,
51 : : &ext_ability);
52 : :
53 [ # # ]: 0 : if (ext_ability & (TXGBE_MD_PHY_10GBASET_ABILITY |
54 : : TXGBE_MD_PHY_1000BASET_ABILITY))
55 : 0 : hw->phy.type = txgbe_phy_cu_unknown;
56 : : else
57 : 0 : hw->phy.type = txgbe_phy_generic;
58 : : }
59 : :
60 : : return true;
61 : : }
62 : :
63 : : /**
64 : : * txgbe_read_phy_if - Read TXGBE_ETHPHYIF register
65 : : * @hw: pointer to hardware structure
66 : : *
67 : : * Read TXGBE_ETHPHYIF register and save field values,
68 : : * and check for valid field values.
69 : : **/
70 : : static s32 txgbe_read_phy_if(struct txgbe_hw *hw)
71 : : {
72 : 0 : hw->phy.media_type = hw->phy.get_media_type(hw);
73 : :
74 : : /* Save NW management interface connected on board. This is used
75 : : * to determine internal PHY mode.
76 : : */
77 : 0 : hw->phy.nw_mng_if_sel = rd32(hw, TXGBE_ETHPHYIF);
78 : :
79 : : /* If MDIO is connected to external PHY, then set PHY address. */
80 : : if (hw->phy.nw_mng_if_sel & TXGBE_ETHPHYIF_MDIO_ACT)
81 : : hw->phy.addr = TXGBE_ETHPHYIF_MDIO_BASE(hw->phy.nw_mng_if_sel);
82 : :
83 [ # # ]: 0 : if (!hw->phy.phy_semaphore_mask)
84 : 0 : hw->phy.phy_semaphore_mask = TXGBE_MNGSEM_SWPHY;
85 : :
86 : : return 0;
87 : : }
88 : :
89 : : /**
90 : : * txgbe_identify_phy - Get physical layer module
91 : : * @hw: pointer to hardware structure
92 : : *
93 : : * Determines the physical layer module found on the current adapter.
94 : : **/
95 : 0 : s32 txgbe_identify_phy(struct txgbe_hw *hw)
96 : : {
97 : : s32 err = TXGBE_ERR_PHY_ADDR_INVALID;
98 : :
99 : : txgbe_read_phy_if(hw);
100 : :
101 [ # # ]: 0 : if (hw->phy.type != txgbe_phy_unknown)
102 : : return 0;
103 : :
104 : : /* Raptor 10GBASE-T requires an external PHY */
105 [ # # ]: 0 : if (hw->phy.media_type == txgbe_media_type_copper) {
106 : 0 : err = txgbe_identify_extphy(hw);
107 [ # # ]: 0 : } else if (hw->phy.media_type == txgbe_media_type_fiber) {
108 : 0 : err = txgbe_identify_module(hw);
109 : : } else {
110 : 0 : hw->phy.type = txgbe_phy_none;
111 : 0 : return 0;
112 : : }
113 : :
114 : : /* Return error if SFP module has been detected but is not supported */
115 [ # # ]: 0 : if (hw->phy.type == txgbe_phy_sfp_unsupported)
116 : 0 : return TXGBE_ERR_SFP_NOT_SUPPORTED;
117 : :
118 : : return err;
119 : : }
120 : :
121 : : /**
122 : : * txgbe_check_reset_blocked - check status of MNG FW veto bit
123 : : * @hw: pointer to the hardware structure
124 : : *
125 : : * This function checks the STAT.MNGVETO bit to see if there are
126 : : * any constraints on link from manageability. For MAC's that don't
127 : : * have this bit just return faluse since the link can not be blocked
128 : : * via this method.
129 : : **/
130 : 0 : s32 txgbe_check_reset_blocked(struct txgbe_hw *hw)
131 : : {
132 : : u32 mmngc;
133 : :
134 : : mmngc = rd32(hw, TXGBE_STAT);
135 [ # # ]: 0 : if (mmngc & TXGBE_STAT_MNGVETO) {
136 : 0 : DEBUGOUT("MNG_VETO bit detected.");
137 : 0 : return true;
138 : : }
139 : :
140 : : return false;
141 : : }
142 : :
143 : : /**
144 : : * txgbe_validate_phy_addr - Determines phy address is valid
145 : : * @hw: pointer to hardware structure
146 : : * @phy_addr: PHY address
147 : : *
148 : : **/
149 : 0 : bool txgbe_validate_phy_addr(struct txgbe_hw *hw, u32 phy_addr)
150 : : {
151 : 0 : u16 phy_id = 0;
152 : : bool valid = false;
153 : :
154 : 0 : hw->phy.addr = phy_addr;
155 : 0 : hw->phy.read_reg(hw, TXGBE_MD_PHY_ID_HIGH,
156 : : TXGBE_MD_DEV_PMA_PMD, &phy_id);
157 : :
158 [ # # ]: 0 : if (phy_id != 0xFFFF && phy_id != 0x0)
159 : : valid = true;
160 : :
161 : 0 : DEBUGOUT("PHY ID HIGH is 0x%04X", phy_id);
162 : :
163 : 0 : return valid;
164 : : }
165 : :
166 : : /**
167 : : * txgbe_get_phy_id - Get the phy type
168 : : * @hw: pointer to hardware structure
169 : : *
170 : : **/
171 : 0 : s32 txgbe_get_phy_id(struct txgbe_hw *hw)
172 : : {
173 : : u32 err;
174 : 0 : u16 phy_id_high = 0;
175 : 0 : u16 phy_id_low = 0;
176 : : u32 i = 0;
177 : : u32 status;
178 : :
179 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml) {
180 : 0 : hw->phy.addr = 0;
181 : :
182 [ # # ]: 0 : for (i = 0; i < 32; i++) {
183 : 0 : hw->phy.addr = i;
184 : 0 : status = txgbe_read_phy_reg_mdi(hw, TXGBE_MD_PHY_ID_HIGH, 0, &phy_id_high);
185 [ # # ]: 0 : if (status) {
186 : 0 : DEBUGOUT("txgbe_read_phy_reg_mdi failed 1");
187 : 0 : return status;
188 : : }
189 : 0 : DEBUGOUT("%d: phy_id_high 0x%x", i, phy_id_high);
190 [ # # ]: 0 : if ((phy_id_high & 0xFFFF) == 0x0141)
191 : : break;
192 : : }
193 : :
194 [ # # ]: 0 : if (i == 32) {
195 : 0 : DEBUGOUT("txgbe_read_phy_reg_mdi failed");
196 : 0 : return TXGBE_ERR_PHY;
197 : : }
198 : :
199 : 0 : status = txgbe_read_phy_reg_mdi(hw, TXGBE_MD_PHY_ID_LOW, 0, &phy_id_low);
200 [ # # ]: 0 : if (status) {
201 : 0 : DEBUGOUT("txgbe_read_phy_reg_mdi failed 2");
202 : 0 : return status;
203 : : }
204 : 0 : hw->phy.id = (u32)(phy_id_high & 0xFFFF) << 6;
205 : 0 : hw->phy.id |= (u32)((phy_id_low & 0xFC00) >> 10);
206 : :
207 : 0 : DEBUGOUT("phy_id 0x%x", hw->phy.id);
208 : :
209 : 0 : return status;
210 : : }
211 : :
212 : 0 : err = hw->phy.read_reg(hw, TXGBE_MD_PHY_ID_HIGH,
213 : : TXGBE_MD_DEV_PMA_PMD,
214 : : &phy_id_high);
215 : :
216 [ # # ]: 0 : if (err == 0) {
217 : 0 : hw->phy.id = (u32)(phy_id_high << 16);
218 : 0 : err = hw->phy.read_reg(hw, TXGBE_MD_PHY_ID_LOW,
219 : : TXGBE_MD_DEV_PMA_PMD,
220 : : &phy_id_low);
221 : 0 : hw->phy.id |= (u32)(phy_id_low & TXGBE_PHY_REVISION_MASK);
222 : 0 : hw->phy.revision = (u32)(phy_id_low & ~TXGBE_PHY_REVISION_MASK);
223 : : }
224 : 0 : DEBUGOUT("PHY_ID_HIGH 0x%04X, PHY_ID_LOW 0x%04X",
225 : : phy_id_high, phy_id_low);
226 : :
227 : 0 : return err;
228 : : }
229 : :
230 : : /**
231 : : * txgbe_get_phy_type_from_id - Get the phy type
232 : : * @phy_id: PHY ID information
233 : : *
234 : : **/
235 : 0 : enum txgbe_phy_type txgbe_get_phy_type_from_id(u32 phy_id)
236 : : {
237 : : enum txgbe_phy_type phy_type;
238 : :
239 [ # # # # : 0 : switch (phy_id) {
# ]
240 : : case TXGBE_PHYID_TN1010:
241 : : phy_type = txgbe_phy_tn;
242 : : break;
243 : 0 : case TXGBE_PHYID_QT2022:
244 : : phy_type = txgbe_phy_qt;
245 : 0 : break;
246 : 0 : case TXGBE_PHYID_ATH:
247 : : phy_type = txgbe_phy_nl;
248 : 0 : break;
249 : 0 : case TXGBE_PHYID_MTD3310:
250 : : phy_type = txgbe_phy_cu_mtd;
251 : 0 : break;
252 : 0 : default:
253 : : phy_type = txgbe_phy_unknown;
254 : 0 : break;
255 : : }
256 : :
257 : 0 : return phy_type;
258 : : }
259 : :
260 : : static s32
261 : 0 : txgbe_reset_extphy(struct txgbe_hw *hw)
262 : : {
263 : 0 : u16 ctrl = 0;
264 : : int err, i;
265 : :
266 : 0 : err = hw->phy.read_reg(hw, TXGBE_MD_PORT_CTRL,
267 : : TXGBE_MD_DEV_GENERAL, &ctrl);
268 [ # # ]: 0 : if (err != 0)
269 : : return err;
270 : 0 : ctrl |= TXGBE_MD_PORT_CTRL_RESET;
271 : 0 : err = hw->phy.write_reg(hw, TXGBE_MD_PORT_CTRL,
272 : : TXGBE_MD_DEV_GENERAL, ctrl);
273 [ # # ]: 0 : if (err != 0)
274 : : return err;
275 : :
276 : : /*
277 : : * Poll for reset bit to self-clear indicating reset is complete.
278 : : * Some PHYs could take up to 3 seconds to complete and need about
279 : : * 1.7 usec delay after the reset is complete.
280 : : */
281 [ # # ]: 0 : for (i = 0; i < 30; i++) {
282 : : msec_delay(100);
283 : 0 : err = hw->phy.read_reg(hw, TXGBE_MD_PORT_CTRL,
284 : : TXGBE_MD_DEV_GENERAL, &ctrl);
285 [ # # ]: 0 : if (err != 0)
286 : 0 : return err;
287 : :
288 [ # # ]: 0 : if (!(ctrl & TXGBE_MD_PORT_CTRL_RESET)) {
289 : 0 : usec_delay(2);
290 : 0 : break;
291 : : }
292 : : }
293 : :
294 [ # # ]: 0 : if (ctrl & TXGBE_MD_PORT_CTRL_RESET) {
295 : : err = TXGBE_ERR_RESET_FAILED;
296 : 0 : DEBUGOUT("PHY reset polling failed to complete.");
297 : : }
298 : :
299 : : return err;
300 : : }
301 : :
302 : : /**
303 : : * txgbe_reset_phy - Performs a PHY reset
304 : : * @hw: pointer to hardware structure
305 : : **/
306 : 0 : s32 txgbe_reset_phy(struct txgbe_hw *hw)
307 : : {
308 : : s32 err = 0;
309 : :
310 [ # # ]: 0 : if (hw->phy.type == txgbe_phy_unknown)
311 : 0 : err = txgbe_identify_phy(hw);
312 : :
313 [ # # # # ]: 0 : if (err != 0 || hw->phy.type == txgbe_phy_none)
314 : 0 : return err;
315 : :
316 : : /* Don't reset PHY if it's shut down due to overtemp. */
317 [ # # ]: 0 : if (hw->phy.check_overtemp(hw) == TXGBE_ERR_OVERTEMP)
318 : : return err;
319 : :
320 : : /* Blocked by MNG FW so bail */
321 [ # # ]: 0 : if (txgbe_check_reset_blocked(hw))
322 : : return err;
323 : :
324 [ # # ]: 0 : switch (hw->phy.type) {
325 : 0 : case txgbe_phy_cu_mtd:
326 : 0 : err = txgbe_reset_extphy(hw);
327 : 0 : break;
328 : : default:
329 : : break;
330 : : }
331 : :
332 : : return err;
333 : : }
334 : :
335 : : /**
336 : : * txgbe_read_phy_mdi - Reads a value from a specified PHY register without
337 : : * the SWFW lock
338 : : * @hw: pointer to hardware structure
339 : : * @reg_addr: 32 bit address of PHY register to read
340 : : * @device_type: 5 bit device type
341 : : * @phy_data: Pointer to read data from PHY register
342 : : **/
343 : 0 : s32 txgbe_read_phy_reg_mdi(struct txgbe_hw *hw, u32 reg_addr, u32 device_type,
344 : : u16 *phy_data)
345 : : {
346 : : u32 command, data;
347 : :
348 : : /* Setup and write the address cycle command */
349 : 0 : command = TXGBE_MDIOSCA_REG(reg_addr) |
350 : 0 : TXGBE_MDIOSCA_DEV(device_type) |
351 : 0 : TXGBE_MDIOSCA_PORT(hw->phy.addr);
352 : : wr32(hw, TXGBE_MDIOSCA, command);
353 : :
354 : : command = TXGBE_MDIOSCD_CMD_READ |
355 : : TXGBE_MDIOSCD_BUSY;
356 : : wr32(hw, TXGBE_MDIOSCD, command);
357 : :
358 : : /*
359 : : * Check every 10 usec to see if the address cycle completed.
360 : : * The MDI Command bit will clear when the operation is
361 : : * complete
362 : : */
363 [ # # ]: 0 : if (!po32m(hw, TXGBE_MDIOSCD, TXGBE_MDIOSCD_BUSY,
364 : : 0, NULL, 100, 100)) {
365 : 0 : DEBUGOUT("PHY address command did not complete");
366 : 0 : return TXGBE_ERR_PHY;
367 : : }
368 : :
369 : : data = rd32(hw, TXGBE_MDIOSCD);
370 : 0 : *phy_data = (u16)TXGBD_MDIOSCD_DAT(data);
371 : :
372 : 0 : return 0;
373 : : }
374 : :
375 : : /**
376 : : * txgbe_read_phy_reg - Reads a value from a specified PHY register
377 : : * using the SWFW lock - this function is needed in most cases
378 : : * @hw: pointer to hardware structure
379 : : * @reg_addr: 32 bit address of PHY register to read
380 : : * @device_type: 5 bit device type
381 : : * @phy_data: Pointer to read data from PHY register
382 : : **/
383 : 0 : s32 txgbe_read_phy_reg(struct txgbe_hw *hw, u32 reg_addr,
384 : : u32 device_type, u16 *phy_data)
385 : : {
386 : : s32 err;
387 : 0 : u32 gssr = hw->phy.phy_semaphore_mask;
388 : :
389 [ # # ]: 0 : if (hw->mac.acquire_swfw_sync(hw, gssr))
390 : : return TXGBE_ERR_SWFW_SYNC;
391 : :
392 : 0 : err = hw->phy.read_reg_mdi(hw, reg_addr, device_type, phy_data);
393 : :
394 : 0 : hw->mac.release_swfw_sync(hw, gssr);
395 : :
396 : 0 : return err;
397 : : }
398 : :
399 : : /**
400 : : * txgbe_write_phy_reg_mdi - Writes a value to specified PHY register
401 : : * without SWFW lock
402 : : * @hw: pointer to hardware structure
403 : : * @reg_addr: 32 bit PHY register to write
404 : : * @device_type: 5 bit device type
405 : : * @phy_data: Data to write to the PHY register
406 : : **/
407 : 0 : s32 txgbe_write_phy_reg_mdi(struct txgbe_hw *hw, u32 reg_addr,
408 : : u32 device_type, u16 phy_data)
409 : : {
410 : : u32 command;
411 : :
412 : : /* write command */
413 : 0 : command = TXGBE_MDIOSCA_REG(reg_addr) |
414 : 0 : TXGBE_MDIOSCA_DEV(device_type) |
415 : 0 : TXGBE_MDIOSCA_PORT(hw->phy.addr);
416 : : wr32(hw, TXGBE_MDIOSCA, command);
417 : :
418 : 0 : command = TXGBE_MDIOSCD_CMD_WRITE |
419 : 0 : TXGBE_MDIOSCD_DAT(phy_data) |
420 : : TXGBE_MDIOSCD_BUSY;
421 : : wr32(hw, TXGBE_MDIOSCD, command);
422 : :
423 : : /* wait for completion */
424 [ # # ]: 0 : if (!po32m(hw, TXGBE_MDIOSCD, TXGBE_MDIOSCD_BUSY,
425 : : 0, NULL, 100, 100)) {
426 : 0 : DEBUGOUT("PHY write cmd didn't complete");
427 : 0 : return -TERR_PHY;
428 : : }
429 : :
430 : : return 0;
431 : : }
432 : :
433 : : /**
434 : : * txgbe_write_phy_reg - Writes a value to specified PHY register
435 : : * using SWFW lock- this function is needed in most cases
436 : : * @hw: pointer to hardware structure
437 : : * @reg_addr: 32 bit PHY register to write
438 : : * @device_type: 5 bit device type
439 : : * @phy_data: Data to write to the PHY register
440 : : **/
441 : 0 : s32 txgbe_write_phy_reg(struct txgbe_hw *hw, u32 reg_addr,
442 : : u32 device_type, u16 phy_data)
443 : : {
444 : : s32 err;
445 : 0 : u32 gssr = hw->phy.phy_semaphore_mask;
446 : :
447 : 0 : if (hw->mac.acquire_swfw_sync(hw, gssr))
448 : : err = TXGBE_ERR_SWFW_SYNC;
449 : :
450 : 0 : err = hw->phy.write_reg_mdi(hw, reg_addr, device_type,
451 : : phy_data);
452 : 0 : hw->mac.release_swfw_sync(hw, gssr);
453 : :
454 : 0 : return err;
455 : : }
456 : :
457 : : /**
458 : : * txgbe_setup_phy_link - Set and restart auto-neg
459 : : * @hw: pointer to hardware structure
460 : : *
461 : : * Restart auto-negotiation and PHY and waits for completion.
462 : : **/
463 : 0 : s32 txgbe_setup_phy_link(struct txgbe_hw *hw)
464 : : {
465 : : s32 err = 0;
466 : 0 : u16 autoneg_reg = TXGBE_MII_AUTONEG_REG;
467 : 0 : bool autoneg = false;
468 : : u32 speed;
469 : :
470 : 0 : txgbe_get_copper_link_capabilities(hw, &speed, &autoneg);
471 : :
472 : : /* Set or unset auto-negotiation 10G advertisement */
473 : 0 : hw->phy.read_reg(hw, TXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
474 : : TXGBE_MD_DEV_AUTO_NEG,
475 : : &autoneg_reg);
476 : :
477 : 0 : autoneg_reg &= ~TXGBE_MII_10GBASE_T_ADVERTISE;
478 [ # # ]: 0 : if ((hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_10GB_FULL) &&
479 [ # # ]: 0 : (speed & TXGBE_LINK_SPEED_10GB_FULL))
480 : 0 : autoneg_reg |= TXGBE_MII_10GBASE_T_ADVERTISE;
481 : :
482 : 0 : hw->phy.write_reg(hw, TXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
483 : : TXGBE_MD_DEV_AUTO_NEG,
484 : : autoneg_reg);
485 : :
486 : 0 : hw->phy.read_reg(hw, TXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
487 : : TXGBE_MD_DEV_AUTO_NEG,
488 : : &autoneg_reg);
489 : :
490 : : /* Set or unset auto-negotiation 5G advertisement */
491 : 0 : autoneg_reg &= ~TXGBE_MII_5GBASE_T_ADVERTISE;
492 [ # # ]: 0 : if ((hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_5GB_FULL) &&
493 [ # # ]: 0 : (speed & TXGBE_LINK_SPEED_5GB_FULL))
494 : 0 : autoneg_reg |= TXGBE_MII_5GBASE_T_ADVERTISE;
495 : :
496 : : /* Set or unset auto-negotiation 2.5G advertisement */
497 : 0 : autoneg_reg &= ~TXGBE_MII_2_5GBASE_T_ADVERTISE;
498 [ # # ]: 0 : if ((hw->phy.autoneg_advertised &
499 : 0 : TXGBE_LINK_SPEED_2_5GB_FULL) &&
500 [ # # ]: 0 : (speed & TXGBE_LINK_SPEED_2_5GB_FULL))
501 : 0 : autoneg_reg |= TXGBE_MII_2_5GBASE_T_ADVERTISE;
502 : : /* Set or unset auto-negotiation 1G advertisement */
503 : 0 : autoneg_reg &= ~TXGBE_MII_1GBASE_T_ADVERTISE;
504 [ # # ]: 0 : if ((hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_1GB_FULL) &&
505 [ # # ]: 0 : (speed & TXGBE_LINK_SPEED_1GB_FULL))
506 : 0 : autoneg_reg |= TXGBE_MII_1GBASE_T_ADVERTISE;
507 : :
508 : 0 : hw->phy.write_reg(hw, TXGBE_MII_AUTONEG_VENDOR_PROVISION_1_REG,
509 : : TXGBE_MD_DEV_AUTO_NEG,
510 : : autoneg_reg);
511 : :
512 : : /* Set or unset auto-negotiation 100M advertisement */
513 : 0 : hw->phy.read_reg(hw, TXGBE_MII_AUTONEG_ADVERTISE_REG,
514 : : TXGBE_MD_DEV_AUTO_NEG,
515 : : &autoneg_reg);
516 : :
517 : 0 : autoneg_reg &= ~(TXGBE_MII_100BASE_T_ADVERTISE |
518 : : TXGBE_MII_100BASE_T_ADVERTISE_HALF);
519 [ # # ]: 0 : if ((hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_100M_FULL) &&
520 [ # # ]: 0 : (speed & TXGBE_LINK_SPEED_100M_FULL))
521 : 0 : autoneg_reg |= TXGBE_MII_100BASE_T_ADVERTISE;
522 : :
523 : 0 : hw->phy.write_reg(hw, TXGBE_MII_AUTONEG_ADVERTISE_REG,
524 : : TXGBE_MD_DEV_AUTO_NEG,
525 : : autoneg_reg);
526 : :
527 : : /* Blocked by MNG FW so don't reset PHY */
528 [ # # ]: 0 : if (txgbe_check_reset_blocked(hw))
529 : : return err;
530 : :
531 : : /* Restart PHY auto-negotiation. */
532 : 0 : hw->phy.read_reg(hw, TXGBE_MD_AUTO_NEG_CONTROL,
533 : : TXGBE_MD_DEV_AUTO_NEG, &autoneg_reg);
534 : :
535 : 0 : autoneg_reg |= TXGBE_MII_RESTART;
536 : :
537 : 0 : hw->phy.write_reg(hw, TXGBE_MD_AUTO_NEG_CONTROL,
538 : : TXGBE_MD_DEV_AUTO_NEG, autoneg_reg);
539 : :
540 : 0 : return err;
541 : : }
542 : :
543 : : /**
544 : : * txgbe_setup_phy_link_speed - Sets the auto advertised capabilities
545 : : * @hw: pointer to hardware structure
546 : : * @speed: new link speed
547 : : * @autoneg_wait_to_complete: unused
548 : : **/
549 : 0 : s32 txgbe_setup_phy_link_speed(struct txgbe_hw *hw,
550 : : u32 speed,
551 : : bool autoneg_wait_to_complete)
552 : : {
553 : : UNREFERENCED_PARAMETER(autoneg_wait_to_complete);
554 : :
555 : : /*
556 : : * Clear autoneg_advertised and set new values based on input link
557 : : * speed.
558 : : */
559 : 0 : hw->phy.autoneg_advertised = 0;
560 : :
561 [ # # ]: 0 : if (speed & TXGBE_LINK_SPEED_10GB_FULL)
562 : 0 : hw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_10GB_FULL;
563 : :
564 [ # # ]: 0 : if (speed & TXGBE_LINK_SPEED_5GB_FULL)
565 : 0 : hw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_5GB_FULL;
566 : :
567 [ # # ]: 0 : if (speed & TXGBE_LINK_SPEED_2_5GB_FULL)
568 : 0 : hw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_2_5GB_FULL;
569 : :
570 [ # # ]: 0 : if (speed & TXGBE_LINK_SPEED_1GB_FULL)
571 : 0 : hw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_1GB_FULL;
572 : :
573 [ # # ]: 0 : if (speed & TXGBE_LINK_SPEED_100M_FULL)
574 : 0 : hw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_100M_FULL;
575 : :
576 [ # # ]: 0 : if (speed & TXGBE_LINK_SPEED_10M_FULL)
577 : 0 : hw->phy.autoneg_advertised |= TXGBE_LINK_SPEED_10M_FULL;
578 : :
579 : : /* Setup link based on the new speed settings */
580 : 0 : hw->phy.setup_link(hw);
581 : :
582 : 0 : return 0;
583 : : }
584 : :
585 : 0 : s32 txgbe_get_phy_fw_version(struct txgbe_hw *hw, u32 *fw_version)
586 : : {
587 : : u16 eeprom_verh, eeprom_verl;
588 : :
589 : 0 : hw->rom.readw_sw(hw, TXGBE_EEPROM_VERSION_H, &eeprom_verh);
590 : 0 : hw->rom.readw_sw(hw, TXGBE_EEPROM_VERSION_L, &eeprom_verl);
591 : :
592 : 0 : *fw_version = (eeprom_verh << 16) | eeprom_verl;
593 : :
594 : 0 : return 0;
595 : : }
596 : :
597 : : /**
598 : : * txgbe_get_copper_speeds_supported - Get copper link speeds from phy
599 : : * @hw: pointer to hardware structure
600 : : *
601 : : * Determines the supported link capabilities by reading the PHY auto
602 : : * negotiation register.
603 : : **/
604 : 0 : static s32 txgbe_get_copper_speeds_supported(struct txgbe_hw *hw)
605 : : {
606 : : s32 err;
607 : : u16 speed_ability;
608 : :
609 : 0 : err = hw->phy.read_reg(hw, TXGBE_MD_PHY_SPEED_ABILITY,
610 : : TXGBE_MD_DEV_PMA_PMD,
611 : : &speed_ability);
612 [ # # ]: 0 : if (err)
613 : : return err;
614 : :
615 [ # # ]: 0 : if (speed_ability & TXGBE_MD_PHY_SPEED_10G)
616 : 0 : hw->phy.speeds_supported |= TXGBE_LINK_SPEED_10GB_FULL;
617 [ # # ]: 0 : if (speed_ability & TXGBE_MD_PHY_SPEED_1G)
618 : 0 : hw->phy.speeds_supported |= TXGBE_LINK_SPEED_1GB_FULL;
619 [ # # ]: 0 : if (speed_ability & TXGBE_MD_PHY_SPEED_100M)
620 : 0 : hw->phy.speeds_supported |= TXGBE_LINK_SPEED_100M_FULL;
621 : :
622 : : return err;
623 : : }
624 : :
625 : : /**
626 : : * txgbe_get_copper_link_capabilities - Determines link capabilities
627 : : * @hw: pointer to hardware structure
628 : : * @speed: pointer to link speed
629 : : * @autoneg: boolean auto-negotiation value
630 : : **/
631 : 0 : s32 txgbe_get_copper_link_capabilities(struct txgbe_hw *hw,
632 : : u32 *speed,
633 : : bool *autoneg)
634 : : {
635 : : s32 err = 0;
636 : :
637 : 0 : *autoneg = true;
638 [ # # ]: 0 : if (!hw->phy.speeds_supported)
639 : 0 : err = txgbe_get_copper_speeds_supported(hw);
640 : :
641 : 0 : *speed = hw->phy.speeds_supported;
642 : 0 : return err;
643 : : }
644 : :
645 : : /**
646 : : * txgbe_check_phy_link_tnx - Determine link and speed status
647 : : * @hw: pointer to hardware structure
648 : : * @speed: current link speed
649 : : * @link_up: true is link is up, false otherwise
650 : : *
651 : : * Reads the VS1 register to determine if link is up and the current speed for
652 : : * the PHY.
653 : : **/
654 : 0 : s32 txgbe_check_phy_link_tnx(struct txgbe_hw *hw, u32 *speed,
655 : : bool *link_up)
656 : : {
657 : : s32 err = 0;
658 : : u32 time_out;
659 : : u32 max_time_out = 10;
660 : : u16 phy_link = 0;
661 : : u16 phy_speed = 0;
662 : 0 : u16 phy_data = 0;
663 : :
664 : : /* Initialize speed and link to default case */
665 : 0 : *link_up = false;
666 : 0 : *speed = TXGBE_LINK_SPEED_10GB_FULL;
667 : :
668 : : /*
669 : : * Check current speed and link status of the PHY register.
670 : : * This is a vendor specific register and may have to
671 : : * be changed for other copper PHYs.
672 : : */
673 [ # # ]: 0 : for (time_out = 0; time_out < max_time_out; time_out++) {
674 : 0 : usec_delay(10);
675 : 0 : err = hw->phy.read_reg(hw,
676 : : TXGBE_MD_VENDOR_SPECIFIC_1_STATUS,
677 : : TXGBE_MD_DEV_VENDOR_1,
678 : : &phy_data);
679 : 0 : phy_link = phy_data & TXGBE_MD_VENDOR_SPECIFIC_1_LINK_STATUS;
680 : 0 : phy_speed = phy_data &
681 : : TXGBE_MD_VENDOR_SPECIFIC_1_SPEED_STATUS;
682 [ # # ]: 0 : if (phy_link == TXGBE_MD_VENDOR_SPECIFIC_1_LINK_STATUS) {
683 : 0 : *link_up = true;
684 [ # # ]: 0 : if (phy_speed ==
685 : : TXGBE_MD_VENDOR_SPECIFIC_1_SPEED_STATUS)
686 : 0 : *speed = TXGBE_LINK_SPEED_1GB_FULL;
687 : : break;
688 : : }
689 : : }
690 : :
691 : 0 : return err;
692 : : }
693 : :
694 : : /**
695 : : * txgbe_setup_phy_link_tnx - Set and restart auto-neg
696 : : * @hw: pointer to hardware structure
697 : : *
698 : : * Restart auto-negotiation and PHY and waits for completion.
699 : : **/
700 : 0 : s32 txgbe_setup_phy_link_tnx(struct txgbe_hw *hw)
701 : : {
702 : : s32 err = 0;
703 : 0 : u16 autoneg_reg = TXGBE_MII_AUTONEG_REG;
704 : 0 : bool autoneg = false;
705 : : u32 speed;
706 : :
707 : 0 : txgbe_get_copper_link_capabilities(hw, &speed, &autoneg);
708 : :
709 [ # # ]: 0 : if (speed & TXGBE_LINK_SPEED_10GB_FULL) {
710 : : /* Set or unset auto-negotiation 10G advertisement */
711 : 0 : hw->phy.read_reg(hw, TXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
712 : : TXGBE_MD_DEV_AUTO_NEG,
713 : : &autoneg_reg);
714 : :
715 : 0 : autoneg_reg &= ~TXGBE_MII_10GBASE_T_ADVERTISE;
716 [ # # ]: 0 : if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_10GB_FULL)
717 : 0 : autoneg_reg |= TXGBE_MII_10GBASE_T_ADVERTISE;
718 : :
719 : 0 : hw->phy.write_reg(hw, TXGBE_MII_10GBASE_T_AUTONEG_CTRL_REG,
720 : : TXGBE_MD_DEV_AUTO_NEG,
721 : : autoneg_reg);
722 : : }
723 : :
724 [ # # ]: 0 : if (speed & TXGBE_LINK_SPEED_1GB_FULL) {
725 : : /* Set or unset auto-negotiation 1G advertisement */
726 : 0 : hw->phy.read_reg(hw, TXGBE_MII_AUTONEG_XNP_TX_REG,
727 : : TXGBE_MD_DEV_AUTO_NEG,
728 : : &autoneg_reg);
729 : :
730 : 0 : autoneg_reg &= ~TXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
731 [ # # ]: 0 : if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_1GB_FULL)
732 : 0 : autoneg_reg |= TXGBE_MII_1GBASE_T_ADVERTISE_XNP_TX;
733 : :
734 : 0 : hw->phy.write_reg(hw, TXGBE_MII_AUTONEG_XNP_TX_REG,
735 : : TXGBE_MD_DEV_AUTO_NEG,
736 : : autoneg_reg);
737 : : }
738 : :
739 [ # # ]: 0 : if (speed & TXGBE_LINK_SPEED_100M_FULL) {
740 : : /* Set or unset auto-negotiation 100M advertisement */
741 : 0 : hw->phy.read_reg(hw, TXGBE_MII_AUTONEG_ADVERTISE_REG,
742 : : TXGBE_MD_DEV_AUTO_NEG,
743 : : &autoneg_reg);
744 : :
745 : 0 : autoneg_reg &= ~TXGBE_MII_100BASE_T_ADVERTISE;
746 [ # # ]: 0 : if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_100M_FULL)
747 : 0 : autoneg_reg |= TXGBE_MII_100BASE_T_ADVERTISE;
748 : :
749 : 0 : hw->phy.write_reg(hw, TXGBE_MII_AUTONEG_ADVERTISE_REG,
750 : : TXGBE_MD_DEV_AUTO_NEG,
751 : : autoneg_reg);
752 : : }
753 : :
754 : : /* Blocked by MNG FW so don't reset PHY */
755 [ # # ]: 0 : if (txgbe_check_reset_blocked(hw))
756 : : return err;
757 : :
758 : : /* Restart PHY auto-negotiation. */
759 : 0 : hw->phy.read_reg(hw, TXGBE_MD_AUTO_NEG_CONTROL,
760 : : TXGBE_MD_DEV_AUTO_NEG, &autoneg_reg);
761 : :
762 : 0 : autoneg_reg |= TXGBE_MII_RESTART;
763 : :
764 : 0 : hw->phy.write_reg(hw, TXGBE_MD_AUTO_NEG_CONTROL,
765 : : TXGBE_MD_DEV_AUTO_NEG, autoneg_reg);
766 : :
767 : 0 : return err;
768 : : }
769 : :
770 : : /**
771 : : * txgbe_identify_module - Identifies module type
772 : : * @hw: pointer to hardware structure
773 : : *
774 : : * Determines HW type and calls appropriate function.
775 : : **/
776 : 0 : s32 txgbe_identify_module(struct txgbe_hw *hw)
777 : : {
778 : : s32 err = TXGBE_ERR_SFP_NOT_PRESENT;
779 : :
780 [ # # # ]: 0 : switch (hw->phy.media_type) {
781 : 0 : case txgbe_media_type_fiber:
782 : 0 : err = txgbe_identify_sfp_module(hw);
783 : 0 : break;
784 : :
785 : 0 : case txgbe_media_type_fiber_qsfp:
786 : 0 : err = txgbe_identify_qsfp_module(hw);
787 : 0 : break;
788 : :
789 : 0 : default:
790 : 0 : hw->phy.sfp_type = txgbe_sfp_type_not_present;
791 : : err = TXGBE_ERR_SFP_NOT_PRESENT;
792 : 0 : break;
793 : : }
794 : :
795 : 0 : return err;
796 : : }
797 : :
798 : : /**
799 : : * txgbe_identify_sfp_module - Identifies SFP modules
800 : : * @hw: pointer to hardware structure
801 : : *
802 : : * Searches for and identifies the SFP module and assigns appropriate PHY type.
803 : : **/
804 : 0 : s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
805 : : {
806 : : s32 err = TXGBE_ERR_PHY_ADDR_INVALID;
807 : : u32 vendor_oui = 0;
808 : 0 : enum txgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
809 : 0 : u8 identifier = 0;
810 : 0 : u8 comp_codes_1g = 0;
811 : 0 : u8 comp_codes_10g = 0;
812 : 0 : u8 comp_codes_25g = 0;
813 : 0 : u8 comp_copper_len = 0;
814 : 0 : u8 oui_bytes[3] = {0, 0, 0};
815 : 0 : u8 cable_tech = 0;
816 : 0 : u8 cable_spec = 0;
817 : 0 : u16 enforce_sfp = 0;
818 : : u32 value;
819 : :
820 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml) {
821 : : value = rd32(hw, TXGBE_GPIOEXT);
822 [ # # ]: 0 : if (value & TXGBE_SFP1_MOD_ABS_LS) {
823 : 0 : hw->phy.sfp_type = txgbe_sfp_type_not_present;
824 : 0 : return TXGBE_ERR_SFP_NOT_PRESENT;
825 : : }
826 : : }
827 : :
828 [ # # ]: 0 : if (hw->phy.media_type != txgbe_media_type_fiber) {
829 : 0 : hw->phy.sfp_type = txgbe_sfp_type_not_present;
830 : 0 : return TXGBE_ERR_SFP_NOT_PRESENT;
831 : : }
832 : :
833 : 0 : err = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
834 [ # # ]: 0 : if (err)
835 : : return -EBUSY;
836 : :
837 : 0 : err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_IDENTIFIER,
838 : : &identifier);
839 [ # # ]: 0 : if (err != 0) {
840 : 0 : ERR_I2C:
841 : 0 : hw->phy.sfp_type = txgbe_sfp_type_not_present;
842 [ # # ]: 0 : if (hw->phy.type != txgbe_phy_nl) {
843 : 0 : hw->phy.id = 0;
844 : 0 : hw->phy.type = txgbe_phy_unknown;
845 : : }
846 : 0 : hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
847 : 0 : return TXGBE_ERR_SFP_NOT_PRESENT;
848 : : }
849 : :
850 [ # # ]: 0 : if (identifier != TXGBE_SFF_IDENTIFIER_SFP) {
851 : 0 : hw->phy.type = txgbe_phy_sfp_unsupported;
852 : 0 : hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
853 : 0 : return TXGBE_ERR_SFP_NOT_SUPPORTED;
854 : : }
855 : :
856 : 0 : err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_1GBE_COMP_CODES,
857 : : &comp_codes_1g);
858 [ # # ]: 0 : if (err != 0)
859 : 0 : goto ERR_I2C;
860 : :
861 : 0 : err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_10GBE_COMP_CODES,
862 : : &comp_codes_10g);
863 [ # # ]: 0 : if (err != 0)
864 : 0 : goto ERR_I2C;
865 : :
866 : 0 : err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_25GBE_COMP_CODES,
867 : : &comp_codes_25g);
868 [ # # ]: 0 : if (err != 0)
869 : 0 : goto ERR_I2C;
870 : :
871 : 0 : err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_COPPER_LENGTH,
872 : : &comp_copper_len);
873 [ # # ]: 0 : if (err != 0)
874 : 0 : goto ERR_I2C;
875 : :
876 : 0 : err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_CABLE_TECHNOLOGY,
877 : : &cable_tech);
878 [ # # ]: 0 : if (err != 0)
879 : 0 : goto ERR_I2C;
880 : :
881 : : /* ID Module
882 : : * =========
883 : : * 0 SFP_DA_CU
884 : : * 1 SFP_SR
885 : : * 2 SFP_LR
886 : : * 3 SFP_DA_CORE0 - chip-specific
887 : : * 4 SFP_DA_CORE1 - chip-specific
888 : : * 5 SFP_SR/LR_CORE0 - chip-specific
889 : : * 6 SFP_SR/LR_CORE1 - chip-specific
890 : : * 7 SFP_act_lmt_DA_CORE0 - chip-specific
891 : : * 8 SFP_act_lmt_DA_CORE1 - chip-specific
892 : : * 9 SFP_1g_cu_CORE0 - chip-specific
893 : : * 10 SFP_1g_cu_CORE1 - chip-specific
894 : : * 11 SFP_1g_sx_CORE0 - chip-specific
895 : : * 12 SFP_1g_sx_CORE1 - chip-specific
896 : : */
897 [ # # ]: 0 : if (cable_tech & TXGBE_SFF_CABLE_DA_PASSIVE) {
898 [ # # ]: 0 : if (hw->bus.lan_id == 0)
899 : 0 : hw->phy.sfp_type = txgbe_sfp_type_da_cu_core0;
900 : : else
901 : 0 : hw->phy.sfp_type = txgbe_sfp_type_da_cu_core1;
902 : :
903 [ # # ]: 0 : if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
904 : : hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1) {
905 : 0 : hw->dac_sfp = true;
906 : : }
907 : :
908 [ # # ]: 0 : if (comp_copper_len == TXGBE_SFF_COPPER_1M)
909 : 0 : hw->bypass_ctle = true;
910 : : else
911 : 0 : hw->bypass_ctle = false;
912 : :
913 : 0 : if (comp_codes_25g == TXGBE_SFF_25GBASECR_91FEC ||
914 [ # # ]: 0 : comp_codes_25g == TXGBE_SFF_25GBASECR_74FEC ||
915 : : comp_codes_25g == TXGBE_SFF_25GBASECR_NOFEC) {
916 : 0 : hw->phy.fiber_suppport_speed =
917 : : TXGBE_LINK_SPEED_25GB_FULL |
918 : : TXGBE_LINK_SPEED_10GB_FULL;
919 : : } else {
920 : 0 : hw->phy.fiber_suppport_speed |=
921 : : TXGBE_LINK_SPEED_10GB_FULL;
922 : : }
923 [ # # ]: 0 : } else if (comp_codes_25g == TXGBE_SFF_25GAUI_C2M_AOC_BER_5 ||
924 [ # # ]: 0 : comp_codes_25g == TXGBE_SFF_25GAUI_C2M_ACC_BER_5 ||
925 [ # # ]: 0 : comp_codes_25g == TXGBE_SFF_25GAUI_C2M_AOC_BER_12 ||
926 : : comp_codes_25g == TXGBE_SFF_25GAUI_C2M_ACC_BER_12) {
927 : 0 : hw->dac_sfp = false;
928 : 0 : hw->phy.sfp_type = (hw->bus.lan_id == 0
929 : : ? txgbe_sfp_type_25g_aoc_core0
930 [ # # ]: 0 : : txgbe_sfp_type_25g_aoc_core1);
931 [ # # ]: 0 : } else if (cable_tech & TXGBE_SFF_CABLE_DA_ACTIVE) {
932 : 0 : hw->dac_sfp = false;
933 : 0 : err = hw->phy.read_i2c_eeprom(hw,
934 : : TXGBE_SFF_CABLE_SPEC_COMP, &cable_spec);
935 [ # # ]: 0 : if (err != 0)
936 : 0 : goto ERR_I2C;
937 [ # # ]: 0 : if (cable_spec & TXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
938 : 0 : hw->phy.sfp_type = (hw->bus.lan_id == 0
939 : : ? txgbe_sfp_type_da_act_lmt_core0
940 [ # # ]: 0 : : txgbe_sfp_type_da_act_lmt_core1);
941 : : } else {
942 : 0 : hw->phy.sfp_type = txgbe_sfp_type_unknown;
943 : : }
944 [ # # ]: 0 : } else if (comp_codes_25g == TXGBE_SFF_25GBASESR_CAPABLE ||
945 : : comp_codes_25g == TXGBE_SFF_25GBASEER_CAPABLE) {
946 [ # # ]: 0 : if (hw->bus.lan_id == 0)
947 : 0 : hw->phy.sfp_type = txgbe_sfp_type_25g_sr_core0;
948 : : else
949 : 0 : hw->phy.sfp_type = txgbe_sfp_type_25g_sr_core1;
950 [ # # ]: 0 : } else if (comp_codes_25g == TXGBE_SFF_25GBASELR_CAPABLE) {
951 [ # # ]: 0 : if (hw->bus.lan_id == 0)
952 : 0 : hw->phy.sfp_type = txgbe_sfp_type_25g_lr_core0;
953 : : else
954 : 0 : hw->phy.sfp_type = txgbe_sfp_type_25g_lr_core1;
955 [ # # ]: 0 : } else if (comp_codes_10g &
956 : : (TXGBE_SFF_10GBASESR_CAPABLE |
957 : : TXGBE_SFF_10GBASELR_CAPABLE)) {
958 : 0 : hw->phy.sfp_type = (hw->bus.lan_id == 0
959 : : ? txgbe_sfp_type_srlr_core0
960 [ # # ]: 0 : : txgbe_sfp_type_srlr_core1);
961 [ # # ]: 0 : } else if (comp_codes_1g & TXGBE_SFF_1GBASET_CAPABLE) {
962 : 0 : hw->phy.sfp_type = (hw->bus.lan_id == 0
963 : : ? txgbe_sfp_type_1g_cu_core0
964 [ # # ]: 0 : : txgbe_sfp_type_1g_cu_core1);
965 [ # # ]: 0 : } else if (comp_codes_1g & TXGBE_SFF_1GBASESX_CAPABLE) {
966 : 0 : hw->phy.sfp_type = (hw->bus.lan_id == 0
967 : : ? txgbe_sfp_type_1g_sx_core0
968 [ # # ]: 0 : : txgbe_sfp_type_1g_sx_core1);
969 [ # # ]: 0 : } else if (comp_codes_1g & TXGBE_SFF_1GBASELX_CAPABLE) {
970 : 0 : hw->phy.sfp_type = (hw->bus.lan_id == 0
971 : : ? txgbe_sfp_type_1g_lx_core0
972 [ # # ]: 0 : : txgbe_sfp_type_1g_lx_core1);
973 : : } else {
974 : 0 : hw->phy.sfp_type = txgbe_sfp_type_unknown;
975 : : }
976 : :
977 [ # # ]: 0 : if (hw->phy.sfp_type != stored_sfp_type)
978 : 0 : hw->phy.sfp_setup_needed = true;
979 : :
980 : : /* Determine if the SFP+ PHY is dual speed or not. */
981 : 0 : hw->phy.multispeed_fiber = false;
982 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml) {
983 : 0 : if ((comp_codes_25g == TXGBE_SFF_25GBASESR_CAPABLE ||
984 [ # # ]: 0 : comp_codes_25g == TXGBE_SFF_25GBASELR_CAPABLE ||
985 : 0 : comp_codes_25g == TXGBE_SFF_25GBASEER_CAPABLE) &&
986 [ # # ]: 0 : ((comp_codes_10g & TXGBE_SFF_10GBASESR_CAPABLE) ||
987 : : (comp_codes_10g & TXGBE_SFF_10GBASELR_CAPABLE)))
988 : 0 : hw->phy.multispeed_fiber = true;
989 : : } else {
990 [ # # ]: 0 : if (((comp_codes_1g & TXGBE_SFF_1GBASESX_CAPABLE) &&
991 [ # # # # ]: 0 : (comp_codes_10g & TXGBE_SFF_10GBASESR_CAPABLE)) ||
992 : 0 : ((comp_codes_1g & TXGBE_SFF_1GBASELX_CAPABLE) &&
993 [ # # ]: 0 : (comp_codes_10g & TXGBE_SFF_10GBASELR_CAPABLE)))
994 : 0 : hw->phy.multispeed_fiber = true;
995 : : }
996 : :
997 : : /* Determine PHY vendor */
998 [ # # ]: 0 : if (hw->phy.type != txgbe_phy_nl) {
999 : 0 : hw->phy.id = identifier;
1000 : 0 : err = hw->phy.read_i2c_eeprom(hw,
1001 : : TXGBE_SFF_VENDOR_OUI_BYTE0, &oui_bytes[0]);
1002 [ # # ]: 0 : if (err != 0)
1003 : 0 : goto ERR_I2C;
1004 : :
1005 : 0 : err = hw->phy.read_i2c_eeprom(hw,
1006 : : TXGBE_SFF_VENDOR_OUI_BYTE1, &oui_bytes[1]);
1007 [ # # ]: 0 : if (err != 0)
1008 : 0 : goto ERR_I2C;
1009 : :
1010 : 0 : err = hw->phy.read_i2c_eeprom(hw,
1011 : : TXGBE_SFF_VENDOR_OUI_BYTE2, &oui_bytes[2]);
1012 [ # # ]: 0 : if (err != 0)
1013 : 0 : goto ERR_I2C;
1014 : :
1015 : 0 : vendor_oui = ((u32)oui_bytes[0] << 24) |
1016 : 0 : ((u32)oui_bytes[1] << 16) |
1017 : 0 : ((u32)oui_bytes[2] << 8);
1018 [ # # # # : 0 : switch (vendor_oui) {
# ]
1019 : 0 : case TXGBE_SFF_VENDOR_OUI_TYCO:
1020 [ # # ]: 0 : if (cable_tech & TXGBE_SFF_CABLE_DA_PASSIVE)
1021 : 0 : hw->phy.type = txgbe_phy_sfp_tyco_passive;
1022 : : break;
1023 : 0 : case TXGBE_SFF_VENDOR_OUI_FTL:
1024 [ # # ]: 0 : if (cable_tech & TXGBE_SFF_CABLE_DA_ACTIVE)
1025 : 0 : hw->phy.type = txgbe_phy_sfp_ftl_active;
1026 : : else
1027 : 0 : hw->phy.type = txgbe_phy_sfp_ftl;
1028 : : break;
1029 : 0 : case TXGBE_SFF_VENDOR_OUI_AVAGO:
1030 : 0 : hw->phy.type = txgbe_phy_sfp_avago;
1031 : 0 : break;
1032 : 0 : case TXGBE_SFF_VENDOR_OUI_INTEL:
1033 : 0 : hw->phy.type = txgbe_phy_sfp_intel;
1034 : 0 : break;
1035 : 0 : default:
1036 [ # # ]: 0 : if (cable_tech & TXGBE_SFF_CABLE_DA_PASSIVE)
1037 : 0 : hw->phy.type = txgbe_phy_sfp_unknown_passive;
1038 [ # # ]: 0 : else if (cable_tech & TXGBE_SFF_CABLE_DA_ACTIVE)
1039 : 0 : hw->phy.type = txgbe_phy_sfp_unknown_active;
1040 : : else
1041 : 0 : hw->phy.type = txgbe_phy_sfp_unknown;
1042 : : break;
1043 : : }
1044 : : }
1045 : :
1046 : : /* Allow any DA cable vendor */
1047 [ # # ]: 0 : if (cable_tech & (TXGBE_SFF_CABLE_DA_PASSIVE |
1048 : : TXGBE_SFF_CABLE_DA_ACTIVE)) {
1049 : 0 : hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
1050 : 0 : return 0;
1051 : : }
1052 : :
1053 : : /* Verify supported 1G SFP modules */
1054 [ # # # # ]: 0 : if (comp_codes_10g == 0 && comp_codes_25g == 0 &&
1055 [ # # ]: 0 : !(hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core1 ||
1056 [ # # ]: 0 : hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core0 ||
1057 [ # # ]: 0 : hw->phy.sfp_type == txgbe_sfp_type_1g_lx_core0 ||
1058 [ # # ]: 0 : hw->phy.sfp_type == txgbe_sfp_type_1g_lx_core1 ||
1059 : : hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core0 ||
1060 : : hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core1)) {
1061 : 0 : hw->phy.type = txgbe_phy_sfp_unsupported;
1062 : 0 : hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
1063 : 0 : return TXGBE_ERR_SFP_NOT_SUPPORTED;
1064 : : }
1065 : :
1066 : 0 : hw->mac.get_device_caps(hw, &enforce_sfp);
1067 [ # # ]: 0 : if (!(enforce_sfp & TXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
1068 [ # # ]: 0 : !hw->allow_unsupported_sfp &&
1069 [ # # ]: 0 : !(hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core0 ||
1070 [ # # ]: 0 : hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core1 ||
1071 [ # # ]: 0 : hw->phy.sfp_type == txgbe_sfp_type_1g_lx_core0 ||
1072 [ # # ]: 0 : hw->phy.sfp_type == txgbe_sfp_type_1g_lx_core1 ||
1073 : : hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core0 ||
1074 : : hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core1)) {
1075 : 0 : DEBUGOUT("SFP+ module not supported");
1076 : 0 : hw->phy.type = txgbe_phy_sfp_unsupported;
1077 : 0 : hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
1078 : 0 : return TXGBE_ERR_SFP_NOT_SUPPORTED;
1079 : : }
1080 : :
1081 : 0 : hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
1082 : 0 : return err;
1083 : : }
1084 : :
1085 : : /**
1086 : : * txgbe_identify_qsfp_module - Identifies QSFP modules
1087 : : * @hw: pointer to hardware structure
1088 : : *
1089 : : * Searches for and identifies the QSFP module and assigns appropriate PHY type
1090 : : **/
1091 : 0 : s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw)
1092 : : {
1093 : : s32 err = TXGBE_ERR_PHY_ADDR_INVALID;
1094 : 0 : u8 identifier = 0, transceiver_type = 0;
1095 : : u32 value;
1096 : :
1097 : : /* config GPIO before read i2c */
1098 : : wr32(hw, TXGBE_GPIODATA, TXGBE_GPIOBIT_1);
1099 : :
1100 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml40) {
1101 : : value = rd32(hw, TXGBE_GPIOEXT);
1102 [ # # ]: 0 : if (value & TXGBE_SFP1_MOD_PRST_LS) {
1103 : 0 : hw->phy.sfp_type = txgbe_sfp_type_not_present;
1104 : 0 : return TXGBE_ERR_SFP_NOT_PRESENT;
1105 : : }
1106 : : }
1107 : :
1108 [ # # ]: 0 : if (hw->phy.media_type != txgbe_media_type_fiber_qsfp) {
1109 : 0 : hw->phy.sfp_type = txgbe_sfp_type_not_present;
1110 : 0 : return TXGBE_ERR_SFP_NOT_PRESENT;
1111 : : }
1112 : :
1113 : 0 : err = hw->mac.acquire_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
1114 [ # # ]: 0 : if (err != 0)
1115 : : return -EBUSY;
1116 : :
1117 : 0 : err = hw->phy.read_i2c_sff8636(hw, 0, TXGBE_SFF_IDENTIFIER,
1118 : : &identifier);
1119 : :
1120 [ # # ]: 0 : if (err != 0)
1121 : 0 : goto err_read_i2c_eeprom;
1122 : :
1123 [ # # ]: 0 : if (identifier != TXGBE_SFF_IDENTIFIER_QSFP &&
1124 : : identifier != TXGBE_SFF_IDENTIFIER_QSFP_PLUS) {
1125 : 0 : PMD_INIT_LOG(ERR, "port[%d] QSFP module not supported, identifier = 0x%x",
1126 : : hw->bus.lan_id, identifier);
1127 : 0 : hw->phy.type = txgbe_phy_sfp_unsupported;
1128 : : err = TXGBE_ERR_SFP_NOT_SUPPORTED;
1129 : : } else {
1130 : 0 : err = hw->phy.read_i2c_sff8636(hw, 0,
1131 : : TXGBE_ETHERNET_COMP_OFFSET,
1132 : : &transceiver_type);
1133 [ # # ]: 0 : if (err != 0)
1134 : 0 : goto err_read_i2c_eeprom;
1135 : :
1136 [ # # ]: 0 : if (transceiver_type & TXGBE_SFF_ETHERNET_40G_CR4) {
1137 [ # # ]: 0 : if (hw->bus.lan_id == 0)
1138 : 0 : hw->phy.sfp_type = txgbe_qsfp_type_40g_cu_core0;
1139 : : else
1140 : 0 : hw->phy.sfp_type = txgbe_qsfp_type_40g_cu_core1;
1141 : 0 : hw->phy.fiber_suppport_speed =
1142 : : TXGBE_LINK_SPEED_40GB_FULL |
1143 : : TXGBE_LINK_SPEED_10GB_FULL;
1144 : : }
1145 : :
1146 [ # # ]: 0 : if (transceiver_type & TXGBE_SFF_ETHERNET_40G_SR4) {
1147 [ # # ]: 0 : if (hw->bus.lan_id == 0)
1148 : 0 : hw->phy.sfp_type = txgbe_qsfp_type_40g_sr_core0;
1149 : : else
1150 : 0 : hw->phy.sfp_type = txgbe_qsfp_type_40g_sr_core1;
1151 : : }
1152 : :
1153 [ # # ]: 0 : if (transceiver_type & TXGBE_SFF_ETHERNET_40G_LR4) {
1154 [ # # ]: 0 : if (hw->bus.lan_id == 0)
1155 : 0 : hw->phy.sfp_type = txgbe_qsfp_type_40g_lr_core0;
1156 : : else
1157 : 0 : hw->phy.sfp_type = txgbe_qsfp_type_40g_lr_core1;
1158 : : }
1159 : : }
1160 : :
1161 : 0 : hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
1162 : 0 : return err;
1163 : :
1164 : 0 : err_read_i2c_eeprom:
1165 : 0 : hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
1166 : 0 : hw->phy.sfp_type = txgbe_sfp_type_not_present;
1167 : 0 : hw->phy.id = 0;
1168 : 0 : hw->phy.type = txgbe_phy_unknown;
1169 : 0 : return TXGBE_ERR_SFP_NOT_PRESENT;
1170 : : }
1171 : :
1172 : : /**
1173 : : * txgbe_read_i2c_eeprom - Reads 8 bit EEPROM word over I2C interface
1174 : : * @hw: pointer to hardware structure
1175 : : * @byte_offset: EEPROM byte offset to read
1176 : : * @eeprom_data: value read
1177 : : *
1178 : : * Performs byte read operation to SFP module's EEPROM over I2C interface.
1179 : : **/
1180 : 0 : s32 txgbe_read_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset,
1181 : : u8 *eeprom_data)
1182 : : {
1183 : 0 : return hw->phy.read_i2c_byte(hw, byte_offset,
1184 : : TXGBE_I2C_EEPROM_DEV_ADDR,
1185 : : eeprom_data);
1186 : : }
1187 : :
1188 : : /**
1189 : : * txgbe_read_i2c_sff8472 - Reads 8 bit word over I2C interface
1190 : : * @hw: pointer to hardware structure
1191 : : * @byte_offset: byte offset at address 0xA2
1192 : : * @sff8472_data: value read
1193 : : *
1194 : : * Performs byte read operation to SFP module's SFF-8472 data over I2C
1195 : : **/
1196 : 0 : s32 txgbe_read_i2c_sff8472(struct txgbe_hw *hw, u8 byte_offset,
1197 : : u8 *sff8472_data)
1198 : : {
1199 : 0 : return hw->phy.read_i2c_byte(hw, byte_offset,
1200 : : TXGBE_I2C_EEPROM_DEV_ADDR2,
1201 : : sff8472_data);
1202 : : }
1203 : :
1204 : : /**
1205 : : * txgbe_read_i2c_sff8636 - Reads 8 bit word over I2C interface
1206 : : * @hw: pointer to hardware structure
1207 : : * @byte_offset: byte offset at address 0xA2
1208 : : * @eeprom_data: value read
1209 : : *
1210 : : * Performs byte read operation to SFP module's SFF-8472 data over I2C
1211 : : **/
1212 : 0 : s32 txgbe_read_i2c_sff8636(struct txgbe_hw *hw, u8 page, u8 byte_offset,
1213 : : u8 *sff8636_data)
1214 : : {
1215 : 0 : s32 err = hw->phy.write_i2c_byte(hw, TXGBE_SFF_QSFP_PAGE_SELECT,
1216 : : TXGBE_I2C_EEPROM_DEV_ADDR,
1217 : : page);
1218 [ # # ]: 0 : if (err != 0)
1219 : : return err;
1220 : :
1221 : 0 : return hw->phy.read_i2c_byte(hw, byte_offset,
1222 : : TXGBE_I2C_EEPROM_DEV_ADDR,
1223 : : sff8636_data);
1224 : : }
1225 : :
1226 : : /**
1227 : : * txgbe_write_i2c_eeprom - Writes 8 bit EEPROM word over I2C interface
1228 : : * @hw: pointer to hardware structure
1229 : : * @byte_offset: EEPROM byte offset to write
1230 : : * @eeprom_data: value to write
1231 : : *
1232 : : * Performs byte write operation to SFP module's EEPROM over I2C interface.
1233 : : **/
1234 : 0 : s32 txgbe_write_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset,
1235 : : u8 eeprom_data)
1236 : : {
1237 : 0 : return hw->phy.write_i2c_byte(hw, byte_offset,
1238 : : TXGBE_I2C_EEPROM_DEV_ADDR,
1239 : : eeprom_data);
1240 : : }
1241 : :
1242 : : /**
1243 : : * txgbe_read_i2c_byte - Reads 8 bit word over I2C
1244 : : * @hw: pointer to hardware structure
1245 : : * @byte_offset: byte offset to read
1246 : : * @dev_addr: address to read from
1247 : : * @data: value read
1248 : : *
1249 : : * Performs byte read operation to SFP module's EEPROM over I2C interface at
1250 : : * a specified device address.
1251 : : **/
1252 : 0 : s32 txgbe_read_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
1253 : : u8 dev_addr, u8 *data)
1254 : : {
1255 : 0 : txgbe_i2c_start(hw, dev_addr);
1256 : :
1257 : : /* wait tx empty */
1258 [ # # ]: 0 : if (!po32m(hw, TXGBE_I2CICR, TXGBE_I2CICR_TXEMPTY,
1259 : : TXGBE_I2CICR_TXEMPTY, NULL, 100, 100)) {
1260 : : return -TERR_TIMEOUT;
1261 : : }
1262 : :
1263 : : /* read data */
1264 : 0 : wr32(hw, TXGBE_I2CDATA,
1265 : 0 : byte_offset | TXGBE_I2CDATA_STOP);
1266 : : wr32(hw, TXGBE_I2CDATA, TXGBE_I2CDATA_READ);
1267 : :
1268 : : /* wait for read complete */
1269 [ # # ]: 0 : if (!po32m(hw, TXGBE_I2CICR, TXGBE_I2CICR_RXFULL,
1270 : : TXGBE_I2CICR_RXFULL, NULL, 100, 100)) {
1271 : : return -TERR_TIMEOUT;
1272 : : }
1273 : :
1274 : 0 : txgbe_i2c_stop(hw);
1275 : :
1276 : 0 : *data = 0xFF & rd32(hw, TXGBE_I2CDATA);
1277 : :
1278 : 0 : return 0;
1279 : : }
1280 : :
1281 : : /**
1282 : : * txgbe_write_i2c_byte - Writes 8 bit word over I2C
1283 : : * @hw: pointer to hardware structure
1284 : : * @byte_offset: byte offset to write
1285 : : * @dev_addr: address to write to
1286 : : * @data: value to write
1287 : : *
1288 : : * Performs byte write operation to SFP module's EEPROM over I2C interface at
1289 : : * a specified device address.
1290 : : **/
1291 : 0 : s32 txgbe_write_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
1292 : : u8 dev_addr, u8 data)
1293 : : {
1294 : 0 : txgbe_i2c_start(hw, dev_addr);
1295 : :
1296 : : /* wait tx empty */
1297 [ # # ]: 0 : if (!po32m(hw, TXGBE_I2CICR, TXGBE_I2CICR_TXEMPTY,
1298 : : TXGBE_I2CICR_TXEMPTY, NULL, 100, 100))
1299 : : return -TERR_TIMEOUT;
1300 : :
1301 : 0 : wr32(hw, TXGBE_I2CDATA, byte_offset);
1302 : 0 : wr32(hw, TXGBE_I2CDATA, data | TXGBE_I2CDATA_WRITE);
1303 : :
1304 : : /* wait for write complete */
1305 [ # # ]: 0 : if (!po32m(hw, TXGBE_I2CICR, TXGBE_I2CICR_RXFULL,
1306 : : TXGBE_I2CICR_RXFULL, NULL, 100, 100))
1307 : : return -TERR_TIMEOUT;
1308 : :
1309 : 0 : txgbe_i2c_stop(hw);
1310 : :
1311 : 0 : return 0;
1312 : : }
1313 : :
1314 : : /**
1315 : : * txgbe_i2c_start - Sets I2C start condition
1316 : : * @hw: pointer to hardware structure
1317 : : *
1318 : : * Sets I2C start condition (High -> Low on SDA while SCL is High)
1319 : : **/
1320 : 0 : static void txgbe_i2c_start(struct txgbe_hw *hw, u8 dev_addr)
1321 : : {
1322 : : wr32(hw, TXGBE_I2CENA, 0);
1323 : :
1324 : : wr32(hw, TXGBE_I2CCON,
1325 : : (TXGBE_I2CCON_MENA |
1326 : : TXGBE_I2CCON_SPEED(1) |
1327 : : TXGBE_I2CCON_RESTART |
1328 : : TXGBE_I2CCON_SDIA));
1329 : 0 : wr32(hw, TXGBE_I2CTAR, dev_addr >> 1);
1330 : : wr32(hw, TXGBE_I2CSSSCLHCNT, 200);
1331 : : wr32(hw, TXGBE_I2CSSSCLLCNT, 200);
1332 : : wr32(hw, TXGBE_I2CRXTL, 0); /* 1byte for rx full signal */
1333 : : wr32(hw, TXGBE_I2CTXTL, 4);
1334 : : wr32(hw, TXGBE_I2CSCLTMOUT, 0xFFFFFF);
1335 : : wr32(hw, TXGBE_I2CSDATMOUT, 0xFFFFFF);
1336 : :
1337 : : wr32(hw, TXGBE_I2CICM, 0);
1338 : : wr32(hw, TXGBE_I2CENA, 1);
1339 : 0 : }
1340 : :
1341 : : /**
1342 : : * txgbe_i2c_stop - Sets I2C stop condition
1343 : : * @hw: pointer to hardware structure
1344 : : *
1345 : : * Sets I2C stop condition (Low -> High on SDA while SCL is High)
1346 : : **/
1347 : 0 : static void txgbe_i2c_stop(struct txgbe_hw *hw)
1348 : : {
1349 : : /* wait for completion */
1350 [ # # ]: 0 : if (!po32m(hw, TXGBE_I2CSTAT, TXGBE_I2CSTAT_MST,
1351 : : 0, NULL, 100, 100)) {
1352 : 0 : DEBUGOUT("i2c stop timeout.");
1353 : : }
1354 : :
1355 : : wr32(hw, TXGBE_I2CENA, 0);
1356 : 0 : }
1357 : :
1358 : : /**
1359 : : * txgbe_check_overtemp - Checks if an overtemp occurred.
1360 : : * @hw: pointer to hardware structure
1361 : : *
1362 : : * Checks if the temp alarm status was triggered due to overtemp
1363 : : **/
1364 : 0 : s32 txgbe_check_overtemp(struct txgbe_hw *hw)
1365 : : {
1366 : : s32 status = 0;
1367 : : u32 ts_state;
1368 : :
1369 : : /* Check that the temp alarm status was triggered */
1370 : : ts_state = rd32(hw, TXGBE_TS_ALARM_ST);
1371 : :
1372 [ # # ]: 0 : if (ts_state & TXGBE_TS_ALARM_ST_DALARM)
1373 : : status = TXGBE_ERR_UNDERTEMP;
1374 [ # # ]: 0 : else if (ts_state & TXGBE_TS_ALARM_ST_ALARM)
1375 : : status = TXGBE_ERR_OVERTEMP;
1376 : :
1377 : 0 : return status;
1378 : : }
1379 : :
1380 : : static void
1381 : 0 : txgbe_set_sgmii_an37_ability(struct txgbe_hw *hw)
1382 : : {
1383 : : u32 value;
1384 : 0 : u8 device_type = hw->subsystem_device_id & 0xF0;
1385 : :
1386 : : wr32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_CTL1, 0x3002);
1387 : : /* for sgmii + external phy, set to 0x0105 (phy sgmii mode) */
1388 : : /* for sgmii direct link, set to 0x010c (mac sgmii mode) */
1389 [ # # ]: 0 : if (device_type == TXGBE_DEV_ID_MAC_SGMII ||
1390 [ # # ]: 0 : hw->phy.media_type == txgbe_media_type_fiber)
1391 : : wr32_epcs(hw, SR_MII_MMD_AN_CTL, 0x010C);
1392 : 0 : else if (device_type == TXGBE_DEV_ID_SGMII ||
1393 [ # # ]: 0 : device_type == TXGBE_DEV_ID_XAUI)
1394 : : wr32_epcs(hw, SR_MII_MMD_AN_CTL, 0x0105);
1395 : : wr32_epcs(hw, SR_MII_MMD_DIGI_CTL, 0x0200);
1396 : : value = rd32_epcs(hw, SR_MII_MMD_CTL);
1397 : 0 : value = (value & ~0x1200) | (0x1 << 9);
1398 [ # # ]: 0 : if (hw->autoneg)
1399 : 0 : value |= SR_MII_MMD_CTL_AN_EN;
1400 : : wr32_epcs(hw, SR_MII_MMD_CTL, value);
1401 : 0 : }
1402 : :
1403 : : static s32
1404 : 0 : txgbe_set_link_to_kr(struct txgbe_hw *hw, bool autoneg)
1405 : : {
1406 : : u32 i;
1407 : : u16 value;
1408 : : s32 err = 0;
1409 : :
1410 : : /* 1. Wait xpcs power-up good */
1411 [ # # ]: 0 : for (i = 0; i < 100; i++) {
1412 [ # # ]: 0 : if ((rd32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_STATUS) &
1413 : : VR_XS_OR_PCS_MMD_DIGI_STATUS_PSEQ_MASK) ==
1414 : : VR_XS_OR_PCS_MMD_DIGI_STATUS_PSEQ_POWER_GOOD)
1415 : : break;
1416 : : msec_delay(10);
1417 : : }
1418 [ # # ]: 0 : if (i == 100) {
1419 : : err = TXGBE_ERR_XPCS_POWER_UP_FAILED;
1420 : 0 : goto out;
1421 : : }
1422 : 0 : BP_LOG("It is set to kr.\n");
1423 : :
1424 : : wr32_epcs(hw, VR_AN_INTR_MSK, 0x7);
1425 : : wr32_epcs(hw, TXGBE_PHY_TX_POWER_ST_CTL, 0x00FC);
1426 : : wr32_epcs(hw, TXGBE_PHY_RX_POWER_ST_CTL, 0x00FC);
1427 : :
1428 [ # # ]: 0 : if (!autoneg) {
1429 : : /* 2. Disable xpcs AN-73 */
1430 : : wr32_epcs(hw, SR_AN_CTRL,
1431 : : SR_AN_CTRL_AN_EN | SR_AN_CTRL_EXT_NP);
1432 : :
1433 : : wr32_epcs(hw, VR_AN_KR_MODE_CL, VR_AN_KR_MODE_CL_PDET);
1434 : :
1435 [ # # ]: 0 : if (!(hw->devarg.auto_neg == 1)) {
1436 : : wr32_epcs(hw, SR_AN_CTRL, 0);
1437 : : wr32_epcs(hw, VR_AN_KR_MODE_CL, 0);
1438 : : } else {
1439 : 0 : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1);
1440 : 0 : value &= ~(1 << 6);
1441 : 0 : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
1442 : : }
1443 [ # # ]: 0 : if (hw->devarg.present == 1) {
1444 : 0 : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1);
1445 : 0 : value |= TXGBE_PHY_TX_EQ_CTL1_DEF;
1446 : 0 : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
1447 : : }
1448 [ # # ]: 0 : if (hw->devarg.poll == 1) {
1449 : : wr32_epcs(hw, VR_PMA_KRTR_TIMER_CTRL0,
1450 : : VR_PMA_KRTR_TIMER_MAX_WAIT);
1451 : : wr32_epcs(hw, VR_PMA_KRTR_TIMER_CTRL2, 0xA697);
1452 : : }
1453 : :
1454 : : /* 3. Set VR_XS_PMA_Gen5_12G_MPLLA_CTRL3 Register
1455 : : * Bit[10:0](MPLLA_BANDWIDTH) = 11'd123 (default: 11'd16)
1456 : : */
1457 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL3,
1458 : : TXGBE_PHY_MPLLA_CTL3_MULTIPLIER_BW_10GBASER_KR);
1459 : :
1460 : : /* 4. Set VR_XS_PMA_Gen5_12G_MISC_CTRL0 Register
1461 : : * Bit[12:8](RX_VREF_CTRL) = 5'hF (default: 5'h11)
1462 : : */
1463 : : wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0xCF00);
1464 : :
1465 : : /* 5. Set VR_XS_PMA_Gen5_12G_RX_EQ_CTRL0 Register
1466 : : * Bit[15:8](VGA1/2_GAIN_0) = 8'h77
1467 : : * Bit[7:5](CTLE_POLE_0) = 3'h2
1468 : : * Bit[4:0](CTLE_BOOST_0) = 4'hA
1469 : : */
1470 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL0, 0x774A);
1471 : :
1472 : : /* 6. Set VR_MII_Gen5_12G_RX_GENCTRL3 Register
1473 : : * Bit[2:0](LOS_TRSHLD_0) = 3'h4 (default: 3)
1474 : : */
1475 : : wr32_epcs(hw, TXGBE_PHY_RX_GEN_CTL3, 0x0004);
1476 : :
1477 : : /* 7. Initialize the mode by setting VR XS or PCS MMD Digital
1478 : : * Control1 Register Bit[15](VR_RST)
1479 : : */
1480 : : wr32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_CTL1, 0xA000);
1481 : :
1482 : : /* Wait phy initialization done */
1483 [ # # ]: 0 : for (i = 0; i < 100; i++) {
1484 : 0 : if ((rd32_epcs(hw,
1485 [ # # ]: 0 : VR_XS_OR_PCS_MMD_DIGI_CTL1) &
1486 : : VR_XS_OR_PCS_MMD_DIGI_CTL1_VR_RST) == 0)
1487 : : break;
1488 : : msleep(100);
1489 : : }
1490 [ # # ]: 0 : if (i == 100) {
1491 : : err = TXGBE_ERR_PHY_INIT_NOT_DONE;
1492 : 0 : goto out;
1493 : : }
1494 : : } else {
1495 : : wr32_epcs(hw, VR_AN_KR_MODE_CL, 0x1);
1496 : : }
1497 : :
1498 [ # # ]: 0 : if (hw->phy.ffe_set == TXGBE_BP_M_KR) {
1499 : : value = (0x1804 & ~0x3F3F);
1500 : 0 : value |= hw->phy.ffe_main << 8 | hw->phy.ffe_pre;
1501 : 0 : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value);
1502 : :
1503 : 0 : value = (0x50 & ~0x7F) | (1 << 6) | hw->phy.ffe_post;
1504 : 0 : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
1505 : : }
1506 : 0 : out:
1507 : 0 : return err;
1508 : : }
1509 : :
1510 : : static s32
1511 : 0 : txgbe_set_link_to_kx4(struct txgbe_hw *hw, bool autoneg)
1512 : : {
1513 : : u32 i;
1514 : : s32 err = 0;
1515 : : u32 value;
1516 : :
1517 : : /* Check link status, if already set, skip setting it again */
1518 [ # # ]: 0 : if (hw->link_status == TXGBE_LINK_STATUS_KX4)
1519 : 0 : goto out;
1520 : :
1521 : 0 : BP_LOG("It is set to kx4.\n");
1522 : : wr32_epcs(hw, TXGBE_PHY_TX_POWER_ST_CTL, 0);
1523 : : wr32_epcs(hw, TXGBE_PHY_RX_POWER_ST_CTL, 0);
1524 : :
1525 : : /* 1. Wait xpcs power-up good */
1526 [ # # ]: 0 : for (i = 0; i < 100; i++) {
1527 [ # # ]: 0 : if ((rd32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_STATUS) &
1528 : : VR_XS_OR_PCS_MMD_DIGI_STATUS_PSEQ_MASK) ==
1529 : : VR_XS_OR_PCS_MMD_DIGI_STATUS_PSEQ_POWER_GOOD)
1530 : : break;
1531 : : msec_delay(10);
1532 : : }
1533 [ # # ]: 0 : if (i == 100) {
1534 : : err = TXGBE_ERR_XPCS_POWER_UP_FAILED;
1535 : 0 : goto out;
1536 : : }
1537 : :
1538 : : wr32m(hw, TXGBE_MACTXCFG, TXGBE_MACTXCFG_TXE, ~TXGBE_MACTXCFG_TXE);
1539 : : wr32m(hw, TXGBE_MACRXCFG, TXGBE_MACRXCFG_ENA, ~TXGBE_MACRXCFG_ENA);
1540 : 0 : hw->mac.disable_sec_tx_path(hw);
1541 : :
1542 : : /* 2. Disable xpcs AN-73 */
1543 [ # # ]: 0 : if (!autoneg)
1544 : : wr32_epcs(hw, SR_AN_CTRL, 0x0);
1545 : : else
1546 : : wr32_epcs(hw, SR_AN_CTRL, 0x3000);
1547 : :
1548 : : /* Disable PHY MPLLA for eth mode change(after ECO) */
1549 : : wr32_ephy(hw, 0x4, 0x250A);
1550 : : txgbe_flush(hw);
1551 : : msec_delay(1);
1552 : :
1553 : : /* Set the eth change_mode bit first in mis_rst register
1554 : : * for corresponding LAN port
1555 : : */
1556 : 0 : wr32(hw, TXGBE_RST, TXGBE_RST_ETH(hw->bus.lan_id));
1557 : :
1558 : : /* Set SR PCS Control2 Register Bits[1:0] = 2'b01
1559 : : * PCS_TYPE_SEL: non KR
1560 : : */
1561 : : wr32_epcs(hw, SR_XS_PCS_CTRL2,
1562 : : SR_PCS_CTRL2_TYPE_SEL_X);
1563 : :
1564 : : /* Set SR PMA MMD Control1 Register Bit[13] = 1'b1
1565 : : * SS13: 10G speed
1566 : : */
1567 : : wr32_epcs(hw, SR_PMA_CTRL1,
1568 : : SR_PMA_CTRL1_SS13_KX4);
1569 : :
1570 : : value = (0xf5f0 & ~0x7F0) | (0x5 << 8) | (0x7 << 5) | 0xF0;
1571 : : wr32_epcs(hw, TXGBE_PHY_TX_GENCTRL1, value);
1572 : :
1573 [ # # ]: 0 : if ((hw->subsystem_device_id & 0xFF) == TXGBE_DEV_ID_MAC_XAUI)
1574 : : wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0xCF00);
1575 : : else
1576 : : wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0x4F00);
1577 : :
1578 [ # # ]: 0 : for (i = 0; i < 4; i++) {
1579 : : if (i == 0)
1580 : : value = (0x45 & ~0xFFFF) | (0x7 << 12) |
1581 : : (0x7 << 8) | 0x6;
1582 : : else
1583 : : value = (0xff06 & ~0xFFFF) | (0x7 << 12) |
1584 : : (0x7 << 8) | 0x6;
1585 : 0 : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL0 + i, value);
1586 : : }
1587 : :
1588 : : value = 0x0 & ~0x7777;
1589 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_ATT_LVL0, value);
1590 : :
1591 : : wr32_epcs(hw, TXGBE_PHY_DFE_TAP_CTL0, 0x0);
1592 : :
1593 : : value = (0x6db & ~0xFFF) | (0x1 << 9) | (0x1 << 6) | (0x1 << 3) | 0x1;
1594 : : wr32_epcs(hw, TXGBE_PHY_RX_GEN_CTL3, value);
1595 : :
1596 : : /* Set VR XS, PMA, or MII Gen5 12G PHY MPLLA
1597 : : * Control 0 Register Bit[7:0] = 8'd40 //MPLLA_MULTIPLIER
1598 : : */
1599 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL0,
1600 : : TXGBE_PHY_MPLLA_CTL0_MULTIPLIER_OTHER);
1601 : :
1602 : : /* Set VR XS, PMA or MII Gen5 12G PHY MPLLA
1603 : : * Control 3 Register Bit[10:0] = 11'd86 //MPLLA_BANDWIDTH
1604 : : */
1605 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL3,
1606 : : TXGBE_PHY_MPLLA_CTL3_MULTIPLIER_BW_OTHER);
1607 : :
1608 : : /* Set VR XS, PMA, or MII Gen5 12G PHY VCO
1609 : : * Calibration Load 0 Register Bit[12:0] = 13'd1360 //VCO_LD_VAL_0
1610 : : */
1611 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_LD0,
1612 : : TXGBE_PHY_VCO_CAL_LD0_OTHER);
1613 : :
1614 : : /* Set VR XS, PMA, or MII Gen5 12G PHY VCO
1615 : : * Calibration Load 1 Register Bit[12:0] = 13'd1360 //VCO_LD_VAL_1
1616 : : */
1617 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_LD1,
1618 : : TXGBE_PHY_VCO_CAL_LD0_OTHER);
1619 : :
1620 : : /* Set VR XS, PMA, or MII Gen5 12G PHY VCO
1621 : : * Calibration Load 2 Register Bit[12:0] = 13'd1360 //VCO_LD_VAL_2
1622 : : */
1623 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_LD2,
1624 : : TXGBE_PHY_VCO_CAL_LD0_OTHER);
1625 : : /* Set VR XS, PMA, or MII Gen5 12G PHY VCO
1626 : : * Calibration Load 3 Register Bit[12:0] = 13'd1360 //VCO_LD_VAL_3
1627 : : */
1628 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_LD3,
1629 : : TXGBE_PHY_VCO_CAL_LD0_OTHER);
1630 : : /* Set VR XS, PMA, or MII Gen5 12G PHY VCO
1631 : : * Calibration Reference 0 Register Bit[5:0] = 6'd34 //VCO_REF_LD_0/1
1632 : : */
1633 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_REF0, 0x2222);
1634 : :
1635 : : /* Set VR XS, PMA, or MII Gen5 12G PHY VCO
1636 : : * Calibration Reference 1 Register Bit[5:0] = 6'd34 //VCO_REF_LD_2/3
1637 : : */
1638 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_REF1, 0x2222);
1639 : :
1640 : : /* Set VR XS, PMA, or MII Gen5 12G PHY AFE-DFE
1641 : : * Enable Register Bit[7:0] = 8'd0 //AFE_EN_0/3_1, DFE_EN_0/3_1
1642 : : */
1643 : : wr32_epcs(hw, TXGBE_PHY_AFE_DFE_ENABLE, 0x0);
1644 : :
1645 : : /* Set VR XS, PMA, or MII Gen5 12G PHY Rx
1646 : : * Equalization Control 4 Register Bit[3:0] = 4'd0 //CONT_ADAPT_0/3_1
1647 : : */
1648 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL, 0x00F0);
1649 : :
1650 : : /* Set VR XS, PMA, or MII Gen5 12G PHY Tx Rate
1651 : : * Control Register Bit[14:12], Bit[10:8], Bit[6:4], Bit[2:0],
1652 : : * all rates to 3'b010 //TX0/1/2/3_RATE
1653 : : */
1654 : : wr32_epcs(hw, TXGBE_PHY_TX_RATE_CTL, 0x2222);
1655 : :
1656 : : /* Set VR XS, PMA, or MII Gen5 12G PHY Rx Rate
1657 : : * Control Register Bit[13:12], Bit[9:8], Bit[5:4], Bit[1:0],
1658 : : * all rates to 2'b10 //RX0/1/2/3_RATE
1659 : : */
1660 : : wr32_epcs(hw, TXGBE_PHY_RX_RATE_CTL, 0x2222);
1661 : :
1662 : : /* Set VR XS, PMA, or MII Gen5 12G PHY Tx General
1663 : : * Control 2 Register Bit[15:8] = 2'b01 //TX0/1/2/3_WIDTH: 10bits
1664 : : */
1665 : : wr32_epcs(hw, TXGBE_PHY_TX_GEN_CTL2, 0x5500);
1666 : :
1667 : : /* Set VR XS, PMA, or MII Gen5 12G PHY Rx General
1668 : : * Control 2 Register Bit[15:8] = 2'b01 //RX0/1/2/3_WIDTH: 10bits
1669 : : */
1670 : : wr32_epcs(hw, TXGBE_PHY_RX_GEN_CTL2, 0x5500);
1671 : :
1672 : : /* Set VR XS, PMA, or MII Gen5 12G PHY MPLLA Control
1673 : : * 2 Register Bit[10:8] = 3'b010
1674 : : * MPLLA_DIV16P5_CLK_EN=0, MPLLA_DIV10_CLK_EN=1, MPLLA_DIV8_CLK_EN=0
1675 : : */
1676 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL2,
1677 : : TXGBE_PHY_MPLLA_CTL2_DIV_CLK_EN_10);
1678 : :
1679 : : wr32_epcs(hw, 0x1f0000, 0x0);
1680 : : wr32_epcs(hw, 0x1f8001, 0x0);
1681 : : wr32_epcs(hw, SR_MII_MMD_DIGI_CTL, 0x0);
1682 : :
1683 : : /* 10. Initialize the mode by setting VR XS or PCS MMD Digital Control1
1684 : : * Register Bit[15](VR_RST)
1685 : : */
1686 : : wr32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_CTL1, 0xA000);
1687 : :
1688 : : /* Wait phy initialization done */
1689 [ # # ]: 0 : for (i = 0; i < 100; i++) {
1690 [ # # ]: 0 : if ((rd32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_CTL1) &
1691 : : VR_XS_OR_PCS_MMD_DIGI_CTL1_VR_RST) == 0)
1692 : : break;
1693 : : msleep(100);
1694 : : }
1695 : :
1696 : : /* If success, set link status */
1697 : 0 : hw->link_status = TXGBE_LINK_STATUS_KX4;
1698 : :
1699 [ # # ]: 0 : if (i == 100) {
1700 : : err = TXGBE_ERR_PHY_INIT_NOT_DONE;
1701 : 0 : goto out;
1702 : : }
1703 : :
1704 [ # # ]: 0 : if (hw->phy.ffe_set == TXGBE_BP_M_KX4) {
1705 : : value = (0x1804 & ~0x3F3F);
1706 : 0 : value |= hw->phy.ffe_main << 8 | hw->phy.ffe_pre;
1707 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value);
1708 : :
1709 : 0 : value = (0x50 & ~0x7F) | (1 << 6) | hw->phy.ffe_post;
1710 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
1711 [ # # ]: 0 : } else if (hw->fw_version <= TXGBE_FW_N_TXEQ) {
1712 : : value = (0x1804 & ~0x3F3F);
1713 : : value |= 40 << 8;
1714 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value);
1715 : :
1716 : : value = (0x50 & ~0x7F) | (1 << 6);
1717 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
1718 : : }
1719 : 0 : out:
1720 : 0 : return err;
1721 : : }
1722 : :
1723 : : static s32
1724 : 0 : txgbe_set_link_to_kx(struct txgbe_hw *hw,
1725 : : u32 speed,
1726 : : bool autoneg)
1727 : : {
1728 : : u32 i;
1729 : : s32 err = 0;
1730 : : u32 wdata = 0;
1731 : : u32 value;
1732 : :
1733 : : /* Check link status, if already set, skip setting it again */
1734 [ # # ]: 0 : if (hw->link_status == TXGBE_LINK_STATUS_KX)
1735 : 0 : goto out;
1736 : :
1737 : 0 : BP_LOG("It is set to kx. speed =0x%x\n", speed);
1738 : : wr32_epcs(hw, TXGBE_PHY_TX_POWER_ST_CTL, 0x00FC);
1739 : : wr32_epcs(hw, TXGBE_PHY_RX_POWER_ST_CTL, 0x00FC);
1740 : :
1741 : : /* 1. Wait xpcs power-up good */
1742 [ # # ]: 0 : for (i = 0; i < 100; i++) {
1743 [ # # ]: 0 : if ((rd32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_STATUS) &
1744 : : VR_XS_OR_PCS_MMD_DIGI_STATUS_PSEQ_MASK) ==
1745 : : VR_XS_OR_PCS_MMD_DIGI_STATUS_PSEQ_POWER_GOOD)
1746 : : break;
1747 : : msec_delay(10);
1748 : : }
1749 [ # # ]: 0 : if (i == 100) {
1750 : : err = TXGBE_ERR_XPCS_POWER_UP_FAILED;
1751 : 0 : goto out;
1752 : : }
1753 : :
1754 : : wr32m(hw, TXGBE_MACTXCFG, TXGBE_MACTXCFG_TXE, ~TXGBE_MACTXCFG_TXE);
1755 : : wr32m(hw, TXGBE_MACRXCFG, TXGBE_MACRXCFG_ENA, ~TXGBE_MACRXCFG_ENA);
1756 : 0 : hw->mac.disable_sec_tx_path(hw);
1757 : :
1758 : : /* 2. Disable xpcs AN-73 */
1759 [ # # ]: 0 : if (!autoneg)
1760 : : wr32_epcs(hw, SR_AN_CTRL, 0x0);
1761 : : else
1762 : : wr32_epcs(hw, SR_AN_CTRL, 0x3000);
1763 : :
1764 : : /* Disable PHY MPLLA for eth mode change(after ECO) */
1765 : : wr32_ephy(hw, 0x4, 0x240A);
1766 : : txgbe_flush(hw);
1767 : : msec_delay(1);
1768 : :
1769 : : /* Set the eth change_mode bit first in mis_rst register
1770 : : * for corresponding LAN port
1771 : : */
1772 : 0 : wr32(hw, TXGBE_RST, TXGBE_RST_ETH(hw->bus.lan_id));
1773 : :
1774 : : /* Set SR PCS Control2 Register Bits[1:0] = 2'b01
1775 : : * PCS_TYPE_SEL: non KR
1776 : : */
1777 : : wr32_epcs(hw, SR_XS_PCS_CTRL2,
1778 : : SR_PCS_CTRL2_TYPE_SEL_X);
1779 : :
1780 : : /* Set SR PMA MMD Control1 Register Bit[13] = 1'b0
1781 : : * SS13: 1G speed
1782 : : */
1783 : : wr32_epcs(hw, SR_PMA_CTRL1,
1784 : : SR_PMA_CTRL1_SS13_KX);
1785 : :
1786 : : /* Set SR MII MMD Control Register to corresponding speed: {Bit[6],
1787 : : * Bit[13]}=[2'b00,2'b01,2'b10]->[10M,100M,1G]
1788 : : */
1789 [ # # ]: 0 : if (speed == TXGBE_LINK_SPEED_100M_FULL)
1790 : : wdata = 0x2100;
1791 [ # # ]: 0 : else if (speed == TXGBE_LINK_SPEED_1GB_FULL)
1792 : : wdata = 0x0140;
1793 [ # # ]: 0 : else if (speed == TXGBE_LINK_SPEED_10M_FULL)
1794 : : wdata = 0x0100;
1795 : : wr32_epcs(hw, SR_MII_MMD_CTL,
1796 : : wdata);
1797 : :
1798 : : value = (0xf5f0 & ~0x710) | (0x5 << 8) | 0x10;
1799 : : wr32_epcs(hw, TXGBE_PHY_TX_GENCTRL1, value);
1800 : :
1801 [ # # ]: 0 : if (hw->devarg.sgmii == 1)
1802 : : wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0x4F00);
1803 : : else
1804 : : wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0xCF00);
1805 : :
1806 [ # # ]: 0 : for (i = 0; i < 4; i++) {
1807 [ # # ]: 0 : if (i) {
1808 : : value = 0xff06;
1809 : : } else {
1810 : : value = (0x45 & ~0xFFFF) | (0x7 << 12) |
1811 : : (0x7 << 8) | 0x6;
1812 : : }
1813 : 0 : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL0 + i, value);
1814 : : }
1815 : :
1816 : : value = 0x0 & ~0x7;
1817 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_ATT_LVL0, value);
1818 : :
1819 : : wr32_epcs(hw, TXGBE_PHY_DFE_TAP_CTL0, 0x0);
1820 : :
1821 : : value = (0x6db & ~0x7) | 0x4;
1822 : : wr32_epcs(hw, TXGBE_PHY_RX_GEN_CTL3, value);
1823 : :
1824 : : /* Set VR XS, PMA, or MII Gen5 12G PHY MPLLA Control
1825 : : * 0 Register Bit[7:0] = 8'd32 //MPLLA_MULTIPLIER
1826 : : */
1827 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL0,
1828 : : TXGBE_PHY_MPLLA_CTL0_MULTIPLIER_1GBASEX_KX);
1829 : :
1830 : : /* Set VR XS, PMA or MII Gen5 12G PHY MPLLA Control
1831 : : * 3 Register Bit[10:0] = 11'd70 //MPLLA_BANDWIDTH
1832 : : */
1833 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL3,
1834 : : TXGBE_PHY_MPLLA_CTL3_MULTIPLIER_BW_1GBASEX_KX);
1835 : :
1836 : : /* Set VR XS, PMA, or MII Gen5 12G PHY VCO
1837 : : * Calibration Load 0 Register Bit[12:0] = 13'd1344 //VCO_LD_VAL_0
1838 : : */
1839 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_LD0,
1840 : : TXGBE_PHY_VCO_CAL_LD0_1GBASEX_KX);
1841 : :
1842 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_LD1, 0x549);
1843 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_LD2, 0x549);
1844 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_LD3, 0x549);
1845 : :
1846 : : /* Set VR XS, PMA, or MII Gen5 12G PHY VCO
1847 : : * Calibration Reference 0 Register Bit[5:0] = 6'd42 //VCO_REF_LD_0
1848 : : */
1849 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_REF0,
1850 : : TXGBE_PHY_VCO_CAL_REF0_LD0_1GBASEX_KX);
1851 : :
1852 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_REF1, 0x2929);
1853 : :
1854 : : /* Set VR XS, PMA, or MII Gen5 12G PHY AFE-DFE
1855 : : * Enable Register Bit[4], Bit[0] = 1'b0 //AFE_EN_0, DFE_EN_0
1856 : : */
1857 : : wr32_epcs(hw, TXGBE_PHY_AFE_DFE_ENABLE,
1858 : : 0x0);
1859 : : /* Set VR XS, PMA, or MII Gen5 12G PHY Rx
1860 : : * Equalization Control 4 Register Bit[0] = 1'b0 //CONT_ADAPT_0
1861 : : */
1862 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL,
1863 : : 0x0010);
1864 : : /* Set VR XS, PMA, or MII Gen5 12G PHY Tx Rate
1865 : : * Control Register Bit[2:0] = 3'b011 //TX0_RATE
1866 : : */
1867 : : wr32_epcs(hw, TXGBE_PHY_TX_RATE_CTL,
1868 : : TXGBE_PHY_TX_RATE_CTL_TX0_RATE_1GBASEX_KX);
1869 : :
1870 : : /* Set VR XS, PMA, or MII Gen5 12G PHY Rx Rate
1871 : : * Control Register Bit[2:0] = 3'b011 //RX0_RATE
1872 : : */
1873 : : wr32_epcs(hw, TXGBE_PHY_RX_RATE_CTL,
1874 : : TXGBE_PHY_RX_RATE_CTL_RX0_RATE_1GBASEX_KX);
1875 : :
1876 : : /* Set VR XS, PMA, or MII Gen5 12G PHY Tx General
1877 : : * Control 2 Register Bit[9:8] = 2'b01 //TX0_WIDTH: 10bits
1878 : : */
1879 : : wr32_epcs(hw, TXGBE_PHY_TX_GEN_CTL2,
1880 : : TXGBE_PHY_TX_GEN_CTL2_TX0_WIDTH_OTHER);
1881 : : /* Set VR XS, PMA, or MII Gen5 12G PHY Rx General
1882 : : * Control 2 Register Bit[9:8] = 2'b01 //RX0_WIDTH: 10bits
1883 : : */
1884 : : wr32_epcs(hw, TXGBE_PHY_RX_GEN_CTL2,
1885 : : TXGBE_PHY_RX_GEN_CTL2_RX0_WIDTH_OTHER);
1886 : : /* Set VR XS, PMA, or MII Gen5 12G PHY MPLLA Control
1887 : : * 2 Register Bit[10:8] = 3'b010 //MPLLA_DIV16P5_CLK_EN=0,
1888 : : * MPLLA_DIV10_CLK_EN=1, MPLLA_DIV8_CLK_EN=0
1889 : : */
1890 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL2,
1891 : : TXGBE_PHY_MPLLA_CTL2_DIV_CLK_EN_10);
1892 : :
1893 : : /* VR MII MMD AN Control Register Bit[8] = 1'b1 //MII_CTRL
1894 : : * Set to 8bit MII (required in 10M/100M SGMII)
1895 : : */
1896 : : wr32_epcs(hw, SR_MII_MMD_AN_CTL,
1897 : : 0x0100);
1898 : :
1899 : : /* 10. Initialize the mode by setting VR XS or PCS MMD Digital Control1
1900 : : * Register Bit[15](VR_RST)
1901 : : */
1902 : : wr32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_CTL1, 0xA000);
1903 : :
1904 : : /* Wait phy initialization done */
1905 [ # # ]: 0 : for (i = 0; i < 100; i++) {
1906 [ # # ]: 0 : if ((rd32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_CTL1) &
1907 : : VR_XS_OR_PCS_MMD_DIGI_CTL1_VR_RST) == 0)
1908 : : break;
1909 : : msleep(100);
1910 : : }
1911 : :
1912 : : /* If success, set link status */
1913 : 0 : hw->link_status = TXGBE_LINK_STATUS_KX;
1914 : :
1915 [ # # ]: 0 : if (i == 100) {
1916 : : err = TXGBE_ERR_PHY_INIT_NOT_DONE;
1917 : 0 : goto out;
1918 : : }
1919 : :
1920 [ # # ]: 0 : if (hw->phy.ffe_set == TXGBE_BP_M_KX) {
1921 : 0 : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0) & ~0x3F3F;
1922 : 0 : value |= hw->phy.ffe_main << 8 | hw->phy.ffe_pre;
1923 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value);
1924 : :
1925 : 0 : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0) & ~0x7F;
1926 : 0 : value |= hw->phy.ffe_post | (1 << 6);
1927 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
1928 [ # # ]: 0 : } else if (hw->fw_version <= TXGBE_FW_N_TXEQ) {
1929 : : value = (0x1804 & ~0x3F3F) | (40 << 8);
1930 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value);
1931 : :
1932 : : value = (0x50 & ~0x7F) | (1 << 6);
1933 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
1934 : : }
1935 : 0 : out:
1936 : 0 : return err;
1937 : : }
1938 : :
1939 : : static s32
1940 : 0 : txgbe_set_link_to_sfi(struct txgbe_hw *hw,
1941 : : u32 speed)
1942 : : {
1943 : : u32 i;
1944 : : s32 err = 0;
1945 : : u32 value = 0;
1946 : :
1947 : : /* Set the module link speed */
1948 : 0 : hw->mac.set_rate_select_speed(hw, speed);
1949 : : /* 1. Wait xpcs power-up good */
1950 [ # # ]: 0 : for (i = 0; i < 100; i++) {
1951 [ # # ]: 0 : if ((rd32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_STATUS) &
1952 : : VR_XS_OR_PCS_MMD_DIGI_STATUS_PSEQ_MASK) ==
1953 : : VR_XS_OR_PCS_MMD_DIGI_STATUS_PSEQ_POWER_GOOD)
1954 : : break;
1955 : : msec_delay(10);
1956 : : }
1957 [ # # ]: 0 : if (i == 100) {
1958 : : err = TXGBE_ERR_XPCS_POWER_UP_FAILED;
1959 : 0 : goto out;
1960 : : }
1961 : :
1962 : : wr32m(hw, TXGBE_MACTXCFG, TXGBE_MACTXCFG_TXE, ~TXGBE_MACTXCFG_TXE);
1963 : : wr32m(hw, TXGBE_MACRXCFG, TXGBE_MACRXCFG_ENA, ~TXGBE_MACRXCFG_ENA);
1964 : 0 : hw->mac.disable_sec_tx_path(hw);
1965 : :
1966 : : /* 2. Disable xpcs AN-73 */
1967 : : wr32_epcs(hw, SR_AN_CTRL, 0x0);
1968 : :
1969 : : /* Disable PHY MPLLA for eth mode change(after ECO) */
1970 : : wr32_ephy(hw, 0x4, 0x243A);
1971 : : txgbe_flush(hw);
1972 : : msec_delay(1);
1973 : : /* Set the eth change_mode bit first in mis_rst register
1974 : : * for corresponding LAN port
1975 : : */
1976 : 0 : wr32(hw, TXGBE_RST, TXGBE_RST_ETH(hw->bus.lan_id));
1977 : :
1978 [ # # ]: 0 : if (speed == TXGBE_LINK_SPEED_10GB_FULL) {
1979 : : /* Set SR PCS Control2 Register Bits[1:0] = 2'b00
1980 : : * PCS_TYPE_SEL: KR
1981 : : */
1982 : : wr32_epcs(hw, SR_XS_PCS_CTRL2, 0);
1983 : : value = rd32_epcs(hw, SR_PMA_CTRL1);
1984 : 0 : value = value | 0x2000;
1985 : : wr32_epcs(hw, SR_PMA_CTRL1, value);
1986 : : /* Set VR_XS_PMA_Gen5_12G_MPLLA_CTRL0 Register Bit[7:0] = 8'd33
1987 : : * MPLLA_MULTIPLIER
1988 : : */
1989 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL0, 0x0021);
1990 : : /* 3. Set VR_XS_PMA_Gen5_12G_MPLLA_CTRL3 Register
1991 : : * Bit[10:0](MPLLA_BANDWIDTH) = 11'd0
1992 : : */
1993 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL3, 0);
1994 : : value = rd32_epcs(hw, TXGBE_PHY_TX_GENCTRL1);
1995 : 0 : value = (value & ~0x700) | 0x500;
1996 : : wr32_epcs(hw, TXGBE_PHY_TX_GENCTRL1, value);
1997 : : /* 4. Set VR_XS_PMA_Gen5_12G_MISC_CTRL0 Register
1998 : : * Bit[12:8](RX_VREF_CTRL) = 5'hF
1999 : : */
2000 : : wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0xCF00);
2001 : : /* Set VR_XS_PMA_Gen5_12G_VCO_CAL_LD0 Register
2002 : : * Bit[12:0] = 13'd1353 //VCO_LD_VAL_0
2003 : : */
2004 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_LD0, 0x0549);
2005 : : /* Set VR_XS_PMA_Gen5_12G_VCO_CAL_REF0 Register
2006 : : * Bit[5:0] = 6'd41 //VCO_REF_LD_0
2007 : : */
2008 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_REF0, 0x0029);
2009 : : /* Set VR_XS_PMA_Gen5_12G_TX_RATE_CTRL Register
2010 : : * Bit[2:0] = 3'b000 //TX0_RATE
2011 : : */
2012 : : wr32_epcs(hw, TXGBE_PHY_TX_RATE_CTL, 0);
2013 : : /* Set VR_XS_PMA_Gen5_12G_RX_RATE_CTRL Register
2014 : : * Bit[2:0] = 3'b000 //RX0_RATE
2015 : : */
2016 : : wr32_epcs(hw, TXGBE_PHY_RX_RATE_CTL, 0);
2017 : : /* Set VR_XS_PMA_Gen5_12G_TX_GENCTRL2 Register Bit[9:8] = 2'b11
2018 : : * TX0_WIDTH: 20bits
2019 : : */
2020 : : wr32_epcs(hw, TXGBE_PHY_TX_GEN_CTL2, 0x0300);
2021 : : /* Set VR_XS_PMA_Gen5_12G_RX_GENCTRL2 Register Bit[9:8] = 2'b11
2022 : : * RX0_WIDTH: 20bits
2023 : : */
2024 : : wr32_epcs(hw, TXGBE_PHY_RX_GEN_CTL2, 0x0300);
2025 : : /* Set VR_XS_PMA_Gen5_12G_MPLLA_CTRL2 Register
2026 : : * Bit[10:8] = 3'b110
2027 : : * MPLLA_DIV16P5_CLK_EN=1
2028 : : * MPLLA_DIV10_CLK_EN=1
2029 : : * MPLLA_DIV8_CLK_EN=0
2030 : : */
2031 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL2, 0x0600);
2032 : :
2033 [ # # ]: 0 : if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
2034 : : hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1) {
2035 : : /* 7. Set VR_XS_PMA_Gen5_12G_RX_EQ_CTRL0 Register
2036 : : * Bit[15:8](VGA1/2_GAIN_0) = 8'h77
2037 : : * Bit[7:5](CTLE_POLE_0) = 3'h2
2038 : : * Bit[4:0](CTLE_BOOST_0) = 4'hF
2039 : : */
2040 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL0, 0x774F);
2041 : :
2042 : : } else {
2043 : : /* 7. Set VR_XS_PMA_Gen5_12G_RX_EQ_CTRL0 Register
2044 : : * Bit[15:8](VGA1/2_GAIN_0) = 8'h00
2045 : : * Bit[7:5](CTLE_POLE_0) = 3'h2
2046 : : * Bit[4:0](CTLE_BOOST_0) = 4'hA
2047 : : */
2048 : : value = rd32_epcs(hw, TXGBE_PHY_RX_EQ_CTL0);
2049 : 0 : value = (value & ~0xFFFF) | (2 << 5) | 0x05;
2050 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL0, value);
2051 : : }
2052 : : value = rd32_epcs(hw, TXGBE_PHY_RX_EQ_ATT_LVL0);
2053 : 0 : value = (value & ~0x7) | 0x0;
2054 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_ATT_LVL0, value);
2055 : :
2056 [ # # ]: 0 : if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
2057 : : hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1) {
2058 : : /* 8. Set VR_XS_PMA_Gen5_12G_DFE_TAP_CTRL0 Register
2059 : : * Bit[7:0](DFE_TAP1_0) = 8'd20
2060 : : */
2061 : : wr32_epcs(hw, TXGBE_PHY_DFE_TAP_CTL0, 0x0014);
2062 : : value = rd32_epcs(hw, TXGBE_PHY_AFE_DFE_ENABLE);
2063 : 0 : value = (value & ~0x11) | 0x11;
2064 : : wr32_epcs(hw, TXGBE_PHY_AFE_DFE_ENABLE, value);
2065 : : } else {
2066 : : /* 8. Set VR_XS_PMA_Gen5_12G_DFE_TAP_CTRL0 Register
2067 : : * Bit[7:0](DFE_TAP1_0) = 8'd20
2068 : : */
2069 : : wr32_epcs(hw, TXGBE_PHY_DFE_TAP_CTL0, 0xBE);
2070 : : /* 9. Set VR_MII_Gen5_12G_AFE_DFE_EN_CTRL Register
2071 : : * Bit[4](DFE_EN_0) = 1'b0, Bit[0](AFE_EN_0) = 1'b0
2072 : : */
2073 : : value = rd32_epcs(hw, TXGBE_PHY_AFE_DFE_ENABLE);
2074 : 0 : value = (value & ~0x11) | 0x0;
2075 : : wr32_epcs(hw, TXGBE_PHY_AFE_DFE_ENABLE, value);
2076 : : }
2077 : : value = rd32_epcs(hw, TXGBE_PHY_RX_EQ_CTL);
2078 : 0 : value = value & ~0x1;
2079 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL, value);
2080 : : } else {
2081 : : /* Set SR PCS Control2 Register Bits[1:0] = 2'b00
2082 : : * PCS_TYPE_SEL: KR
2083 : : */
2084 : : wr32_epcs(hw, SR_XS_PCS_CTRL2, 0x1);
2085 : : /* Set SR PMA MMD Control1 Register Bit[13] = 1'b0
2086 : : * SS13: 1G speed
2087 : : */
2088 : : wr32_epcs(hw, SR_PMA_CTRL1, 0x0000);
2089 : : /* Set SR MII MMD Control Register to corresponding speed */
2090 : : wr32_epcs(hw, SR_MII_MMD_CTL, 0x0140);
2091 : :
2092 : : value = rd32_epcs(hw, TXGBE_PHY_TX_GENCTRL1);
2093 : 0 : value = (value & ~0x710) | 0x500;
2094 : : wr32_epcs(hw, TXGBE_PHY_TX_GENCTRL1, value);
2095 : : /* 4. Set VR_XS_PMA_Gen5_12G_MISC_CTRL0 Register
2096 : : * Bit[12:8](RX_VREF_CTRL) = 5'hF
2097 : : */
2098 : : wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0xCF00);
2099 : :
2100 [ # # ]: 0 : if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
2101 : : hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1) {
2102 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL0, 0x774F);
2103 : : } else {
2104 : : /* 7. Set VR_XS_PMA_Gen5_12G_RX_EQ_CTRL0 Register
2105 : : * Bit[15:8](VGA1/2_GAIN_0) = 8'h00
2106 : : * Bit[7:5](CTLE_POLE_0) = 3'h2
2107 : : * Bit[4:0](CTLE_BOOST_0) = 4'hA
2108 : : */
2109 : : value = rd32_epcs(hw, TXGBE_PHY_RX_EQ_CTL0);
2110 : 0 : value = (value & ~0xFFFF) | 0x7706;
2111 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL0, value);
2112 : : }
2113 : : value = rd32_epcs(hw, TXGBE_PHY_RX_EQ_ATT_LVL0);
2114 : 0 : value = (value & ~0x7) | 0x0;
2115 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_ATT_LVL0, value);
2116 : : /* 8. Set VR_XS_PMA_Gen5_12G_DFE_TAP_CTRL0 Register
2117 : : * Bit[7:0](DFE_TAP1_0) = 8'd00
2118 : : */
2119 : : wr32_epcs(hw, TXGBE_PHY_DFE_TAP_CTL0, 0x0);
2120 : : /* 9. Set VR_MII_Gen5_12G_AFE_DFE_EN_CTRL Register
2121 : : * Bit[4](DFE_EN_0) = 1'b0, Bit[0](AFE_EN_0) = 1'b0
2122 : : */
2123 : : value = rd32_epcs(hw, TXGBE_PHY_RX_GEN_CTL3);
2124 : 0 : value = (value & ~0x7) | 0x4;
2125 : : wr32_epcs(hw, TXGBE_PHY_RX_GEN_CTL3, value);
2126 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL0, 0x0020);
2127 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL3, 0x0046);
2128 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_LD0, 0x0540);
2129 : : wr32_epcs(hw, TXGBE_PHY_VCO_CAL_REF0, 0x002A);
2130 : : wr32_epcs(hw, TXGBE_PHY_AFE_DFE_ENABLE, 0x0);
2131 : : wr32_epcs(hw, TXGBE_PHY_RX_EQ_CTL, 0x0010);
2132 : : wr32_epcs(hw, TXGBE_PHY_TX_RATE_CTL, 0x0003);
2133 : : wr32_epcs(hw, TXGBE_PHY_RX_RATE_CTL, 0x0003);
2134 : : wr32_epcs(hw, TXGBE_PHY_TX_GEN_CTL2, 0x0100);
2135 : : wr32_epcs(hw, TXGBE_PHY_RX_GEN_CTL2, 0x0100);
2136 : : wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL2, 0x0200);
2137 : : wr32_epcs(hw, SR_MII_MMD_AN_CTL, 0x0100);
2138 : : }
2139 : : /* 10. Initialize the mode by setting VR XS or PCS MMD Digital Control1
2140 : : * Register Bit[15](VR_RST)
2141 : : */
2142 : : wr32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_CTL1, 0xA000);
2143 : :
2144 : : /* Wait phy initialization done */
2145 [ # # ]: 0 : for (i = 0; i < 100; i++) {
2146 [ # # ]: 0 : if ((rd32_epcs(hw, VR_XS_OR_PCS_MMD_DIGI_CTL1) &
2147 : : VR_XS_OR_PCS_MMD_DIGI_CTL1_VR_RST) == 0)
2148 : : break;
2149 : : msleep(100);
2150 : : }
2151 [ # # ]: 0 : if (i == 100) {
2152 : : err = TXGBE_ERR_PHY_INIT_NOT_DONE;
2153 : 0 : goto out;
2154 : : }
2155 : :
2156 [ # # ]: 0 : if (hw->phy.ffe_set == TXGBE_BP_M_SFI) {
2157 : 0 : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0) & ~0x3F3F;
2158 : 0 : value |= hw->phy.ffe_main << 8 | hw->phy.ffe_pre;
2159 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value);
2160 : :
2161 : 0 : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0) & ~0x7F;
2162 : 0 : value |= hw->phy.ffe_post | (1 << 6);
2163 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
2164 [ # # ]: 0 : } else if (hw->fw_version <= TXGBE_FW_N_TXEQ) {
2165 : : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0);
2166 : 0 : value = (value & ~0x3F3F) | (24 << 8) | 4;
2167 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value);
2168 : :
2169 : : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1);
2170 : 0 : value = (value & ~0x7F) | 16 | (1 << 6);
2171 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
2172 : : }
2173 : 0 : out:
2174 : 0 : return err;
2175 : : }
2176 : :
2177 : : /**
2178 : : * txgbe_autoc_read - Hides MAC differences needed for AUTOC read
2179 : : * @hw: pointer to hardware structure
2180 : : */
2181 : 0 : u64 txgbe_autoc_read(struct txgbe_hw *hw)
2182 : : {
2183 : : u64 autoc;
2184 : : u32 sr_pcs_ctl;
2185 : : u32 sr_pma_ctl1;
2186 : : u32 sr_an_ctl;
2187 : : u32 sr_an_adv_reg2;
2188 : 0 : u8 type = hw->subsystem_device_id & 0xFF;
2189 : :
2190 : 0 : autoc = hw->mac.autoc;
2191 : :
2192 [ # # ]: 0 : if (hw->phy.multispeed_fiber) {
2193 : 0 : autoc |= TXGBE_AUTOC_LMS_10G;
2194 : : } else if (type == TXGBE_DEV_ID_SFP) {
2195 : : autoc |= TXGBE_AUTOC_LMS_10G;
2196 : 0 : autoc |= TXGBE_AUTOC_10GS_SFI;
2197 : : } else if (type == TXGBE_DEV_ID_QSFP) {
2198 : : autoc = 0; /*TBD*/
2199 : : } else if (type == TXGBE_DEV_ID_XAUI || type == TXGBE_DEV_ID_SFI_XAUI) {
2200 : 0 : autoc |= TXGBE_AUTOC_LMS_10G_LINK_NO_AN;
2201 : : autoc |= TXGBE_AUTOC_10G_XAUI;
2202 : 0 : hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_10GBASE_T;
2203 : : } else if (type == TXGBE_DEV_ID_SGMII) {
2204 : 0 : autoc |= TXGBE_AUTOC_LMS_SGMII_1G_100M;
2205 : 0 : hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_1000BASE_T |
2206 : : TXGBE_PHYSICAL_LAYER_100BASE_TX;
2207 : : } else if (type == TXGBE_DEV_ID_MAC_XAUI) {
2208 : 0 : autoc |= TXGBE_AUTOC_LMS_10G_LINK_NO_AN;
2209 : 0 : hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_10GBASE_KX4;
2210 : : } else if (type == TXGBE_DEV_ID_MAC_SGMII) {
2211 : : autoc |= TXGBE_AUTOC_LMS_1G_LINK_NO_AN;
2212 : 0 : hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_1000BASE_KX;
2213 : : }
2214 : :
2215 [ # # ]: 0 : if (type != TXGBE_DEV_ID_KR_KX_KX4)
2216 : : return autoc;
2217 : :
2218 : : sr_pcs_ctl = rd32_epcs(hw, SR_XS_PCS_CTRL2);
2219 : : sr_pma_ctl1 = rd32_epcs(hw, SR_PMA_CTRL1);
2220 : : sr_an_ctl = rd32_epcs(hw, SR_AN_CTRL);
2221 : : sr_an_adv_reg2 = rd32_epcs(hw, SR_AN_MMD_ADV_REG2);
2222 : :
2223 [ # # ]: 0 : if ((sr_pcs_ctl & SR_PCS_CTRL2_TYPE_SEL) == SR_PCS_CTRL2_TYPE_SEL_X &&
2224 [ # # ]: 0 : (sr_pma_ctl1 & SR_PMA_CTRL1_SS13) == SR_PMA_CTRL1_SS13_KX &&
2225 [ # # ]: 0 : (sr_an_ctl & SR_AN_CTRL_AN_EN) == 0) {
2226 : : /* 1G or KX - no backplane auto-negotiation */
2227 : 0 : autoc |= TXGBE_AUTOC_LMS_1G_LINK_NO_AN |
2228 : : TXGBE_AUTOC_1G_KX;
2229 : 0 : hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_1000BASE_KX;
2230 [ # # ]: 0 : } else if ((sr_pcs_ctl & SR_PCS_CTRL2_TYPE_SEL) ==
2231 : 0 : SR_PCS_CTRL2_TYPE_SEL_X &&
2232 [ # # ]: 0 : (sr_pma_ctl1 & SR_PMA_CTRL1_SS13) == SR_PMA_CTRL1_SS13_KX4 &&
2233 [ # # ]: 0 : (sr_an_ctl & SR_AN_CTRL_AN_EN) == 0) {
2234 : 0 : autoc |= TXGBE_AUTOC_LMS_10G |
2235 : : TXGBE_AUTOC_10G_KX4;
2236 : 0 : hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_10GBASE_KX4;
2237 [ # # ]: 0 : } else if ((sr_pcs_ctl & SR_PCS_CTRL2_TYPE_SEL) ==
2238 : 0 : SR_PCS_CTRL2_TYPE_SEL_R &&
2239 [ # # ]: 0 : (sr_an_ctl & SR_AN_CTRL_AN_EN) == 0) {
2240 : : /* 10 GbE serial link (KR -no backplane auto-negotiation) */
2241 : 0 : autoc |= TXGBE_AUTOC_LMS_10G |
2242 : : TXGBE_AUTOC_10GS_KR;
2243 : 0 : hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_10GBASE_KR;
2244 [ # # ]: 0 : } else if ((sr_an_ctl & SR_AN_CTRL_AN_EN)) {
2245 : : /* KX/KX4/KR backplane auto-negotiation enable */
2246 [ # # ]: 0 : if (sr_an_adv_reg2 & SR_AN_MMD_ADV_REG2_BP_TYPE_KR)
2247 : 0 : autoc |= TXGBE_AUTOC_KR_SUPP;
2248 [ # # ]: 0 : if (sr_an_adv_reg2 & SR_AN_MMD_ADV_REG2_BP_TYPE_KX4)
2249 : 0 : autoc |= TXGBE_AUTOC_KX4_SUPP;
2250 [ # # ]: 0 : if (sr_an_adv_reg2 & SR_AN_MMD_ADV_REG2_BP_TYPE_KX)
2251 : 0 : autoc |= TXGBE_AUTOC_KX_SUPP;
2252 : 0 : autoc |= TXGBE_AUTOC_LMS_KX4_KX_KR;
2253 : 0 : hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_10GBASE_KR |
2254 : : TXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
2255 : : TXGBE_PHYSICAL_LAYER_1000BASE_KX;
2256 : : }
2257 : :
2258 : : return autoc;
2259 : : }
2260 : :
2261 : : /**
2262 : : * txgbe_autoc_write - Hides MAC differences needed for AUTOC write
2263 : : * @hw: pointer to hardware structure
2264 : : * @autoc: value to write to AUTOC
2265 : : */
2266 : 0 : void txgbe_autoc_write(struct txgbe_hw *hw, u64 autoc)
2267 : : {
2268 : : bool autoneg;
2269 : : u32 speed;
2270 : : u32 mactxcfg = 0;
2271 : 0 : u8 device_type = hw->subsystem_device_id & 0xFF;
2272 : :
2273 : 0 : speed = TXGBD_AUTOC_SPEED(autoc);
2274 : 0 : autoc &= ~TXGBE_AUTOC_SPEED_MASK;
2275 : 0 : autoneg = (autoc & TXGBE_AUTOC_AUTONEG ? true : false);
2276 : : autoc &= ~TXGBE_AUTOC_AUTONEG;
2277 : :
2278 [ # # ]: 0 : if (device_type == TXGBE_DEV_ID_KR_KX_KX4) {
2279 [ # # ]: 0 : if (!autoneg) {
2280 [ # # # # ]: 0 : switch (hw->phy.link_mode) {
2281 : 0 : case TXGBE_PHYSICAL_LAYER_10GBASE_KR:
2282 : 0 : txgbe_set_link_to_kr(hw, autoneg);
2283 : 0 : break;
2284 : 0 : case TXGBE_PHYSICAL_LAYER_10GBASE_KX4:
2285 : 0 : txgbe_set_link_to_kx4(hw, autoneg);
2286 : 0 : break;
2287 : 0 : case TXGBE_PHYSICAL_LAYER_1000BASE_KX:
2288 : 0 : txgbe_set_link_to_kx(hw, speed, autoneg);
2289 : 0 : break;
2290 : : default:
2291 : : return;
2292 : : }
2293 : : } else {
2294 : 0 : txgbe_set_link_to_kr(hw, !autoneg);
2295 : : }
2296 : 0 : } else if (device_type == TXGBE_DEV_ID_XAUI ||
2297 [ # # ]: 0 : device_type == TXGBE_DEV_ID_SGMII ||
2298 : 0 : device_type == TXGBE_DEV_ID_MAC_XAUI ||
2299 [ # # # # ]: 0 : device_type == TXGBE_DEV_ID_MAC_SGMII ||
2300 : 0 : (device_type == TXGBE_DEV_ID_SFI_XAUI &&
2301 [ # # ]: 0 : hw->phy.media_type == txgbe_media_type_copper)) {
2302 [ # # ]: 0 : if (speed == TXGBE_LINK_SPEED_10GB_FULL) {
2303 : 0 : txgbe_set_link_to_kx4(hw, 0);
2304 : : } else {
2305 : 0 : txgbe_set_link_to_kx(hw, speed, 0);
2306 [ # # ]: 0 : if (hw->devarg.auto_neg == 1)
2307 : 0 : txgbe_set_sgmii_an37_ability(hw);
2308 : : }
2309 [ # # ]: 0 : } else if (hw->phy.media_type == txgbe_media_type_fiber) {
2310 : 0 : txgbe_set_link_to_sfi(hw, speed);
2311 [ # # ]: 0 : if (speed == TXGBE_LINK_SPEED_1GB_FULL)
2312 : 0 : txgbe_set_sgmii_an37_ability(hw);
2313 : : }
2314 : :
2315 : 0 : hw->mac.enable_sec_tx_path(hw);
2316 : :
2317 [ # # ]: 0 : if (speed == TXGBE_LINK_SPEED_10GB_FULL)
2318 : : mactxcfg = TXGBE_MACTXCFG_SPEED_10G;
2319 [ # # ]: 0 : else if (speed == TXGBE_LINK_SPEED_1GB_FULL)
2320 : : mactxcfg = TXGBE_MACTXCFG_SPEED_1G;
2321 : :
2322 : : /* enable mac transmitter */
2323 : 0 : wr32m(hw, TXGBE_MACTXCFG,
2324 : : TXGBE_MACTXCFG_SPEED_MASK | TXGBE_MACTXCFG_TXE,
2325 : : mactxcfg | TXGBE_MACTXCFG_TXE);
2326 : : wr32m(hw, TXGBE_MACRXCFG, TXGBE_MACRXCFG_ENA, TXGBE_MACRXCFG_ENA);
2327 : : }
2328 : :
2329 : 0 : void txgbe_bp_down_event(struct txgbe_hw *hw)
2330 : : {
2331 [ # # ]: 0 : if (!(hw->devarg.auto_neg == 1))
2332 : : return;
2333 : :
2334 : 0 : BP_LOG("restart phy power.\n");
2335 : : wr32_epcs(hw, VR_AN_KR_MODE_CL, 0);
2336 : : wr32_epcs(hw, SR_AN_CTRL, 0);
2337 : : wr32_epcs(hw, VR_AN_INTR_MSK, 0);
2338 : :
2339 : : msleep(1050);
2340 : 0 : txgbe_set_link_to_kr(hw, 0);
2341 : : }
2342 : :
2343 : 0 : void txgbe_bp_mode_set(struct txgbe_hw *hw)
2344 : : {
2345 [ # # ]: 0 : if (hw->phy.ffe_set == TXGBE_BP_M_SFI)
2346 : 0 : hw->subsystem_device_id = TXGBE_DEV_ID_WX1820_SFP;
2347 [ # # ]: 0 : else if (hw->phy.ffe_set == TXGBE_BP_M_KR)
2348 : 0 : hw->subsystem_device_id = TXGBE_DEV_ID_WX1820_KR_KX_KX4;
2349 [ # # ]: 0 : else if (hw->phy.ffe_set == TXGBE_BP_M_KX4)
2350 : 0 : hw->subsystem_device_id = TXGBE_DEV_ID_WX1820_MAC_XAUI;
2351 [ # # ]: 0 : else if (hw->phy.ffe_set == TXGBE_BP_M_KX)
2352 : 0 : hw->subsystem_device_id = TXGBE_DEV_ID_WX1820_MAC_SGMII;
2353 : 0 : }
2354 : :
2355 : 0 : void txgbe_set_phy_temp(struct txgbe_hw *hw)
2356 : : {
2357 : : u32 value;
2358 : :
2359 [ # # ]: 0 : if (hw->phy.ffe_set == TXGBE_BP_M_SFI) {
2360 : 0 : BP_LOG("Set SFI TX_EQ MAIN:%d PRE:%d POST:%d\n",
2361 : : hw->phy.ffe_main, hw->phy.ffe_pre, hw->phy.ffe_post);
2362 : :
2363 : : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0);
2364 : 0 : value = (value & ~0x3F3F) | (hw->phy.ffe_main << 8) |
2365 : 0 : hw->phy.ffe_pre;
2366 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value);
2367 : :
2368 : : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1);
2369 : 0 : value = (value & ~0x7F) | hw->phy.ffe_post | (1 << 6);
2370 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
2371 : : }
2372 : :
2373 [ # # ]: 0 : if (hw->phy.ffe_set == TXGBE_BP_M_KR) {
2374 : 0 : BP_LOG("Set KR TX_EQ MAIN:%d PRE:%d POST:%d\n",
2375 : : hw->phy.ffe_main, hw->phy.ffe_pre, hw->phy.ffe_post);
2376 : : value = (0x1804 & ~0x3F3F);
2377 : 0 : value |= hw->phy.ffe_main << 8 | hw->phy.ffe_pre;
2378 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value);
2379 : :
2380 : 0 : value = (0x50 & ~0x7F) | (1 << 6) | hw->phy.ffe_post;
2381 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
2382 : : wr32_epcs(hw, 0x18035, 0x00FF);
2383 : : wr32_epcs(hw, 0x18055, 0x00FF);
2384 : : }
2385 : :
2386 [ # # ]: 0 : if (hw->phy.ffe_set == TXGBE_BP_M_KX) {
2387 : 0 : BP_LOG("Set KX TX_EQ MAIN:%d PRE:%d POST:%d\n",
2388 : : hw->phy.ffe_main, hw->phy.ffe_pre, hw->phy.ffe_post);
2389 : : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0);
2390 : 0 : value = (value & ~0x3F3F) | (hw->phy.ffe_main << 8) |
2391 : 0 : hw->phy.ffe_pre;
2392 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value);
2393 : :
2394 : : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1);
2395 : 0 : value = (value & ~0x7F) | hw->phy.ffe_post | (1 << 6);
2396 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
2397 : :
2398 : : wr32_epcs(hw, 0x18035, 0x00FF);
2399 : : wr32_epcs(hw, 0x18055, 0x00FF);
2400 : : }
2401 : 0 : }
2402 : :
2403 : 0 : int txgbe_is_dac_cable(struct txgbe_hw *hw)
2404 : : {
2405 : 0 : if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
2406 [ # # ]: 0 : hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1 ||
2407 [ # # ]: 0 : hw->phy.sfp_type == txgbe_sfp_type_da_act_lmt_core0 ||
2408 [ # # ]: 0 : hw->phy.sfp_type == txgbe_sfp_type_da_act_lmt_core1 ||
2409 [ # # ]: 0 : hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core0 ||
2410 : : hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core1)
2411 : 0 : return true;
2412 : :
2413 : : return false;
2414 : : }
2415 : :
2416 : 0 : int txgbe_xpcs_an_enabled(struct txgbe_hw *hw)
2417 : : {
2418 [ # # # # ]: 0 : if (!(txgbe_is_dac_cable(hw) || txgbe_is_backplane(hw)))
2419 : : return false;
2420 : :
2421 : 0 : return hw->devarg.auto_neg ? true : false;
2422 : : }
2423 : :
2424 : : /**
2425 : : * txgbe_kr_handle - Handle the interrupt of auto-negotiation
2426 : : * @hw: pointer to hardware structure
2427 : : */
2428 : 0 : s32 txgbe_kr_handle(struct txgbe_hw *hw)
2429 : : {
2430 : : u32 value;
2431 : : s32 status = 0;
2432 : :
2433 : : value = rd32_epcs(hw, VR_AN_INTR);
2434 : 0 : BP_LOG("AN INTERRUPT!! value: 0x%x\n", value);
2435 [ # # ]: 0 : if (!(value & VR_AN_INTR_PG_RCV)) {
2436 : : wr32_epcs(hw, VR_AN_INTR, 0);
2437 : 0 : return status;
2438 : : }
2439 : :
2440 : 0 : status = txgbe_handle_bp_flow(0, hw);
2441 : :
2442 : 0 : return status;
2443 : : }
2444 : :
2445 : : /**
2446 : : * txgbe_handle_bp_flow - Handle backplane AN73 flow
2447 : : * @hw: pointer to hardware structure
2448 : : * @link_mode: local AN73 link mode
2449 : : */
2450 : 0 : static s32 txgbe_handle_bp_flow(u32 link_mode, struct txgbe_hw *hw)
2451 : : {
2452 : : u32 value, i, lp_reg, ld_reg;
2453 : : s32 status = 0;
2454 : : struct txgbe_backplane_ability local_ability, lp_ability;
2455 : :
2456 : 0 : local_ability.current_link_mode = link_mode;
2457 : :
2458 : : /* 1. Get the local AN73 Base Page Ability */
2459 : 0 : BP_LOG("<1>. Get the local AN73 Base Page Ability ...\n");
2460 : 0 : txgbe_get_bp_ability(&local_ability, 0, hw);
2461 : :
2462 : : /* 2. Check and clear the AN73 Interrupt Status */
2463 : 0 : BP_LOG("<2>. Check the AN73 Interrupt Status ...\n");
2464 : 0 : txgbe_clear_bp_intr(2, 0, hw);
2465 : :
2466 : : /* 3.1. Get the link partner AN73 Base Page Ability */
2467 : 0 : BP_LOG("<3.1>. Get the link partner AN73 Base Page Ability ...\n");
2468 : 0 : txgbe_get_bp_ability(&lp_ability, 1, hw);
2469 : :
2470 : : /* 3.2. Check the AN73 Link Ability with Link Partner */
2471 : 0 : BP_LOG("<3.2>. Check the AN73 Link Ability with Link Partner ...\n");
2472 : 0 : BP_LOG(" Local Link Ability: 0x%x\n", local_ability.link_ability);
2473 : 0 : BP_LOG(" Link Partner Link Ability: 0x%x\n", lp_ability.link_ability);
2474 : :
2475 : 0 : status = txgbe_check_bp_ability(&local_ability, &lp_ability, hw);
2476 : :
2477 : : wr32_epcs(hw, SR_AN_CTRL, 0);
2478 : : wr32_epcs(hw, VR_AN_KR_MODE_CL, 0);
2479 : :
2480 : : /* 3.3. Check the FEC and KR Training for KR mode */
2481 : 0 : BP_LOG("<3.3>. Check the FEC for KR mode ...\n");
2482 [ # # ]: 0 : if ((local_ability.fec_ability & lp_ability.fec_ability) == 0x03) {
2483 : 0 : BP_LOG("Enable the Backplane KR FEC ...\n");
2484 : : wr32_epcs(hw, SR_PMA_KR_FEC_CTRL, SR_PMA_KR_FEC_CTRL_EN);
2485 : : } else {
2486 : 0 : BP_LOG("Backplane KR FEC is disabled.\n");
2487 : : }
2488 : :
2489 : : printf("Enter training.\n");
2490 : : /* CL72 KR training on */
2491 [ # # ]: 0 : for (i = 0; i < 2; i++) {
2492 : : /* 3.4. Check the CL72 KR Training for KR mode */
2493 : 0 : BP_LOG("<3.4>. Check the CL72 KR Training for KR mode ...\n");
2494 : 0 : BP_LOG("==================%d==================\n", i);
2495 : 0 : status = txgbe_enable_kr_training(hw);
2496 : 0 : BP_LOG("Check the Clause 72 KR Training status ...\n");
2497 : 0 : status |= txgbe_check_kr_training(hw);
2498 : :
2499 : : lp_reg = rd32_epcs(hw, SR_PMA_KR_LP_CESTS);
2500 : 0 : lp_reg &= SR_PMA_KR_LP_CESTS_RR;
2501 : 0 : BP_LOG("SR PMA MMD 10GBASE-KR LP Coefficient Status Register: 0x%x\n",
2502 : : lp_reg);
2503 : : ld_reg = rd32_epcs(hw, SR_PMA_KR_LD_CESTS);
2504 : 0 : ld_reg &= SR_PMA_KR_LD_CESTS_RR;
2505 : 0 : BP_LOG("SR PMA MMD 10GBASE-KR LD Coefficient Status Register: 0x%x\n",
2506 : : ld_reg);
2507 [ # # # # ]: 0 : if (hw->devarg.poll == 0 && status != 0)
2508 : : lp_reg = SR_PMA_KR_LP_CESTS_RR;
2509 : :
2510 [ # # ]: 0 : if (lp_reg & ld_reg) {
2511 : 0 : BP_LOG("==================out==================\n");
2512 : 0 : status = txgbe_disable_kr_training(hw, 0, 0);
2513 : : wr32_epcs(hw, SR_AN_CTRL, 0);
2514 : 0 : txgbe_clear_bp_intr(2, 0, hw);
2515 : 0 : txgbe_clear_bp_intr(1, 0, hw);
2516 : 0 : txgbe_clear_bp_intr(0, 0, hw);
2517 [ # # ]: 0 : for (i = 0; i < 10; i++) {
2518 : : value = rd32_epcs(hw, SR_XS_PCS_KR_STS1);
2519 [ # # ]: 0 : if (value & SR_XS_PCS_KR_STS1_PLU) {
2520 : 0 : BP_LOG("\nINT_AN_INT_CMPLT =1, AN73 Done Success.\n");
2521 : : wr32_epcs(hw, SR_AN_CTRL, 0);
2522 : 0 : return 0;
2523 : : }
2524 : : msec_delay(10);
2525 : : }
2526 : : msec_delay(1000);
2527 : 0 : txgbe_set_link_to_kr(hw, 0);
2528 : :
2529 : 0 : return 0;
2530 : : }
2531 : :
2532 : 0 : status |= txgbe_disable_kr_training(hw, 0, 0);
2533 : : }
2534 : :
2535 : 0 : txgbe_clear_bp_intr(2, 0, hw);
2536 : 0 : txgbe_clear_bp_intr(1, 0, hw);
2537 : 0 : txgbe_clear_bp_intr(0, 0, hw);
2538 : :
2539 : 0 : return status;
2540 : : }
2541 : :
2542 : : /**
2543 : : * txgbe_get_bp_ability
2544 : : * @hw: pointer to hardware structure
2545 : : * @ability: pointer to blackplane ability structure
2546 : : * @link_partner:
2547 : : * 1: Get Link Partner Base Page
2548 : : * 2: Get Link Partner Next Page
2549 : : * (only get NXP Ability Register 1 at the moment)
2550 : : * 0: Get Local Device Base Page
2551 : : */
2552 : 0 : static void txgbe_get_bp_ability(struct txgbe_backplane_ability *ability,
2553 : : u32 link_partner, struct txgbe_hw *hw)
2554 : : {
2555 : : u32 value = 0;
2556 : :
2557 : : /* Link Partner Base Page */
2558 [ # # ]: 0 : if (link_partner == 1) {
2559 : : /* Read the link partner AN73 Base Page Ability Registers */
2560 : 0 : BP_LOG("Read the link partner AN73 Base Page Ability Registers...\n");
2561 : : value = rd32_epcs(hw, SR_AN_MMD_LP_ABL1);
2562 : 0 : BP_LOG("SR AN MMD LP Base Page Ability Register 1: 0x%x\n",
2563 : : value);
2564 : 0 : ability->next_page = SR_MMD_LP_ABL1_ADV_NP(value);
2565 : 0 : BP_LOG(" Next Page (bit15): %d\n", ability->next_page);
2566 : :
2567 : : value = rd32_epcs(hw, SR_AN_MMD_LP_ABL2);
2568 : 0 : BP_LOG("SR AN MMD LP Base Page Ability Register 2: 0x%x\n",
2569 : : value);
2570 : 0 : ability->link_ability =
2571 : 0 : value & SR_AN_MMD_LP_ABL2_BP_TYPE_KR_KX4_KX;
2572 : 0 : BP_LOG(" Link Ability (bit[15:0]): 0x%x\n",
2573 : : ability->link_ability);
2574 : 0 : BP_LOG(" (0x20- KX_ONLY, 0x40- KX4_ONLY, 0x60- KX4_KX\n");
2575 : 0 : BP_LOG(" 0x80- KR_ONLY, 0xA0- KR_KX, 0xC0- KR_KX4, 0xE0- KR_KX4_KX)\n");
2576 : :
2577 : : value = rd32_epcs(hw, SR_AN_MMD_LP_ABL3);
2578 : 0 : BP_LOG("SR AN MMD LP Base Page Ability Register 3: 0x%x\n",
2579 : : value);
2580 : 0 : BP_LOG(" FEC Request (bit15): %d\n", ((value >> 15) & 0x01));
2581 : 0 : BP_LOG(" FEC Enable (bit14): %d\n", ((value >> 14) & 0x01));
2582 : 0 : ability->fec_ability = SR_AN_MMD_LP_ABL3_FCE(value);
2583 [ # # ]: 0 : } else if (link_partner == 2) {
2584 : : /* Read the link partner AN73 Next Page Ability Registers */
2585 : 0 : BP_LOG("\nRead the link partner AN73 Next Page Ability Registers...\n");
2586 : : value = rd32_epcs(hw, SR_AN_LP_XNP_ABL1);
2587 : 0 : BP_LOG(" SR AN MMD LP XNP Ability Register 1: 0x%x\n", value);
2588 : 0 : ability->next_page = SR_AN_LP_XNP_ABL1_NP(value);
2589 : 0 : BP_LOG(" Next Page (bit15): %d\n", ability->next_page);
2590 : : } else {
2591 : : /* Read the local AN73 Base Page Ability Registers */
2592 : 0 : BP_LOG("Read the local AN73 Base Page Ability Registers...\n");
2593 : : value = rd32_epcs(hw, SR_AN_MMD_ADV_REG1);
2594 : 0 : BP_LOG("SR AN MMD Advertisement Register 1: 0x%x\n", value);
2595 : 0 : ability->next_page = SR_AN_MMD_ADV_REG1_NP(value);
2596 : 0 : BP_LOG(" Next Page (bit15): %d\n", ability->next_page);
2597 : :
2598 : : value = rd32_epcs(hw, SR_AN_MMD_ADV_REG2);
2599 : 0 : BP_LOG("SR AN MMD Advertisement Register 2: 0x%x\n", value);
2600 : 0 : ability->link_ability =
2601 : 0 : value & SR_AN_MMD_ADV_REG2_BP_TYPE_KR_KX4_KX;
2602 : 0 : BP_LOG(" Link Ability (bit[15:0]): 0x%x\n",
2603 : : ability->link_ability);
2604 : 0 : BP_LOG(" (0x20- KX_ONLY, 0x40- KX4_ONLY, 0x60- KX4_KX\n");
2605 : 0 : BP_LOG(" 0x80- KR_ONLY, 0xA0- KR_KX, 0xC0- KR_KX4, 0xE0- KR_KX4_KX)\n");
2606 : :
2607 : : value = rd32_epcs(hw, SR_AN_MMD_ADV_REG3);
2608 : 0 : BP_LOG("SR AN MMD Advertisement Register 3: 0x%x\n", value);
2609 : 0 : BP_LOG(" FEC Request (bit15): %d\n", ((value >> 15) & 0x01));
2610 : 0 : BP_LOG(" FEC Enable (bit14): %d\n", ((value >> 14) & 0x01));
2611 : 0 : ability->fec_ability = SR_AN_MMD_ADV_REG3_FCE(value);
2612 : : }
2613 : :
2614 : 0 : BP_LOG("done.\n");
2615 : 0 : }
2616 : :
2617 : : /**
2618 : : * txgbe_check_bp_ability
2619 : : * @hw: pointer to hardware structure
2620 : : * @ability: pointer to blackplane ability structure
2621 : : */
2622 : 0 : static s32 txgbe_check_bp_ability(struct txgbe_backplane_ability *local_ability,
2623 : : struct txgbe_backplane_ability *lp_ability, struct txgbe_hw *hw)
2624 : : {
2625 : : u32 com_link_abi;
2626 : : s32 ret = 0;
2627 : :
2628 : 0 : com_link_abi = local_ability->link_ability & lp_ability->link_ability;
2629 : 0 : BP_LOG("com_link_abi = 0x%x, local_ability = 0x%x, lp_ability = 0x%x\n",
2630 : : com_link_abi, local_ability->link_ability,
2631 : : lp_ability->link_ability);
2632 : :
2633 [ # # ]: 0 : if (!com_link_abi) {
2634 : 0 : BP_LOG("The Link Partner does not support any compatible speed mode.\n");
2635 : : ret = -1;
2636 [ # # ]: 0 : } else if (com_link_abi & BP_TYPE_KR) {
2637 [ # # ]: 0 : if (local_ability->current_link_mode) {
2638 : 0 : BP_LOG("Link mode is not matched with Link Partner: [LINK_KR].\n");
2639 : 0 : BP_LOG("Set the local link mode to [LINK_KR] ...\n");
2640 : 0 : txgbe_set_link_to_kr(hw, 0);
2641 : : ret = 1;
2642 : : } else {
2643 : 0 : BP_LOG("Link mode is matched with Link Partner: [LINK_KR].\n");
2644 : : ret = 0;
2645 : : }
2646 [ # # ]: 0 : } else if (com_link_abi & BP_TYPE_KX4) {
2647 [ # # ]: 0 : if (local_ability->current_link_mode == 0x10) {
2648 : 0 : BP_LOG("Link mode is matched with Link Partner: [LINK_KX4].\n");
2649 : : ret = 0;
2650 : : } else {
2651 : 0 : BP_LOG("Link mode is not matched with Link Partner: [LINK_KX4].\n");
2652 : 0 : BP_LOG("Set the local link mode to [LINK_KX4] ...\n");
2653 : 0 : txgbe_set_link_to_kx4(hw, 1);
2654 : : ret = 1;
2655 : : }
2656 [ # # ]: 0 : } else if (com_link_abi & BP_TYPE_KX) {
2657 [ # # ]: 0 : if (local_ability->current_link_mode == 0x1) {
2658 : 0 : BP_LOG("Link mode is matched with Link Partner: [LINK_KX].\n");
2659 : : ret = 0;
2660 : : } else {
2661 : 0 : BP_LOG("Link mode is not matched with Link Partner: [LINK_KX].\n");
2662 : 0 : BP_LOG("Set the local link mode to [LINK_KX] ...\n");
2663 : 0 : txgbe_set_link_to_kx(hw, 1, 1);
2664 : : ret = 1;
2665 : : }
2666 : : }
2667 : :
2668 : 0 : return ret;
2669 : : }
2670 : :
2671 : : /**
2672 : : * txgbe_clear_bp_intr
2673 : : * @hw: pointer to hardware structure
2674 : : * @index: the bit will be cleared
2675 : : * @index_high:
2676 : : * index_high = 0: Only the index bit will be cleared
2677 : : * index_high != 0: the [index_high, index] range will be cleared
2678 : : */
2679 : 0 : static void txgbe_clear_bp_intr(u32 bit, u32 bit_high, struct txgbe_hw *hw)
2680 : : {
2681 : : u32 rdata = 0, wdata, i;
2682 : :
2683 : : rdata = rd32_epcs(hw, VR_AN_INTR);
2684 : 0 : BP_LOG("[Before clear]Read VR AN MMD Interrupt Register: 0x%x\n",
2685 : : rdata);
2686 : 0 : BP_LOG("Interrupt: 0- AN_INT_CMPLT, 1- AN_INC_LINK, 2- AN_PG_RCV\n\n");
2687 : :
2688 : : wdata = rdata;
2689 [ # # ]: 0 : if (bit_high) {
2690 [ # # ]: 0 : for (i = bit; i <= bit_high; i++)
2691 : 0 : wdata &= ~(1 << i);
2692 : : } else {
2693 : 0 : wdata &= ~(1 << bit);
2694 : : }
2695 : :
2696 : : wr32_epcs(hw, VR_AN_INTR, wdata);
2697 : :
2698 : : rdata = rd32_epcs(hw, VR_AN_INTR);
2699 : 0 : BP_LOG("[After clear]Read VR AN MMD Interrupt Register: 0x%x\n", rdata);
2700 : 0 : }
2701 : :
2702 : 0 : static s32 txgbe_enable_kr_training(struct txgbe_hw *hw)
2703 : : {
2704 : : s32 status = 0;
2705 : : u32 value = 0;
2706 : :
2707 : 0 : BP_LOG("Enable Clause 72 KR Training ...\n");
2708 : :
2709 : : if (CL72_KRTR_PRBS_MODE_EN != 0xFFFF) {
2710 : : /* Set PRBS Timer Duration Control to maximum 6.7ms in
2711 : : * VR_PMA_KRTR_PRBS_CTRL2 Register
2712 : : */
2713 : : value = CL72_KRTR_PRBS_MODE_EN;
2714 : : wr32_epcs(hw, VR_PMA_KRTR_PRBS_CTRL2, value);
2715 : : /* Set PRBS Timer Duration Control to maximum 6.7ms in
2716 : : * VR_PMA_KRTR_PRBS_CTRL1 Register
2717 : : */
2718 : : wr32_epcs(hw, VR_PMA_KRTR_PRBS_CTRL1,
2719 : : VR_PMA_KRTR_PRBS_TIME_LMT);
2720 : : /* Enable PRBS Mode to determine KR Training Status by setting
2721 : : * Bit 0 of VR_PMA_KRTR_PRBS_CTRL0 Register
2722 : : */
2723 : : value = VR_PMA_KRTR_PRBS_MODE_EN;
2724 : : }
2725 : : #ifdef CL72_KRTR_PRBS31_EN
2726 : : /* Enable PRBS Mode to determine KR Training Status by setting
2727 : : * Bit 1 of VR_PMA_KRTR_PRBS_CTRL0 Register
2728 : : */
2729 : : value = VR_PMA_KRTR_PRBS31_EN;
2730 : : #endif
2731 : : wr32_epcs(hw, VR_PMA_KRTR_PRBS_CTRL0, value);
2732 : : /* Read PHY Lane0 TX EQ before Clause 72 KR Training. */
2733 : 0 : txgbe_read_phy_lane_tx_eq(0, hw, 0, 0);
2734 : :
2735 : : /* Enable the Clause 72 start-up protocol
2736 : : * by setting Bit 1 of SR_PMA_KR_PMD_CTRL Register.
2737 : : * Restart the Clause 72 start-up protocol
2738 : : * by setting Bit 0 of SR_PMA_KR_PMD_CTRL Register.
2739 : : */
2740 : : wr32_epcs(hw, SR_PMA_KR_PMD_CTRL,
2741 : : SR_PMA_KR_PMD_CTRL_EN_TR | SR_PMA_KR_PMD_CTRL_RS_TR);
2742 : :
2743 : 0 : return status;
2744 : : }
2745 : :
2746 : 0 : static s32 txgbe_disable_kr_training(struct txgbe_hw *hw, s32 post, s32 mode)
2747 : : {
2748 : : s32 status = 0;
2749 : :
2750 : 0 : BP_LOG("Disable Clause 72 KR Training ...\n");
2751 : : /* Read PHY Lane0 TX EQ before Clause 72 KR Training. */
2752 : 0 : txgbe_read_phy_lane_tx_eq(0, hw, post, mode);
2753 : :
2754 : : wr32_epcs(hw, SR_PMA_KR_PMD_CTRL, SR_PMA_KR_PMD_CTRL_RS_TR);
2755 : :
2756 : 0 : return status;
2757 : : }
2758 : :
2759 : 0 : static s32 txgbe_check_kr_training(struct txgbe_hw *hw)
2760 : : {
2761 : : s32 status = 0;
2762 : : u32 value, test;
2763 : : int i;
2764 [ # # ]: 0 : int times = hw->devarg.poll ? 35 : 20;
2765 : :
2766 [ # # ]: 0 : for (i = 0; i < times; i++) {
2767 : : value = rd32_epcs(hw, SR_PMA_KR_LP_CEU);
2768 : 0 : BP_LOG("SR PMA MMD 10GBASE-KR LP Coefficient Update Register: 0x%x\n",
2769 : : value);
2770 : : value = rd32_epcs(hw, SR_PMA_KR_LP_CESTS);
2771 : 0 : BP_LOG("SR PMA MMD 10GBASE-KR LP Coefficient Status Register: 0x%x\n",
2772 : : value);
2773 : : value = rd32_epcs(hw, SR_PMA_KR_LD_CEU);
2774 : 0 : BP_LOG("SR PMA MMD 10GBASE-KR LD Coefficient Update: 0x%x\n",
2775 : : value);
2776 : : value = rd32_epcs(hw, SR_PMA_KR_LD_CESTS);
2777 : 0 : BP_LOG("SR PMA MMD 10GBASE-KR LD Coefficient Status: 0x%x\n",
2778 : : value);
2779 : : value = rd32_epcs(hw, SR_PMA_KR_PMD_STS);
2780 : 0 : BP_LOG("SR PMA MMD 10GBASE-KR Status Register: 0x%x\n", value);
2781 : 0 : BP_LOG(" Training Failure (bit3): %d\n",
2782 : : ((value >> 3) & 0x01));
2783 : 0 : BP_LOG(" Start-Up Protocol Status (bit2): %d\n",
2784 : : ((value >> 2) & 0x01));
2785 : 0 : BP_LOG(" Frame Lock (bit1): %d\n",
2786 : : ((value >> 1) & 0x01));
2787 : 0 : BP_LOG(" Receiver Status (bit0): %d\n",
2788 : : ((value >> 0) & 0x01));
2789 : :
2790 : : test = rd32_epcs(hw, SR_PMA_KR_LP_CESTS);
2791 [ # # ]: 0 : if (test & SR_PMA_KR_LP_CESTS_RR) {
2792 : 0 : BP_LOG("TEST Coefficient Status Register: 0x%x\n",
2793 : : test);
2794 : : status = 1;
2795 : : }
2796 : :
2797 [ # # ]: 0 : if (value & SR_PMA_KR_PMD_STS_TR_FAIL) {
2798 : 0 : BP_LOG("Training is completed with failure.\n");
2799 : 0 : txgbe_read_phy_lane_tx_eq(0, hw, 0, 0);
2800 : 0 : return 0;
2801 : : }
2802 : :
2803 [ # # ]: 0 : if (value & SR_PMA_KR_PMD_STS_RCV) {
2804 : 0 : BP_LOG("Receiver trained and ready to receive data.\n");
2805 : 0 : txgbe_read_phy_lane_tx_eq(0, hw, 0, 0);
2806 : 0 : return 0;
2807 : : }
2808 : :
2809 : : msec_delay(20);
2810 : : }
2811 : :
2812 : 0 : BP_LOG("ERROR: Check Clause 72 KR Training Complete Timeout.\n");
2813 : 0 : return status;
2814 : : }
2815 : :
2816 : 0 : static void txgbe_read_phy_lane_tx_eq(u16 lane, struct txgbe_hw *hw,
2817 : : s32 post, s32 mode)
2818 : : {
2819 : : u32 value = 0;
2820 : : u32 addr;
2821 : : u32 tx_main_cursor, tx_pre_cursor, tx_post_cursor, lmain;
2822 : :
2823 : 0 : addr = TXGBE_PHY_LANE0_TX_EQ_CTL1 | (lane << 8);
2824 : : value = rd32_ephy(hw, addr);
2825 : 0 : BP_LOG("PHY LANE TX EQ Read Value: %x\n", lane);
2826 : 0 : tx_main_cursor = TXGBE_PHY_LANE0_TX_EQ_CTL1_MAIN(value);
2827 : 0 : BP_LOG("TX_MAIN_CURSOR: %x\n", tx_main_cursor);
2828 : : UNREFERENCED_PARAMETER(tx_main_cursor);
2829 : :
2830 : 0 : addr = TXGBE_PHY_LANE0_TX_EQ_CTL2 | (lane << 8);
2831 : : value = rd32_ephy(hw, addr);
2832 : 0 : tx_pre_cursor = value & TXGBE_PHY_LANE0_TX_EQ_CTL2_PRE;
2833 : 0 : tx_post_cursor = TXGBE_PHY_LANE0_TX_EQ_CTL2_POST(value);
2834 : 0 : BP_LOG("TX_PRE_CURSOR: %x\n", tx_pre_cursor);
2835 : 0 : BP_LOG("TX_POST_CURSOR: %x\n", tx_post_cursor);
2836 : :
2837 [ # # ]: 0 : if (mode == 1) {
2838 : 0 : lmain = 160 - tx_pre_cursor - tx_post_cursor;
2839 : : if (lmain < 88)
2840 : : lmain = 88;
2841 : :
2842 [ # # ]: 0 : if (post)
2843 : 0 : tx_post_cursor = post;
2844 : :
2845 : : wr32_epcs(hw, TXGBE_PHY_EQ_INIT_CTL1, tx_post_cursor);
2846 : 0 : wr32_epcs(hw, TXGBE_PHY_EQ_INIT_CTL0,
2847 : 0 : tx_pre_cursor | (lmain << 8));
2848 : : value = rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1);
2849 : 0 : value &= ~TXGBE_PHY_TX_EQ_CTL1_DEF;
2850 : : wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value);
2851 : : }
2852 : 0 : }
|