a6c48d61081a5fe8345a66d41f59da1f5d7c80b2
[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         vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
3767
3768         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3769                         MDIO_WC_REG_DIGITAL5_MISC7, &val16);
3770
3771         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3772                          MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100);
3773
3774         /* Over 1G - AN local device user page 1 */
3775         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3776                         MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
3777
3778         /* Enable Autoneg */
3779         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3780                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000);
3781
3782 }
3783
3784 static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
3785                                       struct link_params *params,
3786                                       struct link_vars *vars)
3787 {
3788         struct bnx2x *bp = params->bp;
3789         u16 val;
3790
3791         /* Disable Autoneg */
3792         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3793                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
3794
3795         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3796                          MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
3797
3798         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3799                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00);
3800
3801         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3802                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0);
3803
3804         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3805                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3806
3807         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3808                         MDIO_WC_REG_DIGITAL3_UP1, 0x1);
3809
3810         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3811                          MDIO_WC_REG_DIGITAL5_MISC7, 0xa);
3812
3813         /* Disable CL36 PCS Tx */
3814         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3815                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0);
3816
3817         /* Double Wide Single Data Rate @ pll rate */
3818         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3819                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF);
3820
3821         /* Leave cl72 training enable, needed for KR */
3822         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3823                 MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
3824                 0x2);
3825
3826         /* Leave CL72 enabled */
3827         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3828                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3829                          &val);
3830         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3831                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3832                          val | 0x3800);
3833
3834         /* Set speed via PMA/PMD register */
3835         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3836                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3837
3838         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3839                          MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
3840
3841         /*Enable encoded forced speed */
3842         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3843                          MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
3844
3845         /* Turn TX scramble payload only the 64/66 scrambler */
3846         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3847                          MDIO_WC_REG_TX66_CONTROL, 0x9);
3848
3849         /* Turn RX scramble payload only the 64/66 scrambler */
3850         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3851                                  MDIO_WC_REG_RX66_CONTROL, 0xF9);
3852
3853         /* set and clear loopback to cause a reset to 64/66 decoder */
3854         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3855                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
3856         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3857                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3858
3859 }
3860
3861 static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
3862                                        struct link_params *params,
3863                                        u8 is_xfi)
3864 {
3865         struct bnx2x *bp = params->bp;
3866         u16 misc1_val, tap_val, tx_driver_val, lane, val;
3867         /* Hold rxSeqStart */
3868         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3869                         MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3870         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3871                          MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000));
3872
3873         /* Hold tx_fifo_reset */
3874         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3875                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3876         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3877                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1));
3878
3879         /* Disable CL73 AN */
3880         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3881
3882         /* Disable 100FX Enable and Auto-Detect */
3883         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3884                         MDIO_WC_REG_FX100_CTRL1, &val);
3885         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3886                          MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA));
3887
3888         /* Disable 100FX Idle detect */
3889         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3890                         MDIO_WC_REG_FX100_CTRL3, &val);
3891         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3892                          MDIO_WC_REG_FX100_CTRL3, (val | 0x0080));
3893
3894         /* Set Block address to Remote PHY & Clear forced_speed[5] */
3895         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3896                         MDIO_WC_REG_DIGITAL4_MISC3, &val);
3897         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3898                          MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F));
3899
3900         /* Turn off auto-detect & fiber mode */
3901         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3902                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3903         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3904                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3905                          (val & 0xFFEE));
3906
3907         /* Set filter_force_link, disable_false_link and parallel_detect */
3908         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3909                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
3910         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3911                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3912                          ((val | 0x0006) & 0xFFFE));
3913
3914         /* Set XFI / SFI */
3915         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3916                         MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
3917
3918         misc1_val &= ~(0x1f);
3919
3920         if (is_xfi) {
3921                 misc1_val |= 0x5;
3922                 tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3923                            (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3924                            (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3925                 tx_driver_val =
3926                       ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3927                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3928                        (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3929
3930         } else {
3931                 misc1_val |= 0x9;
3932                 tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3933                            (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3934                            (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3935                 tx_driver_val =
3936                       ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3937                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3938                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3939         }
3940         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3941                          MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
3942
3943         /* Set Transmit PMD settings */
3944         lane = bnx2x_get_warpcore_lane(phy, params);
3945         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3946                          MDIO_WC_REG_TX_FIR_TAP,
3947                          tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
3948         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3949                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3950                          tx_driver_val);
3951
3952         /* Enable fiber mode, enable and invert sig_det */
3953         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3954                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3955         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3956                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd);
3957
3958         /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
3959         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3960                         MDIO_WC_REG_DIGITAL4_MISC3, &val);
3961         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3962                          MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
3963
3964         /* 10G XFI Full Duplex */
3965         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3966                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
3967
3968         /* Release tx_fifo_reset */
3969         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3970                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3971         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3972                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE);
3973
3974         /* Release rxSeqStart */
3975         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3976                         MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3977         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3978                          MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF));
3979 }
3980
3981 static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp,
3982                                        struct bnx2x_phy *phy)
3983 {
3984         DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n");
3985 }
3986
3987 static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
3988                                          struct bnx2x_phy *phy,
3989                                          u16 lane)
3990 {
3991         /* Rx0 anaRxControl1G */
3992         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3993                          MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
3994
3995         /* Rx2 anaRxControl1G */
3996         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3997                          MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
3998
3999         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4000                          MDIO_WC_REG_RX66_SCW0, 0xE070);
4001
4002         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4003                          MDIO_WC_REG_RX66_SCW1, 0xC0D0);
4004
4005         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4006                          MDIO_WC_REG_RX66_SCW2, 0xA0B0);
4007
4008         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4009                          MDIO_WC_REG_RX66_SCW3, 0x8090);
4010
4011         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4012                          MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
4013
4014         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4015                          MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
4016
4017         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4018                          MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
4019
4020         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4021                          MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
4022
4023         /* Serdes Digital Misc1 */
4024         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4025                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
4026
4027         /* Serdes Digital4 Misc3 */
4028         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4029                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
4030
4031         /* Set Transmit PMD settings */
4032         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4033                          MDIO_WC_REG_TX_FIR_TAP,
4034                         ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
4035                          (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
4036                          (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
4037                          MDIO_WC_REG_TX_FIR_TAP_ENABLE));
4038         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4039                       MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
4040                      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
4041                       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
4042                       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
4043 }
4044
4045 static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
4046                                            struct link_params *params,
4047                                            u8 fiber_mode,
4048                                            u8 always_autoneg)
4049 {
4050         struct bnx2x *bp = params->bp;
4051         u16 val16, digctrl_kx1, digctrl_kx2;
4052
4053         /* Clear XFI clock comp in non-10G single lane mode. */
4054         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4055                         MDIO_WC_REG_RX66_CONTROL, &val16);
4056         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4057                          MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
4058
4059         if (always_autoneg || phy->req_line_speed == SPEED_AUTO_NEG) {
4060                 /* SGMII Autoneg */
4061                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4062                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4063                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4064                                  MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
4065                                  val16 | 0x1000);
4066                 DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
4067         } else {
4068                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4069                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4070                 val16 &= 0xcebf;
4071                 switch (phy->req_line_speed) {
4072                 case SPEED_10:
4073                         break;
4074                 case SPEED_100:
4075                         val16 |= 0x2000;
4076                         break;
4077                 case SPEED_1000:
4078                         val16 |= 0x0040;
4079                         break;
4080                 default:
4081                         DP(NETIF_MSG_LINK,
4082                            "Speed not supported: 0x%x\n", phy->req_line_speed);
4083                         return;
4084                 }
4085
4086                 if (phy->req_duplex == DUPLEX_FULL)
4087                         val16 |= 0x0100;
4088
4089                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4090                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
4091
4092                 DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
4093                                phy->req_line_speed);
4094                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4095                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4096                 DP(NETIF_MSG_LINK, "  (readback) %x\n", val16);
4097         }
4098
4099         /* SGMII Slave mode and disable signal detect */
4100         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4101                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
4102         if (fiber_mode)
4103                 digctrl_kx1 = 1;
4104         else
4105                 digctrl_kx1 &= 0xff4a;
4106
4107         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4108                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4109                         digctrl_kx1);
4110
4111         /* Turn off parallel detect */
4112         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4113                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
4114         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4115                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4116                         (digctrl_kx2 & ~(1<<2)));
4117
4118         /* Re-enable parallel detect */
4119         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4120                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4121                         (digctrl_kx2 | (1<<2)));
4122
4123         /* Enable autodet */
4124         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4125                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4126                         (digctrl_kx1 | 0x10));
4127 }
4128
4129 static void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
4130                                       struct bnx2x_phy *phy,
4131                                       u8 reset)
4132 {
4133         u16 val;
4134         /* Take lane out of reset after configuration is finished */
4135         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4136                         MDIO_WC_REG_DIGITAL5_MISC6, &val);
4137         if (reset)
4138                 val |= 0xC000;
4139         else
4140                 val &= 0x3FFF;
4141         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4142                          MDIO_WC_REG_DIGITAL5_MISC6, val);
4143         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4144                          MDIO_WC_REG_DIGITAL5_MISC6, &val);
4145 }
4146 /* Clear SFI/XFI link settings registers */
4147 static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
4148                                       struct link_params *params,
4149                                       u16 lane)
4150 {
4151         struct bnx2x *bp = params->bp;
4152         u16 val16;
4153
4154         /* Set XFI clock comp as default. */
4155         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4156                         MDIO_WC_REG_RX66_CONTROL, &val16);
4157         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4158                          MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13));
4159
4160         bnx2x_warpcore_reset_lane(bp, phy, 1);
4161         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
4162         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4163                          MDIO_WC_REG_FX100_CTRL1, 0x014a);
4164         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4165                          MDIO_WC_REG_FX100_CTRL3, 0x0800);
4166         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4167                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8008);
4168         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4169                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195);
4170         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4171                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007);
4172         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4173                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002);
4174         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4175                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000);
4176         lane = bnx2x_get_warpcore_lane(phy, params);
4177         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4178                          MDIO_WC_REG_TX_FIR_TAP, 0x0000);
4179         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4180                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
4181         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4182                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
4183         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4184                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140);
4185         bnx2x_warpcore_reset_lane(bp, phy, 0);
4186 }
4187
4188 static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
4189                                                 u32 chip_id,
4190                                                 u32 shmem_base, u8 port,
4191                                                 u8 *gpio_num, u8 *gpio_port)
4192 {
4193         u32 cfg_pin;
4194         *gpio_num = 0;
4195         *gpio_port = 0;
4196         if (CHIP_IS_E3(bp)) {
4197                 cfg_pin = (REG_RD(bp, shmem_base +
4198                                 offsetof(struct shmem_region,
4199                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4200                                 PORT_HW_CFG_E3_MOD_ABS_MASK) >>
4201                                 PORT_HW_CFG_E3_MOD_ABS_SHIFT;
4202
4203                 /*
4204                  * Should not happen. This function called upon interrupt
4205                  * triggered by GPIO ( since EPIO can only generate interrupts
4206                  * to MCP).
4207                  * So if this function was called and none of the GPIOs was set,
4208                  * it means the shit hit the fan.
4209                  */
4210                 if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
4211                     (cfg_pin > PIN_CFG_GPIO3_P1)) {
4212                         DP(NETIF_MSG_LINK,
4213                            "ERROR: Invalid cfg pin %x for module detect indication\n",
4214                            cfg_pin);
4215                         return -EINVAL;
4216                 }
4217
4218                 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
4219                 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
4220         } else {
4221                 *gpio_num = MISC_REGISTERS_GPIO_3;
4222                 *gpio_port = port;
4223         }
4224         DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port);
4225         return 0;
4226 }
4227
4228 static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
4229                                        struct link_params *params)
4230 {
4231         struct bnx2x *bp = params->bp;
4232         u8 gpio_num, gpio_port;
4233         u32 gpio_val;
4234         if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
4235                                       params->shmem_base, params->port,
4236                                       &gpio_num, &gpio_port) != 0)
4237                 return 0;
4238         gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
4239
4240         /* Call the handling function in case module is detected */
4241         if (gpio_val == 0)
4242                 return 1;
4243         else
4244                 return 0;
4245 }
4246 static int bnx2x_warpcore_get_sigdet(struct bnx2x_phy *phy,
4247                                         struct link_params *params)
4248 {
4249         u16 gp2_status_reg0, lane;
4250         struct bnx2x *bp = params->bp;
4251
4252         lane = bnx2x_get_warpcore_lane(phy, params);
4253
4254         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
4255                                  &gp2_status_reg0);
4256
4257         return (gp2_status_reg0 >> (8+lane)) & 0x1;
4258 }
4259
4260 static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy,
4261                                        struct link_params *params,
4262                                        struct link_vars *vars)
4263 {
4264         struct bnx2x *bp = params->bp;
4265         u32 serdes_net_if;
4266         u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
4267         u16 lane = bnx2x_get_warpcore_lane(phy, params);
4268
4269         vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
4270
4271         if (!vars->turn_to_run_wc_rt)
4272                 return;
4273
4274         /* return if there is no link partner */
4275         if (!(bnx2x_warpcore_get_sigdet(phy, params))) {
4276                 DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n");
4277                 return;
4278         }
4279
4280         if (vars->rx_tx_asic_rst) {
4281                 serdes_net_if = (REG_RD(bp, params->shmem_base +
4282                                 offsetof(struct shmem_region, dev_info.
4283                                 port_hw_config[params->port].default_cfg)) &
4284                                 PORT_HW_CFG_NET_SERDES_IF_MASK);
4285
4286                 switch (serdes_net_if) {
4287                 case PORT_HW_CFG_NET_SERDES_IF_KR:
4288                         /* Do we get link yet? */
4289                         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 0x81d1,
4290                                                                 &gp_status1);
4291                         lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */
4292                                 /*10G KR*/
4293                         lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
4294
4295                         DP(NETIF_MSG_LINK,
4296                                 "gp_status1 0x%x\n", gp_status1);
4297
4298                         if (lnkup_kr || lnkup) {
4299                                         vars->rx_tx_asic_rst = 0;
4300                                         DP(NETIF_MSG_LINK,
4301                                         "link up, rx_tx_asic_rst 0x%x\n",
4302                                         vars->rx_tx_asic_rst);
4303                         } else {
4304                                 /*reset the lane to see if link comes up.*/
4305                                 bnx2x_warpcore_reset_lane(bp, phy, 1);
4306                                 bnx2x_warpcore_reset_lane(bp, phy, 0);
4307
4308                                 /* restart Autoneg */
4309                                 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
4310                                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4311
4312                                 vars->rx_tx_asic_rst--;
4313                                 DP(NETIF_MSG_LINK, "0x%x retry left\n",
4314                                 vars->rx_tx_asic_rst);
4315                         }
4316                         break;
4317
4318                 default:
4319                         break;
4320                 }
4321
4322         } /*params->rx_tx_asic_rst*/
4323
4324 }
4325
4326 static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
4327                                        struct link_params *params,
4328                                        struct link_vars *vars)
4329 {
4330         struct bnx2x *bp = params->bp;
4331         u32 serdes_net_if;
4332         u8 fiber_mode;
4333         u16 lane = bnx2x_get_warpcore_lane(phy, params);
4334         serdes_net_if = (REG_RD(bp, params->shmem_base +
4335                          offsetof(struct shmem_region, dev_info.
4336                                   port_hw_config[params->port].default_cfg)) &
4337                          PORT_HW_CFG_NET_SERDES_IF_MASK);
4338         DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
4339                            "serdes_net_if = 0x%x\n",
4340                        vars->line_speed, serdes_net_if);
4341         bnx2x_set_aer_mmd(params, phy);
4342
4343         vars->phy_flags |= PHY_XGXS_FLAG;
4344         if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
4345             (phy->req_line_speed &&
4346              ((phy->req_line_speed == SPEED_100) ||
4347               (phy->req_line_speed == SPEED_10)))) {
4348                 vars->phy_flags |= PHY_SGMII_FLAG;
4349                 DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
4350                 bnx2x_warpcore_clear_regs(phy, params, lane);
4351                 bnx2x_warpcore_set_sgmii_speed(phy, params, 0, 1);
4352         } else {
4353                 switch (serdes_net_if) {
4354                 case PORT_HW_CFG_NET_SERDES_IF_KR:
4355                         /* Enable KR Auto Neg */
4356                         if (params->loopback_mode == LOOPBACK_NONE)
4357                                 bnx2x_warpcore_enable_AN_KR(phy, params, vars);
4358                         else {
4359                                 DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
4360                                 bnx2x_warpcore_set_10G_KR(phy, params, vars);
4361                         }
4362                         break;
4363
4364                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
4365                         bnx2x_warpcore_clear_regs(phy, params, lane);
4366                         if (vars->line_speed == SPEED_10000) {
4367                                 DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
4368                                 bnx2x_warpcore_set_10G_XFI(phy, params, 1);
4369                         } else {
4370                                 if (SINGLE_MEDIA_DIRECT(params)) {
4371                                         DP(NETIF_MSG_LINK, "1G Fiber\n");
4372                                         fiber_mode = 1;
4373                                 } else {
4374                                         DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
4375                                         fiber_mode = 0;
4376                                 }
4377                                 bnx2x_warpcore_set_sgmii_speed(phy,
4378                                                                 params,
4379                                                                 fiber_mode,
4380                                                                 0);
4381                         }
4382
4383                         break;
4384
4385                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
4386
4387                         bnx2x_warpcore_clear_regs(phy, params, lane);
4388                         if (vars->line_speed == SPEED_10000) {
4389                                 DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
4390                                 bnx2x_warpcore_set_10G_XFI(phy, params, 0);
4391                         } else if (vars->line_speed == SPEED_1000) {
4392                                 DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
4393                                 bnx2x_warpcore_set_sgmii_speed(
4394                                                 phy, params, 1, 0);
4395                         }
4396                         /* Issue Module detection */
4397                         if (bnx2x_is_sfp_module_plugged(phy, params))
4398                                 bnx2x_sfp_module_detection(phy, params);
4399                         break;
4400
4401                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
4402                         if (vars->line_speed != SPEED_20000) {
4403                                 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4404                                 return;
4405                         }
4406                         DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
4407                         bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
4408                         /* Issue Module detection */
4409
4410                         bnx2x_sfp_module_detection(phy, params);
4411                         break;
4412
4413                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
4414                         if (vars->line_speed != SPEED_20000) {
4415                                 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4416                                 return;
4417                         }
4418                         DP(NETIF_MSG_LINK, "Setting 20G KR2\n");
4419                         bnx2x_warpcore_set_20G_KR2(bp, phy);
4420                         break;
4421
4422                 default:
4423                         DP(NETIF_MSG_LINK,
4424                            "Unsupported Serdes Net Interface 0x%x\n",
4425                            serdes_net_if);
4426                         return;
4427                 }
4428         }
4429
4430         /* Take lane out of reset after configuration is finished */
4431         bnx2x_warpcore_reset_lane(bp, phy, 0);
4432         DP(NETIF_MSG_LINK, "Exit config init\n");
4433 }
4434
4435 static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
4436                                          struct bnx2x_phy *phy,
4437                                          u8 tx_en)
4438 {
4439         struct bnx2x *bp = params->bp;
4440         u32 cfg_pin;
4441         u8 port = params->port;
4442
4443         cfg_pin = REG_RD(bp, params->shmem_base +
4444                                 offsetof(struct shmem_region,
4445                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4446                                 PORT_HW_CFG_TX_LASER_MASK;
4447         /* Set the !tx_en since this pin is DISABLE_TX_LASER */
4448         DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
4449         /* For 20G, the expected pin to be used is 3 pins after the current */
4450
4451         bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
4452         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
4453                 bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
4454 }
4455
4456 static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
4457                                       struct link_params *params)
4458 {
4459         struct bnx2x *bp = params->bp;
4460         u16 val16;
4461         bnx2x_sfp_e3_set_transmitter(params, phy, 0);
4462         bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
4463         bnx2x_set_aer_mmd(params, phy);
4464         /* Global register */
4465         bnx2x_warpcore_reset_lane(bp, phy, 1);
4466
4467         /* Clear loopback settings (if any) */
4468         /* 10G & 20G */
4469         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4470                         MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4471         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4472                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 &
4473                          0xBFFF);
4474
4475         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4476                         MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4477         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4478                         MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe);
4479
4480         /* Update those 1-copy registers */
4481         CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4482                           MDIO_AER_BLOCK_AER_REG, 0);
4483                 /* Enable 1G MDIO (1-copy) */
4484         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4485                         MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4486                         &val16);
4487         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4488                          MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4489                          val16 & ~0x10);
4490
4491         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4492                         MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4493         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4494                          MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4495                          val16 & 0xff00);
4496
4497 }
4498
4499 static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
4500                                         struct link_params *params)
4501 {
4502         struct bnx2x *bp = params->bp;
4503         u16 val16;
4504         u32 lane;
4505         DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
4506                        params->loopback_mode, phy->req_line_speed);
4507
4508         if (phy->req_line_speed < SPEED_10000) {
4509                 /* 10/100/1000 */
4510
4511                 /* Update those 1-copy registers */
4512                 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4513                                   MDIO_AER_BLOCK_AER_REG, 0);
4514                 /* Enable 1G MDIO (1-copy) */
4515                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4516                                 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4517                                 &val16);
4518                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4519                                 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4520                                 val16 | 0x10);
4521                 /* Set 1G loopback based on lane (1-copy) */
4522                 lane = bnx2x_get_warpcore_lane(phy, params);
4523                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4524                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4525                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4526                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4527                                 val16 | (1<<lane));
4528
4529                 /* Switch back to 4-copy registers */
4530                 bnx2x_set_aer_mmd(params, phy);
4531         } else {
4532                 /* 10G & 20G */
4533                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4534                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4535                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4536                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
4537                                  0x4000);
4538
4539                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4540                                 MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4541                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4542                                 MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1);
4543         }
4544 }
4545
4546
4547 void bnx2x_sync_link(struct link_params *params,
4548                            struct link_vars *vars)
4549 {
4550         struct bnx2x *bp = params->bp;
4551         u8 link_10g_plus;
4552         if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4553                 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
4554         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4555         if (vars->link_up) {
4556                 DP(NETIF_MSG_LINK, "phy link up\n");
4557
4558                 vars->phy_link_up = 1;
4559                 vars->duplex = DUPLEX_FULL;
4560                 switch (vars->link_status &
4561                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
4562                         case LINK_10THD:
4563                                 vars->duplex = DUPLEX_HALF;
4564                                 /* fall thru */
4565                         case LINK_10TFD:
4566                                 vars->line_speed = SPEED_10;
4567                                 break;
4568
4569                         case LINK_100TXHD:
4570                                 vars->duplex = DUPLEX_HALF;
4571                                 /* fall thru */
4572                         case LINK_100T4:
4573                         case LINK_100TXFD:
4574                                 vars->line_speed = SPEED_100;
4575                                 break;
4576
4577                         case LINK_1000THD:
4578                                 vars->duplex = DUPLEX_HALF;
4579                                 /* fall thru */
4580                         case LINK_1000TFD:
4581                                 vars->line_speed = SPEED_1000;
4582                                 break;
4583
4584                         case LINK_2500THD:
4585                                 vars->duplex = DUPLEX_HALF;
4586                                 /* fall thru */
4587                         case LINK_2500TFD:
4588                                 vars->line_speed = SPEED_2500;
4589                                 break;
4590
4591                         case LINK_10GTFD:
4592                                 vars->line_speed = SPEED_10000;
4593                                 break;
4594                         case LINK_20GTFD:
4595                                 vars->line_speed = SPEED_20000;
4596                                 break;
4597                         default:
4598                                 break;
4599                 }
4600                 vars->flow_ctrl = 0;
4601                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
4602                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
4603
4604                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
4605                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
4606
4607                 if (!vars->flow_ctrl)
4608                         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4609
4610                 if (vars->line_speed &&
4611                     ((vars->line_speed == SPEED_10) ||
4612                      (vars->line_speed == SPEED_100))) {
4613                         vars->phy_flags |= PHY_SGMII_FLAG;
4614                 } else {
4615                         vars->phy_flags &= ~PHY_SGMII_FLAG;
4616                 }
4617                 if (vars->line_speed &&
4618                     USES_WARPCORE(bp) &&
4619                     (vars->line_speed == SPEED_1000))
4620                         vars->phy_flags |= PHY_SGMII_FLAG;
4621                 /* anything 10 and over uses the bmac */
4622                 link_10g_plus = (vars->line_speed >= SPEED_10000);
4623
4624                 if (link_10g_plus) {
4625                         if (USES_WARPCORE(bp))
4626                                 vars->mac_type = MAC_TYPE_XMAC;
4627                         else
4628                                 vars->mac_type = MAC_TYPE_BMAC;
4629                 } else {
4630                         if (USES_WARPCORE(bp))
4631                                 vars->mac_type = MAC_TYPE_UMAC;
4632                         else
4633                                 vars->mac_type = MAC_TYPE_EMAC;
4634                 }
4635         } else { /* link down */
4636                 DP(NETIF_MSG_LINK, "phy link down\n");
4637
4638                 vars->phy_link_up = 0;
4639
4640                 vars->line_speed = 0;
4641                 vars->duplex = DUPLEX_FULL;
4642                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4643
4644                 /* indicate no mac active */
4645                 vars->mac_type = MAC_TYPE_NONE;
4646                 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4647                         vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
4648         }
4649 }
4650
4651 void bnx2x_link_status_update(struct link_params *params,
4652                               struct link_vars *vars)
4653 {
4654         struct bnx2x *bp = params->bp;
4655         u8 port = params->port;
4656         u32 sync_offset, media_types;
4657         /* Update PHY configuration */
4658         set_phy_vars(params, vars);
4659
4660         vars->link_status = REG_RD(bp, params->shmem_base +
4661                                    offsetof(struct shmem_region,
4662                                             port_mb[port].link_status));
4663
4664         vars->phy_flags = PHY_XGXS_FLAG;
4665         bnx2x_sync_link(params, vars);
4666         /* Sync media type */
4667         sync_offset = params->shmem_base +
4668                         offsetof(struct shmem_region,
4669                                  dev_info.port_hw_config[port].media_type);
4670         media_types = REG_RD(bp, sync_offset);
4671
4672         params->phy[INT_PHY].media_type =
4673                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
4674                 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
4675         params->phy[EXT_PHY1].media_type =
4676                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
4677                 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
4678         params->phy[EXT_PHY2].media_type =
4679                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
4680                 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
4681         DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
4682
4683         /* Sync AEU offset */
4684         sync_offset = params->shmem_base +
4685                         offsetof(struct shmem_region,
4686                                  dev_info.port_hw_config[port].aeu_int_mask);
4687
4688         vars->aeu_int_mask = REG_RD(bp, sync_offset);
4689
4690         /* Sync PFC status */
4691         if (vars->link_status & LINK_STATUS_PFC_ENABLED)
4692                 params->feature_config_flags |=
4693                                         FEATURE_CONFIG_PFC_ENABLED;
4694         else
4695                 params->feature_config_flags &=
4696                                         ~FEATURE_CONFIG_PFC_ENABLED;
4697
4698         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
4699                  vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
4700         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
4701                  vars->line_speed, vars->duplex, vars->flow_ctrl);
4702 }
4703
4704 static void bnx2x_set_master_ln(struct link_params *params,
4705                                 struct bnx2x_phy *phy)
4706 {
4707         struct bnx2x *bp = params->bp;
4708         u16 new_master_ln, ser_lane;
4709         ser_lane = ((params->lane_config &
4710                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4711                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4712
4713         /* set the master_ln for AN */
4714         CL22_RD_OVER_CL45(bp, phy,
4715                           MDIO_REG_BANK_XGXS_BLOCK2,
4716                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4717                           &new_master_ln);
4718
4719         CL22_WR_OVER_CL45(bp, phy,
4720                           MDIO_REG_BANK_XGXS_BLOCK2 ,
4721                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4722                           (new_master_ln | ser_lane));
4723 }
4724
4725 static int bnx2x_reset_unicore(struct link_params *params,
4726                                struct bnx2x_phy *phy,
4727                                u8 set_serdes)
4728 {
4729         struct bnx2x *bp = params->bp;
4730         u16 mii_control;
4731         u16 i;
4732         CL22_RD_OVER_CL45(bp, phy,
4733                           MDIO_REG_BANK_COMBO_IEEE0,
4734                           MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4735
4736         /* reset the unicore */
4737         CL22_WR_OVER_CL45(bp, phy,
4738                           MDIO_REG_BANK_COMBO_IEEE0,
4739                           MDIO_COMBO_IEEE0_MII_CONTROL,
4740                           (mii_control |
4741                            MDIO_COMBO_IEEO_MII_CONTROL_RESET));
4742         if (set_serdes)
4743                 bnx2x_set_serdes_access(bp, params->port);
4744
4745         /* wait for the reset to self clear */
4746         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
4747                 udelay(5);
4748
4749                 /* the reset erased the previous bank value */
4750                 CL22_RD_OVER_CL45(bp, phy,
4751                                   MDIO_REG_BANK_COMBO_IEEE0,
4752                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4753                                   &mii_control);
4754
4755                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
4756                         udelay(5);
4757                         return 0;
4758                 }
4759         }
4760
4761         netdev_err(bp->dev,  "Warning: PHY was not initialized,"
4762                               " Port %d\n",
4763                          params->port);
4764         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
4765         return -EINVAL;
4766
4767 }
4768
4769 static void bnx2x_set_swap_lanes(struct link_params *params,
4770                                  struct bnx2x_phy *phy)
4771 {
4772         struct bnx2x *bp = params->bp;
4773         /*
4774          *  Each two bits represents a lane number:
4775          *  No swap is 0123 => 0x1b no need to enable the swap
4776          */
4777         u16 rx_lane_swap, tx_lane_swap;
4778
4779         rx_lane_swap = ((params->lane_config &
4780                          PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
4781                         PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
4782         tx_lane_swap = ((params->lane_config &
4783                          PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
4784                         PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
4785
4786         if (rx_lane_swap != 0x1b) {
4787                 CL22_WR_OVER_CL45(bp, phy,
4788                                   MDIO_REG_BANK_XGXS_BLOCK2,
4789                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP,
4790                                   (rx_lane_swap |
4791                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
4792                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
4793         } else {
4794                 CL22_WR_OVER_CL45(bp, phy,
4795                                   MDIO_REG_BANK_XGXS_BLOCK2,
4796                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
4797         }
4798
4799         if (tx_lane_swap != 0x1b) {
4800                 CL22_WR_OVER_CL45(bp, phy,
4801                                   MDIO_REG_BANK_XGXS_BLOCK2,
4802                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP,
4803                                   (tx_lane_swap |
4804                                    MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
4805         } else {
4806                 CL22_WR_OVER_CL45(bp, phy,
4807                                   MDIO_REG_BANK_XGXS_BLOCK2,
4808                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
4809         }
4810 }
4811
4812 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
4813                                          struct link_params *params)
4814 {
4815         struct bnx2x *bp = params->bp;
4816         u16 control2;
4817         CL22_RD_OVER_CL45(bp, phy,
4818                           MDIO_REG_BANK_SERDES_DIGITAL,
4819                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4820                           &control2);
4821         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4822                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4823         else
4824                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4825         DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
4826                 phy->speed_cap_mask, control2);
4827         CL22_WR_OVER_CL45(bp, phy,
4828                           MDIO_REG_BANK_SERDES_DIGITAL,
4829                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4830                           control2);
4831
4832         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4833              (phy->speed_cap_mask &
4834                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4835                 DP(NETIF_MSG_LINK, "XGXS\n");
4836
4837                 CL22_WR_OVER_CL45(bp, phy,
4838                                  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4839                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
4840                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
4841
4842                 CL22_RD_OVER_CL45(bp, phy,
4843                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
4844                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4845                                   &control2);
4846
4847
4848                 control2 |=
4849                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
4850
4851                 CL22_WR_OVER_CL45(bp, phy,
4852                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
4853                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4854                                   control2);
4855
4856                 /* Disable parallel detection of HiG */
4857                 CL22_WR_OVER_CL45(bp, phy,
4858                                   MDIO_REG_BANK_XGXS_BLOCK2,
4859                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
4860                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
4861                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
4862         }
4863 }
4864
4865 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
4866                               struct link_params *params,
4867                               struct link_vars *vars,
4868                               u8 enable_cl73)
4869 {
4870         struct bnx2x *bp = params->bp;
4871         u16 reg_val;
4872
4873         /* CL37 Autoneg */
4874         CL22_RD_OVER_CL45(bp, phy,
4875                           MDIO_REG_BANK_COMBO_IEEE0,
4876                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4877
4878         /* CL37 Autoneg Enabled */
4879         if (vars->line_speed == SPEED_AUTO_NEG)
4880                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
4881         else /* CL37 Autoneg Disabled */
4882                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4883                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
4884
4885         CL22_WR_OVER_CL45(bp, phy,
4886                           MDIO_REG_BANK_COMBO_IEEE0,
4887                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4888
4889         /* Enable/Disable Autodetection */
4890
4891         CL22_RD_OVER_CL45(bp, phy,
4892                           MDIO_REG_BANK_SERDES_DIGITAL,
4893                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
4894         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
4895                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
4896         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
4897         if (vars->line_speed == SPEED_AUTO_NEG)
4898                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4899         else
4900                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4901
4902         CL22_WR_OVER_CL45(bp, phy,
4903                           MDIO_REG_BANK_SERDES_DIGITAL,
4904                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
4905
4906         /* Enable TetonII and BAM autoneg */
4907         CL22_RD_OVER_CL45(bp, phy,
4908                           MDIO_REG_BANK_BAM_NEXT_PAGE,
4909                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4910                           &reg_val);
4911         if (vars->line_speed == SPEED_AUTO_NEG) {
4912                 /* Enable BAM aneg Mode and TetonII aneg Mode */
4913                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4914                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4915         } else {
4916                 /* TetonII and BAM Autoneg Disabled */
4917                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4918                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4919         }
4920         CL22_WR_OVER_CL45(bp, phy,
4921                           MDIO_REG_BANK_BAM_NEXT_PAGE,
4922                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4923                           reg_val);
4924
4925         if (enable_cl73) {
4926                 /* Enable Cl73 FSM status bits */
4927                 CL22_WR_OVER_CL45(bp, phy,
4928                                   MDIO_REG_BANK_CL73_USERB0,
4929                                   MDIO_CL73_USERB0_CL73_UCTRL,
4930                                   0xe);
4931
4932                 /* Enable BAM Station Manager*/
4933                 CL22_WR_OVER_CL45(bp, phy,
4934                         MDIO_REG_BANK_CL73_USERB0,
4935                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
4936                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
4937                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
4938                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
4939
4940                 /* Advertise CL73 link speeds */
4941                 CL22_RD_OVER_CL45(bp, phy,
4942                                   MDIO_REG_BANK_CL73_IEEEB1,
4943                                   MDIO_CL73_IEEEB1_AN_ADV2,
4944                                   &reg_val);
4945                 if (phy->speed_cap_mask &
4946                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4947                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
4948                 if (phy->speed_cap_mask &
4949                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4950                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
4951
4952                 CL22_WR_OVER_CL45(bp, phy,
4953                                   MDIO_REG_BANK_CL73_IEEEB1,
4954                                   MDIO_CL73_IEEEB1_AN_ADV2,
4955                                   reg_val);
4956
4957                 /* CL73 Autoneg Enabled */
4958                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
4959
4960         } else /* CL73 Autoneg Disabled */
4961                 reg_val = 0;
4962
4963         CL22_WR_OVER_CL45(bp, phy,
4964                           MDIO_REG_BANK_CL73_IEEEB0,
4965                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
4966 }
4967
4968 /* program SerDes, forced speed */
4969 static void bnx2x_program_serdes(struct bnx2x_phy *phy,
4970                                  struct link_params *params,
4971                                  struct link_vars *vars)
4972 {
4973         struct bnx2x *bp = params->bp;
4974         u16 reg_val;
4975
4976         /* program duplex, disable autoneg and sgmii*/
4977         CL22_RD_OVER_CL45(bp, phy,
4978                           MDIO_REG_BANK_COMBO_IEEE0,
4979                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4980         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
4981                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4982                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
4983         if (phy->req_duplex == DUPLEX_FULL)
4984                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
4985         CL22_WR_OVER_CL45(bp, phy,
4986                           MDIO_REG_BANK_COMBO_IEEE0,
4987                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4988
4989         /*
4990          * program speed
4991          *  - needed only if the speed is greater than 1G (2.5G or 10G)
4992          */
4993         CL22_RD_OVER_CL45(bp, phy,
4994                           MDIO_REG_BANK_SERDES_DIGITAL,
4995                           MDIO_SERDES_DIGITAL_MISC1, &reg_val);
4996         /* clearing the speed value before setting the right speed */
4997         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
4998
4999         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
5000                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
5001
5002         if (!((vars->line_speed == SPEED_1000) ||
5003               (vars->line_speed == SPEED_100) ||
5004               (vars->line_speed == SPEED_10))) {
5005
5006                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
5007                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
5008                 if (vars->line_speed == SPEED_10000)
5009                         reg_val |=
5010                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
5011         }
5012
5013         CL22_WR_OVER_CL45(bp, phy,
5014                           MDIO_REG_BANK_SERDES_DIGITAL,
5015                           MDIO_SERDES_DIGITAL_MISC1, reg_val);
5016
5017 }
5018
5019 static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy,
5020                                               struct link_params *params)
5021 {
5022         struct bnx2x *bp = params->bp;
5023         u16 val = 0;
5024
5025         /* configure the 48 bits for BAM AN */
5026
5027         /* set extended capabilities */
5028         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
5029                 val |= MDIO_OVER_1G_UP1_2_5G;
5030         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5031                 val |= MDIO_OVER_1G_UP1_10G;
5032         CL22_WR_OVER_CL45(bp, phy,
5033                           MDIO_REG_BANK_OVER_1G,
5034                           MDIO_OVER_1G_UP1, val);
5035
5036         CL22_WR_OVER_CL45(bp, phy,
5037                           MDIO_REG_BANK_OVER_1G,
5038                           MDIO_OVER_1G_UP3, 0x400);
5039 }
5040
5041 static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy,
5042                                               struct link_params *params,
5043                                               u16 ieee_fc)
5044 {
5045         struct bnx2x *bp = params->bp;
5046         u16 val;
5047         /* for AN, we are always publishing full duplex */
5048
5049         CL22_WR_OVER_CL45(bp, phy,
5050                           MDIO_REG_BANK_COMBO_IEEE0,
5051                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
5052         CL22_RD_OVER_CL45(bp, phy,
5053                           MDIO_REG_BANK_CL73_IEEEB1,
5054                           MDIO_CL73_IEEEB1_AN_ADV1, &val);
5055         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
5056         val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
5057         CL22_WR_OVER_CL45(bp, phy,
5058                           MDIO_REG_BANK_CL73_IEEEB1,
5059                           MDIO_CL73_IEEEB1_AN_ADV1, val);
5060 }
5061
5062 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
5063                                   struct link_params *params,
5064                                   u8 enable_cl73)
5065 {
5066         struct bnx2x *bp = params->bp;
5067         u16 mii_control;
5068
5069         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
5070         /* Enable and restart BAM/CL37 aneg */
5071
5072         if (enable_cl73) {
5073                 CL22_RD_OVER_CL45(bp, phy,
5074                                   MDIO_REG_BANK_CL73_IEEEB0,
5075                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5076                                   &mii_control);
5077
5078                 CL22_WR_OVER_CL45(bp, phy,
5079                                   MDIO_REG_BANK_CL73_IEEEB0,
5080                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5081                                   (mii_control |
5082                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
5083                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
5084         } else {
5085
5086                 CL22_RD_OVER_CL45(bp, phy,
5087                                   MDIO_REG_BANK_COMBO_IEEE0,
5088                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5089                                   &mii_control);
5090                 DP(NETIF_MSG_LINK,
5091                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
5092                          mii_control);
5093                 CL22_WR_OVER_CL45(bp, phy,
5094                                   MDIO_REG_BANK_COMBO_IEEE0,
5095                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5096                                   (mii_control |
5097                                    MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5098                                    MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
5099         }
5100 }
5101
5102 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
5103                                            struct link_params *params,
5104                                            struct link_vars *vars)
5105 {
5106         struct bnx2x *bp = params->bp;
5107         u16 control1;
5108
5109         /* in SGMII mode, the unicore is always slave */
5110
5111         CL22_RD_OVER_CL45(bp, phy,
5112                           MDIO_REG_BANK_SERDES_DIGITAL,
5113                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
5114                           &control1);
5115         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
5116         /* set sgmii mode (and not fiber) */
5117         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
5118                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
5119                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
5120         CL22_WR_OVER_CL45(bp, phy,
5121                           MDIO_REG_BANK_SERDES_DIGITAL,
5122                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
5123                           control1);
5124
5125         /* if forced speed */
5126         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
5127                 /* set speed, disable autoneg */
5128                 u16 mii_control;
5129
5130                 CL22_RD_OVER_CL45(bp, phy,
5131                                   MDIO_REG_BANK_COMBO_IEEE0,
5132                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5133                                   &mii_control);
5134                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5135                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
5136                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
5137
5138                 switch (vars->line_speed) {
5139                 case SPEED_100:
5140                         mii_control |=
5141                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
5142                         break;
5143                 case SPEED_1000:
5144                         mii_control |=
5145                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
5146                         break;
5147                 case SPEED_10:
5148                         /* there is nothing to set for 10M */
5149                         break;
5150                 default:
5151                         /* invalid speed for SGMII */
5152                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5153                                   vars->line_speed);
5154                         break;
5155                 }
5156
5157                 /* setting the full duplex */
5158                 if (phy->req_duplex == DUPLEX_FULL)
5159                         mii_control |=
5160                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5161                 CL22_WR_OVER_CL45(bp, phy,
5162                                   MDIO_REG_BANK_COMBO_IEEE0,
5163                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5164                                   mii_control);
5165
5166         } else { /* AN mode */
5167                 /* enable and restart AN */
5168                 bnx2x_restart_autoneg(phy, params, 0);
5169         }
5170 }
5171
5172
5173 /*
5174  * link management
5175  */
5176
5177 static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
5178                                              struct link_params *params)
5179 {
5180         struct bnx2x *bp = params->bp;
5181         u16 pd_10g, status2_1000x;
5182         if (phy->req_line_speed != SPEED_AUTO_NEG)
5183                 return 0;
5184         CL22_RD_OVER_CL45(bp, phy,
5185                           MDIO_REG_BANK_SERDES_DIGITAL,
5186                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5187                           &status2_1000x);
5188         CL22_RD_OVER_CL45(bp, phy,
5189                           MDIO_REG_BANK_SERDES_DIGITAL,
5190                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5191                           &status2_1000x);
5192         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
5193                 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
5194                          params->port);
5195                 return 1;
5196         }
5197
5198         CL22_RD_OVER_CL45(bp, phy,
5199                           MDIO_REG_BANK_10G_PARALLEL_DETECT,
5200                           MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
5201                           &pd_10g);
5202
5203         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
5204                 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
5205                          params->port);
5206                 return 1;
5207         }
5208         return 0;
5209 }
5210
5211 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
5212                                     struct link_params *params,
5213                                     struct link_vars *vars,
5214                                     u32 gp_status)
5215 {
5216         struct bnx2x *bp = params->bp;
5217         u16 ld_pause;   /* local driver */
5218         u16 lp_pause;   /* link partner */
5219         u16 pause_result;
5220
5221         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5222
5223         /* resolve from gp_status in case of AN complete and not sgmii */
5224         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
5225                 vars->flow_ctrl = phy->req_flow_ctrl;
5226         else if (phy->req_line_speed != SPEED_AUTO_NEG)
5227                 vars->flow_ctrl = params->req_fc_auto_adv;
5228         else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
5229                  (!(vars->phy_flags & PHY_SGMII_FLAG))) {
5230                 if (bnx2x_direct_parallel_detect_used(phy, params)) {
5231                         vars->flow_ctrl = params->req_fc_auto_adv;
5232                         return;
5233                 }
5234                 if ((gp_status &
5235                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5236                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
5237                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5238                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
5239
5240                         CL22_RD_OVER_CL45(bp, phy,
5241                                           MDIO_REG_BANK_CL73_IEEEB1,
5242                                           MDIO_CL73_IEEEB1_AN_ADV1,
5243                                           &ld_pause);
5244                         CL22_RD_OVER_CL45(bp, phy,
5245                                           MDIO_REG_BANK_CL73_IEEEB1,
5246                                           MDIO_CL73_IEEEB1_AN_LP_ADV1,
5247                                           &lp_pause);
5248                         pause_result = (ld_pause &
5249                                         MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
5250                                         >> 8;
5251                         pause_result |= (lp_pause &
5252                                         MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
5253                                         >> 10;
5254                         DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
5255                                  pause_result);
5256                 } else {
5257                         CL22_RD_OVER_CL45(bp, phy,
5258                                           MDIO_REG_BANK_COMBO_IEEE0,
5259                                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
5260                                           &ld_pause);
5261                         CL22_RD_OVER_CL45(bp, phy,
5262                                 MDIO_REG_BANK_COMBO_IEEE0,
5263                                 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
5264                                 &lp_pause);
5265                         pause_result = (ld_pause &
5266                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
5267                         pause_result |= (lp_pause &
5268                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
5269                         DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
5270                                  pause_result);
5271                 }
5272                 bnx2x_pause_resolve(vars, pause_result);
5273         }
5274         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
5275 }
5276
5277 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
5278                                          struct link_params *params)
5279 {
5280         struct bnx2x *bp = params->bp;
5281         u16 rx_status, ustat_val, cl37_fsm_received;
5282         DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
5283         /* Step 1: Make sure signal is detected */
5284         CL22_RD_OVER_CL45(bp, phy,
5285                           MDIO_REG_BANK_RX0,
5286                           MDIO_RX0_RX_STATUS,
5287                           &rx_status);
5288         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
5289             (MDIO_RX0_RX_STATUS_SIGDET)) {
5290                 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
5291                              "rx_status(0x80b0) = 0x%x\n", rx_status);
5292                 CL22_WR_OVER_CL45(bp, phy,
5293                                   MDIO_REG_BANK_CL73_IEEEB0,
5294                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5295                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
5296                 return;
5297         }
5298         /* Step 2: Check CL73 state machine */
5299         CL22_RD_OVER_CL45(bp, phy,
5300                           MDIO_REG_BANK_CL73_USERB0,
5301                           MDIO_CL73_USERB0_CL73_USTAT1,
5302                           &ustat_val);
5303         if ((ustat_val &
5304              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5305               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
5306             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5307               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
5308                 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
5309                              "ustat_val(0x8371) = 0x%x\n", ustat_val);
5310                 return;
5311         }
5312         /*
5313          * Step 3: Check CL37 Message Pages received to indicate LP
5314          * supports only CL37
5315          */
5316         CL22_RD_OVER_CL45(bp, phy,
5317                           MDIO_REG_BANK_REMOTE_PHY,
5318                           MDIO_REMOTE_PHY_MISC_RX_STATUS,
5319                           &cl37_fsm_received);
5320         if ((cl37_fsm_received &
5321              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5322              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
5323             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5324               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
5325                 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
5326                              "misc_rx_status(0x8330) = 0x%x\n",
5327                          cl37_fsm_received);
5328                 return;
5329         }
5330         /*
5331          * The combined cl37/cl73 fsm state information indicating that
5332          * we are connected to a device which does not support cl73, but
5333          * does support cl37 BAM. In this case we disable cl73 and
5334          * restart cl37 auto-neg
5335          */
5336
5337         /* Disable CL73 */
5338         CL22_WR_OVER_CL45(bp, phy,
5339                           MDIO_REG_BANK_CL73_IEEEB0,
5340                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5341                           0);
5342         /* Restart CL37 autoneg */
5343         bnx2x_restart_autoneg(phy, params, 0);
5344         DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
5345 }
5346
5347 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
5348                                   struct link_params *params,
5349                                   struct link_vars *vars,
5350                                   u32 gp_status)
5351 {
5352         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
5353                 vars->link_status |=
5354                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5355
5356         if (bnx2x_direct_parallel_detect_used(phy, params))
5357                 vars->link_status |=
5358                         LINK_STATUS_PARALLEL_DETECTION_USED;
5359 }
5360 static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
5361                                      struct link_params *params,
5362                                       struct link_vars *vars,
5363                                       u16 is_link_up,
5364                                       u16 speed_mask,
5365                                       u16 is_duplex)
5366 {
5367         struct bnx2x *bp = params->bp;
5368         if (phy->req_line_speed == SPEED_AUTO_NEG)
5369                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
5370         if (is_link_up) {
5371                 DP(NETIF_MSG_LINK, "phy link up\n");
5372
5373                 vars->phy_link_up = 1;
5374                 vars->link_status |= LINK_STATUS_LINK_UP;
5375
5376                 switch (speed_mask) {
5377                 case GP_STATUS_10M:
5378                         vars->line_speed = SPEED_10;
5379                         if (vars->duplex == DUPLEX_FULL)
5380                                 vars->link_status |= LINK_10TFD;
5381                         else
5382                                 vars->link_status |= LINK_10THD;
5383                         break;
5384
5385                 case GP_STATUS_100M:
5386                         vars->line_speed = SPEED_100;
5387                         if (vars->duplex == DUPLEX_FULL)
5388                                 vars->link_status |= LINK_100TXFD;
5389                         else
5390                                 vars->link_status |= LINK_100TXHD;
5391                         break;
5392
5393                 case GP_STATUS_1G:
5394                 case GP_STATUS_1G_KX:
5395                         vars->line_speed = SPEED_1000;
5396                         if (vars->duplex == DUPLEX_FULL)
5397                                 vars->link_status |= LINK_1000TFD;
5398                         else
5399                                 vars->link_status |= LINK_1000THD;
5400                         break;
5401
5402                 case GP_STATUS_2_5G:
5403                         vars->line_speed = SPEED_2500;
5404                         if (vars->duplex == DUPLEX_FULL)
5405                                 vars->link_status |= LINK_2500TFD;
5406                         else
5407                                 vars->link_status |= LINK_2500THD;
5408                         break;
5409
5410                 case GP_STATUS_5G:
5411                 case GP_STATUS_6G:
5412                         DP(NETIF_MSG_LINK,
5413                                  "link speed unsupported  gp_status 0x%x\n",
5414                                   speed_mask);
5415                         return -EINVAL;
5416
5417                 case GP_STATUS_10G_KX4:
5418                 case GP_STATUS_10G_HIG:
5419                 case GP_STATUS_10G_CX4:
5420                 case GP_STATUS_10G_KR:
5421                 case GP_STATUS_10G_SFI:
5422                 case GP_STATUS_10G_XFI:
5423                         vars->line_speed = SPEED_10000;
5424                         vars->link_status |= LINK_10GTFD;
5425                         break;
5426                 case GP_STATUS_20G_DXGXS:
5427                         vars->line_speed = SPEED_20000;
5428                         vars->link_status |= LINK_20GTFD;
5429                         break;
5430                 default:
5431                         DP(NETIF_MSG_LINK,
5432                                   "link speed unsupported gp_status 0x%x\n",
5433                                   speed_mask);
5434                         return -EINVAL;
5435                 }
5436         } else { /* link_down */
5437                 DP(NETIF_MSG_LINK, "phy link down\n");
5438
5439                 vars->phy_link_up = 0;
5440
5441                 vars->duplex = DUPLEX_FULL;
5442                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5443                 vars->mac_type = MAC_TYPE_NONE;
5444         }
5445         DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n",
5446                     vars->phy_link_up, vars->line_speed);
5447         return 0;
5448 }
5449
5450 static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
5451                                       struct link_params *params,
5452                                       struct link_vars *vars)
5453 {
5454         struct bnx2x *bp = params->bp;
5455
5456         u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
5457         int rc = 0;
5458
5459         /* Read gp_status */
5460         CL22_RD_OVER_CL45(bp, phy,
5461                           MDIO_REG_BANK_GP_STATUS,
5462                           MDIO_GP_STATUS_TOP_AN_STATUS1,
5463                           &gp_status);
5464         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
5465                 duplex = DUPLEX_FULL;
5466         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
5467                 link_up = 1;
5468         speed_mask = gp_status & GP_STATUS_SPEED_MASK;
5469         DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
5470                        gp_status, link_up, speed_mask);
5471         rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
5472                                          duplex);
5473         if (rc == -EINVAL)
5474                 return rc;
5475
5476         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
5477                 if (SINGLE_MEDIA_DIRECT(params)) {
5478                         bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
5479                         if (phy->req_line_speed == SPEED_AUTO_NEG)
5480                                 bnx2x_xgxs_an_resolve(phy, params, vars,
5481                                                       gp_status);
5482                 }
5483         } else { /* link_down */
5484                 if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5485        &nbs