aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_cmn.c
diff options
context:
space:
mode:
authorVladislav Zolotarov <vladz@broadcom.com>2011-05-04 19:48:23 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-05 13:44:33 -0400
commit2ae17f666099c952053eea7c64cac8189dd76f72 (patch)
tree69da6881c755adccec1ef4e09ec28bc499e979e9 /drivers/net/bnx2x/bnx2x_cmn.c
parent34da9e50e908c4553ddefb38da2c5bacbe2bba58 (diff)
bnx2x: link report improvements
To avoid link notification duplication Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com> Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_cmn.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.c129
1 files changed, 108 insertions, 21 deletions
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c
index 8729061a4fd5..8853ae2a042e 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -758,35 +758,119 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp)
758 return line_speed; 758 return line_speed;
759} 759}
760 760
761/**
762 * bnx2x_fill_report_data - fill link report data to report
763 *
764 * @bp: driver handle
765 * @data: link state to update
766 *
767 * It uses a none-atomic bit operations because is called under the mutex.
768 */
769static inline void bnx2x_fill_report_data(struct bnx2x *bp,
770 struct bnx2x_link_report_data *data)
771{
772 u16 line_speed = bnx2x_get_mf_speed(bp);
773
774 memset(data, 0, sizeof(*data));
775
776 /* Fill the report data: efective line speed */
777 data->line_speed = line_speed;
778
779 /* Link is down */
780 if (!bp->link_vars.link_up || (bp->flags & MF_FUNC_DIS))
781 __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
782 &data->link_report_flags);
783
784 /* Full DUPLEX */
785 if (bp->link_vars.duplex == DUPLEX_FULL)
786 __set_bit(BNX2X_LINK_REPORT_FD, &data->link_report_flags);
787
788 /* Rx Flow Control is ON */
789 if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX)
790 __set_bit(BNX2X_LINK_REPORT_RX_FC_ON, &data->link_report_flags);
791
792 /* Tx Flow Control is ON */
793 if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
794 __set_bit(BNX2X_LINK_REPORT_TX_FC_ON, &data->link_report_flags);
795}
796
797/**
798 * bnx2x_link_report - report link status to OS.
799 *
800 * @bp: driver handle
801 *
802 * Calls the __bnx2x_link_report() under the same locking scheme
803 * as a link/PHY state managing code to ensure a consistent link
804 * reporting.
805 */
806
761void bnx2x_link_report(struct bnx2x *bp) 807void bnx2x_link_report(struct bnx2x *bp)
762{ 808{
763 if (bp->flags & MF_FUNC_DIS) { 809 bnx2x_acquire_phy_lock(bp);
764 netif_carrier_off(bp->dev); 810 __bnx2x_link_report(bp);
765 netdev_err(bp->dev, "NIC Link is Down\n"); 811 bnx2x_release_phy_lock(bp);
766 return; 812}
767 }
768 813
769 if (bp->link_vars.link_up) { 814/**
770 u16 line_speed; 815 * __bnx2x_link_report - report link status to OS.
816 *
817 * @bp: driver handle
818 *
819 * None atomic inmlementation.
820 * Should be called under the phy_lock.
821 */
822void __bnx2x_link_report(struct bnx2x *bp)
823{
824 struct bnx2x_link_report_data cur_data;
771 825
772 if (bp->state == BNX2X_STATE_OPEN) 826 /* reread mf_cfg */
773 netif_carrier_on(bp->dev); 827 if (!CHIP_IS_E1(bp))
774 netdev_info(bp->dev, "NIC Link is Up, "); 828 bnx2x_read_mf_cfg(bp);
829
830 /* Read the current link report info */
831 bnx2x_fill_report_data(bp, &cur_data);
832
833 /* Don't report link down or exactly the same link status twice */
834 if (!memcmp(&cur_data, &bp->last_reported_link, sizeof(cur_data)) ||
835 (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
836 &bp->last_reported_link.link_report_flags) &&
837 test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
838 &cur_data.link_report_flags)))
839 return;
840
841 bp->link_cnt++;
775 842
776 line_speed = bnx2x_get_mf_speed(bp); 843 /* We are going to report a new link parameters now -
844 * remember the current data for the next time.
845 */
846 memcpy(&bp->last_reported_link, &cur_data, sizeof(cur_data));
777 847
778 pr_cont("%d Mbps ", line_speed); 848 if (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
849 &cur_data.link_report_flags)) {
850 netif_carrier_off(bp->dev);
851 netdev_err(bp->dev, "NIC Link is Down\n");
852 return;
853 } else {
854 netif_carrier_on(bp->dev);
855 netdev_info(bp->dev, "NIC Link is Up, ");
856 pr_cont("%d Mbps ", cur_data.line_speed);
779 857
780 if (bp->link_vars.duplex == DUPLEX_FULL) 858 if (test_and_clear_bit(BNX2X_LINK_REPORT_FD,
859 &cur_data.link_report_flags))
781 pr_cont("full duplex"); 860 pr_cont("full duplex");
782 else 861 else
783 pr_cont("half duplex"); 862 pr_cont("half duplex");
784 863
785 if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) { 864 /* Handle the FC at the end so that only these flags would be
786 if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) { 865 * possibly set. This way we may easily check if there is no FC
866 * enabled.
867 */
868 if (cur_data.link_report_flags) {
869 if (test_bit(BNX2X_LINK_REPORT_RX_FC_ON,
870 &cur_data.link_report_flags)) {
787 pr_cont(", receive "); 871 pr_cont(", receive ");
788 if (bp->link_vars.flow_ctrl & 872 if (test_bit(BNX2X_LINK_REPORT_TX_FC_ON,
789 BNX2X_FLOW_CTRL_TX) 873 &cur_data.link_report_flags))
790 pr_cont("& transmit "); 874 pr_cont("& transmit ");
791 } else { 875 } else {
792 pr_cont(", transmit "); 876 pr_cont(", transmit ");
@@ -794,10 +878,6 @@ void bnx2x_link_report(struct bnx2x *bp)
794 pr_cont("flow control ON"); 878 pr_cont("flow control ON");
795 } 879 }
796 pr_cont("\n"); 880 pr_cont("\n");
797
798 } else { /* link_down */
799 netif_carrier_off(bp->dev);
800 netdev_err(bp->dev, "NIC Link is Down\n");
801 } 881 }
802} 882}
803 883
@@ -1345,6 +1425,13 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
1345 1425
1346 bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; 1426 bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
1347 1427
1428 /* Set the initial link reported state to link down */
1429 bnx2x_acquire_phy_lock(bp);
1430 memset(&bp->last_reported_link, 0, sizeof(bp->last_reported_link));
1431 __set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
1432 &bp->last_reported_link.link_report_flags);
1433 bnx2x_release_phy_lock(bp);
1434
1348 /* must be called before memory allocation and HW init */ 1435 /* must be called before memory allocation and HW init */
1349 bnx2x_ilt_set_info(bp); 1436 bnx2x_ilt_set_info(bp);
1350 1437