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