xref: /openbsd-src/sys/dev/pci/igc_phy.c (revision 8550894424f8a4aa4aafb6cd57229dd6ed7cd9dd)
1 /*	$OpenBSD: igc_phy.c,v 1.2 2022/05/11 06:14:15 kevlo Exp $	*/
2 /*-
3  * Copyright 2021 Intel Corp
4  * Copyright 2021 Rubicon Communications, LLC (Netgate)
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <dev/pci/igc_api.h>
9 
10 /**
11  *  igc_init_phy_ops_generic - Initialize PHY function pointers
12  *  @hw: pointer to the HW structure
13  *
14  *  Setups up the function pointers to no-op functions
15  **/
16 void
17 igc_init_phy_ops_generic(struct igc_hw *hw)
18 {
19 	struct igc_phy_info *phy = &hw->phy;
20 	DEBUGFUNC("igc_init_phy_ops_generic");
21 
22 	/* Initialize function pointers */
23 	phy->ops.init_params = igc_null_ops_generic;
24 	phy->ops.acquire = igc_null_ops_generic;
25 	phy->ops.check_reset_block = igc_null_ops_generic;
26 	phy->ops.force_speed_duplex = igc_null_ops_generic;
27 	phy->ops.get_info = igc_null_ops_generic;
28 	phy->ops.set_page = igc_null_set_page;
29 	phy->ops.read_reg = igc_null_read_reg;
30 	phy->ops.read_reg_locked = igc_null_read_reg;
31 	phy->ops.read_reg_page = igc_null_read_reg;
32 	phy->ops.release = igc_null_phy_generic;
33 	phy->ops.reset = igc_null_ops_generic;
34 	phy->ops.set_d0_lplu_state = igc_null_lplu_state;
35 	phy->ops.set_d3_lplu_state = igc_null_lplu_state;
36 	phy->ops.write_reg = igc_null_write_reg;
37 	phy->ops.write_reg_locked = igc_null_write_reg;
38 	phy->ops.write_reg_page = igc_null_write_reg;
39 	phy->ops.power_up = igc_null_phy_generic;
40 	phy->ops.power_down = igc_null_phy_generic;
41 }
42 
43 /**
44  *  igc_null_set_page - No-op function, return 0
45  *  @hw: pointer to the HW structure
46  *  @data: dummy variable
47  **/
48 int
49 igc_null_set_page(struct igc_hw IGC_UNUSEDARG *hw, uint16_t IGC_UNUSEDARG data)
50 {
51 	DEBUGFUNC("igc_null_set_page");
52 	return IGC_SUCCESS;
53 }
54 
55 /**
56  *  igc_null_read_reg - No-op function, return 0
57  *  @hw: pointer to the HW structure
58  *  @offset: dummy variable
59  *  @data: dummy variable
60  **/
61 int
62 igc_null_read_reg(struct igc_hw IGC_UNUSEDARG *hw,
63     uint32_t IGC_UNUSEDARG offset, uint16_t IGC_UNUSEDARG *data)
64 {
65 	DEBUGFUNC("igc_null_read_reg");
66 	return IGC_SUCCESS;
67 }
68 
69 /**
70  *  igc_null_phy_generic - No-op function, return void
71  *  @hw: pointer to the HW structure
72  **/
73 void
74 igc_null_phy_generic(struct igc_hw IGC_UNUSEDARG *hw)
75 {
76 	DEBUGFUNC("igc_null_phy_generic");
77 	return;
78 }
79 
80 /**
81  *  igc_null_lplu_state - No-op function, return 0
82  *  @hw: pointer to the HW structure
83  *  @active: dummy variable
84  **/
85 int
86 igc_null_lplu_state(struct igc_hw IGC_UNUSEDARG *hw, bool IGC_UNUSEDARG active)
87 {
88 	DEBUGFUNC("igc_null_lplu_state");
89 	return IGC_SUCCESS;
90 }
91 
92 /**
93  *  igc_null_write_reg - No-op function, return 0
94  *  @hw: pointer to the HW structure
95  *  @offset: dummy variable
96  *  @data: dummy variable
97  **/
98 int
99 igc_null_write_reg(struct igc_hw IGC_UNUSEDARG *hw,
100     uint32_t IGC_UNUSEDARG offset, uint16_t IGC_UNUSEDARG data)
101 {
102 	DEBUGFUNC("igc_null_write_reg");
103 	return IGC_SUCCESS;
104 }
105 
106 /**
107  *  igc_check_reset_block_generic - Check if PHY reset is blocked
108  *  @hw: pointer to the HW structure
109  *
110  *  Read the PHY management control register and check whether a PHY reset
111  *  is blocked.  If a reset is not blocked return IGC_SUCCESS, otherwise
112  *  return IGC_BLK_PHY_RESET (12).
113  **/
114 int
115 igc_check_reset_block_generic(struct igc_hw *hw)
116 {
117 	uint32_t manc;
118 
119 	DEBUGFUNC("igc_check_reset_block");
120 
121 	manc = IGC_READ_REG(hw, IGC_MANC);
122 
123 	return (manc & IGC_MANC_BLK_PHY_RST_ON_IDE) ?
124 	    IGC_BLK_PHY_RESET : IGC_SUCCESS;
125 }
126 
127 /**
128  *  igc_get_phy_id - Retrieve the PHY ID and revision
129  *  @hw: pointer to the HW structure
130  *
131  *  Reads the PHY registers and stores the PHY ID and possibly the PHY
132  *  revision in the hardware structure.
133  **/
134 int
135 igc_get_phy_id(struct igc_hw *hw)
136 {
137 	struct igc_phy_info *phy = &hw->phy;
138 	uint16_t phy_id;
139 	int ret_val = IGC_SUCCESS;
140 
141 	DEBUGFUNC("igc_get_phy_id");
142 
143 	if (!phy->ops.read_reg)
144 		return IGC_SUCCESS;
145 
146 	ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
147 	if (ret_val)
148 		return ret_val;
149 
150 	phy->id = (uint32_t)(phy_id << 16);
151 	DELAY(200);
152 	ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
153 	if (ret_val)
154 		return ret_val;
155 
156 	phy->id |= (uint32_t)(phy_id & PHY_REVISION_MASK);
157 	phy->revision = (uint32_t)(phy_id & ~PHY_REVISION_MASK);
158 
159 	return IGC_SUCCESS;
160 }
161 
162 /**
163  *  igc_read_phy_reg_mdic - Read MDI control register
164  *  @hw: pointer to the HW structure
165  *  @offset: register offset to be read
166  *  @data: pointer to the read data
167  *
168  *  Reads the MDI control register in the PHY at offset and stores the
169  *  information read to data.
170  **/
171 int
172 igc_read_phy_reg_mdic(struct igc_hw *hw, uint32_t offset, uint16_t *data)
173 {
174 	struct igc_phy_info *phy = &hw->phy;
175 	uint32_t i, mdic = 0;
176 
177 	DEBUGFUNC("igc_read_phy_reg_mdic");
178 
179 	if (offset > MAX_PHY_REG_ADDRESS) {
180 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
181 		return -IGC_ERR_PARAM;
182 	}
183 
184 	/* Set up Op-code, Phy Address, and register offset in the MDI
185 	 * Control register.  The MAC will take care of interfacing with the
186 	 * PHY to retrieve the desired data.
187 	 */
188 	mdic = ((offset << IGC_MDIC_REG_SHIFT) |
189 	    (phy->addr << IGC_MDIC_PHY_SHIFT) | (IGC_MDIC_OP_READ));
190 
191 	IGC_WRITE_REG(hw, IGC_MDIC, mdic);
192 
193 	/* Poll the ready bit to see if the MDI read completed
194 	 * Increasing the time out as testing showed failures with
195 	 * the lower time out
196 	 */
197 	for (i = 0; i < (IGC_GEN_POLL_TIMEOUT * 3); i++) {
198 		DELAY(50);
199 		mdic = IGC_READ_REG(hw, IGC_MDIC);
200 		if (mdic & IGC_MDIC_READY)
201 			break;
202 	}
203 	if (!(mdic & IGC_MDIC_READY)) {
204 		DEBUGOUT("MDI Read did not complete\n");
205 		return -IGC_ERR_PHY;
206 	}
207 	if (mdic & IGC_MDIC_ERROR) {
208 		DEBUGOUT("MDI Error\n");
209 		return -IGC_ERR_PHY;
210 	}
211 	if (((mdic & IGC_MDIC_REG_MASK) >> IGC_MDIC_REG_SHIFT) != offset) {
212 		DEBUGOUT2("MDI Read offset error - requested %d, returned %d\n",
213 		    offset, (mdic & IGC_MDIC_REG_MASK) >> IGC_MDIC_REG_SHIFT);
214 		return -IGC_ERR_PHY;
215 	}
216 	*data = (uint16_t)mdic;
217 
218 	return IGC_SUCCESS;
219 }
220 
221 /**
222  *  igc_write_phy_reg_mdic - Write MDI control register
223  *  @hw: pointer to the HW structure
224  *  @offset: register offset to write to
225  *  @data: data to write to register at offset
226  *
227  *  Writes data to MDI control register in the PHY at offset.
228  **/
229 int
230 igc_write_phy_reg_mdic(struct igc_hw *hw, uint32_t offset, uint16_t data)
231 {
232 	struct igc_phy_info *phy = &hw->phy;
233 	uint32_t i, mdic = 0;
234 
235 	DEBUGFUNC("igc_write_phy_reg_mdic");
236 
237 	if (offset > MAX_PHY_REG_ADDRESS) {
238 		DEBUGOUT1("PHY Address %d is out of range\n", offset);
239 		return -IGC_ERR_PARAM;
240 	}
241 
242 	/* Set up Op-code, Phy Address, and register offset in the MDI
243 	 * Control register.  The MAC will take care of interfacing with the
244 	 * PHY to retrieve the desired data.
245 	 */
246 	mdic = (((uint32_t)data) | (offset << IGC_MDIC_REG_SHIFT) |
247 	    (phy->addr << IGC_MDIC_PHY_SHIFT) | (IGC_MDIC_OP_WRITE));
248 
249 	IGC_WRITE_REG(hw, IGC_MDIC, mdic);
250 
251 	/* Poll the ready bit to see if the MDI read completed
252 	 * Increasing the time out as testing showed failures with
253 	 * the lower time out
254 	 */
255 	for (i = 0; i < (IGC_GEN_POLL_TIMEOUT * 3); i++) {
256 		DELAY(50);
257 		mdic = IGC_READ_REG(hw, IGC_MDIC);
258 		if (mdic & IGC_MDIC_READY)
259 			break;
260 	}
261 	if (!(mdic & IGC_MDIC_READY)) {
262 		DEBUGOUT("MDI Write did not complete\n");
263 		return -IGC_ERR_PHY;
264 	}
265 	if (mdic & IGC_MDIC_ERROR) {
266 		DEBUGOUT("MDI Error\n");
267 		return -IGC_ERR_PHY;
268 	}
269 	if (((mdic & IGC_MDIC_REG_MASK) >> IGC_MDIC_REG_SHIFT) != offset)
270 		return -IGC_ERR_PHY;
271 
272 	return IGC_SUCCESS;
273 }
274 
275 /**
276  *  igc_phy_setup_autoneg - Configure PHY for auto-negotiation
277  *  @hw: pointer to the HW structure
278  *
279  *  Reads the MII auto-neg advertisement register and/or the 1000T control
280  *  register and if the PHY is already setup for auto-negotiation, then
281  *  return successful.  Otherwise, setup advertisement and flow control to
282  *  the appropriate values for the wanted auto-negotiation.
283  **/
284 int
285 igc_phy_setup_autoneg(struct igc_hw *hw)
286 {
287 	struct igc_phy_info *phy = &hw->phy;
288 	uint16_t mii_autoneg_adv_reg;
289 	uint16_t mii_1000t_ctrl_reg = 0;
290 	uint16_t aneg_multigbt_an_ctrl = 0;
291 	int ret_val;
292 
293 	DEBUGFUNC("igc_phy_setup_autoneg");
294 
295 	phy->autoneg_advertised &= phy->autoneg_mask;
296 
297 	/* Read the MII Auto-Neg Advertisement Register (Address 4). */
298 	ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
299 	if (ret_val)
300 		return ret_val;
301 
302 	if (phy->autoneg_mask & ADVERTISE_1000_FULL) {
303 		/* Read the MII 1000Base-T Control Register (Address 9). */
304 		ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL,
305 		    &mii_1000t_ctrl_reg);
306 		if (ret_val)
307 			return ret_val;
308 	}
309 
310 	if ((phy->autoneg_mask & ADVERTISE_2500_FULL) &&
311 	    hw->phy.id == I225_I_PHY_ID) {
312 		/* Read the MULTI GBT AN Control Register - reg 7.32 */
313 		ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
314 		    MMD_DEVADDR_SHIFT) | ANEG_MULTIGBT_AN_CTRL,
315 		    &aneg_multigbt_an_ctrl);
316 		if (ret_val)
317 			return ret_val;
318 	}
319 
320 	/* Need to parse both autoneg_advertised and fc and set up
321 	 * the appropriate PHY registers.  First we will parse for
322 	 * autoneg_advertised software override.  Since we can advertise
323 	 * a plethora of combinations, we need to check each bit
324 	 * individually.
325 	 */
326 
327 	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
328 	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
329 	 * the  1000Base-T Control Register (Address 9).
330 	 */
331 	mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS | NWAY_AR_100TX_HD_CAPS |
332 	    NWAY_AR_10T_FD_CAPS | NWAY_AR_10T_HD_CAPS);
333 	mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
334 
335 	DEBUGOUT1("autoneg_advertised %x\n", phy->autoneg_advertised);
336 
337 	/* Do we want to advertise 10 Mb Half Duplex? */
338 	if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
339 		DEBUGOUT("Advertise 10mb Half duplex\n");
340 		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
341 	}
342 
343 	/* Do we want to advertise 10 Mb Full Duplex? */
344 	if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
345 		DEBUGOUT("Advertise 10mb Full duplex\n");
346 		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
347 	}
348 
349 	/* Do we want to advertise 100 Mb Half Duplex? */
350 	if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
351 		DEBUGOUT("Advertise 100mb Half duplex\n");
352 		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
353 	}
354 
355 	/* Do we want to advertise 100 Mb Full Duplex? */
356 	if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
357 		DEBUGOUT("Advertise 100mb Full duplex\n");
358 		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
359 	}
360 
361 	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
362 	if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
363 		DEBUGOUT("Advertise 1000mb Half duplex request denied!\n");
364 
365 	/* Do we want to advertise 1000 Mb Full Duplex? */
366 	if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
367 		DEBUGOUT("Advertise 1000mb Full duplex\n");
368 		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
369 	}
370 
371 	/* We do not allow the Phy to advertise 2500 Mb Half Duplex */
372 	if (phy->autoneg_advertised & ADVERTISE_2500_HALF)
373 		DEBUGOUT("Advertise 2500mb Half duplex request denied!\n");
374 
375 	/* Do we want to advertise 2500 Mb Full Duplex? */
376 	if (phy->autoneg_advertised & ADVERTISE_2500_FULL) {
377 		DEBUGOUT("Advertise 2500mb Full duplex\n");
378 		aneg_multigbt_an_ctrl |= CR_2500T_FD_CAPS;
379 	} else
380 		aneg_multigbt_an_ctrl &= ~CR_2500T_FD_CAPS;
381 
382 	/* Check for a software override of the flow control settings, and
383 	 * setup the PHY advertisement registers accordingly.  If
384 	 * auto-negotiation is enabled, then software will have to set the
385 	 * "PAUSE" bits to the correct value in the Auto-Negotiation
386 	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
387 	 * negotiation.
388 	 *
389 	 * The possible values of the "fc" parameter are:
390 	 *      0:  Flow control is completely disabled
391 	 *      1:  Rx flow control is enabled (we can receive pause frames
392 	 *          but not send pause frames).
393 	 *      2:  Tx flow control is enabled (we can send pause frames
394 	 *          but we do not support receiving pause frames).
395 	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
396 	 *  other:  No software override.  The flow control configuration
397 	 *          in the EEPROM is used.
398 	 */
399 	switch (hw->fc.current_mode) {
400 	case igc_fc_none:
401 		/* Flow control (Rx & Tx) is completely disabled by a
402 		 * software over-ride.
403 		 */
404 		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
405 		break;
406 	case igc_fc_rx_pause:
407 		/* Rx Flow control is enabled, and Tx Flow control is
408 		 * disabled, by a software over-ride.
409 		 *
410 		 * Since there really isn't a way to advertise that we are
411 		 * capable of Rx Pause ONLY, we will advertise that we
412 		 * support both symmetric and asymmetric Rx PAUSE.  Later
413 		 * (in igc_config_fc_after_link_up) we will disable the
414 		 * hw's ability to send PAUSE frames.
415 		 */
416 		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
417 		break;
418 	case igc_fc_tx_pause:
419 		/* Tx Flow control is enabled, and Rx Flow control is
420 		 * disabled, by a software over-ride.
421 		 */
422 		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
423 		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
424 		break;
425 	case igc_fc_full:
426 		/* Flow control (both Rx and Tx) is enabled by a software
427 		 * over-ride.
428 		 */
429 		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
430 		break;
431 	default:
432 		DEBUGOUT("Flow control param set incorrectly\n");
433 		return -IGC_ERR_CONFIG;
434 	}
435 
436 	ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
437 	if (ret_val)
438 		return ret_val;
439 
440 	DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
441 
442 	if (phy->autoneg_mask & ADVERTISE_1000_FULL)
443 		ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL,
444 		    mii_1000t_ctrl_reg);
445 
446 	if ((phy->autoneg_mask & ADVERTISE_2500_FULL) &&
447 	    hw->phy.id == I225_I_PHY_ID)
448 		ret_val = phy->ops.write_reg(hw,
449 		    (STANDARD_AN_REG_MASK << MMD_DEVADDR_SHIFT) |
450 		    ANEG_MULTIGBT_AN_CTRL, aneg_multigbt_an_ctrl);
451 
452 	return ret_val;
453 }
454 
455 /**
456  *  igc_copper_link_autoneg - Setup/Enable autoneg for copper link
457  *  @hw: pointer to the HW structure
458  *
459  *  Performs initial bounds checking on autoneg advertisement parameter, then
460  *  configure to advertise the full capability.  Setup the PHY to autoneg
461  *  and restart the negotiation process between the link partner.  If
462  *  autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
463  **/
464 int
465 igc_copper_link_autoneg(struct igc_hw *hw)
466 {
467 	struct igc_phy_info *phy = &hw->phy;
468 	uint16_t phy_ctrl;
469 	int ret_val;
470 
471 	DEBUGFUNC("igc_copper_link_autoneg");
472 
473 	/* Perform some bounds checking on the autoneg advertisement
474 	 * parameter.
475 	 */
476 	phy->autoneg_advertised &= phy->autoneg_mask;
477 
478 	/* If autoneg_advertised is zero, we assume it was not defaulted
479 	 * by the calling code so we set to advertise full capability.
480 	 */
481 	if (!phy->autoneg_advertised)
482 		phy->autoneg_advertised = phy->autoneg_mask;
483 
484 	DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
485 	ret_val = igc_phy_setup_autoneg(hw);
486 	if (ret_val) {
487 		DEBUGOUT("Error Setting up Auto-Negotiation\n");
488 		return ret_val;
489 	}
490 	DEBUGOUT("Restarting Auto-Neg\n");
491 
492 	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
493 	 * the Auto Neg Restart bit in the PHY control register.
494 	 */
495 	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
496 	if (ret_val)
497 		return ret_val;
498 
499 	phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
500 	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
501 	if (ret_val)
502 		return ret_val;
503 
504 	/* Does the user want to wait for Auto-Neg to complete here, or
505 	 * check at a later time (for example, callback routine).
506 	 */
507 	if (phy->autoneg_wait_to_complete) {
508 		ret_val = igc_wait_autoneg(hw);
509 		if (ret_val)
510 			return ret_val;
511 	}
512 
513 	hw->mac.get_link_status = true;
514 
515 	return ret_val;
516 }
517 
518 /**
519  *  igc_setup_copper_link_generic - Configure copper link settings
520  *  @hw: pointer to the HW structure
521  *
522  *  Calls the appropriate function to configure the link for auto-neg or forced
523  *  speed and duplex.  Then we check for link, once link is established calls
524  *  to configure collision distance and flow control are called.  If link is
525  *  not established, we return -IGC_ERR_PHY (-2).
526  **/
527 int
528 igc_setup_copper_link_generic(struct igc_hw *hw)
529 {
530 	int ret_val;
531 	bool link;
532 
533 	DEBUGFUNC("igc_setup_copper_link_generic");
534 
535 	if (hw->mac.autoneg) {
536 		/* Setup autoneg and flow control advertisement and perform
537 		 * autonegotiation.
538 		 */
539 		ret_val = igc_copper_link_autoneg(hw);
540 		if (ret_val)
541 			return ret_val;
542 	} else {
543 		/* PHY will be set to 10H, 10F, 100H or 100F
544 		 * depending on user settings.
545 		 */
546 		DEBUGOUT("Forcing Speed and Duplex\n");
547 		ret_val = hw->phy.ops.force_speed_duplex(hw);
548 		if (ret_val) {
549 			DEBUGOUT("Error Forcing Speed and Duplex\n");
550 			return ret_val;
551 		}
552 	}
553 
554 	/* Check link status. Wait up to 100 microseconds for link to become
555 	 * valid.
556 	 */
557 	ret_val = igc_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
558 	    &link);
559 	if (ret_val)
560 		return ret_val;
561 
562 	if (link) {
563 		DEBUGOUT("Valid link established!!!\n");
564 		hw->mac.ops.config_collision_dist(hw);
565 		ret_val = igc_config_fc_after_link_up_generic(hw);
566 	} else
567 		DEBUGOUT("Unable to establish link!!!\n");
568 
569 	return ret_val;
570 }
571 
572 /**
573  *  igc_check_downshift_generic - Checks whether a downshift in speed occurred
574  *  @hw: pointer to the HW structure
575  *
576  *  Success returns 0, Failure returns 1
577  *
578  *  A downshift is detected by querying the PHY link health.
579  **/
580 int
581 igc_check_downshift_generic(struct igc_hw *hw)
582 {
583 	struct igc_phy_info *phy = &hw->phy;
584 	int ret_val;
585 
586 	DEBUGFUNC("igc_check_downshift_generic");
587 
588 	switch (phy->type) {
589 	case igc_phy_i225:
590 	default:
591 		/* speed downshift not supported */
592 		phy->speed_downgraded = false;
593 		return IGC_SUCCESS;
594 	}
595 
596 	return ret_val;
597 }
598 
599 /**
600  *  igc_wait_autoneg - Wait for auto-neg completion
601  *  @hw: pointer to the HW structure
602  *
603  *  Waits for auto-negotiation to complete or for the auto-negotiation time
604  *  limit to expire, which ever happens first.
605  **/
606 int
607 igc_wait_autoneg(struct igc_hw *hw)
608 {
609 	uint16_t i, phy_status;
610 	int ret_val = IGC_SUCCESS;
611 
612 	DEBUGFUNC("igc_wait_autoneg");
613 
614 	if (!hw->phy.ops.read_reg)
615 		return IGC_SUCCESS;
616 
617 	/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
618 	for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
619 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
620 		if (ret_val)
621 			break;
622 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
623 		if (ret_val)
624 			break;
625 		if (phy_status & MII_SR_AUTONEG_COMPLETE)
626 			break;
627 		msec_delay(100);
628 	}
629 
630 	/* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
631 	 * has completed.
632 	 */
633 	return ret_val;
634 }
635 
636 /**
637  *  igc_phy_has_link_generic - Polls PHY for link
638  *  @hw: pointer to the HW structure
639  *  @iterations: number of times to poll for link
640  *  @usec_interval: delay between polling attempts
641  *  @success: pointer to whether polling was successful or not
642  *
643  *  Polls the PHY status register for link, 'iterations' number of times.
644  **/
645 int
646 igc_phy_has_link_generic(struct igc_hw *hw, uint32_t iterations,
647     uint32_t usec_interval, bool *success)
648 {
649 	uint16_t i, phy_status;
650 	int ret_val = IGC_SUCCESS;
651 
652 	DEBUGFUNC("igc_phy_has_link_generic");
653 
654 	if (!hw->phy.ops.read_reg)
655 		return IGC_SUCCESS;
656 
657 	for (i = 0; i < iterations; i++) {
658 		/* Some PHYs require the PHY_STATUS register to be read
659 		 * twice due to the link bit being sticky.  No harm doing
660 		 * it across the board.
661 		 */
662 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
663 		if (ret_val) {
664 			/* If the first read fails, another entity may have
665 			 * ownership of the resources, wait and try again to
666 			 * see if they have relinquished the resources yet.
667 			 */
668 			if (usec_interval >= 1000)
669 				msec_delay(usec_interval/1000);
670 			else
671 				DELAY(usec_interval);
672 		}
673 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
674 		if (ret_val)
675 			break;
676 		if (phy_status & MII_SR_LINK_STATUS)
677 			break;
678 		if (usec_interval >= 1000)
679 			msec_delay(usec_interval/1000);
680 		else
681 			DELAY(usec_interval);
682 	}
683 
684 	*success = (i < iterations);
685 
686 	return ret_val;
687 }
688 
689 /**
690  *  igc_phy_hw_reset_generic - PHY hardware reset
691  *  @hw: pointer to the HW structure
692  *
693  *  Verify the reset block is not blocking us from resetting.  Acquire
694  *  semaphore (if necessary) and read/set/write the device control reset
695  *  bit in the PHY.  Wait the appropriate delay time for the device to
696  *  reset and release the semaphore (if necessary).
697  **/
698 int
699 igc_phy_hw_reset_generic(struct igc_hw *hw)
700 {
701 	struct igc_phy_info *phy = &hw->phy;
702 	uint32_t ctrl, timeout = 10000, phpm = 0;
703 	int ret_val;
704 
705 	DEBUGFUNC("igc_phy_hw_reset_generic");
706 
707 	if (phy->ops.check_reset_block) {
708 		ret_val = phy->ops.check_reset_block(hw);
709 		if (ret_val)
710 			return IGC_SUCCESS;
711 	}
712 
713 	ret_val = phy->ops.acquire(hw);
714 	if (ret_val)
715 		return ret_val;
716 
717 	phpm = IGC_READ_REG(hw, IGC_I225_PHPM);
718 
719 	ctrl = IGC_READ_REG(hw, IGC_CTRL);
720 	IGC_WRITE_REG(hw, IGC_CTRL, ctrl | IGC_CTRL_PHY_RST);
721 	IGC_WRITE_FLUSH(hw);
722 
723 	DELAY(phy->reset_delay_us);
724 
725 	IGC_WRITE_REG(hw, IGC_CTRL, ctrl);
726 	IGC_WRITE_FLUSH(hw);
727 
728 	DELAY(150);
729 
730 	do {
731 		phpm = IGC_READ_REG(hw, IGC_I225_PHPM);
732 		timeout--;
733 		DELAY(1);
734 	} while (!(phpm & IGC_I225_PHPM_RST_COMPL) && timeout);
735 
736 	if (!timeout)
737 		DEBUGOUT("Timeout expired after a phy reset\n");
738 
739 	phy->ops.release(hw);
740 
741 	return ret_val;
742 }
743 
744 /**
745  * igc_power_up_phy_copper - Restore copper link in case of PHY power down
746  * @hw: pointer to the HW structure
747  *
748  * In the case of a PHY power down to save power, or to turn off link during a
749  * driver unload, or wake on lan is not enabled, restore the link to previous
750  * settings.
751  **/
752 void
753 igc_power_up_phy_copper(struct igc_hw *hw)
754 {
755 	uint16_t mii_reg = 0;
756 
757 	/* The PHY will retain its settings across a power down/up cycle */
758 	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
759 	mii_reg &= ~MII_CR_POWER_DOWN;
760 	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
761 	DELAY(300);
762 }
763 
764 /**
765  * igc_power_down_phy_copper - Restore copper link in case of PHY power down
766  * @hw: pointer to the HW structure
767  *
768  * In the case of a PHY power down to save power, or to turn off link during a
769  * driver unload, or wake on lan is not enabled, restore the link to previous
770  * settings.
771  **/
772 void
773 igc_power_down_phy_copper(struct igc_hw *hw)
774 {
775 	uint16_t mii_reg = 0;
776 
777 	/* The PHY will retain its settings across a power down/up cycle */
778 	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
779 	mii_reg |= MII_CR_POWER_DOWN;
780 	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
781 	msec_delay(1);
782 }
783 
784 /**
785  *  igc_write_phy_reg_gpy - Write GPY PHY register
786  *  @hw: pointer to the HW structure
787  *  @offset: register offset to write to
788  *  @data: data to write at register offset
789  *
790  *  Acquires semaphore, if necessary, then writes the data to PHY register
791  *  at the offset.  Release any acquired semaphores before exiting.
792  **/
793 int
794 igc_write_phy_reg_gpy(struct igc_hw *hw, uint32_t offset, uint16_t data)
795 {
796 	uint8_t dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
797 	int ret_val;
798 
799 	DEBUGFUNC("igc_write_phy_reg_gpy");
800 
801 	offset = offset & GPY_REG_MASK;
802 
803 	if (!dev_addr) {
804 		ret_val = hw->phy.ops.acquire(hw);
805 		if (ret_val)
806 			return ret_val;
807 		ret_val = igc_write_phy_reg_mdic(hw, offset, data);
808 		if (ret_val)
809 			return ret_val;
810 		hw->phy.ops.release(hw);
811 	} else {
812 		ret_val = igc_write_xmdio_reg(hw, (uint16_t)offset, dev_addr,
813 		    data);
814 	}
815 
816 	return ret_val;
817 }
818 
819 /**
820  *  igc_read_phy_reg_gpy - Read GPY PHY register
821  *  @hw: pointer to the HW structure
822  *  @offset: lower half is register offset to read to
823  *     upper half is MMD to use.
824  *  @data: data to read at register offset
825  *
826  *  Acquires semaphore, if necessary, then reads the data in the PHY register
827  *  at the offset.  Release any acquired semaphores before exiting.
828  **/
829 int
830 igc_read_phy_reg_gpy(struct igc_hw *hw, uint32_t offset, uint16_t *data)
831 {
832 	uint8_t dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
833 	int ret_val;
834 
835 	DEBUGFUNC("igc_read_phy_reg_gpy");
836 
837 	offset = offset & GPY_REG_MASK;
838 
839 	if (!dev_addr) {
840 		ret_val = hw->phy.ops.acquire(hw);
841 		if (ret_val)
842 			return ret_val;
843 		ret_val = igc_read_phy_reg_mdic(hw, offset, data);
844 		if (ret_val)
845 			return ret_val;
846 		hw->phy.ops.release(hw);
847 	} else {
848 		ret_val = igc_read_xmdio_reg(hw, (uint16_t)offset, dev_addr,
849 		    data);
850 	}
851 
852 	return ret_val;
853 }
854 
855 /**
856  *  __igc_access_xmdio_reg - Read/write XMDIO register
857  *  @hw: pointer to the HW structure
858  *  @address: XMDIO address to program
859  *  @dev_addr: device address to program
860  *  @data: pointer to value to read/write from/to the XMDIO address
861  *  @read: boolean flag to indicate read or write
862  **/
863 int
864 __igc_access_xmdio_reg(struct igc_hw *hw, uint16_t address, uint8_t dev_addr,
865     uint16_t *data, bool read)
866 {
867 	int ret_val;
868 
869 	DEBUGFUNC("__igc_access_xmdio_reg");
870 
871 	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, dev_addr);
872 	if (ret_val)
873 		return ret_val;
874 
875 	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, address);
876 	if (ret_val)
877 		return ret_val;
878 
879 	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, IGC_MMDAC_FUNC_DATA |
880 	    dev_addr);
881 	if (ret_val)
882 		return ret_val;
883 
884 	if (read)
885 		ret_val = hw->phy.ops.read_reg(hw, IGC_MMDAAD, data);
886 	else
887 		ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, *data);
888 	if (ret_val)
889 		return ret_val;
890 
891 	/* Recalibrate the device back to 0 */
892 	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, 0);
893 	if (ret_val)
894 		return ret_val;
895 
896 	return ret_val;
897 }
898 
899 /**
900  *  igc_read_xmdio_reg - Read XMDIO register
901  *  @hw: pointer to the HW structure
902  *  @addr: XMDIO address to program
903  *  @dev_addr: device address to program
904  *  @data: value to be read from the EMI address
905  **/
906 int
907 igc_read_xmdio_reg(struct igc_hw *hw, uint16_t addr, uint8_t dev_addr,
908     uint16_t *data)
909 {
910 	DEBUGFUNC("igc_read_xmdio_reg");
911 
912 	return __igc_access_xmdio_reg(hw, addr, dev_addr, data, true);
913 }
914 
915 /**
916  *  igc_write_xmdio_reg - Write XMDIO register
917  *  @hw: pointer to the HW structure
918  *  @addr: XMDIO address to program
919  *  @dev_addr: device address to program
920  *  @data: value to be written to the XMDIO address
921  **/
922 int
923 igc_write_xmdio_reg(struct igc_hw *hw, uint16_t addr, uint8_t dev_addr,
924     uint16_t data)
925 {
926 	DEBUGFUNC("igc_write_xmdio_reg");
927 
928 	return __igc_access_xmdio_reg(hw, addr, dev_addr, &data, false);
929 }
930