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