xref: /openbsd/sys/dev/pci/igc_phy.c (revision d415bd75)
1 /*	$OpenBSD: igc_phy.c,v 1.3 2023/02/03 11:31:52 mbuhl 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 		/* Read the MULTI GBT AN Control Register - reg 7.32 */
312 		ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK <<
313 		    MMD_DEVADDR_SHIFT) | ANEG_MULTIGBT_AN_CTRL,
314 		    &aneg_multigbt_an_ctrl);
315 		if (ret_val)
316 			return ret_val;
317 	}
318 
319 	/* Need to parse both autoneg_advertised and fc and set up
320 	 * the appropriate PHY registers.  First we will parse for
321 	 * autoneg_advertised software override.  Since we can advertise
322 	 * a plethora of combinations, we need to check each bit
323 	 * individually.
324 	 */
325 
326 	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
327 	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
328 	 * the  1000Base-T Control Register (Address 9).
329 	 */
330 	mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS | NWAY_AR_100TX_HD_CAPS |
331 	    NWAY_AR_10T_FD_CAPS | NWAY_AR_10T_HD_CAPS);
332 	mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS);
333 
334 	DEBUGOUT1("autoneg_advertised %x\n", phy->autoneg_advertised);
335 
336 	/* Do we want to advertise 10 Mb Half Duplex? */
337 	if (phy->autoneg_advertised & ADVERTISE_10_HALF) {
338 		DEBUGOUT("Advertise 10mb Half duplex\n");
339 		mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
340 	}
341 
342 	/* Do we want to advertise 10 Mb Full Duplex? */
343 	if (phy->autoneg_advertised & ADVERTISE_10_FULL) {
344 		DEBUGOUT("Advertise 10mb Full duplex\n");
345 		mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
346 	}
347 
348 	/* Do we want to advertise 100 Mb Half Duplex? */
349 	if (phy->autoneg_advertised & ADVERTISE_100_HALF) {
350 		DEBUGOUT("Advertise 100mb Half duplex\n");
351 		mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
352 	}
353 
354 	/* Do we want to advertise 100 Mb Full Duplex? */
355 	if (phy->autoneg_advertised & ADVERTISE_100_FULL) {
356 		DEBUGOUT("Advertise 100mb Full duplex\n");
357 		mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
358 	}
359 
360 	/* We do not allow the Phy to advertise 1000 Mb Half Duplex */
361 	if (phy->autoneg_advertised & ADVERTISE_1000_HALF)
362 		DEBUGOUT("Advertise 1000mb Half duplex request denied!\n");
363 
364 	/* Do we want to advertise 1000 Mb Full Duplex? */
365 	if (phy->autoneg_advertised & ADVERTISE_1000_FULL) {
366 		DEBUGOUT("Advertise 1000mb Full duplex\n");
367 		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
368 	}
369 
370 	/* We do not allow the Phy to advertise 2500 Mb Half Duplex */
371 	if (phy->autoneg_advertised & ADVERTISE_2500_HALF)
372 		DEBUGOUT("Advertise 2500mb Half duplex request denied!\n");
373 
374 	/* Do we want to advertise 2500 Mb Full Duplex? */
375 	if (phy->autoneg_advertised & ADVERTISE_2500_FULL) {
376 		DEBUGOUT("Advertise 2500mb Full duplex\n");
377 		aneg_multigbt_an_ctrl |= CR_2500T_FD_CAPS;
378 	} else
379 		aneg_multigbt_an_ctrl &= ~CR_2500T_FD_CAPS;
380 
381 	/* Check for a software override of the flow control settings, and
382 	 * setup the PHY advertisement registers accordingly.  If
383 	 * auto-negotiation is enabled, then software will have to set the
384 	 * "PAUSE" bits to the correct value in the Auto-Negotiation
385 	 * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-
386 	 * negotiation.
387 	 *
388 	 * The possible values of the "fc" parameter are:
389 	 *      0:  Flow control is completely disabled
390 	 *      1:  Rx flow control is enabled (we can receive pause frames
391 	 *          but not send pause frames).
392 	 *      2:  Tx flow control is enabled (we can send pause frames
393 	 *          but we do not support receiving pause frames).
394 	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
395 	 *  other:  No software override.  The flow control configuration
396 	 *          in the EEPROM is used.
397 	 */
398 	switch (hw->fc.current_mode) {
399 	case igc_fc_none:
400 		/* Flow control (Rx & Tx) is completely disabled by a
401 		 * software over-ride.
402 		 */
403 		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
404 		break;
405 	case igc_fc_rx_pause:
406 		/* Rx Flow control is enabled, and Tx Flow control is
407 		 * disabled, by a software over-ride.
408 		 *
409 		 * Since there really isn't a way to advertise that we are
410 		 * capable of Rx Pause ONLY, we will advertise that we
411 		 * support both symmetric and asymmetric Rx PAUSE.  Later
412 		 * (in igc_config_fc_after_link_up) we will disable the
413 		 * hw's ability to send PAUSE frames.
414 		 */
415 		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
416 		break;
417 	case igc_fc_tx_pause:
418 		/* Tx Flow control is enabled, and Rx Flow control is
419 		 * disabled, by a software over-ride.
420 		 */
421 		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
422 		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
423 		break;
424 	case igc_fc_full:
425 		/* Flow control (both Rx and Tx) is enabled by a software
426 		 * over-ride.
427 		 */
428 		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
429 		break;
430 	default:
431 		DEBUGOUT("Flow control param set incorrectly\n");
432 		return -IGC_ERR_CONFIG;
433 	}
434 
435 	ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
436 	if (ret_val)
437 		return ret_val;
438 
439 	DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
440 
441 	if (phy->autoneg_mask & ADVERTISE_1000_FULL)
442 		ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL,
443 		    mii_1000t_ctrl_reg);
444 
445 	if (phy->autoneg_mask & ADVERTISE_2500_FULL)
446 		ret_val = phy->ops.write_reg(hw,
447 		    (STANDARD_AN_REG_MASK << MMD_DEVADDR_SHIFT) |
448 		    ANEG_MULTIGBT_AN_CTRL, aneg_multigbt_an_ctrl);
449 
450 	return ret_val;
451 }
452 
453 /**
454  *  igc_copper_link_autoneg - Setup/Enable autoneg for copper link
455  *  @hw: pointer to the HW structure
456  *
457  *  Performs initial bounds checking on autoneg advertisement parameter, then
458  *  configure to advertise the full capability.  Setup the PHY to autoneg
459  *  and restart the negotiation process between the link partner.  If
460  *  autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
461  **/
462 int
463 igc_copper_link_autoneg(struct igc_hw *hw)
464 {
465 	struct igc_phy_info *phy = &hw->phy;
466 	uint16_t phy_ctrl;
467 	int ret_val;
468 
469 	DEBUGFUNC("igc_copper_link_autoneg");
470 
471 	/* Perform some bounds checking on the autoneg advertisement
472 	 * parameter.
473 	 */
474 	phy->autoneg_advertised &= phy->autoneg_mask;
475 
476 	/* If autoneg_advertised is zero, we assume it was not defaulted
477 	 * by the calling code so we set to advertise full capability.
478 	 */
479 	if (!phy->autoneg_advertised)
480 		phy->autoneg_advertised = phy->autoneg_mask;
481 
482 	DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
483 	ret_val = igc_phy_setup_autoneg(hw);
484 	if (ret_val) {
485 		DEBUGOUT("Error Setting up Auto-Negotiation\n");
486 		return ret_val;
487 	}
488 	DEBUGOUT("Restarting Auto-Neg\n");
489 
490 	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
491 	 * the Auto Neg Restart bit in the PHY control register.
492 	 */
493 	ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
494 	if (ret_val)
495 		return ret_val;
496 
497 	phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
498 	ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl);
499 	if (ret_val)
500 		return ret_val;
501 
502 	/* Does the user want to wait for Auto-Neg to complete here, or
503 	 * check at a later time (for example, callback routine).
504 	 */
505 	if (phy->autoneg_wait_to_complete) {
506 		ret_val = igc_wait_autoneg(hw);
507 		if (ret_val)
508 			return ret_val;
509 	}
510 
511 	hw->mac.get_link_status = true;
512 
513 	return ret_val;
514 }
515 
516 /**
517  *  igc_setup_copper_link_generic - Configure copper link settings
518  *  @hw: pointer to the HW structure
519  *
520  *  Calls the appropriate function to configure the link for auto-neg or forced
521  *  speed and duplex.  Then we check for link, once link is established calls
522  *  to configure collision distance and flow control are called.  If link is
523  *  not established, we return -IGC_ERR_PHY (-2).
524  **/
525 int
526 igc_setup_copper_link_generic(struct igc_hw *hw)
527 {
528 	int ret_val;
529 	bool link;
530 
531 	DEBUGFUNC("igc_setup_copper_link_generic");
532 
533 	if (hw->mac.autoneg) {
534 		/* Setup autoneg and flow control advertisement and perform
535 		 * autonegotiation.
536 		 */
537 		ret_val = igc_copper_link_autoneg(hw);
538 		if (ret_val)
539 			return ret_val;
540 	} else {
541 		/* PHY will be set to 10H, 10F, 100H or 100F
542 		 * depending on user settings.
543 		 */
544 		DEBUGOUT("Forcing Speed and Duplex\n");
545 		ret_val = hw->phy.ops.force_speed_duplex(hw);
546 		if (ret_val) {
547 			DEBUGOUT("Error Forcing Speed and Duplex\n");
548 			return ret_val;
549 		}
550 	}
551 
552 	/* Check link status. Wait up to 100 microseconds for link to become
553 	 * valid.
554 	 */
555 	ret_val = igc_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
556 	    &link);
557 	if (ret_val)
558 		return ret_val;
559 
560 	if (link) {
561 		DEBUGOUT("Valid link established!!!\n");
562 		hw->mac.ops.config_collision_dist(hw);
563 		ret_val = igc_config_fc_after_link_up_generic(hw);
564 	} else
565 		DEBUGOUT("Unable to establish link!!!\n");
566 
567 	return ret_val;
568 }
569 
570 /**
571  *  igc_check_downshift_generic - Checks whether a downshift in speed occurred
572  *  @hw: pointer to the HW structure
573  *
574  *  Success returns 0, Failure returns 1
575  *
576  *  A downshift is detected by querying the PHY link health.
577  **/
578 int
579 igc_check_downshift_generic(struct igc_hw *hw)
580 {
581 	struct igc_phy_info *phy = &hw->phy;
582 	int ret_val;
583 
584 	DEBUGFUNC("igc_check_downshift_generic");
585 
586 	switch (phy->type) {
587 	case igc_phy_i225:
588 	default:
589 		/* speed downshift not supported */
590 		phy->speed_downgraded = false;
591 		return IGC_SUCCESS;
592 	}
593 
594 	return ret_val;
595 }
596 
597 /**
598  *  igc_wait_autoneg - Wait for auto-neg completion
599  *  @hw: pointer to the HW structure
600  *
601  *  Waits for auto-negotiation to complete or for the auto-negotiation time
602  *  limit to expire, which ever happens first.
603  **/
604 int
605 igc_wait_autoneg(struct igc_hw *hw)
606 {
607 	uint16_t i, phy_status;
608 	int ret_val = IGC_SUCCESS;
609 
610 	DEBUGFUNC("igc_wait_autoneg");
611 
612 	if (!hw->phy.ops.read_reg)
613 		return IGC_SUCCESS;
614 
615 	/* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */
616 	for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) {
617 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
618 		if (ret_val)
619 			break;
620 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
621 		if (ret_val)
622 			break;
623 		if (phy_status & MII_SR_AUTONEG_COMPLETE)
624 			break;
625 		msec_delay(100);
626 	}
627 
628 	/* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
629 	 * has completed.
630 	 */
631 	return ret_val;
632 }
633 
634 /**
635  *  igc_phy_has_link_generic - Polls PHY for link
636  *  @hw: pointer to the HW structure
637  *  @iterations: number of times to poll for link
638  *  @usec_interval: delay between polling attempts
639  *  @success: pointer to whether polling was successful or not
640  *
641  *  Polls the PHY status register for link, 'iterations' number of times.
642  **/
643 int
644 igc_phy_has_link_generic(struct igc_hw *hw, uint32_t iterations,
645     uint32_t usec_interval, bool *success)
646 {
647 	uint16_t i, phy_status;
648 	int ret_val = IGC_SUCCESS;
649 
650 	DEBUGFUNC("igc_phy_has_link_generic");
651 
652 	if (!hw->phy.ops.read_reg)
653 		return IGC_SUCCESS;
654 
655 	for (i = 0; i < iterations; i++) {
656 		/* Some PHYs require the PHY_STATUS register to be read
657 		 * twice due to the link bit being sticky.  No harm doing
658 		 * it across the board.
659 		 */
660 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
661 		if (ret_val) {
662 			/* If the first read fails, another entity may have
663 			 * ownership of the resources, wait and try again to
664 			 * see if they have relinquished the resources yet.
665 			 */
666 			if (usec_interval >= 1000)
667 				msec_delay(usec_interval/1000);
668 			else
669 				DELAY(usec_interval);
670 		}
671 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
672 		if (ret_val)
673 			break;
674 		if (phy_status & MII_SR_LINK_STATUS)
675 			break;
676 		if (usec_interval >= 1000)
677 			msec_delay(usec_interval/1000);
678 		else
679 			DELAY(usec_interval);
680 	}
681 
682 	*success = (i < iterations);
683 
684 	return ret_val;
685 }
686 
687 /**
688  *  igc_phy_hw_reset_generic - PHY hardware reset
689  *  @hw: pointer to the HW structure
690  *
691  *  Verify the reset block is not blocking us from resetting.  Acquire
692  *  semaphore (if necessary) and read/set/write the device control reset
693  *  bit in the PHY.  Wait the appropriate delay time for the device to
694  *  reset and release the semaphore (if necessary).
695  **/
696 int
697 igc_phy_hw_reset_generic(struct igc_hw *hw)
698 {
699 	struct igc_phy_info *phy = &hw->phy;
700 	uint32_t ctrl, timeout = 10000, phpm = 0;
701 	int ret_val;
702 
703 	DEBUGFUNC("igc_phy_hw_reset_generic");
704 
705 	if (phy->ops.check_reset_block) {
706 		ret_val = phy->ops.check_reset_block(hw);
707 		if (ret_val)
708 			return IGC_SUCCESS;
709 	}
710 
711 	ret_val = phy->ops.acquire(hw);
712 	if (ret_val)
713 		return ret_val;
714 
715 	phpm = IGC_READ_REG(hw, IGC_I225_PHPM);
716 
717 	ctrl = IGC_READ_REG(hw, IGC_CTRL);
718 	IGC_WRITE_REG(hw, IGC_CTRL, ctrl | IGC_CTRL_PHY_RST);
719 	IGC_WRITE_FLUSH(hw);
720 
721 	DELAY(phy->reset_delay_us);
722 
723 	IGC_WRITE_REG(hw, IGC_CTRL, ctrl);
724 	IGC_WRITE_FLUSH(hw);
725 
726 	DELAY(150);
727 
728 	do {
729 		phpm = IGC_READ_REG(hw, IGC_I225_PHPM);
730 		timeout--;
731 		DELAY(1);
732 	} while (!(phpm & IGC_I225_PHPM_RST_COMPL) && timeout);
733 
734 	if (!timeout)
735 		DEBUGOUT("Timeout expired after a phy reset\n");
736 
737 	phy->ops.release(hw);
738 
739 	return ret_val;
740 }
741 
742 /**
743  * igc_power_up_phy_copper - Restore copper link in case of PHY power down
744  * @hw: pointer to the HW structure
745  *
746  * In the case of a PHY power down to save power, or to turn off link during a
747  * driver unload, or wake on lan is not enabled, restore the link to previous
748  * settings.
749  **/
750 void
751 igc_power_up_phy_copper(struct igc_hw *hw)
752 {
753 	uint16_t mii_reg = 0;
754 
755 	/* The PHY will retain its settings across a power down/up cycle */
756 	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
757 	mii_reg &= ~MII_CR_POWER_DOWN;
758 	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
759 	DELAY(300);
760 }
761 
762 /**
763  * igc_power_down_phy_copper - Restore copper link in case of PHY power down
764  * @hw: pointer to the HW structure
765  *
766  * In the case of a PHY power down to save power, or to turn off link during a
767  * driver unload, or wake on lan is not enabled, restore the link to previous
768  * settings.
769  **/
770 void
771 igc_power_down_phy_copper(struct igc_hw *hw)
772 {
773 	uint16_t mii_reg = 0;
774 
775 	/* The PHY will retain its settings across a power down/up cycle */
776 	hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
777 	mii_reg |= MII_CR_POWER_DOWN;
778 	hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
779 	msec_delay(1);
780 }
781 
782 /**
783  *  igc_write_phy_reg_gpy - Write GPY PHY register
784  *  @hw: pointer to the HW structure
785  *  @offset: register offset to write to
786  *  @data: data to write at register offset
787  *
788  *  Acquires semaphore, if necessary, then writes the data to PHY register
789  *  at the offset.  Release any acquired semaphores before exiting.
790  **/
791 int
792 igc_write_phy_reg_gpy(struct igc_hw *hw, uint32_t offset, uint16_t data)
793 {
794 	uint8_t dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
795 	int ret_val;
796 
797 	DEBUGFUNC("igc_write_phy_reg_gpy");
798 
799 	offset = offset & GPY_REG_MASK;
800 
801 	if (!dev_addr) {
802 		ret_val = hw->phy.ops.acquire(hw);
803 		if (ret_val)
804 			return ret_val;
805 		ret_val = igc_write_phy_reg_mdic(hw, offset, data);
806 		if (ret_val)
807 			return ret_val;
808 		hw->phy.ops.release(hw);
809 	} else {
810 		ret_val = igc_write_xmdio_reg(hw, (uint16_t)offset, dev_addr,
811 		    data);
812 	}
813 
814 	return ret_val;
815 }
816 
817 /**
818  *  igc_read_phy_reg_gpy - Read GPY PHY register
819  *  @hw: pointer to the HW structure
820  *  @offset: lower half is register offset to read to
821  *     upper half is MMD to use.
822  *  @data: data to read at register offset
823  *
824  *  Acquires semaphore, if necessary, then reads the data in the PHY register
825  *  at the offset.  Release any acquired semaphores before exiting.
826  **/
827 int
828 igc_read_phy_reg_gpy(struct igc_hw *hw, uint32_t offset, uint16_t *data)
829 {
830 	uint8_t dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
831 	int ret_val;
832 
833 	DEBUGFUNC("igc_read_phy_reg_gpy");
834 
835 	offset = offset & GPY_REG_MASK;
836 
837 	if (!dev_addr) {
838 		ret_val = hw->phy.ops.acquire(hw);
839 		if (ret_val)
840 			return ret_val;
841 		ret_val = igc_read_phy_reg_mdic(hw, offset, data);
842 		if (ret_val)
843 			return ret_val;
844 		hw->phy.ops.release(hw);
845 	} else {
846 		ret_val = igc_read_xmdio_reg(hw, (uint16_t)offset, dev_addr,
847 		    data);
848 	}
849 
850 	return ret_val;
851 }
852 
853 /**
854  *  __igc_access_xmdio_reg - Read/write XMDIO register
855  *  @hw: pointer to the HW structure
856  *  @address: XMDIO address to program
857  *  @dev_addr: device address to program
858  *  @data: pointer to value to read/write from/to the XMDIO address
859  *  @read: boolean flag to indicate read or write
860  **/
861 int
862 __igc_access_xmdio_reg(struct igc_hw *hw, uint16_t address, uint8_t dev_addr,
863     uint16_t *data, bool read)
864 {
865 	int ret_val;
866 
867 	DEBUGFUNC("__igc_access_xmdio_reg");
868 
869 	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, dev_addr);
870 	if (ret_val)
871 		return ret_val;
872 
873 	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, address);
874 	if (ret_val)
875 		return ret_val;
876 
877 	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, IGC_MMDAC_FUNC_DATA |
878 	    dev_addr);
879 	if (ret_val)
880 		return ret_val;
881 
882 	if (read)
883 		ret_val = hw->phy.ops.read_reg(hw, IGC_MMDAAD, data);
884 	else
885 		ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAAD, *data);
886 	if (ret_val)
887 		return ret_val;
888 
889 	/* Recalibrate the device back to 0 */
890 	ret_val = hw->phy.ops.write_reg(hw, IGC_MMDAC, 0);
891 	if (ret_val)
892 		return ret_val;
893 
894 	return ret_val;
895 }
896 
897 /**
898  *  igc_read_xmdio_reg - Read XMDIO register
899  *  @hw: pointer to the HW structure
900  *  @addr: XMDIO address to program
901  *  @dev_addr: device address to program
902  *  @data: value to be read from the EMI address
903  **/
904 int
905 igc_read_xmdio_reg(struct igc_hw *hw, uint16_t addr, uint8_t dev_addr,
906     uint16_t *data)
907 {
908 	DEBUGFUNC("igc_read_xmdio_reg");
909 
910 	return __igc_access_xmdio_reg(hw, addr, dev_addr, data, true);
911 }
912 
913 /**
914  *  igc_write_xmdio_reg - Write XMDIO register
915  *  @hw: pointer to the HW structure
916  *  @addr: XMDIO address to program
917  *  @dev_addr: device address to program
918  *  @data: value to be written to the XMDIO address
919  **/
920 int
921 igc_write_xmdio_reg(struct igc_hw *hw, uint16_t addr, uint8_t dev_addr,
922     uint16_t data)
923 {
924 	DEBUGFUNC("igc_write_xmdio_reg");
925 
926 	return __igc_access_xmdio_reg(hw, addr, dev_addr, &data, false);
927 }
928