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