bnx2x: Disable AN KR work-around for BCM57810
[linux-2.6.git] / drivers / net / ethernet / broadcom / bnx2x / bnx2x_link.c
1 /* Copyright 2008-2011 Broadcom Corporation
2  *
3  * Unless you and Broadcom execute a separate written software license
4  * agreement governing use of this software, this software is licensed to you
5  * under the terms of the GNU General Public License version 2, available
6  * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7  *
8  * Notwithstanding the above, under no circumstances may you combine this
9  * software in any way with any other Broadcom software provided under a
10  * license other than the GPL, without Broadcom's express prior written
11  * consent.
12  *
13  * Written by Yaniv Rosner
14  *
15  */
16
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/pci.h>
22 #include <linux/netdevice.h>
23 #include <linux/delay.h>
24 #include <linux/ethtool.h>
25 #include <linux/mutex.h>
26
27 #include "bnx2x.h"
28 #include "bnx2x_cmn.h"
29
30 /********************************************************/
31 #define ETH_HLEN                        14
32 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
33 #define ETH_OVREHEAD                    (ETH_HLEN + 8 + 8)
34 #define ETH_MIN_PACKET_SIZE             60
35 #define ETH_MAX_PACKET_SIZE             1500
36 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
37 #define MDIO_ACCESS_TIMEOUT             1000
38 #define BMAC_CONTROL_RX_ENABLE          2
39 #define WC_LANE_MAX                     4
40 #define I2C_SWITCH_WIDTH                2
41 #define I2C_BSC0                        0
42 #define I2C_BSC1                        1
43 #define I2C_WA_RETRY_CNT                3
44 #define MCPR_IMC_COMMAND_READ_OP        1
45 #define MCPR_IMC_COMMAND_WRITE_OP       2
46
47 /* LED Blink rate that will achieve ~15.9Hz */
48 #define LED_BLINK_RATE_VAL_E3           354
49 #define LED_BLINK_RATE_VAL_E1X_E2       480
50 /***********************************************************/
51 /*                      Shortcut definitions               */
52 /***********************************************************/
53
54 #define NIG_LATCH_BC_ENABLE_MI_INT 0
55
56 #define NIG_STATUS_EMAC0_MI_INT \
57                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
58 #define NIG_STATUS_XGXS0_LINK10G \
59                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
60 #define NIG_STATUS_XGXS0_LINK_STATUS \
61                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
62 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
63                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
64 #define NIG_STATUS_SERDES0_LINK_STATUS \
65                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
66 #define NIG_MASK_MI_INT \
67                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
68 #define NIG_MASK_XGXS0_LINK10G \
69                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
70 #define NIG_MASK_XGXS0_LINK_STATUS \
71                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
72 #define NIG_MASK_SERDES0_LINK_STATUS \
73                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
74
75 #define MDIO_AN_CL73_OR_37_COMPLETE \
76                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
77                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
78
79 #define XGXS_RESET_BITS \
80         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
81          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
82          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
83          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
84          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
85
86 #define SERDES_RESET_BITS \
87         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
88          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
89          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
90          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
91
92 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
93 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
94 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
95 #define AUTONEG_PARALLEL \
96                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
97 #define AUTONEG_SGMII_FIBER_AUTODET \
98                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
99 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
100
101 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
102                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
103 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
104                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
105 #define GP_STATUS_SPEED_MASK \
106                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
107 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
108 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
109 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
110 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
111 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
112 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
113 #define GP_STATUS_10G_HIG \
114                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
115 #define GP_STATUS_10G_CX4 \
116                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
117 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
118 #define GP_STATUS_10G_KX4 \
119                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
120 #define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
121 #define GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
122 #define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
123 #define GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
124 #define LINK_10THD              LINK_STATUS_SPEED_AND_DUPLEX_10THD
125 #define LINK_10TFD              LINK_STATUS_SPEED_AND_DUPLEX_10TFD
126 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
127 #define LINK_100T4              LINK_STATUS_SPEED_AND_DUPLEX_100T4
128 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
129 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
130 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
131 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
132 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
133 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
134 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
135 #define LINK_10GTFD             LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
136 #define LINK_10GXFD             LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
137 #define LINK_20GTFD             LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
138 #define LINK_20GXFD             LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
139
140
141
142 /* */
143 #define SFP_EEPROM_CON_TYPE_ADDR                0x2
144         #define SFP_EEPROM_CON_TYPE_VAL_LC      0x7
145         #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
146
147
148 #define SFP_EEPROM_COMP_CODE_ADDR               0x3
149         #define SFP_EEPROM_COMP_CODE_SR_MASK    (1<<4)
150         #define SFP_EEPROM_COMP_CODE_LR_MASK    (1<<5)
151         #define SFP_EEPROM_COMP_CODE_LRM_MASK   (1<<6)
152
153 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
154         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
155         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
156
157 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
158         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
159 #define SFP_EEPROM_OPTIONS_SIZE                 2
160
161 #define EDC_MODE_LINEAR                         0x0022
162 #define EDC_MODE_LIMITING                               0x0044
163 #define EDC_MODE_PASSIVE_DAC                    0x0055
164
165 /* BRB default for class 0 E2 */
166 #define DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR      170
167 #define DEFAULT0_E2_BRB_MAC_PAUSE_XON_THR               250
168 #define DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR               10
169 #define DEFAULT0_E2_BRB_MAC_FULL_XON_THR                50
170
171 /* BRB thresholds for E2*/
172 #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE             170
173 #define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE         0
174
175 #define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE              250
176 #define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE          0
177
178 #define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE              10
179 #define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE          90
180
181 #define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE                       50
182 #define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE           250
183
184 /* BRB default for class 0 E3A0 */
185 #define DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR    290
186 #define DEFAULT0_E3A0_BRB_MAC_PAUSE_XON_THR     410
187 #define DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR     10
188 #define DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR      50
189
190 /* BRB thresholds for E3A0 */
191 #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE           290
192 #define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE               0
193
194 #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE            410
195 #define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE                0
196
197 #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE            10
198 #define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE                170
199
200 #define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE             50
201 #define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE         410
202
203 /* BRB default for E3B0 */
204 #define DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR    330
205 #define DEFAULT0_E3B0_BRB_MAC_PAUSE_XON_THR     490
206 #define DEFAULT0_E3B0_BRB_MAC_FULL_XOFF_THR     15
207 #define DEFAULT0_E3B0_BRB_MAC_FULL_XON_THR      55
208
209 /* BRB thresholds for E3B0 2 port mode*/
210 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE                1025
211 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE    0
212
213 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE         1025
214 #define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE     0
215
216 #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE         10
217 #define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE     1025
218
219 #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE          50
220 #define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE      1025
221
222 /* only for E3B0*/
223 #define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR                        1025
224 #define PFC_E3B0_2P_BRB_FULL_LB_XON_THR                 1025
225
226 /* Lossy +Lossless GUARANTIED == GUART */
227 #define PFC_E3B0_2P_MIX_PAUSE_LB_GUART                  284
228 /* Lossless +Lossless*/
229 #define PFC_E3B0_2P_PAUSE_LB_GUART                      236
230 /* Lossy +Lossy*/
231 #define PFC_E3B0_2P_NON_PAUSE_LB_GUART                  342
232
233 /* Lossy +Lossless*/
234 #define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART               284
235 /* Lossless +Lossless*/
236 #define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART           236
237 /* Lossy +Lossy*/
238 #define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART               336
239 #define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST                80
240
241 #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART             0
242 #define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST                0
243
244 /* BRB thresholds for E3B0 4 port mode */
245 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE                304
246 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE    0
247
248 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE         384
249 #define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE     0
250
251 #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE         10
252 #define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE     304
253
254 #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE          50
255 #define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE      384
256
257 /* only for E3B0*/
258 #define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR                        304
259 #define PFC_E3B0_4P_BRB_FULL_LB_XON_THR                 384
260 #define PFC_E3B0_4P_LB_GUART            120
261
262 #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART             120
263 #define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST        80
264
265 #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART             80
266 #define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST        120
267
268 /* Pause defines*/
269 #define DEFAULT_E3B0_BRB_FULL_LB_XOFF_THR                       330
270 #define DEFAULT_E3B0_BRB_FULL_LB_XON_THR                        490
271 #define DEFAULT_E3B0_LB_GUART           40
272
273 #define DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART            40
274 #define DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART_HYST       0
275
276 #define DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART            40
277 #define DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART_HYST       0
278
279 /* ETS defines*/
280 #define DCBX_INVALID_COS                                        (0xFF)
281
282 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND         (0x5000)
283 #define ETS_BW_LIMIT_CREDIT_WEIGHT              (0x5000)
284 #define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS             (1360)
285 #define ETS_E3B0_NIG_MIN_W_VAL_20GBPS                   (2720)
286 #define ETS_E3B0_PBF_MIN_W_VAL                          (10000)
287
288 #define MAX_PACKET_SIZE                                 (9700)
289 #define WC_UC_TIMEOUT                                   100
290 #define MAX_KR_LINK_RETRY                               4
291
292 /**********************************************************/
293 /*                     INTERFACE                          */
294 /**********************************************************/
295
296 #define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
297         bnx2x_cl45_write(_bp, _phy, \
298                 (_phy)->def_md_devad, \
299                 (_bank + (_addr & 0xf)), \
300                 _val)
301
302 #define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
303         bnx2x_cl45_read(_bp, _phy, \
304                 (_phy)->def_md_devad, \
305                 (_bank + (_addr & 0xf)), \
306                 _val)
307
308 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
309 {
310         u32 val = REG_RD(bp, reg);
311
312         val |= bits;
313         REG_WR(bp, reg, val);
314         return val;
315 }
316
317 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
318 {
319         u32 val = REG_RD(bp, reg);
320
321         val &= ~bits;
322         REG_WR(bp, reg, val);
323         return val;
324 }
325
326 /******************************************************************/
327 /*                      EPIO/GPIO section                         */
328 /******************************************************************/
329 static void bnx2x_get_epio(struct bnx2x *bp, u32 epio_pin, u32 *en)
330 {
331         u32 epio_mask, gp_oenable;
332         *en = 0;
333         /* Sanity check */
334         if (epio_pin > 31) {
335                 DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to get\n", epio_pin);
336                 return;
337         }
338
339         epio_mask = 1 << epio_pin;
340         /* Set this EPIO to output */
341         gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
342         REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
343
344         *en = (REG_RD(bp, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
345 }
346 static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en)
347 {
348         u32 epio_mask, gp_output, gp_oenable;
349
350         /* Sanity check */
351         if (epio_pin > 31) {
352                 DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin);
353                 return;
354         }
355         DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en);
356         epio_mask = 1 << epio_pin;
357         /* Set this EPIO to output */
358         gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS);
359         if (en)
360                 gp_output |= epio_mask;
361         else
362                 gp_output &= ~epio_mask;
363
364         REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
365
366         /* Set the value for this EPIO */
367         gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
368         REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
369 }
370
371 static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val)
372 {
373         if (pin_cfg == PIN_CFG_NA)
374                 return;
375         if (pin_cfg >= PIN_CFG_EPIO0) {
376                 bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
377         } else {
378                 u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
379                 u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
380                 bnx2x_set_gpio(bp, gpio_num, (u8)val, gpio_port);
381         }
382 }
383
384 static u32 bnx2x_get_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 *val)
385 {
386         if (pin_cfg == PIN_CFG_NA)
387                 return -EINVAL;
388         if (pin_cfg >= PIN_CFG_EPIO0) {
389                 bnx2x_get_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
390         } else {
391                 u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
392                 u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
393                 *val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
394         }
395         return 0;
396
397 }
398 /******************************************************************/
399 /*                              ETS section                       */
400 /******************************************************************/
401 static void bnx2x_ets_e2e3a0_disabled(struct link_params *params)
402 {
403         /* ETS disabled configuration*/
404         struct bnx2x *bp = params->bp;
405
406         DP(NETIF_MSG_LINK, "ETS E2E3 disabled configuration\n");
407
408         /*
409          * mapping between entry  priority to client number (0,1,2 -debug and
410          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
411          * 3bits client num.
412          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
413          * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
414          */
415
416         REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
417         /*
418          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
419          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
420          * COS0 entry, 4 - COS1 entry.
421          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
422          * bit4   bit3    bit2   bit1     bit0
423          * MCP and debug are strict
424          */
425
426         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
427         /* defines which entries (clients) are subjected to WFQ arbitration */
428         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
429         /*
430          * For strict priority entries defines the number of consecutive
431          * slots for the highest priority.
432          */
433         REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
434         /*
435          * mapping between the CREDIT_WEIGHT registers and actual client
436          * numbers
437          */
438         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
439         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
440         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
441
442         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
443         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
444         REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
445         /* ETS mode disable */
446         REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
447         /*
448          * If ETS mode is enabled (there is no strict priority) defines a WFQ
449          * weight for COS0/COS1.
450          */
451         REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
452         REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
453         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
454         REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
455         REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
456         /* Defines the number of consecutive slots for the strict priority */
457         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
458 }
459 /******************************************************************************
460 * Description:
461 *       Getting min_w_val will be set according to line speed .
462 *.
463 ******************************************************************************/
464 static u32 bnx2x_ets_get_min_w_val_nig(const struct link_vars *vars)
465 {
466         u32 min_w_val = 0;
467         /* Calculate min_w_val.*/
468         if (vars->link_up) {
469                 if (vars->line_speed == SPEED_20000)
470                         min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
471                 else
472                         min_w_val = ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
473         } else
474                 min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
475         /**
476          *  If the link isn't up (static configuration for example ) The
477          *  link will be according to 20GBPS.
478         */
479         return min_w_val;
480 }
481 /******************************************************************************
482 * Description:
483 *       Getting credit upper bound form min_w_val.
484 *.
485 ******************************************************************************/
486 static u32 bnx2x_ets_get_credit_upper_bound(const u32 min_w_val)
487 {
488         const u32 credit_upper_bound = (u32)MAXVAL((150 * min_w_val),
489                                                 MAX_PACKET_SIZE);
490         return credit_upper_bound;
491 }
492 /******************************************************************************
493 * Description:
494 *       Set credit upper bound for NIG.
495 *.
496 ******************************************************************************/
497 static void bnx2x_ets_e3b0_set_credit_upper_bound_nig(
498         const struct link_params *params,
499         const u32 min_w_val)
500 {
501         struct bnx2x *bp = params->bp;
502         const u8 port = params->port;
503         const u32 credit_upper_bound =
504             bnx2x_ets_get_credit_upper_bound(min_w_val);
505
506         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
507                 NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
508         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
509                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
510         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
511                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
512         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
513                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
514         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
515                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
516         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
517                    NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
518
519         if (!port) {
520                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
521                         credit_upper_bound);
522                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
523                         credit_upper_bound);
524                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
525                         credit_upper_bound);
526         }
527 }
528 /******************************************************************************
529 * Description:
530 *       Will return the NIG ETS registers to init values.Except
531 *       credit_upper_bound.
532 *       That isn't used in this configuration (No WFQ is enabled) and will be
533 *       configured acording to spec
534 *.
535 ******************************************************************************/
536 static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params,
537                                         const struct link_vars *vars)
538 {
539         struct bnx2x *bp = params->bp;
540         const u8 port = params->port;
541         const u32 min_w_val = bnx2x_ets_get_min_w_val_nig(vars);
542         /**
543          * mapping between entry  priority to client number (0,1,2 -debug and
544          * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
545          * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
546          * reset value or init tool
547          */
548         if (port) {
549                 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
550                 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
551         } else {
552                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
553                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
554         }
555         /**
556         * For strict priority entries defines the number of consecutive
557         * slots for the highest priority.
558         */
559         /* TODO_ETS - Should be done by reset value or init tool */
560         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
561                    NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
562         /**
563          * mapping between the CREDIT_WEIGHT registers and actual client
564          * numbers
565          */
566         /* TODO_ETS - Should be done by reset value or init tool */
567         if (port) {
568                 /*Port 1 has 6 COS*/
569                 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
570                 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
571         } else {
572                 /*Port 0 has 9 COS*/
573                 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
574                        0x43210876);
575                 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
576         }
577
578         /**
579          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
580          * as strict.  Bits 0,1,2 - debug and management entries, 3 -
581          * COS0 entry, 4 - COS1 entry.
582          * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
583          * bit4   bit3    bit2   bit1     bit0
584          * MCP and debug are strict
585          */
586         if (port)
587                 REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
588         else
589                 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
590         /* defines which entries (clients) are subjected to WFQ arbitration */
591         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
592                    NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
593
594         /**
595         * Please notice the register address are note continuous and a
596         * for here is note appropriate.In 2 port mode port0 only COS0-5
597         * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
598         * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
599         * are never used for WFQ
600         */
601         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
602                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
603         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
604                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
605         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
606                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
607         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
608                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
609         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
610                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
611         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
612                    NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
613         if (!port) {
614                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
615                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
616                 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
617         }
618
619         bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
620 }
621 /******************************************************************************
622 * Description:
623 *       Set credit upper bound for PBF.
624 *.
625 ******************************************************************************/
626 static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf(
627         const struct link_params *params,
628         const u32 min_w_val)
629 {
630         struct bnx2x *bp = params->bp;
631         const u32 credit_upper_bound =
632             bnx2x_ets_get_credit_upper_bound(min_w_val);
633         const u8 port = params->port;
634         u32 base_upper_bound = 0;
635         u8 max_cos = 0;
636         u8 i = 0;
637         /**
638         * In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
639         * port mode port1 has COS0-2 that can be used for WFQ.
640         */
641         if (!port) {
642                 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
643                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
644         } else {
645                 base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
646                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
647         }
648
649         for (i = 0; i < max_cos; i++)
650                 REG_WR(bp, base_upper_bound + (i << 2), credit_upper_bound);
651 }
652
653 /******************************************************************************
654 * Description:
655 *       Will return the PBF ETS registers to init values.Except
656 *       credit_upper_bound.
657 *       That isn't used in this configuration (No WFQ is enabled) and will be
658 *       configured acording to spec
659 *.
660 ******************************************************************************/
661 static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params)
662 {
663         struct bnx2x *bp = params->bp;
664         const u8 port = params->port;
665         const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
666         u8 i = 0;
667         u32 base_weight = 0;
668         u8 max_cos = 0;
669
670         /**
671          * mapping between entry  priority to client number 0 - COS0
672          * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
673          * TODO_ETS - Should be done by reset value or init tool
674          */
675         if (port)
676                 /*  0x688 (|011|0 10|00 1|000) */
677                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688);
678         else
679                 /*  (10 1|100 |011|0 10|00 1|000) */
680                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688);
681
682         /* TODO_ETS - Should be done by reset value or init tool */
683         if (port)
684                 /* 0x688 (|011|0 10|00 1|000)*/
685                 REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
686         else
687         /* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
688         REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
689
690         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
691                    PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100);
692
693
694         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
695                    PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0);
696
697         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
698                    PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
699         /**
700         * In 2 port mode port0 has COS0-5 that can be used for WFQ.
701         * In 4 port mode port1 has COS0-2 that can be used for WFQ.
702         */
703         if (!port) {
704                 base_weight = PBF_REG_COS0_WEIGHT_P0;
705                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
706         } else {
707                 base_weight = PBF_REG_COS0_WEIGHT_P1;
708                 max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
709         }
710
711         for (i = 0; i < max_cos; i++)
712                 REG_WR(bp, base_weight + (0x4 * i), 0);
713
714         bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
715 }
716 /******************************************************************************
717 * Description:
718 *       E3B0 disable will return basicly the values to init values.
719 *.
720 ******************************************************************************/
721 static int bnx2x_ets_e3b0_disabled(const struct link_params *params,
722                                    const struct link_vars *vars)
723 {
724         struct bnx2x *bp = params->bp;
725
726         if (!CHIP_IS_E3B0(bp)) {
727                 DP(NETIF_MSG_LINK,
728                    "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
729                 return -EINVAL;
730         }
731
732         bnx2x_ets_e3b0_nig_disabled(params, vars);
733
734         bnx2x_ets_e3b0_pbf_disabled(params);
735
736         return 0;
737 }
738
739 /******************************************************************************
740 * Description:
741 *       Disable will return basicly the values to init values.
742 *.
743 ******************************************************************************/
744 int bnx2x_ets_disabled(struct link_params *params,
745                       struct link_vars *vars)
746 {
747         struct bnx2x *bp = params->bp;
748         int bnx2x_status = 0;
749
750         if ((CHIP_IS_E2(bp)) || (CHIP_IS_E3A0(bp)))
751                 bnx2x_ets_e2e3a0_disabled(params);
752         else if (CHIP_IS_E3B0(bp))
753                 bnx2x_status = bnx2x_ets_e3b0_disabled(params, vars);
754         else {
755                 DP(NETIF_MSG_LINK, "bnx2x_ets_disabled - chip not supported\n");
756                 return -EINVAL;
757         }
758
759         return bnx2x_status;
760 }
761
762 /******************************************************************************
763 * Description
764 *       Set the COS mappimg to SP and BW until this point all the COS are not
765 *       set as SP or BW.
766 ******************************************************************************/
767 static int bnx2x_ets_e3b0_cli_map(const struct link_params *params,
768                                   const struct bnx2x_ets_params *ets_params,
769                                   const u8 cos_sp_bitmap,
770                                   const u8 cos_bw_bitmap)
771 {
772         struct bnx2x *bp = params->bp;
773         const u8 port = params->port;
774         const u8 nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
775         const u8 pbf_cli_sp_bitmap = cos_sp_bitmap;
776         const u8 nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
777         const u8 pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
778
779         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
780                NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
781
782         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
783                PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap);
784
785         REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
786                NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
787                nig_cli_subject2wfq_bitmap);
788
789         REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
790                PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
791                pbf_cli_subject2wfq_bitmap);
792
793         return 0;
794 }
795
796 /******************************************************************************
797 * Description:
798 *       This function is needed because NIG ARB_CREDIT_WEIGHT_X are
799 *       not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
800 ******************************************************************************/
801 static int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x *bp,
802                                      const u8 cos_entry,
803                                      const u32 min_w_val_nig,
804                                      const u32 min_w_val_pbf,
805                                      const u16 total_bw,
806                                      const u8 bw,
807                                      const u8 port)
808 {
809         u32 nig_reg_adress_crd_weight = 0;
810         u32 pbf_reg_adress_crd_weight = 0;
811         /* Calculate and set BW for this COS - use 1 instead of 0 for BW */
812         const u32 cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
813         const u32 cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
814
815         switch (cos_entry) {
816         case 0:
817             nig_reg_adress_crd_weight =
818                  (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
819                      NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
820              pbf_reg_adress_crd_weight = (port) ?
821                  PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
822              break;
823         case 1:
824              nig_reg_adress_crd_weight = (port) ?
825                  NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
826                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
827              pbf_reg_adress_crd_weight = (port) ?
828                  PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
829              break;
830         case 2:
831              nig_reg_adress_crd_weight = (port) ?
832                  NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
833                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
834
835                  pbf_reg_adress_crd_weight = (port) ?
836                      PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
837              break;
838         case 3:
839             if (port)
840                         return -EINVAL;
841              nig_reg_adress_crd_weight =
842                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
843              pbf_reg_adress_crd_weight =
844                  PBF_REG_COS3_WEIGHT_P0;
845              break;
846         case 4:
847             if (port)
848                 return -EINVAL;
849              nig_reg_adress_crd_weight =
850                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
851              pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0;
852              break;
853         case 5:
854             if (port)
855                 return -EINVAL;
856              nig_reg_adress_crd_weight =
857                  NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
858              pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0;
859              break;
860         }
861
862         REG_WR(bp, nig_reg_adress_crd_weight, cos_bw_nig);
863
864         REG_WR(bp, pbf_reg_adress_crd_weight, cos_bw_pbf);
865
866         return 0;
867 }
868 /******************************************************************************
869 * Description:
870 *       Calculate the total BW.A value of 0 isn't legal.
871 *.
872 ******************************************************************************/
873 static int bnx2x_ets_e3b0_get_total_bw(
874         const struct link_params *params,
875         struct bnx2x_ets_params *ets_params,
876         u16 *total_bw)
877 {
878         struct bnx2x *bp = params->bp;
879         u8 cos_idx = 0;
880         u8 is_bw_cos_exist = 0;
881
882         *total_bw = 0 ;
883
884         /* Calculate total BW requested */
885         for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
886                 if (ets_params->cos[cos_idx].state == bnx2x_cos_state_bw) {
887                         is_bw_cos_exist = 1;
888                         if (!ets_params->cos[cos_idx].params.bw_params.bw) {
889                                 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW"
890                                                    "was set to 0\n");
891                                 /*
892                                  * This is to prevent a state when ramrods
893                                  * can't be sent
894                                 */
895                                 ets_params->cos[cos_idx].params.bw_params.bw
896                                          = 1;
897                         }
898                         *total_bw +=
899                                 ets_params->cos[cos_idx].params.bw_params.bw;
900                 }
901         }
902
903         /* Check total BW is valid */
904         if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
905                 if (*total_bw == 0) {
906                         DP(NETIF_MSG_LINK,
907                            "bnx2x_ets_E3B0_config total BW shouldn't be 0\n");
908                         return -EINVAL;
909                 }
910                 DP(NETIF_MSG_LINK,
911                    "bnx2x_ets_E3B0_config total BW should be 100\n");
912                 /*
913                  * We can handle a case whre the BW isn't 100 this can happen
914                  * if the TC are joined.
915                  */
916         }
917         return 0;
918 }
919
920 /******************************************************************************
921 * Description:
922 *       Invalidate all the sp_pri_to_cos.
923 *.
924 ******************************************************************************/
925 static void bnx2x_ets_e3b0_sp_pri_to_cos_init(u8 *sp_pri_to_cos)
926 {
927         u8 pri = 0;
928         for (pri = 0; pri < DCBX_MAX_NUM_COS; pri++)
929                 sp_pri_to_cos[pri] = DCBX_INVALID_COS;
930 }
931 /******************************************************************************
932 * Description:
933 *       Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
934 *       according to sp_pri_to_cos.
935 *.
936 ******************************************************************************/
937 static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
938                                             u8 *sp_pri_to_cos, const u8 pri,
939                                             const u8 cos_entry)
940 {
941         struct bnx2x *bp = params->bp;
942         const u8 port = params->port;
943         const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
944                 DCBX_E3B0_MAX_NUM_COS_PORT0;
945
946         if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
947                 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
948                                    "parameter There can't be two COS's with "
949                                    "the same strict pri\n");
950                 return -EINVAL;
951         }
952
953         if (pri > max_num_of_cos) {
954                 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
955                    "parameter Illegal strict priority\n");
956             return -EINVAL;
957         }
958
959         sp_pri_to_cos[pri] = cos_entry;
960         return 0;
961
962 }
963
964 /******************************************************************************
965 * Description:
966 *       Returns the correct value according to COS and priority in
967 *       the sp_pri_cli register.
968 *.
969 ******************************************************************************/
970 static u64 bnx2x_e3b0_sp_get_pri_cli_reg(const u8 cos, const u8 cos_offset,
971                                          const u8 pri_set,
972                                          const u8 pri_offset,
973                                          const u8 entry_size)
974 {
975         u64 pri_cli_nig = 0;
976         pri_cli_nig = ((u64)(cos + cos_offset)) << (entry_size *
977                                                     (pri_set + pri_offset));
978
979         return pri_cli_nig;
980 }
981 /******************************************************************************
982 * Description:
983 *       Returns the correct value according to COS and priority in the
984 *       sp_pri_cli register for NIG.
985 *.
986 ******************************************************************************/
987 static u64 bnx2x_e3b0_sp_get_pri_cli_reg_nig(const u8 cos, const u8 pri_set)
988 {
989         /* MCP Dbg0 and dbg1 are always with higher strict pri*/
990         const u8 nig_cos_offset = 3;
991         const u8 nig_pri_offset = 3;
992
993         return bnx2x_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
994                 nig_pri_offset, 4);
995
996 }
997 /******************************************************************************
998 * Description:
999 *       Returns the correct value according to COS and priority in the
1000 *       sp_pri_cli register for PBF.
1001 *.
1002 ******************************************************************************/
1003 static u64 bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos, const u8 pri_set)
1004 {
1005         const u8 pbf_cos_offset = 0;
1006         const u8 pbf_pri_offset = 0;
1007
1008         return bnx2x_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
1009                 pbf_pri_offset, 3);
1010
1011 }
1012
1013 /******************************************************************************
1014 * Description:
1015 *       Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1016 *       according to sp_pri_to_cos.(which COS has higher priority)
1017 *.
1018 ******************************************************************************/
1019 static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params *params,
1020                                              u8 *sp_pri_to_cos)
1021 {
1022         struct bnx2x *bp = params->bp;
1023         u8 i = 0;
1024         const u8 port = params->port;
1025         /* MCP Dbg0 and dbg1 are always with higher strict pri*/
1026         u64 pri_cli_nig = 0x210;
1027         u32 pri_cli_pbf = 0x0;
1028         u8 pri_set = 0;
1029         u8 pri_bitmask = 0;
1030         const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
1031                 DCBX_E3B0_MAX_NUM_COS_PORT0;
1032
1033         u8 cos_bit_to_set = (1 << max_num_of_cos) - 1;
1034
1035         /* Set all the strict priority first */
1036         for (i = 0; i < max_num_of_cos; i++) {
1037                 if (sp_pri_to_cos[i] != DCBX_INVALID_COS) {
1038                         if (sp_pri_to_cos[i] >= DCBX_MAX_NUM_COS) {
1039                                 DP(NETIF_MSG_LINK,
1040                                            "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1041                                            "invalid cos entry\n");
1042                                 return -EINVAL;
1043                         }
1044
1045                         pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1046                             sp_pri_to_cos[i], pri_set);
1047
1048                         pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1049                             sp_pri_to_cos[i], pri_set);
1050                         pri_bitmask = 1 << sp_pri_to_cos[i];
1051                         /* COS is used remove it from bitmap.*/
1052                         if (!(pri_bitmask & cos_bit_to_set)) {
1053                                 DP(NETIF_MSG_LINK,
1054                                         "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1055                                         "invalid There can't be two COS's with"
1056                                         " the same strict pri\n");
1057                                 return -EINVAL;
1058                         }
1059                         cos_bit_to_set &= ~pri_bitmask;
1060                         pri_set++;
1061                 }
1062         }
1063
1064         /* Set all the Non strict priority i= COS*/
1065         for (i = 0; i < max_num_of_cos; i++) {
1066                 pri_bitmask = 1 << i;
1067                 /* Check if COS was already used for SP */
1068                 if (pri_bitmask & cos_bit_to_set) {
1069                         /* COS wasn't used for SP */
1070                         pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1071                             i, pri_set);
1072
1073                         pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1074                             i, pri_set);
1075                         /* COS is used remove it from bitmap.*/
1076                         cos_bit_to_set &= ~pri_bitmask;
1077                         pri_set++;
1078                 }
1079         }
1080
1081         if (pri_set != max_num_of_cos) {
1082                 DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_set_pri_cli_reg not all "
1083                                    "entries were set\n");
1084                 return -EINVAL;
1085         }
1086
1087         if (port) {
1088                 /* Only 6 usable clients*/
1089                 REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1090                        (u32)pri_cli_nig);
1091
1092                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf);
1093         } else {
1094                 /* Only 9 usable clients*/
1095                 const u32 pri_cli_nig_lsb = (u32) (pri_cli_nig);
1096                 const u32 pri_cli_nig_msb = (u32) ((pri_cli_nig >> 32) & 0xF);
1097
1098                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1099                        pri_cli_nig_lsb);
1100                 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1101                        pri_cli_nig_msb);
1102
1103                 REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf);
1104         }
1105         return 0;
1106 }
1107
1108 /******************************************************************************
1109 * Description:
1110 *       Configure the COS to ETS according to BW and SP settings.
1111 ******************************************************************************/
1112 int bnx2x_ets_e3b0_config(const struct link_params *params,
1113                          const struct link_vars *vars,
1114                          struct bnx2x_ets_params *ets_params)
1115 {
1116         struct bnx2x *bp = params->bp;
1117         int bnx2x_status = 0;
1118         const u8 port = params->port;
1119         u16 total_bw = 0;
1120         const u32 min_w_val_nig = bnx2x_ets_get_min_w_val_nig(vars);
1121         const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
1122         u8 cos_bw_bitmap = 0;
1123         u8 cos_sp_bitmap = 0;
1124         u8 sp_pri_to_cos[DCBX_MAX_NUM_COS] = {0};
1125         const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
1126                 DCBX_E3B0_MAX_NUM_COS_PORT0;
1127         u8 cos_entry = 0;
1128
1129         if (!CHIP_IS_E3B0(bp)) {
1130                 DP(NETIF_MSG_LINK,
1131                    "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
1132                 return -EINVAL;
1133         }
1134
1135         if ((ets_params->num_of_cos > max_num_of_cos)) {
1136                 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config the number of COS "
1137                                    "isn't supported\n");
1138                 return -EINVAL;
1139         }
1140
1141         /* Prepare sp strict priority parameters*/
1142         bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1143
1144         /* Prepare BW parameters*/
1145         bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params,
1146                                                    &total_bw);
1147         if (bnx2x_status) {
1148                 DP(NETIF_MSG_LINK,
1149                    "bnx2x_ets_E3B0_config get_total_bw failed\n");
1150                 return -EINVAL;
1151         }
1152
1153         /*
1154          * Upper bound is set according to current link speed (min_w_val
1155          * should be the same for upper bound and COS credit val).
1156          */
1157         bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1158         bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1159
1160
1161         for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1162                 if (bnx2x_cos_state_bw == ets_params->cos[cos_entry].state) {
1163                         cos_bw_bitmap |= (1 << cos_entry);
1164                         /*
1165                          * The function also sets the BW in HW(not the mappin
1166                          * yet)
1167                          */
1168                         bnx2x_status = bnx2x_ets_e3b0_set_cos_bw(
1169                                 bp, cos_entry, min_w_val_nig, min_w_val_pbf,
1170                                 total_bw,
1171                                 ets_params->cos[cos_entry].params.bw_params.bw,
1172                                  port);
1173                 } else if (bnx2x_cos_state_strict ==
1174                         ets_params->cos[cos_entry].state){
1175                         cos_sp_bitmap |= (1 << cos_entry);
1176
1177                         bnx2x_status = bnx2x_ets_e3b0_sp_pri_to_cos_set(
1178                                 params,
1179                                 sp_pri_to_cos,
1180                                 ets_params->cos[cos_entry].params.sp_params.pri,
1181                                 cos_entry);
1182
1183                 } else {
1184                         DP(NETIF_MSG_LINK,
1185                            "bnx2x_ets_e3b0_config cos state not valid\n");
1186                         return -EINVAL;
1187                 }
1188                 if (bnx2x_status) {
1189                         DP(NETIF_MSG_LINK,
1190                            "bnx2x_ets_e3b0_config set cos bw failed\n");
1191                         return bnx2x_status;
1192                 }
1193         }
1194
1195         /* Set SP register (which COS has higher priority) */
1196         bnx2x_status = bnx2x_ets_e3b0_sp_set_pri_cli_reg(params,
1197                                                          sp_pri_to_cos);
1198
1199         if (bnx2x_status) {
1200                 DP(NETIF_MSG_LINK,
1201                    "bnx2x_ets_E3B0_config set_pri_cli_reg failed\n");
1202                 return bnx2x_status;
1203         }
1204
1205         /* Set client mapping of BW and strict */
1206         bnx2x_status = bnx2x_ets_e3b0_cli_map(params, ets_params,
1207                                               cos_sp_bitmap,
1208                                               cos_bw_bitmap);
1209
1210         if (bnx2x_status) {
1211                 DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config SP failed\n");
1212                 return bnx2x_status;
1213         }
1214         return 0;
1215 }
1216 static void bnx2x_ets_bw_limit_common(const struct link_params *params)
1217 {
1218         /* ETS disabled configuration */
1219         struct bnx2x *bp = params->bp;
1220         DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1221         /*
1222          * defines which entries (clients) are subjected to WFQ arbitration
1223          * COS0 0x8
1224          * COS1 0x10
1225          */
1226         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1227         /*
1228          * mapping between the ARB_CREDIT_WEIGHT registers and actual
1229          * client numbers (WEIGHT_0 does not actually have to represent
1230          * client 0)
1231          *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1232          *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
1233          */
1234         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1235
1236         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1237                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1238         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1239                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1240
1241         /* ETS mode enabled*/
1242         REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
1243
1244         /* Defines the number of consecutive slots for the strict priority */
1245         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1246         /*
1247          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1248          * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
1249          * entry, 4 - COS1 entry.
1250          * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1251          * bit4   bit3    bit2     bit1    bit0
1252          * MCP and debug are strict
1253          */
1254         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1255
1256         /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
1257         REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
1258                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1259         REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
1260                ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1261 }
1262
1263 void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
1264                         const u32 cos1_bw)
1265 {
1266         /* ETS disabled configuration*/
1267         struct bnx2x *bp = params->bp;
1268         const u32 total_bw = cos0_bw + cos1_bw;
1269         u32 cos0_credit_weight = 0;
1270         u32 cos1_credit_weight = 0;
1271
1272         DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1273
1274         if ((!total_bw) ||
1275             (!cos0_bw) ||
1276             (!cos1_bw)) {
1277                 DP(NETIF_MSG_LINK, "Total BW can't be zero\n");
1278                 return;
1279         }
1280
1281         cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1282                 total_bw;
1283         cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1284                 total_bw;
1285
1286         bnx2x_ets_bw_limit_common(params);
1287
1288         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
1289         REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
1290
1291         REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
1292         REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
1293 }
1294
1295 int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
1296 {
1297         /* ETS disabled configuration*/
1298         struct bnx2x *bp = params->bp;
1299         u32 val = 0;
1300
1301         DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
1302         /*
1303          * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1304          * as strict.  Bits 0,1,2 - debug and management entries,
1305          * 3 - COS0 entry, 4 - COS1 entry.
1306          *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1307          *  bit4   bit3   bit2      bit1     bit0
1308          * MCP and debug are strict
1309          */
1310         REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
1311         /*
1312          * For strict priority entries defines the number of consecutive slots
1313          * for the highest priority.
1314          */
1315         REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1316         /* ETS mode disable */
1317         REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
1318         /* Defines the number of consecutive slots for the strict priority */
1319         REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
1320
1321         /* Defines the number of consecutive slots for the strict priority */
1322         REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
1323
1324         /*
1325          * mapping between entry  priority to client number (0,1,2 -debug and
1326          * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1327          * 3bits client num.
1328          *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1329          * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
1330          * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
1331          */
1332         val = (!strict_cos) ? 0x2318 : 0x22E0;
1333         REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
1334
1335         return 0;
1336 }
1337 /******************************************************************/
1338 /*                      PFC section                               */
1339 /******************************************************************/
1340 static void bnx2x_update_pfc_xmac(struct link_params *params,
1341                                   struct link_vars *vars,
1342                                   u8 is_lb)
1343 {
1344         struct bnx2x *bp = params->bp;
1345         u32 xmac_base;
1346         u32 pause_val, pfc0_val, pfc1_val;
1347
1348         /* XMAC base adrr */
1349         xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1350
1351         /* Initialize pause and pfc registers */
1352         pause_val = 0x18000;
1353         pfc0_val = 0xFFFF8000;
1354         pfc1_val = 0x2;
1355
1356         /* No PFC support */
1357         if (!(params->feature_config_flags &
1358               FEATURE_CONFIG_PFC_ENABLED)) {
1359
1360                 /*
1361                  * RX flow control - Process pause frame in receive direction
1362                  */
1363                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1364                         pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
1365
1366                 /*
1367                  * TX flow control - Send pause packet when buffer is full
1368                  */
1369                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1370                         pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
1371         } else {/* PFC support */
1372                 pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
1373                         XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
1374                         XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
1375                         XMAC_PFC_CTRL_HI_REG_TX_PFC_EN;
1376         }
1377
1378         /* Write pause and PFC registers */
1379         REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1380         REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1381         REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1382
1383
1384         /* Set MAC address for source TX Pause/PFC frames */
1385         REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_LO,
1386                ((params->mac_addr[2] << 24) |
1387                 (params->mac_addr[3] << 16) |
1388                 (params->mac_addr[4] << 8) |
1389                 (params->mac_addr[5])));
1390         REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_HI,
1391                ((params->mac_addr[0] << 8) |
1392                 (params->mac_addr[1])));
1393
1394         udelay(30);
1395 }
1396
1397
1398 static void bnx2x_emac_get_pfc_stat(struct link_params *params,
1399                                     u32 pfc_frames_sent[2],
1400                                     u32 pfc_frames_received[2])
1401 {
1402         /* Read pfc statistic */
1403         struct bnx2x *bp = params->bp;
1404         u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1405         u32 val_xon = 0;
1406         u32 val_xoff = 0;
1407
1408         DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
1409
1410         /* PFC received frames */
1411         val_xoff = REG_RD(bp, emac_base +
1412                                 EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
1413         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
1414         val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
1415         val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
1416
1417         pfc_frames_received[0] = val_xon + val_xoff;
1418
1419         /* PFC received sent */
1420         val_xoff = REG_RD(bp, emac_base +
1421                                 EMAC_REG_RX_PFC_STATS_XOFF_SENT);
1422         val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
1423         val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
1424         val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
1425
1426         pfc_frames_sent[0] = val_xon + val_xoff;
1427 }
1428
1429 /* Read pfc statistic*/
1430 void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
1431                          u32 pfc_frames_sent[2],
1432                          u32 pfc_frames_received[2])
1433 {
1434         /* Read pfc statistic */
1435         struct bnx2x *bp = params->bp;
1436
1437         DP(NETIF_MSG_LINK, "pfc statistic\n");
1438
1439         if (!vars->link_up)
1440                 return;
1441
1442         if (vars->mac_type == MAC_TYPE_EMAC) {
1443                 DP(NETIF_MSG_LINK, "About to read PFC stats from EMAC\n");
1444                 bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
1445                                         pfc_frames_received);
1446         }
1447 }
1448 /******************************************************************/
1449 /*                      MAC/PBF section                           */
1450 /******************************************************************/
1451 static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port)
1452 {
1453         u32 mode, emac_base;
1454         /**
1455          * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1456          * (a value of 49==0x31) and make sure that the AUTO poll is off
1457          */
1458
1459         if (CHIP_IS_E2(bp))
1460                 emac_base = GRCBASE_EMAC0;
1461         else
1462                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1463         mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1464         mode &= ~(EMAC_MDIO_MODE_AUTO_POLL |
1465                   EMAC_MDIO_MODE_CLOCK_CNT);
1466         if (USES_WARPCORE(bp))
1467                 mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
1468         else
1469                 mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
1470
1471         mode |= (EMAC_MDIO_MODE_CLAUSE_45);
1472         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode);
1473
1474         udelay(40);
1475 }
1476 static u8 bnx2x_is_4_port_mode(struct bnx2x *bp)
1477 {
1478         u32 port4mode_ovwr_val;
1479         /* Check 4-port override enabled */
1480         port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR);
1481         if (port4mode_ovwr_val & (1<<0)) {
1482                 /* Return 4-port mode override value */
1483                 return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
1484         }
1485         /* Return 4-port mode from input pin */
1486         return (u8)REG_RD(bp, MISC_REG_PORT4MODE_EN);
1487 }
1488
1489 static void bnx2x_emac_init(struct link_params *params,
1490                             struct link_vars *vars)
1491 {
1492         /* reset and unreset the emac core */
1493         struct bnx2x *bp = params->bp;
1494         u8 port = params->port;
1495         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1496         u32 val;
1497         u16 timeout;
1498
1499         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1500                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1501         udelay(5);
1502         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1503                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1504
1505         /* init emac - use read-modify-write */
1506         /* self clear reset */
1507         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1508         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
1509
1510         timeout = 200;
1511         do {
1512                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1513                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
1514                 if (!timeout) {
1515                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
1516                         return;
1517                 }
1518                 timeout--;
1519         } while (val & EMAC_MODE_RESET);
1520         bnx2x_set_mdio_clk(bp, params->chip_id, port);
1521         /* Set mac address */
1522         val = ((params->mac_addr[0] << 8) |
1523                 params->mac_addr[1]);
1524         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
1525
1526         val = ((params->mac_addr[2] << 24) |
1527                (params->mac_addr[3] << 16) |
1528                (params->mac_addr[4] << 8) |
1529                 params->mac_addr[5]);
1530         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
1531 }
1532
1533 static void bnx2x_set_xumac_nig(struct link_params *params,
1534                                 u16 tx_pause_en,
1535                                 u8 enable)
1536 {
1537         struct bnx2x *bp = params->bp;
1538
1539         REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
1540                enable);
1541         REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
1542                enable);
1543         REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
1544                NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
1545 }
1546
1547 static void bnx2x_umac_disable(struct link_params *params)
1548 {
1549         u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1550         struct bnx2x *bp = params->bp;
1551         if (!(REG_RD(bp, MISC_REG_RESET_REG_2) &
1552                    (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
1553                 return;
1554
1555         /* Disable RX and TX */
1556         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, 0);
1557 }
1558
1559 static void bnx2x_umac_enable(struct link_params *params,
1560                             struct link_vars *vars, u8 lb)
1561 {
1562         u32 val;
1563         u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1564         struct bnx2x *bp = params->bp;
1565         /* Reset UMAC */
1566         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1567                (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1568         usleep_range(1000, 1000);
1569
1570         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1571                (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1572
1573         DP(NETIF_MSG_LINK, "enabling UMAC\n");
1574
1575         /**
1576          * This register determines on which events the MAC will assert
1577          * error on the i/f to the NIG along w/ EOP.
1578          */
1579
1580         /**
1581          * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK +
1582          * params->port*0x14,      0xfffff.
1583          */
1584         /* This register opens the gate for the UMAC despite its name */
1585         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
1586
1587         val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
1588                 UMAC_COMMAND_CONFIG_REG_PAD_EN |
1589                 UMAC_COMMAND_CONFIG_REG_SW_RESET |
1590                 UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
1591         switch (vars->line_speed) {
1592         case SPEED_10:
1593                 val |= (0<<2);
1594                 break;
1595         case SPEED_100:
1596                 val |= (1<<2);
1597                 break;
1598         case SPEED_1000:
1599                 val |= (2<<2);
1600                 break;
1601         case SPEED_2500:
1602                 val |= (3<<2);
1603                 break;
1604         default:
1605                 DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n",
1606                                vars->line_speed);
1607                 break;
1608         }
1609         if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1610                 val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
1611
1612         if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1613                 val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
1614
1615         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1616         udelay(50);
1617
1618         /* Set MAC address for source TX Pause/PFC frames (under SW reset) */
1619         REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0,
1620                ((params->mac_addr[2] << 24) |
1621                 (params->mac_addr[3] << 16) |
1622                 (params->mac_addr[4] << 8) |
1623                 (params->mac_addr[5])));
1624         REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR1,
1625                ((params->mac_addr[0] << 8) |
1626                 (params->mac_addr[1])));
1627
1628         /* Enable RX and TX */
1629         val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
1630         val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
1631                 UMAC_COMMAND_CONFIG_REG_RX_ENA;
1632         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1633         udelay(50);
1634
1635         /* Remove SW Reset */
1636         val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
1637
1638         /* Check loopback mode */
1639         if (lb)
1640                 val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
1641         REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1642
1643         /*
1644          * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
1645          * length used by the MAC receive logic to check frames.
1646          */
1647         REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
1648         bnx2x_set_xumac_nig(params,
1649                             ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1650         vars->mac_type = MAC_TYPE_UMAC;
1651
1652 }
1653
1654 /* Define the XMAC mode */
1655 static void bnx2x_xmac_init(struct link_params *params, u32 max_speed)
1656 {
1657         struct bnx2x *bp = params->bp;
1658         u32 is_port4mode = bnx2x_is_4_port_mode(bp);
1659
1660         /*
1661          * In 4-port mode, need to set the mode only once, so if XMAC is
1662          * already out of reset, it means the mode has already been set,
1663          * and it must not* reset the XMAC again, since it controls both
1664          * ports of the path
1665          */
1666
1667         if ((CHIP_NUM(bp) == CHIP_NUM_57840) &&
1668             (REG_RD(bp, MISC_REG_RESET_REG_2) &
1669              MISC_REGISTERS_RESET_REG_2_XMAC)) {
1670                 DP(NETIF_MSG_LINK,
1671                    "XMAC already out of reset in 4-port mode\n");
1672                 return;
1673         }
1674
1675         /* Hard reset */
1676         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1677                MISC_REGISTERS_RESET_REG_2_XMAC);
1678         usleep_range(1000, 1000);
1679
1680         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1681                MISC_REGISTERS_RESET_REG_2_XMAC);
1682         if (is_port4mode) {
1683                 DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n");
1684
1685                 /*  Set the number of ports on the system side to up to 2 */
1686                 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1);
1687
1688                 /* Set the number of ports on the Warp Core to 10G */
1689                 REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1690         } else {
1691                 /*  Set the number of ports on the system side to 1 */
1692                 REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
1693                 if (max_speed == SPEED_10000) {
1694                         DP(NETIF_MSG_LINK,
1695                            "Init XMAC to 10G x 1 port per path\n");
1696                         /* Set the number of ports on the Warp Core to 10G */
1697                         REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1698                 } else {
1699                         DP(NETIF_MSG_LINK,
1700                            "Init XMAC to 20G x 2 ports per path\n");
1701                         /* Set the number of ports on the Warp Core to 20G */
1702                         REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1);
1703                 }
1704         }
1705         /* Soft reset */
1706         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1707                MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1708         usleep_range(1000, 1000);
1709
1710         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1711                MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1712
1713 }
1714
1715 static void bnx2x_xmac_disable(struct link_params *params)
1716 {
1717         u8 port = params->port;
1718         struct bnx2x *bp = params->bp;
1719         u32 pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1720
1721         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1722             MISC_REGISTERS_RESET_REG_2_XMAC) {
1723                 /*
1724                  * Send an indication to change the state in the NIG back to XON
1725                  * Clearing this bit enables the next set of this bit to get
1726                  * rising edge
1727                  */
1728                 pfc_ctrl = REG_RD(bp, xmac_base + XMAC_REG_PFC_CTRL_HI);
1729                 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1730                        (pfc_ctrl & ~(1<<1)));
1731                 REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1732                        (pfc_ctrl | (1<<1)));
1733                 DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
1734                 REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);
1735         }
1736 }
1737
1738 static int bnx2x_xmac_enable(struct link_params *params,
1739                              struct link_vars *vars, u8 lb)
1740 {
1741         u32 val, xmac_base;
1742         struct bnx2x *bp = params->bp;
1743         DP(NETIF_MSG_LINK, "enabling XMAC\n");
1744
1745         xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1746
1747         bnx2x_xmac_init(params, vars->line_speed);
1748
1749         /*
1750          * This register determines on which events the MAC will assert
1751          * error on the i/f to the NIG along w/ EOP.
1752          */
1753
1754         /*
1755          * This register tells the NIG whether to send traffic to UMAC
1756          * or XMAC
1757          */
1758         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
1759
1760         /* Set Max packet size */
1761         REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
1762
1763         /* CRC append for Tx packets */
1764         REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
1765
1766         /* update PFC */
1767         bnx2x_update_pfc_xmac(params, vars, 0);
1768
1769         /* Enable TX and RX */
1770         val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
1771
1772         /* Check loopback mode */
1773         if (lb)
1774                 val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
1775         REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
1776         bnx2x_set_xumac_nig(params,
1777                             ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1778
1779         vars->mac_type = MAC_TYPE_XMAC;
1780
1781         return 0;
1782 }
1783
1784 static int bnx2x_emac_enable(struct link_params *params,
1785                              struct link_vars *vars, u8 lb)
1786 {
1787         struct bnx2x *bp = params->bp;
1788         u8 port = params->port;
1789         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1790         u32 val;
1791
1792         DP(NETIF_MSG_LINK, "enabling EMAC\n");
1793
1794         /* Disable BMAC */
1795         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1796                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1797
1798         /* enable emac and not bmac */
1799         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
1800
1801         /* ASIC */
1802         if (vars->phy_flags & PHY_XGXS_FLAG) {
1803                 u32 ser_lane = ((params->lane_config &
1804                                  PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1805                                 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1806
1807                 DP(NETIF_MSG_LINK, "XGXS\n");
1808                 /* select the master lanes (out of 0-3) */
1809                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
1810                 /* select XGXS */
1811                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
1812
1813         } else { /* SerDes */
1814                 DP(NETIF_MSG_LINK, "SerDes\n");
1815                 /* select SerDes */
1816                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
1817         }
1818
1819         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1820                       EMAC_RX_MODE_RESET);
1821         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1822                       EMAC_TX_MODE_RESET);
1823
1824         if (CHIP_REV_IS_SLOW(bp)) {
1825                 /* config GMII mode */
1826                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1827                 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
1828         } else { /* ASIC */
1829                 /* pause enable/disable */
1830                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1831                                EMAC_RX_MODE_FLOW_EN);
1832
1833                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
1834                                (EMAC_TX_MODE_EXT_PAUSE_EN |
1835                                 EMAC_TX_MODE_FLOW_EN));
1836                 if (!(params->feature_config_flags &
1837                       FEATURE_CONFIG_PFC_ENABLED)) {
1838                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1839                                 bnx2x_bits_en(bp, emac_base +
1840                                               EMAC_REG_EMAC_RX_MODE,
1841                                               EMAC_RX_MODE_FLOW_EN);
1842
1843                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1844                                 bnx2x_bits_en(bp, emac_base +
1845                                               EMAC_REG_EMAC_TX_MODE,
1846                                               (EMAC_TX_MODE_EXT_PAUSE_EN |
1847                                                EMAC_TX_MODE_FLOW_EN));
1848                 } else
1849                         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1850                                       EMAC_TX_MODE_FLOW_EN);
1851         }
1852
1853         /* KEEP_VLAN_TAG, promiscuous */
1854         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
1855         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
1856
1857         /*
1858          * Setting this bit causes MAC control frames (except for pause
1859          * frames) to be passed on for processing. This setting has no
1860          * affect on the operation of the pause frames. This bit effects
1861          * all packets regardless of RX Parser packet sorting logic.
1862          * Turn the PFC off to make sure we are in Xon state before
1863          * enabling it.
1864          */
1865         EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
1866         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1867                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1868                 /* Enable PFC again */
1869                 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
1870                         EMAC_REG_RX_PFC_MODE_RX_EN |
1871                         EMAC_REG_RX_PFC_MODE_TX_EN |
1872                         EMAC_REG_RX_PFC_MODE_PRIORITIES);
1873
1874                 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
1875                         ((0x0101 <<
1876                           EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
1877                          (0x00ff <<
1878                           EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
1879                 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
1880         }
1881         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
1882
1883         /* Set Loopback */
1884         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1885         if (lb)
1886                 val |= 0x810;
1887         else
1888                 val &= ~0x810;
1889         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
1890
1891         /* enable emac */
1892         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
1893
1894         /* enable emac for jumbo packets */
1895         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
1896                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
1897                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
1898
1899         /* strip CRC */
1900         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
1901
1902         /* disable the NIG in/out to the bmac */
1903         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
1904         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
1905         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
1906
1907         /* enable the NIG in/out to the emac */
1908         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
1909         val = 0;
1910         if ((params->feature_config_flags &
1911               FEATURE_CONFIG_PFC_ENABLED) ||
1912             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1913                 val = 1;
1914
1915         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
1916         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
1917
1918         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
1919
1920         vars->mac_type = MAC_TYPE_EMAC;
1921         return 0;
1922 }
1923
1924 static void bnx2x_update_pfc_bmac1(struct link_params *params,
1925                                    struct link_vars *vars)
1926 {
1927         u32 wb_data[2];
1928         struct bnx2x *bp = params->bp;
1929         u32 bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1930                 NIG_REG_INGRESS_BMAC0_MEM;
1931
1932         u32 val = 0x14;
1933         if ((!(params->feature_config_flags &
1934               FEATURE_CONFIG_PFC_ENABLED)) &&
1935                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1936                 /* Enable BigMAC to react on received Pause packets */
1937                 val |= (1<<5);
1938         wb_data[0] = val;
1939         wb_data[1] = 0;
1940         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
1941
1942         /* tx control */
1943         val = 0xc0;
1944         if (!(params->feature_config_flags &
1945               FEATURE_CONFIG_PFC_ENABLED) &&
1946                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1947                 val |= 0x800000;
1948         wb_data[0] = val;
1949         wb_data[1] = 0;
1950         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
1951 }
1952
1953 static void bnx2x_update_pfc_bmac2(struct link_params *params,
1954                                    struct link_vars *vars,
1955                                    u8 is_lb)
1956 {
1957         /*
1958          * Set rx control: Strip CRC and enable BigMAC to relay
1959          * control packets to the system as well
1960          */
1961         u32 wb_data[2];
1962         struct bnx2x *bp = params->bp;
1963         u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1964                 NIG_REG_INGRESS_BMAC0_MEM;
1965         u32 val = 0x14;
1966
1967         if ((!(params->feature_config_flags &
1968               FEATURE_CONFIG_PFC_ENABLED)) &&
1969                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1970                 /* Enable BigMAC to react on received Pause packets */
1971                 val |= (1<<5);
1972         wb_data[0] = val;
1973         wb_data[1] = 0;
1974         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
1975         udelay(30);
1976
1977         /* Tx control */
1978         val = 0xc0;
1979         if (!(params->feature_config_flags &
1980                                 FEATURE_CONFIG_PFC_ENABLED) &&
1981             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1982                 val |= 0x800000;
1983         wb_data[0] = val;
1984         wb_data[1] = 0;
1985         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
1986
1987         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1988                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1989                 /* Enable PFC RX & TX & STATS and set 8 COS  */
1990                 wb_data[0] = 0x0;
1991                 wb_data[0] |= (1<<0);  /* RX */
1992                 wb_data[0] |= (1<<1);  /* TX */
1993                 wb_data[0] |= (1<<2);  /* Force initial Xon */
1994                 wb_data[0] |= (1<<3);  /* 8 cos */
1995                 wb_data[0] |= (1<<5);  /* STATS */
1996                 wb_data[1] = 0;
1997                 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
1998                             wb_data, 2);
1999                 /* Clear the force Xon */
2000                 wb_data[0] &= ~(1<<2);
2001         } else {
2002                 DP(NETIF_MSG_LINK, "PFC is disabled\n");
2003                 /* disable PFC RX & TX & STATS and set 8 COS */
2004                 wb_data[0] = 0x8;
2005                 wb_data[1] = 0;
2006         }
2007
2008         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
2009
2010         /*
2011          * Set Time (based unit is 512 bit time) between automatic
2012          * re-sending of PP packets amd enable automatic re-send of
2013          * Per-Priroity Packet as long as pp_gen is asserted and
2014          * pp_disable is low.
2015          */
2016         val = 0x8000;
2017         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2018                 val |= (1<<16); /* enable automatic re-send */
2019
2020         wb_data[0] = val;
2021         wb_data[1] = 0;
2022         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
2023                     wb_data, 2);
2024
2025         /* mac control */
2026         val = 0x3; /* Enable RX and TX */
2027         if (is_lb) {
2028                 val |= 0x4; /* Local loopback */
2029                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2030         }
2031         /* When PFC enabled, Pass pause frames towards the NIG. */
2032         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2033                 val |= ((1<<6)|(1<<5));
2034
2035         wb_data[0] = val;
2036         wb_data[1] = 0;
2037         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2038 }
2039
2040 /* PFC BRB internal port configuration params */
2041 struct bnx2x_pfc_brb_threshold_val {
2042         u32 pause_xoff;
2043         u32 pause_xon;
2044         u32 full_xoff;
2045         u32 full_xon;
2046 };
2047
2048 struct bnx2x_pfc_brb_e3b0_val {
2049         u32 per_class_guaranty_mode;
2050         u32 lb_guarantied_hyst;
2051         u32 full_lb_xoff_th;
2052         u32 full_lb_xon_threshold;
2053         u32 lb_guarantied;
2054         u32 mac_0_class_t_guarantied;
2055         u32 mac_0_class_t_guarantied_hyst;
2056         u32 mac_1_class_t_guarantied;
2057         u32 mac_1_class_t_guarantied_hyst;
2058 };
2059
2060 struct bnx2x_pfc_brb_th_val {
2061         struct bnx2x_pfc_brb_threshold_val pauseable_th;
2062         struct bnx2x_pfc_brb_threshold_val non_pauseable_th;
2063         struct bnx2x_pfc_brb_threshold_val default_class0;
2064         struct bnx2x_pfc_brb_threshold_val default_class1;
2065
2066 };
2067 static int bnx2x_pfc_brb_get_config_params(
2068                                 struct link_params *params,
2069                                 struct bnx2x_pfc_brb_th_val *config_val)
2070 {
2071         struct bnx2x *bp = params->bp;
2072         DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n");
2073
2074         config_val->default_class1.pause_xoff = 0;
2075         config_val->default_class1.pause_xon = 0;
2076         config_val->default_class1.full_xoff = 0;
2077         config_val->default_class1.full_xon = 0;
2078
2079         if (CHIP_IS_E2(bp)) {
2080                 /*  class0 defaults */
2081                 config_val->default_class0.pause_xoff =
2082                         DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR;
2083                 config_val->default_class0.pause_xon =
2084                         DEFAULT0_E2_BRB_MAC_PAUSE_XON_THR;
2085                 config_val->default_class0.full_xoff =
2086                         DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR;
2087                 config_val->default_class0.full_xon =
2088                         DEFAULT0_E2_BRB_MAC_FULL_XON_THR;
2089                 /*  pause able*/
2090                 config_val->pauseable_th.pause_xoff =
2091                         PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2092                 config_val->pauseable_th.pause_xon =
2093                         PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE;
2094                 config_val->pauseable_th.full_xoff =
2095                         PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE;
2096                 config_val->pauseable_th.full_xon =
2097                         PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE;
2098                 /* non pause able*/
2099                 config_val->non_pauseable_th.pause_xoff =
2100                         PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2101                 config_val->non_pauseable_th.pause_xon =
2102                         PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2103                 config_val->non_pauseable_th.full_xoff =
2104                         PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2105                 config_val->non_pauseable_th.full_xon =
2106                         PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2107         } else if (CHIP_IS_E3A0(bp)) {
2108                 /*  class0 defaults */
2109                 config_val->default_class0.pause_xoff =
2110                         DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR;
2111                 config_val->default_class0.pause_xon =
2112                         DEFAULT0_E3A0_BRB_MAC_PAUSE_XON_THR;
2113                 config_val->default_class0.full_xoff =
2114                         DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR;
2115                 config_val->default_class0.full_xon =
2116                         DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR;
2117                 /*  pause able */
2118                 config_val->pauseable_th.pause_xoff =
2119                         PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2120                 config_val->pauseable_th.pause_xon =
2121                         PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE;
2122                 config_val->pauseable_th.full_xoff =
2123                         PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE;
2124                 config_val->pauseable_th.full_xon =
2125                         PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE;
2126                 /* non pause able*/
2127                 config_val->non_pauseable_th.pause_xoff =
2128                         PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2129                 config_val->non_pauseable_th.pause_xon =
2130                         PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2131                 config_val->non_pauseable_th.full_xoff =
2132                         PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2133                 config_val->non_pauseable_th.full_xon =
2134                         PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2135         } else if (CHIP_IS_E3B0(bp)) {
2136                 /*  class0 defaults */
2137                 config_val->default_class0.pause_xoff =
2138                         DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR;
2139                 config_val->default_class0.pause_xon =
2140                     DEFAULT0_E3B0_BRB_MAC_PAUSE_XON_THR;
2141                 config_val->default_class0.full_xoff =
2142                     DEFAULT0_E3B0_BRB_MAC_FULL_XOFF_THR;
2143                 config_val->default_class0.full_xon =
2144                     DEFAULT0_E3B0_BRB_MAC_FULL_XON_THR;
2145
2146                 if (params->phy[INT_PHY].flags &
2147                     FLAGS_4_PORT_MODE) {
2148                         config_val->pauseable_th.pause_xoff =
2149                                 PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2150                         config_val->pauseable_th.pause_xon =
2151                                 PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE;
2152                         config_val->pauseable_th.full_xoff =
2153                                 PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE;
2154                         config_val->pauseable_th.full_xon =
2155                                 PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE;
2156                         /* non pause able*/
2157                         config_val->non_pauseable_th.pause_xoff =
2158                         PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2159                         config_val->non_pauseable_th.pause_xon =
2160                         PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2161                         config_val->non_pauseable_th.full_xoff =
2162                         PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2163                         config_val->non_pauseable_th.full_xon =
2164                         PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2165                 } else {
2166                         config_val->pauseable_th.pause_xoff =
2167                                 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2168                         config_val->pauseable_th.pause_xon =
2169                                 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE;
2170                         config_val->pauseable_th.full_xoff =
2171                                 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE;
2172                         config_val->pauseable_th.full_xon =
2173                                 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE;
2174                         /* non pause able*/
2175                         config_val->non_pauseable_th.pause_xoff =
2176                                 PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2177                         config_val->non_pauseable_th.pause_xon =
2178                                 PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2179                         config_val->non_pauseable_th.full_xoff =
2180                                 PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2181                         config_val->non_pauseable_th.full_xon =
2182                                 PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2183                 }
2184         } else
2185             return -EINVAL;
2186
2187         return 0;
2188 }
2189
2190 static void bnx2x_pfc_brb_get_e3b0_config_params(
2191                 struct link_params *params,
2192                 struct bnx2x_pfc_brb_e3b0_val
2193                 *e3b0_val,
2194                 struct bnx2x_nig_brb_pfc_port_params *pfc_params,
2195                 const u8 pfc_enabled)
2196 {
2197         if (pfc_enabled && pfc_params) {
2198                 e3b0_val->per_class_guaranty_mode = 1;
2199                 e3b0_val->lb_guarantied_hyst = 80;
2200
2201                 if (params->phy[INT_PHY].flags &
2202                     FLAGS_4_PORT_MODE) {
2203                         e3b0_val->full_lb_xoff_th =
2204                                 PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR;
2205                         e3b0_val->full_lb_xon_threshold =
2206                                 PFC_E3B0_4P_BRB_FULL_LB_XON_THR;
2207                         e3b0_val->lb_guarantied =
2208                                 PFC_E3B0_4P_LB_GUART;
2209                         e3b0_val->mac_0_class_t_guarantied =
2210                                 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART;
2211                         e3b0_val->mac_0_class_t_guarantied_hyst =
2212                                 PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST;
2213                         e3b0_val->mac_1_class_t_guarantied =
2214                                 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART;
2215                         e3b0_val->mac_1_class_t_guarantied_hyst =
2216                                 PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST;
2217                 } else {
2218                         e3b0_val->full_lb_xoff_th =
2219                                 PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR;
2220                         e3b0_val->full_lb_xon_threshold =
2221                                 PFC_E3B0_2P_BRB_FULL_LB_XON_THR;
2222                         e3b0_val->mac_0_class_t_guarantied_hyst =
2223                                 PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST;
2224                         e3b0_val->mac_1_class_t_guarantied =
2225                                 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART;
2226                         e3b0_val->mac_1_class_t_guarantied_hyst =
2227                                 PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST;
2228
2229                         if (pfc_params->cos0_pauseable !=
2230                                 pfc_params->cos1_pauseable) {
2231                                 /* nonpauseable= Lossy + pauseable = Lossless*/
2232                                 e3b0_val->lb_guarantied =
2233                                         PFC_E3B0_2P_MIX_PAUSE_LB_GUART;
2234                                 e3b0_val->mac_0_class_t_guarantied =
2235                                PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART;
2236                         } else if (pfc_params->cos0_pauseable) {
2237                                 /* Lossless +Lossless*/
2238                                 e3b0_val->lb_guarantied =
2239                                         PFC_E3B0_2P_PAUSE_LB_GUART;
2240                                 e3b0_val->mac_0_class_t_guarantied =
2241                                    PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART;
2242                         } else {
2243                                 /* Lossy +Lossy*/
2244                                 e3b0_val->lb_guarantied =
2245                                         PFC_E3B0_2P_NON_PAUSE_LB_GUART;
2246                                 e3b0_val->mac_0_class_t_guarantied =
2247                                PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART;
2248                         }
2249                 }
2250         } else {
2251                 e3b0_val->per_class_guaranty_mode = 0;
2252                 e3b0_val->lb_guarantied_hyst = 0;
2253                 e3b0_val->full_lb_xoff_th =
2254                         DEFAULT_E3B0_BRB_FULL_LB_XOFF_THR;
2255                 e3b0_val->full_lb_xon_threshold =
2256                         DEFAULT_E3B0_BRB_FULL_LB_XON_THR;
2257                 e3b0_val->lb_guarantied =
2258                         DEFAULT_E3B0_LB_GUART;
2259                 e3b0_val->mac_0_class_t_guarantied =
2260                         DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART;
2261                 e3b0_val->mac_0_class_t_guarantied_hyst =
2262                         DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART_HYST;
2263                 e3b0_val->mac_1_class_t_guarantied =
2264                         DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART;
2265                 e3b0_val->mac_1_class_t_guarantied_hyst =
2266                         DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART_HYST;
2267         }
2268 }
2269 static int bnx2x_update_pfc_brb(struct link_params *params,
2270                                 struct link_vars *vars,
2271                                 struct bnx2x_nig_brb_pfc_port_params
2272                                 *pfc_params)
2273 {
2274         struct bnx2x *bp = params->bp;
2275         struct bnx2x_pfc_brb_th_val config_val = { {0} };
2276         struct bnx2x_pfc_brb_threshold_val *reg_th_config =
2277                 &config_val.pauseable_th;
2278         struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0};
2279         const int set_pfc = params->feature_config_flags &
2280                 FEATURE_CONFIG_PFC_ENABLED;
2281         const u8 pfc_enabled = (set_pfc && pfc_params);
2282         int bnx2x_status = 0;
2283         u8 port = params->port;
2284
2285         /* default - pause configuration */
2286         reg_th_config = &config_val.pauseable_th;
2287         bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val);
2288         if (bnx2x_status)
2289                 return bnx2x_status;
2290
2291         if (pfc_enabled) {
2292                 /* First COS */
2293                 if (pfc_params->cos0_pauseable)
2294                         reg_th_config = &config_val.pauseable_th;
2295                 else
2296                         reg_th_config = &config_val.non_pauseable_th;
2297         } else
2298                 reg_th_config = &config_val.default_class0;
2299         /*
2300          * The number of free blocks below which the pause signal to class 0
2301          * of MAC #n is asserted. n=0,1
2302          */
2303         REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 :
2304                BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 ,
2305                reg_th_config->pause_xoff);
2306         /*
2307          * The number of free blocks above which the pause signal to class 0
2308          * of MAC #n is de-asserted. n=0,1
2309          */
2310         REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 :
2311                BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon);
2312         /*
2313          * The number of free blocks below which the full signal to class 0
2314          * of MAC #n is asserted. n=0,1
2315          */
2316         REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 :
2317                BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff);
2318         /*
2319          * The number of free blocks above which the full signal to class 0
2320          * of MAC #n is de-asserted. n=0,1
2321          */
2322         REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 :
2323                BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon);
2324
2325         if (pfc_enabled) {
2326                 /* Second COS */
2327                 if (pfc_params->cos1_pauseable)
2328                         reg_th_config = &config_val.pauseable_th;
2329                 else
2330                         reg_th_config = &config_val.non_pauseable_th;
2331         } else
2332                 reg_th_config = &config_val.default_class1;
2333         /*
2334          * The number of free blocks below which the pause signal to
2335          * class 1 of MAC #n is asserted. n=0,1
2336          */
2337         REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 :
2338                BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0,
2339                reg_th_config->pause_xoff);
2340
2341         /*
2342          * The number of free blocks above which the pause signal to
2343          * class 1 of MAC #n is de-asserted. n=0,1
2344          */
2345         REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 :
2346                BRB1_REG_PAUSE_1_XON_THRESHOLD_0,
2347                reg_th_config->pause_xon);
2348         /*
2349          * The number of free blocks below which the full signal to
2350          * class 1 of MAC #n is asserted. n=0,1
2351          */
2352         REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 :
2353                BRB1_REG_FULL_1_XOFF_THRESHOLD_0,
2354                reg_th_config->full_xoff);
2355         /*
2356          * The number of free blocks above which the full signal to
2357          * class 1 of MAC #n is de-asserted. n=0,1
2358          */
2359         REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 :
2360                BRB1_REG_FULL_1_XON_THRESHOLD_0,
2361                reg_th_config->full_xon);
2362
2363         if (CHIP_IS_E3B0(bp)) {
2364                 bnx2x_pfc_brb_get_e3b0_config_params(
2365                         params,
2366                         &e3b0_val,
2367                         pfc_params,
2368                         pfc_enabled);
2369
2370                 REG_WR(bp, BRB1_REG_PER_CLASS_GUARANTY_MODE,
2371                            e3b0_val.per_class_guaranty_mode);
2372
2373                 /*
2374                  * The hysteresis on the guarantied buffer space for the Lb
2375                  * port before signaling XON.
2376                  */
2377                 REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST,
2378                            e3b0_val.lb_guarantied_hyst);
2379
2380                 /*
2381                  * The number of free blocks below which the full signal to the
2382                  * LB port is asserted.
2383                  */
2384                 REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD,
2385                        e3b0_val.full_lb_xoff_th);
2386                 /*
2387                  * The number of free blocks above which the full signal to the
2388                  * LB port is de-asserted.
2389                  */
2390                 REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD,
2391                        e3b0_val.full_lb_xon_threshold);
2392                 /*
2393                  * The number of blocks guarantied for the MAC #n port. n=0,1
2394                  */
2395
2396                 /* The number of blocks guarantied for the LB port.*/
2397                 REG_WR(bp, BRB1_REG_LB_GUARANTIED,
2398                        e3b0_val.lb_guarantied);
2399
2400                 /*
2401                  * The number of blocks guarantied for the MAC #n port.
2402                  */
2403                 REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0,
2404                        2 * e3b0_val.mac_0_class_t_guarantied);
2405                 REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1,
2406                        2 * e3b0_val.mac_1_class_t_guarantied);
2407                 /*
2408                  * The number of blocks guarantied for class #t in MAC0. t=0,1
2409                  */
2410                 REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED,
2411                        e3b0_val.mac_0_class_t_guarantied);
2412                 REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED,
2413                        e3b0_val.mac_0_class_t_guarantied);
2414                 /*
2415                  * The hysteresis on the guarantied buffer space for class in
2416                  * MAC0.  t=0,1
2417                  */
2418                 REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST,
2419                        e3b0_val.mac_0_class_t_guarantied_hyst);
2420                 REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST,
2421                        e3b0_val.mac_0_class_t_guarantied_hyst);
2422
2423                 /*
2424                  * The number of blocks guarantied for class #t in MAC1.t=0,1
2425                  */
2426                 REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED,
2427                        e3b0_val.mac_1_class_t_guarantied);
2428                 REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED,
2429                        e3b0_val.mac_1_class_t_guarantied);
2430                 /*
2431                  * The hysteresis on the guarantied buffer space for class #t
2432                  * in MAC1.  t=0,1
2433                  */
2434                 REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST,
2435                        e3b0_val.mac_1_class_t_guarantied_hyst);
2436                 REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST,
2437                        e3b0_val.mac_1_class_t_guarantied_hyst);
2438         }
2439
2440         return bnx2x_status;
2441 }
2442
2443 /******************************************************************************
2444 * Description:
2445 *  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2446 *  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2447 ******************************************************************************/
2448 int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
2449                                               u8 cos_entry,
2450                                               u32 priority_mask, u8 port)
2451 {
2452         u32 nig_reg_rx_priority_mask_add = 0;
2453
2454         switch (cos_entry) {
2455         case 0:
2456              nig_reg_rx_priority_mask_add = (port) ?
2457                  NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2458                  NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2459              break;
2460         case 1:
2461             nig_reg_rx_priority_mask_add = (port) ?
2462                 NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2463                 NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2464             break;
2465         case 2:
2466             nig_reg_rx_priority_mask_add = (port) ?
2467                 NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2468                 NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2469             break;
2470         case 3:
2471             if (port)
2472                 return -EINVAL;
2473             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2474             break;
2475         case 4:
2476             if (port)
2477                 return -EINVAL;
2478             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2479             break;
2480         case 5:
2481             if (port)
2482                 return -EINVAL;
2483             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2484             break;
2485         }
2486
2487         REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
2488
2489         return 0;
2490 }
2491 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
2492 {
2493         struct bnx2x *bp = params->bp;
2494
2495         REG_WR(bp, params->shmem_base +
2496                offsetof(struct shmem_region,
2497                         port_mb[params->port].link_status), link_status);
2498 }
2499
2500 static void bnx2x_update_pfc_nig(struct link_params *params,
2501                 struct link_vars *vars,
2502                 struct bnx2x_nig_brb_pfc_port_params *nig_params)
2503 {
2504         u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2505         u32 llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2506         u32 pkt_priority_to_cos = 0;
2507         struct bnx2x *bp = params->bp;
2508         u8 port = params->port;
2509
2510         int set_pfc = params->feature_config_flags &
2511                 FEATURE_CONFIG_PFC_ENABLED;
2512         DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
2513
2514         /*
2515          * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2516          * MAC control frames (that are not pause packets)
2517          * will be forwarded to the XCM.
2518          */
2519         xcm_mask = REG_RD(bp, port ? NIG_REG_LLH1_XCM_MASK :
2520                           NIG_REG_LLH0_XCM_MASK);
2521         /*
2522          * nig params will override non PFC params, since it's possible to
2523          * do transition from PFC to SAFC
2524          */
2525         if (set_pfc) {
2526                 pause_enable = 0;
2527                 llfc_out_en = 0;
2528                 llfc_enable = 0;
2529                 if (CHIP_IS_E3(bp))
2530                         ppp_enable = 0;
2531                 else
2532                 ppp_enable = 1;
2533                 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2534                                      NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2535                 xcm_out_en = 0;
2536                 hwpfc_enable = 1;
2537         } else  {
2538                 if (nig_params) {
2539                         llfc_out_en = nig_params->llfc_out_en;
2540                         llfc_enable = nig_params->llfc_enable;
2541                         pause_enable = nig_params->pause_enable;
2542                 } else  /*defaul non PFC mode - PAUSE */
2543                         pause_enable = 1;
2544
2545                 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2546                         NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2547                 xcm_out_en = 1;
2548         }
2549
2550         if (CHIP_IS_E3(bp))
2551                 REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2552                        NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2553         REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
2554                NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2555         REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
2556                NIG_REG_LLFC_ENABLE_0, llfc_enable);
2557         REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
2558                NIG_REG_PAUSE_ENABLE_0, pause_enable);
2559
2560         REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
2561                NIG_REG_PPP_ENABLE_0, ppp_enable);
2562
2563         REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
2564                NIG_REG_LLH0_XCM_MASK, xcm_mask);
2565
2566         REG_WR(bp, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
2567                NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
2568
2569         /* output enable for RX_XCM # IF */
2570         REG_WR(bp, port ? NIG_REG_XCM1_OUT_EN :
2571                NIG_REG_XCM0_OUT_EN, xcm_out_en);
2572
2573         /* HW PFC TX enable */
2574         REG_WR(bp, port ? NIG_REG_P1_HWPFC_ENABLE :
2575                NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
2576
2577         if (nig_params) {
2578                 u8 i = 0;
2579                 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2580
2581                 for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2582                         bnx2x_pfc_nig_rx_priority_mask(bp, i,
2583                 nig_params->rx_cos_priority_mask[i], port);
2584
2585                 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
2586                        NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
2587                        nig_params->llfc_high_priority_classes);
2588
2589                 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
2590                        NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
2591                        nig_params->llfc_low_priority_classes);
2592         }
2593         REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
2594                NIG_REG_P0_PKT_PRIORITY_TO_COS,
2595                pkt_priority_to_cos);
2596 }
2597
2598 int bnx2x_update_pfc(struct link_params *params,
2599                       struct link_vars *vars,
2600                       struct bnx2x_nig_brb_pfc_port_params *pfc_params)
2601 {
2602         /*
2603          * The PFC and pause are orthogonal to one another, meaning when
2604          * PFC is enabled, the pause are disabled, and when PFC is
2605          * disabled, pause are set according to the pause result.
2606          */
2607         u32 val;
2608         struct bnx2x *bp = params->bp;
2609         int bnx2x_status = 0;
2610         u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
2611
2612         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2613                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
2614         else
2615                 vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
2616
2617         bnx2x_update_mng(params, vars->link_status);
2618
2619         /* update NIG params */
2620         bnx2x_update_pfc_nig(params, vars, pfc_params);
2621
2622         /* update BRB params */
2623         bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params);
2624         if (bnx2x_status)
2625                 return bnx2x_status;
2626
2627         if (!vars->link_up)
2628                 return bnx2x_status;
2629
2630         DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
2631         if (CHIP_IS_E3(bp))
2632                 bnx2x_update_pfc_xmac(params, vars, 0);
2633         else {
2634                 val = REG_RD(bp, MISC_REG_RESET_REG_2);
2635                 if ((val &
2636                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
2637                     == 0) {
2638                         DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
2639                         bnx2x_emac_enable(params, vars, 0);
2640                         return bnx2x_status;
2641                 }
2642                 if (CHIP_IS_E2(bp))
2643                         bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
2644                 else
2645                         bnx2x_update_pfc_bmac1(params, vars);
2646
2647                 val = 0;
2648                 if ((params->feature_config_flags &
2649                      FEATURE_CONFIG_PFC_ENABLED) ||
2650                     (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2651                         val = 1;
2652                 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
2653         }
2654         return bnx2x_status;
2655 }
2656
2657
2658 static int bnx2x_bmac1_enable(struct link_params *params,
2659                               struct link_vars *vars,
2660                               u8 is_lb)
2661 {
2662         struct bnx2x *bp = params->bp;
2663         u8 port = params->port;
2664         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2665                                NIG_REG_INGRESS_BMAC0_MEM;
2666         u32 wb_data[2];
2667         u32 val;
2668
2669         DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
2670
2671         /* XGXS control */
2672         wb_data[0] = 0x3c;
2673         wb_data[1] = 0;
2674         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
2675                     wb_data, 2);
2676
2677         /* tx MAC SA */
2678         wb_data[0] = ((params->mac_addr[2] << 24) |
2679                        (params->mac_addr[3] << 16) |
2680                        (params->mac_addr[4] << 8) |
2681                         params->mac_addr[5]);
2682         wb_data[1] = ((params->mac_addr[0] << 8) |
2683                         params->mac_addr[1]);
2684         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
2685
2686         /* mac control */
2687         val = 0x3;
2688         if (is_lb) {
2689                 val |= 0x4;
2690                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2691         }
2692         wb_data[0] = val;
2693         wb_data[1] = 0;
2694         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
2695
2696         /* set rx mtu */
2697         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2698         wb_data[1] = 0;
2699         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
2700
2701         bnx2x_update_pfc_bmac1(params, vars);
2702
2703         /* set tx mtu */
2704         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2705         wb_data[1] = 0;
2706         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
2707
2708         /* set cnt max size */
2709         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2710         wb_data[1] = 0;
2711         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2712
2713         /* configure safc */
2714         wb_data[0] = 0x1000200;
2715         wb_data[1] = 0;
2716         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2717                     wb_data, 2);
2718
2719         return 0;
2720 }
2721
2722 static int bnx2x_bmac2_enable(struct link_params *params,
2723                               struct link_vars *vars,
2724                               u8 is_lb)
2725 {
2726         struct bnx2x *bp = params->bp;
2727         u8 port = params->port;
2728         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2729                                NIG_REG_INGRESS_BMAC0_MEM;
2730         u32 wb_data[2];
2731
2732         DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
2733
2734         wb_data[0] = 0;
2735         wb_data[1] = 0;
2736         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2737         udelay(30);
2738
2739         /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2740         wb_data[0] = 0x3c;
2741         wb_data[1] = 0;
2742         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
2743                     wb_data, 2);
2744
2745         udelay(30);
2746
2747         /* tx MAC SA */
2748         wb_data[0] = ((params->mac_addr[2] << 24) |
2749                        (params->mac_addr[3] << 16) |
2750                        (params->mac_addr[4] << 8) |
2751                         params->mac_addr[5]);
2752         wb_data[1] = ((params->mac_addr[0] << 8) |
2753                         params->mac_addr[1]);
2754         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
2755                     wb_data, 2);
2756
2757         udelay(30);
2758
2759         /* Configure SAFC */
2760         wb_data[0] = 0x1000200;
2761         wb_data[1] = 0;
2762         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
2763                     wb_data, 2);
2764         udelay(30);
2765
2766         /* set rx mtu */
2767         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2768         wb_data[1] = 0;
2769         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
2770         udelay(30);
2771
2772         /* set tx mtu */
2773         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2774         wb_data[1] = 0;
2775         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
2776         udelay(30);
2777         /* set cnt max size */
2778         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
2779         wb_data[1] = 0;
2780         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2781         udelay(30);
2782         bnx2x_update_pfc_bmac2(params, vars, is_lb);
2783
2784         return 0;
2785 }
2786
2787 static int bnx2x_bmac_enable(struct link_params *params,
2788                              struct link_vars *vars,
2789                              u8 is_lb)
2790 {
2791         int rc = 0;
2792         u8 port = params->port;
2793         struct bnx2x *bp = params->bp;
2794         u32 val;
2795         /* reset and unreset the BigMac */
2796         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2797                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2798         msleep(1);
2799
2800         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2801                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2802
2803         /* enable access for bmac registers */
2804         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2805
2806         /* Enable BMAC according to BMAC type*/
2807         if (CHIP_IS_E2(bp))
2808                 rc = bnx2x_bmac2_enable(params, vars, is_lb);
2809         else
2810                 rc = bnx2x_bmac1_enable(params, vars, is_lb);
2811         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
2812         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
2813         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
2814         val = 0;
2815         if ((params->feature_config_flags &
2816               FEATURE_CONFIG_PFC_ENABLED) ||
2817             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2818                 val = 1;
2819         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
2820         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
2821         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
2822         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
2823         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
2824         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
2825
2826         vars->mac_type = MAC_TYPE_BMAC;
2827         return rc;
2828 }
2829
2830 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
2831 {
2832         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2833                         NIG_REG_INGRESS_BMAC0_MEM;
2834         u32 wb_data[2];
2835         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
2836
2837         /* Only if the bmac is out of reset */
2838         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
2839                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
2840             nig_bmac_enable) {
2841
2842                 if (CHIP_IS_E2(bp)) {
2843                         /* Clear Rx Enable bit in BMAC_CONTROL register */
2844                         REG_RD_DMAE(bp, bmac_addr +
2845                                     BIGMAC2_REGISTER_BMAC_CONTROL,
2846                                     wb_data, 2);
2847                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2848                         REG_WR_DMAE(bp, bmac_addr +
2849                                     BIGMAC2_REGISTER_BMAC_CONTROL,
2850                                     wb_data, 2);
2851                 } else {
2852                         /* Clear Rx Enable bit in BMAC_CONTROL register */
2853                         REG_RD_DMAE(bp, bmac_addr +
2854                                         BIGMAC_REGISTER_BMAC_CONTROL,
2855                                         wb_data, 2);
2856                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2857                         REG_WR_DMAE(bp, bmac_addr +
2858                                         BIGMAC_REGISTER_BMAC_CONTROL,
2859                                         wb_data, 2);
2860                 }
2861                 msleep(1);
2862         }
2863 }
2864
2865 static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
2866                             u32 line_speed)
2867 {
2868         struct bnx2x *bp = params->bp;
2869         u8 port = params->port;
2870         u32 init_crd, crd;
2871         u32 count = 1000;
2872
2873         /* disable port */
2874         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
2875
2876         /* wait for init credit */
2877         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
2878         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2879         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
2880
2881         while ((init_crd != crd) && count) {
2882                 msleep(5);
2883
2884                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2885                 count--;
2886         }
2887         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2888         if (init_crd != crd) {
2889                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
2890                           init_crd, crd);
2891                 return -EINVAL;
2892         }
2893
2894         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
2895             line_speed == SPEED_10 ||
2896             line_speed == SPEED_100 ||
2897             line_speed == SPEED_1000 ||
2898             line_speed == SPEED_2500) {
2899                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
2900                 /* update threshold */
2901                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
2902                 /* update init credit */
2903                 init_crd = 778;         /* (800-18-4) */
2904
2905         } else {
2906                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
2907                               ETH_OVREHEAD)/16;
2908                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
2909                 /* update threshold */
2910                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
2911                 /* update init credit */
2912                 switch (line_speed) {
2913                 case SPEED_10000:
2914                         init_crd = thresh + 553 - 22;
2915                         break;
2916                 default:
2917                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2918                                   line_speed);
2919                         return -EINVAL;
2920                 }
2921         }
2922         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
2923         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
2924                  line_speed, init_crd);
2925
2926         /* probe the credit changes */
2927         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
2928         msleep(5);
2929         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
2930
2931         /* enable port */
2932         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
2933         return 0;
2934 }
2935
2936 /**
2937  * bnx2x_get_emac_base - retrive emac base address
2938  *
2939  * @bp:                 driver handle
2940  * @mdc_mdio_access:    access type
2941  * @port:               port id
2942  *
2943  * This function selects the MDC/MDIO access (through emac0 or
2944  * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2945  * phy has a default access mode, which could also be overridden
2946  * by nvram configuration. This parameter, whether this is the
2947  * default phy configuration, or the nvram overrun
2948  * configuration, is passed here as mdc_mdio_access and selects
2949  * the emac_base for the CL45 read/writes operations
2950  */
2951 static u32 bnx2x_get_emac_base(struct bnx2x *bp,
2952                                u32 mdc_mdio_access, u8 port)
2953 {
2954         u32 emac_base = 0;
2955         switch (mdc_mdio_access) {
2956         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2957                 break;
2958         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2959                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2960                         emac_base = GRCBASE_EMAC1;
2961                 else
2962                         emac_base = GRCBASE_EMAC0;
2963                 break;
2964         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2965                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2966                         emac_base = GRCBASE_EMAC0;
2967                 else
2968                         emac_base = GRCBASE_EMAC1;
2969                 break;
2970         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2971                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2972                 break;
2973         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
2974                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2975                 break;
2976         default:
2977                 break;
2978         }
2979         return emac_base;
2980
2981 }
2982
2983 /******************************************************************/
2984 /*                      CL22 access functions                     */
2985 /******************************************************************/
2986 static int bnx2x_cl22_write(struct bnx2x *bp,
2987                                        struct bnx2x_phy *phy,
2988                                        u16 reg, u16 val)
2989 {
2990         u32 tmp, mode;
2991         u8 i;
2992         int rc = 0;
2993         /* Switch to CL22 */
2994         mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2995         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2996                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2997
2998         /* address */
2999         tmp = ((phy->addr << 21) | (reg << 16) | val |
3000                EMAC_MDIO_COMM_COMMAND_WRITE_22 |
3001                EMAC_MDIO_COMM_START_BUSY);
3002         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3003
3004         for (i = 0; i < 50; i++) {
3005                 udelay(10);
3006
3007                 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3008                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3009                         udelay(5);
3010                         break;
3011                 }
3012         }
3013         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3014                 DP(NETIF_MSG_LINK, "write phy register failed\n");
3015                 rc = -EFAULT;
3016         }
3017         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3018         return rc;
3019 }
3020
3021 static int bnx2x_cl22_read(struct bnx2x *bp,
3022                                       struct bnx2x_phy *phy,
3023                                       u16 reg, u16 *ret_val)
3024 {
3025         u32 val, mode;
3026         u16 i;
3027         int rc = 0;
3028
3029         /* Switch to CL22 */
3030         mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
3031         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
3032                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
3033
3034         /* address */
3035         val = ((phy->addr << 21) | (reg << 16) |
3036                EMAC_MDIO_COMM_COMMAND_READ_22 |
3037                EMAC_MDIO_COMM_START_BUSY);
3038         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3039
3040         for (i = 0; i < 50; i++) {
3041                 udelay(10);
3042
3043                 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3044                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3045                         *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
3046                         udelay(5);
3047                         break;
3048                 }
3049         }
3050         if (val & EMAC_MDIO_COMM_START_BUSY) {
3051                 DP(NETIF_MSG_LINK, "read phy register failed\n");
3052
3053                 *ret_val = 0;
3054                 rc = -EFAULT;
3055         }
3056         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
3057         return rc;
3058 }
3059
3060 /******************************************************************/
3061 /*                      CL45 access functions                     */
3062 /******************************************************************/
3063 static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
3064                            u8 devad, u16 reg, u16 *ret_val)
3065 {
3066         u32 val;
3067         u16 i;
3068         int rc = 0;
3069         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3070                 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3071                               EMAC_MDIO_STATUS_10MB);
3072         /* address */
3073         val = ((phy->addr << 21) | (devad << 16) | reg |
3074                EMAC_MDIO_COMM_COMMAND_ADDRESS |
3075                EMAC_MDIO_COMM_START_BUSY);
3076         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3077
3078         for (i = 0; i < 50; i++) {
3079                 udelay(10);
3080
3081                 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3082                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3083                         udelay(5);
3084                         break;
3085                 }
3086         }
3087         if (val & EMAC_MDIO_COMM_START_BUSY) {
3088                 DP(NETIF_MSG_LINK, "read phy register failed\n");
3089                 netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3090                 *ret_val = 0;
3091                 rc = -EFAULT;
3092         } else {
3093                 /* data */
3094                 val = ((phy->addr << 21) | (devad << 16) |
3095                        EMAC_MDIO_COMM_COMMAND_READ_45 |
3096                        EMAC_MDIO_COMM_START_BUSY);
3097                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3098
3099                 for (i = 0; i < 50; i++) {
3100                         udelay(10);
3101
3102                         val = REG_RD(bp, phy->mdio_ctrl +
3103                                      EMAC_REG_EMAC_MDIO_COMM);
3104                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3105                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
3106                                 break;
3107                         }
3108                 }
3109                 if (val & EMAC_MDIO_COMM_START_BUSY) {
3110                         DP(NETIF_MSG_LINK, "read phy register failed\n");
3111                         netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3112                         *ret_val = 0;
3113                         rc = -EFAULT;
3114                 }
3115         }
3116         /* Work around for E3 A0 */
3117         if (phy->flags & FLAGS_MDC_MDIO_WA) {
3118                 phy->flags ^= FLAGS_DUMMY_READ;
3119                 if (phy->flags & FLAGS_DUMMY_READ) {
3120                         u16 temp_val;
3121                         bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
3122                 }
3123         }
3124
3125         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3126                 bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3127                                EMAC_MDIO_STATUS_10MB);
3128         return rc;
3129 }
3130
3131 static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3132                             u8 devad, u16 reg, u16 val)
3133 {
3134         u32 tmp;
3135         u8 i;
3136         int rc = 0;
3137         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3138                 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3139                               EMAC_MDIO_STATUS_10MB);
3140
3141         /* address */
3142
3143         tmp = ((phy->addr << 21) | (devad << 16) | reg |
3144                EMAC_MDIO_COMM_COMMAND_ADDRESS |
3145                EMAC_MDIO_COMM_START_BUSY);
3146         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3147
3148         for (i = 0; i < 50; i++) {
3149                 udelay(10);
3150
3151                 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3152                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3153                         udelay(5);
3154                         break;
3155                 }
3156         }
3157         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3158                 DP(NETIF_MSG_LINK, "write phy register failed\n");
3159                 netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3160                 rc = -EFAULT;
3161         } else {
3162                 /* data */
3163                 tmp = ((phy->addr << 21) | (devad << 16) | val |
3164                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
3165                        EMAC_MDIO_COMM_START_BUSY);
3166                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3167
3168                 for (i = 0; i < 50; i++) {
3169                         udelay(10);
3170
3171                         tmp = REG_RD(bp, phy->mdio_ctrl +
3172                                      EMAC_REG_EMAC_MDIO_COMM);
3173                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3174                                 udelay(5);
3175                                 break;
3176                         }
3177                 }
3178                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3179                         DP(NETIF_MSG_LINK, "write phy register failed\n");
3180                         netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3181                         rc = -EFAULT;
3182                 }
3183         }
3184         /* Work around for E3 A0 */
3185         if (phy->flags & FLAGS_MDC_MDIO_WA) {
3186                 phy->flags ^= FLAGS_DUMMY_READ;
3187                 if (phy->flags & FLAGS_DUMMY_READ) {
3188                         u16 temp_val;
3189                         bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
3190                 }
3191         }
3192         if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3193                 bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3194                                EMAC_MDIO_STATUS_10MB);
3195         return rc;
3196 }
3197 /******************************************************************/
3198 /*                      BSC access functions from E3              */
3199 /******************************************************************/
3200 static void bnx2x_bsc_module_sel(struct link_params *params)
3201 {
3202         int idx;
3203         u32 board_cfg, sfp_ctrl;
3204         u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3205         struct bnx2x *bp = params->bp;
3206         u8 port = params->port;
3207         /* Read I2C output PINs */
3208         board_cfg = REG_RD(bp, params->shmem_base +
3209                            offsetof(struct shmem_region,
3210                                     dev_info.shared_hw_config.board));
3211         i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3212         i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3213                         SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3214
3215         /* Read I2C output value */
3216         sfp_ctrl = REG_RD(bp, params->shmem_base +
3217                           offsetof(struct shmem_region,
3218                                  dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3219         i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3220         i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3221         DP(NETIF_MSG_LINK, "Setting BSC switch\n");
3222         for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3223                 bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
3224 }
3225
3226 static int bnx2x_bsc_read(struct link_params *params,
3227                           struct bnx2x_phy *phy,
3228                           u8 sl_devid,
3229                           u16 sl_addr,
3230                           u8 lc_addr,
3231                           u8 xfer_cnt,
3232                           u32 *data_array)
3233 {
3234         u32 val, i;
3235         int rc = 0;
3236         struct bnx2x *bp = params->bp;
3237
3238         if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) {
3239                 DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid);
3240                 return -EINVAL;
3241         }
3242
3243         if (xfer_cnt > 16) {
3244                 DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n",
3245                                         xfer_cnt);
3246                 return -EINVAL;
3247         }
3248         bnx2x_bsc_module_sel(params);
3249
3250         xfer_cnt = 16 - lc_addr;
3251
3252         /* enable the engine */
3253         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3254         val |= MCPR_IMC_COMMAND_ENABLE;
3255         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3256
3257         /* program slave device ID */
3258         val = (sl_devid << 16) | sl_addr;
3259         REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3260
3261         /* start xfer with 0 byte to update the address pointer ???*/
3262         val = (MCPR_IMC_COMMAND_ENABLE) |
3263               (MCPR_IMC_COMMAND_WRITE_OP <<
3264                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3265                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3266         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3267
3268         /* poll for completion */
3269         i = 0;
3270         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3271         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3272                 udelay(10);
3273                 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3274                 if (i++ > 1000) {
3275                         DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n",
3276                                                                 i);
3277                         rc = -EFAULT;
3278                         break;
3279                 }
3280         }
3281         if (rc == -EFAULT)
3282                 return rc;
3283
3284         /* start xfer with read op */
3285         val = (MCPR_IMC_COMMAND_ENABLE) |
3286                 (MCPR_IMC_COMMAND_READ_OP <<
3287                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3288                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3289                   (xfer_cnt);
3290         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3291
3292         /* poll for completion */
3293         i = 0;
3294         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3295         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3296                 udelay(10);
3297                 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3298                 if (i++ > 1000) {
3299                         DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i);
3300                         rc = -EFAULT;
3301                         break;
3302                 }
3303         }
3304         if (rc == -EFAULT)
3305                 return rc;
3306
3307         for (i = (lc_addr >> 2); i < 4; i++) {
3308                 data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
3309 #ifdef __BIG_ENDIAN
3310                 data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
3311                                 ((data_array[i] & 0x0000ff00) << 8) |
3312                                 ((data_array[i] & 0x00ff0000) >> 8) |
3313                                 ((data_array[i] & 0xff000000) >> 24);
3314 #endif
3315         }
3316         return rc;
3317 }
3318
3319 static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3320                                      u8 devad, u16 reg, u16 or_val)
3321 {
3322         u16 val;
3323         bnx2x_cl45_read(bp, phy, devad, reg, &val);
3324         bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
3325 }
3326
3327 int bnx2x_phy_read(struct link_params *params, u8 phy_addr,
3328                    u8 devad, u16 reg, u16 *ret_val)
3329 {
3330         u8 phy_index;
3331         /*
3332          * Probe for the phy according to the given phy_addr, and execute
3333          * the read request on it
3334          */
3335         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3336                 if (params->phy[phy_index].addr == phy_addr) {
3337                         return bnx2x_cl45_read(params->bp,
3338                                                &params->phy[phy_index], devad,
3339                                                reg, ret_val);
3340                 }
3341         }
3342         return -EINVAL;
3343 }
3344
3345 int bnx2x_phy_write(struct link_params *params, u8 phy_addr,
3346                     u8 devad, u16 reg, u16 val)
3347 {
3348         u8 phy_index;
3349         /*
3350          * Probe for the phy according to the given phy_addr, and execute
3351          * the write request on it
3352          */
3353         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3354                 if (params->phy[phy_index].addr == phy_addr) {
3355                         return bnx2x_cl45_write(params->bp,
3356                                                 &params->phy[phy_index], devad,
3357                                                 reg, val);
3358                 }
3359         }
3360         return -EINVAL;
3361 }
3362 static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy,
3363                                   struct link_params *params)
3364 {
3365         u8 lane = 0;
3366         struct bnx2x *bp = params->bp;
3367         u32 path_swap, path_swap_ovr;
3368         u8 path, port;
3369
3370         path = BP_PATH(bp);
3371         port = params->port;
3372
3373         if (bnx2x_is_4_port_mode(bp)) {
3374                 u32 port_swap, port_swap_ovr;
3375
3376                 /*figure out path swap value */
3377                 path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
3378                 if (path_swap_ovr & 0x1)
3379                         path_swap = (path_swap_ovr & 0x2);
3380                 else
3381                         path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP);
3382
3383                 if (path_swap)
3384                         path = path ^ 1;
3385
3386                 /*figure out port swap value */
3387                 port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
3388                 if (port_swap_ovr & 0x1)
3389                         port_swap = (port_swap_ovr & 0x2);
3390                 else
3391                         port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP);
3392
3393                 if (port_swap)
3394                         port = port ^ 1;
3395
3396                 lane = (port<<1) + path;
3397         } else { /* two port mode - no port swap */
3398
3399                 /*figure out path swap value */
3400                 path_swap_ovr =
3401                         REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
3402                 if (path_swap_ovr & 0x1) {
3403                         path_swap = (path_swap_ovr & 0x2);
3404                 } else {
3405                         path_swap =
3406                                 REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP);
3407                 }
3408                 if (path_swap)
3409                         path = path ^ 1;
3410
3411                 lane = path << 1 ;
3412         }
3413         return lane;
3414 }
3415
3416 static void bnx2x_set_aer_mmd(struct link_params *params,
3417                               struct bnx2x_phy *phy)
3418 {
3419         u32 ser_lane;
3420         u16 offset, aer_val;
3421         struct bnx2x *bp = params->bp;
3422         ser_lane = ((params->lane_config &
3423                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3424                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3425
3426         offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
3427                 (phy->addr + ser_lane) : 0;
3428
3429         if (USES_WARPCORE(bp)) {
3430                 aer_val = bnx2x_get_warpcore_lane(phy, params);
3431                 /*
3432                  * In Dual-lane mode, two lanes are joined together,
3433                  * so in order to configure them, the AER broadcast method is
3434                  * used here.
3435                  * 0x200 is the broadcast address for lanes 0,1
3436                  * 0x201 is the broadcast address for lanes 2,3
3437                  */
3438                 if (phy->flags & FLAGS_WC_DUAL_MODE)
3439                         aer_val = (aer_val >> 1) | 0x200;
3440         } else if (CHIP_IS_E2(bp))
3441                 aer_val = 0x3800 + offset - 1;
3442         else
3443                 aer_val = 0x3800 + offset;
3444
3445         CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3446                           MDIO_AER_BLOCK_AER_REG, aer_val);
3447
3448 }
3449
3450 /******************************************************************/
3451 /*                      Internal phy section                      */
3452 /******************************************************************/
3453
3454 static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
3455 {
3456         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3457
3458         /* Set Clause 22 */
3459         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
3460         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
3461         udelay(500);
3462         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
3463         udelay(500);
3464          /* Set Clause 45 */
3465         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
3466 }
3467
3468 static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
3469 {
3470         u32 val;
3471
3472         DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
3473
3474         val = SERDES_RESET_BITS << (port*16);
3475
3476         /* reset and unreset the SerDes/XGXS */
3477         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3478         udelay(500);
3479         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3480
3481         bnx2x_set_serdes_access(bp, port);
3482
3483         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
3484                DEFAULT_PHY_DEV_ADDR);
3485 }
3486
3487 static void bnx2x_xgxs_deassert(struct link_params *params)
3488 {
3489         struct bnx2x *bp = params->bp;
3490         u8 port;
3491         u32 val;
3492         DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
3493         port = params->port;
3494
3495         val = XGXS_RESET_BITS << (port*16);
3496
3497         /* reset and unreset the SerDes/XGXS */
3498         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3499         udelay(500);
3500         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3501
3502         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
3503         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3504                params->phy[INT_PHY].def_md_devad);
3505 }
3506
3507 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
3508                                      struct link_params *params, u16 *ieee_fc)
3509 {
3510         struct bnx2x *bp = params->bp;
3511         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
3512         /**
3513          * resolve pause mode and advertisement Please refer to Table
3514          * 28B-3 of the 802.3ab-1999 spec
3515          */
3516
3517         switch (phy->req_flow_ctrl) {
3518         case BNX2X_FLOW_CTRL_AUTO:
3519                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
3520                         *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3521                 else
3522                         *ieee_fc |=
3523                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3524                 break;
3525
3526         case BNX2X_FLOW_CTRL_TX:
3527                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3528                 break;
3529
3530         case BNX2X_FLOW_CTRL_RX:
3531         case BNX2X_FLOW_CTRL_BOTH:
3532                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3533                 break;
3534
3535         case BNX2X_FLOW_CTRL_NONE:
3536         default:
3537                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3538                 break;
3539         }
3540         DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
3541 }
3542
3543 static void set_phy_vars(struct link_params *params,
3544                          struct link_vars *vars)
3545 {
3546         struct bnx2x *bp = params->bp;
3547         u8 actual_phy_idx, phy_index, link_cfg_idx;
3548         u8 phy_config_swapped = params->multi_phy_config &
3549                         PORT_HW_CFG_PHY_SWAPPED_ENABLED;
3550         for (phy_index = INT_PHY; phy_index < params->num_phys;
3551               phy_index++) {
3552                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
3553                 actual_phy_idx = phy_index;
3554                 if (phy_config_swapped) {
3555                         if (phy_index == EXT_PHY1)
3556                                 actual_phy_idx = EXT_PHY2;
3557                         else if (phy_index == EXT_PHY2)
3558                                 actual_phy_idx = EXT_PHY1;
3559                 }
3560                 params->phy[actual_phy_idx].req_flow_ctrl =
3561                         params->req_flow_ctrl[link_cfg_idx];
3562
3563                 params->phy[actual_phy_idx].req_line_speed =
3564                         params->req_line_speed[link_cfg_idx];
3565
3566                 params->phy[actual_phy_idx].speed_cap_mask =
3567                         params->speed_cap_mask[link_cfg_idx];
3568
3569                 params->phy[actual_phy_idx].req_duplex =
3570                         params->req_duplex[link_cfg_idx];
3571
3572                 if (params->req_line_speed[link_cfg_idx] ==
3573                     SPEED_AUTO_NEG)
3574                         vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
3575
3576                 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
3577                            " speed_cap_mask %x\n",
3578                            params->phy[actual_phy_idx].req_flow_ctrl,
3579                            params->phy[actual_phy_idx].req_line_speed,
3580                            params->phy[actual_phy_idx].speed_cap_mask);
3581         }
3582 }
3583
3584 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3585                                     struct bnx2x_phy *phy,
3586                                     struct link_vars *vars)
3587 {
3588         u16 val;
3589         struct bnx2x *bp = params->bp;
3590         /* read modify write pause advertizing */
3591         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3592
3593         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3594
3595         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3596         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3597         if ((vars->ieee_fc &
3598             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3599             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3600                 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3601         }
3602         if ((vars->ieee_fc &
3603             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3604             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3605                 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3606         }
3607         DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3608         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3609 }
3610
3611 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
3612 {                                               /*  LD      LP   */
3613         switch (pause_result) {                 /* ASYM P ASYM P */
3614         case 0xb:                               /*   1  0   1  1 */
3615                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
3616                 break;
3617
3618         case 0xe:                               /*   1  1   1  0 */
3619                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
3620                 break;
3621
3622         case 0x5:                               /*   0  1   0  1 */
3623         case 0x7:                               /*   0  1   1  1 */
3624         case 0xd:                               /*   1  1   0  1 */
3625         case 0xf:                               /*   1  1   1  1 */
3626                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
3627                 break;
3628
3629         default:
3630                 break;
3631         }
3632         if (pause_result & (1<<0))
3633                 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
3634         if (pause_result & (1<<1))
3635                 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
3636 }
3637
3638 static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3639                                    struct link_params *params,
3640                                    struct link_vars *vars)
3641 {
3642         struct bnx2x *bp = params->bp;
3643         u16 ld_pause;           /* local */
3644         u16 lp_pause;           /* link partner */
3645         u16 pause_result;
3646         u8 ret = 0;
3647         /* read twice */
3648
3649         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3650
3651         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
3652                 vars->flow_ctrl = phy->req_flow_ctrl;
3653         else if (phy->req_line_speed != SPEED_AUTO_NEG)
3654                 vars->flow_ctrl = params->req_fc_auto_adv;
3655         else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3656                 ret = 1;
3657                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
3658                         bnx2x_cl22_read(bp, phy,
3659                                         0x4, &ld_pause);
3660                         bnx2x_cl22_read(bp, phy,
3661                                         0x5, &lp_pause);
3662                 } else {
3663                         bnx2x_cl45_read(bp, phy,
3664                                         MDIO_AN_DEVAD,
3665                                         MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3666                         bnx2x_cl45_read(bp, phy,
3667                                         MDIO_AN_DEVAD,
3668                                         MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3669                 }
3670                 pause_result = (ld_pause &
3671                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3672                 pause_result |= (lp_pause &
3673                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3674                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
3675                    pause_result);
3676                 bnx2x_pause_resolve(vars, pause_result);
3677         }
3678         return ret;
3679 }
3680 /******************************************************************/
3681 /*                      Warpcore section                          */
3682 /******************************************************************/
3683 /* The init_internal_warpcore should mirror the xgxs,
3684  * i.e. reset the lane (if needed), set aer for the
3685  * init configuration, and set/clear SGMII flag. Internal
3686  * phy init is done purely in phy_init stage.
3687  */
3688 static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
3689                                         struct link_params *params,
3690                                         struct link_vars *vars) {
3691         u16 val16 = 0, lane, bam37 = 0;
3692         struct bnx2x *bp = params->bp;
3693         DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
3694
3695         /* Disable Autoneg: re-enable it after adv is done. */
3696         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3697                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0);
3698
3699         /* Check adding advertisement for 1G KX */
3700         if (((vars->line_speed == SPEED_AUTO_NEG) &&
3701              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
3702             (vars->line_speed == SPEED_1000)) {
3703                 u16 sd_digital;
3704                 val16 |= (1<<5);
3705
3706                 /* Enable CL37 1G Parallel Detect */
3707                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3708                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital);
3709                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3710                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3711                                  (sd_digital | 0x1));
3712
3713                 DP(NETIF_MSG_LINK, "Advertize 1G\n");
3714         }
3715         if (((vars->line_speed == SPEED_AUTO_NEG) &&
3716              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
3717             (vars->line_speed ==  SPEED_10000)) {
3718                 /* Check adding advertisement for 10G KR */
3719                 val16 |= (1<<7);
3720                 /* Enable 10G Parallel Detect */
3721                 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3722                                 MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
3723
3724                 DP(NETIF_MSG_LINK, "Advertize 10G\n");
3725         }
3726
3727         /* Set Transmit PMD settings */
3728         lane = bnx2x_get_warpcore_lane(phy, params);
3729         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3730                       MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3731                      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3732                       (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3733                       (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3734         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3735                          MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
3736                          0x03f0);
3737         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3738                          MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
3739                          0x03f0);
3740
3741         /* Advertised speeds */
3742         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3743                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
3744
3745         /* Advertised and set FEC (Forward Error Correction) */
3746         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3747                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
3748                          (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
3749                           MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
3750
3751         /* Enable CL37 BAM */
3752         if (REG_RD(bp, params->shmem_base +
3753                    offsetof(struct shmem_region, dev_info.
3754                             port_hw_config[params->port].default_cfg)) &
3755             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
3756                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3757                                 MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, &bam37);
3758                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3759                         MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, bam37 | 1);
3760                 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
3761         }
3762
3763         /* Advertise pause */
3764         bnx2x_ext_phy_set_pause(params, phy, vars);
3765
3766         /*
3767          * Set KR Autoneg Work-Around flag for Warpcore version older than D108
3768          */
3769         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3770                         MDIO_WC_REG_UC_INFO_B1_VERSION, &val16);
3771         if (val16 < 0xd108) {
3772                 DP(NETIF_MSG_LINK, "Enable AN KR work-around\n");
3773                 vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
3774         }
3775
3776         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3777                         MDIO_WC_REG_DIGITAL5_MISC7, &val16);
3778
3779         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3780                          MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100);
3781
3782         /* Over 1G - AN local device user page 1 */
3783         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3784                         MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
3785
3786         /* Enable Autoneg */
3787         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3788                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000);
3789
3790 }
3791
3792 static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
3793                                       struct link_params *params,
3794                                       struct link_vars *vars)
3795 {
3796         struct bnx2x *bp = params->bp;
3797         u16 val;
3798
3799         /* Disable Autoneg */
3800         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3801                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
3802
3803         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3804                          MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
3805
3806         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3807                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00);
3808
3809         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3810                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0);
3811
3812         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3813                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3814
3815         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3816                         MDIO_WC_REG_DIGITAL3_UP1, 0x1);
3817
3818         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3819                          MDIO_WC_REG_DIGITAL5_MISC7, 0xa);
3820
3821         /* Disable CL36 PCS Tx */
3822         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3823                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0);
3824
3825         /* Double Wide Single Data Rate @ pll rate */
3826         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3827                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF);
3828
3829         /* Leave cl72 training enable, needed for KR */
3830         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3831                 MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
3832                 0x2);
3833
3834         /* Leave CL72 enabled */
3835         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3836                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3837                          &val);
3838         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3839                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3840                          val | 0x3800);
3841
3842         /* Set speed via PMA/PMD register */
3843         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3844                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3845
3846         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3847                          MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
3848
3849         /*Enable encoded forced speed */
3850         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3851                          MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
3852
3853         /* Turn TX scramble payload only the 64/66 scrambler */
3854         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3855                          MDIO_WC_REG_TX66_CONTROL, 0x9);
3856
3857         /* Turn RX scramble payload only the 64/66 scrambler */
3858         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3859                                  MDIO_WC_REG_RX66_CONTROL, 0xF9);
3860
3861         /* set and clear loopback to cause a reset to 64/66 decoder */
3862         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3863                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
3864         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3865                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3866
3867 }
3868
3869 static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
3870                                        struct link_params *params,
3871                                        u8 is_xfi)
3872 {
3873         struct bnx2x *bp = params->bp;
3874         u16 misc1_val, tap_val, tx_driver_val, lane, val;
3875         /* Hold rxSeqStart */
3876         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3877                         MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3878         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3879                          MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000));
3880
3881         /* Hold tx_fifo_reset */
3882         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3883                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3884         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3885                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1));
3886
3887         /* Disable CL73 AN */
3888         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3889
3890         /* Disable 100FX Enable and Auto-Detect */
3891         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3892                         MDIO_WC_REG_FX100_CTRL1, &val);
3893         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3894                          MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA));
3895
3896         /* Disable 100FX Idle detect */
3897         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3898                         MDIO_WC_REG_FX100_CTRL3, &val);
3899         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3900                          MDIO_WC_REG_FX100_CTRL3, (val | 0x0080));
3901
3902         /* Set Block address to Remote PHY & Clear forced_speed[5] */
3903         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3904                         MDIO_WC_REG_DIGITAL4_MISC3, &val);
3905         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3906                          MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F));
3907
3908         /* Turn off auto-detect & fiber mode */
3909         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3910                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3911         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3912                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3913                          (val & 0xFFEE));
3914
3915         /* Set filter_force_link, disable_false_link and parallel_detect */
3916         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3917                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
3918         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3919                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3920                          ((val | 0x0006) & 0xFFFE));
3921
3922         /* Set XFI / SFI */
3923         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3924                         MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
3925
3926         misc1_val &= ~(0x1f);
3927
3928         if (is_xfi) {
3929                 misc1_val |= 0x5;
3930                 tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3931                            (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3932                            (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3933                 tx_driver_val =
3934                       ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3935                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3936                        (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3937
3938         } else {
3939                 misc1_val |= 0x9;
3940                 tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3941                            (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3942                            (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3943                 tx_driver_val =
3944                       ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3945                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3946                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3947         }
3948         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3949                          MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
3950
3951         /* Set Transmit PMD settings */
3952         lane = bnx2x_get_warpcore_lane(phy, params);
3953         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3954                          MDIO_WC_REG_TX_FIR_TAP,
3955                          tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
3956         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3957                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3958                          tx_driver_val);
3959
3960         /* Enable fiber mode, enable and invert sig_det */
3961         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3962                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3963         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3964                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd);
3965
3966         /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
3967         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3968                         MDIO_WC_REG_DIGITAL4_MISC3, &val);
3969         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3970                          MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
3971
3972         /* 10G XFI Full Duplex */
3973         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3974                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
3975
3976         /* Release tx_fifo_reset */
3977         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3978                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3979         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3980                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE);
3981
3982         /* Release rxSeqStart */
3983         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3984                         MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3985         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3986                          MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF));
3987 }
3988
3989 static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp,
3990                                        struct bnx2x_phy *phy)
3991 {
3992         DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n");
3993 }
3994
3995 static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
3996                                          struct bnx2x_phy *phy,
3997                                          u16 lane)
3998 {
3999         /* Rx0 anaRxControl1G */
4000         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4001                          MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
4002
4003         /* Rx2 anaRxControl1G */
4004         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4005                          MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
4006
4007         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4008                          MDIO_WC_REG_RX66_SCW0, 0xE070);
4009
4010         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4011                          MDIO_WC_REG_RX66_SCW1, 0xC0D0);
4012
4013         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4014                          MDIO_WC_REG_RX66_SCW2, 0xA0B0);
4015
4016         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4017                          MDIO_WC_REG_RX66_SCW3, 0x8090);
4018
4019         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4020                          MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
4021
4022         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4023                          MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
4024
4025         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4026                          MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
4027
4028         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4029                          MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
4030
4031         /* Serdes Digital Misc1 */
4032         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4033                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
4034
4035         /* Serdes Digital4 Misc3 */
4036         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4037                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
4038
4039         /* Set Transmit PMD settings */
4040         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4041                          MDIO_WC_REG_TX_FIR_TAP,
4042                         ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
4043                          (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
4044                          (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
4045                          MDIO_WC_REG_TX_FIR_TAP_ENABLE));
4046         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4047                       MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4048                      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
4049                       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
4050                       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
4051 }
4052
4053 static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
4054                                            struct link_params *params,
4055                                            u8 fiber_mode,
4056                                            u8 always_autoneg)
4057 {
4058         struct bnx2x *bp = params->bp;
4059         u16 val16, digctrl_kx1, digctrl_kx2;
4060
4061         /* Clear XFI clock comp in non-10G single lane mode. */
4062         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4063                         MDIO_WC_REG_RX66_CONTROL, &val16);
4064         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4065                          MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
4066
4067         if (always_autoneg || phy->req_line_speed == SPEED_AUTO_NEG) {
4068                 /* SGMII Autoneg */
4069                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4070                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4071                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4072                                  MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
4073                                  val16 | 0x1000);
4074                 DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
4075         } else {
4076                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4077                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4078                 val16 &= 0xcebf;
4079                 switch (phy->req_line_speed) {
4080                 case SPEED_10:
4081                         break;
4082                 case SPEED_100:
4083                         val16 |= 0x2000;
4084                         break;
4085                 case SPEED_1000:
4086                         val16 |= 0x0040;
4087                         break;
4088                 default:
4089                         DP(NETIF_MSG_LINK,
4090                            "Speed not supported: 0x%x\n", phy->req_line_speed);
4091                         return;
4092                 }
4093
4094                 if (phy->req_duplex == DUPLEX_FULL)
4095                         val16 |= 0x0100;
4096
4097                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4098                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
4099
4100                 DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
4101                                phy->req_line_speed);
4102                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4103                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4104                 DP(NETIF_MSG_LINK, "  (readback) %x\n", val16);
4105         }
4106
4107         /* SGMII Slave mode and disable signal detect */
4108         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4109                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
4110         if (fiber_mode)
4111                 digctrl_kx1 = 1;
4112         else
4113                 digctrl_kx1 &= 0xff4a;
4114
4115         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4116                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4117                         digctrl_kx1);
4118
4119         /* Turn off parallel detect */
4120         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4121                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
4122         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4123                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4124                         (digctrl_kx2 & ~(1<<2)));
4125
4126         /* Re-enable parallel detect */
4127         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4128                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4129                         (digctrl_kx2 | (1<<2)));
4130
4131         /* Enable autodet */
4132         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4133                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4134                         (digctrl_kx1 | 0x10));
4135 }
4136
4137 static void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
4138                                       struct bnx2x_phy *phy,
4139                                       u8 reset)
4140 {
4141         u16 val;
4142         /* Take lane out of reset after configuration is finished */
4143         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4144                         MDIO_WC_REG_DIGITAL5_MISC6, &val);
4145         if (reset)
4146                 val |= 0xC000;
4147         else
4148                 val &= 0x3FFF;
4149         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4150                          MDIO_WC_REG_DIGITAL5_MISC6, val);
4151         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4152                          MDIO_WC_REG_DIGITAL5_MISC6, &val);
4153 }
4154 /* Clear SFI/XFI link settings registers */
4155 static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
4156                                       struct link_params *params,
4157                                       u16 lane)
4158 {
4159         struct bnx2x *bp = params->bp;
4160         u16 val16;
4161
4162         /* Set XFI clock comp as default. */
4163         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4164                         MDIO_WC_REG_RX66_CONTROL, &val16);
4165         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4166                          MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13));
4167
4168         bnx2x_warpcore_reset_lane(bp, phy, 1);
4169         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
4170         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4171                          MDIO_WC_REG_FX100_CTRL1, 0x014a);
4172         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4173                          MDIO_WC_REG_FX100_CTRL3, 0x0800);
4174         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4175                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8008);
4176         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4177                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195);
4178         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4179                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007);
4180         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4181                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002);
4182         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4183                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000);
4184         lane = bnx2x_get_warpcore_lane(phy, params);
4185         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4186                          MDIO_WC_REG_TX_FIR_TAP, 0x0000);
4187         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4188                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
4189         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4190                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
4191         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4192                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140);
4193         bnx2x_warpcore_reset_lane(bp, phy, 0);
4194 }
4195
4196 static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
4197                                                 u32 chip_id,
4198                                                 u32 shmem_base, u8 port,
4199                                                 u8 *gpio_num, u8 *gpio_port)
4200 {
4201         u32 cfg_pin;
4202         *gpio_num = 0;
4203         *gpio_port = 0;
4204         if (CHIP_IS_E3(bp)) {
4205                 cfg_pin = (REG_RD(bp, shmem_base +
4206                                 offsetof(struct shmem_region,
4207                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4208                                 PORT_HW_CFG_E3_MOD_ABS_MASK) >>
4209                                 PORT_HW_CFG_E3_MOD_ABS_SHIFT;
4210
4211                 /*
4212                  * Should not happen. This function called upon interrupt
4213                  * triggered by GPIO ( since EPIO can only generate interrupts
4214                  * to MCP).
4215                  * So if this function was called and none of the GPIOs was set,
4216                  * it means the shit hit the fan.
4217                  */
4218                 if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
4219                     (cfg_pin > PIN_CFG_GPIO3_P1)) {
4220                         DP(NETIF_MSG_LINK,
4221                            "ERROR: Invalid cfg pin %x for module detect indication\n",
4222                            cfg_pin);
4223                         return -EINVAL;
4224                 }
4225
4226                 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
4227                 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
4228         } else {
4229                 *gpio_num = MISC_REGISTERS_GPIO_3;
4230                 *gpio_port = port;
4231         }
4232         DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port);
4233         return 0;
4234 }
4235
4236 static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
4237                                        struct link_params *params)
4238 {
4239         struct bnx2x *bp = params->bp;
4240         u8 gpio_num, gpio_port;
4241         u32 gpio_val;
4242         if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
4243                                       params->shmem_base, params->port,
4244                                       &gpio_num, &gpio_port) != 0)
4245                 return 0;
4246         gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
4247
4248         /* Call the handling function in case module is detected */
4249         if (gpio_val == 0)
4250                 return 1;
4251         else
4252                 return 0;
4253 }
4254 static int bnx2x_warpcore_get_sigdet(struct bnx2x_phy *phy,
4255                                         struct link_params *params)
4256 {
4257         u16 gp2_status_reg0, lane;
4258         struct bnx2x *bp = params->bp;
4259
4260         lane = bnx2x_get_warpcore_lane(phy, params);
4261
4262         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
4263                                  &gp2_status_reg0);
4264
4265         return (gp2_status_reg0 >> (8+lane)) & 0x1;
4266 }
4267
4268 static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy,
4269                                        struct link_params *params,
4270                                        struct link_vars *vars)
4271 {
4272         struct bnx2x *bp = params->bp;
4273         u32 serdes_net_if;
4274         u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
4275         u16 lane = bnx2x_get_warpcore_lane(phy, params);
4276
4277         vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
4278
4279         if (!vars->turn_to_run_wc_rt)
4280                 return;
4281
4282         /* return if there is no link partner */
4283         if (!(bnx2x_warpcore_get_sigdet(phy, params))) {
4284                 DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n");
4285                 return;
4286         }
4287
4288         if (vars->rx_tx_asic_rst) {
4289                 serdes_net_if = (REG_RD(bp, params->shmem_base +
4290                                 offsetof(struct shmem_region, dev_info.
4291                                 port_hw_config[params->port].default_cfg)) &
4292                                 PORT_HW_CFG_NET_SERDES_IF_MASK);
4293
4294                 switch (serdes_net_if) {
4295                 case PORT_HW_CFG_NET_SERDES_IF_KR:
4296                         /* Do we get link yet? */
4297                         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 0x81d1,
4298                                                                 &gp_status1);
4299                         lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */
4300                                 /*10G KR*/
4301                         lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
4302
4303                         DP(NETIF_MSG_LINK,
4304                                 "gp_status1 0x%x\n", gp_status1);
4305
4306                         if (lnkup_kr || lnkup) {
4307                                         vars->rx_tx_asic_rst = 0;
4308                                         DP(NETIF_MSG_LINK,
4309                                         "link up, rx_tx_asic_rst 0x%x\n",
4310                                         vars->rx_tx_asic_rst);
4311                         } else {
4312                                 /*reset the lane to see if link comes up.*/
4313                                 bnx2x_warpcore_reset_lane(bp, phy, 1);
4314                                 bnx2x_warpcore_reset_lane(bp, phy, 0);
4315
4316                                 /* restart Autoneg */
4317                                 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
4318                                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4319
4320                                 vars->rx_tx_asic_rst--;
4321                                 DP(NETIF_MSG_LINK, "0x%x retry left\n",
4322                                 vars->rx_tx_asic_rst);
4323                         }
4324                         break;
4325
4326                 default:
4327                         break;
4328                 }
4329
4330         } /*params->rx_tx_asic_rst*/
4331
4332 }
4333
4334 static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
4335                                        struct link_params *params,
4336                                        struct link_vars *vars)
4337 {
4338         struct bnx2x *bp = params->bp;
4339         u32 serdes_net_if;
4340         u8 fiber_mode;
4341         u16 lane = bnx2x_get_warpcore_lane(phy, params);
4342         serdes_net_if = (REG_RD(bp, params->shmem_base +
4343                          offsetof(struct shmem_region, dev_info.
4344                                   port_hw_config[params->port].default_cfg)) &
4345                          PORT_HW_CFG_NET_SERDES_IF_MASK);
4346         DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
4347                            "serdes_net_if = 0x%x\n",
4348                        vars->line_speed, serdes_net_if);
4349         bnx2x_set_aer_mmd(params, phy);
4350
4351         vars->phy_flags |= PHY_XGXS_FLAG;
4352         if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
4353             (phy->req_line_speed &&
4354              ((phy->req_line_speed == SPEED_100) ||
4355               (phy->req_line_speed == SPEED_10)))) {
4356                 vars->phy_flags |= PHY_SGMII_FLAG;
4357                 DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
4358                 bnx2x_warpcore_clear_regs(phy, params, lane);
4359                 bnx2x_warpcore_set_sgmii_speed(phy, params, 0, 1);
4360         } else {
4361                 switch (serdes_net_if) {
4362                 case PORT_HW_CFG_NET_SERDES_IF_KR:
4363                         /* Enable KR Auto Neg */
4364                         if (params->loopback_mode == LOOPBACK_NONE)
4365                                 bnx2x_warpcore_enable_AN_KR(phy, params, vars);
4366                         else {
4367                                 DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
4368                                 bnx2x_warpcore_set_10G_KR(phy, params, vars);
4369                         }
4370                         break;
4371
4372                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
4373                         bnx2x_warpcore_clear_regs(phy, params, lane);
4374                         if (vars->line_speed == SPEED_10000) {
4375                                 DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
4376                                 bnx2x_warpcore_set_10G_XFI(phy, params, 1);
4377                         } else {
4378                                 if (SINGLE_MEDIA_DIRECT(params)) {
4379                                         DP(NETIF_MSG_LINK, "1G Fiber\n");
4380                                         fiber_mode = 1;
4381                                 } else {
4382                                         DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
4383                                         fiber_mode = 0;
4384                                 }
4385                                 bnx2x_warpcore_set_sgmii_speed(phy,
4386                                                                 params,
4387                                                                 fiber_mode,
4388                                                                 0);
4389                         }
4390
4391                         break;
4392
4393                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
4394
4395                         bnx2x_warpcore_clear_regs(phy, params, lane);
4396                         if (vars->line_speed == SPEED_10000) {
4397                                 DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
4398                                 bnx2x_warpcore_set_10G_XFI(phy, params, 0);
4399                         } else if (vars->line_speed == SPEED_1000) {
4400                                 DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
4401                                 bnx2x_warpcore_set_sgmii_speed(
4402                                                 phy, params, 1, 0);
4403                         }
4404                         /* Issue Module detection */
4405                         if (bnx2x_is_sfp_module_plugged(phy, params))
4406                                 bnx2x_sfp_module_detection(phy, params);
4407                         break;
4408
4409                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
4410                         if (vars->line_speed != SPEED_20000) {
4411                                 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4412                                 return;
4413                         }
4414                         DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
4415                         bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
4416                         /* Issue Module detection */
4417
4418                         bnx2x_sfp_module_detection(phy, params);
4419                         break;
4420
4421                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
4422                         if (vars->line_speed != SPEED_20000) {
4423                                 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4424                                 return;
4425                         }
4426                         DP(NETIF_MSG_LINK, "Setting 20G KR2\n");
4427                         bnx2x_warpcore_set_20G_KR2(bp, phy);
4428                         break;
4429
4430                 default:
4431                         DP(NETIF_MSG_LINK,
4432                            "Unsupported Serdes Net Interface 0x%x\n",
4433                            serdes_net_if);
4434                         return;
4435                 }
4436         }
4437
4438         /* Take lane out of reset after configuration is finished */
4439         bnx2x_warpcore_reset_lane(bp, phy, 0);
4440         DP(NETIF_MSG_LINK, "Exit config init\n");
4441 }
4442
4443 static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
4444                                          struct bnx2x_phy *phy,
4445                                          u8 tx_en)
4446 {
4447         struct bnx2x *bp = params->bp;
4448         u32 cfg_pin;
4449         u8 port = params->port;
4450
4451         cfg_pin = REG_RD(bp, params->shmem_base +
4452                                 offsetof(struct shmem_region,
4453                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4454                                 PORT_HW_CFG_TX_LASER_MASK;
4455         /* Set the !tx_en since this pin is DISABLE_TX_LASER */
4456         DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
4457         /* For 20G, the expected pin to be used is 3 pins after the current */
4458
4459         bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
4460         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
4461                 bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
4462 }
4463
4464 static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
4465                                       struct link_params *params)
4466 {
4467         struct bnx2x *bp = params->bp;
4468         u16 val16;
4469         bnx2x_sfp_e3_set_transmitter(params, phy, 0);
4470         bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
4471         bnx2x_set_aer_mmd(params, phy);
4472         /* Global register */
4473         bnx2x_warpcore_reset_lane(bp, phy, 1);
4474
4475         /* Clear loopback settings (if any) */
4476         /* 10G & 20G */
4477         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4478                         MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4479         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4480                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 &
4481                          0xBFFF);
4482
4483         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4484                         MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4485         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4486                         MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe);
4487
4488         /* Update those 1-copy registers */
4489         CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4490                           MDIO_AER_BLOCK_AER_REG, 0);
4491                 /* Enable 1G MDIO (1-copy) */
4492         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4493                         MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4494                         &val16);
4495         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4496                          MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4497                          val16 & ~0x10);
4498
4499         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4500                         MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4501         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4502                          MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4503                          val16 & 0xff00);
4504
4505 }
4506
4507 static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
4508                                         struct link_params *params)
4509 {
4510         struct bnx2x *bp = params->bp;
4511         u16 val16;
4512         u32 lane;
4513         DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
4514                        params->loopback_mode, phy->req_line_speed);
4515
4516         if (phy->req_line_speed < SPEED_10000) {
4517                 /* 10/100/1000 */
4518
4519                 /* Update those 1-copy registers */
4520                 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4521                                   MDIO_AER_BLOCK_AER_REG, 0);
4522                 /* Enable 1G MDIO (1-copy) */
4523                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4524                                 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4525                                 &val16);
4526                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4527                                 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4528                                 val16 | 0x10);
4529                 /* Set 1G loopback based on lane (1-copy) */
4530                 lane = bnx2x_get_warpcore_lane(phy, params);
4531                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4532                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4533                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4534                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4535                                 val16 | (1<<lane));
4536
4537                 /* Switch back to 4-copy registers */
4538                 bnx2x_set_aer_mmd(params, phy);
4539         } else {
4540                 /* 10G & 20G */
4541                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4542                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4543                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4544                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
4545                                  0x4000);
4546
4547                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4548                                 MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4549                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4550                                 MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1);
4551         }
4552 }
4553
4554
4555 void bnx2x_sync_link(struct link_params *params,
4556                            struct link_vars *vars)
4557 {
4558         struct bnx2x *bp = params->bp;
4559         u8 link_10g_plus;
4560         if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4561                 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
4562         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4563         if (vars->link_up) {
4564                 DP(NETIF_MSG_LINK, "phy link up\n");
4565
4566                 vars->phy_link_up = 1;
4567                 vars->duplex = DUPLEX_FULL;
4568                 switch (vars->link_status &
4569                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
4570                         case LINK_10THD:
4571                                 vars->duplex = DUPLEX_HALF;
4572                                 /* fall thru */
4573                         case LINK_10TFD:
4574                                 vars->line_speed = SPEED_10;
4575                                 break;
4576
4577                         case LINK_100TXHD:
4578                                 vars->duplex = DUPLEX_HALF;
4579                                 /* fall thru */
4580                         case LINK_100T4:
4581                         case LINK_100TXFD:
4582                                 vars->line_speed = SPEED_100;
4583                                 break;
4584
4585                         case LINK_1000THD:
4586                                 vars->duplex = DUPLEX_HALF;
4587                                 /* fall thru */
4588                         case LINK_1000TFD:
4589                                 vars->line_speed = SPEED_1000;
4590                                 break;
4591
4592                         case LINK_2500THD:
4593                                 vars->duplex = DUPLEX_HALF;
4594                                 /* fall thru */
4595                         case LINK_2500TFD:
4596                                 vars->line_speed = SPEED_2500;
4597                                 break;
4598
4599                         case LINK_10GTFD:
4600                                 vars->line_speed = SPEED_10000;
4601                                 break;
4602                         case LINK_20GTFD:
4603                                 vars->line_speed = SPEED_20000;
4604                                 break;
4605                         default:
4606                                 break;
4607                 }
4608                 vars->flow_ctrl = 0;
4609                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
4610                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
4611
4612                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
4613                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
4614
4615                 if (!vars->flow_ctrl)
4616                         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4617
4618                 if (vars->line_speed &&
4619                     ((vars->line_speed == SPEED_10) ||
4620                      (vars->line_speed == SPEED_100))) {
4621                         vars->phy_flags |= PHY_SGMII_FLAG;
4622                 } else {
4623                         vars->phy_flags &= ~PHY_SGMII_FLAG;
4624                 }
4625                 if (vars->line_speed &&
4626                     USES_WARPCORE(bp) &&
4627                     (vars->line_speed == SPEED_1000))
4628                         vars->phy_flags |= PHY_SGMII_FLAG;
4629                 /* anything 10 and over uses the bmac */
4630                 link_10g_plus = (vars->line_speed >= SPEED_10000);
4631
4632                 if (link_10g_plus) {
4633                         if (USES_WARPCORE(bp))
4634                                 vars->mac_type = MAC_TYPE_XMAC;
4635                         else
4636                                 vars->mac_type = MAC_TYPE_BMAC;
4637                 } else {
4638                         if (USES_WARPCORE(bp))
4639                                 vars->mac_type = MAC_TYPE_UMAC;
4640                         else
4641                                 vars->mac_type = MAC_TYPE_EMAC;
4642                 }
4643         } else { /* link down */
4644                 DP(NETIF_MSG_LINK, "phy link down\n");
4645
4646                 vars->phy_link_up = 0;
4647
4648                 vars->line_speed = 0;
4649                 vars->duplex = DUPLEX_FULL;
4650                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4651
4652                 /* indicate no mac active */
4653                 vars->mac_type = MAC_TYPE_NONE;
4654                 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4655                         vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
4656         }
4657 }
4658
4659 void bnx2x_link_status_update(struct link_params *params,
4660                               struct link_vars *vars)
4661 {
4662         struct bnx2x *bp = params->bp;
4663         u8 port = params->port;
4664         u32 sync_offset, media_types;
4665         /* Update PHY configuration */
4666         set_phy_vars(params, vars);
4667
4668         vars->link_status = REG_RD(bp, params->shmem_base +
4669                                    offsetof(struct shmem_region,
4670                                             port_mb[port].link_status));
4671
4672         vars->phy_flags = PHY_XGXS_FLAG;
4673         bnx2x_sync_link(params, vars);
4674         /* Sync media type */
4675         sync_offset = params->shmem_base +
4676                         offsetof(struct shmem_region,
4677                                  dev_info.port_hw_config[port].media_type);
4678         media_types = REG_RD(bp, sync_offset);
4679
4680         params->phy[INT_PHY].media_type =
4681                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
4682                 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
4683         params->phy[EXT_PHY1].media_type =
4684                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
4685                 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
4686         params->phy[EXT_PHY2].media_type =
4687                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
4688                 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
4689         DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
4690
4691         /* Sync AEU offset */
4692         sync_offset = params->shmem_base +
4693                         offsetof(struct shmem_region,
4694                                  dev_info.port_hw_config[port].aeu_int_mask);
4695
4696         vars->aeu_int_mask = REG_RD(bp, sync_offset);
4697
4698         /* Sync PFC status */
4699         if (vars->link_status & LINK_STATUS_PFC_ENABLED)
4700                 params->feature_config_flags |=
4701                                         FEATURE_CONFIG_PFC_ENABLED;
4702         else
4703                 params->feature_config_flags &=
4704                                         ~FEATURE_CONFIG_PFC_ENABLED;
4705
4706         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
4707                  vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
4708         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
4709                  vars->line_speed, vars->duplex, vars->flow_ctrl);
4710 }
4711
4712 static void bnx2x_set_master_ln(struct link_params *params,
4713                                 struct bnx2x_phy *phy)
4714 {
4715         struct bnx2x *bp = params->bp;
4716         u16 new_master_ln, ser_lane;
4717         ser_lane = ((params->lane_config &
4718                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4719                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4720
4721         /* set the master_ln for AN */
4722         CL22_RD_OVER_CL45(bp, phy,
4723                           MDIO_REG_BANK_XGXS_BLOCK2,
4724                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4725                           &new_master_ln);
4726
4727         CL22_WR_OVER_CL45(bp, phy,
4728                           MDIO_REG_BANK_XGXS_BLOCK2 ,
4729                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4730                           (new_master_ln | ser_lane));
4731 }
4732
4733 static int bnx2x_reset_unicore(struct link_params *params,
4734                                struct bnx2x_phy *phy,
4735                                u8 set_serdes)
4736 {
4737         struct bnx2x *bp = params->bp;
4738         u16 mii_control;
4739         u16 i;
4740         CL22_RD_OVER_CL45(bp, phy,
4741                           MDIO_REG_BANK_COMBO_IEEE0,
4742                           MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4743
4744         /* reset the unicore */
4745         CL22_WR_OVER_CL45(bp, phy,
4746                           MDIO_REG_BANK_COMBO_IEEE0,
4747                           MDIO_COMBO_IEEE0_MII_CONTROL,
4748                           (mii_control |
4749                            MDIO_COMBO_IEEO_MII_CONTROL_RESET));
4750         if (set_serdes)
4751                 bnx2x_set_serdes_access(bp, params->port);
4752
4753         /* wait for the reset to self clear */
4754         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
4755                 udelay(5);
4756
4757                 /* the reset erased the previous bank value */
4758                 CL22_RD_OVER_CL45(bp, phy,
4759                                   MDIO_REG_BANK_COMBO_IEEE0,
4760                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4761                                   &mii_control);
4762
4763                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
4764                         udelay(5);
4765                         return 0;
4766                 }
4767         }
4768
4769         netdev_err(bp->dev,  "Warning: PHY was not initialized,"
4770                               " Port %d\n",
4771                          params->port);
4772         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
4773         return -EINVAL;
4774
4775 }
4776
4777 static void bnx2x_set_swap_lanes(struct link_params *params,
4778                                  struct bnx2x_phy *phy)
4779 {
4780         struct bnx2x *bp = params->bp;
4781         /*
4782          *  Each two bits represents a lane number:
4783          *  No swap is 0123 => 0x1b no need to enable the swap
4784          */
4785         u16 rx_lane_swap, tx_lane_swap;
4786
4787         rx_lane_swap = ((params->lane_config &
4788                          PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
4789                         PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
4790         tx_lane_swap = ((params->lane_config &
4791                          PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
4792                         PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
4793
4794         if (rx_lane_swap != 0x1b) {
4795                 CL22_WR_OVER_CL45(bp, phy,
4796                                   MDIO_REG_BANK_XGXS_BLOCK2,
4797                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP,
4798                                   (rx_lane_swap |
4799                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
4800                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
4801         } else {
4802                 CL22_WR_OVER_CL45(bp, phy,
4803                                   MDIO_REG_BANK_XGXS_BLOCK2,
4804                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
4805         }
4806
4807         if (tx_lane_swap != 0x1b) {
4808                 CL22_WR_OVER_CL45(bp, phy,
4809                                   MDIO_REG_BANK_XGXS_BLOCK2,
4810                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP,
4811                                   (tx_lane_swap |
4812                                    MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
4813         } else {
4814                 CL22_WR_OVER_CL45(bp, phy,
4815                                   MDIO_REG_BANK_XGXS_BLOCK2,
4816                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
4817         }
4818 }
4819
4820 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
4821                                          struct link_params *params)
4822 {
4823         struct bnx2x *bp = params->bp;
4824         u16 control2;
4825         CL22_RD_OVER_CL45(bp, phy,
4826                           MDIO_REG_BANK_SERDES_DIGITAL,
4827                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4828                           &control2);
4829         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4830                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4831         else
4832                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4833         DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
4834                 phy->speed_cap_mask, control2);
4835         CL22_WR_OVER_CL45(bp, phy,
4836                           MDIO_REG_BANK_SERDES_DIGITAL,
4837                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4838                           control2);
4839
4840         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4841              (phy->speed_cap_mask &
4842                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4843                 DP(NETIF_MSG_LINK, "XGXS\n");
4844
4845                 CL22_WR_OVER_CL45(bp, phy,
4846                                  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4847                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
4848                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
4849
4850                 CL22_RD_OVER_CL45(bp, phy,
4851                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
4852                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4853                                   &control2);
4854
4855
4856                 control2 |=
4857                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
4858
4859                 CL22_WR_OVER_CL45(bp, phy,
4860                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
4861                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4862                                   control2);
4863
4864                 /* Disable parallel detection of HiG */
4865                 CL22_WR_OVER_CL45(bp, phy,
4866                                   MDIO_REG_BANK_XGXS_BLOCK2,
4867                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
4868                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
4869                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
4870         }
4871 }
4872
4873 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
4874                               struct link_params *params,
4875                               struct link_vars *vars,
4876                               u8 enable_cl73)
4877 {
4878         struct bnx2x *bp = params->bp;
4879         u16 reg_val;
4880
4881         /* CL37 Autoneg */
4882         CL22_RD_OVER_CL45(bp, phy,
4883                           MDIO_REG_BANK_COMBO_IEEE0,
4884                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4885
4886         /* CL37 Autoneg Enabled */
4887         if (vars->line_speed == SPEED_AUTO_NEG)
4888                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
4889         else /* CL37 Autoneg Disabled */
4890                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4891                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
4892
4893         CL22_WR_OVER_CL45(bp, phy,
4894                           MDIO_REG_BANK_COMBO_IEEE0,
4895                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4896
4897         /* Enable/Disable Autodetection */
4898
4899         CL22_RD_OVER_CL45(bp, phy,
4900                           MDIO_REG_BANK_SERDES_DIGITAL,
4901                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
4902         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
4903                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
4904         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
4905         if (vars->line_speed == SPEED_AUTO_NEG)
4906                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4907         else
4908                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4909
4910         CL22_WR_OVER_CL45(bp, phy,
4911                           MDIO_REG_BANK_SERDES_DIGITAL,
4912                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
4913
4914         /* Enable TetonII and BAM autoneg */
4915         CL22_RD_OVER_CL45(bp, phy,
4916                           MDIO_REG_BANK_BAM_NEXT_PAGE,
4917                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4918                           &reg_val);
4919         if (vars->line_speed == SPEED_AUTO_NEG) {
4920                 /* Enable BAM aneg Mode and TetonII aneg Mode */
4921                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4922                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4923         } else {
4924                 /* TetonII and BAM Autoneg Disabled */
4925                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4926                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4927         }
4928         CL22_WR_OVER_CL45(bp, phy,
4929                           MDIO_REG_BANK_BAM_NEXT_PAGE,
4930                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4931                           reg_val);
4932
4933         if (enable_cl73) {
4934                 /* Enable Cl73 FSM status bits */
4935                 CL22_WR_OVER_CL45(bp, phy,
4936                                   MDIO_REG_BANK_CL73_USERB0,
4937                                   MDIO_CL73_USERB0_CL73_UCTRL,
4938                                   0xe);
4939
4940                 /* Enable BAM Station Manager*/
4941                 CL22_WR_OVER_CL45(bp, phy,
4942                         MDIO_REG_BANK_CL73_USERB0,
4943                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
4944                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
4945                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
4946                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
4947
4948                 /* Advertise CL73 link speeds */
4949                 CL22_RD_OVER_CL45(bp, phy,
4950                                   MDIO_REG_BANK_CL73_IEEEB1,
4951                                   MDIO_CL73_IEEEB1_AN_ADV2,
4952                                   &reg_val);
4953                 if (phy->speed_cap_mask &
4954                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4955                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
4956                 if (phy->speed_cap_mask &
4957                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4958                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
4959
4960                 CL22_WR_OVER_CL45(bp, phy,
4961                                   MDIO_REG_BANK_CL73_IEEEB1,
4962                                   MDIO_CL73_IEEEB1_AN_ADV2,
4963                                   reg_val);
4964
4965                 /* CL73 Autoneg Enabled */
4966                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
4967
4968         } else /* CL73 Autoneg Disabled */
4969                 reg_val = 0;
4970
4971         CL22_WR_OVER_CL45(bp, phy,
4972                           MDIO_REG_BANK_CL73_IEEEB0,
4973                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
4974 }
4975
4976 /* program SerDes, forced speed */
4977 static void bnx2x_program_serdes(struct bnx2x_phy *phy,
4978                                  struct link_params *params,
4979                                  struct link_vars *vars)
4980 {
4981         struct bnx2x *bp = params->bp;
4982         u16 reg_val;
4983
4984         /* program duplex, disable autoneg and sgmii*/
4985         CL22_RD_OVER_CL45(bp, phy,
4986                           MDIO_REG_BANK_COMBO_IEEE0,
4987                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4988         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
4989                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4990                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
4991         if (phy->req_duplex == DUPLEX_FULL)
4992                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
4993         CL22_WR_OVER_CL45(bp, phy,
4994                           MDIO_REG_BANK_COMBO_IEEE0,
4995                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4996
4997         /*
4998          * program speed
4999          *  - needed only if the speed is greater than 1G (2.5G or 10G)
5000          */
5001         CL22_RD_OVER_CL45(bp, phy,
5002                           MDIO_REG_BANK_SERDES_DIGITAL,
5003                           MDIO_SERDES_DIGITAL_MISC1, &reg_val);
5004         /* clearing the speed value before setting the right speed */
5005         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
5006
5007         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
5008                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
5009
5010         if (!((vars->line_speed == SPEED_1000) ||
5011               (vars->line_speed == SPEED_100) ||
5012               (vars->line_speed == SPEED_10))) {
5013
5014                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
5015                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
5016                 if (vars->line_speed == SPEED_10000)
5017                         reg_val |=
5018                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
5019         }
5020
5021         CL22_WR_OVER_CL45(bp, phy,
5022                           MDIO_REG_BANK_SERDES_DIGITAL,
5023                           MDIO_SERDES_DIGITAL_MISC1, reg_val);
5024
5025 }
5026
5027 static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy,
5028                                               struct link_params *params)
5029 {
5030         struct bnx2x *bp = params->bp;
5031         u16 val = 0;
5032
5033         /* configure the 48 bits for BAM AN */
5034
5035         /* set extended capabilities */
5036         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
5037                 val |= MDIO_OVER_1G_UP1_2_5G;
5038         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5039                 val |= MDIO_OVER_1G_UP1_10G;
5040         CL22_WR_OVER_CL45(bp, phy,
5041                           MDIO_REG_BANK_OVER_1G,
5042                           MDIO_OVER_1G_UP1, val);
5043
5044         CL22_WR_OVER_CL45(bp, phy,
5045                           MDIO_REG_BANK_OVER_1G,
5046                           MDIO_OVER_1G_UP3, 0x400);
5047 }
5048
5049 static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy,
5050                                               struct link_params *params,
5051                                               u16 ieee_fc)
5052 {
5053         struct bnx2x *bp = params->bp;
5054         u16 val;
5055         /* for AN, we are always publishing full duplex */
5056
5057         CL22_WR_OVER_CL45(bp, phy,
5058                           MDIO_REG_BANK_COMBO_IEEE0,
5059                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
5060         CL22_RD_OVER_CL45(bp, phy,
5061                           MDIO_REG_BANK_CL73_IEEEB1,
5062                           MDIO_CL73_IEEEB1_AN_ADV1, &val);
5063         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
5064         val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
5065         CL22_WR_OVER_CL45(bp, phy,
5066                           MDIO_REG_BANK_CL73_IEEEB1,
5067                           MDIO_CL73_IEEEB1_AN_ADV1, val);
5068 }
5069
5070 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
5071                                   struct link_params *params,
5072                                   u8 enable_cl73)
5073 {
5074         struct bnx2x *bp = params->bp;
5075         u16 mii_control;
5076
5077         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
5078         /* Enable and restart BAM/CL37 aneg */
5079
5080         if (enable_cl73) {
5081                 CL22_RD_OVER_CL45(bp, phy,
5082                                   MDIO_REG_BANK_CL73_IEEEB0,
5083                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5084                                   &mii_control);
5085
5086                 CL22_WR_OVER_CL45(bp, phy,
5087                                   MDIO_REG_BANK_CL73_IEEEB0,
5088                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5089                                   (mii_control |
5090                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
5091                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
5092         } else {
5093
5094                 CL22_RD_OVER_CL45(bp, phy,
5095                                   MDIO_REG_BANK_COMBO_IEEE0,
5096                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5097                                   &mii_control);
5098                 DP(NETIF_MSG_LINK,
5099                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
5100                          mii_control);
5101                 CL22_WR_OVER_CL45(bp, phy,
5102                                   MDIO_REG_BANK_COMBO_IEEE0,
5103                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5104                                   (mii_control |
5105                                    MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5106                                    MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
5107         }
5108 }
5109
5110 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
5111                                            struct link_params *params,
5112                                            struct link_vars *vars)
5113 {
5114         struct bnx2x *bp = params->bp;
5115         u16 control1;
5116
5117         /* in SGMII mode, the unicore is always slave */
5118
5119         CL22_RD_OVER_CL45(bp, phy,
5120                           MDIO_REG_BANK_SERDES_DIGITAL,
5121                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
5122                           &control1);
5123         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
5124         /* set sgmii mode (and not fiber) */
5125         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
5126                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
5127                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
5128         CL22_WR_OVER_CL45(bp, phy,
5129                           MDIO_REG_BANK_SERDES_DIGITAL,
5130                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
5131                           control1);
5132
5133         /* if forced speed */
5134         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
5135                 /* set speed, disable autoneg */
5136                 u16 mii_control;
5137
5138                 CL22_RD_OVER_CL45(bp, phy,
5139                                   MDIO_REG_BANK_COMBO_IEEE0,
5140                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5141                                   &mii_control);
5142                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5143                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
5144                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
5145
5146                 switch (vars->line_speed) {
5147                 case SPEED_100:
5148                         mii_control |=
5149                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
5150                         break;
5151                 case SPEED_1000:
5152                         mii_control |=
5153                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
5154                         break;
5155                 case SPEED_10:
5156                         /* there is nothing to set for 10M */
5157                         break;
5158                 default:
5159                         /* invalid speed for SGMII */
5160                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5161                                   vars->line_speed);
5162                         break;
5163                 }
5164
5165                 /* setting the full duplex */
5166                 if (phy->req_duplex == DUPLEX_FULL)
5167                         mii_control |=
5168                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5169                 CL22_WR_OVER_CL45(bp, phy,
5170                                   MDIO_REG_BANK_COMBO_IEEE0,
5171                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5172                                   mii_control);
5173
5174         } else { /* AN mode */
5175                 /* enable and restart AN */
5176                 bnx2x_restart_autoneg(phy, params, 0);
5177         }
5178 }
5179
5180
5181 /*
5182  * link management
5183  */
5184
5185 static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
5186                                              struct link_params *params)
5187 {
5188         struct bnx2x *bp = params->bp;
5189         u16 pd_10g, status2_1000x;
5190         if (phy->req_line_speed != SPEED_AUTO_NEG)
5191                 return 0;
5192         CL22_RD_OVER_CL45(bp, phy,
5193                           MDIO_REG_BANK_SERDES_DIGITAL,
5194                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5195                           &status2_1000x);
5196         CL22_RD_OVER_CL45(bp, phy,
5197                           MDIO_REG_BANK_SERDES_DIGITAL,
5198                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5199                           &status2_1000x);
5200         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
5201                 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
5202                          params->port);
5203                 return 1;
5204         }
5205
5206         CL22_RD_OVER_CL45(bp, phy,
5207                           MDIO_REG_BANK_10G_PARALLEL_DETECT,
5208                           MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
5209                           &pd_10g);
5210
5211         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
5212                 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
5213                          params->port);
5214                 return 1;
5215         }
5216         return 0;
5217 }
5218
5219 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
5220                                     struct link_params *params,
5221                                     struct link_vars *vars,
5222                                     u32 gp_status)
5223 {
5224         struct bnx2x *bp = params->bp;
5225         u16 ld_pause;   /* local driver */
5226         u16 lp_pause;   /* link partner */
5227         u16 pause_result;
5228
5229         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5230
5231         /* resolve from gp_status in case of AN complete and not sgmii */
5232         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
5233                 vars->flow_ctrl = phy->req_flow_ctrl;
5234         else if (phy->req_line_speed != SPEED_AUTO_NEG)
5235                 vars->flow_ctrl = params->req_fc_auto_adv;
5236         else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
5237                  (!(vars->phy_flags & PHY_SGMII_FLAG))) {
5238                 if (bnx2x_direct_parallel_detect_used(phy, params)) {
5239                         vars->flow_ctrl = params->req_fc_auto_adv;
5240                         return;
5241                 }
5242                 if ((gp_status &
5243                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5244                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
5245                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5246                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
5247
5248                         CL22_RD_OVER_CL45(bp, phy,
5249                                           MDIO_REG_BANK_CL73_IEEEB1,
5250                                           MDIO_CL73_IEEEB1_AN_ADV1,
5251                                           &ld_pause);
5252                         CL22_RD_OVER_CL45(bp, phy,
5253                                           MDIO_REG_BANK_CL73_IEEEB1,
5254                                           MDIO_CL73_IEEEB1_AN_LP_ADV1,
5255                                           &lp_pause);
5256                         pause_result = (ld_pause &
5257                                         MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
5258                                         >> 8;
5259                         pause_result |= (lp_pause &
5260                                         MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
5261                                         >> 10;
5262                         DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
5263                                  pause_result);
5264                 } else {
5265                         CL22_RD_OVER_CL45(bp, phy,
5266                                           MDIO_REG_BANK_COMBO_IEEE0,
5267                                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
5268                                           &ld_pause);
5269                         CL22_RD_OVER_CL45(bp, phy,
5270                                 MDIO_REG_BANK_COMBO_IEEE0,
5271                                 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
5272                                 &lp_pause);
5273                         pause_result = (ld_pause &
5274                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
5275                         pause_result |= (lp_pause &
5276                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
5277                         DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
5278                                  pause_result);
5279                 }
5280                 bnx2x_pause_resolve(vars, pause_result);
5281         }
5282         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
5283 }
5284
5285 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
5286                                          struct link_params *params)
5287 {
5288         struct bnx2x *bp = params->bp;
5289         u16 rx_status, ustat_val, cl37_fsm_received;
5290         DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
5291         /* Step 1: Make sure signal is detected */
5292         CL22_RD_OVER_CL45(bp, phy,
5293                           MDIO_REG_BANK_RX0,
5294                           MDIO_RX0_RX_STATUS,
5295                           &rx_status);
5296         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
5297             (MDIO_RX0_RX_STATUS_SIGDET)) {
5298                 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
5299                              "rx_status(0x80b0) = 0x%x\n", rx_status);
5300                 CL22_WR_OVER_CL45(bp, phy,
5301                                   MDIO_REG_BANK_CL73_IEEEB0,
5302                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5303                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
5304                 return;
5305         }
5306         /* Step 2: Check CL73 state machine */
5307         CL22_RD_OVER_CL45(bp, phy,
5308                           MDIO_REG_BANK_CL73_USERB0,
5309                           MDIO_CL73_USERB0_CL73_USTAT1,
5310                           &ustat_val);
5311         if ((ustat_val &
5312              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5313               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
5314             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5315               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
5316                 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
5317                              "ustat_val(0x8371) = 0x%x\n", ustat_val);
5318                 return;
5319         }
5320         /*
5321          * Step 3: Check CL37 Message Pages received to indicate LP
5322          * supports only CL37
5323          */
5324         CL22_RD_OVER_CL45(bp, phy,
5325                           MDIO_REG_BANK_REMOTE_PHY,
5326                           MDIO_REMOTE_PHY_MISC_RX_STATUS,
5327                           &cl37_fsm_received);
5328         if ((cl37_fsm_received &
5329              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5330              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
5331             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5332               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
5333                 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
5334                              "misc_rx_status(0x8330) = 0x%x\n",
5335                          cl37_fsm_received);
5336                 return;
5337         }
5338         /*
5339          * The combined cl37/cl73 fsm state information indicating that
5340          * we are connected to a device which does not support cl73, but
5341          * does support cl37 BAM. In this case we disable cl73 and
5342          * restart cl37 auto-neg
5343          */
5344
5345         /* Disable CL73 */
5346         CL22_WR_OVER_CL45(bp, phy,
5347                           MDIO_REG_BANK_CL73_IEEEB0,
5348                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5349                           0);
5350         /* Restart CL37 autoneg */
5351         bnx2x_restart_autoneg(phy, params, 0);
5352         DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
5353 }
5354
5355 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
5356                                   struct link_params *params,
5357                                   struct link_vars *vars,
5358                                   u32 gp_status)
5359 {
5360         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
5361                 vars->link_status |=
5362                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5363
5364         if (bnx2x_direct_parallel_detect_used(phy, params))
5365                 vars->link_status |=
5366                         LINK_STATUS_PARALLEL_DETECTION_USED;
5367 }
5368 static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
5369                                      struct link_params *params,
5370                                       struct link_vars *vars,
5371                                       u16 is_link_up,
5372                                       u16 speed_mask,
5373                                       u16 is_duplex)
5374 {
5375         struct bnx2x *bp = params->bp;
5376         if (phy->req_line_speed == SPEED_AUTO_NEG)
5377                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
5378         if (is_link_up) {
5379                 DP(NETIF_MSG_LINK, "phy link up\n");
5380
5381                 vars->phy_link_up = 1;
5382                 vars->link_status |= LINK_STATUS_LINK_UP;
5383
5384                 switch (speed_mask) {
5385                 case GP_STATUS_10M:
5386                         vars->line_speed = SPEED_10;
5387                         if (vars->duplex == DUPLEX_FULL)
5388                                 vars->link_status |= LINK_10TFD;
5389                         else
5390                                 vars->link_status |= LINK_10THD;
5391                         break;
5392
5393                 case GP_STATUS_100M:
5394                         vars->line_speed = SPEED_100;
5395                         if (vars->duplex == DUPLEX_FULL)
5396                                 vars->link_status |= LINK_100TXFD;
5397                         else
5398                                 vars->link_status |= LINK_100TXHD;
5399                         break;
5400
5401                 case GP_STATUS_1G:
5402                 case GP_STATUS_1G_KX:
5403                         vars->line_speed = SPEED_1000;
5404                         if (vars->duplex == DUPLEX_FULL)
5405                                 vars->link_status |= LINK_1000TFD;
5406                         else
5407                                 vars->link_status |= LINK_1000THD;
5408                         break;
5409
5410                 case GP_STATUS_2_5G:
5411                         vars->line_speed = SPEED_2500;
5412                         if (vars->duplex == DUPLEX_FULL)
5413                                 vars->link_status |= LINK_2500TFD;
5414                         else
5415                                 vars->link_status |= LINK_2500THD;
5416                         break;
5417
5418                 case GP_STATUS_5G:
5419                 case GP_STATUS_6G:
5420                         DP(NETIF_MSG_LINK,
5421                                  "link speed unsupported  gp_status 0x%x\n",
5422                                   speed_mask);
5423                         return -EINVAL;
5424
5425                 case GP_STATUS_10G_KX4:
5426                 case GP_STATUS_10G_HIG:
5427                 case GP_STATUS_10G_CX4:
5428                 case GP_STATUS_10G_KR:
5429                 case GP_STATUS_10G_SFI:
5430                 case GP_STATUS_10G_XFI:
5431                         vars->line_speed = SPEED_10000;
5432                         vars->link_status |= LINK_10GTFD;
5433                         break;
5434                 case GP_STATUS_20G_DXGXS:
5435                         vars->line_speed = SPEED_20000;
5436                         vars->link_status |= LINK_20GTFD;
5437                         break;
5438                 default:
5439                         DP(NETIF_MSG_LINK,
5440                                   "link speed unsupported gp_status 0x%x\n",
5441                                   speed_mask);
5442                         return -EINVAL;
5443                 }
5444         } else { /* link_down */
5445                 DP(NETIF_MSG_LINK, "phy link down\n");
5446
5447                 vars->phy_link_up = 0;
5448
5449                 vars->duplex = DUPLEX_FULL;
5450                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5451                 vars->mac_type = MAC_TYPE_NONE;
5452         }
5453         DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n",
5454                     vars->phy_link_up, vars->line_speed);
5455         return 0;
5456 }
5457
5458 static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
5459                                       struct link_params *params,
5460                                       struct link_vars *vars)
5461 {
5462         struct bnx2x *bp = params->bp;
5463
5464         u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
5465         int rc = 0;
5466
5467         /* Read gp_status */
5468         CL22_RD_OVER_CL45(bp, phy,
5469                           MDIO_REG_BANK_GP_STATUS,
5470                           MDIO_GP_STATUS_TOP_AN_STATUS1,
5471                           &gp_status);
5472         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
5473                 duplex = DUPLEX_FULL;
5474         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
5475                 link_up = 1;
5476         speed_mask = gp_status & GP_STATUS_SPEED_MASK;
5477         DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
5478                        gp_status, link_up, speed_mask);
5479         rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
5480