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