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