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