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