bnx2x: Fix chip hanging due to TX pipe stall.
[firefly-linux-kernel-4.4.55.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         /* enable emac and not bmac */
1749         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
1750
1751         /* ASIC */
1752         if (vars->phy_flags & PHY_XGXS_FLAG) {
1753                 u32 ser_lane = ((params->lane_config &
1754                                  PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1755                                 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1756
1757                 DP(NETIF_MSG_LINK, "XGXS\n");
1758                 /* select the master lanes (out of 0-3) */
1759                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
1760                 /* select XGXS */
1761                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
1762
1763         } else { /* SerDes */
1764                 DP(NETIF_MSG_LINK, "SerDes\n");
1765                 /* select SerDes */
1766                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
1767         }
1768
1769         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1770                       EMAC_RX_MODE_RESET);
1771         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1772                       EMAC_TX_MODE_RESET);
1773
1774         if (CHIP_REV_IS_SLOW(bp)) {
1775                 /* config GMII mode */
1776                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1777                 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
1778         } else { /* ASIC */
1779                 /* pause enable/disable */
1780                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1781                                EMAC_RX_MODE_FLOW_EN);
1782
1783                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
1784                                (EMAC_TX_MODE_EXT_PAUSE_EN |
1785                                 EMAC_TX_MODE_FLOW_EN));
1786                 if (!(params->feature_config_flags &
1787                       FEATURE_CONFIG_PFC_ENABLED)) {
1788                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1789                                 bnx2x_bits_en(bp, emac_base +
1790                                               EMAC_REG_EMAC_RX_MODE,
1791                                               EMAC_RX_MODE_FLOW_EN);
1792
1793                         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1794                                 bnx2x_bits_en(bp, emac_base +
1795                                               EMAC_REG_EMAC_TX_MODE,
1796                                               (EMAC_TX_MODE_EXT_PAUSE_EN |
1797                                                EMAC_TX_MODE_FLOW_EN));
1798                 } else
1799                         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1800                                       EMAC_TX_MODE_FLOW_EN);
1801         }
1802
1803         /* KEEP_VLAN_TAG, promiscuous */
1804         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
1805         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
1806
1807         /*
1808          * Setting this bit causes MAC control frames (except for pause
1809          * frames) to be passed on for processing. This setting has no
1810          * affect on the operation of the pause frames. This bit effects
1811          * all packets regardless of RX Parser packet sorting logic.
1812          * Turn the PFC off to make sure we are in Xon state before
1813          * enabling it.
1814          */
1815         EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
1816         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1817                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1818                 /* Enable PFC again */
1819                 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
1820                         EMAC_REG_RX_PFC_MODE_RX_EN |
1821                         EMAC_REG_RX_PFC_MODE_TX_EN |
1822                         EMAC_REG_RX_PFC_MODE_PRIORITIES);
1823
1824                 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
1825                         ((0x0101 <<
1826                           EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
1827                          (0x00ff <<
1828                           EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
1829                 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
1830         }
1831         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
1832
1833         /* Set Loopback */
1834         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1835         if (lb)
1836                 val |= 0x810;
1837         else
1838                 val &= ~0x810;
1839         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
1840
1841         /* enable emac */
1842         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
1843
1844         /* enable emac for jumbo packets */
1845         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
1846                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
1847                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
1848
1849         /* strip CRC */
1850         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
1851
1852         /* disable the NIG in/out to the bmac */
1853         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
1854         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
1855         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
1856
1857         /* enable the NIG in/out to the emac */
1858         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
1859         val = 0;
1860         if ((params->feature_config_flags &
1861               FEATURE_CONFIG_PFC_ENABLED) ||
1862             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1863                 val = 1;
1864
1865         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
1866         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
1867
1868         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
1869
1870         vars->mac_type = MAC_TYPE_EMAC;
1871         return 0;
1872 }
1873
1874 static void bnx2x_update_pfc_bmac1(struct link_params *params,
1875                                    struct link_vars *vars)
1876 {
1877         u32 wb_data[2];
1878         struct bnx2x *bp = params->bp;
1879         u32 bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1880                 NIG_REG_INGRESS_BMAC0_MEM;
1881
1882         u32 val = 0x14;
1883         if ((!(params->feature_config_flags &
1884               FEATURE_CONFIG_PFC_ENABLED)) &&
1885                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1886                 /* Enable BigMAC to react on received Pause packets */
1887                 val |= (1<<5);
1888         wb_data[0] = val;
1889         wb_data[1] = 0;
1890         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
1891
1892         /* tx control */
1893         val = 0xc0;
1894         if (!(params->feature_config_flags &
1895               FEATURE_CONFIG_PFC_ENABLED) &&
1896                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1897                 val |= 0x800000;
1898         wb_data[0] = val;
1899         wb_data[1] = 0;
1900         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
1901 }
1902
1903 static void bnx2x_update_pfc_bmac2(struct link_params *params,
1904                                    struct link_vars *vars,
1905                                    u8 is_lb)
1906 {
1907         /*
1908          * Set rx control: Strip CRC and enable BigMAC to relay
1909          * control packets to the system as well
1910          */
1911         u32 wb_data[2];
1912         struct bnx2x *bp = params->bp;
1913         u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1914                 NIG_REG_INGRESS_BMAC0_MEM;
1915         u32 val = 0x14;
1916
1917         if ((!(params->feature_config_flags &
1918               FEATURE_CONFIG_PFC_ENABLED)) &&
1919                 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1920                 /* Enable BigMAC to react on received Pause packets */
1921                 val |= (1<<5);
1922         wb_data[0] = val;
1923         wb_data[1] = 0;
1924         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
1925         udelay(30);
1926
1927         /* Tx control */
1928         val = 0xc0;
1929         if (!(params->feature_config_flags &
1930                                 FEATURE_CONFIG_PFC_ENABLED) &&
1931             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1932                 val |= 0x800000;
1933         wb_data[0] = val;
1934         wb_data[1] = 0;
1935         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
1936
1937         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1938                 DP(NETIF_MSG_LINK, "PFC is enabled\n");
1939                 /* Enable PFC RX & TX & STATS and set 8 COS  */
1940                 wb_data[0] = 0x0;
1941                 wb_data[0] |= (1<<0);  /* RX */
1942                 wb_data[0] |= (1<<1);  /* TX */
1943                 wb_data[0] |= (1<<2);  /* Force initial Xon */
1944                 wb_data[0] |= (1<<3);  /* 8 cos */
1945                 wb_data[0] |= (1<<5);  /* STATS */
1946                 wb_data[1] = 0;
1947                 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
1948                             wb_data, 2);
1949                 /* Clear the force Xon */
1950                 wb_data[0] &= ~(1<<2);
1951         } else {
1952                 DP(NETIF_MSG_LINK, "PFC is disabled\n");
1953                 /* disable PFC RX & TX & STATS and set 8 COS */
1954                 wb_data[0] = 0x8;
1955                 wb_data[1] = 0;
1956         }
1957
1958         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
1959
1960         /*
1961          * Set Time (based unit is 512 bit time) between automatic
1962          * re-sending of PP packets amd enable automatic re-send of
1963          * Per-Priroity Packet as long as pp_gen is asserted and
1964          * pp_disable is low.
1965          */
1966         val = 0x8000;
1967         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
1968                 val |= (1<<16); /* enable automatic re-send */
1969
1970         wb_data[0] = val;
1971         wb_data[1] = 0;
1972         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
1973                     wb_data, 2);
1974
1975         /* mac control */
1976         val = 0x3; /* Enable RX and TX */
1977         if (is_lb) {
1978                 val |= 0x4; /* Local loopback */
1979                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
1980         }
1981         /* When PFC enabled, Pass pause frames towards the NIG. */
1982         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
1983                 val |= ((1<<6)|(1<<5));
1984
1985         wb_data[0] = val;
1986         wb_data[1] = 0;
1987         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
1988 }
1989
1990
1991 /* PFC BRB internal port configuration params */
1992 struct bnx2x_pfc_brb_threshold_val {
1993         u32 pause_xoff;
1994         u32 pause_xon;
1995         u32 full_xoff;
1996         u32 full_xon;
1997 };
1998
1999 struct bnx2x_pfc_brb_e3b0_val {
2000         u32 full_lb_xoff_th;
2001         u32 full_lb_xon_threshold;
2002         u32 lb_guarantied;
2003         u32 mac_0_class_t_guarantied;
2004         u32 mac_0_class_t_guarantied_hyst;
2005         u32 mac_1_class_t_guarantied;
2006         u32 mac_1_class_t_guarantied_hyst;
2007 };
2008
2009 struct bnx2x_pfc_brb_th_val {
2010         struct bnx2x_pfc_brb_threshold_val pauseable_th;
2011         struct bnx2x_pfc_brb_threshold_val non_pauseable_th;
2012 };
2013 static int bnx2x_pfc_brb_get_config_params(
2014                                 struct link_params *params,
2015                                 struct bnx2x_pfc_brb_th_val *config_val)
2016 {
2017         struct bnx2x *bp = params->bp;
2018         DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n");
2019         if (CHIP_IS_E2(bp)) {
2020                 config_val->pauseable_th.pause_xoff =
2021                     PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2022                 config_val->pauseable_th.pause_xon =
2023                     PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE;
2024                 config_val->pauseable_th.full_xoff =
2025                     PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE;
2026                 config_val->pauseable_th.full_xon =
2027                     PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE;
2028                 /* non pause able*/
2029                 config_val->non_pauseable_th.pause_xoff =
2030                     PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2031                 config_val->non_pauseable_th.pause_xon =
2032                     PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2033                 config_val->non_pauseable_th.full_xoff =
2034                     PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2035                 config_val->non_pauseable_th.full_xon =
2036                     PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2037         } else if (CHIP_IS_E3A0(bp)) {
2038                 config_val->pauseable_th.pause_xoff =
2039                     PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2040                 config_val->pauseable_th.pause_xon =
2041                     PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE;
2042                 config_val->pauseable_th.full_xoff =
2043                     PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE;
2044                 config_val->pauseable_th.full_xon =
2045                     PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE;
2046                 /* non pause able*/
2047                 config_val->non_pauseable_th.pause_xoff =
2048                     PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2049                 config_val->non_pauseable_th.pause_xon =
2050                     PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2051                 config_val->non_pauseable_th.full_xoff =
2052                     PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2053                 config_val->non_pauseable_th.full_xon =
2054                     PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2055         } else if (CHIP_IS_E3B0(bp)) {
2056                 if (params->phy[INT_PHY].flags &
2057                     FLAGS_4_PORT_MODE) {
2058                         config_val->pauseable_th.pause_xoff =
2059                             PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2060                         config_val->pauseable_th.pause_xon =
2061                             PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE;
2062                         config_val->pauseable_th.full_xoff =
2063                             PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE;
2064                         config_val->pauseable_th.full_xon =
2065                             PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE;
2066                         /* non pause able*/
2067                         config_val->non_pauseable_th.pause_xoff =
2068                             PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2069                         config_val->non_pauseable_th.pause_xon =
2070                             PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2071                         config_val->non_pauseable_th.full_xoff =
2072                             PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2073                         config_val->non_pauseable_th.full_xon =
2074                             PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2075             } else {
2076                 config_val->pauseable_th.pause_xoff =
2077                     PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2078                 config_val->pauseable_th.pause_xon =
2079                     PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE;
2080                 config_val->pauseable_th.full_xoff =
2081                     PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE;
2082                 config_val->pauseable_th.full_xon =
2083                         PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE;
2084                 /* non pause able*/
2085                 config_val->non_pauseable_th.pause_xoff =
2086                     PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2087                 config_val->non_pauseable_th.pause_xon =
2088                     PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2089                 config_val->non_pauseable_th.full_xoff =
2090                     PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2091                 config_val->non_pauseable_th.full_xon =
2092                     PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2093             }
2094         } else
2095             return -EINVAL;
2096
2097         return 0;
2098 }
2099
2100
2101 static void bnx2x_pfc_brb_get_e3b0_config_params(struct link_params *params,
2102                                                  struct bnx2x_pfc_brb_e3b0_val
2103                                                  *e3b0_val,
2104                                                  u32 cos0_pauseable,
2105                                                  u32 cos1_pauseable)
2106 {
2107         if (params->phy[INT_PHY].flags & FLAGS_4_PORT_MODE) {
2108                 e3b0_val->full_lb_xoff_th =
2109                     PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR;
2110                 e3b0_val->full_lb_xon_threshold =
2111                     PFC_E3B0_4P_BRB_FULL_LB_XON_THR;
2112                 e3b0_val->lb_guarantied =
2113                     PFC_E3B0_4P_LB_GUART;
2114                 e3b0_val->mac_0_class_t_guarantied =
2115                     PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART;
2116                 e3b0_val->mac_0_class_t_guarantied_hyst =
2117                     PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST;
2118                 e3b0_val->mac_1_class_t_guarantied =
2119                     PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART;
2120                 e3b0_val->mac_1_class_t_guarantied_hyst =
2121                     PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST;
2122         } else {
2123                 e3b0_val->full_lb_xoff_th =
2124                     PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR;
2125                 e3b0_val->full_lb_xon_threshold =
2126                     PFC_E3B0_2P_BRB_FULL_LB_XON_THR;
2127                 e3b0_val->mac_0_class_t_guarantied_hyst =
2128                     PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST;
2129                 e3b0_val->mac_1_class_t_guarantied =
2130                     PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART;
2131                 e3b0_val->mac_1_class_t_guarantied_hyst =
2132                     PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST;
2133
2134                 if (cos0_pauseable != cos1_pauseable) {
2135                         /* nonpauseable= Lossy + pauseable = Lossless*/
2136                         e3b0_val->lb_guarantied =
2137                             PFC_E3B0_2P_MIX_PAUSE_LB_GUART;
2138                         e3b0_val->mac_0_class_t_guarantied =
2139                             PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART;
2140                 } else if (cos0_pauseable) {
2141                         /* Lossless +Lossless*/
2142                         e3b0_val->lb_guarantied =
2143                             PFC_E3B0_2P_PAUSE_LB_GUART;
2144                         e3b0_val->mac_0_class_t_guarantied =
2145                             PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART;
2146                 } else {
2147                         /* Lossy +Lossy*/
2148                         e3b0_val->lb_guarantied =
2149                             PFC_E3B0_2P_NON_PAUSE_LB_GUART;
2150                         e3b0_val->mac_0_class_t_guarantied =
2151                             PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART;
2152                 }
2153         }
2154 }
2155 static int bnx2x_update_pfc_brb(struct link_params *params,
2156                                 struct link_vars *vars,
2157                                 struct bnx2x_nig_brb_pfc_port_params
2158                                 *pfc_params)
2159 {
2160         struct bnx2x *bp = params->bp;
2161         struct bnx2x_pfc_brb_th_val config_val = { {0} };
2162         struct bnx2x_pfc_brb_threshold_val *reg_th_config =
2163             &config_val.pauseable_th;
2164         struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0};
2165         int set_pfc = params->feature_config_flags &
2166                 FEATURE_CONFIG_PFC_ENABLED;
2167         int bnx2x_status = 0;
2168         u8 port = params->port;
2169
2170         /* default - pause configuration */
2171         reg_th_config = &config_val.pauseable_th;
2172         bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val);
2173         if (0 != bnx2x_status)
2174                 return bnx2x_status;
2175
2176         if (set_pfc && pfc_params)
2177                 /* First COS */
2178                 if (!pfc_params->cos0_pauseable)
2179                         reg_th_config = &config_val.non_pauseable_th;
2180         /*
2181          * The number of free blocks below which the pause signal to class 0
2182          * of MAC #n is asserted. n=0,1
2183          */
2184         REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 :
2185                BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 ,
2186                reg_th_config->pause_xoff);
2187         /*
2188          * The number of free blocks above which the pause signal to class 0
2189          * of MAC #n is de-asserted. n=0,1
2190          */
2191         REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 :
2192                BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon);
2193         /*
2194          * The number of free blocks below which the full signal to class 0
2195          * of MAC #n is asserted. n=0,1
2196          */
2197         REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 :
2198                BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff);
2199         /*
2200          * The number of free blocks above which the full signal to class 0
2201          * of MAC #n is de-asserted. n=0,1
2202          */
2203         REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 :
2204                BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon);
2205
2206         if (set_pfc && pfc_params) {
2207                 /* Second COS */
2208                 if (pfc_params->cos1_pauseable)
2209                         reg_th_config = &config_val.pauseable_th;
2210                 else
2211                         reg_th_config = &config_val.non_pauseable_th;
2212                 /*
2213                  * The number of free blocks below which the pause signal to
2214                  * class 1 of MAC #n is asserted. n=0,1
2215                 **/
2216                 REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 :
2217                        BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0,
2218                        reg_th_config->pause_xoff);
2219                 /*
2220                  * The number of free blocks above which the pause signal to
2221                  * class 1 of MAC #n is de-asserted. n=0,1
2222                  */
2223                 REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 :
2224                        BRB1_REG_PAUSE_1_XON_THRESHOLD_0,
2225                        reg_th_config->pause_xon);
2226                 /*
2227                  * The number of free blocks below which the full signal to
2228                  * class 1 of MAC #n is asserted. n=0,1
2229                  */
2230                 REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 :
2231                        BRB1_REG_FULL_1_XOFF_THRESHOLD_0,
2232                        reg_th_config->full_xoff);
2233                 /*
2234                  * The number of free blocks above which the full signal to
2235                  * class 1 of MAC #n is de-asserted. n=0,1
2236                  */
2237                 REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 :
2238                        BRB1_REG_FULL_1_XON_THRESHOLD_0,
2239                        reg_th_config->full_xon);
2240
2241
2242                 if (CHIP_IS_E3B0(bp)) {
2243                         /*Should be done by init tool */
2244                         /*
2245                         * BRB_empty_for_dup = BRB1_REG_BRB_EMPTY_THRESHOLD
2246                         * reset value
2247                         * 944
2248                         */
2249
2250                         /**
2251                          * The hysteresis on the guarantied buffer space for the Lb port
2252                          * before signaling XON.
2253                          **/
2254                         REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST, 80);
2255
2256                         bnx2x_pfc_brb_get_e3b0_config_params(
2257                             params,
2258                             &e3b0_val,
2259                             pfc_params->cos0_pauseable,
2260                             pfc_params->cos1_pauseable);
2261                         /**
2262                          * The number of free blocks below which the full signal to the
2263                          * LB port is asserted.
2264                         */
2265                         REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD,
2266                                    e3b0_val.full_lb_xoff_th);
2267                         /**
2268                          * The number of free blocks above which the full signal to the
2269                          * LB port is de-asserted.
2270                         */
2271                         REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD,
2272                                    e3b0_val.full_lb_xon_threshold);
2273                         /**
2274                         * The number of blocks guarantied for the MAC #n port. n=0,1
2275                         */
2276
2277                         /*The number of blocks guarantied for the LB port.*/
2278                         REG_WR(bp, BRB1_REG_LB_GUARANTIED,
2279                                e3b0_val.lb_guarantied);
2280
2281                         /**
2282                          * The number of blocks guarantied for the MAC #n port.
2283                         */
2284                         REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0,
2285                                    2 * e3b0_val.mac_0_class_t_guarantied);
2286                         REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1,
2287                                    2 * e3b0_val.mac_1_class_t_guarantied);
2288                         /**
2289                          * The number of blocks guarantied for class #t in MAC0. t=0,1
2290                         */
2291                         REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED,
2292                                e3b0_val.mac_0_class_t_guarantied);
2293                         REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED,
2294                                e3b0_val.mac_0_class_t_guarantied);
2295                         /**
2296                          * The hysteresis on the guarantied buffer space for class in
2297                          * MAC0.  t=0,1
2298                         */
2299                         REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST,
2300                                e3b0_val.mac_0_class_t_guarantied_hyst);
2301                         REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST,
2302                                e3b0_val.mac_0_class_t_guarantied_hyst);
2303
2304                         /**
2305                          * The number of blocks guarantied for class #t in MAC1.t=0,1
2306                         */
2307                         REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED,
2308                                e3b0_val.mac_1_class_t_guarantied);
2309                         REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED,
2310                                e3b0_val.mac_1_class_t_guarantied);
2311                         /**
2312                          * The hysteresis on the guarantied buffer space for class #t
2313                         * in MAC1.  t=0,1
2314                         */
2315                         REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST,
2316                                e3b0_val.mac_1_class_t_guarantied_hyst);
2317                         REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST,
2318                                e3b0_val.mac_1_class_t_guarantied_hyst);
2319
2320             }
2321
2322         }
2323
2324         return bnx2x_status;
2325 }
2326
2327 /******************************************************************************
2328 * Description:
2329 *  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2330 *  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2331 ******************************************************************************/
2332 int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
2333                                               u8 cos_entry,
2334                                               u32 priority_mask, u8 port)
2335 {
2336         u32 nig_reg_rx_priority_mask_add = 0;
2337
2338         switch (cos_entry) {
2339         case 0:
2340              nig_reg_rx_priority_mask_add = (port) ?
2341                  NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2342                  NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2343              break;
2344         case 1:
2345             nig_reg_rx_priority_mask_add = (port) ?
2346                 NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2347                 NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2348             break;
2349         case 2:
2350             nig_reg_rx_priority_mask_add = (port) ?
2351                 NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2352                 NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2353             break;
2354         case 3:
2355             if (port)
2356                 return -EINVAL;
2357             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2358             break;
2359         case 4:
2360             if (port)
2361                 return -EINVAL;
2362             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2363             break;
2364         case 5:
2365             if (port)
2366                 return -EINVAL;
2367             nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2368             break;
2369         }
2370
2371         REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
2372
2373         return 0;
2374 }
2375 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
2376 {
2377         struct bnx2x *bp = params->bp;
2378
2379         REG_WR(bp, params->shmem_base +
2380                offsetof(struct shmem_region,
2381                         port_mb[params->port].link_status), link_status);
2382 }
2383
2384 static void bnx2x_update_pfc_nig(struct link_params *params,
2385                 struct link_vars *vars,
2386                 struct bnx2x_nig_brb_pfc_port_params *nig_params)
2387 {
2388         u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2389         u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
2390         u32 pkt_priority_to_cos = 0;
2391         struct bnx2x *bp = params->bp;
2392         u8 port = params->port;
2393
2394         int set_pfc = params->feature_config_flags &
2395                 FEATURE_CONFIG_PFC_ENABLED;
2396         DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
2397
2398         /*
2399          * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2400          * MAC control frames (that are not pause packets)
2401          * will be forwarded to the XCM.
2402          */
2403         xcm_mask = REG_RD(bp,
2404                                 port ? NIG_REG_LLH1_XCM_MASK :
2405                                 NIG_REG_LLH0_XCM_MASK);
2406         /*
2407          * nig params will override non PFC params, since it's possible to
2408          * do transition from PFC to SAFC
2409          */
2410         if (set_pfc) {
2411                 pause_enable = 0;
2412                 llfc_out_en = 0;
2413                 llfc_enable = 0;
2414                 if (CHIP_IS_E3(bp))
2415                         ppp_enable = 0;
2416                 else
2417                 ppp_enable = 1;
2418                 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2419                                      NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2420                 xcm0_out_en = 0;
2421                 p0_hwpfc_enable = 1;
2422         } else  {
2423                 if (nig_params) {
2424                         llfc_out_en = nig_params->llfc_out_en;
2425                         llfc_enable = nig_params->llfc_enable;
2426                         pause_enable = nig_params->pause_enable;
2427                 } else  /*defaul non PFC mode - PAUSE */
2428                         pause_enable = 1;
2429
2430                 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2431                         NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2432                 xcm0_out_en = 1;
2433         }
2434
2435         if (CHIP_IS_E3(bp))
2436                 REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2437                        NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2438         REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
2439                NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2440         REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
2441                NIG_REG_LLFC_ENABLE_0, llfc_enable);
2442         REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
2443                NIG_REG_PAUSE_ENABLE_0, pause_enable);
2444
2445         REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
2446                NIG_REG_PPP_ENABLE_0, ppp_enable);
2447
2448         REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
2449                NIG_REG_LLH0_XCM_MASK, xcm_mask);
2450
2451         REG_WR(bp,  NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
2452
2453         /* output enable for RX_XCM # IF */
2454         REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
2455
2456         /* HW PFC TX enable */
2457         REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
2458
2459         if (nig_params) {
2460                 u8 i = 0;
2461                 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2462
2463                 for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2464                         bnx2x_pfc_nig_rx_priority_mask(bp, i,
2465                 nig_params->rx_cos_priority_mask[i], port);
2466
2467                 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
2468                        NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
2469                        nig_params->llfc_high_priority_classes);
2470
2471                 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
2472                        NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
2473                        nig_params->llfc_low_priority_classes);
2474         }
2475         REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
2476                NIG_REG_P0_PKT_PRIORITY_TO_COS,
2477                pkt_priority_to_cos);
2478 }
2479
2480 int bnx2x_update_pfc(struct link_params *params,
2481                       struct link_vars *vars,
2482                       struct bnx2x_nig_brb_pfc_port_params *pfc_params)
2483 {
2484         /*
2485          * The PFC and pause are orthogonal to one another, meaning when
2486          * PFC is enabled, the pause are disabled, and when PFC is
2487          * disabled, pause are set according to the pause result.
2488          */
2489         u32 val;
2490         struct bnx2x *bp = params->bp;
2491         int bnx2x_status = 0;
2492         u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
2493
2494         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2495                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
2496         else
2497                 vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
2498
2499         bnx2x_update_mng(params, vars->link_status);
2500
2501         /* update NIG params */
2502         bnx2x_update_pfc_nig(params, vars, pfc_params);
2503
2504         /* update BRB params */
2505         bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params);
2506         if (0 != bnx2x_status)
2507                 return bnx2x_status;
2508
2509         if (!vars->link_up)
2510                 return bnx2x_status;
2511
2512         DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
2513         if (CHIP_IS_E3(bp))
2514                 bnx2x_update_pfc_xmac(params, vars, 0);
2515         else {
2516                 val = REG_RD(bp, MISC_REG_RESET_REG_2);
2517                 if ((val &
2518                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
2519                     == 0) {
2520                         DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
2521                         bnx2x_emac_enable(params, vars, 0);
2522                         return bnx2x_status;
2523                 }
2524
2525                 if (CHIP_IS_E2(bp))
2526                         bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
2527                 else
2528                         bnx2x_update_pfc_bmac1(params, vars);
2529
2530                 val = 0;
2531                 if ((params->feature_config_flags &
2532                      FEATURE_CONFIG_PFC_ENABLED) ||
2533                     (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2534                         val = 1;
2535                 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
2536         }
2537         return bnx2x_status;
2538 }
2539
2540
2541 static int bnx2x_bmac1_enable(struct link_params *params,
2542                               struct link_vars *vars,
2543                               u8 is_lb)
2544 {
2545         struct bnx2x *bp = params->bp;
2546         u8 port = params->port;
2547         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2548                                NIG_REG_INGRESS_BMAC0_MEM;
2549         u32 wb_data[2];
2550         u32 val;
2551
2552         DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
2553
2554         /* XGXS control */
2555         wb_data[0] = 0x3c;
2556         wb_data[1] = 0;
2557         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
2558                     wb_data, 2);
2559
2560         /* tx MAC SA */
2561         wb_data[0] = ((params->mac_addr[2] << 24) |
2562                        (params->mac_addr[3] << 16) |
2563                        (params->mac_addr[4] << 8) |
2564                         params->mac_addr[5]);
2565         wb_data[1] = ((params->mac_addr[0] << 8) |
2566                         params->mac_addr[1]);
2567         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
2568
2569         /* mac control */
2570         val = 0x3;
2571         if (is_lb) {
2572                 val |= 0x4;
2573                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2574         }
2575         wb_data[0] = val;
2576         wb_data[1] = 0;
2577         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
2578
2579         /* set rx mtu */
2580         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2581         wb_data[1] = 0;
2582         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
2583
2584         bnx2x_update_pfc_bmac1(params, vars);
2585
2586         /* set tx mtu */
2587         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2588         wb_data[1] = 0;
2589         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
2590
2591         /* set cnt max size */
2592         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2593         wb_data[1] = 0;
2594         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2595
2596         /* configure safc */
2597         wb_data[0] = 0x1000200;
2598         wb_data[1] = 0;
2599         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2600                     wb_data, 2);
2601
2602         if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) {
2603                 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LSS_STATUS,
2604                             wb_data, 2);
2605                 if (wb_data[0] > 0)
2606                         return -ESRCH;
2607         }
2608         return 0;
2609 }
2610
2611 static int bnx2x_bmac2_enable(struct link_params *params,
2612                               struct link_vars *vars,
2613                               u8 is_lb)
2614 {
2615         struct bnx2x *bp = params->bp;
2616         u8 port = params->port;
2617         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2618                                NIG_REG_INGRESS_BMAC0_MEM;
2619         u32 wb_data[2];
2620
2621         DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
2622
2623         wb_data[0] = 0;
2624         wb_data[1] = 0;
2625         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2626         udelay(30);
2627
2628         /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2629         wb_data[0] = 0x3c;
2630         wb_data[1] = 0;
2631         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
2632                     wb_data, 2);
2633
2634         udelay(30);
2635
2636         /* tx MAC SA */
2637         wb_data[0] = ((params->mac_addr[2] << 24) |
2638                        (params->mac_addr[3] << 16) |
2639                        (params->mac_addr[4] << 8) |
2640                         params->mac_addr[5]);
2641         wb_data[1] = ((params->mac_addr[0] << 8) |
2642                         params->mac_addr[1]);
2643         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
2644                     wb_data, 2);
2645
2646         udelay(30);
2647
2648         /* Configure SAFC */
2649         wb_data[0] = 0x1000200;
2650         wb_data[1] = 0;
2651         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
2652                     wb_data, 2);
2653         udelay(30);
2654
2655         /* set rx mtu */
2656         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2657         wb_data[1] = 0;
2658         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
2659         udelay(30);
2660
2661         /* set tx mtu */
2662         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2663         wb_data[1] = 0;
2664         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
2665         udelay(30);
2666         /* set cnt max size */
2667         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
2668         wb_data[1] = 0;
2669         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2670         udelay(30);
2671         bnx2x_update_pfc_bmac2(params, vars, is_lb);
2672
2673         if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) {
2674                 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LSS_STAT,
2675                             wb_data, 2);
2676                 if (wb_data[0] > 0) {
2677                         DP(NETIF_MSG_LINK, "Got bad LSS status 0x%x\n",
2678                                        wb_data[0]);
2679                         return -ESRCH;
2680                 }
2681         }
2682
2683         return 0;
2684 }
2685
2686 static int bnx2x_bmac_enable(struct link_params *params,
2687                              struct link_vars *vars,
2688                              u8 is_lb)
2689 {
2690         int rc = 0;
2691         u8 port = params->port;
2692         struct bnx2x *bp = params->bp;
2693         u32 val;
2694         /* reset and unreset the BigMac */
2695         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2696                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2697         msleep(1);
2698
2699         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2700                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2701
2702         /* enable access for bmac registers */
2703         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2704
2705         /* Enable BMAC according to BMAC type*/
2706         if (CHIP_IS_E2(bp))
2707                 rc = bnx2x_bmac2_enable(params, vars, is_lb);
2708         else
2709                 rc = bnx2x_bmac1_enable(params, vars, is_lb);
2710         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
2711         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
2712         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
2713         val = 0;
2714         if ((params->feature_config_flags &
2715               FEATURE_CONFIG_PFC_ENABLED) ||
2716             (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2717                 val = 1;
2718         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
2719         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
2720         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
2721         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
2722         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
2723         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
2724
2725         vars->mac_type = MAC_TYPE_BMAC;
2726         return rc;
2727 }
2728
2729 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
2730 {
2731         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2732                         NIG_REG_INGRESS_BMAC0_MEM;
2733         u32 wb_data[2];
2734         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
2735
2736         /* Only if the bmac is out of reset */
2737         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
2738                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
2739             nig_bmac_enable) {
2740
2741                 if (CHIP_IS_E2(bp)) {
2742                         /* Clear Rx Enable bit in BMAC_CONTROL register */
2743                         REG_RD_DMAE(bp, bmac_addr +
2744                                     BIGMAC2_REGISTER_BMAC_CONTROL,
2745                                     wb_data, 2);
2746                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2747                         REG_WR_DMAE(bp, bmac_addr +
2748                                     BIGMAC2_REGISTER_BMAC_CONTROL,
2749                                     wb_data, 2);
2750                 } else {
2751                         /* Clear Rx Enable bit in BMAC_CONTROL register */
2752                         REG_RD_DMAE(bp, bmac_addr +
2753                                         BIGMAC_REGISTER_BMAC_CONTROL,
2754                                         wb_data, 2);
2755                         wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2756                         REG_WR_DMAE(bp, bmac_addr +
2757                                         BIGMAC_REGISTER_BMAC_CONTROL,
2758                                         wb_data, 2);
2759                 }
2760                 msleep(1);
2761         }
2762 }
2763
2764 static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
2765                             u32 line_speed)
2766 {
2767         struct bnx2x *bp = params->bp;
2768         u8 port = params->port;
2769         u32 init_crd, crd;
2770         u32 count = 1000;
2771
2772         /* disable port */
2773         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
2774
2775         /* wait for init credit */
2776         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
2777         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2778         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
2779
2780         while ((init_crd != crd) && count) {
2781                 msleep(5);
2782
2783                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2784                 count--;
2785         }
2786         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2787         if (init_crd != crd) {
2788                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
2789                           init_crd, crd);
2790                 return -EINVAL;
2791         }
2792
2793         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
2794             line_speed == SPEED_10 ||
2795             line_speed == SPEED_100 ||
2796             line_speed == SPEED_1000 ||
2797             line_speed == SPEED_2500) {
2798                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
2799                 /* update threshold */
2800                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
2801                 /* update init credit */
2802                 init_crd = 778;         /* (800-18-4) */
2803
2804         } else {
2805                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
2806                               ETH_OVREHEAD)/16;
2807                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
2808                 /* update threshold */
2809                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
2810                 /* update init credit */
2811                 switch (line_speed) {
2812                 case SPEED_10000:
2813                         init_crd = thresh + 553 - 22;
2814                         break;
2815                 default:
2816                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2817                                   line_speed);
2818                         return -EINVAL;
2819                 }
2820         }
2821         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
2822         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
2823                  line_speed, init_crd);
2824
2825         /* probe the credit changes */
2826         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
2827         msleep(5);
2828         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
2829
2830         /* enable port */
2831         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
2832         return 0;
2833 }
2834
2835 /**
2836  * bnx2x_get_emac_base - retrive emac base address
2837  *
2838  * @bp:                 driver handle
2839  * @mdc_mdio_access:    access type
2840  * @port:               port id
2841  *
2842  * This function selects the MDC/MDIO access (through emac0 or
2843  * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2844  * phy has a default access mode, which could also be overridden
2845  * by nvram configuration. This parameter, whether this is the
2846  * default phy configuration, or the nvram overrun
2847  * configuration, is passed here as mdc_mdio_access and selects
2848  * the emac_base for the CL45 read/writes operations
2849  */
2850 static u32 bnx2x_get_emac_base(struct bnx2x *bp,
2851                                u32 mdc_mdio_access, u8 port)
2852 {
2853         u32 emac_base = 0;
2854         switch (mdc_mdio_access) {
2855         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2856                 break;
2857         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2858                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2859                         emac_base = GRCBASE_EMAC1;
2860                 else
2861                         emac_base = GRCBASE_EMAC0;
2862                 break;
2863         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2864                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
2865                         emac_base = GRCBASE_EMAC0;
2866                 else
2867                         emac_base = GRCBASE_EMAC1;
2868                 break;
2869         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2870                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2871                 break;
2872         case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
2873                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2874                 break;
2875         default:
2876                 break;
2877         }
2878         return emac_base;
2879
2880 }
2881
2882 /******************************************************************/
2883 /*                      CL22 access functions                     */
2884 /******************************************************************/
2885 static int bnx2x_cl22_write(struct bnx2x *bp,
2886                                        struct bnx2x_phy *phy,
2887                                        u16 reg, u16 val)
2888 {
2889         u32 tmp, mode;
2890         u8 i;
2891         int rc = 0;
2892         /* Switch to CL22 */
2893         mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2894         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2895                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2896
2897         /* address */
2898         tmp = ((phy->addr << 21) | (reg << 16) | val |
2899                EMAC_MDIO_COMM_COMMAND_WRITE_22 |
2900                EMAC_MDIO_COMM_START_BUSY);
2901         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2902
2903         for (i = 0; i < 50; i++) {
2904                 udelay(10);
2905
2906                 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2907                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2908                         udelay(5);
2909                         break;
2910                 }
2911         }
2912         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2913                 DP(NETIF_MSG_LINK, "write phy register failed\n");
2914                 rc = -EFAULT;
2915         }
2916         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2917         return rc;
2918 }
2919
2920 static int bnx2x_cl22_read(struct bnx2x *bp,
2921                                       struct bnx2x_phy *phy,
2922                                       u16 reg, u16 *ret_val)
2923 {
2924         u32 val, mode;
2925         u16 i;
2926         int rc = 0;
2927
2928         /* Switch to CL22 */
2929         mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2930         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2931                mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2932
2933         /* address */
2934         val = ((phy->addr << 21) | (reg << 16) |
2935                EMAC_MDIO_COMM_COMMAND_READ_22 |
2936                EMAC_MDIO_COMM_START_BUSY);
2937         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2938
2939         for (i = 0; i < 50; i++) {
2940                 udelay(10);
2941
2942                 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2943                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2944                         *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
2945                         udelay(5);
2946                         break;
2947                 }
2948         }
2949         if (val & EMAC_MDIO_COMM_START_BUSY) {
2950                 DP(NETIF_MSG_LINK, "read phy register failed\n");
2951
2952                 *ret_val = 0;
2953                 rc = -EFAULT;
2954         }
2955         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2956         return rc;
2957 }
2958
2959 /******************************************************************/
2960 /*                      CL45 access functions                     */
2961 /******************************************************************/
2962 static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
2963                            u8 devad, u16 reg, u16 *ret_val)
2964 {
2965         u32 val;
2966         u16 i;
2967         int rc = 0;
2968
2969         /* address */
2970         val = ((phy->addr << 21) | (devad << 16) | reg |
2971                EMAC_MDIO_COMM_COMMAND_ADDRESS |
2972                EMAC_MDIO_COMM_START_BUSY);
2973         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2974
2975         for (i = 0; i < 50; i++) {
2976                 udelay(10);
2977
2978                 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2979                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2980                         udelay(5);
2981                         break;
2982                 }
2983         }
2984         if (val & EMAC_MDIO_COMM_START_BUSY) {
2985                 DP(NETIF_MSG_LINK, "read phy register failed\n");
2986                 netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2987                 *ret_val = 0;
2988                 rc = -EFAULT;
2989         } else {
2990                 /* data */
2991                 val = ((phy->addr << 21) | (devad << 16) |
2992                        EMAC_MDIO_COMM_COMMAND_READ_45 |
2993                        EMAC_MDIO_COMM_START_BUSY);
2994                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2995
2996                 for (i = 0; i < 50; i++) {
2997                         udelay(10);
2998
2999                         val = REG_RD(bp, phy->mdio_ctrl +
3000                                      EMAC_REG_EMAC_MDIO_COMM);
3001                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3002                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
3003                                 break;
3004                         }
3005                 }
3006                 if (val & EMAC_MDIO_COMM_START_BUSY) {
3007                         DP(NETIF_MSG_LINK, "read phy register failed\n");
3008                         netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3009                         *ret_val = 0;
3010                         rc = -EFAULT;
3011                 }
3012         }
3013         /* Work around for E3 A0 */
3014         if (phy->flags & FLAGS_MDC_MDIO_WA) {
3015                 phy->flags ^= FLAGS_DUMMY_READ;
3016                 if (phy->flags & FLAGS_DUMMY_READ) {
3017                         u16 temp_val;
3018                         bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
3019                 }
3020         }
3021
3022         return rc;
3023 }
3024
3025 static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3026                             u8 devad, u16 reg, u16 val)
3027 {
3028         u32 tmp;
3029         u8 i;
3030         int rc = 0;
3031
3032         /* address */
3033
3034         tmp = ((phy->addr << 21) | (devad << 16) | reg |
3035                EMAC_MDIO_COMM_COMMAND_ADDRESS |
3036                EMAC_MDIO_COMM_START_BUSY);
3037         REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3038
3039         for (i = 0; i < 50; i++) {
3040                 udelay(10);
3041
3042                 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3043                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3044                         udelay(5);
3045                         break;
3046                 }
3047         }
3048         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3049                 DP(NETIF_MSG_LINK, "write phy register failed\n");
3050                 netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3051                 rc = -EFAULT;
3052
3053         } else {
3054                 /* data */
3055                 tmp = ((phy->addr << 21) | (devad << 16) | val |
3056                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
3057                        EMAC_MDIO_COMM_START_BUSY);
3058                 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3059
3060                 for (i = 0; i < 50; i++) {
3061                         udelay(10);
3062
3063                         tmp = REG_RD(bp, phy->mdio_ctrl +
3064                                      EMAC_REG_EMAC_MDIO_COMM);
3065                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3066                                 udelay(5);
3067                                 break;
3068                         }
3069                 }
3070                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3071                         DP(NETIF_MSG_LINK, "write phy register failed\n");
3072                         netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3073                         rc = -EFAULT;
3074                 }
3075         }
3076         /* Work around for E3 A0 */
3077         if (phy->flags & FLAGS_MDC_MDIO_WA) {
3078                 phy->flags ^= FLAGS_DUMMY_READ;
3079                 if (phy->flags & FLAGS_DUMMY_READ) {
3080                         u16 temp_val;
3081                         bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
3082                 }
3083         }
3084
3085         return rc;
3086 }
3087
3088
3089 /******************************************************************/
3090 /*                      BSC access functions from E3              */
3091 /******************************************************************/
3092 static void bnx2x_bsc_module_sel(struct link_params *params)
3093 {
3094         int idx;
3095         u32 board_cfg, sfp_ctrl;
3096         u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3097         struct bnx2x *bp = params->bp;
3098         u8 port = params->port;
3099         /* Read I2C output PINs */
3100         board_cfg = REG_RD(bp, params->shmem_base +
3101                            offsetof(struct shmem_region,
3102                                     dev_info.shared_hw_config.board));
3103         i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3104         i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3105                         SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3106
3107         /* Read I2C output value */
3108         sfp_ctrl = REG_RD(bp, params->shmem_base +
3109                           offsetof(struct shmem_region,
3110                                  dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3111         i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3112         i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3113         DP(NETIF_MSG_LINK, "Setting BSC switch\n");
3114         for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3115                 bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
3116 }
3117
3118 static int bnx2x_bsc_read(struct link_params *params,
3119                           struct bnx2x_phy *phy,
3120                           u8 sl_devid,
3121                           u16 sl_addr,
3122                           u8 lc_addr,
3123                           u8 xfer_cnt,
3124                           u32 *data_array)
3125 {
3126         u32 val, i;
3127         int rc = 0;
3128         struct bnx2x *bp = params->bp;
3129
3130         if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) {
3131                 DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid);
3132                 return -EINVAL;
3133         }
3134
3135         if (xfer_cnt > 16) {
3136                 DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n",
3137                                         xfer_cnt);
3138                 return -EINVAL;
3139         }
3140         bnx2x_bsc_module_sel(params);
3141
3142         xfer_cnt = 16 - lc_addr;
3143
3144         /* enable the engine */
3145         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3146         val |= MCPR_IMC_COMMAND_ENABLE;
3147         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3148
3149         /* program slave device ID */
3150         val = (sl_devid << 16) | sl_addr;
3151         REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3152
3153         /* start xfer with 0 byte to update the address pointer ???*/
3154         val = (MCPR_IMC_COMMAND_ENABLE) |
3155               (MCPR_IMC_COMMAND_WRITE_OP <<
3156                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3157                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3158         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3159
3160         /* poll for completion */
3161         i = 0;
3162         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3163         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3164                 udelay(10);
3165                 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3166                 if (i++ > 1000) {
3167                         DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n",
3168                                                                 i);
3169                         rc = -EFAULT;
3170                         break;
3171                 }
3172         }
3173         if (rc == -EFAULT)
3174                 return rc;
3175
3176         /* start xfer with read op */
3177         val = (MCPR_IMC_COMMAND_ENABLE) |
3178                 (MCPR_IMC_COMMAND_READ_OP <<
3179                 MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3180                 (lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3181                   (xfer_cnt);
3182         REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3183
3184         /* poll for completion */
3185         i = 0;
3186         val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3187         while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3188                 udelay(10);
3189                 val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3190                 if (i++ > 1000) {
3191                         DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i);
3192                         rc = -EFAULT;
3193                         break;
3194                 }
3195         }
3196         if (rc == -EFAULT)
3197                 return rc;
3198
3199         for (i = (lc_addr >> 2); i < 4; i++) {
3200                 data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
3201 #ifdef __BIG_ENDIAN
3202                 data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
3203                                 ((data_array[i] & 0x0000ff00) << 8) |
3204                                 ((data_array[i] & 0x00ff0000) >> 8) |
3205                                 ((data_array[i] & 0xff000000) >> 24);
3206 #endif
3207         }
3208         return rc;
3209 }
3210
3211 static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3212                                      u8 devad, u16 reg, u16 or_val)
3213 {
3214         u16 val;
3215         bnx2x_cl45_read(bp, phy, devad, reg, &val);
3216         bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
3217 }
3218
3219 int bnx2x_phy_read(struct link_params *params, u8 phy_addr,
3220                    u8 devad, u16 reg, u16 *ret_val)
3221 {
3222         u8 phy_index;
3223         /*
3224          * Probe for the phy according to the given phy_addr, and execute
3225          * the read request on it
3226          */
3227         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3228                 if (params->phy[phy_index].addr == phy_addr) {
3229                         return bnx2x_cl45_read(params->bp,
3230                                                &params->phy[phy_index], devad,
3231                                                reg, ret_val);
3232                 }
3233         }
3234         return -EINVAL;
3235 }
3236
3237 int bnx2x_phy_write(struct link_params *params, u8 phy_addr,
3238                     u8 devad, u16 reg, u16 val)
3239 {
3240         u8 phy_index;
3241         /*
3242          * Probe for the phy according to the given phy_addr, and execute
3243          * the write request on it
3244          */
3245         for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3246                 if (params->phy[phy_index].addr == phy_addr) {
3247                         return bnx2x_cl45_write(params->bp,
3248                                                 &params->phy[phy_index], devad,
3249                                                 reg, val);
3250                 }
3251         }
3252         return -EINVAL;
3253 }
3254 static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy,
3255                                   struct link_params *params)
3256 {
3257         u8 lane = 0;
3258         struct bnx2x *bp = params->bp;
3259         u32 path_swap, path_swap_ovr;
3260         u8 path, port;
3261
3262         path = BP_PATH(bp);
3263         port = params->port;
3264
3265         if (bnx2x_is_4_port_mode(bp)) {
3266                 u32 port_swap, port_swap_ovr;
3267
3268                 /*figure out path swap value */
3269                 path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
3270                 if (path_swap_ovr & 0x1)
3271                         path_swap = (path_swap_ovr & 0x2);
3272                 else
3273                         path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP);
3274
3275                 if (path_swap)
3276                         path = path ^ 1;
3277
3278                 /*figure out port swap value */
3279                 port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
3280                 if (port_swap_ovr & 0x1)
3281                         port_swap = (port_swap_ovr & 0x2);
3282                 else
3283                         port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP);
3284
3285                 if (port_swap)
3286                         port = port ^ 1;
3287
3288                 lane = (port<<1) + path;
3289         } else { /* two port mode - no port swap */
3290
3291                 /*figure out path swap value */
3292                 path_swap_ovr =
3293                         REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
3294                 if (path_swap_ovr & 0x1) {
3295                         path_swap = (path_swap_ovr & 0x2);
3296                 } else {
3297                         path_swap =
3298                                 REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP);
3299                 }
3300                 if (path_swap)
3301                         path = path ^ 1;
3302
3303                 lane = path << 1 ;
3304         }
3305         return lane;
3306 }
3307
3308 static void bnx2x_set_aer_mmd(struct link_params *params,
3309                               struct bnx2x_phy *phy)
3310 {
3311         u32 ser_lane;
3312         u16 offset, aer_val;
3313         struct bnx2x *bp = params->bp;
3314         ser_lane = ((params->lane_config &
3315                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3316                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3317
3318         offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
3319                 (phy->addr + ser_lane) : 0;
3320
3321         if (USES_WARPCORE(bp)) {
3322                 aer_val = bnx2x_get_warpcore_lane(phy, params);
3323                 /*
3324                  * In Dual-lane mode, two lanes are joined together,
3325                  * so in order to configure them, the AER broadcast method is
3326                  * used here.
3327                  * 0x200 is the broadcast address for lanes 0,1
3328                  * 0x201 is the broadcast address for lanes 2,3
3329                  */
3330                 if (phy->flags & FLAGS_WC_DUAL_MODE)
3331                         aer_val = (aer_val >> 1) | 0x200;
3332         } else if (CHIP_IS_E2(bp))
3333                 aer_val = 0x3800 + offset - 1;
3334         else
3335                 aer_val = 0x3800 + offset;
3336         DP(NETIF_MSG_LINK, "Set AER to 0x%x\n", aer_val);
3337         CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3338                           MDIO_AER_BLOCK_AER_REG, aer_val);
3339
3340 }
3341
3342 /******************************************************************/
3343 /*                      Internal phy section                      */
3344 /******************************************************************/
3345
3346 static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
3347 {
3348         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3349
3350         /* Set Clause 22 */
3351         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
3352         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
3353         udelay(500);
3354         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
3355         udelay(500);
3356          /* Set Clause 45 */
3357         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
3358 }
3359
3360 static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
3361 {
3362         u32 val;
3363
3364         DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
3365
3366         val = SERDES_RESET_BITS << (port*16);
3367
3368         /* reset and unreset the SerDes/XGXS */
3369         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3370         udelay(500);
3371         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3372
3373         bnx2x_set_serdes_access(bp, port);
3374
3375         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
3376                DEFAULT_PHY_DEV_ADDR);
3377 }
3378
3379 static void bnx2x_xgxs_deassert(struct link_params *params)
3380 {
3381         struct bnx2x *bp = params->bp;
3382         u8 port;
3383         u32 val;
3384         DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
3385         port = params->port;
3386
3387         val = XGXS_RESET_BITS << (port*16);
3388
3389         /* reset and unreset the SerDes/XGXS */
3390         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3391         udelay(500);
3392         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3393
3394         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
3395         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3396                params->phy[INT_PHY].def_md_devad);
3397 }
3398
3399 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
3400                                      struct link_params *params, u16 *ieee_fc)
3401 {
3402         struct bnx2x *bp = params->bp;
3403         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
3404         /**
3405          * resolve pause mode and advertisement Please refer to Table
3406          * 28B-3 of the 802.3ab-1999 spec
3407          */
3408
3409         switch (phy->req_flow_ctrl) {
3410         case BNX2X_FLOW_CTRL_AUTO:
3411                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
3412                         *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3413                 else
3414                         *ieee_fc |=
3415                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3416                 break;
3417
3418         case BNX2X_FLOW_CTRL_TX:
3419                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3420                 break;
3421
3422         case BNX2X_FLOW_CTRL_RX:
3423         case BNX2X_FLOW_CTRL_BOTH:
3424                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3425                 break;
3426
3427         case BNX2X_FLOW_CTRL_NONE:
3428         default:
3429                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3430                 break;
3431         }
3432         DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
3433 }
3434
3435 static void set_phy_vars(struct link_params *params,
3436                          struct link_vars *vars)
3437 {
3438         struct bnx2x *bp = params->bp;
3439         u8 actual_phy_idx, phy_index, link_cfg_idx;
3440         u8 phy_config_swapped = params->multi_phy_config &
3441                         PORT_HW_CFG_PHY_SWAPPED_ENABLED;
3442         for (phy_index = INT_PHY; phy_index < params->num_phys;
3443               phy_index++) {
3444                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
3445                 actual_phy_idx = phy_index;
3446                 if (phy_config_swapped) {
3447                         if (phy_index == EXT_PHY1)
3448                                 actual_phy_idx = EXT_PHY2;
3449                         else if (phy_index == EXT_PHY2)
3450                                 actual_phy_idx = EXT_PHY1;
3451                 }
3452                 params->phy[actual_phy_idx].req_flow_ctrl =
3453                         params->req_flow_ctrl[link_cfg_idx];
3454
3455                 params->phy[actual_phy_idx].req_line_speed =
3456                         params->req_line_speed[link_cfg_idx];
3457
3458                 params->phy[actual_phy_idx].speed_cap_mask =
3459                         params->speed_cap_mask[link_cfg_idx];
3460
3461                 params->phy[actual_phy_idx].req_duplex =
3462                         params->req_duplex[link_cfg_idx];
3463
3464                 if (params->req_line_speed[link_cfg_idx] ==
3465                     SPEED_AUTO_NEG)
3466                         vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
3467
3468                 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
3469                            " speed_cap_mask %x\n",
3470                            params->phy[actual_phy_idx].req_flow_ctrl,
3471                            params->phy[actual_phy_idx].req_line_speed,
3472                            params->phy[actual_phy_idx].speed_cap_mask);
3473         }
3474 }
3475
3476 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3477                                     struct bnx2x_phy *phy,
3478                                     struct link_vars *vars)
3479 {
3480         u16 val;
3481         struct bnx2x *bp = params->bp;
3482         /* read modify write pause advertizing */
3483         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3484
3485         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3486
3487         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3488         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3489         if ((vars->ieee_fc &
3490             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3491             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3492                 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3493         }
3494         if ((vars->ieee_fc &
3495             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3496             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3497                 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3498         }
3499         DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3500         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3501 }
3502
3503 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
3504 {                                               /*  LD      LP   */
3505         switch (pause_result) {                 /* ASYM P ASYM P */
3506         case 0xb:                               /*   1  0   1  1 */
3507                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
3508                 break;
3509
3510         case 0xe:                               /*   1  1   1  0 */
3511                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
3512                 break;
3513
3514         case 0x5:                               /*   0  1   0  1 */
3515         case 0x7:                               /*   0  1   1  1 */
3516         case 0xd:                               /*   1  1   0  1 */
3517         case 0xf:                               /*   1  1   1  1 */
3518                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
3519                 break;
3520
3521         default:
3522                 break;
3523         }
3524         if (pause_result & (1<<0))
3525                 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
3526         if (pause_result & (1<<1))
3527                 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
3528 }
3529
3530 static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3531                                    struct link_params *params,
3532                                    struct link_vars *vars)
3533 {
3534         struct bnx2x *bp = params->bp;
3535         u16 ld_pause;           /* local */
3536         u16 lp_pause;           /* link partner */
3537         u16 pause_result;
3538         u8 ret = 0;
3539         /* read twice */
3540
3541         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3542
3543         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
3544                 vars->flow_ctrl = phy->req_flow_ctrl;
3545         else if (phy->req_line_speed != SPEED_AUTO_NEG)
3546                 vars->flow_ctrl = params->req_fc_auto_adv;
3547         else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3548                 ret = 1;
3549                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
3550                         bnx2x_cl22_read(bp, phy,
3551                                         0x4, &ld_pause);
3552                         bnx2x_cl22_read(bp, phy,
3553                                         0x5, &lp_pause);
3554                 } else {
3555                         bnx2x_cl45_read(bp, phy,
3556                                         MDIO_AN_DEVAD,
3557                                         MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3558                         bnx2x_cl45_read(bp, phy,
3559                                         MDIO_AN_DEVAD,
3560                                         MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3561                 }
3562                 pause_result = (ld_pause &
3563                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3564                 pause_result |= (lp_pause &
3565                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3566                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
3567                    pause_result);
3568                 bnx2x_pause_resolve(vars, pause_result);
3569         }
3570         return ret;
3571 }
3572 /******************************************************************/
3573 /*                      Warpcore section                          */
3574 /******************************************************************/
3575 /* The init_internal_warpcore should mirror the xgxs,
3576  * i.e. reset the lane (if needed), set aer for the
3577  * init configuration, and set/clear SGMII flag. Internal
3578  * phy init is done purely in phy_init stage.
3579  */
3580 static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
3581                                         struct link_params *params,
3582                                         struct link_vars *vars) {
3583         u16 val16 = 0, lane, bam37 = 0;
3584         struct bnx2x *bp = params->bp;
3585         DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
3586         /* Check adding advertisement for 1G KX */
3587         if (((vars->line_speed == SPEED_AUTO_NEG) &&
3588              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
3589             (vars->line_speed == SPEED_1000)) {
3590                 u16 sd_digital;
3591                 val16 |= (1<<5);
3592
3593                 /* Enable CL37 1G Parallel Detect */
3594                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3595                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital);
3596                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3597                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3598                                  (sd_digital | 0x1));
3599
3600                 DP(NETIF_MSG_LINK, "Advertize 1G\n");
3601         }
3602         if (((vars->line_speed == SPEED_AUTO_NEG) &&
3603              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
3604             (vars->line_speed ==  SPEED_10000)) {
3605                 /* Check adding advertisement for 10G KR */
3606                 val16 |= (1<<7);
3607                 /* Enable 10G Parallel Detect */
3608                 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3609                                 MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
3610
3611                 DP(NETIF_MSG_LINK, "Advertize 10G\n");
3612         }
3613
3614         /* Set Transmit PMD settings */
3615         lane = bnx2x_get_warpcore_lane(phy, params);
3616         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3617                       MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3618                      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3619                       (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3620                       (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3621         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3622                          MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
3623                          0x03f0);
3624         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3625                          MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
3626                          0x03f0);
3627         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3628                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3629                          0x383f);
3630
3631         /* Advertised speeds */
3632         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3633                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
3634
3635         /* Enable CL37 BAM */
3636         if (REG_RD(bp, params->shmem_base +
3637                    offsetof(struct shmem_region, dev_info.
3638                             port_hw_config[params->port].default_cfg)) &
3639             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
3640                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3641                                 MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, &bam37);
3642                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3643                         MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, bam37 | 1);
3644                 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
3645         }
3646
3647         /* Advertise pause */
3648         bnx2x_ext_phy_set_pause(params, phy, vars);
3649
3650         /* Enable Autoneg */
3651         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3652                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000);
3653
3654         /* Over 1G - AN local device user page 1 */
3655         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3656                         MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
3657
3658         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3659                         MDIO_WC_REG_DIGITAL5_MISC7, &val16);
3660
3661         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3662                          MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100);
3663 }
3664
3665 static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
3666                                       struct link_params *params,
3667                                       struct link_vars *vars)
3668 {
3669         struct bnx2x *bp = params->bp;
3670         u16 val;
3671
3672         /* Disable Autoneg */
3673         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3674                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
3675
3676         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3677                          MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
3678
3679         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3680                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00);
3681
3682         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3683                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0);
3684
3685         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3686                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3687
3688         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3689                         MDIO_WC_REG_DIGITAL3_UP1, 0x1);
3690
3691         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3692                          MDIO_WC_REG_DIGITAL5_MISC7, 0xa);
3693
3694         /* Disable CL36 PCS Tx */
3695         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3696                         MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0);
3697
3698         /* Double Wide Single Data Rate @ pll rate */
3699         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3700                         MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF);
3701
3702         /* Leave cl72 training enable, needed for KR */
3703         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3704                 MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
3705                 0x2);
3706
3707         /* Leave CL72 enabled */
3708         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3709                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3710                          &val);
3711         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3712                          MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3713                          val | 0x3800);
3714
3715         /* Set speed via PMA/PMD register */
3716         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3717                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3718
3719         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3720                          MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
3721
3722         /*Enable encoded forced speed */
3723         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3724                          MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
3725
3726         /* Turn TX scramble payload only the 64/66 scrambler */
3727         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3728                          MDIO_WC_REG_TX66_CONTROL, 0x9);
3729
3730         /* Turn RX scramble payload only the 64/66 scrambler */
3731         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3732                                  MDIO_WC_REG_RX66_CONTROL, 0xF9);
3733
3734         /* set and clear loopback to cause a reset to 64/66 decoder */
3735         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3736                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
3737         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3738                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3739
3740 }
3741
3742 static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
3743                                        struct link_params *params,
3744                                        u8 is_xfi)
3745 {
3746         struct bnx2x *bp = params->bp;
3747         u16 misc1_val, tap_val, tx_driver_val, lane, val;
3748         /* Hold rxSeqStart */
3749         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3750                         MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3751         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3752                          MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000));
3753
3754         /* Hold tx_fifo_reset */
3755         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3756                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3757         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3758                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1));
3759
3760         /* Disable CL73 AN */
3761         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3762
3763         /* Disable 100FX Enable and Auto-Detect */
3764         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3765                         MDIO_WC_REG_FX100_CTRL1, &val);
3766         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3767                          MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA));
3768
3769         /* Disable 100FX Idle detect */
3770         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3771                         MDIO_WC_REG_FX100_CTRL3, &val);
3772         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3773                          MDIO_WC_REG_FX100_CTRL3, (val | 0x0080));
3774
3775         /* Set Block address to Remote PHY & Clear forced_speed[5] */
3776         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3777                         MDIO_WC_REG_DIGITAL4_MISC3, &val);
3778         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3779                          MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F));
3780
3781         /* Turn off auto-detect & fiber mode */
3782         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3783                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3784         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3785                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3786                          (val & 0xFFEE));
3787
3788         /* Set filter_force_link, disable_false_link and parallel_detect */
3789         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3790                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
3791         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3792                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3793                          ((val | 0x0006) & 0xFFFE));
3794
3795         /* Set XFI / SFI */
3796         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3797                         MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
3798
3799         misc1_val &= ~(0x1f);
3800
3801         if (is_xfi) {
3802                 misc1_val |= 0x5;
3803                 tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3804                            (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3805                            (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3806                 tx_driver_val =
3807                       ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3808                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3809                        (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3810
3811         } else {
3812                 misc1_val |= 0x9;
3813                 tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3814                            (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3815                            (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3816                 tx_driver_val =
3817                       ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3818                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3819                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3820         }
3821         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3822                          MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
3823
3824         /* Set Transmit PMD settings */
3825         lane = bnx2x_get_warpcore_lane(phy, params);
3826         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3827                          MDIO_WC_REG_TX_FIR_TAP,
3828                          tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
3829         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3830                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3831                          tx_driver_val);
3832
3833         /* Enable fiber mode, enable and invert sig_det */
3834         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3835                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3836         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3837                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd);
3838
3839         /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
3840         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3841                         MDIO_WC_REG_DIGITAL4_MISC3, &val);
3842         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3843                          MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
3844
3845         /* 10G XFI Full Duplex */
3846         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3847                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
3848
3849         /* Release tx_fifo_reset */
3850         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3851                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3852         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3853                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE);
3854
3855         /* Release rxSeqStart */
3856         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3857                         MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3858         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3859                          MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF));
3860 }
3861
3862 static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp,
3863                                        struct bnx2x_phy *phy)
3864 {
3865         DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n");
3866 }
3867
3868 static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
3869                                          struct bnx2x_phy *phy,
3870                                          u16 lane)
3871 {
3872         /* Rx0 anaRxControl1G */
3873         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3874                          MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
3875
3876         /* Rx2 anaRxControl1G */
3877         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3878                          MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
3879
3880         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3881                          MDIO_WC_REG_RX66_SCW0, 0xE070);
3882
3883         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3884                          MDIO_WC_REG_RX66_SCW1, 0xC0D0);
3885
3886         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3887                          MDIO_WC_REG_RX66_SCW2, 0xA0B0);
3888
3889         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3890                          MDIO_WC_REG_RX66_SCW3, 0x8090);
3891
3892         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3893                          MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
3894
3895         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3896                          MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
3897
3898         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3899                          MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
3900
3901         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3902                          MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
3903
3904         /* Serdes Digital Misc1 */
3905         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3906                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
3907
3908         /* Serdes Digital4 Misc3 */
3909         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3910                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
3911
3912         /* Set Transmit PMD settings */
3913         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3914                          MDIO_WC_REG_TX_FIR_TAP,
3915                         ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3916                          (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3917                          (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
3918                          MDIO_WC_REG_TX_FIR_TAP_ENABLE));
3919         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3920                       MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3921                      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3922                       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3923                       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3924 }
3925
3926 static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
3927                                            struct link_params *params,
3928                                            u8 fiber_mode)
3929 {
3930         struct bnx2x *bp = params->bp;
3931         u16 val16, digctrl_kx1, digctrl_kx2;
3932         u8 lane;
3933
3934         lane = bnx2x_get_warpcore_lane(phy, params);
3935
3936         /* Clear XFI clock comp in non-10G single lane mode. */
3937         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3938                         MDIO_WC_REG_RX66_CONTROL, &val16);
3939         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3940                          MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
3941
3942         if (phy->req_line_speed == SPEED_AUTO_NEG) {
3943                 /* SGMII Autoneg */
3944                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3945                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3946                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3947                                  MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
3948                                  val16 | 0x1000);
3949                 DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
3950         } else {
3951                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3952                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3953                 val16 &= 0xcfbf;
3954                 switch (phy->req_line_speed) {
3955                 case SPEED_10:
3956                         break;
3957                 case SPEED_100:
3958                         val16 |= 0x2000;
3959                         break;
3960                 case SPEED_1000:
3961                         val16 |= 0x0040;
3962                         break;
3963                 default:
3964                         DP(NETIF_MSG_LINK, "Speed not supported: 0x%x"
3965                                            "\n", phy->req_line_speed);
3966                         return;
3967                 }
3968
3969                 if (phy->req_duplex == DUPLEX_FULL)
3970                         val16 |= 0x0100;
3971
3972                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3973                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
3974
3975                 DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
3976                                phy->req_line_speed);
3977                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3978                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3979                 DP(NETIF_MSG_LINK, "  (readback) %x\n", val16);
3980         }
3981
3982         /* SGMII Slave mode and disable signal detect */
3983         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3984                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
3985         if (fiber_mode)
3986                 digctrl_kx1 = 1;
3987         else
3988                 digctrl_kx1 &= 0xff4a;
3989
3990         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3991                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3992                         digctrl_kx1);
3993
3994         /* Turn off parallel detect */
3995         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3996                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
3997         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3998                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3999                         (digctrl_kx2 & ~(1<<2)));
4000
4001         /* Re-enable parallel detect */
4002         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4003                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4004                         (digctrl_kx2 | (1<<2)));
4005
4006         /* Enable autodet */
4007         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4008                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4009                         (digctrl_kx1 | 0x10));
4010 }
4011
4012 static void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
4013                                       struct bnx2x_phy *phy,
4014                                       u8 reset)
4015 {
4016         u16 val;
4017         /* Take lane out of reset after configuration is finished */
4018         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4019                         MDIO_WC_REG_DIGITAL5_MISC6, &val);
4020         if (reset)
4021                 val |= 0xC000;
4022         else
4023                 val &= 0x3FFF;
4024         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4025                          MDIO_WC_REG_DIGITAL5_MISC6, val);
4026         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4027                          MDIO_WC_REG_DIGITAL5_MISC6, &val);
4028 }
4029
4030
4031         /* Clear SFI/XFI link settings registers */
4032 static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
4033                                       struct link_params *params,
4034                                       u16 lane)
4035 {
4036         struct bnx2x *bp = params->bp;
4037         u16 val16;
4038
4039         /* Set XFI clock comp as default. */
4040         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4041                         MDIO_WC_REG_RX66_CONTROL, &val16);
4042         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4043                          MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13));
4044
4045         bnx2x_warpcore_reset_lane(bp, phy, 1);
4046         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
4047         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4048                          MDIO_WC_REG_FX100_CTRL1, 0x014a);
4049         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4050                          MDIO_WC_REG_FX100_CTRL3, 0x0800);
4051         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4052                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8008);
4053         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4054                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195);
4055         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4056                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007);
4057         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4058                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002);
4059         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4060                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000);
4061         lane = bnx2x_get_warpcore_lane(phy, params);
4062         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4063                          MDIO_WC_REG_TX_FIR_TAP, 0x0000);
4064         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4065                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
4066         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4067                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
4068         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4069                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140);
4070         bnx2x_warpcore_reset_lane(bp, phy, 0);
4071 }
4072
4073 static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
4074                                                 u32 chip_id,
4075                                                 u32 shmem_base, u8 port,
4076                                                 u8 *gpio_num, u8 *gpio_port)
4077 {
4078         u32 cfg_pin;
4079         *gpio_num = 0;
4080         *gpio_port = 0;
4081         if (CHIP_IS_E3(bp)) {
4082                 cfg_pin = (REG_RD(bp, shmem_base +
4083                                 offsetof(struct shmem_region,
4084                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4085                                 PORT_HW_CFG_E3_MOD_ABS_MASK) >>
4086                                 PORT_HW_CFG_E3_MOD_ABS_SHIFT;
4087
4088                 /*
4089                  * Should not happen. This function called upon interrupt
4090                  * triggered by GPIO ( since EPIO can only generate interrupts
4091                  * to MCP).
4092                  * So if this function was called and none of the GPIOs was set,
4093                  * it means the shit hit the fan.
4094                  */
4095                 if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
4096                     (cfg_pin > PIN_CFG_GPIO3_P1)) {
4097                         DP(NETIF_MSG_LINK, "ERROR: Invalid cfg pin %x for "
4098                                            "module detect indication\n",
4099                                        cfg_pin);
4100                         return -EINVAL;
4101                 }
4102
4103                 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
4104                 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
4105         } else {
4106                 *gpio_num = MISC_REGISTERS_GPIO_3;
4107                 *gpio_port = port;
4108         }
4109         DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port);
4110         return 0;
4111 }
4112
4113 static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
4114                                        struct link_params *params)
4115 {
4116         struct bnx2x *bp = params->bp;
4117         u8 gpio_num, gpio_port;
4118         u32 gpio_val;
4119         if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
4120                                       params->shmem_base, params->port,
4121                                       &gpio_num, &gpio_port) != 0)
4122                 return 0;
4123         gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
4124
4125         /* Call the handling function in case module is detected */
4126         if (gpio_val == 0)
4127                 return 1;
4128         else
4129                 return 0;
4130 }
4131
4132 static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
4133                                        struct link_params *params,
4134                                        struct link_vars *vars)
4135 {
4136         struct bnx2x *bp = params->bp;
4137         u32 serdes_net_if;
4138         u8 fiber_mode;
4139         u16 lane = bnx2x_get_warpcore_lane(phy, params);
4140         serdes_net_if = (REG_RD(bp, params->shmem_base +
4141                          offsetof(struct shmem_region, dev_info.
4142                                   port_hw_config[params->port].default_cfg)) &
4143                          PORT_HW_CFG_NET_SERDES_IF_MASK);
4144         DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
4145                            "serdes_net_if = 0x%x\n",
4146                        vars->line_speed, serdes_net_if);
4147         bnx2x_set_aer_mmd(params, phy);
4148
4149         vars->phy_flags |= PHY_XGXS_FLAG;
4150         if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
4151             (phy->req_line_speed &&
4152              ((phy->req_line_speed == SPEED_100) ||
4153               (phy->req_line_speed == SPEED_10)))) {
4154                 vars->phy_flags |= PHY_SGMII_FLAG;
4155                 DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
4156                 bnx2x_warpcore_clear_regs(phy, params, lane);
4157                 bnx2x_warpcore_set_sgmii_speed(phy, params, 0);
4158         } else {
4159                 switch (serdes_net_if) {
4160                 case PORT_HW_CFG_NET_SERDES_IF_KR:
4161                         /* Enable KR Auto Neg */
4162                         if (params->loopback_mode == LOOPBACK_NONE)
4163                                 bnx2x_warpcore_enable_AN_KR(phy, params, vars);
4164                         else {
4165                                 DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
4166                                 bnx2x_warpcore_set_10G_KR(phy, params, vars);
4167                         }
4168                         break;
4169
4170                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
4171                         bnx2x_warpcore_clear_regs(phy, params, lane);
4172                         if (vars->line_speed == SPEED_10000) {
4173                                 DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
4174                                 bnx2x_warpcore_set_10G_XFI(phy, params, 1);
4175                         } else {
4176                                 if (SINGLE_MEDIA_DIRECT(params)) {
4177                                         DP(NETIF_MSG_LINK, "1G Fiber\n");
4178                                         fiber_mode = 1;
4179                                 } else {
4180                                         DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
4181                                         fiber_mode = 0;
4182                                 }
4183                                 bnx2x_warpcore_set_sgmii_speed(phy,
4184                                                                 params,
4185                                                                 fiber_mode);
4186                         }
4187
4188                         break;
4189
4190                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
4191
4192                         bnx2x_warpcore_clear_regs(phy, params, lane);
4193                         if (vars->line_speed == SPEED_10000) {
4194                                 DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
4195                                 bnx2x_warpcore_set_10G_XFI(phy, params, 0);
4196                         } else if (vars->line_speed == SPEED_1000) {
4197                                 DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
4198                                 bnx2x_warpcore_set_sgmii_speed(phy, params, 1);
4199                         }
4200                         /* Issue Module detection */
4201                         if (bnx2x_is_sfp_module_plugged(phy, params))
4202                                 bnx2x_sfp_module_detection(phy, params);
4203                         break;
4204
4205                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
4206                         if (vars->line_speed != SPEED_20000) {
4207                                 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4208                                 return;
4209                         }
4210                         DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
4211                         bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
4212                         /* Issue Module detection */
4213
4214                         bnx2x_sfp_module_detection(phy, params);
4215                         break;
4216
4217                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
4218                         if (vars->line_speed != SPEED_20000) {
4219                                 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4220                                 return;
4221                         }
4222                         DP(NETIF_MSG_LINK, "Setting 20G KR2\n");
4223                         bnx2x_warpcore_set_20G_KR2(bp, phy);
4224                         break;
4225
4226                 default:
4227                         DP(NETIF_MSG_LINK, "Unsupported Serdes Net Interface "
4228                                            "0x%x\n", serdes_net_if);
4229                         return;
4230                 }
4231         }
4232
4233         /* Take lane out of reset after configuration is finished */
4234         bnx2x_warpcore_reset_lane(bp, phy, 0);
4235         DP(NETIF_MSG_LINK, "Exit config init\n");
4236 }
4237
4238 static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
4239                                          struct bnx2x_phy *phy,
4240                                          u8 tx_en)
4241 {
4242         struct bnx2x *bp = params->bp;
4243         u32 cfg_pin;
4244         u8 port = params->port;
4245
4246         cfg_pin = REG_RD(bp, params->shmem_base +
4247                                 offsetof(struct shmem_region,
4248                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4249                                 PORT_HW_CFG_TX_LASER_MASK;
4250         /* Set the !tx_en since this pin is DISABLE_TX_LASER */
4251         DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
4252         /* For 20G, the expected pin to be used is 3 pins after the current */
4253
4254         bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
4255         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
4256                 bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
4257 }
4258
4259 static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
4260                                       struct link_params *params)
4261 {
4262         struct bnx2x *bp = params->bp;
4263         u16 val16;
4264         bnx2x_sfp_e3_set_transmitter(params, phy, 0);
4265         bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
4266         bnx2x_set_aer_mmd(params, phy);
4267         /* Global register */
4268         bnx2x_warpcore_reset_lane(bp, phy, 1);
4269
4270         /* Clear loopback settings (if any) */
4271         /* 10G & 20G */
4272         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4273                         MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4274         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4275                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 &
4276                          0xBFFF);
4277
4278         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4279                         MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4280         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4281                         MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe);
4282
4283         /* Update those 1-copy registers */
4284         CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4285                           MDIO_AER_BLOCK_AER_REG, 0);
4286                 /* Enable 1G MDIO (1-copy) */
4287         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4288                         MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4289                         &val16);
4290         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4291                          MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4292                          val16 & ~0x10);
4293
4294         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4295                         MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4296         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4297                          MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4298                          val16 & 0xff00);
4299
4300 }
4301
4302 static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
4303                                         struct link_params *params)
4304 {
4305         struct bnx2x *bp = params->bp;
4306         u16 val16;
4307         u32 lane;
4308         DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
4309                        params->loopback_mode, phy->req_line_speed);
4310
4311         if (phy->req_line_speed < SPEED_10000) {
4312                 /* 10/100/1000 */
4313
4314                 /* Update those 1-copy registers */
4315                 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4316                                   MDIO_AER_BLOCK_AER_REG, 0);
4317                 /* Enable 1G MDIO (1-copy) */
4318                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4319                                 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4320                                 &val16);
4321                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4322                                 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4323                                 val16 | 0x10);
4324                 /* Set 1G loopback based on lane (1-copy) */
4325                 lane = bnx2x_get_warpcore_lane(phy, params);
4326                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4327                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4328                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4329                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4330                                 val16 | (1<<lane));
4331
4332                 /* Switch back to 4-copy registers */
4333                 bnx2x_set_aer_mmd(params, phy);
4334                 /* Global loopback, not recommended. */
4335                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4336                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4337                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4338                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
4339                                 0x4000);
4340         } else {
4341                 /* 10G & 20G */
4342                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4343                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4344                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4345                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
4346                                  0x4000);
4347
4348                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4349                                 MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4350                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4351                                 MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1);
4352         }
4353 }
4354
4355
4356 void bnx2x_link_status_update(struct link_params *params,
4357                               struct link_vars *vars)
4358 {
4359         struct bnx2x *bp = params->bp;
4360         u8 link_10g_plus;
4361         u8 port = params->port;
4362         u32 sync_offset, media_types;
4363         /* Update PHY configuration */
4364         set_phy_vars(params, vars);
4365
4366         vars->link_status = REG_RD(bp, params->shmem_base +
4367                                    offsetof(struct shmem_region,
4368                                             port_mb[port].link_status));
4369
4370         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4371         vars->phy_flags = PHY_XGXS_FLAG;
4372         if (vars->link_up) {
4373                 DP(NETIF_MSG_LINK, "phy link up\n");
4374
4375                 vars->phy_link_up = 1;
4376                 vars->duplex = DUPLEX_FULL;
4377                 switch (vars->link_status &
4378                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
4379                         case LINK_10THD:
4380                                 vars->duplex = DUPLEX_HALF;
4381                                 /* fall thru */
4382                         case LINK_10TFD:
4383                                 vars->line_speed = SPEED_10;
4384                                 break;
4385
4386                         case LINK_100TXHD:
4387                                 vars->duplex = DUPLEX_HALF;
4388                                 /* fall thru */
4389                         case LINK_100T4:
4390                         case LINK_100TXFD:
4391                                 vars->line_speed = SPEED_100;
4392                                 break;
4393
4394                         case LINK_1000THD:
4395                                 vars->duplex = DUPLEX_HALF;
4396                                 /* fall thru */
4397                         case LINK_1000TFD:
4398                                 vars->line_speed = SPEED_1000;
4399                                 break;
4400
4401                         case LINK_2500THD:
4402                                 vars->duplex = DUPLEX_HALF;
4403                                 /* fall thru */
4404                         case LINK_2500TFD:
4405                                 vars->line_speed = SPEED_2500;
4406                                 break;
4407
4408                         case LINK_10GTFD:
4409                                 vars->line_speed = SPEED_10000;
4410                                 break;
4411                         case LINK_20GTFD:
4412                                 vars->line_speed = SPEED_20000;
4413                                 break;
4414                         default:
4415                                 break;
4416                 }
4417                 vars->flow_ctrl = 0;
4418                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
4419                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
4420
4421                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
4422                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
4423
4424                 if (!vars->flow_ctrl)
4425                         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4426
4427                 if (vars->line_speed &&
4428                     ((vars->line_speed == SPEED_10) ||
4429                      (vars->line_speed == SPEED_100))) {
4430                         vars->phy_flags |= PHY_SGMII_FLAG;
4431                 } else {
4432                         vars->phy_flags &= ~PHY_SGMII_FLAG;
4433                 }
4434                 if (vars->line_speed &&
4435                     USES_WARPCORE(bp) &&
4436                     (vars->line_speed == SPEED_1000))
4437                         vars->phy_flags |= PHY_SGMII_FLAG;
4438                 /* anything 10 and over uses the bmac */
4439                 link_10g_plus = (vars->line_speed >= SPEED_10000);
4440
4441                 if (link_10g_plus) {
4442                         if (USES_WARPCORE(bp))
4443                                 vars->mac_type = MAC_TYPE_XMAC;
4444                         else
4445                                 vars->mac_type = MAC_TYPE_BMAC;
4446                 } else {
4447                         if (USES_WARPCORE(bp))
4448                                 vars->mac_type = MAC_TYPE_UMAC;
4449                         else
4450                                 vars->mac_type = MAC_TYPE_EMAC;
4451                 }
4452         } else { /* link down */
4453                 DP(NETIF_MSG_LINK, "phy link down\n");
4454
4455                 vars->phy_link_up = 0;
4456
4457                 vars->line_speed = 0;
4458                 vars->duplex = DUPLEX_FULL;
4459                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4460
4461                 /* indicate no mac active */
4462                 vars->mac_type = MAC_TYPE_NONE;
4463         }
4464
4465         /* Sync media type */
4466         sync_offset = params->shmem_base +
4467                         offsetof(struct shmem_region,
4468                                  dev_info.port_hw_config[port].media_type);
4469         media_types = REG_RD(bp, sync_offset);
4470
4471         params->phy[INT_PHY].media_type =
4472                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
4473                 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
4474         params->phy[EXT_PHY1].media_type =
4475                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
4476                 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
4477         params->phy[EXT_PHY2].media_type =
4478                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
4479                 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
4480         DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
4481
4482         /* Sync AEU offset */
4483         sync_offset = params->shmem_base +
4484                         offsetof(struct shmem_region,
4485                                  dev_info.port_hw_config[port].aeu_int_mask);
4486
4487         vars->aeu_int_mask = REG_RD(bp, sync_offset);
4488
4489         /* Sync PFC status */
4490         if (vars->link_status & LINK_STATUS_PFC_ENABLED)
4491                 params->feature_config_flags |=
4492                                         FEATURE_CONFIG_PFC_ENABLED;
4493         else
4494                 params->feature_config_flags &=
4495                                         ~FEATURE_CONFIG_PFC_ENABLED;
4496
4497         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
4498                  vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
4499         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
4500                  vars->line_speed, vars->duplex, vars->flow_ctrl);
4501 }
4502
4503
4504 static void bnx2x_set_master_ln(struct link_params *params,
4505                                 struct bnx2x_phy *phy)
4506 {
4507         struct bnx2x *bp = params->bp;
4508         u16 new_master_ln, ser_lane;
4509         ser_lane = ((params->lane_config &
4510                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4511                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4512
4513         /* set the master_ln for AN */
4514         CL22_RD_OVER_CL45(bp, phy,
4515                           MDIO_REG_BANK_XGXS_BLOCK2,
4516                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4517                           &new_master_ln);
4518
4519         CL22_WR_OVER_CL45(bp, phy,
4520                           MDIO_REG_BANK_XGXS_BLOCK2 ,
4521                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4522                           (new_master_ln | ser_lane));
4523 }
4524
4525 static int bnx2x_reset_unicore(struct link_params *params,
4526                                struct bnx2x_phy *phy,
4527                                u8 set_serdes)
4528 {
4529         struct bnx2x *bp = params->bp;
4530         u16 mii_control;
4531         u16 i;
4532         CL22_RD_OVER_CL45(bp, phy,
4533                           MDIO_REG_BANK_COMBO_IEEE0,
4534                           MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4535
4536         /* reset the unicore */
4537         CL22_WR_OVER_CL45(bp, phy,
4538                           MDIO_REG_BANK_COMBO_IEEE0,
4539                           MDIO_COMBO_IEEE0_MII_CONTROL,
4540                           (mii_control |
4541                            MDIO_COMBO_IEEO_MII_CONTROL_RESET));
4542         if (set_serdes)
4543                 bnx2x_set_serdes_access(bp, params->port);
4544
4545         /* wait for the reset to self clear */
4546         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
4547                 udelay(5);
4548
4549                 /* the reset erased the previous bank value */
4550                 CL22_RD_OVER_CL45(bp, phy,
4551                                   MDIO_REG_BANK_COMBO_IEEE0,
4552                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4553                                   &mii_control);
4554
4555                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
4556                         udelay(5);
4557                         return 0;
4558                 }
4559         }
4560
4561         netdev_err(bp->dev,  "Warning: PHY was not initialized,"
4562                               " Port %d\n",
4563                          params->port);
4564         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
4565         return -EINVAL;
4566
4567 }
4568
4569 static void bnx2x_set_swap_lanes(struct link_params *params,
4570                                  struct bnx2x_phy *phy)
4571 {
4572         struct bnx2x *bp = params->bp;
4573         /*
4574          *  Each two bits represents a lane number:
4575          *  No swap is 0123 => 0x1b no need to enable the swap
4576          */
4577         u16 ser_lane, rx_lane_swap, tx_lane_swap;
4578
4579         ser_lane = ((params->lane_config &
4580                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4581                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4582         rx_lane_swap = ((params->lane_config &
4583                          PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
4584                         PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
4585         tx_lane_swap = ((params->lane_config &
4586                          PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
4587                         PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
4588
4589         if (rx_lane_swap != 0x1b) {
4590                 CL22_WR_OVER_CL45(bp, phy,
4591                                   MDIO_REG_BANK_XGXS_BLOCK2,
4592                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP,
4593                                   (rx_lane_swap |
4594                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
4595                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
4596         } else {
4597                 CL22_WR_OVER_CL45(bp, phy,
4598                                   MDIO_REG_BANK_XGXS_BLOCK2,
4599                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
4600         }
4601
4602         if (tx_lane_swap != 0x1b) {
4603                 CL22_WR_OVER_CL45(bp, phy,
4604                                   MDIO_REG_BANK_XGXS_BLOCK2,
4605                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP,
4606                                   (tx_lane_swap |
4607                                    MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
4608         } else {
4609                 CL22_WR_OVER_CL45(bp, phy,
4610                                   MDIO_REG_BANK_XGXS_BLOCK2,
4611                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
4612         }
4613 }
4614
4615 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
4616                                          struct link_params *params)
4617 {
4618         struct bnx2x *bp = params->bp;
4619         u16 control2;
4620         CL22_RD_OVER_CL45(bp, phy,
4621                           MDIO_REG_BANK_SERDES_DIGITAL,
4622                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4623                           &control2);
4624         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4625                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4626         else
4627                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4628         DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
4629                 phy->speed_cap_mask, control2);
4630         CL22_WR_OVER_CL45(bp, phy,
4631                           MDIO_REG_BANK_SERDES_DIGITAL,
4632                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4633                           control2);
4634
4635         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4636              (phy->speed_cap_mask &
4637                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4638                 DP(NETIF_MSG_LINK, "XGXS\n");
4639
4640                 CL22_WR_OVER_CL45(bp, phy,
4641                                  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4642                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
4643                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
4644
4645                 CL22_RD_OVER_CL45(bp, phy,
4646                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
4647                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4648                                   &control2);
4649
4650
4651                 control2 |=
4652                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
4653
4654                 CL22_WR_OVER_CL45(bp, phy,
4655                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
4656                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4657                                   control2);
4658
4659                 /* Disable parallel detection of HiG */
4660                 CL22_WR_OVER_CL45(bp, phy,
4661                                   MDIO_REG_BANK_XGXS_BLOCK2,
4662                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
4663                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
4664                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
4665         }
4666 }
4667
4668 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
4669                               struct link_params *params,
4670                               struct link_vars *vars,
4671                               u8 enable_cl73)
4672 {
4673         struct bnx2x *bp = params->bp;
4674         u16 reg_val;
4675
4676         /* CL37 Autoneg */
4677         CL22_RD_OVER_CL45(bp, phy,
4678                           MDIO_REG_BANK_COMBO_IEEE0,
4679                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4680
4681         /* CL37 Autoneg Enabled */
4682         if (vars->line_speed == SPEED_AUTO_NEG)
4683                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
4684         else /* CL37 Autoneg Disabled */
4685                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4686                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
4687
4688         CL22_WR_OVER_CL45(bp, phy,
4689                           MDIO_REG_BANK_COMBO_IEEE0,
4690                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4691
4692         /* Enable/Disable Autodetection */
4693
4694         CL22_RD_OVER_CL45(bp, phy,
4695                           MDIO_REG_BANK_SERDES_DIGITAL,
4696                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
4697         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
4698                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
4699         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
4700         if (vars->line_speed == SPEED_AUTO_NEG)
4701                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4702         else
4703                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4704
4705         CL22_WR_OVER_CL45(bp, phy,
4706                           MDIO_REG_BANK_SERDES_DIGITAL,
4707                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
4708
4709         /* Enable TetonII and BAM autoneg */
4710         CL22_RD_OVER_CL45(bp, phy,
4711                           MDIO_REG_BANK_BAM_NEXT_PAGE,
4712                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4713                           &reg_val);
4714         if (vars->line_speed == SPEED_AUTO_NEG) {
4715                 /* Enable BAM aneg Mode and TetonII aneg Mode */
4716                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4717                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4718         } else {
4719                 /* TetonII and BAM Autoneg Disabled */
4720                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4721                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4722         }
4723         CL22_WR_OVER_CL45(bp, phy,
4724                           MDIO_REG_BANK_BAM_NEXT_PAGE,
4725                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4726                           reg_val);
4727
4728         if (enable_cl73) {
4729                 /* Enable Cl73 FSM status bits */
4730                 CL22_WR_OVER_CL45(bp, phy,
4731                                   MDIO_REG_BANK_CL73_USERB0,
4732                                   MDIO_CL73_USERB0_CL73_UCTRL,
4733                                   0xe);
4734
4735                 /* Enable BAM Station Manager*/
4736                 CL22_WR_OVER_CL45(bp, phy,
4737                         MDIO_REG_BANK_CL73_USERB0,
4738                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
4739                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
4740                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
4741                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
4742
4743                 /* Advertise CL73 link speeds */
4744                 CL22_RD_OVER_CL45(bp, phy,
4745                                   MDIO_REG_BANK_CL73_IEEEB1,
4746                                   MDIO_CL73_IEEEB1_AN_ADV2,
4747                                   &reg_val);
4748                 if (phy->speed_cap_mask &
4749                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4750                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
4751                 if (phy->speed_cap_mask &
4752                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4753                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
4754
4755                 CL22_WR_OVER_CL45(bp, phy,
4756                                   MDIO_REG_BANK_CL73_IEEEB1,
4757                                   MDIO_CL73_IEEEB1_AN_ADV2,
4758                                   reg_val);
4759
4760                 /* CL73 Autoneg Enabled */
4761                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
4762
4763         } else /* CL73 Autoneg Disabled */
4764                 reg_val = 0;
4765
4766         CL22_WR_OVER_CL45(bp, phy,
4767                           MDIO_REG_BANK_CL73_IEEEB0,
4768                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
4769 }
4770
4771 /* program SerDes, forced speed */
4772 static void bnx2x_program_serdes(struct bnx2x_phy *phy,
4773                                  struct link_params *params,
4774                                  struct link_vars *vars)
4775 {
4776         struct bnx2x *bp = params->bp;
4777         u16 reg_val;
4778
4779         /* program duplex, disable autoneg and sgmii*/
4780         CL22_RD_OVER_CL45(bp, phy,
4781                           MDIO_REG_BANK_COMBO_IEEE0,
4782                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4783         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
4784                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4785                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
4786         if (phy->req_duplex == DUPLEX_FULL)
4787                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
4788         CL22_WR_OVER_CL45(bp, phy,
4789                           MDIO_REG_BANK_COMBO_IEEE0,
4790                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4791
4792         /*
4793          * program speed
4794          *  - needed only if the speed is greater than 1G (2.5G or 10G)
4795          */
4796         CL22_RD_OVER_CL45(bp, phy,
4797                           MDIO_REG_BANK_SERDES_DIGITAL,
4798                           MDIO_SERDES_DIGITAL_MISC1, &reg_val);
4799         /* clearing the speed value before setting the right speed */
4800         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
4801
4802         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
4803                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
4804
4805         if (!((vars->line_speed == SPEED_1000) ||
4806               (vars->line_speed == SPEED_100) ||
4807               (vars->line_speed == SPEED_10))) {
4808
4809                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
4810                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
4811                 if (vars->line_speed == SPEED_10000)
4812                         reg_val |=
4813                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
4814         }
4815
4816         CL22_WR_OVER_CL45(bp, phy,
4817                           MDIO_REG_BANK_SERDES_DIGITAL,
4818                           MDIO_SERDES_DIGITAL_MISC1, reg_val);
4819
4820 }
4821
4822 static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy,
4823                                               struct link_params *params)
4824 {
4825         struct bnx2x *bp = params->bp;
4826         u16 val = 0;
4827
4828         /* configure the 48 bits for BAM AN */
4829
4830         /* set extended capabilities */
4831         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
4832                 val |= MDIO_OVER_1G_UP1_2_5G;
4833         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4834                 val |= MDIO_OVER_1G_UP1_10G;
4835         CL22_WR_OVER_CL45(bp, phy,
4836                           MDIO_REG_BANK_OVER_1G,
4837                           MDIO_OVER_1G_UP1, val);
4838
4839         CL22_WR_OVER_CL45(bp, phy,
4840                           MDIO_REG_BANK_OVER_1G,
4841                           MDIO_OVER_1G_UP3, 0x400);
4842 }
4843
4844 static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy,
4845                                               struct link_params *params,
4846                                               u16 ieee_fc)
4847 {
4848         struct bnx2x *bp = params->bp;
4849         u16 val;
4850         /* for AN, we are always publishing full duplex */
4851
4852         CL22_WR_OVER_CL45(bp, phy,
4853                           MDIO_REG_BANK_COMBO_IEEE0,
4854                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
4855         CL22_RD_OVER_CL45(bp, phy,
4856                           MDIO_REG_BANK_CL73_IEEEB1,
4857                           MDIO_CL73_IEEEB1_AN_ADV1, &val);
4858         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
4859         val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
4860         CL22_WR_OVER_CL45(bp, phy,
4861                           MDIO_REG_BANK_CL73_IEEEB1,
4862                           MDIO_CL73_IEEEB1_AN_ADV1, val);
4863 }
4864
4865 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
4866                                   struct link_params *params,
4867                                   u8 enable_cl73)
4868 {
4869         struct bnx2x *bp = params->bp;
4870         u16 mii_control;
4871
4872         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
4873         /* Enable and restart BAM/CL37 aneg */
4874
4875         if (enable_cl73) {
4876                 CL22_RD_OVER_CL45(bp, phy,
4877                                   MDIO_REG_BANK_CL73_IEEEB0,
4878                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4879                                   &mii_control);
4880
4881                 CL22_WR_OVER_CL45(bp, phy,
4882                                   MDIO_REG_BANK_CL73_IEEEB0,
4883                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4884                                   (mii_control |
4885                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
4886                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
4887         } else {
4888
4889                 CL22_RD_OVER_CL45(bp, phy,
4890                                   MDIO_REG_BANK_COMBO_IEEE0,
4891                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4892                                   &mii_control);
4893                 DP(NETIF_MSG_LINK,
4894                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
4895                          mii_control);
4896                 CL22_WR_OVER_CL45(bp, phy,
4897                                   MDIO_REG_BANK_COMBO_IEEE0,
4898                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4899                                   (mii_control |
4900                                    MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4901                                    MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
4902         }
4903 }
4904
4905 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
4906                                            struct link_params *params,
4907                                            struct link_vars *vars)
4908 {
4909         struct bnx2x *bp = params->bp;
4910         u16 control1;
4911
4912         /* in SGMII mode, the unicore is always slave */
4913
4914         CL22_RD_OVER_CL45(bp, phy,
4915                           MDIO_REG_BANK_SERDES_DIGITAL,
4916                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
4917                           &control1);
4918         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
4919         /* set sgmii mode (and not fiber) */
4920         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
4921                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
4922                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
4923         CL22_WR_OVER_CL45(bp, phy,
4924                           MDIO_REG_BANK_SERDES_DIGITAL,
4925                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
4926                           control1);
4927
4928         /* if forced speed */
4929         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
4930                 /* set speed, disable autoneg */
4931                 u16 mii_control;
4932
4933                 CL22_RD_OVER_CL45(bp, phy,
4934                                   MDIO_REG_BANK_COMBO_IEEE0,
4935                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4936                                   &mii_control);
4937                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4938                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
4939                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
4940
4941                 switch (vars->line_speed) {
4942                 case SPEED_100:
4943                         mii_control |=
4944                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
4945                         break;
4946                 case SPEED_1000:
4947                         mii_control |=
4948                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
4949                         break;
4950                 case SPEED_10:
4951                         /* there is nothing to set for 10M */
4952                         break;
4953                 default:
4954                         /* invalid speed for SGMII */
4955                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
4956                                   vars->line_speed);
4957                         break;
4958                 }
4959
4960                 /* setting the full duplex */
4961                 if (phy->req_duplex == DUPLEX_FULL)
4962                         mii_control |=
4963                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
4964                 CL22_WR_OVER_CL45(bp, phy,
4965                                   MDIO_REG_BANK_COMBO_IEEE0,
4966                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4967                                   mii_control);
4968
4969         } else { /* AN mode */
4970                 /* enable and restart AN */
4971                 bnx2x_restart_autoneg(phy, params, 0);
4972         }
4973 }
4974
4975
4976 /*
4977  * link management
4978  */
4979
4980 static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
4981                                              struct link_params *params)
4982 {
4983         struct bnx2x *bp = params->bp;
4984         u16 pd_10g, status2_1000x;
4985         if (phy->req_line_speed != SPEED_AUTO_NEG)
4986                 return 0;
4987         CL22_RD_OVER_CL45(bp, phy,
4988                           MDIO_REG_BANK_SERDES_DIGITAL,
4989                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
4990                           &status2_1000x);
4991         CL22_RD_OVER_CL45(bp, phy,
4992                           MDIO_REG_BANK_SERDES_DIGITAL,
4993                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
4994                           &status2_1000x);
4995         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
4996                 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
4997                          params->port);
4998                 return 1;
4999         }
5000
5001         CL22_RD_OVER_CL45(bp, phy,
5002                           MDIO_REG_BANK_10G_PARALLEL_DETECT,
5003                           MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
5004                           &pd_10g);
5005
5006         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
5007                 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
5008                          params->port);
5009                 return 1;
5010         }
5011         return 0;
5012 }
5013
5014 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
5015                                     struct link_params *params,
5016                                     struct link_vars *vars,
5017                                     u32 gp_status)
5018 {
5019         struct bnx2x *bp = params->bp;
5020         u16 ld_pause;   /* local driver */
5021         u16 lp_pause;   /* link partner */
5022         u16 pause_result;
5023
5024         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5025
5026         /* resolve from gp_status in case of AN complete and not sgmii */
5027         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
5028                 vars->flow_ctrl = phy->req_flow_ctrl;
5029         else if (phy->req_line_speed != SPEED_AUTO_NEG)
5030                 vars->flow_ctrl = params->req_fc_auto_adv;
5031         else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
5032                  (!(vars->phy_flags & PHY_SGMII_FLAG))) {
5033                 if (bnx2x_direct_parallel_detect_used(phy, params)) {
5034                         vars->flow_ctrl = params->req_fc_auto_adv;
5035                         return;
5036                 }
5037                 if ((gp_status &
5038                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5039                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
5040                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5041                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
5042
5043                         CL22_RD_OVER_CL45(bp, phy,
5044                                           MDIO_REG_BANK_CL73_IEEEB1,
5045                                           MDIO_CL73_IEEEB1_AN_ADV1,
5046                                           &ld_pause);
5047                         CL22_RD_OVER_CL45(bp, phy,
5048                                           MDIO_REG_BANK_CL73_IEEEB1,
5049                                           MDIO_CL73_IEEEB1_AN_LP_ADV1,
5050                                           &lp_pause);
5051                         pause_result = (ld_pause &
5052                                         MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
5053                                         >> 8;
5054                         pause_result |= (lp_pause &
5055                                         MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
5056                                         >> 10;
5057                         DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
5058                                  pause_result);
5059                 } else {
5060                         CL22_RD_OVER_CL45(bp, phy,
5061                                           MDIO_REG_BANK_COMBO_IEEE0,
5062                                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
5063                                           &ld_pause);
5064                         CL22_RD_OVER_CL45(bp, phy,
5065                                 MDIO_REG_BANK_COMBO_IEEE0,
5066                                 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
5067                                 &lp_pause);
5068                         pause_result = (ld_pause &
5069                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
5070                         pause_result |= (lp_pause &
5071                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
5072                         DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
5073                                  pause_result);
5074                 }
5075                 bnx2x_pause_resolve(vars, pause_result);
5076         }
5077         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
5078 }
5079
5080 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
5081                                          struct link_params *params)
5082 {
5083         struct bnx2x *bp = params->bp;
5084         u16 rx_status, ustat_val, cl37_fsm_received;
5085         DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
5086         /* Step 1: Make sure signal is detected */
5087         CL22_RD_OVER_CL45(bp, phy,
5088                           MDIO_REG_BANK_RX0,
5089                           MDIO_RX0_RX_STATUS,
5090                           &rx_status);
5091         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
5092             (MDIO_RX0_RX_STATUS_SIGDET)) {
5093                 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
5094                              "rx_status(0x80b0) = 0x%x\n", rx_status);
5095                 CL22_WR_OVER_CL45(bp, phy,
5096                                   MDIO_REG_BANK_CL73_IEEEB0,
5097                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5098                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
5099                 return;
5100         }
5101         /* Step 2: Check CL73 state machine */
5102         CL22_RD_OVER_CL45(bp, phy,
5103                           MDIO_REG_BANK_CL73_USERB0,
5104                           MDIO_CL73_USERB0_CL73_USTAT1,
5105                           &ustat_val);
5106         if ((ustat_val &
5107              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5108               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
5109             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5110               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
5111                 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
5112                              "ustat_val(0x8371) = 0x%x\n", ustat_val);
5113                 return;
5114         }
5115         /*
5116          * Step 3: Check CL37 Message Pages received to indicate LP
5117          * supports only CL37
5118          */
5119         CL22_RD_OVER_CL45(bp, phy,
5120                           MDIO_REG_BANK_REMOTE_PHY,
5121                           MDIO_REMOTE_PHY_MISC_RX_STATUS,
5122                           &cl37_fsm_received);
5123         if ((cl37_fsm_received &
5124              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5125              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
5126             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5127               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
5128                 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
5129                              "misc_rx_status(0x8330) = 0x%x\n",
5130                          cl37_fsm_received);
5131                 return;
5132         }
5133         /*
5134          * The combined cl37/cl73 fsm state information indicating that
5135          * we are connected to a device which does not support cl73, but
5136          * does support cl37 BAM. In this case we disable cl73 and
5137          * restart cl37 auto-neg
5138          */
5139
5140         /* Disable CL73 */
5141         CL22_WR_OVER_CL45(bp, phy,
5142                           MDIO_REG_BANK_CL73_IEEEB0,
5143                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5144                           0);
5145         /* Restart CL37 autoneg */
5146         bnx2x_restart_autoneg(phy, params, 0);
5147         DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
5148 }
5149
5150 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
5151                                   struct link_params *params,
5152                                   struct link_vars *vars,
5153                                   u32 gp_status)
5154 {
5155         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
5156                 vars->link_status |=
5157                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5158
5159         if (bnx2x_direct_parallel_detect_used(phy, params))
5160                 vars->link_status |=
5161                         LINK_STATUS_PARALLEL_DETECTION_USED;
5162 }
5163 static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
5164                                      struct link_params *params,
5165                                       struct link_vars *vars,
5166                                       u16 is_link_up,
5167                                       u16 speed_mask,
5168                                       u16 is_duplex)
5169 {
5170         struct bnx2x *bp = params->bp;
5171         if (phy->req_line_speed == SPEED_AUTO_NEG)
5172                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
5173         if (is_link_up) {
5174                 DP(NETIF_MSG_LINK, "phy link up\n");
5175
5176                 vars->phy_link_up = 1;
5177                 vars->link_status |= LINK_STATUS_LINK_UP;
5178
5179                 switch (speed_mask) {
5180                 case GP_STATUS_10M:
5181                         vars->line_speed = SPEED_10;
5182                         if (vars->duplex == DUPLEX_FULL)
5183                                 vars->link_status |= LINK_10TFD;
5184                         else
5185                                 vars->link_status |= LINK_10THD;
5186                         break;
5187
5188                 case GP_STATUS_100M:
5189                         vars->line_speed = SPEED_100;
5190                         if (vars->duplex == DUPLEX_FULL)
5191                                 vars->link_status |= LINK_100TXFD;
5192                         else
5193                                 vars->link_status |= LINK_100TXHD;
5194                         break;
5195
5196                 case GP_STATUS_1G:
5197                 case GP_STATUS_1G_KX:
5198                         vars->line_speed = SPEED_1000;
5199                         if (vars->duplex == DUPLEX_FULL)
5200                                 vars->link_status |= LINK_1000TFD;
5201                         else
5202                                 vars->link_status |= LINK_1000THD;
5203                         break;
5204
5205                 case GP_STATUS_2_5G:
5206                         vars->line_speed = SPEED_2500;
5207                         if (vars->duplex == DUPLEX_FULL)
5208                                 vars->link_status |= LINK_2500TFD;
5209                         else
5210                                 vars->link_status |= LINK_2500THD;
5211                         break;
5212
5213                 case GP_STATUS_5G:
5214                 case GP_STATUS_6G:
5215                         DP(NETIF_MSG_LINK,
5216                                  "link speed unsupported  gp_status 0x%x\n",
5217                                   speed_mask);
5218                         return -EINVAL;
5219
5220                 case GP_STATUS_10G_KX4:
5221                 case GP_STATUS_10G_HIG:
5222                 case GP_STATUS_10G_CX4:
5223                 case GP_STATUS_10G_KR:
5224                 case GP_STATUS_10G_SFI:
5225                 case GP_STATUS_10G_XFI:
5226                         vars->line_speed = SPEED_10000;
5227                         vars->link_status |= LINK_10GTFD;
5228                         break;
5229                 case GP_STATUS_20G_DXGXS:
5230                         vars->line_speed = SPEED_20000;
5231                         vars->link_status |= LINK_20GTFD;
5232                         break;
5233                 default:
5234                         DP(NETIF_MSG_LINK,
5235                                   "link speed unsupported gp_status 0x%x\n",
5236                                   speed_mask);
5237                         return -EINVAL;
5238                 }
5239         } else { /* link_down */
5240                 DP(NETIF_MSG_LINK, "phy link down\n");
5241
5242                 vars->phy_link_up = 0;
5243
5244                 vars->duplex = DUPLEX_FULL;
5245                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5246                 vars->mac_type = MAC_TYPE_NONE;
5247         }
5248         DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n",
5249                     vars->phy_link_up, vars->line_speed);
5250         return 0;
5251 }
5252
5253 static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
5254                                       struct link_params *params,
5255                                       struct link_vars *vars)
5256 {
5257
5258         struct bnx2x *bp = params->bp;
5259
5260         u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
5261         int rc = 0;
5262
5263         /* Read gp_status */
5264         CL22_RD_OVER_CL45(bp, phy,
5265                           MDIO_REG_BANK_GP_STATUS,
5266                           MDIO_GP_STATUS_TOP_AN_STATUS1,
5267                           &gp_status);
5268         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
5269                 duplex = DUPLEX_FULL;
5270         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
5271                 link_up = 1;
5272         speed_mask = gp_status & GP_STATUS_SPEED_MASK;
5273         DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
5274                        gp_status, link_up, speed_mask);
5275         rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
5276                                          duplex);
5277         if (rc == -EINVAL)
5278                 return rc;
5279
5280         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
5281                 if (SINGLE_MEDIA_DIRECT(params)) {
5282                         bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
5283                         if (phy->req_line_speed == SPEED_AUTO_NEG)
5284                                 bnx2x_xgxs_an_resolve(phy, params, vars,
5285                                                       gp_status);
5286                 }
5287         } else { /* link_down */
5288                 if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5289                     SINGLE_MEDIA_DIRECT(params)) {
5290                         /* Check signal is detected */
5291                         bnx2x_check_fallback_to_cl37(phy, params);
5292                 }
5293         }
5294
5295         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
5296                    vars->duplex, vars->flow_ctrl, vars->link_status);
5297         return rc;
5298 }
5299
5300 static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
5301                                      struct link_params *params,
5302                                      struct link_vars *vars)
5303 {
5304
5305         struct bnx2x *bp = params->bp;
5306
5307         u8 lane;
5308         u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
5309         int rc = 0;
5310         lane = bnx2x_get_warpcore_lane(phy, params);
5311         /* Read gp_status */
5312         if (phy->req_line_speed > SPEED_10000) {
5313                 u16 temp_link_up;
5314                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5315                                 1, &temp_link_up);
5316                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5317                                 1, &link_up);
5318                 DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n",
5319                                temp_link_up, link_up);
5320                 link_up &= (1<<2);
5321                 if (link_up)
5322                         bnx2x_ext_phy_resolve_fc(phy, params, vars);
5323         } else {
5324                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5325                                 MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1);
5326                 DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1);
5327                 /* Check for either KR or generic link up. */
5328                 gp_status1 = ((gp_status1 >> 8) & 0xf) |
5329                         ((gp_status1 >> 12) & 0xf);
5330                 link_up = gp_status1 & (1 << lane);
5331                 if (link_up && SINGLE_MEDIA_DIRECT(params)) {
5332                         u16 pd, gp_status4;
5333                         if (phy->req_line_speed == SPEED_AUTO_NEG) {
5334                                 /* Check Autoneg complete */
5335                                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5336                                                 MDIO_WC_REG_GP2_STATUS_GP_2_4,
5337                                                 &gp_status4);
5338                                 if (gp_status4 & ((1<<12)<<lane))
5339                                         vars->link_status |=
5340                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5341
5342                                 /* Check parallel detect used */
5343                                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5344                                                 MDIO_WC_REG_PAR_DET_10G_STATUS,
5345                                                 &pd);
5346                                 if (pd & (1<<15))
5347                                         vars->link_status |=
5348                                         LINK_STATUS_PARALLEL_DETECTION_USED;
5349                         }
5350                         bnx2x_ext_phy_resolve_fc(phy, params, vars);
5351                 }
5352         }
5353
5354         if (lane < 2) {
5355                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5356                                 MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
5357         } else {
5358                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5359                                 MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
5360         }
5361         DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed);
5362
5363         if ((lane & 1) == 0)
5364                 gp_speed <<= 8;
5365         gp_speed &= 0x3f00;
5366
5367
5368         rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
5369                                          duplex);
5370
5371         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
5372                    vars->duplex, vars->flow_ctrl, vars->link_status);
5373         return rc;
5374 }
5375 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
5376 {
5377         struct bnx2x *bp = params->bp;
5378         struct bnx2x_phy *phy = &params->phy[INT_PHY];
5379         u16 lp_up2;
5380         u16 tx_driver;
5381         u16 bank;
5382
5383         /* read precomp */
5384         CL22_RD_OVER_CL45(bp, phy,
5385                           MDIO_REG_BANK_OVER_1G,
5386                           MDIO_OVER_1G_LP_UP2, &lp_up2);
5387
5388         /* bits [10:7] at lp_up2, positioned at [15:12] */
5389         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
5390                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
5391                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
5392
5393         if (lp_up2 == 0)
5394                 return;
5395
5396         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
5397               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
5398                 CL22_RD_OVER_CL45(bp, phy,
5399                                   bank,
5400                                   MDIO_TX0_TX_DRIVER, &tx_driver);
5401
5402                 /* replace tx_driver bits [15:12] */
5403                 if (lp_up2 !=
5404                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
5405                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
5406                         tx_driver |= lp_up2;
5407                         CL22_WR_OVER_CL45(bp, phy,
5408                                           bank,
5409                                           MDIO_TX0_TX_DRIVER, tx_driver);
5410                 }
5411         }
5412 }
5413
5414 static int bnx2x_emac_program(struct link_params *params,
5415                               struct link_vars *vars)
5416 {
5417         struct bnx2x *bp = params->bp;
5418         u8 port = params->port;
5419         u16 mode = 0;
5420
5421         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
5422         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
5423                        EMAC_REG_EMAC_MODE,
5424                        (EMAC_MODE_25G_MODE |
5425                         EMAC_MODE_PORT_MII_10M |
5426                         EMAC_MODE_HALF_DUPLEX));
5427         switch (vars->line_speed) {
5428         case SPEED_10:
5429                 mode |= EMAC_MODE_PORT_MII_10M;
5430                 break;
5431
5432         case SPEED_100:
5433                 mode |= EMAC_MODE_PORT_MII;
5434                 break;
5435
5436         case SPEED_1000:
5437                 mode |= EMAC_MODE_PORT_GMII;
5438                 break;
5439
5440         case SPEED_2500:
5441                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
5442                 break;
5443
5444         default:
5445                 /* 10G not valid for EMAC */
5446                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5447                            vars->line_speed);
5448                 return -EINVAL;
5449         }
5450
5451         if (vars->duplex == DUPLEX_HALF)
5452                 mode |= EMAC_MODE_HALF_DUPLEX;
5453         bnx2x_bits_en(bp,
5454                       GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
5455                       mode);
5456
5457         bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
5458         return 0;
5459 }
5460
5461 static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
5462                                   struct link_params *params)
5463 {
5464
5465         u16 bank, i = 0;
5466         struct bnx2x *bp = params->bp;
5467
5468         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
5469               bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
5470                         CL22_WR_OVER_CL45(bp, phy,
5471                                           bank,
5472                                           MDIO_RX0_RX_EQ_BOOST,
5473                                           phy->rx_preemphasis[i]);
5474         }
5475
5476         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
5477                       bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
5478                         CL22_WR_OVER_CL45(bp, phy,
5479                                           bank,
5480                                           MDIO_TX0_TX_DRIVER,
5481                                           phy->tx_preemphasis[i]);
5482         }
5483 }
5484
5485 static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy,
5486                                    struct link_params *params,
5487                                    struct link_vars *vars)
5488 {
5489         struct bnx2x *bp = params->bp;
5490         u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
5491                           (params->loopback_mode == LOOPBACK_XGXS));
5492         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
5493                 if (SINGLE_MEDIA_DIRECT(params) &&
5494                     (params->feature_config_flags &
5495                      FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
5496                         bnx2x_set_preemphasis(phy, params);
5497
5498                 /* forced speed requested? */
5499                 if (vars->line_speed != SPEED_AUTO_NEG ||
5500                     (SINGLE_MEDIA_DIRECT(params) &&
5501                      params->loopback_mode == LOOPBACK_EXT)) {
5502                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
5503
5504                         /* disable autoneg */
5505                         bnx2x_set_autoneg(phy, params, vars, 0);
5506
5507                         /* program speed and duplex */
5508                         bnx2x_program_serdes(phy, params, vars);
5509
5510                 } else { /* AN_mode */
5511                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
5512
5513                         /* AN enabled */
5514                         bnx2x_set_brcm_cl37_advertisement(phy, params);
5515
5516                         /* program duplex & pause advertisement (for aneg) */
5517                         bnx2x_set_ieee_aneg_advertisement(phy, params,
5518                                                           vars->ieee_fc);
5519
5520                         /* enable autoneg */
5521                         bnx2x_set_autoneg(phy, params, vars, enable_cl73);
5522
5523                         /* enable and restart AN */
5524                         bnx2x_restart_autoneg(phy, params, enable_cl73);
5525                 }
5526
5527         } else { /* SGMII mode */
5528                 DP(NETIF_MSG_LINK, "SGMII\n");
5529
5530                 bnx2x_initialize_sgmii_process(phy, params, vars);
5531         }
5532 }
5533
5534 static int bnx2x_prepare_xgxs(struct bnx2x_phy *phy,
5535                           struct link_params *params,
5536                           struct link_vars *vars)
5537 {
5538         int rc;
5539         vars->phy_flags |= PHY_XGXS_FLAG;
5540         if ((phy->req_line_speed &&
5541              ((phy->req_line_speed == SPEED_100) ||
5542               (phy->req_line_speed == SPEED_10))) ||
5543             (!phy->req_line_speed &&
5544              (phy->speed_cap_mask >=
5545               PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5546              (phy->speed_cap_mask <
5547               PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
5548             (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
5549                 vars->phy_flags |= PHY_SGMII_FLAG;
5550         else
5551                 vars->phy_flags &= ~PHY_SGMII_FLAG;
5552
5553         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
5554         bnx2x_set_aer_mmd(params, phy);
5555         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
5556                 bnx2x_set_master_ln(params, phy);
5557
5558         rc = bnx2x_reset_unicore(params, phy, 0);
5559         /* reset the SerDes and wait for reset bit return low */
5560         if (rc != 0)
5561                 return rc;
5562
5563         bnx2x_set_aer_mmd(params, phy);
5564         /* setting the masterLn_def again after the reset */
5565         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5566                 bnx2x_set_master_ln(params, phy);
5567                 bnx2x_set_swap_lanes(params, phy);
5568         }
5569
5570         return rc;
5571 }
5572
5573 static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
5574                                      struct bnx2x_phy *phy,
5575                                      struct link_params *params)
5576 {
5577         u16 cnt, ctrl;
5578         /* Wait for soft reset to get cleared up to 1 sec */
5579         for (cnt = 0; cnt < 1000; cnt++) {
5580                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
5581                         bnx2x_cl22_read(bp, phy,
5582                                 MDIO_PMA_REG_CTRL, &ctrl);
5583                 else
5584                         bnx2x_cl45_read(bp, phy,
5585                                 MDIO_PMA_DEVAD,
5586                                 MDIO_PMA_REG_CTRL, &ctrl);
5587                 if (!(ctrl & (1<<15)))
5588                         break;
5589                 msleep(1);
5590         }
5591
5592         if (cnt == 1000)
5593                 netdev_err(bp->dev,  "Warning: PHY was not initialized,"
5594                                       " Port %d\n",
5595                          params->port);
5596         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
5597         return cnt;
5598 }
5599
5600 static void bnx2x_link_int_enable(struct link_params *params)
5601 {
5602         u8 port = params->port;
5603         u32 mask;
5604         struct bnx2x *bp = params->bp;
5605
5606         /* Setting the status to report on link up for either XGXS or SerDes */
5607         if (CHIP_IS_E3(bp)) {
5608                 mask = NIG_MASK_XGXS0_LINK_STATUS;
5609                 if (!(SINGLE_MEDIA_DIRECT(params)))
5610                         mask |= NIG_MASK_MI_INT;
5611         } else if (params->switch_cfg == SWITCH_CFG_10G) {
5612                 mask = (NIG_MASK_XGXS0_LINK10G |
5613                         NIG_MASK_XGXS0_LINK_STATUS);
5614                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5615                 if (!(SINGLE_MEDIA_DIRECT(params)) &&
5616                         params->phy[INT_PHY].type !=
5617                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
5618                         mask |= NIG_MASK_MI_INT;
5619                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5620                 }
5621
5622         } else { /* SerDes */
5623                 mask = NIG_MASK_SERDES0_LINK_STATUS;
5624                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5625                 if (!(SINGLE_MEDIA_DIRECT(params)) &&
5626                         params->phy[INT_PHY].type !=
5627                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
5628                         mask |= NIG_MASK_MI_INT;
5629                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5630                 }
5631         }
5632         bnx2x_bits_en(bp,
5633                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5634                       mask);
5635
5636         DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
5637                  (params->switch_cfg == SWITCH_CFG_10G),
5638                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5639         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5640                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5641                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5642                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5643         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5644            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5645            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5646 }
5647
5648 static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
5649                                      u8 exp_mi_int)
5650 {
5651         u32 latch_status = 0;
5652
5653         /*
5654          * Disable the MI INT ( external phy int ) by writing 1 to the
5655          * status register. Link down indication is high-active-signal,
5656          * so in this case we need to write the status to clear the XOR
5657          */
5658         /* Read Latched signals */
5659         latch_status = REG_RD(bp,
5660                                     NIG_REG_LATCH_STATUS_0 + port*8);
5661         DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
5662         /* Handle only those with latched-signal=up.*/
5663         if (exp_mi_int)
5664                 bnx2x_bits_en(bp,
5665                               NIG_REG_STATUS_INTERRUPT_PORT0
5666                               + port*4,
5667                               NIG_STATUS_EMAC0_MI_INT);
5668         else
5669                 bnx2x_bits_dis(bp,
5670                                NIG_REG_STATUS_INTERRUPT_PORT0
5671                                + port*4,
5672                                NIG_STATUS_EMAC0_MI_INT);
5673
5674         if (latch_status & 1) {
5675
5676                 /* For all latched-signal=up : Re-Arm Latch signals */
5677                 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
5678                        (latch_status & 0xfffe) | (latch_status & 1));
5679         }
5680         /* For all latched-signal=up,Write original_signal to status */
5681 }
5682
5683 static void bnx2x_link_int_ack(struct link_params *params,
5684                                struct link_vars *vars, u8 is_10g_plus)
5685 {
5686         struct bnx2x *bp = params->bp;
5687         u8 port = params->port;
5688         u32 mask;
5689         /*
5690          * First reset all status we assume only one line will be
5691          * change at a time
5692          */
5693         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5694                        (NIG_STATUS_XGXS0_LINK10G |
5695                         NIG_STATUS_XGXS0_LINK_STATUS |
5696                         NIG_STATUS_SERDES0_LINK_STATUS));
5697         if (vars->phy_link_up) {
5698                 if (USES_WARPCORE(bp))
5699                         mask = NIG_STATUS_XGXS0_LINK_STATUS;
5700                 else {
5701                         if (is_10g_plus)
5702                                 mask = NIG_STATUS_XGXS0_LINK10G;
5703                         else if (params->switch_cfg == SWITCH_CFG_10G) {
5704                                 /*
5705                                  * Disable the link interrupt by writing 1 to
5706                                  * the relevant lane in the status register
5707                                  */
5708                                 u32 ser_lane =
5709                                         ((params->lane_config &
5710                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5711                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5712                                 mask = ((1 << ser_lane) <<
5713                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
5714                         } else
5715                                 mask = NIG_STATUS_SERDES0_LINK_STATUS;
5716                 }
5717                 DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n",
5718                                mask);
5719                 bnx2x_bits_en(bp,
5720                               NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5721                               mask);
5722         }
5723 }
5724
5725 static int bnx2x_format_ver(u32 num, u8 *str, u16 *len)
5726 {
5727         u8 *str_ptr = str;
5728         u32 mask = 0xf0000000;
5729         u8 shift = 8*4;
5730         u8 digit;
5731         u8 remove_leading_zeros = 1;
5732         if (*len < 10) {
5733                 /* Need more than 10chars for this format */
5734                 *str_ptr = '\0';
5735                 (*len)--;
5736                 return -EINVAL;
5737         }
5738         while (shift > 0) {
5739
5740                 shift -= 4;
5741                 digit = ((num & mask) >> shift);
5742                 if (digit == 0 && remove_leading_zeros) {
5743                         mask = mask >> 4;
5744                         continue;
5745                 } else if (digit < 0xa)
5746                         *str_ptr = digit + '0';
5747                 else
5748                         *str_ptr = digit - 0xa + 'a';
5749                 remove_leading_zeros = 0;
5750                 str_ptr++;
5751                 (*len)--;
5752                 mask = mask >> 4;
5753                 if (shift == 4*4) {
5754                         *str_ptr = '.';
5755                         str_ptr++;
5756                         (*len)--;
5757                         remove_leading_zeros = 1;
5758                 }
5759         }
5760         return 0;
5761 }
5762
5763
5764 static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
5765 {
5766         str[0] = '\0';
5767         (*len)--;
5768         return 0;
5769 }
5770
5771 int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
5772                                  u8 *version, u16 len)
5773 {
5774         struct bnx2x *bp;
5775         u32 spirom_ver = 0;
5776         int status = 0;
5777         u8 *ver_p = version;
5778         u16 remain_len = len;
5779         if (version == NULL || params == NULL)
5780                 return -EINVAL;
5781         bp = params->bp;
5782
5783         /* Extract first external phy*/
5784         version[0] = '\0';
5785         spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
5786
5787         if (params->phy[EXT_PHY1].format_fw_ver) {
5788                 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
5789                                                               ver_p,
5790                                                               &remain_len);
5791                 ver_p += (len - remain_len);
5792         }
5793         if ((params->num_phys == MAX_PHYS) &&
5794             (params->phy[EXT_PHY2].ver_addr != 0)) {
5795                 spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr);
5796                 if (params->phy[EXT_PHY2].format_fw_ver) {
5797                         *ver_p = '/';
5798                         ver_p++;
5799                         remain_len--;
5800                         status |= params->phy[EXT_PHY2].format_fw_ver(
5801                                 spirom_ver,
5802                                 ver_p,
5803                                 &remain_len);
5804                         ver_p = version + (len - remain_len);
5805                 }
5806         }
5807         *ver_p = '\0';
5808         return status;
5809 }
5810
5811 static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
5812                                     struct link_params *params)
5813 {
5814         u8 port = params->port;
5815         struct bnx2x *bp = params->bp;
5816
5817         if (phy->req_line_speed != SPEED_1000) {
5818                 u32 md_devad = 0;
5819
5820                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
5821
5822                 if (!CHIP_IS_E3(bp)) {
5823                         /* change the uni_phy_addr in the nig */
5824                         md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
5825                                                port*0x18));
5826
5827                         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5828                                0x5);
5829                 }
5830
5831                 bnx2x_cl45_write(bp, phy,
5832                                  5,
5833                                  (MDIO_REG_BANK_AER_BLOCK +
5834                                   (MDIO_AER_BLOCK_AER_REG & 0xf)),
5835                                  0x2800);
5836
5837                 bnx2x_cl45_write(bp, phy,
5838                                  5,
5839                                  (MDIO_REG_BANK_CL73_IEEEB0 +
5840                                   (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5841                                  0x6041);
5842                 msleep(200);
5843                 /* set aer mmd back */
5844                 bnx2x_set_aer_mmd(params, phy);
5845
5846                 if (!CHIP_IS_E3(bp)) {
5847                         /* and md_devad */
5848                         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5849                                md_devad);
5850                 }
5851         } else {
5852                 u16 mii_ctrl;
5853                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
5854                 bnx2x_cl45_read(bp, phy, 5,
5855                                 (MDIO_REG_BANK_COMBO_IEEE0 +
5856                                 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
5857                                 &mii_ctrl);
5858                 bnx2x_cl45_write(bp, phy, 5,
5859                                  (MDIO_REG_BANK_COMBO_IEEE0 +
5860                                  (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
5861                                  mii_ctrl |
5862                                  MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
5863         }
5864 }
5865
5866 int bnx2x_set_led(struct link_params *params,
5867                   struct link_vars *vars, u8 mode, u32 speed)
5868 {
5869         u8 port = params->port;
5870         u16 hw_led_mode = params->hw_led_mode;
5871         int rc = 0;
5872         u8 phy_idx;
5873         u32 tmp;
5874         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5875         struct bnx2x *bp = params->bp;
5876         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5877         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5878                  speed, hw_led_mode);
5879         /* In case */
5880         for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
5881                 if (params->phy[phy_idx].set_link_led) {
5882                         params->phy[phy_idx].set_link_led(
5883                                 &params->phy[phy_idx], params, mode);
5884                 }
5885         }
5886
5887         switch (mode) {
5888         case LED_MODE_FRONT_PANEL_OFF:
5889         case LED_MODE_OFF:
5890                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
5891                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5892                        SHARED_HW_CFG_LED_MAC1);
5893
5894                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5895                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
5896                 break;
5897
5898         case LED_MODE_OPER:
5899                 /*
5900                  * For all other phys, OPER mode is same as ON, so in case
5901                  * link is down, do nothing
5902                  */
5903                 if (!vars->link_up)
5904                         break;
5905         case LED_MODE_ON:
5906                 if (((params->phy[EXT_PHY1].type ==
5907                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
5908                          (params->phy[EXT_PHY1].type ==
5909                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
5910                     CHIP_IS_E2(bp) && params->num_phys == 2) {
5911                         /*
5912                          * This is a work-around for E2+8727 Configurations
5913                          */
5914                         if (mode == LED_MODE_ON ||
5915                                 speed == SPEED_10000){
5916                                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
5917                                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
5918
5919                                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5920                                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
5921                                         (tmp | EMAC_LED_OVERRIDE));
5922                                 return rc;
5923                         }
5924                 } else if (SINGLE_MEDIA_DIRECT(params) &&
5925                            (CHIP_IS_E1x(bp) ||
5926                             CHIP_IS_E2(bp))) {
5927                         /*
5928                          * This is a work-around for HW issue found when link
5929                          * is up in CL73
5930                          */
5931                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
5932                         REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
5933                 } else {
5934                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
5935                 }
5936
5937                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
5938                 /* Set blinking rate to ~15.9Hz */
5939                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
5940                        LED_BLINK_RATE_VAL);
5941                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
5942                        port*4, 1);
5943                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5944                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp & (~EMAC_LED_OVERRIDE)));
5945
5946                 if (CHIP_IS_E1(bp) &&
5947                     ((speed == SPEED_2500) ||
5948                      (speed == SPEED_1000) ||
5949                      (speed == SPEED_100) ||
5950                      (speed == SPEED_10))) {
5951                         /*
5952                          * On Everest 1 Ax chip versions for speeds less than
5953                          * 10G LED scheme is different
5954                          */
5955                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5956                                + port*4, 1);
5957                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
5958                                port*4, 0);
5959                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
5960                                port*4, 1);
5961                 }
5962                 break;
5963
5964         default:
5965                 rc = -EINVAL;
5966                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
5967                          mode);
5968                 break;
5969         }
5970         return rc;
5971
5972 }
5973
5974 /*
5975  * This function comes to reflect the actual link state read DIRECTLY from the
5976  * HW
5977  */
5978 int bnx2x_test_link(struct link_params *params, struct link_vars *vars,
5979                     u8 is_serdes)
5980 {
5981         struct bnx2x *bp = params->bp;
5982         u16 gp_status = 0, phy_index = 0;
5983         u8 ext_phy_link_up = 0, serdes_phy_type;
5984         struct link_vars temp_vars;
5985         struct bnx2x_phy *int_phy = &params->phy[INT_PHY];
5986
5987         if (CHIP_IS_E3(bp)) {
5988                 u16 link_up;
5989                 if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)]
5990                     > SPEED_10000) {
5991                         /* Check 20G link */
5992                         bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
5993                                         1, &link_up);
5994                         bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
5995                                         1, &link_up);
5996                         link_up &= (1<<2);
5997                 } else {
5998                         /* Check 10G link and below*/
5999                         u8 lane = bnx2x_get_warpcore_lane(int_phy, params);
6000                         bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
6001                                         MDIO_WC_REG_GP2_STATUS_GP_2_1,
6002                                         &gp_status);
6003                         gp_status = ((gp_status >> 8) & 0xf) |
6004                                 ((gp_status >> 12) & 0xf);
6005                         link_up = gp_status & (1 << lane);
6006                 }
6007                 if (!link_up)
6008                         return -ESRCH;
6009         } else {
6010                 CL22_RD_OVER_CL45(bp, int_phy,
6011                           MDIO_REG_BANK_GP_STATUS,
6012                           MDIO_GP_STATUS_TOP_AN_STATUS1,
6013                           &gp_status);
6014         /* link is up only if both local phy and external phy are up */
6015         if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
6016                 return -ESRCH;
6017         }
6018         /* In XGXS loopback mode, do not check external PHY */
6019         if (params->loopback_mode == LOOPBACK_XGXS)
6020                 return 0;
6021
6022         switch (params->num_phys) {
6023         case 1:
6024                 /* No external PHY */
6025                 return 0;
6026         case 2:
6027                 ext_phy_link_up = params->phy[EXT_PHY1].read_status(
6028                         &params->phy[EXT_PHY1],
6029                         params, &temp_vars);
6030                 break;
6031         case 3: /* Dual Media */
6032                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6033                       phy_index++) {
6034                         serdes_phy_type = ((params->phy[phy_index].media_type ==
6035                                             ETH_PHY_SFP_FIBER) ||
6036                                            (params->phy[phy_index].media_type ==
6037                                             ETH_PHY_XFP_FIBER) ||
6038                                            (params->phy[phy_index].media_type ==
6039                                             ETH_PHY_DA_TWINAX));
6040
6041                         if (is_serdes != serdes_phy_type)
6042                                 continue;
6043                         if (params->phy[phy_index].read_status) {
6044                                 ext_phy_link_up |=
6045                                         params->phy[phy_index].read_status(
6046                                                 &params->phy[phy_index],
6047                                                 params, &temp_vars);
6048                         }
6049                 }
6050                 break;
6051         }
6052         if (ext_phy_link_up)
6053                 return 0;
6054         return -ESRCH;
6055 }
6056
6057 static int bnx2x_link_initialize(struct link_params *params,
6058                                  struct link_vars *vars)
6059 {
6060         int rc = 0;
6061         u8 phy_index, non_ext_phy;
6062         struct bnx2x *bp = params->bp;
6063         /*
6064          * In case of external phy existence, the line speed would be the
6065          * line speed linked up by the external phy. In case it is direct
6066          * only, then the line_speed during initialization will be
6067          * equal to the req_line_speed
6068          */
6069         vars->line_speed = params->phy[INT_PHY].req_line_speed;
6070
6071         /*
6072          * Initialize the internal phy in case this is a direct board
6073          * (no external phys), or this board has external phy which requires
6074          * to first.
6075          */
6076         if (!USES_WARPCORE(bp))
6077                 bnx2x_prepare_xgxs(&params->phy[INT_PHY], params, vars);
6078         /* init ext phy and enable link state int */
6079         non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
6080                        (params->loopback_mode == LOOPBACK_XGXS));
6081
6082         if (non_ext_phy ||
6083             (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
6084             (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6085                 struct bnx2x_phy *phy = &params->phy[INT_PHY];
6086                 if (vars->line_speed == SPEED_AUTO_NEG &&
6087                     (CHIP_IS_E1x(bp) ||
6088                      CHIP_IS_E2(bp)))
6089                         bnx2x_set_parallel_detection(phy, params);
6090                         if (params->phy[INT_PHY].config_init)
6091                                 params->phy[INT_PHY].config_init(phy,
6092                                                                  params,
6093                                                                  vars);
6094         }
6095
6096         /* Init external phy*/
6097         if (non_ext_phy) {
6098                 if (params->phy[INT_PHY].supported &
6099                     SUPPORTED_FIBRE)
6100                         vars->link_status |= LINK_STATUS_SERDES_LINK;
6101         } else {
6102                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6103                       phy_index++) {
6104                         /*
6105                          * No need to initialize second phy in case of first
6106                          * phy only selection. In case of second phy, we do
6107                          * need to initialize the first phy, since they are
6108                          * connected.
6109                          */
6110                         if (params->phy[phy_index].supported &
6111                             SUPPORTED_FIBRE)
6112                                 vars->link_status |= LINK_STATUS_SERDES_LINK;
6113
6114                         if (phy_index == EXT_PHY2 &&
6115                             (bnx2x_phy_selection(params) ==
6116                              PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
6117                                 DP(NETIF_MSG_LINK, "Not initializing"
6118                                                 " second phy\n");
6119                                 continue;
6120                         }
6121                         params->phy[phy_index].config_init(
6122                                 &params->phy[phy_index],
6123                                 params, vars);
6124                 }
6125         }
6126         /* Reset the interrupt indication after phy was initialized */
6127         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
6128                        params->port*4,
6129                        (NIG_STATUS_XGXS0_LINK10G |
6130                         NIG_STATUS_XGXS0_LINK_STATUS |
6131                         NIG_STATUS_SERDES0_LINK_STATUS |
6132                         NIG_MASK_MI_INT));
6133         bnx2x_update_mng(params, vars->link_status);
6134         return rc;
6135 }
6136
6137 static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
6138                                  struct link_params *params)
6139 {
6140         /* reset the SerDes/XGXS */
6141         REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6142                (0x1ff << (params->port*16)));
6143 }
6144
6145 static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
6146                                         struct link_params *params)
6147 {
6148         struct bnx2x *bp = params->bp;
6149         u8 gpio_port;
6150         /* HW reset */
6151         if (CHIP_IS_E2(bp))
6152                 gpio_port = BP_PATH(bp);
6153         else
6154                 gpio_port = params->port;
6155         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6156                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
6157                        gpio_port);
6158         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6159                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
6160                        gpio_port);
6161         DP(NETIF_MSG_LINK, "reset external PHY\n");
6162 }
6163
6164 static int bnx2x_update_link_down(struct link_params *params,
6165                                   struct link_vars *vars)
6166 {
6167         struct bnx2x *bp = params->bp;
6168         u8 port = params->port;
6169
6170         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
6171         bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
6172         vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
6173         /* indicate no mac active */
6174         vars->mac_type = MAC_TYPE_NONE;
6175
6176         /* update shared memory */
6177         vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
6178                                LINK_STATUS_LINK_UP |
6179                                LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
6180                                LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
6181                                LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
6182                                LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK);
6183         vars->line_speed = 0;
6184         bnx2x_update_mng(params, vars->link_status);
6185
6186         /* activate nig drain */
6187         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6188
6189         /* disable emac */
6190         if (!CHIP_IS_E3(bp))
6191                 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6192
6193         msleep(10);
6194         /* reset BigMac/Xmac */
6195         if (CHIP_IS_E1x(bp) ||
6196             CHIP_IS_E2(bp)) {
6197                 bnx2x_bmac_rx_disable(bp, params->port);
6198                 REG_WR(bp, GRCBASE_MISC +
6199                        MISC_REGISTERS_RESET_REG_2_CLEAR,
6200                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6201         }
6202         if (CHIP_IS_E3(bp))
6203                 bnx2x_xmac_disable(params);
6204
6205         return 0;
6206 }
6207
6208 static int bnx2x_update_link_up(struct link_params *params,
6209                                 struct link_vars *vars,
6210                                 u8 link_10g)
6211 {
6212         struct bnx2x *bp = params->bp;
6213         u8 port = params->port;
6214         int rc = 0;
6215
6216         vars->link_status |= LINK_STATUS_LINK_UP;
6217         vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
6218
6219         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
6220                 vars->link_status |=
6221                         LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
6222
6223         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
6224                 vars->link_status |=
6225                         LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
6226         if (USES_WARPCORE(bp)) {
6227                 if (link_10g) {
6228                         if (bnx2x_xmac_enable(params, vars, 0) ==
6229                             -ESRCH) {
6230                                 DP(NETIF_MSG_LINK, "Found errors on XMAC\n");
6231                                 vars->link_up = 0;
6232                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
6233                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
6234                         }
6235                 } else
6236                         bnx2x_umac_enable(params, vars, 0);
6237                 bnx2x_set_led(params, vars,
6238                               LED_MODE_OPER, vars->line_speed);
6239         }
6240         if ((CHIP_IS_E1x(bp) ||
6241              CHIP_IS_E2(bp))) {
6242                 if (link_10g) {
6243                         if (bnx2x_bmac_enable(params, vars, 0) ==
6244                             -ESRCH) {
6245                                 DP(NETIF_MSG_LINK, "Found errors on BMAC\n");
6246                                 vars->link_up = 0;
6247                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
6248                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
6249                         }
6250
6251                         bnx2x_set_led(params, vars,
6252                                       LED_MODE_OPER, SPEED_10000);
6253                 } else {
6254                         rc = bnx2x_emac_program(params, vars);
6255                         bnx2x_emac_enable(params, vars, 0);
6256
6257                         /* AN complete? */
6258                         if ((vars->link_status &
6259                              LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
6260                             && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
6261                             SINGLE_MEDIA_DIRECT(params))
6262                                 bnx2x_set_gmii_tx_driver(params);
6263                 }
6264         }
6265
6266         /* PBF - link up */
6267         if (CHIP_IS_E1x(bp))
6268                 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6269                                        vars->line_speed);
6270
6271         /* disable drain */
6272         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6273
6274         /* update shared memory */
6275         bnx2x_update_mng(params, vars->link_status);
6276         msleep(20);
6277         return rc;
6278 }
6279 /*
6280  * The bnx2x_link_update function should be called upon link
6281  * interrupt.
6282  * Link is considered up as follows:
6283  * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
6284  *   to be up
6285  * - SINGLE_MEDIA - The link between the 577xx and the external
6286  *   phy (XGXS) need to up as well as the external link of the
6287  *   phy (PHY_EXT1)
6288  * - DUAL_MEDIA - The link between the 577xx and the first
6289  *   external phy needs to be up, and at least one of the 2
6290  *   external phy link must be up.
6291  */
6292 int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6293 {
6294         struct bnx2x *bp = params->bp;
6295         struct link_vars phy_vars[MAX_PHYS];
6296         u8 port = params->port;
6297         u8 link_10g_plus, phy_index;
6298         u8 ext_phy_link_up = 0, cur_link_up;
6299         int rc = 0;
6300         u8 is_mi_int = 0;
6301         u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
6302         u8 active_external_phy = INT_PHY;
6303         vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
6304         for (phy_index = INT_PHY; phy_index < params->num_phys;
6305               phy_index++) {
6306                 phy_vars[phy_index].flow_ctrl = 0;
6307                 phy_vars[phy_index].link_status = 0;
6308                 phy_vars[phy_index].line_speed = 0;
6309                 phy_vars[phy_index].duplex = DUPLEX_FULL;
6310                 phy_vars[phy_index].phy_link_up = 0;
6311                 phy_vars[phy_index].link_up = 0;
6312                 phy_vars[phy_index].fault_detected = 0;
6313         }
6314
6315         if (USES_WARPCORE(bp))
6316                 bnx2x_set_aer_mmd(params, &params->phy[INT_PHY]);
6317
6318         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6319                  port, (vars->phy_flags & PHY_XGXS_FLAG),
6320                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6321
6322         is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6323                                 port*0x18) > 0);
6324         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6325                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6326                  is_mi_int,
6327                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6328
6329         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6330           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6331           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6332
6333         /* disable emac */
6334         if (!CHIP_IS_E3(bp))
6335                 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6336
6337         /*
6338          * Step 1:
6339          * Check external link change only for external phys, and apply
6340          * priority selection between them in case the link on both phys
6341          * is up. Note that instead of the common vars, a temporary
6342          * vars argument is used since each phy may have different link/
6343          * speed/duplex result
6344          */
6345         for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6346               phy_index++) {
6347                 struct bnx2x_phy *phy = &params->phy[phy_index];
6348                 if (!phy->read_status)
6349                         continue;
6350                 /* Read link status and params of this ext phy */
6351                 cur_link_up = phy->read_status(phy, params,
6352                                                &phy_vars[phy_index]);
6353                 if (cur_link_up) {
6354                         DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
6355                                    phy_index);
6356                 } else {
6357                         DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
6358                                    phy_index);
6359                         continue;
6360                 }
6361
6362                 if (!ext_phy_link_up) {
6363                         ext_phy_link_up = 1;
6364                         active_external_phy = phy_index;
6365                 } else {
6366                         switch (bnx2x_phy_selection(params)) {
6367                         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
6368                         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6369                         /*
6370                          * In this option, the first PHY makes sure to pass the
6371                          * traffic through itself only.
6372                          * Its not clear how to reset the link on the second phy
6373                          */
6374                                 active_external_phy = EXT_PHY1;
6375                                 break;
6376                         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6377                         /*
6378                          * In this option, the first PHY makes sure to pass the
6379                          * traffic through the second PHY.
6380                          */
6381                                 active_external_phy = EXT_PHY2;
6382                                 break;
6383                         default:
6384                         /*
6385                          * Link indication on both PHYs with the following cases
6386                          * is invalid:
6387                          * - FIRST_PHY means that second phy wasn't initialized,
6388                          * hence its link is expected to be down
6389                          * - SECOND_PHY means that first phy should not be able
6390                          * to link up by itself (using configuration)
6391                          * - DEFAULT should be overriden during initialiazation
6392                          */
6393                                 DP(NETIF_MSG_LINK, "Invalid link indication"
6394                                            "mpc=0x%x. DISABLING LINK !!!\n",
6395                                            params->multi_phy_config);
6396                                 ext_phy_link_up = 0;
6397                                 break;
6398                         }
6399                 }
6400         }
6401         prev_line_speed = vars->line_speed;
6402         /*
6403          * Step 2:
6404          * Read the status of the internal phy. In case of
6405          * DIRECT_SINGLE_MEDIA board, this link is the external link,
6406          * otherwise this is the link between the 577xx and the first
6407          * external phy
6408          */
6409         if (params->phy[INT_PHY].read_status)
6410                 params->phy[INT_PHY].read_status(
6411                         &params->phy[INT_PHY],
6412                         params, vars);
6413         /*
6414          * The INT_PHY flow control reside in the vars. This include the
6415          * case where the speed or flow control are not set to AUTO.
6416          * Otherwise, the active external phy flow control result is set
6417          * to the vars. The ext_phy_line_speed is needed to check if the
6418          * speed is different between the internal phy and external phy.
6419          * This case may be result of intermediate link speed change.
6420          */
6421         if (active_external_phy > INT_PHY) {
6422                 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
6423                 /*
6424                  * Link speed is taken from the XGXS. AN and FC result from
6425                  * the external phy.
6426                  */
6427                 vars->link_status |= phy_vars[active_external_phy].link_status;
6428
6429                 /*
6430                  * if active_external_phy is first PHY and link is up - disable
6431                  * disable TX on second external PHY
6432                  */
6433                 if (active_external_phy == EXT_PHY1) {
6434                         if (params->phy[EXT_PHY2].phy_specific_func) {
6435                                 DP(NETIF_MSG_LINK, "Disabling TX on"
6436                                                    " EXT_PHY2\n");
6437                                 params->phy[EXT_PHY2].phy_specific_func(
6438                                         &params->phy[EXT_PHY2],
6439                                         params, DISABLE_TX);
6440                         }
6441                 }
6442
6443                 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
6444                 vars->duplex = phy_vars[active_external_phy].duplex;
6445                 if (params->phy[active_external_phy].supported &
6446                     SUPPORTED_FIBRE)
6447                         vars->link_status |= LINK_STATUS_SERDES_LINK;
6448                 else
6449                         vars->link_status &= ~LINK_STATUS_SERDES_LINK;
6450                 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
6451                            active_external_phy);
6452         }
6453
6454         for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6455               phy_index++) {
6456                 if (params->phy[phy_index].flags &
6457                     FLAGS_REARM_LATCH_SIGNAL) {
6458                         bnx2x_rearm_latch_signal(bp, port,
6459                                                  phy_index ==
6460                                                  active_external_phy);
6461                         break;
6462                 }
6463         }
6464         DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
6465                    " ext_phy_line_speed = %d\n", vars->flow_ctrl,
6466                    vars->link_status, ext_phy_line_speed);
6467         /*
6468          * Upon link speed change set the NIG into drain mode. Comes to
6469          * deals with possible FIFO glitch due to clk change when speed
6470          * is decreased without link down indicator
6471          */
6472
6473         if (vars->phy_link_up) {
6474                 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
6475                     (ext_phy_line_speed != vars->line_speed)) {
6476                         DP(NETIF_MSG_LINK, "Internal link speed %d is"
6477                                    " different than the external"
6478                                    " link speed %d\n", vars->line_speed,
6479                                    ext_phy_line_speed);
6480                         vars->phy_link_up = 0;
6481                 } else if (prev_line_speed != vars->line_speed) {
6482                         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
6483                                0);
6484                         msleep(1);
6485                 }
6486         }
6487
6488         /* anything 10 and over uses the bmac */
6489         link_10g_plus = (vars->line_speed >= SPEED_10000);
6490
6491         bnx2x_link_int_ack(params, vars, link_10g_plus);
6492
6493         /*
6494          * In case external phy link is up, and internal link is down
6495          * (not initialized yet probably after link initialization, it
6496          * needs to be initialized.
6497          * Note that after link down-up as result of cable plug, the xgxs
6498          * link would probably become up again without the need
6499          * initialize it
6500          */
6501         if (!(SINGLE_MEDIA_DIRECT(params))) {
6502                 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
6503                            " init_preceding = %d\n", ext_phy_link_up,
6504                            vars->phy_link_up,
6505                            params->phy[EXT_PHY1].flags &
6506                            FLAGS_INIT_XGXS_FIRST);
6507                 if (!(params->phy[EXT_PHY1].flags &
6508                       FLAGS_INIT_XGXS_FIRST)
6509                     && ext_phy_link_up && !vars->phy_link_up) {
6510                         vars->line_speed = ext_phy_line_speed;
6511                         if (vars->line_speed < SPEED_1000)
6512                                 vars->phy_flags |= PHY_SGMII_FLAG;
6513                         else
6514                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
6515
6516                         if (params->phy[INT_PHY].config_init)
6517                                 params->phy[INT_PHY].config_init(
6518                                         &params->phy[INT_PHY], params,
6519                                                 vars);
6520                 }
6521         }
6522         /*
6523          * Link is up only if both local phy and external phy (in case of
6524          * non-direct board) are up and no fault detected on active PHY.
6525          */
6526         vars->link_up = (vars->phy_link_up &&
6527                          (ext_phy_link_up ||
6528                           SINGLE_MEDIA_DIRECT(params)) &&
6529                          (phy_vars[active_external_phy].fault_detected == 0));
6530
6531         if (vars->link_up)
6532                 rc = bnx2x_update_link_up(params, vars, link_10g_plus);
6533         else
6534                 rc = bnx2x_update_link_down(params, vars);
6535
6536         return rc;
6537 }
6538
6539
6540 /*****************************************************************************/
6541 /*                          External Phy section                             */
6542 /*****************************************************************************/
6543 void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
6544 {
6545         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6546                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6547         msleep(1);
6548         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6549                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6550 }
6551
6552 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
6553                                       u32 spirom_ver, u32 ver_addr)
6554 {
6555         DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
6556                  (u16)(spirom_ver>>16), (u16)spirom_ver, port);
6557
6558         if (ver_addr)
6559                 REG_WR(bp, ver_addr, spirom_ver);
6560 }
6561
6562 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
6563                                       struct bnx2x_phy *phy,
6564                                       u8 port)
6565 {
6566         u16 fw_ver1, fw_ver2;
6567
6568         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6569                         MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6570         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6571                         MDIO_PMA_REG_ROM_VER2, &fw_ver2);
6572         bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
6573                                   phy->ver_addr);
6574 }
6575
6576 static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
6577                                        struct bnx2x_phy *phy,
6578                                        struct link_vars *vars)
6579 {
6580         u16 val;
6581         bnx2x_cl45_read(bp, phy,
6582                         MDIO_AN_DEVAD,
6583                         MDIO_AN_REG_STATUS, &val);
6584         bnx2x_cl45_read(bp, phy,
6585                         MDIO_AN_DEVAD,
6586                         MDIO_AN_REG_STATUS, &val);
6587         if (val & (1<<5))
6588                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6589         if ((val & (1<<0)) == 0)
6590                 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
6591 }
6592
6593 /******************************************************************/
6594 /*              common BCM8073/BCM8727 PHY SECTION                */
6595 /******************************************************************/
6596 static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
6597                                   struct link_params *params,
6598                                   struct link_vars *vars)
6599 {
6600         struct bnx2x *bp = params->bp;
6601         if (phy->req_line_speed == SPEED_10 ||
6602             phy->req_line_speed == SPEED_100) {
6603                 vars->flow_ctrl = phy->req_flow_ctrl;
6604                 return;
6605         }
6606
6607         if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
6608             (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
6609                 u16 pause_result;
6610                 u16 ld_pause;           /* local */
6611                 u16 lp_pause;           /* link partner */
6612                 bnx2x_cl45_read(bp, phy,
6613                                 MDIO_AN_DEVAD,
6614                                 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
6615
6616                 bnx2x_cl45_read(bp, phy,
6617                                 MDIO_AN_DEVAD,
6618                                 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
6619                 pause_result = (ld_pause &
6620                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
6621                 pause_result |= (lp_pause &
6622                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
6623
6624                 bnx2x_pause_resolve(vars, pause_result);
6625                 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
6626                            pause_result);
6627         }
6628 }
6629 static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
6630                                              struct bnx2x_phy *phy,
6631                                              u8 port)
6632 {
6633         u32 count = 0;
6634         u16 fw_ver1, fw_msgout;
6635         int rc = 0;
6636
6637         /* Boot port from external ROM  */
6638         /* EDC grst */
6639         bnx2x_cl45_write(bp, phy,
6640                          MDIO_PMA_DEVAD,
6641                          MDIO_PMA_REG_GEN_CTRL,
6642                          0x0001);
6643
6644         /* ucode reboot and rst */
6645         bnx2x_cl45_write(bp, phy,
6646                          MDIO_PMA_DEVAD,
6647                          MDIO_PMA_REG_GEN_CTRL,
6648                          0x008c);
6649
6650         bnx2x_cl45_write(bp, phy,
6651                          MDIO_PMA_DEVAD,
6652                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
6653
6654         /* Reset internal microprocessor */
6655         bnx2x_cl45_write(bp, phy,
6656                          MDIO_PMA_DEVAD,
6657                          MDIO_PMA_REG_GEN_CTRL,
6658                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
6659
6660         /* Release srst bit */
6661         bnx2x_cl45_write(bp, phy,
6662                          MDIO_PMA_DEVAD,
6663                          MDIO_PMA_REG_GEN_CTRL,
6664                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
6665
6666         /* Delay 100ms per the PHY specifications */
6667         msleep(100);
6668
6669         /* 8073 sometimes taking longer to download */
6670         do {
6671                 count++;
6672                 if (count > 300) {
6673                         DP(NETIF_MSG_LINK,
6674                                  "bnx2x_8073_8727_external_rom_boot port %x:"
6675                                  "Download failed. fw version = 0x%x\n",
6676                                  port, fw_ver1);
6677                         rc = -EINVAL;
6678                         break;
6679                 }
6680
6681                 bnx2x_cl45_read(bp, phy,
6682                                 MDIO_PMA_DEVAD,
6683                                 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6684                 bnx2x_cl45_read(bp, phy,
6685                                 MDIO_PMA_DEVAD,
6686                                 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
6687
6688                 msleep(1);
6689         } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
6690                         ((fw_msgout & 0xff) != 0x03 && (phy->type ==
6691                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
6692
6693         /* Clear ser_boot_ctl bit */
6694         bnx2x_cl45_write(bp, phy,
6695                          MDIO_PMA_DEVAD,
6696                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
6697         bnx2x_save_bcm_spirom_ver(bp, phy, port);
6698
6699         DP(NETIF_MSG_LINK,
6700                  "bnx2x_8073_8727_external_rom_boot port %x:"
6701                  "Download complete. fw version = 0x%x\n",
6702                  port, fw_ver1);
6703
6704         return rc;
6705 }
6706
6707 /******************************************************************/
6708 /*                      BCM8073 PHY SECTION                       */
6709 /******************************************************************/
6710 static int bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
6711 {
6712         /* This is only required for 8073A1, version 102 only */
6713         u16 val;
6714
6715         /* Read 8073 HW revision*/
6716         bnx2x_cl45_read(bp, phy,
6717                         MDIO_PMA_DEVAD,
6718                         MDIO_PMA_REG_8073_CHIP_REV, &val);
6719
6720         if (val != 1) {
6721                 /* No need to workaround in 8073 A1 */
6722                 return 0;
6723         }
6724
6725         bnx2x_cl45_read(bp, phy,
6726                         MDIO_PMA_DEVAD,
6727                         MDIO_PMA_REG_ROM_VER2, &val);
6728
6729         /* SNR should be applied only for version 0x102 */
6730         if (val != 0x102)
6731                 return 0;
6732
6733         return 1;
6734 }
6735
6736 static int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
6737 {
6738         u16 val, cnt, cnt1 ;
6739
6740         bnx2x_cl45_read(bp, phy,
6741                         MDIO_PMA_DEVAD,
6742                         MDIO_PMA_REG_8073_CHIP_REV, &val);
6743
6744         if (val > 0) {
6745                 /* No need to workaround in 8073 A1 */
6746                 return 0;
6747         }
6748         /* XAUI workaround in 8073 A0: */
6749
6750         /*
6751          * After loading the boot ROM and restarting Autoneg, poll
6752          * Dev1, Reg $C820:
6753          */
6754
6755         for (cnt = 0; cnt < 1000; cnt++) {
6756                 bnx2x_cl45_read(bp, phy,
6757                                 MDIO_PMA_DEVAD,
6758                                 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
6759                                 &val);
6760                   /*
6761                    * If bit [14] = 0 or bit [13] = 0, continue on with
6762                    * system initialization (XAUI work-around not required, as
6763                    * these bits indicate 2.5G or 1G link up).
6764                    */
6765                 if (!(val & (1<<14)) || !(val & (1<<13))) {
6766                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
6767                         return 0;
6768                 } else if (!(val & (1<<15))) {
6769                         DP(NETIF_MSG_LINK, "bit 15 went off\n");
6770                         /*
6771                          * If bit 15 is 0, then poll Dev1, Reg $C841 until it's
6772                          * MSB (bit15) goes to 1 (indicating that the XAUI
6773                          * workaround has completed), then continue on with
6774                          * system initialization.
6775                          */
6776                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
6777                                 bnx2x_cl45_read(bp, phy,
6778                                         MDIO_PMA_DEVAD,
6779                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
6780                                 if (val & (1<<15)) {
6781                                         DP(NETIF_MSG_LINK,
6782                                           "XAUI workaround has completed\n");
6783                                         return 0;
6784                                  }
6785                                  msleep(3);
6786                         }
6787                         break;
6788                 }
6789                 msleep(3);
6790         }
6791         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
6792         return -EINVAL;
6793 }
6794
6795 static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
6796 {
6797         /* Force KR or KX */
6798         bnx2x_cl45_write(bp, phy,
6799                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
6800         bnx2x_cl45_write(bp, phy,
6801                          MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
6802         bnx2x_cl45_write(bp, phy,
6803                          MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
6804         bnx2x_cl45_write(bp, phy,
6805                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
6806 }
6807
6808 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
6809                                       struct bnx2x_phy *phy,
6810                                       struct link_vars *vars)
6811 {
6812         u16 cl37_val;
6813         struct bnx2x *bp = params->bp;
6814         bnx2x_cl45_read(bp, phy,
6815                         MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
6816
6817         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
6818         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
6819         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
6820         if ((vars->ieee_fc &
6821             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
6822             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
6823                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
6824         }
6825         if ((vars->ieee_fc &
6826             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
6827             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
6828                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
6829         }
6830         if ((vars->ieee_fc &
6831             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
6832             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
6833                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
6834         }
6835         DP(NETIF_MSG_LINK,
6836                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
6837
6838         bnx2x_cl45_write(bp, phy,
6839                          MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
6840         msleep(500);
6841 }
6842
6843 static int bnx2x_8073_config_init(struct bnx2x_phy *phy,
6844                                   struct link_params *params,
6845                                   struct link_vars *vars)
6846 {
6847         struct bnx2x *bp = params->bp;
6848         u16 val = 0, tmp1;
6849         u8 gpio_port;
6850         DP(NETIF_MSG_LINK, "Init 8073\n");
6851
6852         if (CHIP_IS_E2(bp))
6853                 gpio_port = BP_PATH(bp);
6854         else
6855                 gpio_port = params->port;
6856         /* Restore normal power mode*/
6857         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6858                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
6859
6860         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6861                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
6862
6863         /* enable LASI */
6864         bnx2x_cl45_write(bp, phy,
6865                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2));
6866         bnx2x_cl45_write(bp, phy,
6867                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
6868
6869         bnx2x_8073_set_pause_cl37(params, phy, vars);
6870
6871         bnx2x_cl45_read(bp, phy,
6872                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
6873
6874         bnx2x_cl45_read(bp, phy,
6875                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
6876
6877         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
6878
6879         /* Swap polarity if required - Must be done only in non-1G mode */
6880         if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
6881                 /* Configure the 8073 to swap _P and _N of the KR lines */
6882                 DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
6883                 /* 10G Rx/Tx and 1G Tx signal polarity swap */
6884                 bnx2x_cl45_read(bp, phy,
6885                                 MDIO_PMA_DEVAD,
6886                                 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
6887                 bnx2x_cl45_write(bp, phy,
6888                                  MDIO_PMA_DEVAD,
6889                                  MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
6890                                  (val | (3<<9)));
6891         }
6892
6893
6894         /* Enable CL37 BAM */
6895         if (REG_RD(bp, params->shmem_base +
6896                          offsetof(struct shmem_region, dev_info.
6897                                   port_hw_config[params->port].default_cfg)) &
6898             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
6899
6900                 bnx2x_cl45_read(bp, phy,
6901                                 MDIO_AN_DEVAD,
6902                                 MDIO_AN_REG_8073_BAM, &val);
6903                 bnx2x_cl45_write(bp, phy,
6904                                  MDIO_AN_DEVAD,
6905                                  MDIO_AN_REG_8073_BAM, val | 1);
6906                 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
6907         }
6908         if (params->loopback_mode == LOOPBACK_EXT) {
6909                 bnx2x_807x_force_10G(bp, phy);
6910                 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
6911                 return 0;
6912         } else {
6913                 bnx2x_cl45_write(bp, phy,
6914                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
6915         }
6916         if (phy->req_line_speed != SPEED_AUTO_NEG) {
6917                 if (phy->req_line_speed == SPEED_10000) {
6918                         val = (1<<7);
6919                 } else if (phy->req_line_speed ==  SPEED_2500) {
6920                         val = (1<<5);
6921                         /*
6922                          * Note that 2.5G works only when used with 1G
6923                          * advertisement
6924                          */
6925                 } else
6926                         val = (1<<5);
6927         } else {
6928                 val = 0;
6929                 if (phy->speed_cap_mask &
6930                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
6931                         val |= (1<<7);
6932
6933                 /* Note that 2.5G works only when used with 1G advertisement */
6934                 if (phy->speed_cap_mask &
6935                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
6936                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
6937                         val |= (1<<5);
6938                 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
6939         }
6940
6941         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
6942         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
6943
6944         if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
6945              (phy->req_line_speed == SPEED_AUTO_NEG)) ||
6946             (phy->req_line_speed == SPEED_2500)) {
6947                 u16 phy_ver;
6948                 /* Allow 2.5G for A1 and above */
6949                 bnx2x_cl45_read(bp, phy,
6950                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
6951                                 &phy_ver);
6952                 DP(NETIF_MSG_LINK, "Add 2.5G\n");
6953                 if (phy_ver > 0)
6954                         tmp1 |= 1;
6955                 else
6956                         tmp1 &= 0xfffe;
6957         } else {
6958                 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
6959                 tmp1 &= 0xfffe;
6960         }
6961
6962         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
6963         /* Add support for CL37 (passive mode) II */
6964
6965         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
6966         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
6967                          (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
6968                                   0x20 : 0x40)));
6969
6970         /* Add support for CL37 (passive mode) III */
6971         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
6972
6973         /*
6974          * The SNR will improve about 2db by changing BW and FEE main
6975          * tap. Rest commands are executed after link is up
6976          * Change FFE main cursor to 5 in EDC register
6977          */
6978         if (bnx2x_8073_is_snr_needed(bp, phy))
6979                 bnx2x_cl45_write(bp, phy,
6980                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
6981                                  0xFB0C);
6982
6983         /* Enable FEC (Forware Error Correction) Request in the AN */
6984         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
6985         tmp1 |= (1<<15);
6986         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
6987
6988         bnx2x_ext_phy_set_pause(params, phy, vars);
6989
6990         /* Restart autoneg */
6991         msleep(500);
6992         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
6993         DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
6994                    ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
6995         return 0;
6996 }
6997
6998 static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
6999                                  struct link_params *params,
7000                                  struct link_vars *vars)
7001 {
7002         struct bnx2x *bp = params->bp;
7003         u8 link_up = 0;
7004         u16 val1, val2;
7005         u16 link_status = 0;
7006         u16 an1000_status = 0;
7007
7008         bnx2x_cl45_read(bp, phy,
7009                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
7010
7011         DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
7012
7013         /* clear the interrupt LASI status register */
7014         bnx2x_cl45_read(bp, phy,
7015                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
7016         bnx2x_cl45_read(bp, phy,
7017                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
7018         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
7019         /* Clear MSG-OUT */
7020         bnx2x_cl45_read(bp, phy,
7021                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
7022
7023         /* Check the LASI */
7024         bnx2x_cl45_read(bp, phy,
7025                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
7026
7027         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
7028
7029         /* Check the link status */
7030         bnx2x_cl45_read(bp, phy,
7031                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
7032         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
7033
7034         bnx2x_cl45_read(bp, phy,
7035                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
7036         bnx2x_cl45_read(bp, phy,
7037                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
7038         link_up = ((val1 & 4) == 4);
7039         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
7040
7041         if (link_up &&
7042              ((phy->req_line_speed != SPEED_10000))) {
7043                 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
7044                         return 0;
7045         }
7046         bnx2x_cl45_read(bp, phy,
7047                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
7048         bnx2x_cl45_read(bp, phy,
7049                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
7050
7051         /* Check the link status on 1.1.2 */
7052         bnx2x_cl45_read(bp, phy,
7053                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
7054         bnx2x_cl45_read(bp, phy,
7055                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
7056         DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
7057                    "an_link_status=0x%x\n", val2, val1, an1000_status);
7058
7059         link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
7060         if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
7061                 /*
7062                  * The SNR will improve about 2dbby changing the BW and FEE main
7063                  * tap. The 1st write to change FFE main tap is set before
7064                  * restart AN. Change PLL Bandwidth in EDC register
7065                  */
7066                 bnx2x_cl45_write(bp, phy,
7067                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
7068                                  0x26BC);
7069
7070                 /* Change CDR Bandwidth in EDC register */
7071                 bnx2x_cl45_write(bp, phy,
7072                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
7073                                  0x0333);
7074         }
7075         bnx2x_cl45_read(bp, phy,
7076                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
7077                         &link_status);
7078
7079         /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
7080         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
7081                 link_up = 1;
7082                 vars->line_speed = SPEED_10000;
7083                 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
7084                            params->port);
7085         } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
7086                 link_up = 1;
7087                 vars->line_speed = SPEED_2500;
7088                 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
7089                            params->port);
7090         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
7091                 link_up = 1;
7092                 vars->line_speed = SPEED_1000;
7093                 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
7094                            params->port);
7095         } else {
7096                 link_up = 0;
7097                 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
7098                            params->port);
7099         }
7100
7101         if (link_up) {
7102                 /* Swap polarity if required */
7103                 if (params->lane_config &
7104                     PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
7105                         /* Configure the 8073 to swap P and N of the KR lines */
7106                         bnx2x_cl45_read(bp, phy,
7107                                         MDIO_XS_DEVAD,
7108                                         MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
7109                         /*
7110                          * Set bit 3 to invert Rx in 1G mode and clear this bit
7111                          * when it`s in 10G mode.
7112                          */
7113                         if (vars->line_speed == SPEED_1000) {
7114                                 DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
7115                                               "the 8073\n");
7116                                 val1 |= (1<<3);
7117                         } else
7118                                 val1 &= ~(1<<3);
7119
7120                         bnx2x_cl45_write(bp, phy,
7121                                          MDIO_XS_DEVAD,
7122                                          MDIO_XS_REG_8073_RX_CTRL_PCIE,
7123                                          val1);
7124                 }
7125                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
7126                 bnx2x_8073_resolve_fc(phy, params, vars);
7127                 vars->duplex = DUPLEX_FULL;
7128         }
7129         return link_up;
7130 }
7131
7132 static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
7133                                   struct link_params *params)
7134 {
7135         struct bnx2x *bp = params->bp;
7136         u8 gpio_port;
7137         if (CHIP_IS_E2(bp))
7138                 gpio_port = BP_PATH(bp);
7139         else
7140                 gpio_port = params->port;
7141         DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
7142            gpio_port);
7143         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7144                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
7145                        gpio_port);
7146 }
7147
7148 /******************************************************************/
7149 /*                      BCM8705 PHY SECTION                       */
7150 /******************************************************************/
7151 static int bnx2x_8705_config_init(struct bnx2x_phy *phy,
7152                                   struct link_params *params,
7153                                   struct link_vars *vars)
7154 {
7155         struct bnx2x *bp = params->bp;
7156         DP(NETIF_MSG_LINK, "init 8705\n");
7157         /* Restore normal power mode*/
7158         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7159                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
7160         /* HW reset */
7161         bnx2x_ext_phy_hw_reset(bp, params->port);
7162         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
7163         bnx2x_wait_reset_complete(bp, phy, params);
7164
7165         bnx2x_cl45_write(bp, phy,
7166                          MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
7167         bnx2x_cl45_write(bp, phy,
7168                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
7169         bnx2x_cl45_write(bp, phy,
7170                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
7171         bnx2x_cl45_write(bp, phy,
7172                          MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
7173         /* BCM8705 doesn't have microcode, hence the 0 */
7174         bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
7175         return 0;
7176 }
7177
7178 static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
7179                                  struct link_params *params,
7180                                  struct link_vars *vars)
7181 {
7182         u8 link_up = 0;
7183         u16 val1, rx_sd;
7184         struct bnx2x *bp = params->bp;
7185         DP(NETIF_MSG_LINK, "read status 8705\n");
7186         bnx2x_cl45_read(bp, phy,
7187                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7188         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
7189
7190         bnx2x_cl45_read(bp, phy,
7191                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7192         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
7193
7194         bnx2x_cl45_read(bp, phy,
7195                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
7196
7197         bnx2x_cl45_read(bp, phy,
7198                       MDIO_PMA_DEVAD, 0xc809, &val1);
7199         bnx2x_cl45_read(bp, phy,
7200                       MDIO_PMA_DEVAD, 0xc809, &val1);
7201
7202         DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
7203         link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
7204         if (link_up) {
7205                 vars->line_speed = SPEED_10000;
7206                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
7207         }
7208         return link_up;
7209 }
7210
7211 /******************************************************************/
7212 /*                      SFP+ module Section                       */
7213 /******************************************************************/
7214 static void bnx2x_set_disable_pmd_transmit(struct link_params *params,
7215                                            struct bnx2x_phy *phy,
7216                                            u8 pmd_dis)
7217 {
7218         struct bnx2x *bp = params->bp;
7219         /*
7220          * Disable transmitter only for bootcodes which can enable it afterwards
7221          * (for D3 link)
7222          */
7223         if (pmd_dis) {
7224                 if (params->feature_config_flags &
7225                      FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED)
7226                         DP(NETIF_MSG_LINK, "Disabling PMD transmitter\n");
7227                 else {
7228                         DP(NETIF_MSG_LINK, "NOT disabling PMD transmitter\n");
7229                         return;
7230                 }
7231         } else
7232                 DP(NETIF_MSG_LINK, "Enabling PMD transmitter\n");
7233         bnx2x_cl45_write(bp, phy,
7234                          MDIO_PMA_DEVAD,
7235                          MDIO_PMA_REG_TX_DISABLE, pmd_dis);
7236 }
7237
7238 static u8 bnx2x_get_gpio_port(struct link_params *params)
7239 {
7240         u8 gpio_port;
7241         u32 swap_val, swap_override;
7242         struct bnx2x *bp = params->bp;
7243         if (CHIP_IS_E2(bp))
7244                 gpio_port = BP_PATH(bp);
7245         else
7246                 gpio_port = params->port;
7247         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7248         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7249         return gpio_port ^ (swap_val && swap_override);
7250 }
7251
7252 static void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params,
7253                                            struct bnx2x_phy *phy,
7254                                            u8 tx_en)
7255 {
7256         u16 val;
7257         u8 port = params->port;
7258         struct bnx2x *bp = params->bp;
7259         u32 tx_en_mode;
7260
7261         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
7262         tx_en_mode = REG_RD(bp, params->shmem_base +
7263                             offsetof(struct shmem_region,
7264                                      dev_info.port_hw_config[port].sfp_ctrl)) &
7265                 PORT_HW_CFG_TX_LASER_MASK;
7266         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
7267                            "mode = %x\n", tx_en, port, tx_en_mode);
7268         switch (tx_en_mode) {
7269         case PORT_HW_CFG_TX_LASER_MDIO:
7270
7271                 bnx2x_cl45_read(bp, phy,
7272                                 MDIO_PMA_DEVAD,
7273                                 MDIO_PMA_REG_PHY_IDENTIFIER,
7274                                 &val);
7275
7276                 if (tx_en)
7277                         val &= ~(1<<15);
7278                 else
7279                         val |= (1<<15);
7280
7281                 bnx2x_cl45_write(bp, phy,
7282                                  MDIO_PMA_DEVAD,
7283                                  MDIO_PMA_REG_PHY_IDENTIFIER,
7284                                  val);
7285         break;
7286         case PORT_HW_CFG_TX_LASER_GPIO0:
7287         case PORT_HW_CFG_TX_LASER_GPIO1:
7288         case PORT_HW_CFG_TX_LASER_GPIO2:
7289         case PORT_HW_CFG_TX_LASER_GPIO3:
7290         {
7291                 u16 gpio_pin;
7292                 u8 gpio_port, gpio_mode;
7293                 if (tx_en)
7294                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
7295                 else
7296                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
7297
7298                 gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
7299                 gpio_port = bnx2x_get_gpio_port(params);
7300                 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
7301                 break;
7302         }
7303         default:
7304                 DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
7305                 break;
7306         }
7307 }
7308
7309 static void bnx2x_sfp_set_transmitter(struct link_params *params,
7310                                       struct bnx2x_phy *phy,
7311                                       u8 tx_en)
7312 {
7313         struct bnx2x *bp = params->bp;
7314         DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en);
7315         if (CHIP_IS_E3(bp))
7316                 bnx2x_sfp_e3_set_transmitter(params, phy, tx_en);
7317         else
7318                 bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en);
7319 }
7320
7321 static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7322                                              struct link_params *params,
7323                                              u16 addr, u8 byte_cnt, u8 *o_buf)
7324 {
7325         struct bnx2x *bp = params->bp;
7326         u16 val = 0;
7327         u16 i;
7328         if (byte_cnt > 16) {
7329                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
7330                             " is limited to 0xf\n");
7331                 return -EINVAL;
7332         }
7333         /* Set the read command byte count */
7334         bnx2x_cl45_write(bp, phy,
7335                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7336                          (byte_cnt | 0xa000));
7337
7338         /* Set the read command address */
7339         bnx2x_cl45_write(bp, phy,
7340                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7341                          addr);
7342
7343         /* Activate read command */
7344         bnx2x_cl45_write(bp, phy,
7345                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7346                          0x2c0f);
7347
7348         /* Wait up to 500us for command complete status */
7349         for (i = 0; i < 100; i++) {
7350                 bnx2x_cl45_read(bp, phy,
7351                                 MDIO_PMA_DEVAD,
7352                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7353                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7354                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7355                         break;
7356                 udelay(5);
7357         }
7358
7359         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7360                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7361                 DP(NETIF_MSG_LINK,
7362                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7363                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7364                 return -EINVAL;
7365         }
7366
7367         /* Read the buffer */
7368         for (i = 0; i < byte_cnt; i++) {
7369                 bnx2x_cl45_read(bp, phy,
7370                                 MDIO_PMA_DEVAD,
7371                                 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
7372                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
7373         }
7374
7375         for (i = 0; i < 100; i++) {
7376                 bnx2x_cl45_read(bp, phy,
7377                                 MDIO_PMA_DEVAD,
7378                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7379                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7380                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
7381                         return 0;
7382                 msleep(1);
7383         }
7384         return -EINVAL;
7385 }
7386
7387 static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7388                                                  struct link_params *params,
7389                                                  u16 addr, u8 byte_cnt,
7390                                                  u8 *o_buf)
7391 {
7392         int rc = 0;
7393         u8 i, j = 0, cnt = 0;
7394         u32 data_array[4];
7395         u16 addr32;
7396         struct bnx2x *bp = params->bp;
7397         /*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:"
7398                                         " addr %d, cnt %d\n",
7399                                         addr, byte_cnt);*/
7400         if (byte_cnt > 16) {
7401                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
7402                             " is limited to 16 bytes\n");
7403                 return -EINVAL;
7404         }
7405
7406         /* 4 byte aligned address */
7407         addr32 = addr & (~0x3);
7408         do {
7409                 rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
7410                                     data_array);
7411         } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT));
7412
7413         if (rc == 0) {
7414                 for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
7415                         o_buf[j] = *((u8 *)data_array + i);
7416                         j++;
7417                 }
7418         }
7419
7420         return rc;
7421 }
7422
7423 static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7424                                              struct link_params *params,
7425                                              u16 addr, u8 byte_cnt, u8 *o_buf)
7426 {
7427         struct bnx2x *bp = params->bp;
7428         u16 val, i;
7429
7430         if (byte_cnt > 16) {
7431                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
7432                             " is limited to 0xf\n");
7433                 return -EINVAL;
7434         }
7435
7436         /* Need to read from 1.8000 to clear it */
7437         bnx2x_cl45_read(bp, phy,
7438                         MDIO_PMA_DEVAD,
7439                         MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7440                         &val);
7441
7442         /* Set the read command byte count */
7443         bnx2x_cl45_write(bp, phy,
7444                          MDIO_PMA_DEVAD,
7445                          MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7446                          ((byte_cnt < 2) ? 2 : byte_cnt));
7447
7448         /* Set the read command address */
7449         bnx2x_cl45_write(bp, phy,
7450                          MDIO_PMA_DEVAD,
7451                          MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7452                          addr);
7453         /* Set the destination address */
7454         bnx2x_cl45_write(bp, phy,
7455                          MDIO_PMA_DEVAD,
7456                          0x8004,
7457                          MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
7458
7459         /* Activate read command */
7460         bnx2x_cl45_write(bp, phy,
7461                          MDIO_PMA_DEVAD,
7462                          MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7463                          0x8002);
7464         /*
7465          * Wait appropriate time for two-wire command to finish before
7466          * polling the status register
7467          */
7468         msleep(1);
7469
7470         /* Wait up to 500us for command complete status */
7471         for (i = 0; i < 100; i++) {
7472                 bnx2x_cl45_read(bp, phy,
7473                                 MDIO_PMA_DEVAD,
7474                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7475                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7476                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7477                         break;
7478                 udelay(5);
7479         }
7480
7481         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7482                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7483                 DP(NETIF_MSG_LINK,
7484                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7485                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7486                 return -EFAULT;
7487         }
7488
7489         /* Read the buffer */
7490         for (i = 0; i < byte_cnt; i++) {
7491                 bnx2x_cl45_read(bp, phy,
7492                                 MDIO_PMA_DEVAD,
7493                                 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
7494                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
7495         }
7496
7497         for (i = 0; i < 100; i++) {
7498                 bnx2x_cl45_read(bp, phy,
7499                                 MDIO_PMA_DEVAD,
7500                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7501                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7502                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
7503                         return 0;
7504                 msleep(1);
7505         }
7506
7507         return -EINVAL;
7508 }
7509
7510 int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7511                                  struct link_params *params, u16 addr,
7512                                  u8 byte_cnt, u8 *o_buf)
7513 {
7514         int rc = -EINVAL;
7515         switch (phy->type) {
7516         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7517                 rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
7518                                                        byte_cnt, o_buf);
7519         break;
7520         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7521         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7522                 rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
7523                                                        byte_cnt, o_buf);
7524         break;
7525         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
7526                 rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
7527                                                            byte_cnt, o_buf);
7528         break;
7529         }
7530         return rc;
7531 }
7532
7533 static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
7534                               struct link_params *params,
7535                               u16 *edc_mode)
7536 {
7537         struct bnx2x *bp = params->bp;
7538         u32 sync_offset = 0, phy_idx, media_types;
7539         u8 val, check_limiting_mode = 0;
7540         *edc_mode = EDC_MODE_LIMITING;
7541
7542         phy->media_type = ETH_PHY_UNSPECIFIED;
7543         /* First check for copper cable */
7544         if (bnx2x_read_sfp_module_eeprom(phy,
7545                                          params,
7546                                          SFP_EEPROM_CON_TYPE_ADDR,
7547                                          1,
7548                                          &val) != 0) {
7549                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
7550                 return -EINVAL;
7551         }
7552
7553         switch (val) {
7554         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
7555         {
7556                 u8 copper_module_type;
7557                 phy->media_type = ETH_PHY_DA_TWINAX;
7558                 /*
7559                  * Check if its active cable (includes SFP+ module)
7560                  * of passive cable
7561                  */
7562                 if (bnx2x_read_sfp_module_eeprom(phy,
7563                                                params,
7564                                                SFP_EEPROM_FC_TX_TECH_ADDR,
7565                                                1,
7566                                                &copper_module_type) != 0) {
7567                         DP(NETIF_MSG_LINK,
7568                                 "Failed to read copper-cable-type"
7569                                 " from SFP+ EEPROM\n");
7570                         return -EINVAL;
7571                 }
7572
7573                 if (copper_module_type &
7574                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
7575                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
7576                         check_limiting_mode = 1;
7577                 } else if (copper_module_type &
7578                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
7579                                 DP(NETIF_MSG_LINK, "Passive Copper"
7580                                             " cable detected\n");
7581                                 *edc_mode =
7582                                       EDC_MODE_PASSIVE_DAC;
7583                 } else {
7584                         DP(NETIF_MSG_LINK, "Unknown copper-cable-"
7585                                      "type 0x%x !!!\n", copper_module_type);
7586                         return -EINVAL;
7587                 }
7588                 break;
7589         }
7590         case SFP_EEPROM_CON_TYPE_VAL_LC:
7591                 phy->media_type = ETH_PHY_SFP_FIBER;
7592                 DP(NETIF_MSG_LINK, "Optic module detected\n");
7593                 check_limiting_mode = 1;
7594                 break;
7595         default:
7596                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
7597                          val);
7598                 return -EINVAL;
7599         }
7600         sync_offset = params->shmem_base +
7601                 offsetof(struct shmem_region,
7602                          dev_info.port_hw_config[params->port].media_type);
7603         media_types = REG_RD(bp, sync_offset);
7604         /* Update media type for non-PMF sync */
7605         for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
7606                 if (&(params->phy[phy_idx]) == phy) {
7607                         media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
7608                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
7609                         media_types |= ((phy->media_type &
7610                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
7611                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
7612                         break;
7613                 }
7614         }
7615         REG_WR(bp, sync_offset, media_types);
7616         if (check_limiting_mode) {
7617                 u8 options[SFP_EEPROM_OPTIONS_SIZE];
7618                 if (bnx2x_read_sfp_module_eeprom(phy,
7619                                                  params,
7620                                                  SFP_EEPROM_OPTIONS_ADDR,
7621                                                  SFP_EEPROM_OPTIONS_SIZE,
7622                                                  options) != 0) {
7623                         DP(NETIF_MSG_LINK, "Failed to read Option"
7624                                 " field from module EEPROM\n");
7625                         return -EINVAL;
7626                 }
7627                 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
7628                         *edc_mode = EDC_MODE_LINEAR;
7629                 else
7630                         *edc_mode = EDC_MODE_LIMITING;
7631         }
7632         DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
7633         return 0;
7634 }
7635 /*
7636  * This function read the relevant field from the module (SFP+), and verify it
7637  * is compliant with this board
7638  */
7639 static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
7640                                    struct link_params *params)
7641 {
7642         struct bnx2x *bp = params->bp;
7643         u32 val, cmd;
7644         u32 fw_resp, fw_cmd_param;
7645         char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
7646         char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
7647         phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
7648         val = REG_RD(bp, params->shmem_base +
7649                          offsetof(struct shmem_region, dev_info.
7650                                   port_feature_config[params->port].config));
7651         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
7652             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
7653                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
7654                 return 0;
7655         }
7656
7657         if (params->feature_config_flags &
7658             FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
7659                 /* Use specific phy request */
7660                 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
7661         } else if (params->feature_config_flags &
7662                    FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
7663                 /* Use first phy request only in case of non-dual media*/
7664                 if (DUAL_MEDIA(params)) {
7665                         DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
7666                            "verification\n");
7667                         return -EINVAL;
7668                 }
7669                 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
7670         } else {
7671                 /* No support in OPT MDL detection */
7672                 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
7673                           "verification\n");
7674                 return -EINVAL;
7675         }
7676
7677         fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
7678         fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
7679         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
7680                 DP(NETIF_MSG_LINK, "Approved module\n");
7681                 return 0;
7682         }
7683
7684         /* format the warning message */
7685         if (bnx2x_read_sfp_module_eeprom(phy,
7686                                          params,
7687                                          SFP_EEPROM_VENDOR_NAME_ADDR,
7688                                          SFP_EEPROM_VENDOR_NAME_SIZE,
7689                                          (u8 *)vendor_name))
7690                 vendor_name[0] = '\0';
7691         else
7692                 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
7693         if (bnx2x_read_sfp_module_eeprom(phy,
7694                                          params,
7695                                          SFP_EEPROM_PART_NO_ADDR,
7696                                          SFP_EEPROM_PART_NO_SIZE,
7697                                          (u8 *)vendor_pn))
7698                 vendor_pn[0] = '\0';
7699         else
7700                 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
7701
7702         netdev_err(bp->dev,  "Warning: Unqualified SFP+ module detected,"
7703                               " Port %d from %s part number %s\n",
7704                          params->port, vendor_name, vendor_pn);
7705         phy->flags |= FLAGS_SFP_NOT_APPROVED;
7706         return -EINVAL;
7707 }
7708
7709 static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
7710                                                  struct link_params *params)
7711
7712 {
7713         u8 val;
7714         struct bnx2x *bp = params->bp;
7715         u16 timeout;
7716         /*
7717          * Initialization time after hot-plug may take up to 300ms for
7718          * some phys type ( e.g. JDSU )
7719          */
7720
7721         for (timeout = 0; timeout < 60; timeout++) {
7722                 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
7723                     == 0) {
7724                         DP(NETIF_MSG_LINK, "SFP+ module initialization "
7725                                      "took %d ms\n", timeout * 5);
7726                         return 0;
7727                 }
7728                 msleep(5);
7729         }
7730         return -EINVAL;
7731 }
7732
7733 static void bnx2x_8727_power_module(struct bnx2x *bp,
7734                                     struct bnx2x_phy *phy,
7735                                     u8 is_power_up) {
7736         /* Make sure GPIOs are not using for LED mode */
7737         u16 val;
7738         /*
7739          * In the GPIO register, bit 4 is use to determine if the GPIOs are
7740          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
7741          * output
7742          * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
7743          * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
7744          * where the 1st bit is the over-current(only input), and 2nd bit is
7745          * for power( only output )
7746          *
7747          * In case of NOC feature is disabled and power is up, set GPIO control
7748          *  as input to enable listening of over-current indication
7749          */
7750         if (phy->flags & FLAGS_NOC)
7751                 return;
7752         if (is_power_up)
7753                 val = (1<<4);
7754         else
7755                 /*
7756                  * Set GPIO control to OUTPUT, and set the power bit
7757                  * to according to the is_power_up
7758                  */
7759                 val = (1<<1);
7760
7761         bnx2x_cl45_write(bp, phy,
7762                          MDIO_PMA_DEVAD,
7763                          MDIO_PMA_REG_8727_GPIO_CTRL,
7764                          val);
7765 }
7766
7767 static int bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
7768                                         struct bnx2x_phy *phy,
7769                                         u16 edc_mode)
7770 {
7771         u16 cur_limiting_mode;
7772
7773         bnx2x_cl45_read(bp, phy,
7774                         MDIO_PMA_DEVAD,
7775                         MDIO_PMA_REG_ROM_VER2,
7776                         &cur_limiting_mode);
7777         DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
7778                  cur_limiting_mode);
7779
7780         if (edc_mode == EDC_MODE_LIMITING) {
7781                 DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n");
7782                 bnx2x_cl45_write(bp, phy,
7783                                  MDIO_PMA_DEVAD,
7784                                  MDIO_PMA_REG_ROM_VER2,
7785                                  EDC_MODE_LIMITING);
7786         } else { /* LRM mode ( default )*/
7787
7788                 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
7789
7790                 /*
7791                  * Changing to LRM mode takes quite few seconds. So do it only
7792                  * if current mode is limiting (default is LRM)
7793                  */
7794                 if (cur_limiting_mode != EDC_MODE_LIMITING)
7795                         return 0;
7796
7797                 bnx2x_cl45_write(bp, phy,
7798                                  MDIO_PMA_DEVAD,
7799                                  MDIO_PMA_REG_LRM_MODE,
7800                                  0);
7801                 bnx2x_cl45_write(bp, phy,
7802                                  MDIO_PMA_DEVAD,
7803                                  MDIO_PMA_REG_ROM_VER2,
7804                                  0x128);
7805                 bnx2x_cl45_write(bp, phy,
7806                                  MDIO_PMA_DEVAD,
7807                                  MDIO_PMA_REG_MISC_CTRL0,
7808                                  0x4008);
7809                 bnx2x_cl45_write(bp, phy,
7810                                  MDIO_PMA_DEVAD,
7811                                  MDIO_PMA_REG_LRM_MODE,
7812                                  0xaaaa);
7813         }
7814         return 0;
7815 }
7816
7817 static int bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
7818                                         struct bnx2x_phy *phy,
7819                                         u16 edc_mode)
7820 {
7821         u16 phy_identifier;
7822         u16 rom_ver2_val;
7823         bnx2x_cl45_read(bp, phy,
7824                         MDIO_PMA_DEVAD,
7825                         MDIO_PMA_REG_PHY_IDENTIFIER,
7826                         &phy_identifier);
7827
7828         bnx2x_cl45_write(bp, phy,
7829                          MDIO_PMA_DEVAD,
7830                          MDIO_PMA_REG_PHY_IDENTIFIER,
7831                          (phy_identifier & ~(1<<9)));
7832
7833         bnx2x_cl45_read(bp, phy,
7834                         MDIO_PMA_DEVAD,
7835                         MDIO_PMA_REG_ROM_VER2,
7836                         &rom_ver2_val);
7837         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
7838         bnx2x_cl45_write(bp, phy,
7839                          MDIO_PMA_DEVAD,
7840                          MDIO_PMA_REG_ROM_VER2,
7841                          (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
7842
7843         bnx2x_cl45_write(bp, phy,
7844                          MDIO_PMA_DEVAD,
7845                          MDIO_PMA_REG_PHY_IDENTIFIER,
7846                          (phy_identifier | (1<<9)));
7847
7848         return 0;
7849 }
7850
7851 static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
7852                                      struct link_params *params,
7853                                      u32 action)
7854 {
7855         struct bnx2x *bp = params->bp;
7856
7857         switch (action) {
7858         case DISABLE_TX:
7859                 bnx2x_sfp_set_transmitter(params, phy, 0);
7860                 break;
7861         case ENABLE_TX:
7862                 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
7863                         bnx2x_sfp_set_transmitter(params, phy, 1);
7864                 break;
7865         default:
7866                 DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
7867                    action);
7868                 return;
7869         }
7870 }
7871
7872 static void bnx2x_set_e1e2_module_fault_led(struct link_params *params,
7873                                            u8 gpio_mode)
7874 {
7875         struct bnx2x *bp = params->bp;
7876
7877         u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
7878                             offsetof(struct shmem_region,
7879                         dev_info.port_hw_config[params->port].sfp_ctrl)) &
7880                 PORT_HW_CFG_FAULT_MODULE_LED_MASK;
7881         switch (fault_led_gpio) {
7882         case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
7883                 return;
7884         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
7885         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
7886         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
7887         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
7888         {
7889                 u8 gpio_port = bnx2x_get_gpio_port(params);
7890                 u16 gpio_pin = fault_led_gpio -
7891                         PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
7892                 DP(NETIF_MSG_LINK, "Set fault module-detected led "
7893                                    "pin %x port %x mode %x\n",
7894                                gpio_pin, gpio_port, gpio_mode);
7895                 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
7896         }
7897         break;
7898         default:
7899                 DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
7900                                fault_led_gpio);
7901         }
7902 }
7903
7904 static void bnx2x_set_e3_module_fault_led(struct link_params *params,
7905                                           u8 gpio_mode)
7906 {
7907         u32 pin_cfg;
7908         u8 port = params->port;
7909         struct bnx2x *bp = params->bp;
7910         pin_cfg = (REG_RD(bp, params->shmem_base +
7911                          offsetof(struct shmem_region,
7912                                   dev_info.port_hw_config[port].e3_sfp_ctrl)) &
7913                 PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
7914                 PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
7915         DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n",
7916                        gpio_mode, pin_cfg);
7917         bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode);
7918 }
7919
7920 static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
7921                                            u8 gpio_mode)
7922 {
7923         struct bnx2x *bp = params->bp;
7924         DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode);
7925         if (CHIP_IS_E3(bp)) {
7926                 /*
7927                  * Low ==> if SFP+ module is supported otherwise
7928                  * High ==> if SFP+ module is not on the approved vendor list
7929                  */
7930                 bnx2x_set_e3_module_fault_led(params, gpio_mode);
7931         } else
7932                 bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
7933 }
7934
7935 static void bnx2x_warpcore_power_module(struct link_params *params,
7936                                         struct bnx2x_phy *phy,
7937                                         u8 power)
7938 {
7939         u32 pin_cfg;
7940         struct bnx2x *bp = params->bp;
7941
7942         pin_cfg = (REG_RD(bp, params->shmem_base +
7943                           offsetof(struct shmem_region,
7944                         dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
7945                         PORT_HW_CFG_E3_PWR_DIS_MASK) >>
7946                         PORT_HW_CFG_E3_PWR_DIS_SHIFT;
7947
7948         if (pin_cfg == PIN_CFG_NA)
7949                 return;
7950         DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
7951                        power, pin_cfg);
7952         /*
7953          * Low ==> corresponding SFP+ module is powered
7954          * high ==> the SFP+ module is powered down
7955          */
7956         bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
7957 }
7958
7959 static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy,
7960                                     struct link_params *params)
7961 {
7962         bnx2x_warpcore_power_module(params, phy, 0);
7963 }
7964
7965 static void bnx2x_power_sfp_module(struct link_params *params,
7966                                    struct bnx2x_phy *phy,
7967                                    u8 power)
7968 {
7969         struct bnx2x *bp = params->bp;
7970         DP(NETIF_MSG_LINK, "Setting SFP+ power to %x\n", power);
7971
7972         switch (phy->type) {
7973         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7974         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7975                 bnx2x_8727_power_module(params->bp, phy, power);
7976                 break;
7977         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
7978                 bnx2x_warpcore_power_module(params, phy, power);
7979                 break;
7980         default:
7981                 break;
7982         }
7983 }
7984 static void bnx2x_warpcore_set_limiting_mode(struct link_params *params,
7985                                              struct bnx2x_phy *phy,
7986                                              u16 edc_mode)
7987 {
7988         u16 val = 0;
7989         u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
7990         struct bnx2x *bp = params->bp;
7991
7992         u8 lane = bnx2x_get_warpcore_lane(phy, params);
7993         /* This is a global register which controls all lanes */
7994         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
7995                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
7996         val &= ~(0xf << (lane << 2));
7997
7998         switch (edc_mode) {
7999         case EDC_MODE_LINEAR:
8000         case EDC_MODE_LIMITING:
8001                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
8002                 break;
8003         case EDC_MODE_PASSIVE_DAC:
8004                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
8005                 break;
8006         default:
8007                 break;
8008         }
8009
8010         val |= (mode << (lane << 2));
8011         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
8012                          MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
8013         /* A must read */
8014         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
8015                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
8016
8017
8018 }
8019
8020 static void bnx2x_set_limiting_mode(struct link_params *params,
8021                                     struct bnx2x_phy *phy,
8022                                     u16 edc_mode)
8023 {
8024         switch (phy->type) {
8025         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
8026                 bnx2x_8726_set_limiting_mode(params->bp, phy, edc_mode);
8027                 break;
8028         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8029         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8030                 bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode);
8031                 break;
8032         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
8033                 bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode);
8034                 break;
8035         }
8036 }
8037
8038 int bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
8039                                struct link_params *params)
8040 {
8041         struct bnx2x *bp = params->bp;
8042         u16 edc_mode;
8043         int rc = 0;
8044
8045         u32 val = REG_RD(bp, params->shmem_base +
8046                              offsetof(struct shmem_region, dev_info.
8047                                      port_feature_config[params->port].config));
8048
8049         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
8050                  params->port);
8051         /* Power up module */
8052         bnx2x_power_sfp_module(params, phy, 1);
8053         if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
8054                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
8055                 return -EINVAL;
8056         } else if (bnx2x_verify_sfp_module(phy, params) != 0) {
8057                 /* check SFP+ module compatibility */
8058                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
8059                 rc = -EINVAL;
8060                 /* Turn on fault module-detected led */
8061                 bnx2x_set_sfp_module_fault_led(params,
8062                                                MISC_REGISTERS_GPIO_HIGH);
8063
8064                 /* Check if need to power down the SFP+ module */
8065                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8066                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
8067                         DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
8068                         bnx2x_power_sfp_module(params, phy, 0);
8069                         return rc;
8070                 }
8071         } else {
8072                 /* Turn off fault module-detected led */
8073                 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
8074         }
8075
8076         /*
8077          * Check and set limiting mode / LRM mode on 8726. On 8727 it
8078          * is done automatically
8079          */
8080         bnx2x_set_limiting_mode(params, phy, edc_mode);
8081
8082         /*
8083          * Enable transmit for this module if the module is approved, or
8084          * if unapproved modules should also enable the Tx laser
8085          */
8086         if (rc == 0 ||
8087             (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
8088             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
8089                 bnx2x_sfp_set_transmitter(params, phy, 1);
8090         else
8091                 bnx2x_sfp_set_transmitter(params, phy, 0);
8092
8093         return rc;
8094 }
8095
8096 void bnx2x_handle_module_detect_int(struct link_params *params)
8097 {
8098         struct bnx2x *bp = params->bp;
8099         struct bnx2x_phy *phy;
8100         u32 gpio_val;
8101         u8 gpio_num, gpio_port;
8102         if (CHIP_IS_E3(bp))
8103                 phy = &params->phy[INT_PHY];
8104         else
8105                 phy = &params->phy[EXT_PHY1];
8106
8107         if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base,
8108                                       params->port, &gpio_num, &gpio_port) ==
8109             -EINVAL) {
8110                 DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n");
8111                 return;
8112         }
8113
8114         /* Set valid module led off */
8115         bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
8116
8117         /* Get current gpio val reflecting module plugged in / out*/
8118         gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
8119
8120         /* Call the handling function in case module is detected */
8121         if (gpio_val == 0) {
8122                 bnx2x_power_sfp_module(params, phy, 1);
8123                 bnx2x_set_gpio_int(bp, gpio_num,
8124                                    MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
8125                                    gpio_port);
8126                 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
8127                         bnx2x_sfp_module_detection(phy, params);
8128                 else
8129                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
8130         } else {
8131                 u32 val = REG_RD(bp, params->shmem_base +
8132                                  offsetof(struct shmem_region, dev_info.
8133                                           port_feature_config[params->port].
8134                                           config));
8135
8136                 bnx2x_set_gpio_int(bp, gpio_num,
8137                                    MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
8138                                    gpio_port);
8139                 /*
8140                  * Module was plugged out.
8141                  * Disable transmit for this module
8142                  */
8143                 phy->media_type = ETH_PHY_NOT_PRESENT;
8144                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8145                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
8146                         bnx2x_sfp_set_transmitter(params, phy, 0);
8147         }
8148 }
8149
8150 /******************************************************************/
8151 /*              Used by 8706 and 8727                             */
8152 /******************************************************************/
8153 static void bnx2x_sfp_mask_fault(struct bnx2x *bp,
8154                                  struct bnx2x_phy *phy,
8155                                  u16 alarm_status_offset,
8156                                  u16 alarm_ctrl_offset)
8157 {
8158         u16 alarm_status, val;
8159         bnx2x_cl45_read(bp, phy,
8160                         MDIO_PMA_DEVAD, alarm_status_offset,
8161                         &alarm_status);
8162         bnx2x_cl45_read(bp, phy,
8163                         MDIO_PMA_DEVAD, alarm_status_offset,
8164                         &alarm_status);
8165         /* Mask or enable the fault event. */
8166         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
8167         if (alarm_status & (1<<0))
8168                 val &= ~(1<<0);
8169         else
8170                 val |= (1<<0);
8171         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
8172 }
8173 /******************************************************************/
8174 /*              common BCM8706/BCM8726 PHY SECTION                */
8175 /******************************************************************/
8176 static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
8177                                       struct link_params *params,
8178                                       struct link_vars *vars)
8179 {
8180         u8 link_up = 0;
8181         u16 val1, val2, rx_sd, pcs_status;
8182         struct bnx2x *bp = params->bp;
8183         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
8184         /* Clear RX Alarm*/
8185         bnx2x_cl45_read(bp, phy,
8186                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
8187
8188         bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
8189                              MDIO_PMA_LASI_TXCTRL);
8190
8191         /* clear LASI indication*/
8192         bnx2x_cl45_read(bp, phy,
8193                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8194         bnx2x_cl45_read(bp, phy,
8195                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
8196         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
8197
8198         bnx2x_cl45_read(bp, phy,
8199                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8200         bnx2x_cl45_read(bp, phy,
8201                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
8202         bnx2x_cl45_read(bp, phy,
8203                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8204         bnx2x_cl45_read(bp, phy,
8205                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8206
8207         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
8208                         " link_status 0x%x\n", rx_sd, pcs_status, val2);
8209         /*
8210          * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
8211          * are set, or if the autoneg bit 1 is set
8212          */
8213         link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
8214         if (link_up) {
8215                 if (val2 & (1<<1))
8216                         vars->line_speed = SPEED_1000;
8217                 else
8218                         vars->line_speed = SPEED_10000;
8219                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
8220                 vars->duplex = DUPLEX_FULL;
8221         }
8222
8223         /* Capture 10G link fault. Read twice to clear stale value. */
8224         if (vars->line_speed == SPEED_10000) {
8225                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8226                             MDIO_PMA_LASI_TXSTAT, &val1);
8227                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8228                             MDIO_PMA_LASI_TXSTAT, &val1);
8229                 if (val1 & (1<<0))
8230                         vars->fault_detected = 1;
8231         }
8232
8233         return link_up;
8234 }
8235
8236 /******************************************************************/
8237 /*                      BCM8706 PHY SECTION                       */
8238 /******************************************************************/
8239 static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
8240                                  struct link_params *params,
8241                                  struct link_vars *vars)
8242 {
8243         u32 tx_en_mode;
8244         u16 cnt, val, tmp1;
8245         struct bnx2x *bp = params->bp;
8246
8247         /* SPF+ PHY: Set flag to check for Tx error */
8248         vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG;
8249
8250         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
8251                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8252         /* HW reset */
8253         bnx2x_ext_phy_hw_reset(bp, params->port);
8254         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
8255         bnx2x_wait_reset_complete(bp, phy, params);
8256
8257         /* Wait until fw is loaded */
8258         for (cnt = 0; cnt < 100; cnt++) {
8259                 bnx2x_cl45_read(bp, phy,
8260                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
8261                 if (val)
8262                         break;
8263                 msleep(10);
8264         }
8265         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
8266         if ((params->feature_config_flags &
8267              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8268                 u8 i;
8269                 u16 reg;
8270                 for (i = 0; i < 4; i++) {
8271                         reg = MDIO_XS_8706_REG_BANK_RX0 +
8272                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
8273                                    MDIO_XS_8706_REG_BANK_RX0);
8274                         bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
8275                         /* Clear first 3 bits of the control */
8276                         val &= ~0x7;
8277                         /* Set control bits according to configuration */
8278                         val |= (phy->rx_preemphasis[i] & 0x7);
8279                         DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
8280                                    " reg 0x%x <-- val 0x%x\n", reg, val);
8281                         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
8282                 }
8283         }
8284         /* Force speed */
8285         if (phy->req_line_speed == SPEED_10000) {
8286                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
8287
8288                 bnx2x_cl45_write(bp, phy,
8289                                  MDIO_PMA_DEVAD,
8290                                  MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
8291                 bnx2x_cl45_write(bp, phy,
8292                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
8293                                  0);
8294                 /* Arm LASI for link and Tx fault. */
8295                 bnx2x_cl45_write(bp, phy,
8296                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
8297         } else {
8298                 /* Force 1Gbps using autoneg with 1G advertisement */
8299
8300                 /* Allow CL37 through CL73 */
8301                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
8302                 bnx2x_cl45_write(bp, phy,
8303                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8304
8305                 /* Enable Full-Duplex advertisement on CL37 */
8306                 bnx2x_cl45_write(bp, phy,
8307                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
8308                 /* Enable CL37 AN */
8309                 bnx2x_cl45_write(bp, phy,
8310                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8311                 /* 1G support */
8312                 bnx2x_cl45_write(bp, phy,
8313                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
8314
8315                 /* Enable clause 73 AN */
8316                 bnx2x_cl45_write(bp, phy,
8317                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8318                 bnx2x_cl45_write(bp, phy,
8319                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8320                                  0x0400);
8321                 bnx2x_cl45_write(bp, phy,
8322                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
8323                                  0x0004);
8324         }
8325         bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8326
8327         /*
8328          * If TX Laser is controlled by GPIO_0, do not let PHY go into low
8329          * power mode, if TX Laser is disabled
8330          */
8331
8332         tx_en_mode = REG_RD(bp, params->shmem_base +
8333                             offsetof(struct shmem_region,
8334                                 dev_info.port_hw_config[params->port].sfp_ctrl))
8335                         & PORT_HW_CFG_TX_LASER_MASK;
8336
8337         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
8338                 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
8339                 bnx2x_cl45_read(bp, phy,
8340                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
8341                 tmp1 |= 0x1;
8342                 bnx2x_cl45_write(bp, phy,
8343                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
8344         }
8345
8346         return 0;
8347 }
8348
8349 static int bnx2x_8706_read_status(struct bnx2x_phy *phy,
8350                                   struct link_params *params,
8351                                   struct link_vars *vars)
8352 {
8353         return bnx2x_8706_8726_read_status(phy, params, vars);
8354 }
8355
8356 /******************************************************************/
8357 /*                      BCM8726 PHY SECTION                       */
8358 /******************************************************************/
8359 static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
8360                                        struct link_params *params)
8361 {
8362         struct bnx2x *bp = params->bp;
8363         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
8364         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
8365 }
8366
8367 static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
8368                                          struct link_params *params)
8369 {
8370         struct bnx2x *bp = params->bp;
8371         /* Need to wait 100ms after reset */
8372         msleep(100);
8373
8374         /* Micro controller re-boot */
8375         bnx2x_cl45_write(bp, phy,
8376                          MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
8377
8378         /* Set soft reset */
8379         bnx2x_cl45_write(bp, phy,
8380                          MDIO_PMA_DEVAD,
8381                          MDIO_PMA_REG_GEN_CTRL,
8382                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
8383
8384         bnx2x_cl45_write(bp, phy,
8385                          MDIO_PMA_DEVAD,
8386                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
8387
8388         bnx2x_cl45_write(bp, phy,
8389                          MDIO_PMA_DEVAD,
8390                          MDIO_PMA_REG_GEN_CTRL,
8391                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
8392
8393         /* wait for 150ms for microcode load */
8394         msleep(150);
8395
8396         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
8397         bnx2x_cl45_write(bp, phy,
8398                          MDIO_PMA_DEVAD,
8399                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
8400
8401         msleep(200);
8402         bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8403 }
8404
8405 static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
8406                                  struct link_params *params,
8407                                  struct link_vars *vars)
8408 {
8409         struct bnx2x *bp = params->bp;
8410         u16 val1;
8411         u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
8412         if (link_up) {
8413                 bnx2x_cl45_read(bp, phy,
8414                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
8415                                 &val1);
8416                 if (val1 & (1<<15)) {
8417                         DP(NETIF_MSG_LINK, "Tx is disabled\n");
8418                         link_up = 0;
8419                         vars->line_speed = 0;
8420                 }
8421         }
8422         return link_up;
8423 }
8424
8425
8426 static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
8427                                   struct link_params *params,
8428                                   struct link_vars *vars)
8429 {
8430         struct bnx2x *bp = params->bp;
8431         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
8432
8433         /* SPF+ PHY: Set flag to check for Tx error */
8434         vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG;
8435
8436         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
8437         bnx2x_wait_reset_complete(bp, phy, params);
8438
8439         bnx2x_8726_external_rom_boot(phy, params);
8440
8441         /*
8442          * Need to call module detected on initialization since the module
8443          * detection triggered by actual module insertion might occur before
8444          * driver is loaded, and when driver is loaded, it reset all
8445          * registers, including the transmitter
8446          */
8447         bnx2x_sfp_module_detection(phy, params);
8448
8449         if (phy->req_line_speed == SPEED_1000) {
8450                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
8451                 bnx2x_cl45_write(bp, phy,
8452                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
8453                 bnx2x_cl45_write(bp, phy,
8454                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
8455                 bnx2x_cl45_write(bp, phy,
8456                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
8457                 bnx2x_cl45_write(bp, phy,
8458                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8459                                  0x400);
8460         } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
8461                    (phy->speed_cap_mask &
8462                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
8463                    ((phy->speed_cap_mask &
8464                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
8465                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
8466                 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
8467                 /* Set Flow control */
8468                 bnx2x_ext_phy_set_pause(params, phy, vars);
8469                 bnx2x_cl45_write(bp, phy,
8470                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
8471                 bnx2x_cl45_write(bp, phy,
8472                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8473                 bnx2x_cl45_write(bp, phy,
8474                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
8475                 bnx2x_cl45_write(bp, phy,
8476                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8477                 bnx2x_cl45_write(bp, phy,
8478                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8479                 /*
8480                  * Enable RX-ALARM control to receive interrupt for 1G speed
8481                  * change
8482                  */
8483                 bnx2x_cl45_write(bp, phy,
8484                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
8485                 bnx2x_cl45_write(bp, phy,
8486                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8487                                  0x400);
8488
8489         } else { /* Default 10G. Set only LASI control */
8490                 bnx2x_cl45_write(bp, phy,
8491                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
8492         }
8493
8494         /* Set TX PreEmphasis if needed */
8495         if ((params->feature_config_flags &
8496              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8497                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
8498                          "TX_CTRL2 0x%x\n",
8499                          phy->tx_preemphasis[0],
8500                          phy->tx_preemphasis[1]);
8501                 bnx2x_cl45_write(bp, phy,
8502                                  MDIO_PMA_DEVAD,
8503                                  MDIO_PMA_REG_8726_TX_CTRL1,
8504                                  phy->tx_preemphasis[0]);
8505
8506                 bnx2x_cl45_write(bp, phy,
8507                                  MDIO_PMA_DEVAD,
8508                                  MDIO_PMA_REG_8726_TX_CTRL2,
8509                                  phy->tx_preemphasis[1]);
8510         }
8511
8512         return 0;
8513
8514 }
8515
8516 static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
8517                                   struct link_params *params)
8518 {
8519         struct bnx2x *bp = params->bp;
8520         DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
8521         /* Set serial boot control for external load */
8522         bnx2x_cl45_write(bp, phy,
8523                          MDIO_PMA_DEVAD,
8524                          MDIO_PMA_REG_GEN_CTRL, 0x0001);
8525 }
8526
8527 /******************************************************************/
8528 /*                      BCM8727 PHY SECTION                       */
8529 /******************************************************************/
8530
8531 static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
8532                                     struct link_params *params, u8 mode)
8533 {
8534         struct bnx2x *bp = params->bp;
8535         u16 led_mode_bitmask = 0;
8536         u16 gpio_pins_bitmask = 0;
8537         u16 val;
8538         /* Only NOC flavor requires to set the LED specifically */
8539         if (!(phy->flags & FLAGS_NOC))
8540                 return;
8541         switch (mode) {
8542         case LED_MODE_FRONT_PANEL_OFF:
8543         case LED_MODE_OFF:
8544                 led_mode_bitmask = 0;
8545                 gpio_pins_bitmask = 0x03;
8546                 break;
8547         case LED_MODE_ON:
8548                 led_mode_bitmask = 0;
8549                 gpio_pins_bitmask = 0x02;
8550                 break;
8551         case LED_MODE_OPER:
8552                 led_mode_bitmask = 0x60;
8553                 gpio_pins_bitmask = 0x11;
8554                 break;
8555         }
8556         bnx2x_cl45_read(bp, phy,
8557                         MDIO_PMA_DEVAD,
8558                         MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8559                         &val);
8560         val &= 0xff8f;
8561         val |= led_mode_bitmask;
8562         bnx2x_cl45_write(bp, phy,
8563                          MDIO_PMA_DEVAD,
8564                          MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8565                          val);
8566         bnx2x_cl45_read(bp, phy,
8567                         MDIO_PMA_DEVAD,
8568                         MDIO_PMA_REG_8727_GPIO_CTRL,
8569                         &val);
8570         val &= 0xffe0;
8571         val |= gpio_pins_bitmask;
8572         bnx2x_cl45_write(bp, phy,
8573                          MDIO_PMA_DEVAD,
8574                          MDIO_PMA_REG_8727_GPIO_CTRL,
8575                          val);
8576 }
8577 static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
8578                                 struct link_params *params) {
8579         u32 swap_val, swap_override;
8580         u8 port;
8581         /*
8582          * The PHY reset is controlled by GPIO 1. Fake the port number
8583          * to cancel the swap done in set_gpio()
8584          */
8585         struct bnx2x *bp = params->bp;
8586         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
8587         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
8588         port = (swap_val && swap_override) ^ 1;
8589         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
8590                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
8591 }
8592
8593 static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
8594                                   struct link_params *params,
8595                                   struct link_vars *vars)
8596 {
8597         u32 tx_en_mode;
8598         u16 tmp1, val, mod_abs, tmp2;
8599         u16 rx_alarm_ctrl_val;
8600         u16 lasi_ctrl_val;
8601         struct bnx2x *bp = params->bp;
8602         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
8603
8604         /* SPF+ PHY: Set flag to check for Tx error */
8605         vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG;
8606
8607         bnx2x_wait_reset_complete(bp, phy, params);
8608         rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
8609         /* Should be 0x6 to enable XS on Tx side. */
8610         lasi_ctrl_val = 0x0006;
8611
8612         DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
8613         /* enable LASI */
8614         bnx2x_cl45_write(bp, phy,
8615                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8616                          rx_alarm_ctrl_val);
8617         bnx2x_cl45_write(bp, phy,
8618                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
8619                          0);
8620         bnx2x_cl45_write(bp, phy,
8621                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, lasi_ctrl_val);
8622
8623         /*
8624          * Initially configure MOD_ABS to interrupt when module is
8625          * presence( bit 8)
8626          */
8627         bnx2x_cl45_read(bp, phy,
8628                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
8629         /*
8630          * Set EDC off by setting OPTXLOS signal input to low (bit 9).
8631          * When the EDC is off it locks onto a reference clock and avoids
8632          * becoming 'lost'
8633          */
8634         mod_abs &= ~(1<<8);
8635         if (!(phy->flags & FLAGS_NOC))
8636                 mod_abs &= ~(1<<9);
8637         bnx2x_cl45_write(bp, phy,
8638                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8639
8640
8641         /* Enable/Disable PHY transmitter output */
8642         bnx2x_set_disable_pmd_transmit(params, phy, 0);
8643
8644         /* Make MOD_ABS give interrupt on change */
8645         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8646                         &val);
8647         val |= (1<<12);
8648         if (phy->flags & FLAGS_NOC)
8649                 val |= (3<<5);
8650
8651         /*
8652          * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
8653          * status which reflect SFP+ module over-current
8654          */
8655         if (!(phy->flags & FLAGS_NOC))
8656                 val &= 0xff8f; /* Reset bits 4-6 */
8657         bnx2x_cl45_write(bp, phy,
8658                          MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
8659
8660         bnx2x_8727_power_module(bp, phy, 1);
8661
8662         bnx2x_cl45_read(bp, phy,
8663                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
8664
8665         bnx2x_cl45_read(bp, phy,
8666                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
8667
8668         /* Set option 1G speed */
8669         if (phy->req_line_speed == SPEED_1000) {
8670                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
8671                 bnx2x_cl45_write(bp, phy,
8672                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
8673                 bnx2x_cl45_write(bp, phy,
8674                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
8675                 bnx2x_cl45_read(bp, phy,
8676                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
8677                 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
8678                 /*
8679                  * Power down the XAUI until link is up in case of dual-media
8680                  * and 1G
8681                  */
8682                 if (DUAL_MEDIA(params)) {
8683                         bnx2x_cl45_read(bp, phy,
8684                                         MDIO_PMA_DEVAD,
8685                                         MDIO_PMA_REG_8727_PCS_GP, &val);
8686                         val |= (3<<10);
8687                         bnx2x_cl45_write(bp, phy,
8688                                          MDIO_PMA_DEVAD,
8689                                          MDIO_PMA_REG_8727_PCS_GP, val);
8690                 }
8691         } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
8692                    ((phy->speed_cap_mask &
8693                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
8694                    ((phy->speed_cap_mask &
8695                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
8696                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
8697
8698                 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
8699                 bnx2x_cl45_write(bp, phy,
8700                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
8701                 bnx2x_cl45_write(bp, phy,
8702                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
8703         } else {
8704                 /*
8705                  * Since the 8727 has only single reset pin, need to set the 10G
8706                  * registers although it is default
8707                  */
8708                 bnx2x_cl45_write(bp, phy,
8709                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
8710                                  0x0020);
8711                 bnx2x_cl45_write(bp, phy,
8712                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
8713                 bnx2x_cl45_write(bp, phy,
8714                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
8715                 bnx2x_cl45_write(bp, phy,
8716                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
8717                                  0x0008);
8718         }
8719
8720         /*
8721          * Set 2-wire transfer rate of SFP+ module EEPROM
8722          * to 100Khz since some DACs(direct attached cables) do
8723          * not work at 400Khz.
8724          */
8725         bnx2x_cl45_write(bp, phy,
8726                          MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
8727                          0xa001);
8728
8729         /* Set TX PreEmphasis if needed */
8730         if ((params->feature_config_flags &
8731              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8732                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8733                            phy->tx_preemphasis[0],
8734                            phy->tx_preemphasis[1]);
8735                 bnx2x_cl45_write(bp, phy,
8736                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
8737                                  phy->tx_preemphasis[0]);
8738
8739                 bnx2x_cl45_write(bp, phy,
8740                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
8741                                  phy->tx_preemphasis[1]);
8742         }
8743
8744         /*
8745          * If TX Laser is controlled by GPIO_0, do not let PHY go into low
8746          * power mode, if TX Laser is disabled
8747          */
8748         tx_en_mode = REG_RD(bp, params->shmem_base +
8749                             offsetof(struct shmem_region,
8750                                 dev_info.port_hw_config[params->port].sfp_ctrl))
8751                         & PORT_HW_CFG_TX_LASER_MASK;
8752
8753         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
8754
8755                 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
8756                 bnx2x_cl45_read(bp, phy,
8757                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
8758                 tmp2 |= 0x1000;
8759                 tmp2 &= 0xFFEF;
8760                 bnx2x_cl45_write(bp, phy,
8761                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
8762         }
8763
8764         return 0;
8765 }
8766
8767 static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
8768                                       struct link_params *params)
8769 {
8770         struct bnx2x *bp = params->bp;
8771         u16 mod_abs, rx_alarm_status;
8772         u32 val = REG_RD(bp, params->shmem_base +
8773                              offsetof(struct shmem_region, dev_info.
8774                                       port_feature_config[params->port].
8775                                       config));
8776         bnx2x_cl45_read(bp, phy,
8777                         MDIO_PMA_DEVAD,
8778                         MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
8779         if (mod_abs & (1<<8)) {
8780
8781                 /* Module is absent */
8782                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
8783                             "show module is absent\n");
8784                 phy->media_type = ETH_PHY_NOT_PRESENT;
8785                 /*
8786                  * 1. Set mod_abs to detect next module
8787                  *    presence event
8788                  * 2. Set EDC off by setting OPTXLOS signal input to low
8789                  *    (bit 9).
8790                  *    When the EDC is off it locks onto a reference clock and
8791                  *    avoids becoming 'lost'.
8792                  */
8793                 mod_abs &= ~(1<<8);
8794                 if (!(phy->flags & FLAGS_NOC))
8795                         mod_abs &= ~(1<<9);
8796                 bnx2x_cl45_write(bp, phy,
8797                                  MDIO_PMA_DEVAD,
8798                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8799
8800                 /*
8801                  * Clear RX alarm since it stays up as long as
8802                  * the mod_abs wasn't changed
8803                  */
8804                 bnx2x_cl45_read(bp, phy,
8805                                 MDIO_PMA_DEVAD,
8806                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
8807
8808         } else {
8809                 /* Module is present */
8810                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
8811                             "show module is present\n");
8812                 /*
8813                  * First disable transmitter, and if the module is ok, the
8814                  * module_detection will enable it
8815                  * 1. Set mod_abs to detect next module absent event ( bit 8)
8816                  * 2. Restore the default polarity of the OPRXLOS signal and
8817                  * this signal will then correctly indicate the presence or
8818                  * absence of the Rx signal. (bit 9)
8819                  */
8820                 mod_abs |= (1<<8);
8821                 if (!(phy->flags & FLAGS_NOC))
8822                         mod_abs |= (1<<9);
8823                 bnx2x_cl45_write(bp, phy,
8824                                  MDIO_PMA_DEVAD,
8825                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8826
8827                 /*
8828                  * Clear RX alarm since it stays up as long as the mod_abs
8829                  * wasn't changed. This is need to be done before calling the
8830                  * module detection, otherwise it will clear* the link update
8831                  * alarm
8832                  */
8833                 bnx2x_cl45_read(bp, phy,
8834                                 MDIO_PMA_DEVAD,
8835                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
8836
8837
8838                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8839                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
8840                         bnx2x_sfp_set_transmitter(params, phy, 0);
8841
8842                 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
8843                         bnx2x_sfp_module_detection(phy, params);
8844                 else
8845                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
8846         }
8847
8848         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
8849                    rx_alarm_status);
8850         /* No need to check link status in case of module plugged in/out */
8851 }
8852
8853 static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
8854                                  struct link_params *params,
8855                                  struct link_vars *vars)
8856
8857 {
8858         struct bnx2x *bp = params->bp;
8859         u8 link_up = 0, oc_port = params->port;
8860         u16 link_status = 0;
8861         u16 rx_alarm_status, lasi_ctrl, val1;
8862
8863         /* If PHY is not initialized, do not check link status */
8864         bnx2x_cl45_read(bp, phy,
8865                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
8866                         &lasi_ctrl);
8867         if (!lasi_ctrl)
8868                 return 0;
8869
8870         /* Check the LASI on Rx */
8871         bnx2x_cl45_read(bp, phy,
8872                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
8873                         &rx_alarm_status);
8874         vars->line_speed = 0;
8875         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
8876
8877         bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
8878                              MDIO_PMA_LASI_TXCTRL);
8879
8880         bnx2x_cl45_read(bp, phy,
8881                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8882
8883         DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
8884
8885         /* Clear MSG-OUT */
8886         bnx2x_cl45_read(bp, phy,
8887                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
8888
8889         /*
8890          * If a module is present and there is need to check
8891          * for over current
8892          */
8893         if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
8894                 /* Check over-current using 8727 GPIO0 input*/
8895                 bnx2x_cl45_read(bp, phy,
8896                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
8897                                 &val1);
8898
8899                 if ((val1 & (1<<8)) == 0) {
8900                         if (!CHIP_IS_E1x(bp))
8901                                 oc_port = BP_PATH(bp) + (params->port << 1);
8902                         DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
8903                                        " on port %d\n", oc_port);
8904                         netdev_err(bp->dev, "Error:  Power fault on Port %d has"
8905                                             " been detected and the power to "
8906                                             "that SFP+ module has been removed"
8907                                             " to prevent failure of the card."
8908                                             " Please remove the SFP+ module and"
8909                                             " restart the system to clear this"
8910                                             " error.\n",
8911                          oc_port);
8912                         /* Disable all RX_ALARMs except for mod_abs */
8913                         bnx2x_cl45_write(bp, phy,
8914                                          MDIO_PMA_DEVAD,
8915                                          MDIO_PMA_LASI_RXCTRL, (1<<5));
8916
8917                         bnx2x_cl45_read(bp, phy,
8918                                         MDIO_PMA_DEVAD,
8919                                         MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
8920                         /* Wait for module_absent_event */
8921                         val1 |= (1<<8);
8922                         bnx2x_cl45_write(bp, phy,
8923                                          MDIO_PMA_DEVAD,
8924                                          MDIO_PMA_REG_PHY_IDENTIFIER, val1);
8925                         /* Clear RX alarm */
8926                         bnx2x_cl45_read(bp, phy,
8927                                 MDIO_PMA_DEVAD,
8928                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
8929                         return 0;
8930                 }
8931         } /* Over current check */
8932
8933         /* When module absent bit is set, check module */
8934         if (rx_alarm_status & (1<<5)) {
8935                 bnx2x_8727_handle_mod_abs(phy, params);
8936                 /* Enable all mod_abs and link detection bits */
8937                 bnx2x_cl45_write(bp, phy,
8938                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8939                                  ((1<<5) | (1<<2)));
8940         }
8941         DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
8942         bnx2x_8727_specific_func(phy, params, ENABLE_TX);
8943         /* If transmitter is disabled, ignore false link up indication */
8944         bnx2x_cl45_read(bp, phy,
8945                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
8946         if (val1 & (1<<15)) {
8947                 DP(NETIF_MSG_LINK, "Tx is disabled\n");
8948                 return 0;
8949         }
8950
8951         bnx2x_cl45_read(bp, phy,
8952                         MDIO_PMA_DEVAD,
8953                         MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
8954
8955         /*
8956          * Bits 0..2 --> speed detected,
8957          * Bits 13..15--> link is down
8958          */
8959         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
8960                 link_up = 1;
8961                 vars->line_speed = SPEED_10000;
8962                 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
8963                            params->port);
8964         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
8965                 link_up = 1;
8966                 vars->line_speed = SPEED_1000;
8967                 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
8968                            params->port);
8969         } else {
8970                 link_up = 0;
8971                 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
8972                            params->port);
8973         }
8974
8975         /* Capture 10G link fault. */
8976         if (vars->line_speed == SPEED_10000) {
8977                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8978                             MDIO_PMA_LASI_TXSTAT, &val1);
8979
8980                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8981                             MDIO_PMA_LASI_TXSTAT, &val1);
8982
8983                 if (val1 & (1<<0)) {
8984                         vars->fault_detected = 1;
8985                 }
8986         }
8987
8988         if (link_up) {
8989                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
8990                 vars->duplex = DUPLEX_FULL;
8991                 DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
8992         }
8993
8994         if ((DUAL_MEDIA(params)) &&
8995             (phy->req_line_speed == SPEED_1000)) {
8996                 bnx2x_cl45_read(bp, phy,
8997                                 MDIO_PMA_DEVAD,
8998                                 MDIO_PMA_REG_8727_PCS_GP, &val1);
8999                 /*
9000                  * In case of dual-media board and 1G, power up the XAUI side,
9001                  * otherwise power it down. For 10G it is done automatically
9002                  */
9003                 if (link_up)
9004                         val1 &= ~(3<<10);
9005                 else
9006                         val1 |= (3<<10);
9007                 bnx2x_cl45_write(bp, phy,
9008                                  MDIO_PMA_DEVAD,
9009                                  MDIO_PMA_REG_8727_PCS_GP, val1);
9010         }
9011         return link_up;
9012 }
9013
9014 static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
9015                                   struct link_params *params)
9016 {
9017         struct bnx2x *bp = params->bp;
9018
9019         /* Enable/Disable PHY transmitter output */
9020         bnx2x_set_disable_pmd_transmit(params, phy, 1);
9021
9022         /* Disable Transmitter */
9023         bnx2x_sfp_set_transmitter(params, phy, 0);
9024         /* Clear LASI */
9025         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
9026
9027 }
9028
9029 /******************************************************************/
9030 /*              BCM8481/BCM84823/BCM84833 PHY SECTION             */
9031 /******************************************************************/
9032 static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
9033                                            struct link_params *params)
9034 {
9035         u16 val, fw_ver1, fw_ver2, cnt;
9036         u8 port;
9037         struct bnx2x *bp = params->bp;
9038
9039         port = params->port;
9040
9041         /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
9042         /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
9043         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
9044         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
9045         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
9046         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
9047         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
9048
9049         for (cnt = 0; cnt < 100; cnt++) {
9050                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
9051                 if (val & 1)
9052                         break;
9053                 udelay(5);
9054         }
9055         if (cnt == 100) {
9056                 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
9057                 bnx2x_save_spirom_version(bp, port, 0,
9058                                           phy->ver_addr);
9059                 return;
9060         }
9061
9062
9063         /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
9064         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
9065         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
9066         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
9067         for (cnt = 0; cnt < 100; cnt++) {
9068                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
9069                 if (val & 1)
9070                         break;
9071                 udelay(5);
9072         }
9073         if (cnt == 100) {
9074                 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
9075                 bnx2x_save_spirom_version(bp, port, 0,
9076                                           phy->ver_addr);
9077                 return;
9078         }
9079
9080         /* lower 16 bits of the register SPI_FW_STATUS */
9081         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
9082         /* upper 16 bits of register SPI_FW_STATUS */
9083         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
9084
9085         bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
9086                                   phy->ver_addr);
9087 }
9088
9089 static void bnx2x_848xx_set_led(struct bnx2x *bp,
9090                                 struct bnx2x_phy *phy)
9091 {
9092         u16 val;
9093
9094         /* PHYC_CTL_LED_CTL */
9095         bnx2x_cl45_read(bp, phy,
9096                         MDIO_PMA_DEVAD,
9097                         MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
9098         val &= 0xFE00;
9099         val |= 0x0092;
9100
9101         bnx2x_cl45_write(bp, phy,
9102                          MDIO_PMA_DEVAD,
9103                          MDIO_PMA_REG_8481_LINK_SIGNAL, val);
9104
9105         bnx2x_cl45_write(bp, phy,
9106                          MDIO_PMA_DEVAD,
9107                          MDIO_PMA_REG_8481_LED1_MASK,
9108                          0x80);
9109
9110         bnx2x_cl45_write(bp, phy,
9111                          MDIO_PMA_DEVAD,
9112                          MDIO_PMA_REG_8481_LED2_MASK,
9113                          0x18);
9114
9115         /* Select activity source by Tx and Rx, as suggested by PHY AE */
9116         bnx2x_cl45_write(bp, phy,
9117                          MDIO_PMA_DEVAD,
9118                          MDIO_PMA_REG_8481_LED3_MASK,
9119                          0x0006);
9120
9121         /* Select the closest activity blink rate to that in 10/100/1000 */
9122         bnx2x_cl45_write(bp, phy,
9123                         MDIO_PMA_DEVAD,
9124                         MDIO_PMA_REG_8481_LED3_BLINK,
9125                         0);
9126
9127         bnx2x_cl45_read(bp, phy,
9128                         MDIO_PMA_DEVAD,
9129                         MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val);
9130         val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
9131
9132         bnx2x_cl45_write(bp, phy,
9133                          MDIO_PMA_DEVAD,
9134                          MDIO_PMA_REG_84823_CTL_LED_CTL_1, val);
9135
9136         /* 'Interrupt Mask' */
9137         bnx2x_cl45_write(bp, phy,
9138                          MDIO_AN_DEVAD,
9139                          0xFFFB, 0xFFFD);
9140 }
9141
9142 static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
9143                                        struct link_params *params,
9144                                        struct link_vars *vars)
9145 {
9146         struct bnx2x *bp = params->bp;
9147         u16 autoneg_val, an_1000_val, an_10_100_val;
9148         u16 tmp_req_line_speed;
9149
9150         tmp_req_line_speed = phy->req_line_speed;
9151         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
9152                 if (phy->req_line_speed == SPEED_10000)
9153                         phy->req_line_speed = SPEED_AUTO_NEG;
9154
9155         /*
9156          * This phy uses the NIG latch mechanism since link indication
9157          * arrives through its LED4 and not via its LASI signal, so we
9158          * get steady signal instead of clear on read
9159          */
9160         bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
9161                       1 << NIG_LATCH_BC_ENABLE_MI_INT);
9162
9163         bnx2x_cl45_write(bp, phy,
9164                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
9165
9166         bnx2x_848xx_set_led(bp, phy);
9167
9168         /* set 1000 speed advertisement */
9169         bnx2x_cl45_read(bp, phy,
9170                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9171                         &an_1000_val);
9172
9173         bnx2x_ext_phy_set_pause(params, phy, vars);
9174         bnx2x_cl45_read(bp, phy,
9175                         MDIO_AN_DEVAD,
9176                         MDIO_AN_REG_8481_LEGACY_AN_ADV,
9177                         &an_10_100_val);
9178         bnx2x_cl45_read(bp, phy,
9179                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
9180                         &autoneg_val);
9181         /* Disable forced speed */
9182         autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
9183         an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
9184
9185         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9186              (phy->speed_cap_mask &
9187              PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
9188             (phy->req_line_speed == SPEED_1000)) {
9189                 an_1000_val |= (1<<8);
9190                 autoneg_val |= (1<<9 | 1<<12);
9191                 if (phy->req_duplex == DUPLEX_FULL)
9192                         an_1000_val |= (1<<9);
9193                 DP(NETIF_MSG_LINK, "Advertising 1G\n");
9194         } else
9195                 an_1000_val &= ~((1<<8) | (1<<9));
9196
9197         bnx2x_cl45_write(bp, phy,
9198                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9199                          an_1000_val);
9200
9201         /* set 100 speed advertisement */
9202         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9203              (phy->speed_cap_mask &
9204               (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
9205                PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) &&
9206              (phy->supported &
9207               (SUPPORTED_100baseT_Half |
9208                SUPPORTED_100baseT_Full)))) {
9209                 an_10_100_val |= (1<<7);
9210                 /* Enable autoneg and restart autoneg for legacy speeds */
9211                 autoneg_val |= (1<<9 | 1<<12);
9212
9213                 if (phy->req_duplex == DUPLEX_FULL)
9214                         an_10_100_val |= (1<<8);
9215                 DP(NETIF_MSG_LINK, "Advertising 100M\n");
9216         }
9217         /* set 10 speed advertisement */
9218         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9219              (phy->speed_cap_mask &
9220               (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
9221                PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) &&
9222              (phy->supported &
9223               (SUPPORTED_10baseT_Half |
9224                SUPPORTED_10baseT_Full)))) {
9225                 an_10_100_val |= (1<<5);
9226                 autoneg_val |= (1<<9 | 1<<12);
9227                 if (phy->req_duplex == DUPLEX_FULL)
9228                         an_10_100_val |= (1<<6);
9229                 DP(NETIF_MSG_LINK, "Advertising 10M\n");
9230         }
9231
9232         /* Only 10/100 are allowed to work in FORCE mode */
9233         if ((phy->req_line_speed == SPEED_100) &&
9234             (phy->supported &
9235              (SUPPORTED_100baseT_Half |
9236               SUPPORTED_100baseT_Full))) {
9237                 autoneg_val |= (1<<13);
9238                 /* Enabled AUTO-MDIX when autoneg is disabled */
9239                 bnx2x_cl45_write(bp, phy,
9240                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9241                                  (1<<15 | 1<<9 | 7<<0));
9242                 DP(NETIF_MSG_LINK, "Setting 100M force\n");
9243         }
9244         if ((phy->req_line_speed == SPEED_10) &&
9245             (phy->supported &
9246              (SUPPORTED_10baseT_Half |
9247               SUPPORTED_10baseT_Full))) {
9248                 /* Enabled AUTO-MDIX when autoneg is disabled */
9249                 bnx2x_cl45_write(bp, phy,
9250                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9251                                  (1<<15 | 1<<9 | 7<<0));
9252                 DP(NETIF_MSG_LINK, "Setting 10M force\n");
9253         }
9254
9255         bnx2x_cl45_write(bp, phy,
9256                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
9257                          an_10_100_val);
9258
9259         if (phy->req_duplex == DUPLEX_FULL)
9260                 autoneg_val |= (1<<8);
9261
9262         bnx2x_cl45_write(bp, phy,
9263                          MDIO_AN_DEVAD,
9264                          MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
9265
9266         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9267             (phy->speed_cap_mask &
9268              PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
9269                 (phy->req_line_speed == SPEED_10000)) {
9270                         DP(NETIF_MSG_LINK, "Advertising 10G\n");
9271                         /* Restart autoneg for 10G*/
9272
9273                         bnx2x_cl45_write(bp, phy,
9274                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
9275                                  0x3200);
9276         } else if (phy->req_line_speed != SPEED_10 &&
9277                    phy->req_line_speed != SPEED_100) {
9278                 bnx2x_cl45_write(bp, phy,
9279                                  MDIO_AN_DEVAD,
9280                                  MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9281                                  1);
9282         }
9283         /* Save spirom version */
9284         bnx2x_save_848xx_spirom_version(phy, params);
9285
9286         phy->req_line_speed = tmp_req_line_speed;
9287
9288         return 0;
9289 }
9290
9291 static int bnx2x_8481_config_init(struct bnx2x_phy *phy,
9292                                   struct link_params *params,
9293                                   struct link_vars *vars)
9294 {
9295         struct bnx2x *bp = params->bp;
9296         /* Restore normal power mode*/
9297         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
9298                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9299
9300         /* HW reset */
9301         bnx2x_ext_phy_hw_reset(bp, params->port);
9302         bnx2x_wait_reset_complete(bp, phy, params);
9303
9304         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
9305         return bnx2x_848xx_cmn_config_init(phy, params, vars);
9306 }
9307
9308
9309 #define PHY84833_HDSHK_WAIT 300
9310 static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
9311                                    struct link_params *params,
9312                                    struct link_vars *vars)
9313 {
9314         u32 idx;
9315         u32 pair_swap;
9316         u16 val;
9317         u16 data;
9318         struct bnx2x *bp = params->bp;
9319         /* Do pair swap */
9320
9321         /* Check for configuration. */
9322         pair_swap = REG_RD(bp, params->shmem_base +
9323                            offsetof(struct shmem_region,
9324                         dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
9325                 PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
9326
9327         if (pair_swap == 0)
9328                 return 0;
9329
9330         data = (u16)pair_swap;
9331
9332         /* Write CMD_OPEN_OVERRIDE to STATUS reg */
9333         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9334                         MDIO_84833_TOP_CFG_SCRATCH_REG2,
9335                         PHY84833_CMD_OPEN_OVERRIDE);
9336         for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9337                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9338                                 MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9339                 if (val == PHY84833_CMD_OPEN_FOR_CMDS)
9340                         break;
9341                 msleep(1);
9342         }
9343         if (idx >= PHY84833_HDSHK_WAIT) {
9344                 DP(NETIF_MSG_LINK, "Pairswap: FW not ready.\n");
9345                 return -EINVAL;
9346         }
9347
9348         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9349                         MDIO_84833_TOP_CFG_SCRATCH_REG4,
9350                         data);
9351         /* Issue pair swap command */
9352         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9353                         MDIO_84833_TOP_CFG_SCRATCH_REG0,
9354                         PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE);
9355         for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9356                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9357                                 MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9358                 if ((val == PHY84833_CMD_COMPLETE_PASS) ||
9359                         (val == PHY84833_CMD_COMPLETE_ERROR))
9360                         break;
9361                 msleep(1);
9362         }
9363         if ((idx >= PHY84833_HDSHK_WAIT) ||
9364                 (val == PHY84833_CMD_COMPLETE_ERROR)) {
9365                 DP(NETIF_MSG_LINK, "Pairswap: override failed.\n");
9366                 return -EINVAL;
9367         }
9368         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9369                         MDIO_84833_TOP_CFG_SCRATCH_REG2,
9370                         PHY84833_CMD_CLEAR_COMPLETE);
9371         DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data);
9372         return 0;
9373 }
9374
9375
9376 static u8 bnx2x_84833_get_reset_gpios(struct bnx2x *bp,
9377                                       u32 shmem_base_path[],
9378                                       u32 chip_id)
9379 {
9380         u32 reset_pin[2];
9381         u32 idx;
9382         u8 reset_gpios;
9383         if (CHIP_IS_E3(bp)) {
9384                 /* Assume that these will be GPIOs, not EPIOs. */
9385                 for (idx = 0; idx < 2; idx++) {
9386                         /* Map config param to register bit. */
9387                         reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
9388                                 offsetof(struct shmem_region,
9389                                 dev_info.port_hw_config[0].e3_cmn_pin_cfg));
9390                         reset_pin[idx] = (reset_pin[idx] &
9391                                 PORT_HW_CFG_E3_PHY_RESET_MASK) >>
9392                                 PORT_HW_CFG_E3_PHY_RESET_SHIFT;
9393                         reset_pin[idx] -= PIN_CFG_GPIO0_P0;
9394                         reset_pin[idx] = (1 << reset_pin[idx]);
9395                 }
9396                 reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
9397         } else {
9398                 /* E2, look from diff place of shmem. */
9399                 for (idx = 0; idx < 2; idx++) {
9400                         reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
9401                                 offsetof(struct shmem_region,
9402                                 dev_info.port_hw_config[0].default_cfg));
9403                         reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
9404                         reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
9405                         reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
9406                         reset_pin[idx] = (1 << reset_pin[idx]);
9407                 }
9408                 reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
9409         }
9410
9411         return reset_gpios;
9412 }
9413
9414 static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
9415                                 struct link_params *params)
9416 {
9417         struct bnx2x *bp = params->bp;
9418         u8 reset_gpios;
9419         u32 other_shmem_base_addr = REG_RD(bp, params->shmem2_base +
9420                                 offsetof(struct shmem2_region,
9421                                 other_shmem_base_addr));
9422
9423         u32 shmem_base_path[2];
9424         shmem_base_path[0] = params->shmem_base;
9425         shmem_base_path[1] = other_shmem_base_addr;
9426
9427         reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path,
9428                                                   params->chip_id);
9429
9430         bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
9431         udelay(10);
9432         DP(NETIF_MSG_LINK, "84833 hw reset on pin values 0x%x\n",
9433                 reset_gpios);
9434
9435         return 0;
9436 }
9437
9438 static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
9439                                                 u32 shmem_base_path[],
9440                                                 u32 chip_id)
9441 {
9442         u8 reset_gpios;
9443
9444         reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id);
9445
9446         bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
9447         udelay(10);
9448         bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
9449         msleep(800);
9450         DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n",
9451                 reset_gpios);
9452
9453         return 0;
9454 }
9455
9456 #define PHY84833_CONSTANT_LATENCY 1193
9457 static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
9458                                    struct link_params *params,
9459                                    struct link_vars *vars)
9460 {
9461         struct bnx2x *bp = params->bp;
9462         u8 port, initialize = 1;
9463         u16 val;
9464         u16 temp;
9465         u32 actual_phy_selection, cms_enable, idx;
9466         int rc = 0;
9467
9468         msleep(1);
9469
9470         if (!(CHIP_IS_E1(bp)))
9471                 port = BP_PATH(bp);
9472         else
9473                 port = params->port;
9474
9475         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9476                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
9477                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
9478                                port);
9479         } else {
9480                 /* MDIO reset */
9481                 bnx2x_cl45_write(bp, phy,
9482                                 MDIO_PMA_DEVAD,
9483                                 MDIO_PMA_REG_CTRL, 0x8000);
9484                 /* Bring PHY out of super isolate mode */
9485                 bnx2x_cl45_read(bp, phy,
9486                                 MDIO_CTL_DEVAD,
9487                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
9488                 val &= ~MDIO_84833_SUPER_ISOLATE;
9489                 bnx2x_cl45_write(bp, phy,
9490                                 MDIO_CTL_DEVAD,
9491                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
9492         }
9493
9494         bnx2x_wait_reset_complete(bp, phy, params);
9495
9496         /* Wait for GPHY to come out of reset */
9497         msleep(50);
9498
9499         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
9500                 bnx2x_84833_pair_swap_cfg(phy, params, vars);
9501
9502         /*
9503          * BCM84823 requires that XGXS links up first @ 10G for normal behavior
9504          */
9505         temp = vars->line_speed;
9506         vars->line_speed = SPEED_10000;
9507         bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
9508         bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
9509         vars->line_speed = temp;
9510
9511         /* Set dual-media configuration according to configuration */
9512
9513         bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9514                         MDIO_CTL_REG_84823_MEDIA, &val);
9515         val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9516                  MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
9517                  MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
9518                  MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
9519                  MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
9520
9521         if (CHIP_IS_E3(bp)) {
9522                 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9523                          MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
9524         } else {
9525                 val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
9526                         MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
9527         }
9528
9529         actual_phy_selection = bnx2x_phy_selection(params);
9530
9531         switch (actual_phy_selection) {
9532         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
9533                 /* Do nothing. Essentially this is like the priority copper */
9534                 break;
9535         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
9536                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
9537                 break;
9538         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
9539                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
9540                 break;
9541         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
9542                 /* Do nothing here. The first PHY won't be initialized at all */
9543                 break;
9544         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
9545                 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
9546                 initialize = 0;
9547                 break;
9548         }
9549         if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
9550                 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
9551
9552         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9553                          MDIO_CTL_REG_84823_MEDIA, val);
9554         DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
9555                    params->multi_phy_config, val);
9556
9557         /* AutogrEEEn */
9558         if (params->feature_config_flags &
9559                 FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
9560                 /* Ensure that f/w is ready */
9561                 for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9562                         bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9563                                         MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9564                         if (val == PHY84833_CMD_OPEN_FOR_CMDS)
9565                                 break;
9566                         usleep_range(1000, 1000);
9567                 }
9568                 if (idx >= PHY84833_HDSHK_WAIT) {
9569                         DP(NETIF_MSG_LINK, "AutogrEEEn: FW not ready.\n");
9570                         return -EINVAL;
9571                 }
9572
9573                 /* Select EEE mode */
9574                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9575                                 MDIO_84833_TOP_CFG_SCRATCH_REG3,
9576                                 0x2);
9577
9578                 /* Set Idle and Latency */
9579                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9580                                 MDIO_84833_TOP_CFG_SCRATCH_REG4,
9581                                 PHY84833_CONSTANT_LATENCY + 1);
9582
9583                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9584                                 MDIO_84833_TOP_CFG_DATA3_REG,
9585                                 PHY84833_CONSTANT_LATENCY + 1);
9586
9587                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9588                                 MDIO_84833_TOP_CFG_DATA4_REG,
9589                                 PHY84833_CONSTANT_LATENCY);
9590
9591                 /* Send EEE instruction to command register */
9592                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9593                                 MDIO_84833_TOP_CFG_SCRATCH_REG0,
9594                                 PHY84833_DIAG_CMD_SET_EEE_MODE);
9595
9596                 /* Ensure that the command has completed */
9597                 for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9598                         bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9599                                         MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9600                         if ((val == PHY84833_CMD_COMPLETE_PASS) ||
9601                                 (val == PHY84833_CMD_COMPLETE_ERROR))
9602                                 break;
9603                         usleep_range(1000, 1000);
9604                 }
9605                 if ((idx >= PHY84833_HDSHK_WAIT) ||
9606                         (val == PHY84833_CMD_COMPLETE_ERROR)) {
9607                         DP(NETIF_MSG_LINK, "AutogrEEEn: command failed.\n");
9608                         return -EINVAL;
9609                 }
9610
9611                 /* Reset command handler */
9612                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9613                             MDIO_84833_TOP_CFG_SCRATCH_REG2,
9614                             PHY84833_CMD_CLEAR_COMPLETE);
9615         }
9616
9617         if (initialize)
9618                 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
9619         else
9620                 bnx2x_save_848xx_spirom_version(phy, params);
9621         /* 84833 PHY has a better feature and doesn't need to support this. */
9622         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9623                 cms_enable = REG_RD(bp, params->shmem_base +
9624                         offsetof(struct shmem_region,
9625                         dev_info.port_hw_config[params->port].default_cfg)) &
9626                         PORT_HW_CFG_ENABLE_CMS_MASK;
9627
9628                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9629                                 MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
9630                 if (cms_enable)
9631                         val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
9632                 else
9633                         val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
9634                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9635                                  MDIO_CTL_REG_84823_USER_CTRL_REG, val);
9636         }
9637
9638         return rc;
9639 }
9640
9641 static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
9642                                   struct link_params *params,
9643                                   struct link_vars *vars)
9644 {
9645         struct bnx2x *bp = params->bp;
9646         u16 val, val1, val2;
9647         u8 link_up = 0;
9648
9649
9650         /* Check 10G-BaseT link status */
9651         /* Check PMD signal ok */
9652         bnx2x_cl45_read(bp, phy,
9653                         MDIO_AN_DEVAD, 0xFFFA, &val1);
9654         bnx2x_cl45_read(bp, phy,
9655                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
9656                         &val2);
9657         DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
9658
9659         /* Check link 10G */
9660         if (val2 & (1<<11)) {
9661                 vars->line_speed = SPEED_10000;
9662                 vars->duplex = DUPLEX_FULL;
9663                 link_up = 1;
9664                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
9665         } else { /* Check Legacy speed link */
9666                 u16 legacy_status, legacy_speed;
9667
9668                 /* Enable expansion register 0x42 (Operation mode status) */
9669                 bnx2x_cl45_write(bp, phy,
9670                                  MDIO_AN_DEVAD,
9671                                  MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
9672
9673                 /* Get legacy speed operation status */
9674                 bnx2x_cl45_read(bp, phy,
9675                                 MDIO_AN_DEVAD,
9676                                 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
9677                                 &legacy_status);
9678
9679                 DP(NETIF_MSG_LINK, "Legacy speed status"
9680                              " = 0x%x\n", legacy_status);
9681                 link_up = ((legacy_status & (1<<11)) == (1<<11));
9682                 if (link_up) {
9683                         legacy_speed = (legacy_status & (3<<9));
9684                         if (legacy_speed == (0<<9))
9685                                 vars->line_speed = SPEED_10;
9686                         else if (legacy_speed == (1<<9))
9687                                 vars->line_speed = SPEED_100;
9688                         else if (legacy_speed == (2<<9))
9689                                 vars->line_speed = SPEED_1000;
9690                         else /* Should not happen */
9691                                 vars->line_speed = 0;
9692
9693                         if (legacy_status & (1<<8))
9694                                 vars->duplex = DUPLEX_FULL;
9695                         else
9696                                 vars->duplex = DUPLEX_HALF;
9697
9698                         DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
9699                                    " is_duplex_full= %d\n", vars->line_speed,
9700                                    (vars->duplex == DUPLEX_FULL));
9701                         /* Check legacy speed AN resolution */
9702                         bnx2x_cl45_read(bp, phy,
9703                                         MDIO_AN_DEVAD,
9704                                         MDIO_AN_REG_8481_LEGACY_MII_STATUS,
9705                                         &val);
9706                         if (val & (1<<5))
9707                                 vars->link_status |=
9708                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
9709                         bnx2x_cl45_read(bp, phy,
9710                                         MDIO_AN_DEVAD,
9711                                         MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
9712                                         &val);
9713                         if ((val & (1<<0)) == 0)
9714                                 vars->link_status |=
9715                                         LINK_STATUS_PARALLEL_DETECTION_USED;
9716                 }
9717         }
9718         if (link_up) {
9719                 DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
9720                            vars->line_speed);
9721                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
9722         }
9723
9724         return link_up;
9725 }
9726
9727
9728 static int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
9729 {
9730         int status = 0;
9731         u32 spirom_ver;
9732         spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
9733         status = bnx2x_format_ver(spirom_ver, str, len);
9734         return status;
9735 }
9736
9737 static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
9738                                 struct link_params *params)
9739 {
9740         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
9741                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
9742         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
9743                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
9744 }
9745
9746 static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
9747                                         struct link_params *params)
9748 {
9749         bnx2x_cl45_write(params->bp, phy,
9750                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
9751         bnx2x_cl45_write(params->bp, phy,
9752                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
9753 }
9754
9755 static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
9756                                    struct link_params *params)
9757 {
9758         struct bnx2x *bp = params->bp;
9759         u8 port;
9760         u16 val16;
9761
9762         if (!(CHIP_IS_E1(bp)))
9763                 port = BP_PATH(bp);
9764         else
9765                 port = params->port;
9766
9767         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9768                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
9769                                MISC_REGISTERS_GPIO_OUTPUT_LOW,
9770                                port);
9771         } else {
9772                 bnx2x_cl45_read(bp, phy,
9773                                 MDIO_CTL_DEVAD,
9774                                 0x400f, &val16);
9775                 /* Put to low power mode on newer FW */
9776                 if ((val16 & 0x303f) > 0x1009)
9777                         bnx2x_cl45_write(bp, phy,
9778                                         MDIO_PMA_DEVAD,
9779                                         MDIO_PMA_REG_CTRL, 0x800);
9780         }
9781 }
9782
9783 static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
9784                                      struct link_params *params, u8 mode)
9785 {
9786         struct bnx2x *bp = params->bp;
9787         u16 val;
9788         u8 port;
9789
9790         if (!(CHIP_IS_E1(bp)))
9791                 port = BP_PATH(bp);
9792         else
9793                 port = params->port;
9794
9795         switch (mode) {
9796         case LED_MODE_OFF:
9797
9798                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", port);
9799
9800                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9801                     SHARED_HW_CFG_LED_EXTPHY1) {
9802
9803                         /* Set LED masks */
9804                         bnx2x_cl45_write(bp, phy,
9805                                         MDIO_PMA_DEVAD,
9806                                         MDIO_PMA_REG_8481_LED1_MASK,
9807                                         0x0);
9808
9809                         bnx2x_cl45_write(bp, phy,
9810                                         MDIO_PMA_DEVAD,
9811                                         MDIO_PMA_REG_8481_LED2_MASK,
9812                                         0x0);
9813
9814                         bnx2x_cl45_write(bp, phy,
9815                                         MDIO_PMA_DEVAD,
9816                                         MDIO_PMA_REG_8481_LED3_MASK,
9817                                         0x0);
9818
9819                         bnx2x_cl45_write(bp, phy,
9820                                         MDIO_PMA_DEVAD,
9821                                         MDIO_PMA_REG_8481_LED5_MASK,
9822                                         0x0);
9823
9824                 } else {
9825                         bnx2x_cl45_write(bp, phy,
9826                                          MDIO_PMA_DEVAD,
9827                                          MDIO_PMA_REG_8481_LED1_MASK,
9828                                          0x0);
9829                 }
9830                 break;
9831         case LED_MODE_FRONT_PANEL_OFF:
9832
9833                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
9834                    port);
9835
9836                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9837                     SHARED_HW_CFG_LED_EXTPHY1) {
9838
9839                         /* Set LED masks */
9840                         bnx2x_cl45_write(bp, phy,
9841                                          MDIO_PMA_DEVAD,
9842                                          MDIO_PMA_REG_8481_LED1_MASK,
9843                                          0x0);
9844
9845                         bnx2x_cl45_write(bp, phy,
9846                                          MDIO_PMA_DEVAD,
9847                                          MDIO_PMA_REG_8481_LED2_MASK,
9848                                          0x0);
9849
9850                         bnx2x_cl45_write(bp, phy,
9851                                          MDIO_PMA_DEVAD,
9852                                          MDIO_PMA_REG_8481_LED3_MASK,
9853                                          0x0);
9854
9855                         bnx2x_cl45_write(bp, phy,
9856                                          MDIO_PMA_DEVAD,
9857                                          MDIO_PMA_REG_8481_LED5_MASK,
9858                                          0x20);
9859
9860                 } else {
9861                         bnx2x_cl45_write(bp, phy,
9862                                          MDIO_PMA_DEVAD,
9863                                          MDIO_PMA_REG_8481_LED1_MASK,
9864                                          0x0);
9865                 }
9866                 break;
9867         case LED_MODE_ON:
9868
9869                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", port);
9870
9871                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9872                     SHARED_HW_CFG_LED_EXTPHY1) {
9873                         /* Set control reg */
9874                         bnx2x_cl45_read(bp, phy,
9875                                         MDIO_PMA_DEVAD,
9876                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
9877                                         &val);
9878                         val &= 0x8000;
9879                         val |= 0x2492;
9880
9881                         bnx2x_cl45_write(bp, phy,
9882                                          MDIO_PMA_DEVAD,
9883                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
9884                                          val);
9885
9886                         /* Set LED masks */
9887                         bnx2x_cl45_write(bp, phy,
9888                                          MDIO_PMA_DEVAD,
9889                                          MDIO_PMA_REG_8481_LED1_MASK,
9890                                          0x0);
9891
9892                         bnx2x_cl45_write(bp, phy,
9893                                          MDIO_PMA_DEVAD,
9894                                          MDIO_PMA_REG_8481_LED2_MASK,
9895                                          0x20);
9896
9897                         bnx2x_cl45_write(bp, phy,
9898                                          MDIO_PMA_DEVAD,
9899                                          MDIO_PMA_REG_8481_LED3_MASK,
9900                                          0x20);
9901
9902                         bnx2x_cl45_write(bp, phy,
9903                                          MDIO_PMA_DEVAD,
9904                                          MDIO_PMA_REG_8481_LED5_MASK,
9905                                          0x0);
9906                 } else {
9907                         bnx2x_cl45_write(bp, phy,
9908                                          MDIO_PMA_DEVAD,
9909                                          MDIO_PMA_REG_8481_LED1_MASK,
9910                                          0x20);
9911                 }
9912                 break;
9913
9914         case LED_MODE_OPER:
9915
9916                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", port);
9917
9918                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9919                     SHARED_HW_CFG_LED_EXTPHY1) {
9920
9921                         /* Set control reg */
9922                         bnx2x_cl45_read(bp, phy,
9923                                         MDIO_PMA_DEVAD,
9924                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
9925                                         &val);
9926
9927                         if (!((val &
9928                                MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
9929                           >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
9930                                 DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n");
9931                                 bnx2x_cl45_write(bp, phy,
9932                                                  MDIO_PMA_DEVAD,
9933                                                  MDIO_PMA_REG_8481_LINK_SIGNAL,
9934                                                  0xa492);
9935                         }
9936
9937                         /* Set LED masks */
9938                         bnx2x_cl45_write(bp, phy,
9939                                          MDIO_PMA_DEVAD,
9940                                          MDIO_PMA_REG_8481_LED1_MASK,
9941                                          0x10);
9942
9943                         bnx2x_cl45_write(bp, phy,
9944                                          MDIO_PMA_DEVAD,
9945                                          MDIO_PMA_REG_8481_LED2_MASK,
9946                                          0x80);
9947
9948                         bnx2x_cl45_write(bp, phy,
9949                                          MDIO_PMA_DEVAD,
9950                                          MDIO_PMA_REG_8481_LED3_MASK,
9951                                          0x98);
9952
9953                         bnx2x_cl45_write(bp, phy,
9954                                          MDIO_PMA_DEVAD,
9955                                          MDIO_PMA_REG_8481_LED5_MASK,
9956                                          0x40);
9957
9958                 } else {
9959                         bnx2x_cl45_write(bp, phy,
9960                                          MDIO_PMA_DEVAD,
9961                                          MDIO_PMA_REG_8481_LED1_MASK,
9962                                          0x80);
9963
9964                         /* Tell LED3 to blink on source */
9965                         bnx2x_cl45_read(bp, phy,
9966                                         MDIO_PMA_DEVAD,
9967                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
9968                                         &val);
9969                         val &= ~(7<<6);
9970                         val |= (1<<6); /* A83B[8:6]= 1 */
9971                         bnx2x_cl45_write(bp, phy,
9972                                          MDIO_PMA_DEVAD,
9973                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
9974                                          val);
9975                 }
9976                 break;
9977         }
9978
9979         /*
9980          * This is a workaround for E3+84833 until autoneg
9981          * restart is fixed in f/w
9982          */
9983         if (CHIP_IS_E3(bp)) {
9984                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
9985                                 MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
9986         }
9987 }
9988
9989 /******************************************************************/
9990 /*                      54618SE PHY SECTION                       */
9991 /******************************************************************/
9992 static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
9993                                                struct link_params *params,
9994                                                struct link_vars *vars)
9995 {
9996         struct bnx2x *bp = params->bp;
9997         u8 port;
9998         u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
9999         u32 cfg_pin;
10000
10001         DP(NETIF_MSG_LINK, "54618SE cfg init\n");
10002         usleep_range(1000, 1000);
10003
10004         /* This works with E3 only, no need to check the chip
10005            before determining the port. */
10006         port = params->port;
10007
10008         cfg_pin = (REG_RD(bp, params->shmem_base +
10009                         offsetof(struct shmem_region,
10010                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
10011                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
10012                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
10013
10014         /* Drive pin high to bring the GPHY out of reset. */
10015         bnx2x_set_cfg_pin(bp, cfg_pin, 1);
10016
10017         /* wait for GPHY to reset */
10018         msleep(50);
10019
10020         /* reset phy */
10021         bnx2x_cl22_write(bp, phy,
10022                          MDIO_PMA_REG_CTRL, 0x8000);
10023         bnx2x_wait_reset_complete(bp, phy, params);
10024
10025         /*wait for GPHY to reset */
10026         msleep(50);
10027
10028         /* Configure LED4: set to INTR (0x6). */
10029         /* Accessing shadow register 0xe. */
10030         bnx2x_cl22_write(bp, phy,
10031                         MDIO_REG_GPHY_SHADOW,
10032                         MDIO_REG_GPHY_SHADOW_LED_SEL2);
10033         bnx2x_cl22_read(bp, phy,
10034                         MDIO_REG_GPHY_SHADOW,
10035                         &temp);
10036         temp &= ~(0xf << 4);
10037         temp |= (0x6 << 4);
10038         bnx2x_cl22_write(bp, phy,
10039                         MDIO_REG_GPHY_SHADOW,
10040                         MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
10041         /* Configure INTR based on link status change. */
10042         bnx2x_cl22_write(bp, phy,
10043                         MDIO_REG_INTR_MASK,
10044                         ~MDIO_REG_INTR_MASK_LINK_STATUS);
10045
10046         /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
10047         bnx2x_cl22_write(bp, phy,
10048                         MDIO_REG_GPHY_SHADOW,
10049                         MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
10050         bnx2x_cl22_read(bp, phy,
10051                         MDIO_REG_GPHY_SHADOW,
10052                         &temp);
10053         temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
10054         bnx2x_cl22_write(bp, phy,
10055                         MDIO_REG_GPHY_SHADOW,
10056                         MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
10057
10058         /* Set up fc */
10059         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
10060         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
10061         fc_val = 0;
10062         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
10063                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
10064                 fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
10065
10066         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
10067                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
10068                 fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
10069
10070         /* read all advertisement */
10071         bnx2x_cl22_read(bp, phy,
10072                         0x09,
10073                         &an_1000_val);
10074
10075         bnx2x_cl22_read(bp, phy,
10076                         0x04,
10077                         &an_10_100_val);
10078
10079         bnx2x_cl22_read(bp, phy,
10080                         MDIO_PMA_REG_CTRL,
10081                         &autoneg_val);
10082
10083         /* Disable forced speed */
10084         autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
10085         an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
10086                            (1<<11));
10087
10088         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10089                         (phy->speed_cap_mask &
10090                         PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
10091                         (phy->req_line_speed == SPEED_1000)) {
10092                 an_1000_val |= (1<<8);
10093                 autoneg_val |= (1<<9 | 1<<12);
10094                 if (phy->req_duplex == DUPLEX_FULL)
10095                         an_1000_val |= (1<<9);
10096                 DP(NETIF_MSG_LINK, "Advertising 1G\n");
10097         } else
10098                 an_1000_val &= ~((1<<8) | (1<<9));
10099
10100         bnx2x_cl22_write(bp, phy,
10101                         0x09,
10102                         an_1000_val);
10103         bnx2x_cl22_read(bp, phy,
10104                         0x09,
10105                         &an_1000_val);
10106
10107         /* set 100 speed advertisement */
10108         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10109                         (phy->speed_cap_mask &
10110                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
10111                         PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
10112                 an_10_100_val |= (1<<7);
10113                 /* Enable autoneg and restart autoneg for legacy speeds */
10114                 autoneg_val |= (1<<9 | 1<<12);
10115
10116                 if (phy->req_duplex == DUPLEX_FULL)
10117                         an_10_100_val |= (1<<8);
10118                 DP(NETIF_MSG_LINK, "Advertising 100M\n");
10119         }
10120
10121         /* set 10 speed advertisement */
10122         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10123                         (phy->speed_cap_mask &
10124                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
10125                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
10126                 an_10_100_val |= (1<<5);
10127                 autoneg_val |= (1<<9 | 1<<12);
10128                 if (phy->req_duplex == DUPLEX_FULL)
10129                         an_10_100_val |= (1<<6);
10130                 DP(NETIF_MSG_LINK, "Advertising 10M\n");
10131         }
10132
10133         /* Only 10/100 are allowed to work in FORCE mode */
10134         if (phy->req_line_speed == SPEED_100) {
10135                 autoneg_val |= (1<<13);
10136                 /* Enabled AUTO-MDIX when autoneg is disabled */
10137                 bnx2x_cl22_write(bp, phy,
10138                                 0x18,
10139                                 (1<<15 | 1<<9 | 7<<0));
10140                 DP(NETIF_MSG_LINK, "Setting 100M force\n");
10141         }
10142         if (phy->req_line_speed == SPEED_10) {
10143                 /* Enabled AUTO-MDIX when autoneg is disabled */
10144                 bnx2x_cl22_write(bp, phy,
10145                                 0x18,
10146                                 (1<<15 | 1<<9 | 7<<0));
10147                 DP(NETIF_MSG_LINK, "Setting 10M force\n");
10148         }
10149
10150         /* Check if we should turn on Auto-GrEEEn */
10151         bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &temp);
10152         if (temp == MDIO_REG_GPHY_ID_54618SE) {
10153                 if (params->feature_config_flags &
10154                     FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
10155                         temp = 6;
10156                         DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
10157                 } else {
10158                         temp = 0;
10159                         DP(NETIF_MSG_LINK, "Disabling Auto-GrEEEn\n");
10160                 }
10161                 bnx2x_cl22_write(bp, phy,
10162                                  MDIO_REG_GPHY_CL45_ADDR_REG, MDIO_AN_DEVAD);
10163                 bnx2x_cl22_write(bp, phy,
10164                                  MDIO_REG_GPHY_CL45_DATA_REG,
10165                                  MDIO_REG_GPHY_EEE_ADV);
10166                 bnx2x_cl22_write(bp, phy,
10167                                  MDIO_REG_GPHY_CL45_ADDR_REG,
10168                                  (0x1 << 14) | MDIO_AN_DEVAD);
10169                 bnx2x_cl22_write(bp, phy,
10170                                  MDIO_REG_GPHY_CL45_DATA_REG,
10171                                  temp);
10172         }
10173
10174         bnx2x_cl22_write(bp, phy,
10175                         0x04,
10176                         an_10_100_val | fc_val);
10177
10178         if (phy->req_duplex == DUPLEX_FULL)
10179                 autoneg_val |= (1<<8);
10180
10181         bnx2x_cl22_write(bp, phy,
10182                         MDIO_PMA_REG_CTRL, autoneg_val);
10183
10184         return 0;
10185 }
10186
10187 static void bnx2x_54618se_set_link_led(struct bnx2x_phy *phy,
10188                                        struct link_params *params, u8 mode)
10189 {
10190         struct bnx2x *bp = params->bp;
10191         DP(NETIF_MSG_LINK, "54618SE set link led (mode=%x)\n", mode);
10192         switch (mode) {
10193         case LED_MODE_FRONT_PANEL_OFF:
10194         case LED_MODE_OFF:
10195         case LED_MODE_OPER:
10196         case LED_MODE_ON:
10197         default:
10198                 break;
10199         }
10200         return;
10201 }
10202
10203 static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
10204                                      struct link_params *params)
10205 {
10206         struct bnx2x *bp = params->bp;
10207         u32 cfg_pin;
10208         u8 port;
10209
10210         /* This works with E3 only, no need to check the chip
10211            before determining the port. */
10212         port = params->port;
10213         cfg_pin = (REG_RD(bp, params->shmem_base +
10214                         offsetof(struct shmem_region,
10215                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
10216                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
10217                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
10218
10219         /* Drive pin low to put GPHY in reset. */
10220         bnx2x_set_cfg_pin(bp, cfg_pin, 0);
10221 }
10222
10223 static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
10224                                     struct link_params *params,
10225                                     struct link_vars *vars)
10226 {
10227         struct bnx2x *bp = params->bp;
10228         u16 val;
10229         u8 link_up = 0;
10230         u16 legacy_status, legacy_speed;
10231
10232         /* Get speed operation status */
10233         bnx2x_cl22_read(bp, phy,
10234                         0x19,
10235                         &legacy_status);
10236         DP(NETIF_MSG_LINK, "54618SE read_status: 0x%x\n", legacy_status);
10237
10238         /* Read status to clear the PHY interrupt. */
10239         bnx2x_cl22_read(bp, phy,
10240                         MDIO_REG_INTR_STATUS,
10241                         &val);
10242
10243         link_up = ((legacy_status & (1<<2)) == (1<<2));
10244
10245         if (link_up) {
10246                 legacy_speed = (legacy_status & (7<<8));
10247                 if (legacy_speed == (7<<8)) {
10248                         vars->line_speed = SPEED_1000;
10249                         vars->duplex = DUPLEX_FULL;
10250                 } else if (legacy_speed == (6<<8)) {
10251                         vars->line_speed = SPEED_1000;
10252                         vars->duplex = DUPLEX_HALF;
10253                 } else if (legacy_speed == (5<<8)) {
10254                         vars->line_speed = SPEED_100;
10255                         vars->duplex = DUPLEX_FULL;
10256                 }
10257                 /* Omitting 100Base-T4 for now */
10258                 else if (legacy_speed == (3<<8)) {
10259                         vars->line_speed = SPEED_100;
10260                         vars->duplex = DUPLEX_HALF;
10261                 } else if (legacy_speed == (2<<8)) {
10262                         vars->line_speed = SPEED_10;
10263                         vars->duplex = DUPLEX_FULL;
10264                 } else if (legacy_speed == (1<<8)) {
10265                         vars->line_speed = SPEED_10;
10266                         vars->duplex = DUPLEX_HALF;
10267                 } else /* Should not happen */
10268                         vars->line_speed = 0;
10269
10270                 DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
10271                            " is_duplex_full= %d\n", vars->line_speed,
10272                            (vars->duplex == DUPLEX_FULL));
10273
10274                 /* Check legacy speed AN resolution */
10275                 bnx2x_cl22_read(bp, phy,
10276                                 0x01,
10277                                 &val);
10278                 if (val & (1<<5))
10279                         vars->link_status |=
10280                                 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
10281                 bnx2x_cl22_read(bp, phy,
10282                                 0x06,
10283                                 &val);
10284                 if ((val & (1<<0)) == 0)
10285                         vars->link_status |=
10286                                 LINK_STATUS_PARALLEL_DETECTION_USED;
10287
10288                 DP(NETIF_MSG_LINK, "BCM54618SE: link speed is %d\n",
10289                            vars->line_speed);
10290
10291                 /* Report whether EEE is resolved. */
10292                 bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &val);
10293                 if (val == MDIO_REG_GPHY_ID_54618SE) {
10294                         if (vars->link_status &
10295                             LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
10296                                 val = 0;
10297                         else {
10298                                 bnx2x_cl22_write(bp, phy,
10299                                         MDIO_REG_GPHY_CL45_ADDR_REG,
10300                                         MDIO_AN_DEVAD);
10301                                 bnx2x_cl22_write(bp, phy,
10302                                         MDIO_REG_GPHY_CL45_DATA_REG,
10303                                         MDIO_REG_GPHY_EEE_RESOLVED);
10304                                 bnx2x_cl22_write(bp, phy,
10305                                         MDIO_REG_GPHY_CL45_ADDR_REG,
10306                                         (0x1 << 14) | MDIO_AN_DEVAD);
10307                                 bnx2x_cl22_read(bp, phy,
10308                                         MDIO_REG_GPHY_CL45_DATA_REG,
10309                                         &val);
10310                         }
10311                         DP(NETIF_MSG_LINK, "EEE resolution: 0x%x\n", val);
10312                 }
10313
10314                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10315         }
10316         return link_up;
10317 }
10318
10319 static void bnx2x_54618se_config_loopback(struct bnx2x_phy *phy,
10320                                           struct link_params *params)
10321 {
10322         struct bnx2x *bp = params->bp;
10323         u16 val;
10324         u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
10325
10326         DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54618se\n");
10327
10328         /* Enable master/slave manual mmode and set to master */
10329         /* mii write 9 [bits set 11 12] */
10330         bnx2x_cl22_write(bp, phy, 0x09, 3<<11);
10331
10332         /* forced 1G and disable autoneg */
10333         /* set val [mii read 0] */
10334         /* set val [expr $val & [bits clear 6 12 13]] */
10335         /* set val [expr $val | [bits set 6 8]] */
10336         /* mii write 0 $val */
10337         bnx2x_cl22_read(bp, phy, 0x00, &val);
10338         val &= ~((1<<6) | (1<<12) | (1<<13));
10339         val |= (1<<6) | (1<<8);
10340         bnx2x_cl22_write(bp, phy, 0x00, val);
10341
10342         /* Set external loopback and Tx using 6dB coding */
10343         /* mii write 0x18 7 */
10344         /* set val [mii read 0x18] */
10345         /* mii write 0x18 [expr $val | [bits set 10 15]] */
10346         bnx2x_cl22_write(bp, phy, 0x18, 7);
10347         bnx2x_cl22_read(bp, phy, 0x18, &val);
10348         bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15));
10349
10350         /* This register opens the gate for the UMAC despite its name */
10351         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
10352
10353         /*
10354          * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
10355          * length used by the MAC receive logic to check frames.
10356          */
10357         REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
10358 }
10359
10360 /******************************************************************/
10361 /*                      SFX7101 PHY SECTION                       */
10362 /******************************************************************/
10363 static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
10364                                        struct link_params *params)
10365 {
10366         struct bnx2x *bp = params->bp;
10367         /* SFX7101_XGXS_TEST1 */
10368         bnx2x_cl45_write(bp, phy,
10369                          MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
10370 }
10371
10372 static int bnx2x_7101_config_init(struct bnx2x_phy *phy,
10373                                   struct link_params *params,
10374                                   struct link_vars *vars)
10375 {
10376         u16 fw_ver1, fw_ver2, val;
10377         struct bnx2x *bp = params->bp;
10378         DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
10379
10380         /* Restore normal power mode*/
10381         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
10382                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10383         /* HW reset */
10384         bnx2x_ext_phy_hw_reset(bp, params->port);
10385         bnx2x_wait_reset_complete(bp, phy, params);
10386
10387         bnx2x_cl45_write(bp, phy,
10388                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
10389         DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
10390         bnx2x_cl45_write(bp, phy,
10391                          MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
10392
10393         bnx2x_ext_phy_set_pause(params, phy, vars);
10394         /* Restart autoneg */
10395         bnx2x_cl45_read(bp, phy,
10396                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
10397         val |= 0x200;
10398         bnx2x_cl45_write(bp, phy,
10399                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
10400
10401         /* Save spirom version */
10402         bnx2x_cl45_read(bp, phy,
10403                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
10404
10405         bnx2x_cl45_read(bp, phy,
10406                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
10407         bnx2x_save_spirom_version(bp, params->port,
10408                                   (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
10409         return 0;
10410 }
10411
10412 static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
10413                                  struct link_params *params,
10414                                  struct link_vars *vars)
10415 {
10416         struct bnx2x *bp = params->bp;
10417         u8 link_up;
10418         u16 val1, val2;
10419         bnx2x_cl45_read(bp, phy,
10420                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
10421         bnx2x_cl45_read(bp, phy,
10422                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
10423         DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
10424                    val2, val1);
10425         bnx2x_cl45_read(bp, phy,
10426                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
10427         bnx2x_cl45_read(bp, phy,
10428                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
10429         DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
10430                    val2, val1);
10431         link_up = ((val1 & 4) == 4);
10432         /* if link is up print the AN outcome of the SFX7101 PHY */
10433         if (link_up) {
10434                 bnx2x_cl45_read(bp, phy,
10435                                 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
10436                                 &val2);
10437                 vars->line_speed = SPEED_10000;
10438                 vars->duplex = DUPLEX_FULL;
10439                 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
10440                            val2, (val2 & (1<<14)));
10441                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
10442                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10443         }
10444         return link_up;
10445 }
10446
10447 static int bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
10448 {
10449         if (*len < 5)
10450                 return -EINVAL;
10451         str[0] = (spirom_ver & 0xFF);
10452         str[1] = (spirom_ver & 0xFF00) >> 8;
10453         str[2] = (spirom_ver & 0xFF0000) >> 16;
10454         str[3] = (spirom_ver & 0xFF000000) >> 24;
10455         str[4] = '\0';
10456         *len -= 5;
10457         return 0;
10458 }
10459
10460 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
10461 {
10462         u16 val, cnt;
10463
10464         bnx2x_cl45_read(bp, phy,
10465                         MDIO_PMA_DEVAD,
10466                         MDIO_PMA_REG_7101_RESET, &val);
10467
10468         for (cnt = 0; cnt < 10; cnt++) {
10469                 msleep(50);
10470                 /* Writes a self-clearing reset */
10471                 bnx2x_cl45_write(bp, phy,
10472                                  MDIO_PMA_DEVAD,
10473                                  MDIO_PMA_REG_7101_RESET,
10474                                  (val | (1<<15)));
10475                 /* Wait for clear */
10476                 bnx2x_cl45_read(bp, phy,
10477                                 MDIO_PMA_DEVAD,
10478                                 MDIO_PMA_REG_7101_RESET, &val);
10479
10480                 if ((val & (1<<15)) == 0)
10481                         break;
10482         }
10483 }
10484
10485 static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
10486                                 struct link_params *params) {
10487         /* Low power mode is controlled by GPIO 2 */
10488         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
10489                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10490         /* The PHY reset is controlled by GPIO 1 */
10491         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10492                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10493 }
10494
10495 static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
10496                                     struct link_params *params, u8 mode)
10497 {
10498         u16 val = 0;
10499         struct bnx2x *bp = params->bp;
10500         switch (mode) {
10501         case LED_MODE_FRONT_PANEL_OFF:
10502         case LED_MODE_OFF:
10503                 val = 2;
10504                 break;
10505         case LED_MODE_ON:
10506                 val = 1;
10507                 break;
10508         case LED_MODE_OPER:
10509                 val = 0;
10510                 break;
10511         }
10512         bnx2x_cl45_write(bp, phy,
10513                          MDIO_PMA_DEVAD,
10514                          MDIO_PMA_REG_7107_LINK_LED_CNTL,
10515                          val);
10516 }
10517
10518 /******************************************************************/
10519 /*                      STATIC PHY DECLARATION                    */
10520 /******************************************************************/
10521
10522 static struct bnx2x_phy phy_null = {
10523         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
10524         .addr           = 0,
10525         .def_md_devad   = 0,
10526         .flags          = FLAGS_INIT_XGXS_FIRST,
10527         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10528         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10529         .mdio_ctrl      = 0,
10530         .supported      = 0,
10531         .media_type     = ETH_PHY_NOT_PRESENT,
10532         .ver_addr       = 0,
10533         .req_flow_ctrl  = 0,
10534         .req_line_speed = 0,
10535         .speed_cap_mask = 0,
10536         .req_duplex     = 0,
10537         .rsrv           = 0,
10538         .config_init    = (config_init_t)NULL,
10539         .read_status    = (read_status_t)NULL,
10540         .link_reset     = (link_reset_t)NULL,
10541         .config_loopback = (config_loopback_t)NULL,
10542         .format_fw_ver  = (format_fw_ver_t)NULL,
10543         .hw_reset       = (hw_reset_t)NULL,
10544         .set_link_led   = (set_link_led_t)NULL,
10545         .phy_specific_func = (phy_specific_func_t)NULL
10546 };
10547
10548 static struct bnx2x_phy phy_serdes = {
10549         .type           = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
10550         .addr           = 0xff,
10551         .def_md_devad   = 0,
10552         .flags          = 0,
10553         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10554         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10555         .mdio_ctrl      = 0,
10556         .supported      = (SUPPORTED_10baseT_Half |
10557                            SUPPORTED_10baseT_Full |
10558                            SUPPORTED_100baseT_Half |
10559                            SUPPORTED_100baseT_Full |
10560                            SUPPORTED_1000baseT_Full |
10561                            SUPPORTED_2500baseX_Full |
10562                            SUPPORTED_TP |
10563                            SUPPORTED_Autoneg |
10564                            SUPPORTED_Pause |
10565                            SUPPORTED_Asym_Pause),
10566         .media_type     = ETH_PHY_BASE_T,
10567         .ver_addr       = 0,
10568         .req_flow_ctrl  = 0,
10569         .req_line_speed = 0,
10570         .speed_cap_mask = 0,
10571         .req_duplex     = 0,
10572         .rsrv           = 0,
10573         .config_init    = (config_init_t)bnx2x_xgxs_config_init,
10574         .read_status    = (read_status_t)bnx2x_link_settings_status,
10575         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
10576         .config_loopback = (config_loopback_t)NULL,
10577         .format_fw_ver  = (format_fw_ver_t)NULL,
10578         .hw_reset       = (hw_reset_t)NULL,
10579         .set_link_led   = (set_link_led_t)NULL,
10580         .phy_specific_func = (phy_specific_func_t)NULL
10581 };
10582
10583 static struct bnx2x_phy phy_xgxs = {
10584         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
10585         .addr           = 0xff,
10586         .def_md_devad   = 0,
10587         .flags          = 0,
10588         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10589         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10590         .mdio_ctrl      = 0,
10591         .supported      = (SUPPORTED_10baseT_Half |
10592                            SUPPORTED_10baseT_Full |
10593                            SUPPORTED_100baseT_Half |
10594                            SUPPORTED_100baseT_Full |
10595                            SUPPORTED_1000baseT_Full |
10596                            SUPPORTED_2500baseX_Full |
10597                            SUPPORTED_10000baseT_Full |
10598                            SUPPORTED_FIBRE |
10599                            SUPPORTED_Autoneg |
10600                            SUPPORTED_Pause |
10601                            SUPPORTED_Asym_Pause),
10602         .media_type     = ETH_PHY_CX4,
10603         .ver_addr       = 0,
10604         .req_flow_ctrl  = 0,
10605         .req_line_speed = 0,
10606         .speed_cap_mask = 0,
10607         .req_duplex     = 0,
10608         .rsrv           = 0,
10609         .config_init    = (config_init_t)bnx2x_xgxs_config_init,
10610         .read_status    = (read_status_t)bnx2x_link_settings_status,
10611         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
10612         .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
10613         .format_fw_ver  = (format_fw_ver_t)NULL,
10614         .hw_reset       = (hw_reset_t)NULL,
10615         .set_link_led   = (set_link_led_t)NULL,
10616         .phy_specific_func = (phy_specific_func_t)NULL
10617 };
10618 static struct bnx2x_phy phy_warpcore = {
10619         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
10620         .addr           = 0xff,
10621         .def_md_devad   = 0,
10622         .flags          = FLAGS_HW_LOCK_REQUIRED,
10623         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10624         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10625         .mdio_ctrl      = 0,
10626         .supported      = (SUPPORTED_10baseT_Half |
10627                              SUPPORTED_10baseT_Full |
10628                              SUPPORTED_100baseT_Half |
10629                              SUPPORTED_100baseT_Full |
10630                              SUPPORTED_1000baseT_Full |
10631                              SUPPORTED_10000baseT_Full |
10632                              SUPPORTED_20000baseKR2_Full |
10633                              SUPPORTED_20000baseMLD2_Full |
10634                              SUPPORTED_FIBRE |
10635                              SUPPORTED_Autoneg |
10636                              SUPPORTED_Pause |
10637                              SUPPORTED_Asym_Pause),
10638         .media_type     = ETH_PHY_UNSPECIFIED,
10639         .ver_addr       = 0,
10640         .req_flow_ctrl  = 0,
10641         .req_line_speed = 0,
10642         .speed_cap_mask = 0,
10643         /* req_duplex = */0,
10644         /* rsrv = */0,
10645         .config_init    = (config_init_t)bnx2x_warpcore_config_init,
10646         .read_status    = (read_status_t)bnx2x_warpcore_read_status,
10647         .link_reset     = (link_reset_t)bnx2x_warpcore_link_reset,
10648         .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback,
10649         .format_fw_ver  = (format_fw_ver_t)NULL,
10650         .hw_reset       = (hw_reset_t)bnx2x_warpcore_hw_reset,
10651         .set_link_led   = (set_link_led_t)NULL,
10652         .phy_specific_func = (phy_specific_func_t)NULL
10653 };
10654
10655
10656 static struct bnx2x_phy phy_7101 = {
10657         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
10658         .addr           = 0xff,
10659         .def_md_devad   = 0,
10660         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
10661         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10662         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10663         .mdio_ctrl      = 0,
10664         .supported      = (SUPPORTED_10000baseT_Full |
10665                            SUPPORTED_TP |
10666                            SUPPORTED_Autoneg |
10667                            SUPPORTED_Pause |
10668                            SUPPORTED_Asym_Pause),
10669         .media_type     = ETH_PHY_BASE_T,
10670         .ver_addr       = 0,
10671         .req_flow_ctrl  = 0,
10672         .req_line_speed = 0,
10673         .speed_cap_mask = 0,
10674         .req_duplex     = 0,
10675         .rsrv           = 0,
10676         .config_init    = (config_init_t)bnx2x_7101_config_init,
10677         .read_status    = (read_status_t)bnx2x_7101_read_status,
10678         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
10679         .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
10680         .format_fw_ver  = (format_fw_ver_t)bnx2x_7101_format_ver,
10681         .hw_reset       = (hw_reset_t)bnx2x_7101_hw_reset,
10682         .set_link_led   = (set_link_led_t)bnx2x_7101_set_link_led,
10683         .phy_specific_func = (phy_specific_func_t)NULL
10684 };
10685 static struct bnx2x_phy phy_8073 = {
10686         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
10687         .addr           = 0xff,
10688         .def_md_devad   = 0,
10689         .flags          = FLAGS_HW_LOCK_REQUIRED,
10690         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10691         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10692         .mdio_ctrl      = 0,
10693         .supported      = (SUPPORTED_10000baseT_Full |
10694                            SUPPORTED_2500baseX_Full |
10695                            SUPPORTED_1000baseT_Full |
10696                            SUPPORTED_FIBRE |
10697                            SUPPORTED_Autoneg |
10698                            SUPPORTED_Pause |
10699                            SUPPORTED_Asym_Pause),
10700         .media_type     = ETH_PHY_KR,
10701         .ver_addr       = 0,
10702         .req_flow_ctrl  = 0,
10703         .req_line_speed = 0,
10704         .speed_cap_mask = 0,
10705         .req_duplex     = 0,
10706         .rsrv           = 0,
10707         .config_init    = (config_init_t)bnx2x_8073_config_init,
10708         .read_status    = (read_status_t)bnx2x_8073_read_status,
10709         .link_reset     = (link_reset_t)bnx2x_8073_link_reset,
10710         .config_loopback = (config_loopback_t)NULL,
10711         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
10712         .hw_reset       = (hw_reset_t)NULL,
10713         .set_link_led   = (set_link_led_t)NULL,
10714         .phy_specific_func = (phy_specific_func_t)NULL
10715 };
10716 static struct bnx2x_phy phy_8705 = {
10717         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
10718         .addr           = 0xff,
10719         .def_md_devad   = 0,
10720         .flags          = FLAGS_INIT_XGXS_FIRST,
10721         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10722         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10723         .mdio_ctrl      = 0,
10724         .supported      = (SUPPORTED_10000baseT_Full |
10725                            SUPPORTED_FIBRE |
10726                            SUPPORTED_Pause |
10727                            SUPPORTED_Asym_Pause),
10728         .media_type     = ETH_PHY_XFP_FIBER,
10729         .ver_addr       = 0,
10730         .req_flow_ctrl  = 0,
10731         .req_line_speed = 0,
10732         .speed_cap_mask = 0,
10733         .req_duplex     = 0,
10734         .rsrv           = 0,
10735         .config_init    = (config_init_t)bnx2x_8705_config_init,
10736         .read_status    = (read_status_t)bnx2x_8705_read_status,
10737         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
10738         .config_loopback = (config_loopback_t)NULL,
10739         .format_fw_ver  = (format_fw_ver_t)bnx2x_null_format_ver,
10740         .hw_reset       = (hw_reset_t)NULL,
10741         .set_link_led   = (set_link_led_t)NULL,
10742         .phy_specific_func = (phy_specific_func_t)NULL
10743 };
10744 static struct bnx2x_phy phy_8706 = {
10745         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
10746         .addr           = 0xff,
10747         .def_md_devad   = 0,
10748         .flags          = FLAGS_INIT_XGXS_FIRST,
10749         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10750         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10751         .mdio_ctrl      = 0,
10752         .supported      = (SUPPORTED_10000baseT_Full |
10753                            SUPPORTED_1000baseT_Full |
10754                            SUPPORTED_FIBRE |
10755                            SUPPORTED_Pause |
10756                            SUPPORTED_Asym_Pause),
10757         .media_type     = ETH_PHY_SFP_FIBER,
10758         .ver_addr       = 0,
10759         .req_flow_ctrl  = 0,
10760         .req_line_speed = 0,
10761         .speed_cap_mask = 0,
10762         .req_duplex     = 0,
10763         .rsrv           = 0,
10764         .config_init    = (config_init_t)bnx2x_8706_config_init,
10765         .read_status    = (read_status_t)bnx2x_8706_read_status,
10766         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
10767         .config_loopback = (config_loopback_t)NULL,
10768         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
10769         .hw_reset       = (hw_reset_t)NULL,
10770         .set_link_led   = (set_link_led_t)NULL,
10771         .phy_specific_func = (phy_specific_func_t)NULL
10772 };
10773
10774 static struct bnx2x_phy phy_8726 = {
10775         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
10776         .addr           = 0xff,
10777         .def_md_devad   = 0,
10778         .flags          = (FLAGS_HW_LOCK_REQUIRED |
10779                            FLAGS_INIT_XGXS_FIRST),
10780         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10781         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10782         .mdio_ctrl      = 0,
10783         .supported      = (SUPPORTED_10000baseT_Full |
10784                            SUPPORTED_1000baseT_Full |
10785                            SUPPORTED_Autoneg |
10786                            SUPPORTED_FIBRE |
10787                            SUPPORTED_Pause |
10788                            SUPPORTED_Asym_Pause),
10789         .media_type     = ETH_PHY_NOT_PRESENT,
10790         .ver_addr       = 0,
10791         .req_flow_ctrl  = 0,
10792         .req_line_speed = 0,
10793         .speed_cap_mask = 0,
10794         .req_duplex     = 0,
10795         .rsrv           = 0,
10796         .config_init    = (config_init_t)bnx2x_8726_config_init,
10797         .read_status    = (read_status_t)bnx2x_8726_read_status,
10798         .link_reset     = (link_reset_t)bnx2x_8726_link_reset,
10799         .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
10800         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
10801         .hw_reset       = (hw_reset_t)NULL,
10802         .set_link_led   = (set_link_led_t)NULL,
10803         .phy_specific_func = (phy_specific_func_t)NULL
10804 };
10805
10806 static struct bnx2x_phy phy_8727 = {
10807         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
10808         .addr           = 0xff,
10809         .def_md_devad   = 0,
10810         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
10811         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10812         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10813         .mdio_ctrl      = 0,
10814         .supported      = (SUPPORTED_10000baseT_Full |
10815                            SUPPORTED_1000baseT_Full |
10816                            SUPPORTED_FIBRE |
10817                            SUPPORTED_Pause |
10818                            SUPPORTED_Asym_Pause),
10819         .media_type     = ETH_PHY_NOT_PRESENT,
10820         .ver_addr       = 0,
10821         .req_flow_ctrl  = 0,
10822         .req_line_speed = 0,
10823         .speed_cap_mask = 0,
10824         .req_duplex     = 0,
10825         .rsrv           = 0,
10826         .config_init    = (config_init_t)bnx2x_8727_config_init,
10827         .read_status    = (read_status_t)bnx2x_8727_read_status,
10828         .link_reset     = (link_reset_t)bnx2x_8727_link_reset,
10829         .config_loopback = (config_loopback_t)NULL,
10830         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
10831         .hw_reset       = (hw_reset_t)bnx2x_8727_hw_reset,
10832         .set_link_led   = (set_link_led_t)bnx2x_8727_set_link_led,
10833         .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
10834 };
10835 static struct bnx2x_phy phy_8481 = {
10836         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
10837         .addr           = 0xff,
10838         .def_md_devad   = 0,
10839         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
10840                           FLAGS_REARM_LATCH_SIGNAL,
10841         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10842         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10843         .mdio_ctrl      = 0,
10844         .supported      = (SUPPORTED_10baseT_Half |
10845                            SUPPORTED_10baseT_Full |
10846                            SUPPORTED_100baseT_Half |
10847                            SUPPORTED_100baseT_Full |
10848                            SUPPORTED_1000baseT_Full |
10849                            SUPPORTED_10000baseT_Full |
10850                            SUPPORTED_TP |
10851                            SUPPORTED_Autoneg |
10852                            SUPPORTED_Pause |
10853                            SUPPORTED_Asym_Pause),
10854         .media_type     = ETH_PHY_BASE_T,
10855         .ver_addr       = 0,
10856         .req_flow_ctrl  = 0,
10857         .req_line_speed = 0,
10858         .speed_cap_mask = 0,
10859         .req_duplex     = 0,
10860         .rsrv           = 0,
10861         .config_init    = (config_init_t)bnx2x_8481_config_init,
10862         .read_status    = (read_status_t)bnx2x_848xx_read_status,
10863         .link_reset     = (link_reset_t)bnx2x_8481_link_reset,
10864         .config_loopback = (config_loopback_t)NULL,
10865         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
10866         .hw_reset       = (hw_reset_t)bnx2x_8481_hw_reset,
10867         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
10868         .phy_specific_func = (phy_specific_func_t)NULL
10869 };
10870
10871 static struct bnx2x_phy phy_84823 = {
10872         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
10873         .addr           = 0xff,
10874         .def_md_devad   = 0,
10875         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
10876                           FLAGS_REARM_LATCH_SIGNAL,
10877         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10878         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10879         .mdio_ctrl      = 0,
10880         .supported      = (SUPPORTED_10baseT_Half |
10881                            SUPPORTED_10baseT_Full |
10882                            SUPPORTED_100baseT_Half |
10883                            SUPPORTED_100baseT_Full |
10884                            SUPPORTED_1000baseT_Full |
10885                            SUPPORTED_10000baseT_Full |
10886                            SUPPORTED_TP |
10887                            SUPPORTED_Autoneg |
10888                            SUPPORTED_Pause |
10889                            SUPPORTED_Asym_Pause),
10890         .media_type     = ETH_PHY_BASE_T,
10891         .ver_addr       = 0,
10892         .req_flow_ctrl  = 0,
10893         .req_line_speed = 0,
10894         .speed_cap_mask = 0,
10895         .req_duplex     = 0,
10896         .rsrv           = 0,
10897         .config_init    = (config_init_t)bnx2x_848x3_config_init,
10898         .read_status    = (read_status_t)bnx2x_848xx_read_status,
10899         .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
10900         .config_loopback = (config_loopback_t)NULL,
10901         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
10902         .hw_reset       = (hw_reset_t)NULL,
10903         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
10904         .phy_specific_func = (phy_specific_func_t)NULL
10905 };
10906
10907 static struct bnx2x_phy phy_84833 = {
10908         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
10909         .addr           = 0xff,
10910         .def_md_devad   = 0,
10911         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
10912                             FLAGS_REARM_LATCH_SIGNAL,
10913         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10914         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10915         .mdio_ctrl      = 0,
10916         .supported      = (SUPPORTED_100baseT_Half |
10917                            SUPPORTED_100baseT_Full |
10918                            SUPPORTED_1000baseT_Full |
10919                            SUPPORTED_10000baseT_Full |
10920                            SUPPORTED_TP |
10921                            SUPPORTED_Autoneg |
10922                            SUPPORTED_Pause |
10923                            SUPPORTED_Asym_Pause),
10924         .media_type     = ETH_PHY_BASE_T,
10925         .ver_addr       = 0,
10926         .req_flow_ctrl  = 0,
10927         .req_line_speed = 0,
10928         .speed_cap_mask = 0,
10929         .req_duplex     = 0,
10930         .rsrv           = 0,
10931         .config_init    = (config_init_t)bnx2x_848x3_config_init,
10932         .read_status    = (read_status_t)bnx2x_848xx_read_status,
10933         .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
10934         .config_loopback = (config_loopback_t)NULL,
10935         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
10936         .hw_reset       = (hw_reset_t)bnx2x_84833_hw_reset_phy,
10937         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
10938         .phy_specific_func = (phy_specific_func_t)NULL
10939 };
10940
10941 static struct bnx2x_phy phy_54618se = {
10942         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE,
10943         .addr           = 0xff,
10944         .def_md_devad   = 0,
10945         .flags          = FLAGS_INIT_XGXS_FIRST,
10946         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10947         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10948         .mdio_ctrl      = 0,
10949         .supported      = (SUPPORTED_10baseT_Half |
10950                            SUPPORTED_10baseT_Full |
10951                            SUPPORTED_100baseT_Half |
10952                            SUPPORTED_100baseT_Full |
10953                            SUPPORTED_1000baseT_Full |
10954                            SUPPORTED_TP |
10955                            SUPPORTED_Autoneg |
10956                            SUPPORTED_Pause |
10957                            SUPPORTED_Asym_Pause),
10958         .media_type     = ETH_PHY_BASE_T,
10959         .ver_addr       = 0,
10960         .req_flow_ctrl  = 0,
10961         .req_line_speed = 0,
10962         .speed_cap_mask = 0,
10963         /* req_duplex = */0,
10964         /* rsrv = */0,
10965         .config_init    = (config_init_t)bnx2x_54618se_config_init,
10966         .read_status    = (read_status_t)bnx2x_54618se_read_status,
10967         .link_reset     = (link_reset_t)bnx2x_54618se_link_reset,
10968         .config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
10969         .format_fw_ver  = (format_fw_ver_t)NULL,
10970         .hw_reset       = (hw_reset_t)NULL,
10971         .set_link_led   = (set_link_led_t)bnx2x_54618se_set_link_led,
10972         .phy_specific_func = (phy_specific_func_t)NULL
10973 };
10974 /*****************************************************************/
10975 /*                                                               */
10976 /* Populate the phy according. Main function: bnx2x_populate_phy   */
10977 /*                                                               */
10978 /*****************************************************************/
10979
10980 static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
10981                                      struct bnx2x_phy *phy, u8 port,
10982                                      u8 phy_index)
10983 {
10984         /* Get the 4 lanes xgxs config rx and tx */
10985         u32 rx = 0, tx = 0, i;
10986         for (i = 0; i < 2; i++) {
10987                 /*
10988                  * INT_PHY and EXT_PHY1 share the same value location in the
10989                  * shmem. When num_phys is greater than 1, than this value
10990                  * applies only to EXT_PHY1
10991                  */
10992                 if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
10993                         rx = REG_RD(bp, shmem_base +
10994                                     offsetof(struct shmem_region,
10995                           dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
10996
10997                         tx = REG_RD(bp, shmem_base +
10998                                     offsetof(struct shmem_region,
10999                           dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
11000                 } else {
11001                         rx = REG_RD(bp, shmem_base +
11002                                     offsetof(struct shmem_region,
11003                          dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11004
11005                         tx = REG_RD(bp, shmem_base +
11006                                     offsetof(struct shmem_region,
11007                          dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11008                 }
11009
11010                 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
11011                 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
11012
11013                 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
11014                 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
11015         }
11016 }
11017
11018 static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
11019                                     u8 phy_index, u8 port)
11020 {
11021         u32 ext_phy_config = 0;
11022         switch (phy_index) {
11023         case EXT_PHY1:
11024                 ext_phy_config = REG_RD(bp, shmem_base +
11025                                               offsetof(struct shmem_region,
11026                         dev_info.port_hw_config[port].external_phy_config));
11027                 break;
11028         case EXT_PHY2:
11029                 ext_phy_config = REG_RD(bp, shmem_base +
11030                                               offsetof(struct shmem_region,
11031                         dev_info.port_hw_config[port].external_phy_config2));
11032                 break;
11033         default:
11034                 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
11035                 return -EINVAL;
11036         }
11037
11038         return ext_phy_config;
11039 }
11040 static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
11041                                   struct bnx2x_phy *phy)
11042 {
11043         u32 phy_addr;
11044         u32 chip_id;
11045         u32 switch_cfg = (REG_RD(bp, shmem_base +
11046                                        offsetof(struct shmem_region,
11047                         dev_info.port_feature_config[port].link_config)) &
11048                           PORT_FEATURE_CONNECTED_SWITCH_MASK);
11049         chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
11050         DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id);
11051         if (USES_WARPCORE(bp)) {
11052                 u32 serdes_net_if;
11053                 phy_addr = REG_RD(bp,
11054                                   MISC_REG_WC0_CTRL_PHY_ADDR);
11055                 *phy = phy_warpcore;
11056                 if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
11057                         phy->flags |= FLAGS_4_PORT_MODE;
11058                 else
11059                         phy->flags &= ~FLAGS_4_PORT_MODE;
11060                         /* Check Dual mode */
11061                 serdes_net_if = (REG_RD(bp, shmem_base +
11062                                         offsetof(struct shmem_region, dev_info.
11063                                         port_hw_config[port].default_cfg)) &
11064                                  PORT_HW_CFG_NET_SERDES_IF_MASK);
11065                 /*
11066                  * Set the appropriate supported and flags indications per
11067                  * interface type of the chip
11068                  */
11069                 switch (serdes_net_if) {
11070                 case PORT_HW_CFG_NET_SERDES_IF_SGMII:
11071                         phy->supported &= (SUPPORTED_10baseT_Half |
11072                                            SUPPORTED_10baseT_Full |
11073                                            SUPPORTED_100baseT_Half |
11074                                            SUPPORTED_100baseT_Full |
11075                                            SUPPORTED_1000baseT_Full |
11076                                            SUPPORTED_FIBRE |
11077                                            SUPPORTED_Autoneg |
11078                                            SUPPORTED_Pause |
11079                                            SUPPORTED_Asym_Pause);
11080                         phy->media_type = ETH_PHY_BASE_T;
11081                         break;
11082                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
11083                         phy->media_type = ETH_PHY_XFP_FIBER;
11084                         break;
11085                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
11086                         phy->supported &= (SUPPORTED_1000baseT_Full |
11087                                            SUPPORTED_10000baseT_Full |
11088                                            SUPPORTED_FIBRE |
11089                                            SUPPORTED_Pause |
11090                                            SUPPORTED_Asym_Pause);
11091                         phy->media_type = ETH_PHY_SFP_FIBER;
11092                         break;
11093                 case PORT_HW_CFG_NET_SERDES_IF_KR:
11094                         phy->media_type = ETH_PHY_KR;
11095                         phy->supported &= (SUPPORTED_1000baseT_Full |
11096                                            SUPPORTED_10000baseT_Full |
11097                                            SUPPORTED_FIBRE |
11098                                            SUPPORTED_Autoneg |
11099                                            SUPPORTED_Pause |
11100                                            SUPPORTED_Asym_Pause);
11101                         break;
11102                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
11103                         phy->media_type = ETH_PHY_KR;
11104                         phy->flags |= FLAGS_WC_DUAL_MODE;
11105                         phy->supported &= (SUPPORTED_20000baseMLD2_Full |
11106                                            SUPPORTED_FIBRE |
11107                                            SUPPORTED_Pause |
11108                                            SUPPORTED_Asym_Pause);
11109                         break;
11110                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
11111                         phy->media_type = ETH_PHY_KR;
11112                         phy->flags |= FLAGS_WC_DUAL_MODE;
11113                         phy->supported &= (SUPPORTED_20000baseKR2_Full |
11114                                            SUPPORTED_FIBRE |
11115                                            SUPPORTED_Pause |
11116                                            SUPPORTED_Asym_Pause);
11117                         break;
11118                 default:
11119                         DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n",
11120                                        serdes_net_if);
11121                         break;
11122                 }
11123
11124                 /*
11125                  * Enable MDC/MDIO work-around for E3 A0 since free running MDC
11126                  * was not set as expected. For B0, ECO will be enabled so there
11127                  * won't be an issue there
11128                  */
11129                 if (CHIP_REV(bp) == CHIP_REV_Ax)
11130                         phy->flags |= FLAGS_MDC_MDIO_WA;
11131         } else {
11132                 switch (switch_cfg) {
11133                 case SWITCH_CFG_1G:
11134                         phy_addr = REG_RD(bp,
11135                                           NIG_REG_SERDES0_CTRL_PHY_ADDR +
11136                                           port * 0x10);
11137                         *phy = phy_serdes;
11138                         break;
11139                 case SWITCH_CFG_10G:
11140                         phy_addr = REG_RD(bp,
11141                                           NIG_REG_XGXS0_CTRL_PHY_ADDR +
11142                                           port * 0x18);
11143                         *phy = phy_xgxs;
11144                         break;
11145                 default:
11146                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
11147                         return -EINVAL;
11148                 }
11149         }
11150         phy->addr = (u8)phy_addr;
11151         phy->mdio_ctrl = bnx2x_get_emac_base(bp,
11152                                             SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
11153                                             port);
11154         if (CHIP_IS_E2(bp))
11155                 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
11156         else
11157                 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
11158
11159         DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
11160                    port, phy->addr, phy->mdio_ctrl);
11161
11162         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
11163         return 0;
11164 }
11165
11166 static int bnx2x_populate_ext_phy(struct bnx2x *bp,
11167                                   u8 phy_index,
11168                                   u32 shmem_base,
11169                                   u32 shmem2_base,
11170                                   u8 port,
11171                                   struct bnx2x_phy *phy)
11172 {
11173         u32 ext_phy_config, phy_type, config2;
11174         u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
11175         ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
11176                                                   phy_index, port);
11177         phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
11178         /* Select the phy type */
11179         switch (phy_type) {
11180         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
11181                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
11182                 *phy = phy_8073;
11183                 break;
11184         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
11185                 *phy = phy_8705;
11186                 break;
11187         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
11188                 *phy = phy_8706;
11189                 break;
11190         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
11191                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11192                 *phy = phy_8726;
11193                 break;
11194         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
11195                 /* BCM8727_NOC => BCM8727 no over current */
11196                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11197                 *phy = phy_8727;
11198                 phy->flags |= FLAGS_NOC;
11199                 break;
11200         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
11201         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
11202                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11203                 *phy = phy_8727;
11204                 break;
11205         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
11206                 *phy = phy_8481;
11207                 break;
11208         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
11209                 *phy = phy_84823;
11210                 break;
11211         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
11212                 *phy = phy_84833;
11213                 break;
11214         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
11215                 *phy = phy_54618se;
11216                 break;
11217         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
11218                 *phy = phy_7101;
11219                 break;
11220         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
11221                 *phy = phy_null;
11222                 return -EINVAL;
11223         default:
11224                 *phy = phy_null;
11225                 return 0;
11226         }
11227
11228         phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
11229         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
11230
11231         /*
11232          * The shmem address of the phy version is located on different
11233          * structures. In case this structure is too old, do not set
11234          * the address
11235          */
11236         config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
11237                                         dev_info.shared_hw_config.config2));
11238         if (phy_index == EXT_PHY1) {
11239                 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
11240                                 port_mb[port].ext_phy_fw_version);
11241
11242                 /* Check specific mdc mdio settings */
11243                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
11244                         mdc_mdio_access = config2 &
11245                         SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
11246         } else {
11247                 u32 size = REG_RD(bp, shmem2_base);
11248
11249                 if (size >
11250                     offsetof(struct shmem2_region, ext_phy_fw_version2)) {
11251                         phy->ver_addr = shmem2_base +
11252                             offsetof(struct shmem2_region,
11253                                      ext_phy_fw_version2[port]);
11254                 }
11255                 /* Check specific mdc mdio settings */
11256                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
11257                         mdc_mdio_access = (config2 &
11258                         SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
11259                         (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
11260                          SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
11261         }
11262         phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
11263
11264         /*
11265          * In case mdc/mdio_access of the external phy is different than the
11266          * mdc/mdio access of the XGXS, a HW lock must be taken in each access
11267          * to prevent one port interfere with another port's CL45 operations.
11268          */
11269         if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
11270                 phy->flags |= FLAGS_HW_LOCK_REQUIRED;
11271         DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
11272                    phy_type, port, phy_index);
11273         DP(NETIF_MSG_LINK, "             addr=0x%x, mdio_ctl=0x%x\n",
11274                    phy->addr, phy->mdio_ctrl);
11275         return 0;
11276 }
11277
11278 static int bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
11279                               u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
11280 {
11281         int status = 0;
11282         phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
11283         if (phy_index == INT_PHY)
11284                 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
11285         status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
11286                                         port, phy);
11287         return status;
11288 }
11289
11290 static void bnx2x_phy_def_cfg(struct link_params *params,
11291                               struct bnx2x_phy *phy,
11292                               u8 phy_index)
11293 {
11294         struct bnx2x *bp = params->bp;
11295         u32 link_config;
11296         /* Populate the default phy configuration for MF mode */
11297         if (phy_index == EXT_PHY2) {
11298                 link_config = REG_RD(bp, params->shmem_base +
11299                                      offsetof(struct shmem_region, dev_info.
11300                         port_feature_config[params->port].link_config2));
11301                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
11302                                              offsetof(struct shmem_region,
11303                                                       dev_info.
11304                         port_hw_config[params->port].speed_capability_mask2));
11305         } else {
11306                 link_config = REG_RD(bp, params->shmem_base +
11307                                      offsetof(struct shmem_region, dev_info.
11308                                 port_feature_config[params->port].link_config));
11309                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
11310                                              offsetof(struct shmem_region,
11311                                                       dev_info.
11312                         port_hw_config[params->port].speed_capability_mask));
11313         }
11314         DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
11315                        " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
11316
11317         phy->req_duplex = DUPLEX_FULL;
11318         switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
11319         case PORT_FEATURE_LINK_SPEED_10M_HALF:
11320                 phy->req_duplex = DUPLEX_HALF;
11321         case PORT_FEATURE_LINK_SPEED_10M_FULL:
11322                 phy->req_line_speed = SPEED_10;
11323                 break;
11324         case PORT_FEATURE_LINK_SPEED_100M_HALF:
11325                 phy->req_duplex = DUPLEX_HALF;
11326         case PORT_FEATURE_LINK_SPEED_100M_FULL:
11327                 phy->req_line_speed = SPEED_100;
11328                 break;
11329         case PORT_FEATURE_LINK_SPEED_1G:
11330                 phy->req_line_speed = SPEED_1000;
11331                 break;
11332         case PORT_FEATURE_LINK_SPEED_2_5G:
11333                 phy->req_line_speed = SPEED_2500;
11334                 break;
11335         case PORT_FEATURE_LINK_SPEED_10G_CX4:
11336                 phy->req_line_speed = SPEED_10000;
11337                 break;
11338         default:
11339                 phy->req_line_speed = SPEED_AUTO_NEG;
11340                 break;
11341         }
11342
11343         switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
11344         case PORT_FEATURE_FLOW_CONTROL_AUTO:
11345                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
11346                 break;
11347         case PORT_FEATURE_FLOW_CONTROL_TX:
11348                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
11349                 break;
11350         case PORT_FEATURE_FLOW_CONTROL_RX:
11351                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
11352                 break;
11353         case PORT_FEATURE_FLOW_CONTROL_BOTH:
11354                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
11355                 break;
11356         default:
11357                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11358                 break;
11359         }
11360 }
11361
11362 u32 bnx2x_phy_selection(struct link_params *params)
11363 {
11364         u32 phy_config_swapped, prio_cfg;
11365         u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
11366
11367         phy_config_swapped = params->multi_phy_config &
11368                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11369
11370         prio_cfg = params->multi_phy_config &
11371                         PORT_HW_CFG_PHY_SELECTION_MASK;
11372
11373         if (phy_config_swapped) {
11374                 switch (prio_cfg) {
11375                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
11376                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
11377                      break;
11378                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
11379                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
11380                      break;
11381                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
11382                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
11383                      break;
11384                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
11385                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
11386                      break;
11387                 }
11388         } else
11389                 return_cfg = prio_cfg;
11390
11391         return return_cfg;
11392 }
11393
11394
11395 int bnx2x_phy_probe(struct link_params *params)
11396 {
11397         u8 phy_index, actual_phy_idx, link_cfg_idx;
11398         u32 phy_config_swapped, sync_offset, media_types;
11399         struct bnx2x *bp = params->bp;
11400         struct bnx2x_phy *phy;
11401         params->num_phys = 0;
11402         DP(NETIF_MSG_LINK, "Begin phy probe\n");
11403         phy_config_swapped = params->multi_phy_config &
11404                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11405
11406         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
11407               phy_index++) {
11408                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
11409                 actual_phy_idx = phy_index;
11410                 if (phy_config_swapped) {
11411                         if (phy_index == EXT_PHY1)
11412                                 actual_phy_idx = EXT_PHY2;
11413                         else if (phy_index == EXT_PHY2)
11414                                 actual_phy_idx = EXT_PHY1;
11415                 }
11416                 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
11417                                " actual_phy_idx %x\n", phy_config_swapped,
11418                            phy_index, actual_phy_idx);
11419                 phy = &params->phy[actual_phy_idx];
11420                 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
11421                                        params->shmem2_base, params->port,
11422                                        phy) != 0) {
11423                         params->num_phys = 0;
11424                         DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
11425                                    phy_index);
11426                         for (phy_index = INT_PHY;
11427                               phy_index < MAX_PHYS;
11428                               phy_index++)
11429                                 *phy = phy_null;
11430                         return -EINVAL;
11431                 }
11432                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
11433                         break;
11434
11435                 sync_offset = params->shmem_base +
11436                         offsetof(struct shmem_region,
11437                         dev_info.port_hw_config[params->port].media_type);
11438                 media_types = REG_RD(bp, sync_offset);
11439
11440                 /*
11441                  * Update media type for non-PMF sync only for the first time
11442                  * In case the media type changes afterwards, it will be updated
11443                  * using the update_status function
11444                  */
11445                 if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
11446                                     (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
11447                                      actual_phy_idx))) == 0) {
11448                         media_types |= ((phy->media_type &
11449                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
11450                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
11451                                  actual_phy_idx));
11452                 }
11453                 REG_WR(bp, sync_offset, media_types);
11454
11455                 bnx2x_phy_def_cfg(params, phy, phy_index);
11456                 params->num_phys++;
11457         }
11458
11459         DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
11460         return 0;
11461 }
11462
11463 void bnx2x_init_bmac_loopback(struct link_params *params,
11464                               struct link_vars *vars)
11465 {
11466         struct bnx2x *bp = params->bp;
11467                 vars->link_up = 1;
11468                 vars->line_speed = SPEED_10000;
11469                 vars->duplex = DUPLEX_FULL;
11470                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11471                 vars->mac_type = MAC_TYPE_BMAC;
11472
11473                 vars->phy_flags = PHY_XGXS_FLAG;
11474
11475                 bnx2x_xgxs_deassert(params);
11476
11477                 /* set bmac loopback */
11478                 bnx2x_bmac_enable(params, vars, 1);
11479
11480                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11481 }
11482
11483 void bnx2x_init_emac_loopback(struct link_params *params,
11484                               struct link_vars *vars)
11485 {
11486         struct bnx2x *bp = params->bp;
11487                 vars->link_up = 1;
11488                 vars->line_speed = SPEED_1000;
11489                 vars->duplex = DUPLEX_FULL;
11490                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11491                 vars->mac_type = MAC_TYPE_EMAC;
11492
11493                 vars->phy_flags = PHY_XGXS_FLAG;
11494
11495                 bnx2x_xgxs_deassert(params);
11496                 /* set bmac loopback */
11497                 bnx2x_emac_enable(params, vars, 1);
11498                 bnx2x_emac_program(params, vars);
11499                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11500 }
11501
11502 void bnx2x_init_xmac_loopback(struct link_params *params,
11503                               struct link_vars *vars)
11504 {
11505         struct bnx2x *bp = params->bp;
11506         vars->link_up = 1;
11507         if (!params->req_line_speed[0])
11508                 vars->line_speed = SPEED_10000;
11509         else
11510                 vars->line_speed = params->req_line_speed[0];
11511         vars->duplex = DUPLEX_FULL;
11512         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11513         vars->mac_type = MAC_TYPE_XMAC;
11514         vars->phy_flags = PHY_XGXS_FLAG;
11515         /*
11516          * Set WC to loopback mode since link is required to provide clock
11517          * to the XMAC in 20G mode
11518          */
11519         if (vars->line_speed == SPEED_20000) {
11520                 bnx2x_set_aer_mmd(params, &params->phy[0]);
11521                 bnx2x_warpcore_reset_lane(bp, &params->phy[0], 0);
11522                 params->phy[INT_PHY].config_loopback(
11523                         &params->phy[INT_PHY],
11524                         params);
11525         }
11526         bnx2x_xmac_enable(params, vars, 1);
11527         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11528 }
11529
11530 void bnx2x_init_umac_loopback(struct link_params *params,
11531                               struct link_vars *vars)
11532 {
11533         struct bnx2x *bp = params->bp;
11534         vars->link_up = 1;
11535         vars->line_speed = SPEED_1000;
11536         vars->duplex = DUPLEX_FULL;
11537         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11538         vars->mac_type = MAC_TYPE_UMAC;
11539         vars->phy_flags = PHY_XGXS_FLAG;
11540         bnx2x_umac_enable(params, vars, 1);
11541
11542         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11543 }
11544
11545 void bnx2x_init_xgxs_loopback(struct link_params *params,
11546                               struct link_vars *vars)
11547 {
11548         struct bnx2x *bp = params->bp;
11549                 vars->link_up = 1;
11550                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11551                 vars->duplex = DUPLEX_FULL;
11552         if (params->req_line_speed[0] == SPEED_1000)
11553                         vars->line_speed = SPEED_1000;
11554         else
11555                         vars->line_speed = SPEED_10000;
11556
11557         if (!USES_WARPCORE(bp))
11558                 bnx2x_xgxs_deassert(params);
11559         bnx2x_link_initialize(params, vars);
11560
11561         if (params->req_line_speed[0] == SPEED_1000) {
11562                 if (USES_WARPCORE(bp))
11563                         bnx2x_umac_enable(params, vars, 0);
11564                 else {
11565                         bnx2x_emac_program(params, vars);
11566                         bnx2x_emac_enable(params, vars, 0);
11567                 }
11568         } else {
11569                 if (USES_WARPCORE(bp))
11570                         bnx2x_xmac_enable(params, vars, 0);
11571                 else
11572                         bnx2x_bmac_enable(params, vars, 0);
11573         }
11574
11575                 if (params->loopback_mode == LOOPBACK_XGXS) {
11576                         /* set 10G XGXS loopback */
11577                         params->phy[INT_PHY].config_loopback(
11578                                 &params->phy[INT_PHY],
11579                                 params);
11580
11581                 } else {
11582                         /* set external phy loopback */
11583                         u8 phy_index;
11584                         for (phy_index = EXT_PHY1;
11585                               phy_index < params->num_phys; phy_index++) {
11586                                 if (params->phy[phy_index].config_loopback)
11587                                         params->phy[phy_index].config_loopback(
11588                                                 &params->phy[phy_index],
11589                                                 params);
11590                         }
11591                 }
11592                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11593
11594         bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
11595 }
11596
11597 int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
11598 {
11599         struct bnx2x *bp = params->bp;
11600         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
11601         DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
11602                    params->req_line_speed[0], params->req_flow_ctrl[0]);
11603         DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
11604                    params->req_line_speed[1], params->req_flow_ctrl[1]);
11605         vars->link_status = 0;
11606         vars->phy_link_up = 0;
11607         vars->link_up = 0;
11608         vars->line_speed = 0;
11609         vars->duplex = DUPLEX_FULL;
11610         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11611         vars->mac_type = MAC_TYPE_NONE;
11612         vars->phy_flags = 0;
11613
11614         /* disable attentions */
11615         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
11616                        (NIG_MASK_XGXS0_LINK_STATUS |
11617                         NIG_MASK_XGXS0_LINK10G |
11618                         NIG_MASK_SERDES0_LINK_STATUS |
11619                         NIG_MASK_MI_INT));
11620
11621         bnx2x_emac_init(params, vars);
11622
11623         if (params->num_phys == 0) {
11624                 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
11625                 return -EINVAL;
11626         }
11627         set_phy_vars(params, vars);
11628
11629         DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
11630         switch (params->loopback_mode) {
11631         case LOOPBACK_BMAC:
11632                 bnx2x_init_bmac_loopback(params, vars);
11633                 break;
11634         case LOOPBACK_EMAC:
11635                 bnx2x_init_emac_loopback(params, vars);
11636                 break;
11637         case LOOPBACK_XMAC:
11638                 bnx2x_init_xmac_loopback(params, vars);
11639                 break;
11640         case LOOPBACK_UMAC:
11641                 bnx2x_init_umac_loopback(params, vars);
11642                 break;
11643         case LOOPBACK_XGXS:
11644         case LOOPBACK_EXT_PHY:
11645                 bnx2x_init_xgxs_loopback(params, vars);
11646                 break;
11647         default:
11648                 if (!CHIP_IS_E3(bp)) {
11649                         if (params->switch_cfg == SWITCH_CFG_10G)
11650                                 bnx2x_xgxs_deassert(params);
11651                         else
11652                                 bnx2x_serdes_deassert(bp, params->port);
11653                 }
11654                 bnx2x_link_initialize(params, vars);
11655                 msleep(30);
11656                 bnx2x_link_int_enable(params);
11657                 break;
11658         }
11659         return 0;
11660 }
11661
11662 int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
11663                      u8 reset_ext_phy)
11664 {
11665         struct bnx2x *bp = params->bp;
11666         u8 phy_index, port = params->port, clear_latch_ind = 0;
11667         DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
11668         /* disable attentions */
11669         vars->link_status = 0;
11670         bnx2x_update_mng(params, vars->link_status);
11671         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
11672                        (NIG_MASK_XGXS0_LINK_STATUS |
11673                         NIG_MASK_XGXS0_LINK10G |
11674                         NIG_MASK_SERDES0_LINK_STATUS |
11675                         NIG_MASK_MI_INT));
11676
11677         /* activate nig drain */
11678         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
11679
11680         /* disable nig egress interface */
11681         if (!CHIP_IS_E3(bp)) {
11682                 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
11683                 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
11684         }
11685
11686         /* Stop BigMac rx */
11687         if (!CHIP_IS_E3(bp))
11688                 bnx2x_bmac_rx_disable(bp, port);
11689         else
11690                 bnx2x_xmac_disable(params);
11691         /* disable emac */
11692         if (!CHIP_IS_E3(bp))
11693                 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
11694
11695         msleep(10);
11696         /* The PHY reset is controlled by GPIO 1
11697          * Hold it as vars low
11698          */
11699          /* clear link led */
11700         bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
11701
11702         if (reset_ext_phy) {
11703                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
11704                       phy_index++) {
11705                         if (params->phy[phy_index].link_reset)
11706                                 params->phy[phy_index].link_reset(
11707                                         &params->phy[phy_index],
11708                                         params);
11709                         if (params->phy[phy_index].flags &
11710                             FLAGS_REARM_LATCH_SIGNAL)
11711                                 clear_latch_ind = 1;
11712                 }
11713         }
11714
11715         if (clear_latch_ind) {
11716                 /* Clear latching indication */
11717                 bnx2x_rearm_latch_signal(bp, port, 0);
11718                 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
11719                                1 << NIG_LATCH_BC_ENABLE_MI_INT);
11720         }
11721         if (params->phy[INT_PHY].link_reset)
11722                 params->phy[INT_PHY].link_reset(
11723                         &params->phy[INT_PHY], params);
11724         /* reset BigMac */
11725         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
11726                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
11727
11728         /* disable nig ingress interface */
11729         if (!CHIP_IS_E3(bp)) {
11730                 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
11731                 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
11732         }
11733         vars->link_up = 0;
11734         vars->phy_flags = 0;
11735         return 0;
11736 }
11737
11738 /****************************************************************************/
11739 /*                              Common function                             */
11740 /****************************************************************************/
11741 static int bnx2x_8073_common_init_phy(struct bnx2x *bp,
11742                                       u32 shmem_base_path[],
11743                                       u32 shmem2_base_path[], u8 phy_index,
11744                                       u32 chip_id)
11745 {
11746         struct bnx2x_phy phy[PORT_MAX];
11747         struct bnx2x_phy *phy_blk[PORT_MAX];
11748         u16 val;
11749         s8 port = 0;
11750         s8 port_of_path = 0;
11751         u32 swap_val, swap_override;
11752         swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
11753         swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
11754         port ^= (swap_val && swap_override);
11755         bnx2x_ext_phy_hw_reset(bp, port);
11756         /* PART1 - Reset both phys */
11757         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11758                 u32 shmem_base, shmem2_base;
11759                 /* In E2, same phy is using for port0 of the two paths */
11760                 if (CHIP_IS_E1x(bp)) {
11761                         shmem_base = shmem_base_path[0];
11762                         shmem2_base = shmem2_base_path[0];
11763                         port_of_path = port;
11764                 } else {
11765                         shmem_base = shmem_base_path[port];
11766                         shmem2_base = shmem2_base_path[port];
11767                         port_of_path = 0;
11768                 }
11769
11770                 /* Extract the ext phy address for the port */
11771                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
11772                                        port_of_path, &phy[port]) !=
11773                     0) {
11774                         DP(NETIF_MSG_LINK, "populate_phy failed\n");
11775                         return -EINVAL;
11776                 }
11777                 /* disable attentions */
11778                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
11779                                port_of_path*4,
11780                                (NIG_MASK_XGXS0_LINK_STATUS |
11781                                 NIG_MASK_XGXS0_LINK10G |
11782                                 NIG_MASK_SERDES0_LINK_STATUS |
11783                                 NIG_MASK_MI_INT));
11784
11785                 /* Need to take the phy out of low power mode in order
11786                         to write to access its registers */
11787                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
11788                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
11789                                port);
11790
11791                 /* Reset the phy */
11792                 bnx2x_cl45_write(bp, &phy[port],
11793                                  MDIO_PMA_DEVAD,
11794                                  MDIO_PMA_REG_CTRL,
11795                                  1<<15);
11796         }
11797
11798         /* Add delay of 150ms after reset */
11799         msleep(150);
11800
11801         if (phy[PORT_0].addr & 0x1) {
11802                 phy_blk[PORT_0] = &(phy[PORT_1]);
11803                 phy_blk[PORT_1] = &(phy[PORT_0]);
11804         } else {
11805                 phy_blk[PORT_0] = &(phy[PORT_0]);
11806                 phy_blk[PORT_1] = &(phy[PORT_1]);
11807         }
11808
11809         /* PART2 - Download firmware to both phys */
11810         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11811                 if (CHIP_IS_E1x(bp))
11812                         port_of_path = port;
11813                 else
11814                         port_of_path = 0;
11815
11816                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
11817                            phy_blk[port]->addr);
11818                 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
11819                                                       port_of_path))
11820                         return -EINVAL;
11821
11822                 /* Only set bit 10 = 1 (Tx power down) */
11823                 bnx2x_cl45_read(bp, phy_blk[port],
11824                                 MDIO_PMA_DEVAD,
11825                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
11826
11827                 /* Phase1 of TX_POWER_DOWN reset */
11828                 bnx2x_cl45_write(bp, phy_blk[port],
11829                                  MDIO_PMA_DEVAD,
11830                                  MDIO_PMA_REG_TX_POWER_DOWN,
11831                                  (val | 1<<10));
11832         }
11833
11834         /*
11835          * Toggle Transmitter: Power down and then up with 600ms delay
11836          * between
11837          */
11838         msleep(600);
11839
11840         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
11841         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11842                 /* Phase2 of POWER_DOWN_RESET */
11843                 /* Release bit 10 (Release Tx power down) */
11844                 bnx2x_cl45_read(bp, phy_blk[port],
11845                                 MDIO_PMA_DEVAD,
11846                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
11847
11848                 bnx2x_cl45_write(bp, phy_blk[port],
11849                                 MDIO_PMA_DEVAD,
11850                                 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
11851                 msleep(15);
11852
11853                 /* Read modify write the SPI-ROM version select register */
11854                 bnx2x_cl45_read(bp, phy_blk[port],
11855                                 MDIO_PMA_DEVAD,
11856                                 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
11857                 bnx2x_cl45_write(bp, phy_blk[port],
11858                                  MDIO_PMA_DEVAD,
11859                                  MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
11860
11861                 /* set GPIO2 back to LOW */
11862                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
11863                                MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
11864         }
11865         return 0;
11866 }
11867 static int bnx2x_8726_common_init_phy(struct bnx2x *bp,
11868                                       u32 shmem_base_path[],
11869                                       u32 shmem2_base_path[], u8 phy_index,
11870                                       u32 chip_id)
11871 {
11872         u32 val;
11873         s8 port;
11874         struct bnx2x_phy phy;
11875         /* Use port1 because of the static port-swap */
11876         /* Enable the module detection interrupt */
11877         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
11878         val |= ((1<<MISC_REGISTERS_GPIO_3)|
11879                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
11880         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
11881
11882         bnx2x_ext_phy_hw_reset(bp, 0);
11883         msleep(5);
11884         for (port = 0; port < PORT_MAX; port++) {
11885                 u32 shmem_base, shmem2_base;
11886
11887                 /* In E2, same phy is using for port0 of the two paths */
11888                 if (CHIP_IS_E1x(bp)) {
11889                         shmem_base = shmem_base_path[0];
11890                         shmem2_base = shmem2_base_path[0];
11891                 } else {
11892                         shmem_base = shmem_base_path[port];
11893                         shmem2_base = shmem2_base_path[port];
11894                 }
11895                 /* Extract the ext phy address for the port */
11896                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
11897                                        port, &phy) !=
11898                     0) {
11899                         DP(NETIF_MSG_LINK, "populate phy failed\n");
11900                         return -EINVAL;
11901                 }
11902
11903                 /* Reset phy*/
11904                 bnx2x_cl45_write(bp, &phy,
11905                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
11906
11907
11908                 /* Set fault module detected LED on */
11909                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
11910                                MISC_REGISTERS_GPIO_HIGH,
11911                                port);
11912         }
11913
11914         return 0;
11915 }
11916 static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
11917                                          u8 *io_gpio, u8 *io_port)
11918 {
11919
11920         u32 phy_gpio_reset = REG_RD(bp, shmem_base +
11921                                           offsetof(struct shmem_region,
11922                                 dev_info.port_hw_config[PORT_0].default_cfg));
11923         switch (phy_gpio_reset) {
11924         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
11925                 *io_gpio = 0;
11926                 *io_port = 0;
11927                 break;
11928         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
11929                 *io_gpio = 1;
11930                 *io_port = 0;
11931                 break;
11932         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
11933                 *io_gpio = 2;
11934                 *io_port = 0;
11935                 break;
11936         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
11937                 *io_gpio = 3;
11938                 *io_port = 0;
11939                 break;
11940         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
11941                 *io_gpio = 0;
11942                 *io_port = 1;
11943                 break;
11944         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
11945                 *io_gpio = 1;
11946                 *io_port = 1;
11947                 break;
11948         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
11949                 *io_gpio = 2;
11950                 *io_port = 1;
11951                 break;
11952         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
11953                 *io_gpio = 3;
11954                 *io_port = 1;
11955                 break;
11956         default:
11957                 /* Don't override the io_gpio and io_port */
11958                 break;
11959         }
11960 }
11961
11962 static int bnx2x_8727_common_init_phy(struct bnx2x *bp,
11963                                       u32 shmem_base_path[],
11964                                       u32 shmem2_base_path[], u8 phy_index,
11965                                       u32 chip_id)
11966 {
11967         s8 port, reset_gpio;
11968         u32 swap_val, swap_override;
11969         struct bnx2x_phy phy[PORT_MAX];
11970         struct bnx2x_phy *phy_blk[PORT_MAX];
11971         s8 port_of_path;
11972         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
11973         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
11974
11975         reset_gpio = MISC_REGISTERS_GPIO_1;
11976         port = 1;
11977
11978         /*
11979          * Retrieve the reset gpio/port which control the reset.
11980          * Default is GPIO1, PORT1
11981          */
11982         bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
11983                                      (u8 *)&reset_gpio, (u8 *)&port);
11984
11985         /* Calculate the port based on port swap */
11986         port ^= (swap_val && swap_override);
11987
11988         /* Initiate PHY reset*/
11989         bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
11990                        port);
11991         msleep(1);
11992         bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
11993                        port);
11994
11995         msleep(5);
11996
11997         /* PART1 - Reset both phys */
11998         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11999                 u32 shmem_base, shmem2_base;
12000
12001                 /* In E2, same phy is using for port0 of the two paths */
12002                 if (CHIP_IS_E1x(bp)) {
12003                         shmem_base = shmem_base_path[0];
12004                         shmem2_base = shmem2_base_path[0];
12005                         port_of_path = port;
12006                 } else {
12007                         shmem_base = shmem_base_path[port];
12008                         shmem2_base = shmem2_base_path[port];
12009                         port_of_path = 0;
12010                 }
12011
12012                 /* Extract the ext phy address for the port */
12013                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12014                                        port_of_path, &phy[port]) !=
12015                                        0) {
12016                         DP(NETIF_MSG_LINK, "populate phy failed\n");
12017                         return -EINVAL;
12018                 }
12019                 /* disable attentions */
12020                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
12021                                port_of_path*4,
12022                                (NIG_MASK_XGXS0_LINK_STATUS |
12023                                 NIG_MASK_XGXS0_LINK10G |
12024                                 NIG_MASK_SERDES0_LINK_STATUS |
12025                                 NIG_MASK_MI_INT));
12026
12027
12028                 /* Reset the phy */
12029                 bnx2x_cl45_write(bp, &phy[port],
12030                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
12031         }
12032
12033         /* Add delay of 150ms after reset */
12034         msleep(150);
12035         if (phy[PORT_0].addr & 0x1) {
12036                 phy_blk[PORT_0] = &(phy[PORT_1]);
12037                 phy_blk[PORT_1] = &(phy[PORT_0]);
12038         } else {
12039                 phy_blk[PORT_0] = &(phy[PORT_0]);
12040                 phy_blk[PORT_1] = &(phy[PORT_1]);
12041         }
12042         /* PART2 - Download firmware to both phys */
12043         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12044                 if (CHIP_IS_E1x(bp))
12045                         port_of_path = port;
12046                 else
12047                         port_of_path = 0;
12048                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
12049                            phy_blk[port]->addr);
12050                 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
12051                                                       port_of_path))
12052                         return -EINVAL;
12053                 /* Disable PHY transmitter output */
12054                 bnx2x_cl45_write(bp, phy_blk[port],
12055                                  MDIO_PMA_DEVAD,
12056                                  MDIO_PMA_REG_TX_DISABLE, 1);
12057
12058         }
12059         return 0;
12060 }
12061
12062 static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
12063                                      u32 shmem2_base_path[], u8 phy_index,
12064                                      u32 ext_phy_type, u32 chip_id)
12065 {
12066         int rc = 0;
12067
12068         switch (ext_phy_type) {
12069         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
12070                 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
12071                                                 shmem2_base_path,
12072                                                 phy_index, chip_id);
12073                 break;
12074         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
12075         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
12076         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
12077                 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
12078                                                 shmem2_base_path,
12079                                                 phy_index, chip_id);
12080                 break;
12081
12082         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
12083                 /*
12084                  * GPIO1 affects both ports, so there's need to pull
12085                  * it for single port alone
12086                  */
12087                 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
12088                                                 shmem2_base_path,
12089                                                 phy_index, chip_id);
12090                 break;
12091         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
12092                 /*
12093                  * GPIO3's are linked, and so both need to be toggled
12094                  * to obtain required 2us pulse.
12095                  */
12096                 rc = bnx2x_84833_common_init_phy(bp, shmem_base_path, chip_id);
12097                 break;
12098         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
12099                 rc = -EINVAL;
12100                 break;
12101         default:
12102                 DP(NETIF_MSG_LINK,
12103                            "ext_phy 0x%x common init not required\n",
12104                            ext_phy_type);
12105                 break;
12106         }
12107
12108         if (rc != 0)
12109                 netdev_err(bp->dev,  "Warning: PHY was not initialized,"
12110                                       " Port %d\n",
12111                          0);
12112         return rc;
12113 }
12114
12115 int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
12116                           u32 shmem2_base_path[], u32 chip_id)
12117 {
12118         int rc = 0;
12119         u32 phy_ver, val;
12120         u8 phy_index = 0;
12121         u32 ext_phy_type, ext_phy_config;
12122         bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
12123         bnx2x_set_mdio_clk(bp, chip_id, PORT_1);
12124         DP(NETIF_MSG_LINK, "Begin common phy init\n");
12125         if (CHIP_IS_E3(bp)) {
12126                 /* Enable EPIO */
12127                 val = REG_RD(bp, MISC_REG_GEN_PURP_HWG);
12128                 REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1);
12129         }
12130         /* Check if common init was already done */
12131         phy_ver = REG_RD(bp, shmem_base_path[0] +
12132                          offsetof(struct shmem_region,
12133                                   port_mb[PORT_0].ext_phy_fw_version));
12134         if (phy_ver) {
12135                 DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
12136                                phy_ver);
12137                 return 0;
12138         }
12139
12140         /* Read the ext_phy_type for arbitrary port(0) */
12141         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12142               phy_index++) {
12143                 ext_phy_config = bnx2x_get_ext_phy_config(bp,
12144                                                           shmem_base_path[0],
12145                                                           phy_index, 0);
12146                 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
12147                 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
12148                                                 shmem2_base_path,
12149                                                 phy_index, ext_phy_type,
12150                                                 chip_id);
12151         }
12152         return rc;
12153 }
12154
12155 static void bnx2x_check_over_curr(struct link_params *params,
12156                                   struct link_vars *vars)
12157 {
12158         struct bnx2x *bp = params->bp;
12159         u32 cfg_pin;
12160         u8 port = params->port;
12161         u32 pin_val;
12162
12163         cfg_pin = (REG_RD(bp, params->shmem_base +
12164                           offsetof(struct shmem_region,
12165                                dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
12166                    PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
12167                 PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
12168
12169         /* Ignore check if no external input PIN available */
12170         if (bnx2x_get_cfg_pin(bp, cfg_pin, &pin_val) != 0)
12171                 return;
12172
12173         if (!pin_val) {
12174                 if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
12175                         netdev_err(bp->dev, "Error:  Power fault on Port %d has"
12176                                             " been detected and the power to "
12177                                             "that SFP+ module has been removed"
12178                                             " to prevent failure of the card."
12179                                             " Please remove the SFP+ module and"
12180                                             " restart the system to clear this"
12181                                             " error.\n",
12182                          params->port);
12183                         vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
12184                 }
12185         } else
12186                 vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
12187 }
12188
12189 static void bnx2x_analyze_link_error(struct link_params *params,
12190                                      struct link_vars *vars, u32 lss_status)
12191 {
12192         struct bnx2x *bp = params->bp;
12193         /* Compare new value with previous value */
12194         u8 led_mode;
12195         u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0;
12196
12197         /*DP(NETIF_MSG_LINK, "CHECK LINK: %x half_open:%x-> lss:%x\n",
12198                        vars->link_up,
12199                        half_open_conn, lss_status);*/
12200
12201         if ((lss_status ^ half_open_conn) == 0)
12202                 return;
12203
12204         /* If values differ */
12205         DP(NETIF_MSG_LINK, "Link changed:%x %x->%x\n", vars->link_up,
12206                        half_open_conn, lss_status);
12207
12208         /*
12209          * a. Update shmem->link_status accordingly
12210          * b. Update link_vars->link_up
12211          */
12212         if (lss_status) {
12213                 vars->link_status &= ~LINK_STATUS_LINK_UP;
12214                 vars->link_up = 0;
12215                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
12216                 /*
12217                  * Set LED mode to off since the PHY doesn't know about these
12218                  * errors
12219                  */
12220                 led_mode = LED_MODE_OFF;
12221         } else {
12222                 vars->link_status |= LINK_STATUS_LINK_UP;
12223                 vars->link_up = 1;
12224                 vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
12225                 led_mode = LED_MODE_OPER;
12226         }
12227         /* Update the LED according to the link state */
12228         bnx2x_set_led(params, vars, led_mode, SPEED_10000);
12229
12230         /* Update link status in the shared memory */
12231         bnx2x_update_mng(params, vars->link_status);
12232
12233         /* C. Trigger General Attention */
12234         vars->periodic_flags |= PERIODIC_FLAGS_LINK_EVENT;
12235         bnx2x_notify_link_changed(bp);
12236 }
12237
12238 static void bnx2x_check_half_open_conn(struct link_params *params,
12239                                        struct link_vars *vars)
12240 {
12241         struct bnx2x *bp = params->bp;
12242         u32 lss_status = 0;
12243         u32 mac_base;
12244         /* In case link status is physically up @ 10G do */
12245         if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
12246                 return;
12247
12248         if (!CHIP_IS_E3(bp) &&
12249             (REG_RD(bp, MISC_REG_RESET_REG_2) &
12250                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))) {
12251                 /* Check E1X / E2 BMAC */
12252                 u32 lss_status_reg;
12253                 u32 wb_data[2];
12254                 mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
12255                         NIG_REG_INGRESS_BMAC0_MEM;
12256                 /*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
12257                 if (CHIP_IS_E2(bp))
12258                         lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
12259                 else
12260                         lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
12261
12262                 REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2);
12263                 lss_status = (wb_data[0] > 0);
12264
12265                 bnx2x_analyze_link_error(params, vars, lss_status);
12266         }
12267 }
12268
12269 void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
12270 {
12271         struct bnx2x *bp = params->bp;
12272         if (!params) {
12273                 DP(NETIF_MSG_LINK, "Ininitliazed params !\n");
12274                 return;
12275         }
12276         /* DP(NETIF_MSG_LINK, "Periodic called vars->phy_flags 0x%x speed 0x%x
12277          RESET_REG_2 0x%x\n", vars->phy_flags, vars->line_speed,
12278           REG_RD(bp, MISC_REG_RESET_REG_2)); */
12279         bnx2x_check_half_open_conn(params, vars);
12280         if (CHIP_IS_E3(bp))
12281                 bnx2x_check_over_curr(params, vars);
12282 }
12283
12284 u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
12285 {
12286         u8 phy_index;
12287         struct bnx2x_phy phy;
12288         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
12289               phy_index++) {
12290                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12291                                        0, &phy) != 0) {
12292                         DP(NETIF_MSG_LINK, "populate phy failed\n");
12293                         return 0;
12294                 }
12295
12296                 if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
12297                         return 1;
12298         }
12299         return 0;
12300 }
12301
12302 u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
12303                              u32 shmem_base,
12304                              u32 shmem2_base,
12305                              u8 port)
12306 {
12307         u8 phy_index, fan_failure_det_req = 0;
12308         struct bnx2x_phy phy;
12309         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12310               phy_index++) {
12311                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12312                                        port, &phy)
12313                     != 0) {
12314                         DP(NETIF_MSG_LINK, "populate phy failed\n");
12315                         return 0;
12316                 }
12317                 fan_failure_det_req |= (phy.flags &
12318                                         FLAGS_FAN_FAILURE_DET_REQ);
12319         }
12320         return fan_failure_det_req;
12321 }
12322
12323 void bnx2x_hw_reset_phy(struct link_params *params)
12324 {
12325         u8 phy_index;
12326         struct bnx2x *bp = params->bp;
12327         bnx2x_update_mng(params, 0);
12328         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
12329                        (NIG_MASK_XGXS0_LINK_STATUS |
12330                         NIG_MASK_XGXS0_LINK10G |
12331                         NIG_MASK_SERDES0_LINK_STATUS |
12332                         NIG_MASK_MI_INT));
12333
12334         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
12335               phy_index++) {
12336                 if (params->phy[phy_index].hw_reset) {
12337                         params->phy[phy_index].hw_reset(
12338                                 &params->phy[phy_index],
12339                                 params);
12340                         params->phy[phy_index] = phy_null;
12341                 }
12342         }
12343 }
12344
12345 void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars,
12346                             u32 chip_id, u32 shmem_base, u32 shmem2_base,
12347                             u8 port)
12348 {
12349         u8 gpio_num = 0xff, gpio_port = 0xff, phy_index;
12350         u32 val;
12351         u32 offset, aeu_mask, swap_val, swap_override, sync_offset;
12352         if (CHIP_IS_E3(bp)) {
12353                 if (bnx2x_get_mod_abs_int_cfg(bp, chip_id,
12354                                               shmem_base,
12355                                               port,
12356                                               &gpio_num,
12357                                               &gpio_port) != 0)
12358                         return;
12359         } else {
12360                 struct bnx2x_phy phy;
12361                 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12362                       phy_index++) {
12363                         if (bnx2x_populate_phy(bp, phy_index, shmem_base,
12364                                                shmem2_base, port, &phy)
12365                             != 0) {
12366                                 DP(NETIF_MSG_LINK, "populate phy failed\n");
12367                                 return;
12368                         }
12369                         if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
12370                                 gpio_num = MISC_REGISTERS_GPIO_3;
12371                                 gpio_port = port;
12372                                 break;
12373                         }
12374                 }
12375         }
12376
12377         if (gpio_num == 0xff)
12378                 return;
12379
12380         /* Set GPIO3 to trigger SFP+ module insertion/removal */
12381         bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port);
12382
12383         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
12384         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
12385         gpio_port ^= (swap_val && swap_override);
12386
12387         vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
12388                 (gpio_num + (gpio_port << 2));
12389
12390         sync_offset = shmem_base +
12391                 offsetof(struct shmem_region,
12392                          dev_info.port_hw_config[port].aeu_int_mask);
12393         REG_WR(bp, sync_offset, vars->aeu_int_mask);
12394
12395         DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
12396                        gpio_num, gpio_port, vars->aeu_int_mask);
12397
12398         if (port == 0)
12399                 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
12400         else
12401                 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
12402
12403         /* Open appropriate AEU for interrupts */
12404         aeu_mask = REG_RD(bp, offset);
12405         aeu_mask |= vars->aeu_int_mask;
12406         REG_WR(bp, offset, aeu_mask);
12407
12408         /* Enable the GPIO to trigger interrupt */
12409         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
12410         val |= 1 << (gpio_num + (gpio_port << 2));
12411         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
12412 }