]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From 6c55c3cdc86881383075a933594748b30dd0054b Mon Sep 17 00:00:00 2001 |
2 | From: Eilon Greenstein <eilong@broadcom.com> | |
3 | Date: Wed, 14 Jan 2009 06:44:13 +0000 | |
4 | Subject: bnx2x: 1G-10G toggling race | |
5 | Acked-by: Karsten Keil <kkeil@novell.com> | |
6 | Reference: bnc#472500 | |
7 | ||
8 | The HW should be configured so fast toggling between 1G and 10G will not be | |
9 | missed. Make sure that the HW is re-configured in full | |
10 | ||
11 | Signed-off-by: Yaniv Rosner <yanivr@broadcom.com> | |
12 | Signed-off-by: Eilon Greenstein <eilong@broadcom.com> | |
13 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
14 | --- | |
15 | drivers/net/bnx2x_link.c | 43 ++++++++++++++++++++++++++++++++----------- | |
16 | 1 files changed, 32 insertions(+), 11 deletions(-) | |
17 | ||
18 | Index: linux-2.6.27-bnx2x_2/drivers/net/bnx2x_link.c | |
19 | =================================================================== | |
20 | --- linux-2.6.27-bnx2x_2.orig/drivers/net/bnx2x_link.c | |
21 | +++ linux-2.6.27-bnx2x_2/drivers/net/bnx2x_link.c | |
22 | @@ -317,6 +317,9 @@ static u8 bnx2x_emac_enable(struct link_ | |
23 | val &= ~0x810; | |
24 | EMAC_WR(bp, EMAC_REG_EMAC_MODE, val); | |
25 | ||
26 | + /* enable emac */ | |
27 | + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1); | |
28 | + | |
29 | /* enable emac for jumbo packets */ | |
30 | EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE, | |
31 | (EMAC_RX_MTU_SIZE_JUMBO_ENA | | |
32 | @@ -1609,7 +1612,7 @@ static u8 bnx2x_link_settings_status(str | |
33 | u32 gp_status) | |
34 | { | |
35 | struct bnx2x *bp = params->bp; | |
36 | - | |
37 | + u16 new_line_speed; | |
38 | u8 rc = 0; | |
39 | vars->link_status = 0; | |
40 | ||
41 | @@ -1629,7 +1632,7 @@ static u8 bnx2x_link_settings_status(str | |
42 | ||
43 | switch (gp_status & GP_STATUS_SPEED_MASK) { | |
44 | case GP_STATUS_10M: | |
45 | - vars->line_speed = SPEED_10; | |
46 | + new_line_speed = SPEED_10; | |
47 | if (vars->duplex == DUPLEX_FULL) | |
48 | vars->link_status |= LINK_10TFD; | |
49 | else | |
50 | @@ -1637,7 +1640,7 @@ static u8 bnx2x_link_settings_status(str | |
51 | break; | |
52 | ||
53 | case GP_STATUS_100M: | |
54 | - vars->line_speed = SPEED_100; | |
55 | + new_line_speed = SPEED_100; | |
56 | if (vars->duplex == DUPLEX_FULL) | |
57 | vars->link_status |= LINK_100TXFD; | |
58 | else | |
59 | @@ -1646,7 +1649,7 @@ static u8 bnx2x_link_settings_status(str | |
60 | ||
61 | case GP_STATUS_1G: | |
62 | case GP_STATUS_1G_KX: | |
63 | - vars->line_speed = SPEED_1000; | |
64 | + new_line_speed = SPEED_1000; | |
65 | if (vars->duplex == DUPLEX_FULL) | |
66 | vars->link_status |= LINK_1000TFD; | |
67 | else | |
68 | @@ -1654,7 +1657,7 @@ static u8 bnx2x_link_settings_status(str | |
69 | break; | |
70 | ||
71 | case GP_STATUS_2_5G: | |
72 | - vars->line_speed = SPEED_2500; | |
73 | + new_line_speed = SPEED_2500; | |
74 | if (vars->duplex == DUPLEX_FULL) | |
75 | vars->link_status |= LINK_2500TFD; | |
76 | else | |
77 | @@ -1671,32 +1674,32 @@ static u8 bnx2x_link_settings_status(str | |
78 | case GP_STATUS_10G_KX4: | |
79 | case GP_STATUS_10G_HIG: | |
80 | case GP_STATUS_10G_CX4: | |
81 | - vars->line_speed = SPEED_10000; | |
82 | + new_line_speed = SPEED_10000; | |
83 | vars->link_status |= LINK_10GTFD; | |
84 | break; | |
85 | ||
86 | case GP_STATUS_12G_HIG: | |
87 | - vars->line_speed = SPEED_12000; | |
88 | + new_line_speed = SPEED_12000; | |
89 | vars->link_status |= LINK_12GTFD; | |
90 | break; | |
91 | ||
92 | case GP_STATUS_12_5G: | |
93 | - vars->line_speed = SPEED_12500; | |
94 | + new_line_speed = SPEED_12500; | |
95 | vars->link_status |= LINK_12_5GTFD; | |
96 | break; | |
97 | ||
98 | case GP_STATUS_13G: | |
99 | - vars->line_speed = SPEED_13000; | |
100 | + new_line_speed = SPEED_13000; | |
101 | vars->link_status |= LINK_13GTFD; | |
102 | break; | |
103 | ||
104 | case GP_STATUS_15G: | |
105 | - vars->line_speed = SPEED_15000; | |
106 | + new_line_speed = SPEED_15000; | |
107 | vars->link_status |= LINK_15GTFD; | |
108 | break; | |
109 | ||
110 | case GP_STATUS_16G: | |
111 | - vars->line_speed = SPEED_16000; | |
112 | + new_line_speed = SPEED_16000; | |
113 | vars->link_status |= LINK_16GTFD; | |
114 | break; | |
115 | ||
116 | @@ -1708,6 +1711,15 @@ static u8 bnx2x_link_settings_status(str | |
117 | break; | |
118 | } | |
119 | ||
120 | + /* Upon link speed change set the NIG into drain mode. | |
121 | + Comes to deals with possible FIFO glitch due to clk change | |
122 | + when speed is decreased without link down indicator */ | |
123 | + if (new_line_speed != vars->line_speed) { | |
124 | + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE | |
125 | + + params->port*4, 0); | |
126 | + msleep(1); | |
127 | + } | |
128 | + vars->line_speed = new_line_speed; | |
129 | vars->link_status |= LINK_STATUS_SERDES_LINK; | |
130 | ||
131 | if ((params->req_line_speed == SPEED_AUTO_NEG) && | |
132 | @@ -4194,6 +4206,11 @@ static u8 bnx2x_update_link_down(struct | |
133 | /* activate nig drain */ | |
134 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); | |
135 | ||
136 | + /* disable emac */ | |
137 | + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); | |
138 | + | |
139 | + msleep(10); | |
140 | + | |
141 | /* reset BigMac */ | |
142 | bnx2x_bmac_rx_disable(bp, params->port); | |
143 | REG_WR(bp, GRCBASE_MISC + | |
144 | @@ -4238,6 +4255,7 @@ static u8 bnx2x_update_link_up(struct li | |
145 | ||
146 | /* update shared memory */ | |
147 | bnx2x_update_mng(params, vars->link_status); | |
148 | + msleep(20); | |
149 | return rc; | |
150 | } | |
151 | /* This function should called upon link interrupt */ | |
152 | @@ -4276,6 +4294,9 @@ u8 bnx2x_link_update(struct link_params | |
153 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), | |
154 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); | |
155 | ||
156 | + /* disable emac */ | |
157 | + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); | |
158 | + | |
159 | ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | |
160 | ||
161 | /* Check external link change only for non-direct */ |