aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/igc/igc_mac.c
diff options
context:
space:
mode:
authorSasha Neftin <sasha.neftin@intel.com>2018-10-11 03:17:34 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2018-10-17 16:56:55 -0400
commit4eb8080143a9d9fd513bacc65b2466c57983aaae (patch)
tree32923ea729cb92f3afbf68e7ca1698ed7db0b2ef /drivers/net/ethernet/intel/igc/igc_mac.c
parent5586838fe9ced0980e210b39d635ff3842297448 (diff)
igc: Add setup link functionality
Add link establishment methods Add auto negotiation methods Add read MAC address method Signed-off-by: Sasha Neftin <sasha.neftin@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igc/igc_mac.c')
-rw-r--r--drivers/net/ethernet/intel/igc/igc_mac.c271
1 files changed, 271 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc_mac.c b/drivers/net/ethernet/intel/igc/igc_mac.c
index fce7f7f5aa46..f7683d3ae47c 100644
--- a/drivers/net/ethernet/intel/igc/igc_mac.c
+++ b/drivers/net/ethernet/intel/igc/igc_mac.c
@@ -92,6 +92,8 @@ s32 igc_setup_link(struct igc_hw *hw)
92 /* In the case of the phy reset being blocked, we already have a link. 92 /* In the case of the phy reset being blocked, we already have a link.
93 * We do not need to set it up again. 93 * We do not need to set it up again.
94 */ 94 */
95 if (igc_check_reset_block(hw))
96 goto out;
95 97
96 /* If requested flow control is set to default, set flow control 98 /* If requested flow control is set to default, set flow control
97 * based on the EEPROM flow control settings. 99 * based on the EEPROM flow control settings.
@@ -142,10 +144,74 @@ out:
142 */ 144 */
143static s32 igc_set_default_fc(struct igc_hw *hw) 145static s32 igc_set_default_fc(struct igc_hw *hw)
144{ 146{
147 hw->fc.requested_mode = igc_fc_full;
145 return 0; 148 return 0;
146} 149}
147 150
148/** 151/**
152 * igc_force_mac_fc - Force the MAC's flow control settings
153 * @hw: pointer to the HW structure
154 *
155 * Force the MAC's flow control settings. Sets the TFCE and RFCE bits in the
156 * device control register to reflect the adapter settings. TFCE and RFCE
157 * need to be explicitly set by software when a copper PHY is used because
158 * autonegotiation is managed by the PHY rather than the MAC. Software must
159 * also configure these bits when link is forced on a fiber connection.
160 */
161s32 igc_force_mac_fc(struct igc_hw *hw)
162{
163 s32 ret_val = 0;
164 u32 ctrl;
165
166 ctrl = rd32(IGC_CTRL);
167
168 /* Because we didn't get link via the internal auto-negotiation
169 * mechanism (we either forced link or we got link via PHY
170 * auto-neg), we have to manually enable/disable transmit an
171 * receive flow control.
172 *
173 * The "Case" statement below enables/disable flow control
174 * according to the "hw->fc.current_mode" parameter.
175 *
176 * The possible values of the "fc" parameter are:
177 * 0: Flow control is completely disabled
178 * 1: Rx flow control is enabled (we can receive pause
179 * frames but not send pause frames).
180 * 2: Tx flow control is enabled (we can send pause frames
181 * frames but we do not receive pause frames).
182 * 3: Both Rx and TX flow control (symmetric) is enabled.
183 * other: No other values should be possible at this point.
184 */
185 hw_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
186
187 switch (hw->fc.current_mode) {
188 case igc_fc_none:
189 ctrl &= (~(IGC_CTRL_TFCE | IGC_CTRL_RFCE));
190 break;
191 case igc_fc_rx_pause:
192 ctrl &= (~IGC_CTRL_TFCE);
193 ctrl |= IGC_CTRL_RFCE;
194 break;
195 case igc_fc_tx_pause:
196 ctrl &= (~IGC_CTRL_RFCE);
197 ctrl |= IGC_CTRL_TFCE;
198 break;
199 case igc_fc_full:
200 ctrl |= (IGC_CTRL_TFCE | IGC_CTRL_RFCE);
201 break;
202 default:
203 hw_dbg("Flow control param set incorrectly\n");
204 ret_val = -IGC_ERR_CONFIG;
205 goto out;
206 }
207
208 wr32(IGC_CTRL, ctrl);
209
210out:
211 return ret_val;
212}
213
214/**
149 * igc_set_fc_watermarks - Set flow control high/low watermarks 215 * igc_set_fc_watermarks - Set flow control high/low watermarks
150 * @hw: pointer to the HW structure 216 * @hw: pointer to the HW structure
151 * 217 *
@@ -371,6 +437,7 @@ s32 igc_check_for_copper_link(struct igc_hw *hw)
371 * settings because we may have had to re-autoneg with a 437 * settings because we may have had to re-autoneg with a
372 * different link partner. 438 * different link partner.
373 */ 439 */
440 ret_val = igc_config_fc_after_link_up(hw);
374 if (ret_val) 441 if (ret_val)
375 hw_dbg("Error configuring flow control\n"); 442 hw_dbg("Error configuring flow control\n");
376 443
@@ -400,6 +467,210 @@ void igc_config_collision_dist(struct igc_hw *hw)
400} 467}
401 468
402/** 469/**
470 * igc_config_fc_after_link_up - Configures flow control after link
471 * @hw: pointer to the HW structure
472 *
473 * Checks the status of auto-negotiation after link up to ensure that the
474 * speed and duplex were not forced. If the link needed to be forced, then
475 * flow control needs to be forced also. If auto-negotiation is enabled
476 * and did not fail, then we configure flow control based on our link
477 * partner.
478 */
479s32 igc_config_fc_after_link_up(struct igc_hw *hw)
480{
481 u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
482 struct igc_mac_info *mac = &hw->mac;
483 u16 speed, duplex;
484 s32 ret_val = 0;
485
486 /* Check for the case where we have fiber media and auto-neg failed
487 * so we had to force link. In this case, we need to force the
488 * configuration of the MAC to match the "fc" parameter.
489 */
490 if (mac->autoneg_failed) {
491 if (hw->phy.media_type == igc_media_type_copper)
492 ret_val = igc_force_mac_fc(hw);
493 }
494
495 if (ret_val) {
496 hw_dbg("Error forcing flow control settings\n");
497 goto out;
498 }
499
500 /* Check for the case where we have copper media and auto-neg is
501 * enabled. In this case, we need to check and see if Auto-Neg
502 * has completed, and if so, how the PHY and link partner has
503 * flow control configured.
504 */
505 if (hw->phy.media_type == igc_media_type_copper && mac->autoneg) {
506 /* Read the MII Status Register and check to see if AutoNeg
507 * has completed. We read this twice because this reg has
508 * some "sticky" (latched) bits.
509 */
510 ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
511 &mii_status_reg);
512 if (ret_val)
513 goto out;
514 ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
515 &mii_status_reg);
516 if (ret_val)
517 goto out;
518
519 if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
520 hw_dbg("Copper PHY and Auto Neg has not completed.\n");
521 goto out;
522 }
523
524 /* The AutoNeg process has completed, so we now need to
525 * read both the Auto Negotiation Advertisement
526 * Register (Address 4) and the Auto_Negotiation Base
527 * Page Ability Register (Address 5) to determine how
528 * flow control was negotiated.
529 */
530 ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV,
531 &mii_nway_adv_reg);
532 if (ret_val)
533 goto out;
534 ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY,
535 &mii_nway_lp_ability_reg);
536 if (ret_val)
537 goto out;
538 /* Two bits in the Auto Negotiation Advertisement Register
539 * (Address 4) and two bits in the Auto Negotiation Base
540 * Page Ability Register (Address 5) determine flow control
541 * for both the PHY and the link partner. The following
542 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
543 * 1999, describes these PAUSE resolution bits and how flow
544 * control is determined based upon these settings.
545 * NOTE: DC = Don't Care
546 *
547 * LOCAL DEVICE | LINK PARTNER
548 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
549 *-------|---------|-------|---------|--------------------
550 * 0 | 0 | DC | DC | igc_fc_none
551 * 0 | 1 | 0 | DC | igc_fc_none
552 * 0 | 1 | 1 | 0 | igc_fc_none
553 * 0 | 1 | 1 | 1 | igc_fc_tx_pause
554 * 1 | 0 | 0 | DC | igc_fc_none
555 * 1 | DC | 1 | DC | igc_fc_full
556 * 1 | 1 | 0 | 0 | igc_fc_none
557 * 1 | 1 | 0 | 1 | igc_fc_rx_pause
558 *
559 * Are both PAUSE bits set to 1? If so, this implies
560 * Symmetric Flow Control is enabled at both ends. The
561 * ASM_DIR bits are irrelevant per the spec.
562 *
563 * For Symmetric Flow Control:
564 *
565 * LOCAL DEVICE | LINK PARTNER
566 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
567 *-------|---------|-------|---------|--------------------
568 * 1 | DC | 1 | DC | IGC_fc_full
569 *
570 */
571 if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
572 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
573 /* Now we need to check if the user selected RX ONLY
574 * of pause frames. In this case, we had to advertise
575 * FULL flow control because we could not advertise RX
576 * ONLY. Hence, we must now check to see if we need to
577 * turn OFF the TRANSMISSION of PAUSE frames.
578 */
579 if (hw->fc.requested_mode == igc_fc_full) {
580 hw->fc.current_mode = igc_fc_full;
581 hw_dbg("Flow Control = FULL.\n");
582 } else {
583 hw->fc.current_mode = igc_fc_rx_pause;
584 hw_dbg("Flow Control = RX PAUSE frames only.\n");
585 }
586 }
587
588 /* For receiving PAUSE frames ONLY.
589 *
590 * LOCAL DEVICE | LINK PARTNER
591 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
592 *-------|---------|-------|---------|--------------------
593 * 0 | 1 | 1 | 1 | igc_fc_tx_pause
594 */
595 else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
596 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
597 (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
598 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
599 hw->fc.current_mode = igc_fc_tx_pause;
600 hw_dbg("Flow Control = TX PAUSE frames only.\n");
601 }
602 /* For transmitting PAUSE frames ONLY.
603 *
604 * LOCAL DEVICE | LINK PARTNER
605 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
606 *-------|---------|-------|---------|--------------------
607 * 1 | 1 | 0 | 1 | igc_fc_rx_pause
608 */
609 else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
610 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
611 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
612 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
613 hw->fc.current_mode = igc_fc_rx_pause;
614 hw_dbg("Flow Control = RX PAUSE frames only.\n");
615 }
616 /* Per the IEEE spec, at this point flow control should be
617 * disabled. However, we want to consider that we could
618 * be connected to a legacy switch that doesn't advertise
619 * desired flow control, but can be forced on the link
620 * partner. So if we advertised no flow control, that is
621 * what we will resolve to. If we advertised some kind of
622 * receive capability (Rx Pause Only or Full Flow Control)
623 * and the link partner advertised none, we will configure
624 * ourselves to enable Rx Flow Control only. We can do
625 * this safely for two reasons: If the link partner really
626 * didn't want flow control enabled, and we enable Rx, no
627 * harm done since we won't be receiving any PAUSE frames
628 * anyway. If the intent on the link partner was to have
629 * flow control enabled, then by us enabling RX only, we
630 * can at least receive pause frames and process them.
631 * This is a good idea because in most cases, since we are
632 * predominantly a server NIC, more times than not we will
633 * be asked to delay transmission of packets than asking
634 * our link partner to pause transmission of frames.
635 */
636 else if ((hw->fc.requested_mode == igc_fc_none) ||
637 (hw->fc.requested_mode == igc_fc_tx_pause) ||
638 (hw->fc.strict_ieee)) {
639 hw->fc.current_mode = igc_fc_none;
640 hw_dbg("Flow Control = NONE.\n");
641 } else {
642 hw->fc.current_mode = igc_fc_rx_pause;
643 hw_dbg("Flow Control = RX PAUSE frames only.\n");
644 }
645
646 /* Now we need to do one last check... If we auto-
647 * negotiated to HALF DUPLEX, flow control should not be
648 * enabled per IEEE 802.3 spec.
649 */
650 ret_val = hw->mac.ops.get_speed_and_duplex(hw, &speed, &duplex);
651 if (ret_val) {
652 hw_dbg("Error getting link speed and duplex\n");
653 goto out;
654 }
655
656 if (duplex == HALF_DUPLEX)
657 hw->fc.current_mode = igc_fc_none;
658
659 /* Now we call a subroutine to actually force the MAC
660 * controller to use the correct flow control settings.
661 */
662 ret_val = igc_force_mac_fc(hw);
663 if (ret_val) {
664 hw_dbg("Error forcing flow control settings\n");
665 goto out;
666 }
667 }
668
669out:
670 return 0;
671}
672
673/**
403 * igc_get_auto_rd_done - Check for auto read completion 674 * igc_get_auto_rd_done - Check for auto read completion
404 * @hw: pointer to the HW structure 675 * @hw: pointer to the HW structure
405 * 676 *