]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
bnx2x: Fix link down in 57712 following LFA
[karo-tx-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_specific_func(struct bnx2x_phy *phy,
3299                                      struct link_params *params,
3300                                      u32 action)
3301 {
3302         struct bnx2x *bp = params->bp;
3303         switch (action) {
3304         case PHY_INIT:
3305                 /* Set correct devad */
3306                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0);
3307                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
3308                        phy->def_md_devad);
3309                 break;
3310         }
3311 }
3312
3313 static void bnx2x_xgxs_deassert(struct link_params *params)
3314 {
3315         struct bnx2x *bp = params->bp;
3316         u8 port;
3317         u32 val;
3318         DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
3319         port = params->port;
3320
3321         val = XGXS_RESET_BITS << (port*16);
3322
3323         /* Reset and unreset the SerDes/XGXS */
3324         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3325         udelay(500);
3326         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3327         bnx2x_xgxs_specific_func(&params->phy[INT_PHY], params,
3328                                  PHY_INIT);
3329 }
3330
3331 static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
3332                                      struct link_params *params, u16 *ieee_fc)
3333 {
3334         struct bnx2x *bp = params->bp;
3335         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
3336         /* Resolve pause mode and advertisement Please refer to Table
3337          * 28B-3 of the 802.3ab-1999 spec
3338          */
3339
3340         switch (phy->req_flow_ctrl) {
3341         case BNX2X_FLOW_CTRL_AUTO:
3342                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
3343                         *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3344                 else
3345                         *ieee_fc |=
3346                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3347                 break;
3348
3349         case BNX2X_FLOW_CTRL_TX:
3350                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3351                 break;
3352
3353         case BNX2X_FLOW_CTRL_RX:
3354         case BNX2X_FLOW_CTRL_BOTH:
3355                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3356                 break;
3357
3358         case BNX2X_FLOW_CTRL_NONE:
3359         default:
3360                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3361                 break;
3362         }
3363         DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
3364 }
3365
3366 static void set_phy_vars(struct link_params *params,
3367                          struct link_vars *vars)
3368 {
3369         struct bnx2x *bp = params->bp;
3370         u8 actual_phy_idx, phy_index, link_cfg_idx;
3371         u8 phy_config_swapped = params->multi_phy_config &
3372                         PORT_HW_CFG_PHY_SWAPPED_ENABLED;
3373         for (phy_index = INT_PHY; phy_index < params->num_phys;
3374               phy_index++) {
3375                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
3376                 actual_phy_idx = phy_index;
3377                 if (phy_config_swapped) {
3378                         if (phy_index == EXT_PHY1)
3379                                 actual_phy_idx = EXT_PHY2;
3380                         else if (phy_index == EXT_PHY2)
3381                                 actual_phy_idx = EXT_PHY1;
3382                 }
3383                 params->phy[actual_phy_idx].req_flow_ctrl =
3384                         params->req_flow_ctrl[link_cfg_idx];
3385
3386                 params->phy[actual_phy_idx].req_line_speed =
3387                         params->req_line_speed[link_cfg_idx];
3388
3389                 params->phy[actual_phy_idx].speed_cap_mask =
3390                         params->speed_cap_mask[link_cfg_idx];
3391
3392                 params->phy[actual_phy_idx].req_duplex =
3393                         params->req_duplex[link_cfg_idx];
3394
3395                 if (params->req_line_speed[link_cfg_idx] ==
3396                     SPEED_AUTO_NEG)
3397                         vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
3398
3399                 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
3400                            " speed_cap_mask %x\n",
3401                            params->phy[actual_phy_idx].req_flow_ctrl,
3402                            params->phy[actual_phy_idx].req_line_speed,
3403                            params->phy[actual_phy_idx].speed_cap_mask);
3404         }
3405 }
3406
3407 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3408                                     struct bnx2x_phy *phy,
3409                                     struct link_vars *vars)
3410 {
3411         u16 val;
3412         struct bnx2x *bp = params->bp;
3413         /* Read modify write pause advertizing */
3414         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3415
3416         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3417
3418         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3419         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3420         if ((vars->ieee_fc &
3421             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3422             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3423                 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3424         }
3425         if ((vars->ieee_fc &
3426             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3427             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3428                 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3429         }
3430         DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3431         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3432 }
3433
3434 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
3435 {                                               /*  LD      LP   */
3436         switch (pause_result) {                 /* ASYM P ASYM P */
3437         case 0xb:                               /*   1  0   1  1 */
3438                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
3439                 break;
3440
3441         case 0xe:                               /*   1  1   1  0 */
3442                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
3443                 break;
3444
3445         case 0x5:                               /*   0  1   0  1 */
3446         case 0x7:                               /*   0  1   1  1 */
3447         case 0xd:                               /*   1  1   0  1 */
3448         case 0xf:                               /*   1  1   1  1 */
3449                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
3450                 break;
3451
3452         default:
3453                 break;
3454         }
3455         if (pause_result & (1<<0))
3456                 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
3457         if (pause_result & (1<<1))
3458                 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
3459
3460 }
3461
3462 static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy,
3463                                         struct link_params *params,
3464                                         struct link_vars *vars)
3465 {
3466         u16 ld_pause;           /* local */
3467         u16 lp_pause;           /* link partner */
3468         u16 pause_result;
3469         struct bnx2x *bp = params->bp;
3470         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
3471                 bnx2x_cl22_read(bp, phy, 0x4, &ld_pause);
3472                 bnx2x_cl22_read(bp, phy, 0x5, &lp_pause);
3473         } else if (CHIP_IS_E3(bp) &&
3474                 SINGLE_MEDIA_DIRECT(params)) {
3475                 u8 lane = bnx2x_get_warpcore_lane(phy, params);
3476                 u16 gp_status, gp_mask;
3477                 bnx2x_cl45_read(bp, phy,
3478                                 MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
3479                                 &gp_status);
3480                 gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
3481                            MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
3482                         lane;
3483                 if ((gp_status & gp_mask) == gp_mask) {
3484                         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3485                                         MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3486                         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3487                                         MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3488                 } else {
3489                         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3490                                         MDIO_AN_REG_CL37_FC_LD, &ld_pause);
3491                         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3492                                         MDIO_AN_REG_CL37_FC_LP, &lp_pause);
3493                         ld_pause = ((ld_pause &
3494                                      MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
3495                                     << 3);
3496                         lp_pause = ((lp_pause &
3497                                      MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
3498                                     << 3);
3499                 }
3500         } else {
3501                 bnx2x_cl45_read(bp, phy,
3502                                 MDIO_AN_DEVAD,
3503                                 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3504                 bnx2x_cl45_read(bp, phy,
3505                                 MDIO_AN_DEVAD,
3506                                 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3507         }
3508         pause_result = (ld_pause &
3509                         MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3510         pause_result |= (lp_pause &
3511                          MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3512         DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", pause_result);
3513         bnx2x_pause_resolve(vars, pause_result);
3514
3515 }
3516
3517 static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3518                                    struct link_params *params,
3519                                    struct link_vars *vars)
3520 {
3521         u8 ret = 0;
3522         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3523         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) {
3524                 /* Update the advertised flow-controled of LD/LP in AN */
3525                 if (phy->req_line_speed == SPEED_AUTO_NEG)
3526                         bnx2x_ext_phy_update_adv_fc(phy, params, vars);
3527                 /* But set the flow-control result as the requested one */
3528                 vars->flow_ctrl = phy->req_flow_ctrl;
3529         } else if (phy->req_line_speed != SPEED_AUTO_NEG)
3530                 vars->flow_ctrl = params->req_fc_auto_adv;
3531         else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3532                 ret = 1;
3533                 bnx2x_ext_phy_update_adv_fc(phy, params, vars);
3534         }
3535         return ret;
3536 }
3537 /******************************************************************/
3538 /*                      Warpcore section                          */
3539 /******************************************************************/
3540 /* The init_internal_warpcore should mirror the xgxs,
3541  * i.e. reset the lane (if needed), set aer for the
3542  * init configuration, and set/clear SGMII flag. Internal
3543  * phy init is done purely in phy_init stage.
3544  */
3545
3546 static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy,
3547                                                struct link_params *params)
3548 {
3549         struct bnx2x *bp = params->bp;
3550
3551         DP(NETIF_MSG_LINK, "Configure WC for LPI pass through\n");
3552         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3553                          MDIO_WC_REG_EEE_COMBO_CONTROL0, 0x7c);
3554         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3555                                  MDIO_WC_REG_DIGITAL4_MISC5, 0xc000);
3556 }
3557
3558 static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
3559                                         struct link_params *params,
3560                                         struct link_vars *vars) {
3561         u16 val16 = 0, lane, i, cl72_ctrl;
3562         struct bnx2x *bp = params->bp;
3563         static struct bnx2x_reg_set reg_set[] = {
3564                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
3565                 {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0},
3566                 {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff},
3567                 {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555},
3568                 {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0},
3569                 {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415},
3570                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190},
3571                 /* Disable Autoneg: re-enable it after adv is done. */
3572                 {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0}
3573         };
3574         DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
3575         /* Set to default registers that may be overriden by 10G force */
3576         for (i = 0; i < sizeof(reg_set)/sizeof(struct bnx2x_reg_set); i++)
3577                 bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
3578                                  reg_set[i].val);
3579
3580         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3581                 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl);
3582         cl72_ctrl &= 0xf8ff;
3583         cl72_ctrl |= 0x3800;
3584         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3585                 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl);
3586
3587         /* Check adding advertisement for 1G KX */
3588         if (((vars->line_speed == SPEED_AUTO_NEG) &&
3589              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
3590             (vars->line_speed == SPEED_1000)) {
3591                 u32 addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2;
3592                 val16 |= (1<<5);
3593
3594                 /* Enable CL37 1G Parallel Detect */
3595                 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1);
3596                 DP(NETIF_MSG_LINK, "Advertize 1G\n");
3597         }
3598         if (((vars->line_speed == SPEED_AUTO_NEG) &&
3599              (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
3600             (vars->line_speed ==  SPEED_10000)) {
3601                 /* Check adding advertisement for 10G KR */
3602                 val16 |= (1<<7);
3603                 /* Enable 10G Parallel Detect */
3604                 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3605                                  MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
3606
3607                 DP(NETIF_MSG_LINK, "Advertize 10G\n");
3608         }
3609
3610         /* Set Transmit PMD settings */
3611         lane = bnx2x_get_warpcore_lane(phy, params);
3612         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3613                       MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3614                      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3615                       (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3616                       (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3617         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3618                          MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
3619                          0x03f0);
3620         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3621                          MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
3622                          0x03f0);
3623
3624         /* Advertised speeds */
3625         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3626                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
3627
3628         /* Advertised and set FEC (Forward Error Correction) */
3629         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3630                          MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
3631                          (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
3632                           MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
3633
3634         /* Enable CL37 BAM */
3635         if (REG_RD(bp, params->shmem_base +
3636                    offsetof(struct shmem_region, dev_info.
3637                             port_hw_config[params->port].default_cfg)) &
3638             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
3639                 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3640                                          MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL,
3641                                          1);
3642                 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
3643         }
3644
3645         /* Advertise pause */
3646         bnx2x_ext_phy_set_pause(params, phy, vars);
3647         /* Set KR Autoneg Work-Around flag for Warpcore version older than D108
3648          */
3649         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3650                         MDIO_WC_REG_UC_INFO_B1_VERSION, &val16);
3651         if (val16 < 0xd108) {
3652                 DP(NETIF_MSG_LINK, "Enable AN KR work-around\n");
3653                 vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
3654         }
3655         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3656                                  MDIO_WC_REG_DIGITAL5_MISC7, 0x100);
3657
3658         /* Over 1G - AN local device user page 1 */
3659         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3660                         MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
3661
3662         /* Enable Autoneg */
3663         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3664                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
3665
3666 }
3667
3668 static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
3669                                       struct link_params *params,
3670                                       struct link_vars *vars)
3671 {
3672         struct bnx2x *bp = params->bp;
3673         u16 i;
3674         static struct bnx2x_reg_set reg_set[] = {
3675                 /* Disable Autoneg */
3676                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
3677                 {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0},
3678                 {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3679                         0x3f00},
3680                 {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0},
3681                 {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0},
3682                 {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1},
3683                 {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa},
3684                 /* Disable CL36 PCS Tx */
3685                 {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0},
3686                 /* Double Wide Single Data Rate @ pll rate */
3687                 {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF},
3688                 /* Leave cl72 training enable, needed for KR */
3689                 {MDIO_PMA_DEVAD,
3690                 MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
3691                 0x2}
3692         };
3693
3694         for (i = 0; i < sizeof(reg_set)/sizeof(struct bnx2x_reg_set); i++)
3695                 bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
3696                                  reg_set[i].val);
3697
3698         /* Leave CL72 enabled */
3699         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3700                                  MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3701                                  0x3800);
3702
3703         /* Set speed via PMA/PMD register */
3704         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3705                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3706
3707         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3708                          MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
3709
3710         /* Enable encoded forced speed */
3711         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3712                          MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
3713
3714         /* Turn TX scramble payload only the 64/66 scrambler */
3715         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3716                          MDIO_WC_REG_TX66_CONTROL, 0x9);
3717
3718         /* Turn RX scramble payload only the 64/66 scrambler */
3719         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3720                                  MDIO_WC_REG_RX66_CONTROL, 0xF9);
3721
3722         /* Set and clear loopback to cause a reset to 64/66 decoder */
3723         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3724                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
3725         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3726                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3727
3728 }
3729
3730 static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
3731                                        struct link_params *params,
3732                                        u8 is_xfi)
3733 {
3734         struct bnx2x *bp = params->bp;
3735         u16 misc1_val, tap_val, tx_driver_val, lane, val;
3736         /* Hold rxSeqStart */
3737         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3738                                  MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, 0x8000);
3739
3740         /* Hold tx_fifo_reset */
3741         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3742                                  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x1);
3743
3744         /* Disable CL73 AN */
3745         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3746
3747         /* Disable 100FX Enable and Auto-Detect */
3748         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3749                         MDIO_WC_REG_FX100_CTRL1, &val);
3750         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3751                          MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA));
3752
3753         /* Disable 100FX Idle detect */
3754         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3755                                  MDIO_WC_REG_FX100_CTRL3, 0x0080);
3756
3757         /* Set Block address to Remote PHY & Clear forced_speed[5] */
3758         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3759                         MDIO_WC_REG_DIGITAL4_MISC3, &val);
3760         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3761                          MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F));
3762
3763         /* Turn off auto-detect & fiber mode */
3764         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3765                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3766         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3767                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3768                          (val & 0xFFEE));
3769
3770         /* Set filter_force_link, disable_false_link and parallel_detect */
3771         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3772                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
3773         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3774                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3775                          ((val | 0x0006) & 0xFFFE));
3776
3777         /* Set XFI / SFI */
3778         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3779                         MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
3780
3781         misc1_val &= ~(0x1f);
3782
3783         if (is_xfi) {
3784                 misc1_val |= 0x5;
3785                 tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3786                            (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3787                            (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3788                 tx_driver_val =
3789                       ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3790                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3791                        (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3792
3793         } else {
3794                 misc1_val |= 0x9;
3795                 tap_val = ((0x0f << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3796                            (0x2b << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3797                            (0x02 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3798                 tx_driver_val =
3799                       ((0x03 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3800                        (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3801                        (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3802         }
3803         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3804                          MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
3805
3806         /* Set Transmit PMD settings */
3807         lane = bnx2x_get_warpcore_lane(phy, params);
3808         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3809                          MDIO_WC_REG_TX_FIR_TAP,
3810                          tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
3811         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3812                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3813                          tx_driver_val);
3814
3815         /* Enable fiber mode, enable and invert sig_det */
3816         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3817                                  MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0xd);
3818
3819         /* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
3820         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3821                                  MDIO_WC_REG_DIGITAL4_MISC3, 0x8080);
3822
3823         bnx2x_warpcore_set_lpi_passthrough(phy, params);
3824
3825         /* 10G XFI Full Duplex */
3826         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3827                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
3828
3829         /* Release tx_fifo_reset */
3830         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3831                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3832         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3833                          MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE);
3834
3835         /* Release rxSeqStart */
3836         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3837                         MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3838         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3839                          MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF));
3840 }
3841
3842 static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp,
3843                                        struct bnx2x_phy *phy)
3844 {
3845         DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n");
3846 }
3847
3848 static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
3849                                          struct bnx2x_phy *phy,
3850                                          u16 lane)
3851 {
3852         /* Rx0 anaRxControl1G */
3853         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3854                          MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
3855
3856         /* Rx2 anaRxControl1G */
3857         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3858                          MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
3859
3860         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3861                          MDIO_WC_REG_RX66_SCW0, 0xE070);
3862
3863         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3864                          MDIO_WC_REG_RX66_SCW1, 0xC0D0);
3865
3866         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3867                          MDIO_WC_REG_RX66_SCW2, 0xA0B0);
3868
3869         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3870                          MDIO_WC_REG_RX66_SCW3, 0x8090);
3871
3872         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3873                          MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
3874
3875         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3876                          MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
3877
3878         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3879                          MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
3880
3881         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3882                          MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
3883
3884         /* Serdes Digital Misc1 */
3885         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3886                          MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
3887
3888         /* Serdes Digital4 Misc3 */
3889         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3890                          MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
3891
3892         /* Set Transmit PMD settings */
3893         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3894                          MDIO_WC_REG_TX_FIR_TAP,
3895                         ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3896                          (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3897                          (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
3898                          MDIO_WC_REG_TX_FIR_TAP_ENABLE));
3899         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3900                       MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3901                      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3902                       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3903                       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3904 }
3905
3906 static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
3907                                            struct link_params *params,
3908                                            u8 fiber_mode,
3909                                            u8 always_autoneg)
3910 {
3911         struct bnx2x *bp = params->bp;
3912         u16 val16, digctrl_kx1, digctrl_kx2;
3913
3914         /* Clear XFI clock comp in non-10G single lane mode. */
3915         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3916                         MDIO_WC_REG_RX66_CONTROL, &val16);
3917         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3918                          MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
3919
3920         bnx2x_warpcore_set_lpi_passthrough(phy, params);
3921
3922         if (always_autoneg || phy->req_line_speed == SPEED_AUTO_NEG) {
3923                 /* SGMII Autoneg */
3924                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3925                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3926                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3927                                  MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
3928                                  val16 | 0x1000);
3929                 DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
3930         } else {
3931                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3932                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3933                 val16 &= 0xcebf;
3934                 switch (phy->req_line_speed) {
3935                 case SPEED_10:
3936                         break;
3937                 case SPEED_100:
3938                         val16 |= 0x2000;
3939                         break;
3940                 case SPEED_1000:
3941                         val16 |= 0x0040;
3942                         break;
3943                 default:
3944                         DP(NETIF_MSG_LINK,
3945                            "Speed not supported: 0x%x\n", phy->req_line_speed);
3946                         return;
3947                 }
3948
3949                 if (phy->req_duplex == DUPLEX_FULL)
3950                         val16 |= 0x0100;
3951
3952                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3953                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
3954
3955                 DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
3956                                phy->req_line_speed);
3957                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3958                                 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3959                 DP(NETIF_MSG_LINK, "  (readback) %x\n", val16);
3960         }
3961
3962         /* SGMII Slave mode and disable signal detect */
3963         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3964                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
3965         if (fiber_mode)
3966                 digctrl_kx1 = 1;
3967         else
3968                 digctrl_kx1 &= 0xff4a;
3969
3970         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3971                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3972                         digctrl_kx1);
3973
3974         /* Turn off parallel detect */
3975         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3976                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
3977         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3978                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3979                         (digctrl_kx2 & ~(1<<2)));
3980
3981         /* Re-enable parallel detect */
3982         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3983                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3984                         (digctrl_kx2 | (1<<2)));
3985
3986         /* Enable autodet */
3987         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3988                         MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3989                         (digctrl_kx1 | 0x10));
3990 }
3991
3992 static void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
3993                                       struct bnx2x_phy *phy,
3994                                       u8 reset)
3995 {
3996         u16 val;
3997         /* Take lane out of reset after configuration is finished */
3998         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3999                         MDIO_WC_REG_DIGITAL5_MISC6, &val);
4000         if (reset)
4001                 val |= 0xC000;
4002         else
4003                 val &= 0x3FFF;
4004         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4005                          MDIO_WC_REG_DIGITAL5_MISC6, val);
4006         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4007                          MDIO_WC_REG_DIGITAL5_MISC6, &val);
4008 }
4009 /* Clear SFI/XFI link settings registers */
4010 static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
4011                                       struct link_params *params,
4012                                       u16 lane)
4013 {
4014         struct bnx2x *bp = params->bp;
4015         u16 i;
4016         static struct bnx2x_reg_set wc_regs[] = {
4017                 {MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0},
4018                 {MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL1, 0x014a},
4019                 {MDIO_WC_DEVAD, MDIO_WC_REG_FX100_CTRL3, 0x0800},
4020                 {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL4_MISC3, 0x8008},
4021                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4022                         0x0195},
4023                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4024                         0x0007},
4025                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3,
4026                         0x0002},
4027                 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000},
4028                 {MDIO_WC_DEVAD, MDIO_WC_REG_TX_FIR_TAP, 0x0000},
4029                 {MDIO_WC_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040},
4030                 {MDIO_WC_DEVAD, MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140}
4031         };
4032         /* Set XFI clock comp as default. */
4033         bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4034                                  MDIO_WC_REG_RX66_CONTROL, (3<<13));
4035
4036         for (i = 0; i < sizeof(wc_regs)/sizeof(struct bnx2x_reg_set); i++)
4037                 bnx2x_cl45_write(bp, phy, wc_regs[i].devad, wc_regs[i].reg,
4038                                  wc_regs[i].val);
4039
4040         lane = bnx2x_get_warpcore_lane(phy, params);
4041         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4042                          MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
4043
4044 }
4045
4046 static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
4047                                                 u32 chip_id,
4048                                                 u32 shmem_base, u8 port,
4049                                                 u8 *gpio_num, u8 *gpio_port)
4050 {
4051         u32 cfg_pin;
4052         *gpio_num = 0;
4053         *gpio_port = 0;
4054         if (CHIP_IS_E3(bp)) {
4055                 cfg_pin = (REG_RD(bp, shmem_base +
4056                                 offsetof(struct shmem_region,
4057                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4058                                 PORT_HW_CFG_E3_MOD_ABS_MASK) >>
4059                                 PORT_HW_CFG_E3_MOD_ABS_SHIFT;
4060
4061                 /* Should not happen. This function called upon interrupt
4062                  * triggered by GPIO ( since EPIO can only generate interrupts
4063                  * to MCP).
4064                  * So if this function was called and none of the GPIOs was set,
4065                  * it means the shit hit the fan.
4066                  */
4067                 if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
4068                     (cfg_pin > PIN_CFG_GPIO3_P1)) {
4069                         DP(NETIF_MSG_LINK,
4070                            "ERROR: Invalid cfg pin %x for module detect indication\n",
4071                            cfg_pin);
4072                         return -EINVAL;
4073                 }
4074
4075                 *gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
4076                 *gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
4077         } else {
4078                 *gpio_num = MISC_REGISTERS_GPIO_3;
4079                 *gpio_port = port;
4080         }
4081         DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port);
4082         return 0;
4083 }
4084
4085 static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
4086                                        struct link_params *params)
4087 {
4088         struct bnx2x *bp = params->bp;
4089         u8 gpio_num, gpio_port;
4090         u32 gpio_val;
4091         if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
4092                                       params->shmem_base, params->port,
4093                                       &gpio_num, &gpio_port) != 0)
4094                 return 0;
4095         gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
4096
4097         /* Call the handling function in case module is detected */
4098         if (gpio_val == 0)
4099                 return 1;
4100         else
4101                 return 0;
4102 }
4103 static int bnx2x_warpcore_get_sigdet(struct bnx2x_phy *phy,
4104                                         struct link_params *params)
4105 {
4106         u16 gp2_status_reg0, lane;
4107         struct bnx2x *bp = params->bp;
4108
4109         lane = bnx2x_get_warpcore_lane(phy, params);
4110
4111         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
4112                                  &gp2_status_reg0);
4113
4114         return (gp2_status_reg0 >> (8+lane)) & 0x1;
4115 }
4116
4117 static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy,
4118                                        struct link_params *params,
4119                                        struct link_vars *vars)
4120 {
4121         struct bnx2x *bp = params->bp;
4122         u32 serdes_net_if;
4123         u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
4124         u16 lane = bnx2x_get_warpcore_lane(phy, params);
4125
4126         vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
4127
4128         if (!vars->turn_to_run_wc_rt)
4129                 return;
4130
4131         /* Return if there is no link partner */
4132         if (!(bnx2x_warpcore_get_sigdet(phy, params))) {
4133                 DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n");
4134                 return;
4135         }
4136
4137         if (vars->rx_tx_asic_rst) {
4138                 serdes_net_if = (REG_RD(bp, params->shmem_base +
4139                                 offsetof(struct shmem_region, dev_info.
4140                                 port_hw_config[params->port].default_cfg)) &
4141                                 PORT_HW_CFG_NET_SERDES_IF_MASK);
4142
4143                 switch (serdes_net_if) {
4144                 case PORT_HW_CFG_NET_SERDES_IF_KR:
4145                         /* Do we get link yet? */
4146                         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 0x81d1,
4147                                                                 &gp_status1);
4148                         lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */
4149                                 /*10G KR*/
4150                         lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
4151
4152                         DP(NETIF_MSG_LINK,
4153                                 "gp_status1 0x%x\n", gp_status1);
4154
4155                         if (lnkup_kr || lnkup) {
4156                                         vars->rx_tx_asic_rst = 0;
4157                                         DP(NETIF_MSG_LINK,
4158                                         "link up, rx_tx_asic_rst 0x%x\n",
4159                                         vars->rx_tx_asic_rst);
4160                         } else {
4161                                 /* Reset the lane to see if link comes up.*/
4162                                 bnx2x_warpcore_reset_lane(bp, phy, 1);
4163                                 bnx2x_warpcore_reset_lane(bp, phy, 0);
4164
4165                                 /* Restart Autoneg */
4166                                 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
4167                                         MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4168
4169                                 vars->rx_tx_asic_rst--;
4170                                 DP(NETIF_MSG_LINK, "0x%x retry left\n",
4171                                 vars->rx_tx_asic_rst);
4172                         }
4173                         break;
4174
4175                 default:
4176                         break;
4177                 }
4178
4179         } /*params->rx_tx_asic_rst*/
4180
4181 }
4182 static void bnx2x_warpcore_config_sfi(struct bnx2x_phy *phy,
4183                                       struct link_params *params)
4184 {
4185         u16 lane = bnx2x_get_warpcore_lane(phy, params);
4186         struct bnx2x *bp = params->bp;
4187         bnx2x_warpcore_clear_regs(phy, params, lane);
4188         if ((params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)] ==
4189              SPEED_10000) &&
4190             (phy->media_type != ETH_PHY_SFP_1G_FIBER)) {
4191                 DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
4192                 bnx2x_warpcore_set_10G_XFI(phy, params, 0);
4193         } else {
4194                 DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
4195                 bnx2x_warpcore_set_sgmii_speed(phy, params, 1, 0);
4196         }
4197 }
4198
4199 static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
4200                                        struct link_params *params,
4201                                        struct link_vars *vars)
4202 {
4203         struct bnx2x *bp = params->bp;
4204         u32 serdes_net_if;
4205         u8 fiber_mode;
4206         u16 lane = bnx2x_get_warpcore_lane(phy, params);
4207         serdes_net_if = (REG_RD(bp, params->shmem_base +
4208                          offsetof(struct shmem_region, dev_info.
4209                                   port_hw_config[params->port].default_cfg)) &
4210                          PORT_HW_CFG_NET_SERDES_IF_MASK);
4211         DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
4212                            "serdes_net_if = 0x%x\n",
4213                        vars->line_speed, serdes_net_if);
4214         bnx2x_set_aer_mmd(params, phy);
4215         bnx2x_warpcore_reset_lane(bp, phy, 1);
4216         vars->phy_flags |= PHY_XGXS_FLAG;
4217         if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
4218             (phy->req_line_speed &&
4219              ((phy->req_line_speed == SPEED_100) ||
4220               (phy->req_line_speed == SPEED_10)))) {
4221                 vars->phy_flags |= PHY_SGMII_FLAG;
4222                 DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
4223                 bnx2x_warpcore_clear_regs(phy, params, lane);
4224                 bnx2x_warpcore_set_sgmii_speed(phy, params, 0, 1);
4225         } else {
4226                 switch (serdes_net_if) {
4227                 case PORT_HW_CFG_NET_SERDES_IF_KR:
4228                         /* Enable KR Auto Neg */
4229                         if (params->loopback_mode != LOOPBACK_EXT)
4230                                 bnx2x_warpcore_enable_AN_KR(phy, params, vars);
4231                         else {
4232                                 DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
4233                                 bnx2x_warpcore_set_10G_KR(phy, params, vars);
4234                         }
4235                         break;
4236
4237                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
4238                         bnx2x_warpcore_clear_regs(phy, params, lane);
4239                         if (vars->line_speed == SPEED_10000) {
4240                                 DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
4241                                 bnx2x_warpcore_set_10G_XFI(phy, params, 1);
4242                         } else {
4243                                 if (SINGLE_MEDIA_DIRECT(params)) {
4244                                         DP(NETIF_MSG_LINK, "1G Fiber\n");
4245                                         fiber_mode = 1;
4246                                 } else {
4247                                         DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
4248                                         fiber_mode = 0;
4249                                 }
4250                                 bnx2x_warpcore_set_sgmii_speed(phy,
4251                                                                 params,
4252                                                                 fiber_mode,
4253                                                                 0);
4254                         }
4255
4256                         break;
4257
4258                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
4259                         /* Issue Module detection */
4260                         if (bnx2x_is_sfp_module_plugged(phy, params))
4261                                 bnx2x_sfp_module_detection(phy, params);
4262
4263                         bnx2x_warpcore_config_sfi(phy, params);
4264                         break;
4265
4266                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
4267                         if (vars->line_speed != SPEED_20000) {
4268                                 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4269                                 return;
4270                         }
4271                         DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
4272                         bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
4273                         /* Issue Module detection */
4274
4275                         bnx2x_sfp_module_detection(phy, params);
4276                         break;
4277
4278                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
4279                         if (vars->line_speed != SPEED_20000) {
4280                                 DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4281                                 return;
4282                         }
4283                         DP(NETIF_MSG_LINK, "Setting 20G KR2\n");
4284                         bnx2x_warpcore_set_20G_KR2(bp, phy);
4285                         break;
4286
4287                 default:
4288                         DP(NETIF_MSG_LINK,
4289                            "Unsupported Serdes Net Interface 0x%x\n",
4290                            serdes_net_if);
4291                         return;
4292                 }
4293         }
4294
4295         /* Take lane out of reset after configuration is finished */
4296         bnx2x_warpcore_reset_lane(bp, phy, 0);
4297         DP(NETIF_MSG_LINK, "Exit config init\n");
4298 }
4299
4300 static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
4301                                          struct bnx2x_phy *phy,
4302                                          u8 tx_en)
4303 {
4304         struct bnx2x *bp = params->bp;
4305         u32 cfg_pin;
4306         u8 port = params->port;
4307
4308         cfg_pin = REG_RD(bp, params->shmem_base +
4309                                 offsetof(struct shmem_region,
4310                                 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4311                                 PORT_HW_CFG_TX_LASER_MASK;
4312         /* Set the !tx_en since this pin is DISABLE_TX_LASER */
4313         DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
4314         /* For 20G, the expected pin to be used is 3 pins after the current */
4315
4316         bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
4317         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
4318                 bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
4319 }
4320
4321 static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
4322                                       struct link_params *params)
4323 {
4324         struct bnx2x *bp = params->bp;
4325         u16 val16;
4326         bnx2x_sfp_e3_set_transmitter(params, phy, 0);
4327         bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
4328         bnx2x_set_aer_mmd(params, phy);
4329         /* Global register */
4330         bnx2x_warpcore_reset_lane(bp, phy, 1);
4331
4332         /* Clear loopback settings (if any) */
4333         /* 10G & 20G */
4334         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4335                         MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4336         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4337                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 &
4338                          0xBFFF);
4339
4340         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4341                         MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4342         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4343                         MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe);
4344
4345         /* Update those 1-copy registers */
4346         CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4347                           MDIO_AER_BLOCK_AER_REG, 0);
4348         /* Enable 1G MDIO (1-copy) */
4349         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4350                         MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4351                         &val16);
4352         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4353                          MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4354                          val16 & ~0x10);
4355
4356         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4357                         MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4358         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4359                          MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4360                          val16 & 0xff00);
4361
4362 }
4363
4364 static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
4365                                         struct link_params *params)
4366 {
4367         struct bnx2x *bp = params->bp;
4368         u16 val16;
4369         u32 lane;
4370         DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
4371                        params->loopback_mode, phy->req_line_speed);
4372
4373         if (phy->req_line_speed < SPEED_10000) {
4374                 /* 10/100/1000 */
4375
4376                 /* Update those 1-copy registers */
4377                 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4378                                   MDIO_AER_BLOCK_AER_REG, 0);
4379                 /* Enable 1G MDIO (1-copy) */
4380                 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4381                                          MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4382                                          0x10);
4383                 /* Set 1G loopback based on lane (1-copy) */
4384                 lane = bnx2x_get_warpcore_lane(phy, params);
4385                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4386                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4387                 bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4388                                 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4389                                 val16 | (1<<lane));
4390
4391                 /* Switch back to 4-copy registers */
4392                 bnx2x_set_aer_mmd(params, phy);
4393         } else {
4394                 /* 10G & 20G */
4395                 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4396                                          MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
4397                                          0x4000);
4398
4399                 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
4400                                          MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1);
4401         }
4402 }
4403
4404
4405
4406 static void bnx2x_sync_link(struct link_params *params,
4407                              struct link_vars *vars)
4408 {
4409         struct bnx2x *bp = params->bp;
4410         u8 link_10g_plus;
4411         if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4412                 vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
4413         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4414         if (vars->link_up) {
4415                 DP(NETIF_MSG_LINK, "phy link up\n");
4416
4417                 vars->phy_link_up = 1;
4418                 vars->duplex = DUPLEX_FULL;
4419                 switch (vars->link_status &
4420                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
4421                 case LINK_10THD:
4422                         vars->duplex = DUPLEX_HALF;
4423                         /* Fall thru */
4424                 case LINK_10TFD:
4425                         vars->line_speed = SPEED_10;
4426                         break;
4427
4428                 case LINK_100TXHD:
4429                         vars->duplex = DUPLEX_HALF;
4430                         /* Fall thru */
4431                 case LINK_100T4:
4432                 case LINK_100TXFD:
4433                         vars->line_speed = SPEED_100;
4434                         break;
4435
4436                 case LINK_1000THD:
4437                         vars->duplex = DUPLEX_HALF;
4438                         /* Fall thru */
4439                 case LINK_1000TFD:
4440                         vars->line_speed = SPEED_1000;
4441                         break;
4442
4443                 case LINK_2500THD:
4444                         vars->duplex = DUPLEX_HALF;
4445                         /* Fall thru */
4446                 case LINK_2500TFD:
4447                         vars->line_speed = SPEED_2500;
4448                         break;
4449
4450                 case LINK_10GTFD:
4451                         vars->line_speed = SPEED_10000;
4452                         break;
4453                 case LINK_20GTFD:
4454                         vars->line_speed = SPEED_20000;
4455                         break;
4456                 default:
4457                         break;
4458                 }
4459                 vars->flow_ctrl = 0;
4460                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
4461                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
4462
4463                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
4464                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
4465
4466                 if (!vars->flow_ctrl)
4467                         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4468
4469                 if (vars->line_speed &&
4470                     ((vars->line_speed == SPEED_10) ||
4471                      (vars->line_speed == SPEED_100))) {
4472                         vars->phy_flags |= PHY_SGMII_FLAG;
4473                 } else {
4474                         vars->phy_flags &= ~PHY_SGMII_FLAG;
4475                 }
4476                 if (vars->line_speed &&
4477                     USES_WARPCORE(bp) &&
4478                     (vars->line_speed == SPEED_1000))
4479                         vars->phy_flags |= PHY_SGMII_FLAG;
4480                 /* Anything 10 and over uses the bmac */
4481                 link_10g_plus = (vars->line_speed >= SPEED_10000);
4482
4483                 if (link_10g_plus) {
4484                         if (USES_WARPCORE(bp))
4485                                 vars->mac_type = MAC_TYPE_XMAC;
4486                         else
4487                                 vars->mac_type = MAC_TYPE_BMAC;
4488                 } else {
4489                         if (USES_WARPCORE(bp))
4490                                 vars->mac_type = MAC_TYPE_UMAC;
4491                         else
4492                                 vars->mac_type = MAC_TYPE_EMAC;
4493                 }
4494         } else { /* Link down */
4495                 DP(NETIF_MSG_LINK, "phy link down\n");
4496
4497                 vars->phy_link_up = 0;
4498
4499                 vars->line_speed = 0;
4500                 vars->duplex = DUPLEX_FULL;
4501                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4502
4503                 /* Indicate no mac active */
4504                 vars->mac_type = MAC_TYPE_NONE;
4505                 if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4506                         vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
4507                 if (vars->link_status & LINK_STATUS_SFP_TX_FAULT)
4508                         vars->phy_flags |= PHY_SFP_TX_FAULT_FLAG;
4509         }
4510 }
4511
4512 void bnx2x_link_status_update(struct link_params *params,
4513                               struct link_vars *vars)
4514 {
4515         struct bnx2x *bp = params->bp;
4516         u8 port = params->port;
4517         u32 sync_offset, media_types;
4518         /* Update PHY configuration */
4519         set_phy_vars(params, vars);
4520
4521         vars->link_status = REG_RD(bp, params->shmem_base +
4522                                    offsetof(struct shmem_region,
4523                                             port_mb[port].link_status));
4524         if (bnx2x_eee_has_cap(params))
4525                 vars->eee_status = REG_RD(bp, params->shmem2_base +
4526                                           offsetof(struct shmem2_region,
4527                                                    eee_status[params->port]));
4528
4529         vars->phy_flags = PHY_XGXS_FLAG;
4530         bnx2x_sync_link(params, vars);
4531         /* Sync media type */
4532         sync_offset = params->shmem_base +
4533                         offsetof(struct shmem_region,
4534                                  dev_info.port_hw_config[port].media_type);
4535         media_types = REG_RD(bp, sync_offset);
4536
4537         params->phy[INT_PHY].media_type =
4538                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
4539                 PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
4540         params->phy[EXT_PHY1].media_type =
4541                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
4542                 PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
4543         params->phy[EXT_PHY2].media_type =
4544                 (media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
4545                 PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
4546         DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
4547
4548         /* Sync AEU offset */
4549         sync_offset = params->shmem_base +
4550                         offsetof(struct shmem_region,
4551                                  dev_info.port_hw_config[port].aeu_int_mask);
4552
4553         vars->aeu_int_mask = REG_RD(bp, sync_offset);
4554
4555         /* Sync PFC status */
4556         if (vars->link_status & LINK_STATUS_PFC_ENABLED)
4557                 params->feature_config_flags |=
4558                                         FEATURE_CONFIG_PFC_ENABLED;
4559         else
4560                 params->feature_config_flags &=
4561                                         ~FEATURE_CONFIG_PFC_ENABLED;
4562
4563         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
4564                  vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
4565         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
4566                  vars->line_speed, vars->duplex, vars->flow_ctrl);
4567 }
4568
4569 static void bnx2x_set_master_ln(struct link_params *params,
4570                                 struct bnx2x_phy *phy)
4571 {
4572         struct bnx2x *bp = params->bp;
4573         u16 new_master_ln, ser_lane;
4574         ser_lane = ((params->lane_config &
4575                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4576                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4577
4578         /* Set the master_ln for AN */
4579         CL22_RD_OVER_CL45(bp, phy,
4580                           MDIO_REG_BANK_XGXS_BLOCK2,
4581                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4582                           &new_master_ln);
4583
4584         CL22_WR_OVER_CL45(bp, phy,
4585                           MDIO_REG_BANK_XGXS_BLOCK2 ,
4586                           MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4587                           (new_master_ln | ser_lane));
4588 }
4589
4590 static int bnx2x_reset_unicore(struct link_params *params,
4591                                struct bnx2x_phy *phy,
4592                                u8 set_serdes)
4593 {
4594         struct bnx2x *bp = params->bp;
4595         u16 mii_control;
4596         u16 i;
4597         CL22_RD_OVER_CL45(bp, phy,
4598                           MDIO_REG_BANK_COMBO_IEEE0,
4599                           MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4600
4601         /* Reset the unicore */
4602         CL22_WR_OVER_CL45(bp, phy,
4603                           MDIO_REG_BANK_COMBO_IEEE0,
4604                           MDIO_COMBO_IEEE0_MII_CONTROL,
4605                           (mii_control |
4606                            MDIO_COMBO_IEEO_MII_CONTROL_RESET));
4607         if (set_serdes)
4608                 bnx2x_set_serdes_access(bp, params->port);
4609
4610         /* Wait for the reset to self clear */
4611         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
4612                 udelay(5);
4613
4614                 /* The reset erased the previous bank value */
4615                 CL22_RD_OVER_CL45(bp, phy,
4616                                   MDIO_REG_BANK_COMBO_IEEE0,
4617                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4618                                   &mii_control);
4619
4620                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
4621                         udelay(5);
4622                         return 0;
4623                 }
4624         }
4625
4626         netdev_err(bp->dev,  "Warning: PHY was not initialized,"
4627                               " Port %d\n",
4628                          params->port);
4629         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
4630         return -EINVAL;
4631
4632 }
4633
4634 static void bnx2x_set_swap_lanes(struct link_params *params,
4635                                  struct bnx2x_phy *phy)
4636 {
4637         struct bnx2x *bp = params->bp;
4638         /* Each two bits represents a lane number:
4639          * No swap is 0123 => 0x1b no need to enable the swap
4640          */
4641         u16 rx_lane_swap, tx_lane_swap;
4642
4643         rx_lane_swap = ((params->lane_config &
4644                          PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
4645                         PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
4646         tx_lane_swap = ((params->lane_config &
4647                          PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
4648                         PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
4649
4650         if (rx_lane_swap != 0x1b) {
4651                 CL22_WR_OVER_CL45(bp, phy,
4652                                   MDIO_REG_BANK_XGXS_BLOCK2,
4653                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP,
4654                                   (rx_lane_swap |
4655                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
4656                                    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
4657         } else {
4658                 CL22_WR_OVER_CL45(bp, phy,
4659                                   MDIO_REG_BANK_XGXS_BLOCK2,
4660                                   MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
4661         }
4662
4663         if (tx_lane_swap != 0x1b) {
4664                 CL22_WR_OVER_CL45(bp, phy,
4665                                   MDIO_REG_BANK_XGXS_BLOCK2,
4666                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP,
4667                                   (tx_lane_swap |
4668                                    MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
4669         } else {
4670                 CL22_WR_OVER_CL45(bp, phy,
4671                                   MDIO_REG_BANK_XGXS_BLOCK2,
4672                                   MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
4673         }
4674 }
4675
4676 static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
4677                                          struct link_params *params)
4678 {
4679         struct bnx2x *bp = params->bp;
4680         u16 control2;
4681         CL22_RD_OVER_CL45(bp, phy,
4682                           MDIO_REG_BANK_SERDES_DIGITAL,
4683                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4684                           &control2);
4685         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4686                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4687         else
4688                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4689         DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
4690                 phy->speed_cap_mask, control2);
4691         CL22_WR_OVER_CL45(bp, phy,
4692                           MDIO_REG_BANK_SERDES_DIGITAL,
4693                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4694                           control2);
4695
4696         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4697              (phy->speed_cap_mask &
4698                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4699                 DP(NETIF_MSG_LINK, "XGXS\n");
4700
4701                 CL22_WR_OVER_CL45(bp, phy,
4702                                  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4703                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
4704                                  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
4705
4706                 CL22_RD_OVER_CL45(bp, phy,
4707                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
4708                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4709                                   &control2);
4710
4711
4712                 control2 |=
4713                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
4714
4715                 CL22_WR_OVER_CL45(bp, phy,
4716                                   MDIO_REG_BANK_10G_PARALLEL_DETECT,
4717                                   MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4718                                   control2);
4719
4720                 /* Disable parallel detection of HiG */
4721                 CL22_WR_OVER_CL45(bp, phy,
4722                                   MDIO_REG_BANK_XGXS_BLOCK2,
4723                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
4724                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
4725                                   MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
4726         }
4727 }
4728
4729 static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
4730                               struct link_params *params,
4731                               struct link_vars *vars,
4732                               u8 enable_cl73)
4733 {
4734         struct bnx2x *bp = params->bp;
4735         u16 reg_val;
4736
4737         /* CL37 Autoneg */
4738         CL22_RD_OVER_CL45(bp, phy,
4739                           MDIO_REG_BANK_COMBO_IEEE0,
4740                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4741
4742         /* CL37 Autoneg Enabled */
4743         if (vars->line_speed == SPEED_AUTO_NEG)
4744                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
4745         else /* CL37 Autoneg Disabled */
4746                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4747                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
4748
4749         CL22_WR_OVER_CL45(bp, phy,
4750                           MDIO_REG_BANK_COMBO_IEEE0,
4751                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4752
4753         /* Enable/Disable Autodetection */
4754
4755         CL22_RD_OVER_CL45(bp, phy,
4756                           MDIO_REG_BANK_SERDES_DIGITAL,
4757                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
4758         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
4759                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
4760         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
4761         if (vars->line_speed == SPEED_AUTO_NEG)
4762                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4763         else
4764                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4765
4766         CL22_WR_OVER_CL45(bp, phy,
4767                           MDIO_REG_BANK_SERDES_DIGITAL,
4768                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
4769
4770         /* Enable TetonII and BAM autoneg */
4771         CL22_RD_OVER_CL45(bp, phy,
4772                           MDIO_REG_BANK_BAM_NEXT_PAGE,
4773                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4774                           &reg_val);
4775         if (vars->line_speed == SPEED_AUTO_NEG) {
4776                 /* Enable BAM aneg Mode and TetonII aneg Mode */
4777                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4778                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4779         } else {
4780                 /* TetonII and BAM Autoneg Disabled */
4781                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4782                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4783         }
4784         CL22_WR_OVER_CL45(bp, phy,
4785                           MDIO_REG_BANK_BAM_NEXT_PAGE,
4786                           MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4787                           reg_val);
4788
4789         if (enable_cl73) {
4790                 /* Enable Cl73 FSM status bits */
4791                 CL22_WR_OVER_CL45(bp, phy,
4792                                   MDIO_REG_BANK_CL73_USERB0,
4793                                   MDIO_CL73_USERB0_CL73_UCTRL,
4794                                   0xe);
4795
4796                 /* Enable BAM Station Manager*/
4797                 CL22_WR_OVER_CL45(bp, phy,
4798                         MDIO_REG_BANK_CL73_USERB0,
4799                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
4800                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
4801                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
4802                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
4803
4804                 /* Advertise CL73 link speeds */
4805                 CL22_RD_OVER_CL45(bp, phy,
4806                                   MDIO_REG_BANK_CL73_IEEEB1,
4807                                   MDIO_CL73_IEEEB1_AN_ADV2,
4808                                   &reg_val);
4809                 if (phy->speed_cap_mask &
4810                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4811                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
4812                 if (phy->speed_cap_mask &
4813                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4814                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
4815
4816                 CL22_WR_OVER_CL45(bp, phy,
4817                                   MDIO_REG_BANK_CL73_IEEEB1,
4818                                   MDIO_CL73_IEEEB1_AN_ADV2,
4819                                   reg_val);
4820
4821                 /* CL73 Autoneg Enabled */
4822                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
4823
4824         } else /* CL73 Autoneg Disabled */
4825                 reg_val = 0;
4826
4827         CL22_WR_OVER_CL45(bp, phy,
4828                           MDIO_REG_BANK_CL73_IEEEB0,
4829                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
4830 }
4831
4832 /* Program SerDes, forced speed */
4833 static void bnx2x_program_serdes(struct bnx2x_phy *phy,
4834                                  struct link_params *params,
4835                                  struct link_vars *vars)
4836 {
4837         struct bnx2x *bp = params->bp;
4838         u16 reg_val;
4839
4840         /* Program duplex, disable autoneg and sgmii*/
4841         CL22_RD_OVER_CL45(bp, phy,
4842                           MDIO_REG_BANK_COMBO_IEEE0,
4843                           MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4844         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
4845                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4846                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
4847         if (phy->req_duplex == DUPLEX_FULL)
4848                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
4849         CL22_WR_OVER_CL45(bp, phy,
4850                           MDIO_REG_BANK_COMBO_IEEE0,
4851                           MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4852
4853         /* Program speed
4854          *  - needed only if the speed is greater than 1G (2.5G or 10G)
4855          */
4856         CL22_RD_OVER_CL45(bp, phy,
4857                           MDIO_REG_BANK_SERDES_DIGITAL,
4858                           MDIO_SERDES_DIGITAL_MISC1, &reg_val);
4859         /* Clearing the speed value before setting the right speed */
4860         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
4861
4862         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
4863                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
4864
4865         if (!((vars->line_speed == SPEED_1000) ||
4866               (vars->line_speed == SPEED_100) ||
4867               (vars->line_speed == SPEED_10))) {
4868
4869                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
4870                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
4871                 if (vars->line_speed == SPEED_10000)
4872                         reg_val |=
4873                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
4874         }
4875
4876         CL22_WR_OVER_CL45(bp, phy,
4877                           MDIO_REG_BANK_SERDES_DIGITAL,
4878                           MDIO_SERDES_DIGITAL_MISC1, reg_val);
4879
4880 }
4881
4882 static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy,
4883                                               struct link_params *params)
4884 {
4885         struct bnx2x *bp = params->bp;
4886         u16 val = 0;
4887
4888         /* Set extended capabilities */
4889         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
4890                 val |= MDIO_OVER_1G_UP1_2_5G;
4891         if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4892                 val |= MDIO_OVER_1G_UP1_10G;
4893         CL22_WR_OVER_CL45(bp, phy,
4894                           MDIO_REG_BANK_OVER_1G,
4895                           MDIO_OVER_1G_UP1, val);
4896
4897         CL22_WR_OVER_CL45(bp, phy,
4898                           MDIO_REG_BANK_OVER_1G,
4899                           MDIO_OVER_1G_UP3, 0x400);
4900 }
4901
4902 static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy,
4903                                               struct link_params *params,
4904                                               u16 ieee_fc)
4905 {
4906         struct bnx2x *bp = params->bp;
4907         u16 val;
4908         /* For AN, we are always publishing full duplex */
4909
4910         CL22_WR_OVER_CL45(bp, phy,
4911                           MDIO_REG_BANK_COMBO_IEEE0,
4912                           MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
4913         CL22_RD_OVER_CL45(bp, phy,
4914                           MDIO_REG_BANK_CL73_IEEEB1,
4915                           MDIO_CL73_IEEEB1_AN_ADV1, &val);
4916         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
4917         val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
4918         CL22_WR_OVER_CL45(bp, phy,
4919                           MDIO_REG_BANK_CL73_IEEEB1,
4920                           MDIO_CL73_IEEEB1_AN_ADV1, val);
4921 }
4922
4923 static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
4924                                   struct link_params *params,
4925                                   u8 enable_cl73)
4926 {
4927         struct bnx2x *bp = params->bp;
4928         u16 mii_control;
4929
4930         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
4931         /* Enable and restart BAM/CL37 aneg */
4932
4933         if (enable_cl73) {
4934                 CL22_RD_OVER_CL45(bp, phy,
4935                                   MDIO_REG_BANK_CL73_IEEEB0,
4936                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4937                                   &mii_control);
4938
4939                 CL22_WR_OVER_CL45(bp, phy,
4940                                   MDIO_REG_BANK_CL73_IEEEB0,
4941                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4942                                   (mii_control |
4943                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
4944                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
4945         } else {
4946
4947                 CL22_RD_OVER_CL45(bp, phy,
4948                                   MDIO_REG_BANK_COMBO_IEEE0,
4949                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4950                                   &mii_control);
4951                 DP(NETIF_MSG_LINK,
4952                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
4953                          mii_control);
4954                 CL22_WR_OVER_CL45(bp, phy,
4955                                   MDIO_REG_BANK_COMBO_IEEE0,
4956                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4957                                   (mii_control |
4958                                    MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4959                                    MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
4960         }
4961 }
4962
4963 static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
4964                                            struct link_params *params,
4965                                            struct link_vars *vars)
4966 {
4967         struct bnx2x *bp = params->bp;
4968         u16 control1;
4969
4970         /* In SGMII mode, the unicore is always slave */
4971
4972         CL22_RD_OVER_CL45(bp, phy,
4973                           MDIO_REG_BANK_SERDES_DIGITAL,
4974                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
4975                           &control1);
4976         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
4977         /* Set sgmii mode (and not fiber) */
4978         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
4979                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
4980                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
4981         CL22_WR_OVER_CL45(bp, phy,
4982                           MDIO_REG_BANK_SERDES_DIGITAL,
4983                           MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
4984                           control1);
4985
4986         /* If forced speed */
4987         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
4988                 /* Set speed, disable autoneg */
4989                 u16 mii_control;
4990
4991                 CL22_RD_OVER_CL45(bp, phy,
4992                                   MDIO_REG_BANK_COMBO_IEEE0,
4993                                   MDIO_COMBO_IEEE0_MII_CONTROL,
4994                                   &mii_control);
4995                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4996                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
4997                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
4998
4999                 switch (vars->line_speed) {
5000                 case SPEED_100:
5001                         mii_control |=
5002                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
5003                         break;
5004                 case SPEED_1000:
5005                         mii_control |=
5006                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
5007                         break;
5008                 case SPEED_10:
5009                         /* There is nothing to set for 10M */
5010                         break;
5011                 default:
5012                         /* Invalid speed for SGMII */
5013                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5014                                   vars->line_speed);
5015                         break;
5016                 }
5017
5018                 /* Setting the full duplex */
5019                 if (phy->req_duplex == DUPLEX_FULL)
5020                         mii_control |=
5021                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5022                 CL22_WR_OVER_CL45(bp, phy,
5023                                   MDIO_REG_BANK_COMBO_IEEE0,
5024                                   MDIO_COMBO_IEEE0_MII_CONTROL,
5025                                   mii_control);
5026
5027         } else { /* AN mode */
5028                 /* Enable and restart AN */
5029                 bnx2x_restart_autoneg(phy, params, 0);
5030         }
5031 }
5032
5033 /* Link management
5034  */
5035 static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
5036                                              struct link_params *params)
5037 {
5038         struct bnx2x *bp = params->bp;
5039         u16 pd_10g, status2_1000x;
5040         if (phy->req_line_speed != SPEED_AUTO_NEG)
5041                 return 0;
5042         CL22_RD_OVER_CL45(bp, phy,
5043                           MDIO_REG_BANK_SERDES_DIGITAL,
5044                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5045                           &status2_1000x);
5046         CL22_RD_OVER_CL45(bp, phy,
5047                           MDIO_REG_BANK_SERDES_DIGITAL,
5048                           MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5049                           &status2_1000x);
5050         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
5051                 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
5052                          params->port);
5053                 return 1;
5054         }
5055
5056         CL22_RD_OVER_CL45(bp, phy,
5057                           MDIO_REG_BANK_10G_PARALLEL_DETECT,
5058                           MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
5059                           &pd_10g);
5060
5061         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
5062                 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
5063                          params->port);
5064                 return 1;
5065         }
5066         return 0;
5067 }
5068
5069 static void bnx2x_update_adv_fc(struct bnx2x_phy *phy,
5070                                 struct link_params *params,
5071                                 struct link_vars *vars,
5072                                 u32 gp_status)
5073 {
5074         u16 ld_pause;   /* local driver */
5075         u16 lp_pause;   /* link partner */
5076         u16 pause_result;
5077         struct bnx2x *bp = params->bp;
5078         if ((gp_status &
5079              (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5080               MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
5081             (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5082              MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
5083
5084                 CL22_RD_OVER_CL45(bp, phy,
5085                                   MDIO_REG_BANK_CL73_IEEEB1,
5086                                   MDIO_CL73_IEEEB1_AN_ADV1,
5087                                   &ld_pause);
5088                 CL22_RD_OVER_CL45(bp, phy,
5089                                   MDIO_REG_BANK_CL73_IEEEB1,
5090                                   MDIO_CL73_IEEEB1_AN_LP_ADV1,
5091                                   &lp_pause);
5092                 pause_result = (ld_pause &
5093                                 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8;
5094                 pause_result |= (lp_pause &
5095                                  MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) >> 10;
5096                 DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n", pause_result);
5097         } else {
5098                 CL22_RD_OVER_CL45(bp, phy,
5099                                   MDIO_REG_BANK_COMBO_IEEE0,
5100                                   MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
5101                                   &ld_pause);
5102                 CL22_RD_OVER_CL45(bp, phy,
5103                         MDIO_REG_BANK_COMBO_IEEE0,
5104                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
5105                         &lp_pause);
5106                 pause_result = (ld_pause &
5107                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
5108                 pause_result |= (lp_pause &
5109                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
5110                 DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n", pause_result);
5111         }
5112         bnx2x_pause_resolve(vars, pause_result);
5113
5114 }
5115
5116 static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
5117                                     struct link_params *params,
5118                                     struct link_vars *vars,
5119                                     u32 gp_status)
5120 {
5121         struct bnx2x *bp = params->bp;
5122         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5123
5124         /* Resolve from gp_status in case of AN complete and not sgmii */
5125         if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) {
5126                 /* Update the advertised flow-controled of LD/LP in AN */
5127                 if (phy->req_line_speed == SPEED_AUTO_NEG)
5128                         bnx2x_update_adv_fc(phy, params, vars, gp_status);
5129                 /* But set the flow-control result as the requested one */
5130                 vars->flow_ctrl = phy->req_flow_ctrl;
5131         } else if (phy->req_line_speed != SPEED_AUTO_NEG)
5132                 vars->flow_ctrl = params->req_fc_auto_adv;
5133         else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
5134                  (!(vars->phy_flags & PHY_SGMII_FLAG))) {
5135                 if (bnx2x_direct_parallel_detect_used(phy, params)) {
5136                         vars->flow_ctrl = params->req_fc_auto_adv;
5137                         return;
5138                 }
5139                 bnx2x_update_adv_fc(phy, params, vars, gp_status);
5140         }
5141         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
5142 }
5143
5144 static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
5145                                          struct link_params *params)
5146 {
5147         struct bnx2x *bp = params->bp;
5148         u16 rx_status, ustat_val, cl37_fsm_received;
5149         DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
5150         /* Step 1: Make sure signal is detected */
5151         CL22_RD_OVER_CL45(bp, phy,
5152                           MDIO_REG_BANK_RX0,
5153                           MDIO_RX0_RX_STATUS,
5154                           &rx_status);
5155         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
5156             (MDIO_RX0_RX_STATUS_SIGDET)) {
5157                 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
5158                              "rx_status(0x80b0) = 0x%x\n", rx_status);
5159                 CL22_WR_OVER_CL45(bp, phy,
5160                                   MDIO_REG_BANK_CL73_IEEEB0,
5161                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5162                                   MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
5163                 return;
5164         }
5165         /* Step 2: Check CL73 state machine */
5166         CL22_RD_OVER_CL45(bp, phy,
5167                           MDIO_REG_BANK_CL73_USERB0,
5168                           MDIO_CL73_USERB0_CL73_USTAT1,
5169                           &ustat_val);
5170         if ((ustat_val &
5171              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5172               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
5173             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5174               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
5175                 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
5176                              "ustat_val(0x8371) = 0x%x\n", ustat_val);
5177                 return;
5178         }
5179         /* Step 3: Check CL37 Message Pages received to indicate LP
5180          * supports only CL37
5181          */
5182         CL22_RD_OVER_CL45(bp, phy,
5183                           MDIO_REG_BANK_REMOTE_PHY,
5184                           MDIO_REMOTE_PHY_MISC_RX_STATUS,
5185                           &cl37_fsm_received);
5186         if ((cl37_fsm_received &
5187              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5188              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
5189             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5190               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
5191                 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
5192                              "misc_rx_status(0x8330) = 0x%x\n",
5193                          cl37_fsm_received);
5194                 return;
5195         }
5196         /* The combined cl37/cl73 fsm state information indicating that
5197          * we are connected to a device which does not support cl73, but
5198          * does support cl37 BAM. In this case we disable cl73 and
5199          * restart cl37 auto-neg
5200          */
5201
5202         /* Disable CL73 */
5203         CL22_WR_OVER_CL45(bp, phy,
5204                           MDIO_REG_BANK_CL73_IEEEB0,
5205                           MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5206                           0);
5207         /* Restart CL37 autoneg */
5208         bnx2x_restart_autoneg(phy, params, 0);
5209         DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
5210 }
5211
5212 static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
5213                                   struct link_params *params,
5214                                   struct link_vars *vars,
5215                                   u32 gp_status)
5216 {
5217         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
5218                 vars->link_status |=
5219                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5220
5221         if (bnx2x_direct_parallel_detect_used(phy, params))
5222                 vars->link_status |=
5223                         LINK_STATUS_PARALLEL_DETECTION_USED;
5224 }
5225 static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
5226                                      struct link_params *params,
5227                                       struct link_vars *vars,
5228                                       u16 is_link_up,
5229                                       u16 speed_mask,
5230                                       u16 is_duplex)
5231 {
5232         struct bnx2x *bp = params->bp;
5233         if (phy->req_line_speed == SPEED_AUTO_NEG)
5234                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
5235         if (is_link_up) {
5236                 DP(NETIF_MSG_LINK, "phy link up\n");
5237
5238                 vars->phy_link_up = 1;
5239                 vars->link_status |= LINK_STATUS_LINK_UP;
5240
5241                 switch (speed_mask) {
5242                 case GP_STATUS_10M:
5243                         vars->line_speed = SPEED_10;
5244                         if (is_duplex == DUPLEX_FULL)
5245                                 vars->link_status |= LINK_10TFD;
5246                         else
5247                                 vars->link_status |= LINK_10THD;
5248                         break;
5249
5250                 case GP_STATUS_100M:
5251                         vars->line_speed = SPEED_100;
5252                         if (is_duplex == DUPLEX_FULL)
5253                                 vars->link_status |= LINK_100TXFD;
5254                         else
5255                                 vars->link_status |= LINK_100TXHD;
5256                         break;
5257
5258                 case GP_STATUS_1G:
5259                 case GP_STATUS_1G_KX:
5260                         vars->line_speed = SPEED_1000;
5261                         if (is_duplex == DUPLEX_FULL)
5262                                 vars->link_status |= LINK_1000TFD;
5263                         else
5264                                 vars->link_status |= LINK_1000THD;
5265                         break;
5266
5267                 case GP_STATUS_2_5G:
5268                         vars->line_speed = SPEED_2500;
5269                         if (is_duplex == DUPLEX_FULL)
5270                                 vars->link_status |= LINK_2500TFD;
5271                         else
5272                                 vars->link_status |= LINK_2500THD;
5273                         break;
5274
5275                 case GP_STATUS_5G:
5276                 case GP_STATUS_6G:
5277                         DP(NETIF_MSG_LINK,
5278                                  "link speed unsupported  gp_status 0x%x\n",
5279                                   speed_mask);
5280                         return -EINVAL;
5281
5282                 case GP_STATUS_10G_KX4:
5283                 case GP_STATUS_10G_HIG:
5284                 case GP_STATUS_10G_CX4:
5285                 case GP_STATUS_10G_KR:
5286                 case GP_STATUS_10G_SFI:
5287                 case GP_STATUS_10G_XFI:
5288                         vars->line_speed = SPEED_10000;
5289                         vars->link_status |= LINK_10GTFD;
5290                         break;
5291                 case GP_STATUS_20G_DXGXS:
5292                         vars->line_speed = SPEED_20000;
5293                         vars->link_status |= LINK_20GTFD;
5294                         break;
5295                 default:
5296                         DP(NETIF_MSG_LINK,
5297                                   "link speed unsupported gp_status 0x%x\n",
5298                                   speed_mask);
5299                         return -EINVAL;
5300                 }
5301         } else { /* link_down */
5302                 DP(NETIF_MSG_LINK, "phy link down\n");
5303
5304                 vars->phy_link_up = 0;
5305
5306                 vars->duplex = DUPLEX_FULL;
5307                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5308                 vars->mac_type = MAC_TYPE_NONE;
5309         }
5310         DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n",
5311                     vars->phy_link_up, vars->line_speed);
5312         return 0;
5313 }
5314
5315 static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
5316                                       struct link_params *params,
5317                                       struct link_vars *vars)
5318 {
5319         struct bnx2x *bp = params->bp;
5320
5321         u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
5322         int rc = 0;
5323
5324         /* Read gp_status */
5325         CL22_RD_OVER_CL45(bp, phy,
5326                           MDIO_REG_BANK_GP_STATUS,
5327                           MDIO_GP_STATUS_TOP_AN_STATUS1,
5328                           &gp_status);
5329         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
5330                 duplex = DUPLEX_FULL;
5331         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
5332                 link_up = 1;
5333         speed_mask = gp_status & GP_STATUS_SPEED_MASK;
5334         DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
5335                        gp_status, link_up, speed_mask);
5336         rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
5337                                          duplex);
5338         if (rc == -EINVAL)
5339                 return rc;
5340
5341         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
5342                 if (SINGLE_MEDIA_DIRECT(params)) {
5343                         vars->duplex = duplex;
5344                         bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
5345                         if (phy->req_line_speed == SPEED_AUTO_NEG)
5346                                 bnx2x_xgxs_an_resolve(phy, params, vars,
5347                                                       gp_status);
5348                 }
5349         } else { /* Link_down */
5350                 if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5351                     SINGLE_MEDIA_DIRECT(params)) {
5352                         /* Check signal is detected */
5353                         bnx2x_check_fallback_to_cl37(phy, params);
5354                 }
5355         }
5356
5357         /* Read LP advertised speeds*/
5358         if (SINGLE_MEDIA_DIRECT(params) &&
5359             (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)) {
5360                 u16 val;
5361
5362                 CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB1,
5363                                   MDIO_CL73_IEEEB1_AN_LP_ADV2, &val);
5364
5365                 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
5366                         vars->link_status |=
5367                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
5368                 if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
5369                            MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
5370                         vars->link_status |=
5371                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5372
5373                 CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_OVER_1G,
5374                                   MDIO_OVER_1G_LP_UP1, &val);
5375
5376                 if (val & MDIO_OVER_1G_UP1_2_5G)
5377                         vars->link_status |=
5378                                 LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
5379                 if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
5380                         vars->link_status |=
5381                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5382         }
5383
5384         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
5385                    vars->duplex, vars->flow_ctrl, vars->link_status);
5386         return rc;
5387 }
5388
5389 static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
5390                                      struct link_params *params,
5391                                      struct link_vars *vars)
5392 {
5393         struct bnx2x *bp = params->bp;
5394         u8 lane;
5395         u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
5396         int rc = 0;
5397         lane = bnx2x_get_warpcore_lane(phy, params);
5398         /* Read gp_status */
5399         if (phy->req_line_speed > SPEED_10000) {
5400                 u16 temp_link_up;
5401                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5402                                 1, &temp_link_up);
5403                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5404                                 1, &link_up);
5405                 DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n",
5406                                temp_link_up, link_up);
5407                 link_up &= (1<<2);
5408                 if (link_up)
5409                         bnx2x_ext_phy_resolve_fc(phy, params, vars);
5410         } else {
5411                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5412                                 MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1);
5413                 DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1);
5414                 /* Check for either KR or generic link up. */
5415                 gp_status1 = ((gp_status1 >> 8) & 0xf) |
5416                         ((gp_status1 >> 12) & 0xf);
5417                 link_up = gp_status1 & (1 << lane);
5418                 if (link_up && SINGLE_MEDIA_DIRECT(params)) {
5419                         u16 pd, gp_status4;
5420                         if (phy->req_line_speed == SPEED_AUTO_NEG) {
5421                                 /* Check Autoneg complete */
5422                                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5423                                                 MDIO_WC_REG_GP2_STATUS_GP_2_4,
5424                                                 &gp_status4);
5425                                 if (gp_status4 & ((1<<12)<<lane))
5426                                         vars->link_status |=
5427                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5428
5429                                 /* Check parallel detect used */
5430                                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5431                                                 MDIO_WC_REG_PAR_DET_10G_STATUS,
5432                                                 &pd);
5433                                 if (pd & (1<<15))
5434                                         vars->link_status |=
5435                                         LINK_STATUS_PARALLEL_DETECTION_USED;
5436                         }
5437                         bnx2x_ext_phy_resolve_fc(phy, params, vars);
5438                         vars->duplex = duplex;
5439                 }
5440         }
5441
5442         if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) &&
5443             SINGLE_MEDIA_DIRECT(params)) {
5444                 u16 val;
5445
5446                 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
5447                                 MDIO_AN_REG_LP_AUTO_NEG2, &val);
5448
5449                 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
5450                         vars->link_status |=
5451                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
5452                 if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
5453                            MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
5454                         vars->link_status |=
5455                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5456
5457                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5458                                 MDIO_WC_REG_DIGITAL3_LP_UP1, &val);
5459
5460                 if (val & MDIO_OVER_1G_UP1_2_5G)
5461                         vars->link_status |=
5462                                 LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
5463                 if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
5464                         vars->link_status |=
5465                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
5466
5467         }
5468
5469
5470         if (lane < 2) {
5471                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5472                                 MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
5473         } else {
5474                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5475                                 MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
5476         }
5477         DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed);
5478
5479         if ((lane & 1) == 0)
5480                 gp_speed <<= 8;
5481         gp_speed &= 0x3f00;
5482
5483
5484         rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
5485                                          duplex);
5486
5487         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
5488                    vars->duplex, vars->flow_ctrl, vars->link_status);
5489         return rc;
5490 }
5491 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
5492 {
5493         struct bnx2x *bp = params->bp;
5494         struct bnx2x_phy *phy = &params->phy[INT_PHY];
5495         u16 lp_up2;
5496         u16 tx_driver;
5497         u16 bank;
5498
5499         /* Read precomp */
5500         CL22_RD_OVER_CL45(bp, phy,
5501                           MDIO_REG_BANK_OVER_1G,
5502                           MDIO_OVER_1G_LP_UP2, &lp_up2);
5503
5504         /* Bits [10:7] at lp_up2, positioned at [15:12] */
5505         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
5506                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
5507                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
5508
5509         if (lp_up2 == 0)
5510                 return;
5511
5512         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
5513               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
5514                 CL22_RD_OVER_CL45(bp, phy,
5515                                   bank,
5516                                   MDIO_TX0_TX_DRIVER, &tx_driver);
5517
5518                 /* Replace tx_driver bits [15:12] */
5519                 if (lp_up2 !=
5520                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
5521                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
5522                         tx_driver |= lp_up2;
5523                         CL22_WR_OVER_CL45(bp, phy,
5524                                           bank,
5525                                           MDIO_TX0_TX_DRIVER, tx_driver);
5526                 }
5527         }
5528 }
5529
5530 static int bnx2x_emac_program(struct link_params *params,
5531                               struct link_vars *vars)
5532 {
5533         struct bnx2x *bp = params->bp;
5534         u8 port = params->port;
5535         u16 mode = 0;
5536
5537         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
5538         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
5539                        EMAC_REG_EMAC_MODE,
5540                        (EMAC_MODE_25G_MODE |
5541                         EMAC_MODE_PORT_MII_10M |
5542                         EMAC_MODE_HALF_DUPLEX));
5543         switch (vars->line_speed) {
5544         case SPEED_10:
5545                 mode |= EMAC_MODE_PORT_MII_10M;
5546                 break;
5547
5548         case SPEED_100:
5549                 mode |= EMAC_MODE_PORT_MII;
5550                 break;
5551
5552         case SPEED_1000:
5553                 mode |= EMAC_MODE_PORT_GMII;
5554                 break;
5555
5556         case SPEED_2500:
5557                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
5558                 break;
5559
5560         default:
5561                 /* 10G not valid for EMAC */
5562                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5563                            vars->line_speed);
5564                 return -EINVAL;
5565         }
5566
5567         if (vars->duplex == DUPLEX_HALF)
5568                 mode |= EMAC_MODE_HALF_DUPLEX;
5569         bnx2x_bits_en(bp,
5570                       GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
5571                       mode);
5572
5573         bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
5574         return 0;
5575 }
5576
5577 static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
5578                                   struct link_params *params)
5579 {
5580
5581         u16 bank, i = 0;
5582         struct bnx2x *bp = params->bp;
5583
5584         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
5585               bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
5586                         CL22_WR_OVER_CL45(bp, phy,
5587                                           bank,
5588                                           MDIO_RX0_RX_EQ_BOOST,
5589                                           phy->rx_preemphasis[i]);
5590         }
5591
5592         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
5593                       bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
5594                         CL22_WR_OVER_CL45(bp, phy,
5595                                           bank,
5596                                           MDIO_TX0_TX_DRIVER,
5597                                           phy->tx_preemphasis[i]);
5598         }
5599 }
5600
5601 static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy,
5602                                    struct link_params *params,
5603                                    struct link_vars *vars)
5604 {
5605         struct bnx2x *bp = params->bp;
5606         u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
5607                           (params->loopback_mode == LOOPBACK_XGXS));
5608         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
5609                 if (SINGLE_MEDIA_DIRECT(params) &&
5610                     (params->feature_config_flags &
5611                      FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
5612                         bnx2x_set_preemphasis(phy, params);
5613
5614                 /* Forced speed requested? */
5615                 if (vars->line_speed != SPEED_AUTO_NEG ||
5616                     (SINGLE_MEDIA_DIRECT(params) &&
5617                      params->loopback_mode == LOOPBACK_EXT)) {
5618                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
5619
5620                         /* Disable autoneg */
5621                         bnx2x_set_autoneg(phy, params, vars, 0);
5622
5623                         /* Program speed and duplex */
5624                         bnx2x_program_serdes(phy, params, vars);
5625
5626                 } else { /* AN_mode */
5627                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
5628
5629                         /* AN enabled */
5630                         bnx2x_set_brcm_cl37_advertisement(phy, params);
5631
5632                         /* Program duplex & pause advertisement (for aneg) */
5633                         bnx2x_set_ieee_aneg_advertisement(phy, params,
5634                                                           vars->ieee_fc);
5635
5636                         /* Enable autoneg */
5637                         bnx2x_set_autoneg(phy, params, vars, enable_cl73);
5638
5639                         /* Enable and restart AN */
5640                         bnx2x_restart_autoneg(phy, params, enable_cl73);
5641                 }
5642
5643         } else { /* SGMII mode */
5644                 DP(NETIF_MSG_LINK, "SGMII\n");
5645
5646                 bnx2x_initialize_sgmii_process(phy, params, vars);
5647         }
5648 }
5649
5650 static int bnx2x_prepare_xgxs(struct bnx2x_phy *phy,
5651                           struct link_params *params,
5652                           struct link_vars *vars)
5653 {
5654         int rc;
5655         vars->phy_flags |= PHY_XGXS_FLAG;
5656         if ((phy->req_line_speed &&
5657              ((phy->req_line_speed == SPEED_100) ||
5658               (phy->req_line_speed == SPEED_10))) ||
5659             (!phy->req_line_speed &&
5660              (phy->speed_cap_mask >=
5661               PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5662              (phy->speed_cap_mask <
5663               PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
5664             (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
5665                 vars->phy_flags |= PHY_SGMII_FLAG;
5666         else
5667                 vars->phy_flags &= ~PHY_SGMII_FLAG;
5668
5669         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
5670         bnx2x_set_aer_mmd(params, phy);
5671         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
5672                 bnx2x_set_master_ln(params, phy);
5673
5674         rc = bnx2x_reset_unicore(params, phy, 0);
5675         /* Reset the SerDes and wait for reset bit return low */
5676         if (rc)
5677                 return rc;
5678
5679         bnx2x_set_aer_mmd(params, phy);
5680         /* Setting the masterLn_def again after the reset */
5681         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5682                 bnx2x_set_master_ln(params, phy);
5683                 bnx2x_set_swap_lanes(params, phy);
5684         }
5685
5686         return rc;
5687 }
5688
5689 static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
5690                                      struct bnx2x_phy *phy,
5691                                      struct link_params *params)
5692 {
5693         u16 cnt, ctrl;
5694         /* Wait for soft reset to get cleared up to 1 sec */
5695         for (cnt = 0; cnt < 1000; cnt++) {
5696                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
5697                         bnx2x_cl22_read(bp, phy,
5698                                 MDIO_PMA_REG_CTRL, &ctrl);
5699                 else
5700                         bnx2x_cl45_read(bp, phy,
5701                                 MDIO_PMA_DEVAD,
5702                                 MDIO_PMA_REG_CTRL, &ctrl);
5703                 if (!(ctrl & (1<<15)))
5704                         break;
5705                 usleep_range(1000, 2000);
5706         }
5707
5708         if (cnt == 1000)
5709                 netdev_err(bp->dev,  "Warning: PHY was not initialized,"
5710                                       " Port %d\n",
5711                          params->port);
5712         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
5713         return cnt;
5714 }
5715
5716 static void bnx2x_link_int_enable(struct link_params *params)
5717 {
5718         u8 port = params->port;
5719         u32 mask;
5720         struct bnx2x *bp = params->bp;
5721
5722         /* Setting the status to report on link up for either XGXS or SerDes */
5723         if (CHIP_IS_E3(bp)) {
5724                 mask = NIG_MASK_XGXS0_LINK_STATUS;
5725                 if (!(SINGLE_MEDIA_DIRECT(params)))
5726                         mask |= NIG_MASK_MI_INT;
5727         } else if (params->switch_cfg == SWITCH_CFG_10G) {
5728                 mask = (NIG_MASK_XGXS0_LINK10G |
5729                         NIG_MASK_XGXS0_LINK_STATUS);
5730                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5731                 if (!(SINGLE_MEDIA_DIRECT(params)) &&
5732                         params->phy[INT_PHY].type !=
5733                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
5734                         mask |= NIG_MASK_MI_INT;
5735                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5736                 }
5737
5738         } else { /* SerDes */
5739                 mask = NIG_MASK_SERDES0_LINK_STATUS;
5740                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5741                 if (!(SINGLE_MEDIA_DIRECT(params)) &&
5742                         params->phy[INT_PHY].type !=
5743                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
5744                         mask |= NIG_MASK_MI_INT;
5745                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5746                 }
5747         }
5748         bnx2x_bits_en(bp,
5749                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5750                       mask);
5751
5752         DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
5753                  (params->switch_cfg == SWITCH_CFG_10G),
5754                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5755         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5756                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5757                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5758                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5759         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5760            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5761            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5762 }
5763
5764 static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
5765                                      u8 exp_mi_int)
5766 {
5767         u32 latch_status = 0;
5768
5769         /* Disable the MI INT ( external phy int ) by writing 1 to the
5770          * status register. Link down indication is high-active-signal,
5771          * so in this case we need to write the status to clear the XOR
5772          */
5773         /* Read Latched signals */
5774         latch_status = REG_RD(bp,
5775                                     NIG_REG_LATCH_STATUS_0 + port*8);
5776         DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
5777         /* Handle only those with latched-signal=up.*/
5778         if (exp_mi_int)
5779                 bnx2x_bits_en(bp,
5780                               NIG_REG_STATUS_INTERRUPT_PORT0
5781                               + port*4,
5782                               NIG_STATUS_EMAC0_MI_INT);
5783         else
5784                 bnx2x_bits_dis(bp,
5785                                NIG_REG_STATUS_INTERRUPT_PORT0
5786                                + port*4,
5787                                NIG_STATUS_EMAC0_MI_INT);
5788
5789         if (latch_status & 1) {
5790
5791                 /* For all latched-signal=up : Re-Arm Latch signals */
5792                 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
5793                        (latch_status & 0xfffe) | (latch_status & 1));
5794         }
5795         /* For all latched-signal=up,Write original_signal to status */
5796 }
5797
5798 static void bnx2x_link_int_ack(struct link_params *params,
5799                                struct link_vars *vars, u8 is_10g_plus)
5800 {
5801         struct bnx2x *bp = params->bp;
5802         u8 port = params->port;
5803         u32 mask;
5804         /* First reset all status we assume only one line will be
5805          * change at a time
5806          */
5807         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5808                        (NIG_STATUS_XGXS0_LINK10G |
5809                         NIG_STATUS_XGXS0_LINK_STATUS |
5810                         NIG_STATUS_SERDES0_LINK_STATUS));
5811         if (vars->phy_link_up) {
5812                 if (USES_WARPCORE(bp))
5813                         mask = NIG_STATUS_XGXS0_LINK_STATUS;
5814                 else {
5815                         if (is_10g_plus)
5816                                 mask = NIG_STATUS_XGXS0_LINK10G;
5817                         else if (params->switch_cfg == SWITCH_CFG_10G) {
5818                                 /* Disable the link interrupt by writing 1 to
5819                                  * the relevant lane in the status register
5820                                  */
5821                                 u32 ser_lane =
5822                                         ((params->lane_config &
5823                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5824                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5825                                 mask = ((1 << ser_lane) <<
5826                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
5827                         } else
5828                                 mask = NIG_STATUS_SERDES0_LINK_STATUS;
5829                 }
5830                 DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n",
5831                                mask);
5832                 bnx2x_bits_en(bp,
5833                               NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5834                               mask);
5835         }
5836 }
5837
5838 static int bnx2x_format_ver(u32 num, u8 *str, u16 *len)
5839 {
5840         u8 *str_ptr = str;
5841         u32 mask = 0xf0000000;
5842         u8 shift = 8*4;
5843         u8 digit;
5844         u8 remove_leading_zeros = 1;
5845         if (*len < 10) {
5846                 /* Need more than 10chars for this format */
5847                 *str_ptr = '\0';
5848                 (*len)--;
5849                 return -EINVAL;
5850         }
5851         while (shift > 0) {
5852
5853                 shift -= 4;
5854                 digit = ((num & mask) >> shift);
5855                 if (digit == 0 && remove_leading_zeros) {
5856                         mask = mask >> 4;
5857                         continue;
5858                 } else if (digit < 0xa)
5859                         *str_ptr = digit + '0';
5860                 else
5861                         *str_ptr = digit - 0xa + 'a';
5862                 remove_leading_zeros = 0;
5863                 str_ptr++;
5864                 (*len)--;
5865                 mask = mask >> 4;
5866                 if (shift == 4*4) {
5867                         *str_ptr = '.';
5868                         str_ptr++;
5869                         (*len)--;
5870                         remove_leading_zeros = 1;
5871                 }
5872         }
5873         return 0;
5874 }
5875
5876
5877 static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
5878 {
5879         str[0] = '\0';
5880         (*len)--;
5881         return 0;
5882 }
5883
5884 int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 *version,
5885                                  u16 len)
5886 {
5887         struct bnx2x *bp;
5888         u32 spirom_ver = 0;
5889         int status = 0;
5890         u8 *ver_p = version;
5891         u16 remain_len = len;
5892         if (version == NULL || params == NULL)
5893                 return -EINVAL;
5894         bp = params->bp;
5895
5896         /* Extract first external phy*/
5897         version[0] = '\0';
5898         spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
5899
5900         if (params->phy[EXT_PHY1].format_fw_ver) {
5901                 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
5902                                                               ver_p,
5903                                                               &remain_len);
5904                 ver_p += (len - remain_len);
5905         }
5906         if ((params->num_phys == MAX_PHYS) &&
5907             (params->phy[EXT_PHY2].ver_addr != 0)) {
5908                 spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr);
5909                 if (params->phy[EXT_PHY2].format_fw_ver) {
5910                         *ver_p = '/';
5911                         ver_p++;
5912                         remain_len--;
5913                         status |= params->phy[EXT_PHY2].format_fw_ver(
5914                                 spirom_ver,
5915                                 ver_p,
5916                                 &remain_len);
5917                         ver_p = version + (len - remain_len);
5918                 }
5919         }
5920         *ver_p = '\0';
5921         return status;
5922 }
5923
5924 static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
5925                                     struct link_params *params)
5926 {
5927         u8 port = params->port;
5928         struct bnx2x *bp = params->bp;
5929
5930         if (phy->req_line_speed != SPEED_1000) {
5931                 u32 md_devad = 0;
5932
5933                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
5934
5935                 if (!CHIP_IS_E3(bp)) {
5936                         /* Change the uni_phy_addr in the nig */
5937                         md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
5938                                                port*0x18));
5939
5940                         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5941                                0x5);
5942                 }
5943
5944                 bnx2x_cl45_write(bp, phy,
5945                                  5,
5946                                  (MDIO_REG_BANK_AER_BLOCK +
5947                                   (MDIO_AER_BLOCK_AER_REG & 0xf)),
5948                                  0x2800);
5949
5950                 bnx2x_cl45_write(bp, phy,
5951                                  5,
5952                                  (MDIO_REG_BANK_CL73_IEEEB0 +
5953                                   (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5954                                  0x6041);
5955                 msleep(200);
5956                 /* Set aer mmd back */
5957                 bnx2x_set_aer_mmd(params, phy);
5958
5959                 if (!CHIP_IS_E3(bp)) {
5960                         /* And md_devad */
5961                         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5962                                md_devad);
5963                 }
5964         } else {
5965                 u16 mii_ctrl;
5966                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
5967                 bnx2x_cl45_read(bp, phy, 5,
5968                                 (MDIO_REG_BANK_COMBO_IEEE0 +
5969                                 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
5970                                 &mii_ctrl);
5971                 bnx2x_cl45_write(bp, phy, 5,
5972                                  (MDIO_REG_BANK_COMBO_IEEE0 +
5973                                  (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
5974                                  mii_ctrl |
5975                                  MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
5976         }
5977 }
5978
5979 int bnx2x_set_led(struct link_params *params,
5980                   struct link_vars *vars, u8 mode, u32 speed)
5981 {
5982         u8 port = params->port;
5983         u16 hw_led_mode = params->hw_led_mode;
5984         int rc = 0;
5985         u8 phy_idx;
5986         u32 tmp;
5987         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5988         struct bnx2x *bp = params->bp;
5989         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5990         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5991                  speed, hw_led_mode);
5992         /* In case */
5993         for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
5994                 if (params->phy[phy_idx].set_link_led) {
5995                         params->phy[phy_idx].set_link_led(
5996                                 &params->phy[phy_idx], params, mode);
5997                 }
5998         }
5999
6000         switch (mode) {
6001         case LED_MODE_FRONT_PANEL_OFF:
6002         case LED_MODE_OFF:
6003                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
6004                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
6005                        SHARED_HW_CFG_LED_MAC1);
6006
6007                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6008                 if (params->phy[EXT_PHY1].type ==
6009                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
6010                         tmp &= ~(EMAC_LED_1000MB_OVERRIDE |
6011                                 EMAC_LED_100MB_OVERRIDE |
6012                                 EMAC_LED_10MB_OVERRIDE);
6013                 else
6014                         tmp |= EMAC_LED_OVERRIDE;
6015
6016                 EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp);
6017                 break;
6018
6019         case LED_MODE_OPER:
6020                 /* For all other phys, OPER mode is same as ON, so in case
6021                  * link is down, do nothing
6022                  */
6023                 if (!vars->link_up)
6024                         break;
6025         case LED_MODE_ON:
6026                 if (((params->phy[EXT_PHY1].type ==
6027                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
6028                          (params->phy[EXT_PHY1].type ==
6029                           PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
6030                     CHIP_IS_E2(bp) && params->num_phys == 2) {
6031                         /* This is a work-around for E2+8727 Configurations */
6032                         if (mode == LED_MODE_ON ||
6033                                 speed == SPEED_10000){
6034                                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
6035                                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
6036
6037                                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6038                                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
6039                                         (tmp | EMAC_LED_OVERRIDE));
6040                                 /* Return here without enabling traffic
6041                                  * LED blink and setting rate in ON mode.
6042                                  * In oper mode, enabling LED blink
6043                                  * and setting rate is needed.
6044                                  */
6045                                 if (mode == LED_MODE_ON)
6046                                         return rc;
6047                         }
6048                 } else if (SINGLE_MEDIA_DIRECT(params)) {
6049                         /* This is a work-around for HW issue found when link
6050                          * is up in CL73
6051                          */
6052                         if ((!CHIP_IS_E3(bp)) ||
6053                             (CHIP_IS_E3(bp) &&
6054                              mode == LED_MODE_ON))
6055                                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
6056
6057                         if (CHIP_IS_E1x(bp) ||
6058                             CHIP_IS_E2(bp) ||
6059                             (mode == LED_MODE_ON))
6060                                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
6061                         else
6062                                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
6063                                        hw_led_mode);
6064                 } else if ((params->phy[EXT_PHY1].type ==
6065                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
6066                            (mode == LED_MODE_ON)) {
6067                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
6068                         tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6069                         EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp |
6070                                 EMAC_LED_OVERRIDE | EMAC_LED_1000MB_OVERRIDE);
6071                         /* Break here; otherwise, it'll disable the
6072                          * intended override.
6073                          */
6074                         break;
6075                 } else
6076                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
6077                                hw_led_mode);
6078
6079                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
6080                 /* Set blinking rate to ~15.9Hz */
6081                 if (CHIP_IS_E3(bp))
6082                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
6083                                LED_BLINK_RATE_VAL_E3);
6084                 else
6085                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
6086                                LED_BLINK_RATE_VAL_E1X_E2);
6087                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
6088                        port*4, 1);
6089                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6090                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
6091                         (tmp & (~EMAC_LED_OVERRIDE)));
6092
6093                 if (CHIP_IS_E1(bp) &&
6094                     ((speed == SPEED_2500) ||
6095                      (speed == SPEED_1000) ||
6096                      (speed == SPEED_100) ||
6097                      (speed == SPEED_10))) {
6098                         /* For speeds less than 10G LED scheme is different */
6099                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
6100                                + port*4, 1);
6101                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
6102                                port*4, 0);
6103                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
6104                                port*4, 1);
6105                 }
6106                 break;
6107
6108         default:
6109                 rc = -EINVAL;
6110                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
6111                          mode);
6112                 break;
6113         }
6114         return rc;
6115
6116 }
6117
6118 /* This function comes to reflect the actual link state read DIRECTLY from the
6119  * HW
6120  */
6121 int bnx2x_test_link(struct link_params *params, struct link_vars *vars,
6122                     u8 is_serdes)
6123 {
6124         struct bnx2x *bp = params->bp;
6125         u16 gp_status = 0, phy_index = 0;
6126         u8 ext_phy_link_up = 0, serdes_phy_type;
6127         struct link_vars temp_vars;
6128         struct bnx2x_phy *int_phy = &params->phy[INT_PHY];
6129
6130         if (CHIP_IS_E3(bp)) {
6131                 u16 link_up;
6132                 if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)]
6133                     > SPEED_10000) {
6134                         /* Check 20G link */
6135                         bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
6136                                         1, &link_up);
6137                         bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
6138                                         1, &link_up);
6139                         link_up &= (1<<2);
6140                 } else {
6141                         /* Check 10G link and below*/
6142                         u8 lane = bnx2x_get_warpcore_lane(int_phy, params);
6143                         bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
6144                                         MDIO_WC_REG_GP2_STATUS_GP_2_1,
6145                                         &gp_status);
6146                         gp_status = ((gp_status >> 8) & 0xf) |
6147                                 ((gp_status >> 12) & 0xf);
6148                         link_up = gp_status & (1 << lane);
6149                 }
6150                 if (!link_up)
6151                         return -ESRCH;
6152         } else {
6153                 CL22_RD_OVER_CL45(bp, int_phy,
6154                           MDIO_REG_BANK_GP_STATUS,
6155                           MDIO_GP_STATUS_TOP_AN_STATUS1,
6156                           &gp_status);
6157         /* Link is up only if both local phy and external phy are up */
6158         if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
6159                 return -ESRCH;
6160         }
6161         /* In XGXS loopback mode, do not check external PHY */
6162         if (params->loopback_mode == LOOPBACK_XGXS)
6163                 return 0;
6164
6165         switch (params->num_phys) {
6166         case 1:
6167                 /* No external PHY */
6168                 return 0;
6169         case 2:
6170                 ext_phy_link_up = params->phy[EXT_PHY1].read_status(
6171                         &params->phy[EXT_PHY1],
6172                         params, &temp_vars);
6173                 break;
6174         case 3: /* Dual Media */
6175                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6176                       phy_index++) {
6177                         serdes_phy_type = ((params->phy[phy_index].media_type ==
6178                                             ETH_PHY_SFPP_10G_FIBER) ||
6179                                            (params->phy[phy_index].media_type ==
6180                                             ETH_PHY_SFP_1G_FIBER) ||
6181                                            (params->phy[phy_index].media_type ==
6182                                             ETH_PHY_XFP_FIBER) ||
6183                                            (params->phy[phy_index].media_type ==
6184                                             ETH_PHY_DA_TWINAX));
6185
6186                         if (is_serdes != serdes_phy_type)
6187                                 continue;
6188                         if (params->phy[phy_index].read_status) {
6189                                 ext_phy_link_up |=
6190                                         params->phy[phy_index].read_status(
6191                                                 &params->phy[phy_index],
6192                                                 params, &temp_vars);
6193                         }
6194                 }
6195                 break;
6196         }
6197         if (ext_phy_link_up)
6198                 return 0;
6199         return -ESRCH;
6200 }
6201
6202 static int bnx2x_link_initialize(struct link_params *params,
6203                                  struct link_vars *vars)
6204 {
6205         int rc = 0;
6206         u8 phy_index, non_ext_phy;
6207         struct bnx2x *bp = params->bp;
6208         /* In case of external phy existence, the line speed would be the
6209          * line speed linked up by the external phy. In case it is direct
6210          * only, then the line_speed during initialization will be
6211          * equal to the req_line_speed
6212          */
6213         vars->line_speed = params->phy[INT_PHY].req_line_speed;
6214
6215         /* Initialize the internal phy in case this is a direct board
6216          * (no external phys), or this board has external phy which requires
6217          * to first.
6218          */
6219         if (!USES_WARPCORE(bp))
6220                 bnx2x_prepare_xgxs(&params->phy[INT_PHY], params, vars);
6221         /* init ext phy and enable link state int */
6222         non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
6223                        (params->loopback_mode == LOOPBACK_XGXS));
6224
6225         if (non_ext_phy ||
6226             (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
6227             (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6228                 struct bnx2x_phy *phy = &params->phy[INT_PHY];
6229                 if (vars->line_speed == SPEED_AUTO_NEG &&
6230                     (CHIP_IS_E1x(bp) ||
6231                      CHIP_IS_E2(bp)))
6232                         bnx2x_set_parallel_detection(phy, params);
6233                         if (params->phy[INT_PHY].config_init)
6234                                 params->phy[INT_PHY].config_init(phy,
6235                                                                  params,
6236                                                                  vars);
6237         }
6238
6239         /* Init external phy*/
6240         if (non_ext_phy) {
6241                 if (params->phy[INT_PHY].supported &
6242                     SUPPORTED_FIBRE)
6243                         vars->link_status |= LINK_STATUS_SERDES_LINK;
6244         } else {
6245                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6246                       phy_index++) {
6247                         /* No need to initialize second phy in case of first
6248                          * phy only selection. In case of second phy, we do
6249                          * need to initialize the first phy, since they are
6250                          * connected.
6251                          */
6252                         if (params->phy[phy_index].supported &
6253                             SUPPORTED_FIBRE)
6254                                 vars->link_status |= LINK_STATUS_SERDES_LINK;
6255
6256                         if (phy_index == EXT_PHY2 &&
6257                             (bnx2x_phy_selection(params) ==
6258                              PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
6259                                 DP(NETIF_MSG_LINK,
6260                                    "Not initializing second phy\n");
6261                                 continue;
6262                         }
6263                         params->phy[phy_index].config_init(
6264                                 &params->phy[phy_index],
6265                                 params, vars);
6266                 }
6267         }
6268         /* Reset the interrupt indication after phy was initialized */
6269         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
6270                        params->port*4,
6271                        (NIG_STATUS_XGXS0_LINK10G |
6272                         NIG_STATUS_XGXS0_LINK_STATUS |
6273                         NIG_STATUS_SERDES0_LINK_STATUS |
6274                         NIG_MASK_MI_INT));
6275         return rc;
6276 }
6277
6278 static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
6279                                  struct link_params *params)
6280 {
6281         /* Reset the SerDes/XGXS */
6282         REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6283                (0x1ff << (params->port*16)));
6284 }
6285
6286 static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
6287                                         struct link_params *params)
6288 {
6289         struct bnx2x *bp = params->bp;
6290         u8 gpio_port;
6291         /* HW reset */
6292         if (CHIP_IS_E2(bp))
6293                 gpio_port = BP_PATH(bp);
6294         else
6295                 gpio_port = params->port;
6296         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6297                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
6298                        gpio_port);
6299         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6300                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
6301                        gpio_port);
6302         DP(NETIF_MSG_LINK, "reset external PHY\n");
6303 }
6304
6305 static int bnx2x_update_link_down(struct link_params *params,
6306                                   struct link_vars *vars)
6307 {
6308         struct bnx2x *bp = params->bp;
6309         u8 port = params->port;
6310
6311         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
6312         bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
6313         vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
6314         /* Indicate no mac active */
6315         vars->mac_type = MAC_TYPE_NONE;
6316
6317         /* Update shared memory */
6318         vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
6319                                LINK_STATUS_LINK_UP |
6320                                LINK_STATUS_PHYSICAL_LINK_FLAG |
6321                                LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
6322                                LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
6323                                LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
6324                                LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK |
6325                                LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE |
6326                                LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE);
6327         vars->line_speed = 0;
6328         bnx2x_update_mng(params, vars->link_status);
6329
6330         /* Activate nig drain */
6331         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6332
6333         /* Disable emac */
6334         if (!CHIP_IS_E3(bp))
6335                 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6336
6337         usleep_range(10000, 20000);
6338         /* Reset BigMac/Xmac */
6339         if (CHIP_IS_E1x(bp) ||
6340             CHIP_IS_E2(bp))
6341                 bnx2x_set_bmac_rx(bp, params->chip_id, params->port, 0);
6342
6343         if (CHIP_IS_E3(bp)) {
6344                 /* Prevent LPI Generation by chip */
6345                 REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 + (params->port << 2),
6346                        0);
6347                 REG_WR(bp, MISC_REG_CPMU_LP_MASK_ENT_P0 + (params->port << 2),
6348                        0);
6349                 vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
6350                                       SHMEM_EEE_ACTIVE_BIT);
6351
6352                 bnx2x_update_mng_eee(params, vars->eee_status);
6353                 bnx2x_set_xmac_rxtx(params, 0);
6354                 bnx2x_set_umac_rxtx(params, 0);
6355         }
6356
6357         return 0;
6358 }
6359
6360 static int bnx2x_update_link_up(struct link_params *params,
6361                                 struct link_vars *vars,
6362                                 u8 link_10g)
6363 {
6364         struct bnx2x *bp = params->bp;
6365         u8 phy_idx, port = params->port;
6366         int rc = 0;
6367
6368         vars->link_status |= (LINK_STATUS_LINK_UP |
6369                               LINK_STATUS_PHYSICAL_LINK_FLAG);
6370         vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
6371
6372         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
6373                 vars->link_status |=
6374                         LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
6375
6376         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
6377                 vars->link_status |=
6378                         LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
6379         if (USES_WARPCORE(bp)) {
6380                 if (link_10g) {
6381                         if (bnx2x_xmac_enable(params, vars, 0) ==
6382                             -ESRCH) {
6383                                 DP(NETIF_MSG_LINK, "Found errors on XMAC\n");
6384                                 vars->link_up = 0;
6385                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
6386                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
6387                         }
6388                 } else
6389                         bnx2x_umac_enable(params, vars, 0);
6390                 bnx2x_set_led(params, vars,
6391                               LED_MODE_OPER, vars->line_speed);
6392
6393                 if ((vars->eee_status & SHMEM_EEE_ACTIVE_BIT) &&
6394                     (vars->eee_status & SHMEM_EEE_LPI_REQUESTED_BIT)) {
6395                         DP(NETIF_MSG_LINK, "Enabling LPI assertion\n");
6396                         REG_WR(bp, MISC_REG_CPMU_LP_FW_ENABLE_P0 +
6397                                (params->port << 2), 1);
6398                         REG_WR(bp, MISC_REG_CPMU_LP_DR_ENABLE, 1);
6399                         REG_WR(bp, MISC_REG_CPMU_LP_MASK_ENT_P0 +
6400                                (params->port << 2), 0xfc20);
6401                 }
6402         }
6403         if ((CHIP_IS_E1x(bp) ||
6404              CHIP_IS_E2(bp))) {
6405                 if (link_10g) {
6406                         if (bnx2x_bmac_enable(params, vars, 0, 1) ==
6407                             -ESRCH) {
6408                                 DP(NETIF_MSG_LINK, "Found errors on BMAC\n");
6409                                 vars->link_up = 0;
6410                                 vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
6411                                 vars->link_status &= ~LINK_STATUS_LINK_UP;
6412                         }
6413
6414                         bnx2x_set_led(params, vars,
6415                                       LED_MODE_OPER, SPEED_10000);
6416                 } else {
6417                         rc = bnx2x_emac_program(params, vars);
6418                         bnx2x_emac_enable(params, vars, 0);
6419
6420                         /* AN complete? */
6421                         if ((vars->link_status &
6422                              LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
6423                             && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
6424                             SINGLE_MEDIA_DIRECT(params))
6425                                 bnx2x_set_gmii_tx_driver(params);
6426                 }
6427         }
6428
6429         /* PBF - link up */
6430         if (CHIP_IS_E1x(bp))
6431                 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6432                                        vars->line_speed);
6433
6434         /* Disable drain */
6435         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6436
6437         /* Update shared memory */
6438         bnx2x_update_mng(params, vars->link_status);
6439         bnx2x_update_mng_eee(params, vars->eee_status);
6440         /* Check remote fault */
6441         for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
6442                 if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
6443                         bnx2x_check_half_open_conn(params, vars, 0);
6444                         break;
6445                 }
6446         }
6447         msleep(20);
6448         return rc;
6449 }
6450 /* The bnx2x_link_update function should be called upon link
6451  * interrupt.
6452  * Link is considered up as follows:
6453  * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
6454  *   to be up
6455  * - SINGLE_MEDIA - The link between the 577xx and the external
6456  *   phy (XGXS) need to up as well as the external link of the
6457  *   phy (PHY_EXT1)
6458  * - DUAL_MEDIA - The link between the 577xx and the first
6459  *   external phy needs to be up, and at least one of the 2
6460  *   external phy link must be up.
6461  */
6462 int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6463 {
6464         struct bnx2x *bp = params->bp;
6465         struct link_vars phy_vars[MAX_PHYS];
6466         u8 port = params->port;
6467         u8 link_10g_plus, phy_index;
6468         u8 ext_phy_link_up = 0, cur_link_up;
6469         int rc = 0;
6470         u8 is_mi_int = 0;
6471         u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
6472         u8 active_external_phy = INT_PHY;
6473         vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
6474         for (phy_index = INT_PHY; phy_index < params->num_phys;
6475               phy_index++) {
6476                 phy_vars[phy_index].flow_ctrl = 0;
6477                 phy_vars[phy_index].link_status = 0;
6478                 phy_vars[phy_index].line_speed = 0;
6479                 phy_vars[phy_index].duplex = DUPLEX_FULL;
6480                 phy_vars[phy_index].phy_link_up = 0;
6481                 phy_vars[phy_index].link_up = 0;
6482                 phy_vars[phy_index].fault_detected = 0;
6483                 /* different consideration, since vars holds inner state */
6484                 phy_vars[phy_index].eee_status = vars->eee_status;
6485         }
6486
6487         if (USES_WARPCORE(bp))
6488                 bnx2x_set_aer_mmd(params, &params->phy[INT_PHY]);
6489
6490         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6491                  port, (vars->phy_flags & PHY_XGXS_FLAG),
6492                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6493
6494         is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6495                                 port*0x18) > 0);
6496         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6497                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6498                  is_mi_int,
6499                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6500
6501         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6502           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6503           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6504
6505         /* Disable emac */
6506         if (!CHIP_IS_E3(bp))
6507                 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6508
6509         /* Step 1:
6510          * Check external link change only for external phys, and apply
6511          * priority selection between them in case the link on both phys
6512          * is up. Note that instead of the common vars, a temporary
6513          * vars argument is used since each phy may have different link/
6514          * speed/duplex result
6515          */
6516         for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6517               phy_index++) {
6518                 struct bnx2x_phy *phy = &params->phy[phy_index];
6519                 if (!phy->read_status)
6520                         continue;
6521                 /* Read link status and params of this ext phy */
6522                 cur_link_up = phy->read_status(phy, params,
6523                                                &phy_vars[phy_index]);
6524                 if (cur_link_up) {
6525                         DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
6526                                    phy_index);
6527                 } else {
6528                         DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
6529                                    phy_index);
6530                         continue;
6531                 }
6532
6533                 if (!ext_phy_link_up) {
6534                         ext_phy_link_up = 1;
6535                         active_external_phy = phy_index;
6536                 } else {
6537                         switch (bnx2x_phy_selection(params)) {
6538                         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
6539                         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6540                         /* In this option, the first PHY makes sure to pass the
6541                          * traffic through itself only.
6542                          * Its not clear how to reset the link on the second phy
6543                          */
6544                                 active_external_phy = EXT_PHY1;
6545                                 break;
6546                         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6547                         /* In this option, the first PHY makes sure to pass the
6548                          * traffic through the second PHY.
6549                          */
6550                                 active_external_phy = EXT_PHY2;
6551                                 break;
6552                         default:
6553                         /* Link indication on both PHYs with the following cases
6554                          * is invalid:
6555                          * - FIRST_PHY means that second phy wasn't initialized,
6556                          * hence its link is expected to be down
6557                          * - SECOND_PHY means that first phy should not be able
6558                          * to link up by itself (using configuration)
6559                          * - DEFAULT should be overriden during initialiazation
6560                          */
6561                                 DP(NETIF_MSG_LINK, "Invalid link indication"
6562                                            "mpc=0x%x. DISABLING LINK !!!\n",
6563                                            params->multi_phy_config);
6564                                 ext_phy_link_up = 0;
6565                                 break;
6566                         }
6567                 }
6568         }
6569         prev_line_speed = vars->line_speed;
6570         /* Step 2:
6571          * Read the status of the internal phy. In case of
6572          * DIRECT_SINGLE_MEDIA board, this link is the external link,
6573          * otherwise this is the link between the 577xx and the first
6574          * external phy
6575          */
6576         if (params->phy[INT_PHY].read_status)
6577                 params->phy[INT_PHY].read_status(
6578                         &params->phy[INT_PHY],
6579                         params, vars);
6580         /* The INT_PHY flow control reside in the vars. This include the
6581          * case where the speed or flow control are not set to AUTO.
6582          * Otherwise, the active external phy flow control result is set
6583          * to the vars. The ext_phy_line_speed is needed to check if the
6584          * speed is different between the internal phy and external phy.
6585          * This case may be result of intermediate link speed change.
6586          */
6587         if (active_external_phy > INT_PHY) {
6588                 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
6589                 /* Link speed is taken from the XGXS. AN and FC result from
6590                  * the external phy.
6591                  */
6592                 vars->link_status |= phy_vars[active_external_phy].link_status;
6593
6594                 /* if active_external_phy is first PHY and link is up - disable
6595                  * disable TX on second external PHY
6596                  */
6597                 if (active_external_phy == EXT_PHY1) {
6598                         if (params->phy[EXT_PHY2].phy_specific_func) {
6599                                 DP(NETIF_MSG_LINK,
6600                                    "Disabling TX on EXT_PHY2\n");
6601                                 params->phy[EXT_PHY2].phy_specific_func(
6602                                         &params->phy[EXT_PHY2],
6603                                         params, DISABLE_TX);
6604                         }
6605                 }
6606
6607                 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
6608                 vars->duplex = phy_vars[active_external_phy].duplex;
6609                 if (params->phy[active_external_phy].supported &
6610                     SUPPORTED_FIBRE)
6611                         vars->link_status |= LINK_STATUS_SERDES_LINK;
6612                 else
6613                         vars->link_status &= ~LINK_STATUS_SERDES_LINK;
6614
6615                 vars->eee_status = phy_vars[active_external_phy].eee_status;
6616
6617                 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
6618                            active_external_phy);
6619         }
6620
6621         for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6622               phy_index++) {
6623                 if (params->phy[phy_index].flags &
6624                     FLAGS_REARM_LATCH_SIGNAL) {
6625                         bnx2x_rearm_latch_signal(bp, port,
6626                                                  phy_index ==
6627                                                  active_external_phy);
6628                         break;
6629                 }
6630         }
6631         DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
6632                    " ext_phy_line_speed = %d\n", vars->flow_ctrl,
6633                    vars->link_status, ext_phy_line_speed);
6634         /* Upon link speed change set the NIG into drain mode. Comes to
6635          * deals with possible FIFO glitch due to clk change when speed
6636          * is decreased without link down indicator
6637          */
6638
6639         if (vars->phy_link_up) {
6640                 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
6641                     (ext_phy_line_speed != vars->line_speed)) {
6642                         DP(NETIF_MSG_LINK, "Internal link speed %d is"
6643                                    " different than the external"
6644                                    " link speed %d\n", vars->line_speed,
6645                                    ext_phy_line_speed);
6646                         vars->phy_link_up = 0;
6647                 } else if (prev_line_speed != vars->line_speed) {
6648                         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
6649                                0);
6650                          usleep_range(1000, 2000);
6651                 }
6652         }
6653
6654         /* Anything 10 and over uses the bmac */
6655         link_10g_plus = (vars->line_speed >= SPEED_10000);
6656
6657         bnx2x_link_int_ack(params, vars, link_10g_plus);
6658
6659         /* In case external phy link is up, and internal link is down
6660          * (not initialized yet probably after link initialization, it
6661          * needs to be initialized.
6662          * Note that after link down-up as result of cable plug, the xgxs
6663          * link would probably become up again without the need
6664          * initialize it
6665          */
6666         if (!(SINGLE_MEDIA_DIRECT(params))) {
6667                 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
6668                            " init_preceding = %d\n", ext_phy_link_up,
6669                            vars->phy_link_up,
6670                            params->phy[EXT_PHY1].flags &
6671                            FLAGS_INIT_XGXS_FIRST);
6672                 if (!(params->phy[EXT_PHY1].flags &
6673                       FLAGS_INIT_XGXS_FIRST)
6674                     && ext_phy_link_up && !vars->phy_link_up) {
6675                         vars->line_speed = ext_phy_line_speed;
6676                         if (vars->line_speed < SPEED_1000)
6677                                 vars->phy_flags |= PHY_SGMII_FLAG;
6678                         else
6679                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
6680
6681                         if (params->phy[INT_PHY].config_init)
6682                                 params->phy[INT_PHY].config_init(
6683                                         &params->phy[INT_PHY], params,
6684                                                 vars);
6685                 }
6686         }
6687         /* Link is up only if both local phy and external phy (in case of
6688          * non-direct board) are up and no fault detected on active PHY.
6689          */
6690         vars->link_up = (vars->phy_link_up &&
6691                          (ext_phy_link_up ||
6692                           SINGLE_MEDIA_DIRECT(params)) &&
6693                          (phy_vars[active_external_phy].fault_detected == 0));
6694
6695         /* Update the PFC configuration in case it was changed */
6696         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
6697                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
6698         else
6699                 vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
6700
6701         if (vars->link_up)
6702                 rc = bnx2x_update_link_up(params, vars, link_10g_plus);
6703         else
6704                 rc = bnx2x_update_link_down(params, vars);
6705
6706         /* Update MCP link status was changed */
6707         if (params->feature_config_flags & FEATURE_CONFIG_BC_SUPPORTS_AFEX)
6708                 bnx2x_fw_command(bp, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0);
6709
6710         return rc;
6711 }
6712
6713 /*****************************************************************************/
6714 /*                          External Phy section                             */
6715 /*****************************************************************************/
6716 void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
6717 {
6718         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6719                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6720          usleep_range(1000, 2000);
6721         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6722                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6723 }
6724
6725 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
6726                                       u32 spirom_ver, u32 ver_addr)
6727 {
6728         DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
6729                  (u16)(spirom_ver>>16), (u16)spirom_ver, port);
6730
6731         if (ver_addr)
6732                 REG_WR(bp, ver_addr, spirom_ver);
6733 }
6734
6735 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
6736                                       struct bnx2x_phy *phy,
6737                                       u8 port)
6738 {
6739         u16 fw_ver1, fw_ver2;
6740
6741         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6742                         MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6743         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6744                         MDIO_PMA_REG_ROM_VER2, &fw_ver2);
6745         bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
6746                                   phy->ver_addr);
6747 }
6748
6749 static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
6750                                        struct bnx2x_phy *phy,
6751                                        struct link_vars *vars)
6752 {
6753         u16 val;
6754         bnx2x_cl45_read(bp, phy,
6755                         MDIO_AN_DEVAD,
6756                         MDIO_AN_REG_STATUS, &val);
6757         bnx2x_cl45_read(bp, phy,
6758                         MDIO_AN_DEVAD,
6759                         MDIO_AN_REG_STATUS, &val);
6760         if (val & (1<<5))
6761                 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6762         if ((val & (1<<0)) == 0)
6763                 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
6764 }
6765
6766 /******************************************************************/
6767 /*              common BCM8073/BCM8727 PHY SECTION                */
6768 /******************************************************************/
6769 static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
6770                                   struct link_params *params,
6771                                   struct link_vars *vars)
6772 {
6773         struct bnx2x *bp = params->bp;
6774         if (phy->req_line_speed == SPEED_10 ||
6775             phy->req_line_speed == SPEED_100) {
6776                 vars->flow_ctrl = phy->req_flow_ctrl;
6777                 return;
6778         }
6779
6780         if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
6781             (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
6782                 u16 pause_result;
6783                 u16 ld_pause;           /* local */
6784                 u16 lp_pause;           /* link partner */
6785                 bnx2x_cl45_read(bp, phy,
6786                                 MDIO_AN_DEVAD,
6787                                 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
6788
6789                 bnx2x_cl45_read(bp, phy,
6790                                 MDIO_AN_DEVAD,
6791                                 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
6792                 pause_result = (ld_pause &
6793                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
6794                 pause_result |= (lp_pause &
6795                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
6796
6797                 bnx2x_pause_resolve(vars, pause_result);
6798                 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
6799                            pause_result);
6800         }
6801 }
6802 static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
6803                                              struct bnx2x_phy *phy,
6804                                              u8 port)
6805 {
6806         u32 count = 0;
6807         u16 fw_ver1, fw_msgout;
6808         int rc = 0;
6809
6810         /* Boot port from external ROM  */
6811         /* EDC grst */
6812         bnx2x_cl45_write(bp, phy,
6813                          MDIO_PMA_DEVAD,
6814                          MDIO_PMA_REG_GEN_CTRL,
6815                          0x0001);
6816
6817         /* Ucode reboot and rst */
6818         bnx2x_cl45_write(bp, phy,
6819                          MDIO_PMA_DEVAD,
6820                          MDIO_PMA_REG_GEN_CTRL,
6821                          0x008c);
6822
6823         bnx2x_cl45_write(bp, phy,
6824                          MDIO_PMA_DEVAD,
6825                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
6826
6827         /* Reset internal microprocessor */
6828         bnx2x_cl45_write(bp, phy,
6829                          MDIO_PMA_DEVAD,
6830                          MDIO_PMA_REG_GEN_CTRL,
6831                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
6832
6833         /* Release srst bit */
6834         bnx2x_cl45_write(bp, phy,
6835                          MDIO_PMA_DEVAD,
6836                          MDIO_PMA_REG_GEN_CTRL,
6837                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
6838
6839         /* Delay 100ms per the PHY specifications */
6840         msleep(100);
6841
6842         /* 8073 sometimes taking longer to download */
6843         do {
6844                 count++;
6845                 if (count > 300) {
6846                         DP(NETIF_MSG_LINK,
6847                                  "bnx2x_8073_8727_external_rom_boot port %x:"
6848                                  "Download failed. fw version = 0x%x\n",
6849                                  port, fw_ver1);
6850                         rc = -EINVAL;
6851                         break;
6852                 }
6853
6854                 bnx2x_cl45_read(bp, phy,
6855                                 MDIO_PMA_DEVAD,
6856                                 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6857                 bnx2x_cl45_read(bp, phy,
6858                                 MDIO_PMA_DEVAD,
6859                                 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
6860
6861                  usleep_range(1000, 2000);
6862         } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
6863                         ((fw_msgout & 0xff) != 0x03 && (phy->type ==
6864                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
6865
6866         /* Clear ser_boot_ctl bit */
6867         bnx2x_cl45_write(bp, phy,
6868                          MDIO_PMA_DEVAD,
6869                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
6870         bnx2x_save_bcm_spirom_ver(bp, phy, port);
6871
6872         DP(NETIF_MSG_LINK,
6873                  "bnx2x_8073_8727_external_rom_boot port %x:"
6874                  "Download complete. fw version = 0x%x\n",
6875                  port, fw_ver1);
6876
6877         return rc;
6878 }
6879
6880 /******************************************************************/
6881 /*                      BCM8073 PHY SECTION                       */
6882 /******************************************************************/
6883 static int bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
6884 {
6885         /* This is only required for 8073A1, version 102 only */
6886         u16 val;
6887
6888         /* Read 8073 HW revision*/
6889         bnx2x_cl45_read(bp, phy,
6890                         MDIO_PMA_DEVAD,
6891                         MDIO_PMA_REG_8073_CHIP_REV, &val);
6892
6893         if (val != 1) {
6894                 /* No need to workaround in 8073 A1 */
6895                 return 0;
6896         }
6897
6898         bnx2x_cl45_read(bp, phy,
6899                         MDIO_PMA_DEVAD,
6900                         MDIO_PMA_REG_ROM_VER2, &val);
6901
6902         /* SNR should be applied only for version 0x102 */
6903         if (val != 0x102)
6904                 return 0;
6905
6906         return 1;
6907 }
6908
6909 static int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
6910 {
6911         u16 val, cnt, cnt1 ;
6912
6913         bnx2x_cl45_read(bp, phy,
6914                         MDIO_PMA_DEVAD,
6915                         MDIO_PMA_REG_8073_CHIP_REV, &val);
6916
6917         if (val > 0) {
6918                 /* No need to workaround in 8073 A1 */
6919                 return 0;
6920         }
6921         /* XAUI workaround in 8073 A0: */
6922
6923         /* After loading the boot ROM and restarting Autoneg, poll
6924          * Dev1, Reg $C820:
6925          */
6926
6927         for (cnt = 0; cnt < 1000; cnt++) {
6928                 bnx2x_cl45_read(bp, phy,
6929                                 MDIO_PMA_DEVAD,
6930                                 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
6931                                 &val);
6932                   /* If bit [14] = 0 or bit [13] = 0, continue on with
6933                    * system initialization (XAUI work-around not required, as
6934                    * these bits indicate 2.5G or 1G link up).
6935                    */
6936                 if (!(val & (1<<14)) || !(val & (1<<13))) {
6937                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
6938                         return 0;
6939                 } else if (!(val & (1<<15))) {
6940                         DP(NETIF_MSG_LINK, "bit 15 went off\n");
6941                         /* If bit 15 is 0, then poll Dev1, Reg $C841 until it's
6942                          * MSB (bit15) goes to 1 (indicating that the XAUI
6943                          * workaround has completed), then continue on with
6944                          * system initialization.
6945                          */
6946                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
6947                                 bnx2x_cl45_read(bp, phy,
6948                                         MDIO_PMA_DEVAD,
6949                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
6950                                 if (val & (1<<15)) {
6951                                         DP(NETIF_MSG_LINK,
6952                                           "XAUI workaround has completed\n");
6953                                         return 0;
6954                                  }
6955                                  usleep_range(3000, 6000);
6956                         }
6957                         break;
6958                 }
6959                 usleep_range(3000, 6000);
6960         }
6961         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
6962         return -EINVAL;
6963 }
6964
6965 static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
6966 {
6967         /* Force KR or KX */
6968         bnx2x_cl45_write(bp, phy,
6969                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
6970         bnx2x_cl45_write(bp, phy,
6971                          MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
6972         bnx2x_cl45_write(bp, phy,
6973                          MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
6974         bnx2x_cl45_write(bp, phy,
6975                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
6976 }
6977
6978 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
6979                                       struct bnx2x_phy *phy,
6980                                       struct link_vars *vars)
6981 {
6982         u16 cl37_val;
6983         struct bnx2x *bp = params->bp;
6984         bnx2x_cl45_read(bp, phy,
6985                         MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
6986
6987         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
6988         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
6989         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
6990         if ((vars->ieee_fc &
6991             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
6992             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
6993                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
6994         }
6995         if ((vars->ieee_fc &
6996             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
6997             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
6998                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
6999         }
7000         if ((vars->ieee_fc &
7001             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
7002             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
7003                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
7004         }
7005         DP(NETIF_MSG_LINK,
7006                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
7007
7008         bnx2x_cl45_write(bp, phy,
7009                          MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
7010         msleep(500);
7011 }
7012
7013 static void bnx2x_8073_specific_func(struct bnx2x_phy *phy,
7014                                      struct link_params *params,
7015                                      u32 action)
7016 {
7017         struct bnx2x *bp = params->bp;
7018         switch (action) {
7019         case PHY_INIT:
7020                 /* Enable LASI */
7021                 bnx2x_cl45_write(bp, phy,
7022                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2));
7023                 bnx2x_cl45_write(bp, phy,
7024                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
7025                 break;
7026         }
7027 }
7028
7029 static int bnx2x_8073_config_init(struct bnx2x_phy *phy,
7030                                   struct link_params *params,
7031                                   struct link_vars *vars)
7032 {
7033         struct bnx2x *bp = params->bp;
7034         u16 val = 0, tmp1;
7035         u8 gpio_port;
7036         DP(NETIF_MSG_LINK, "Init 8073\n");
7037
7038         if (CHIP_IS_E2(bp))
7039                 gpio_port = BP_PATH(bp);
7040         else
7041                 gpio_port = params->port;
7042         /* Restore normal power mode*/
7043         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7044                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
7045
7046         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
7047                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
7048
7049         bnx2x_8073_specific_func(phy, params, PHY_INIT);
7050         bnx2x_8073_set_pause_cl37(params, phy, vars);
7051
7052         bnx2x_cl45_read(bp, phy,
7053                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
7054
7055         bnx2x_cl45_read(bp, phy,
7056                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
7057
7058         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
7059
7060         /* Swap polarity if required - Must be done only in non-1G mode */
7061         if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
7062                 /* Configure the 8073 to swap _P and _N of the KR lines */
7063                 DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
7064                 /* 10G Rx/Tx and 1G Tx signal polarity swap */
7065                 bnx2x_cl45_read(bp, phy,
7066                                 MDIO_PMA_DEVAD,
7067                                 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
7068                 bnx2x_cl45_write(bp, phy,
7069                                  MDIO_PMA_DEVAD,
7070                                  MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
7071                                  (val | (3<<9)));
7072         }
7073
7074
7075         /* Enable CL37 BAM */
7076         if (REG_RD(bp, params->shmem_base +
7077                          offsetof(struct shmem_region, dev_info.
7078                                   port_hw_config[params->port].default_cfg)) &
7079             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
7080
7081                 bnx2x_cl45_read(bp, phy,
7082                                 MDIO_AN_DEVAD,
7083                                 MDIO_AN_REG_8073_BAM, &val);
7084                 bnx2x_cl45_write(bp, phy,
7085                                  MDIO_AN_DEVAD,
7086                                  MDIO_AN_REG_8073_BAM, val | 1);
7087                 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
7088         }
7089         if (params->loopback_mode == LOOPBACK_EXT) {
7090                 bnx2x_807x_force_10G(bp, phy);
7091                 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
7092                 return 0;
7093         } else {
7094                 bnx2x_cl45_write(bp, phy,
7095                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
7096         }
7097         if (phy->req_line_speed != SPEED_AUTO_NEG) {
7098                 if (phy->req_line_speed == SPEED_10000) {
7099                         val = (1<<7);
7100                 } else if (phy->req_line_speed ==  SPEED_2500) {
7101                         val = (1<<5);
7102                         /* Note that 2.5G works only when used with 1G
7103                          * advertisement
7104                          */
7105                 } else
7106                         val = (1<<5);
7107         } else {
7108                 val = 0;
7109                 if (phy->speed_cap_mask &
7110                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
7111                         val |= (1<<7);
7112
7113                 /* Note that 2.5G works only when used with 1G advertisement */
7114                 if (phy->speed_cap_mask &
7115                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
7116                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
7117                         val |= (1<<5);
7118                 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
7119         }
7120
7121         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
7122         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
7123
7124         if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
7125              (phy->req_line_speed == SPEED_AUTO_NEG)) ||
7126             (phy->req_line_speed == SPEED_2500)) {
7127                 u16 phy_ver;
7128                 /* Allow 2.5G for A1 and above */
7129                 bnx2x_cl45_read(bp, phy,
7130                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
7131                                 &phy_ver);
7132                 DP(NETIF_MSG_LINK, "Add 2.5G\n");
7133                 if (phy_ver > 0)
7134                         tmp1 |= 1;
7135                 else
7136                         tmp1 &= 0xfffe;
7137         } else {
7138                 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
7139                 tmp1 &= 0xfffe;
7140         }
7141
7142         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
7143         /* Add support for CL37 (passive mode) II */
7144
7145         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
7146         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
7147                          (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
7148                                   0x20 : 0x40)));
7149
7150         /* Add support for CL37 (passive mode) III */
7151         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
7152
7153         /* The SNR will improve about 2db by changing BW and FEE main
7154          * tap. Rest commands are executed after link is up
7155          * Change FFE main cursor to 5 in EDC register
7156          */
7157         if (bnx2x_8073_is_snr_needed(bp, phy))
7158                 bnx2x_cl45_write(bp, phy,
7159                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
7160                                  0xFB0C);
7161
7162         /* Enable FEC (Forware Error Correction) Request in the AN */
7163         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
7164         tmp1 |= (1<<15);
7165         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
7166
7167         bnx2x_ext_phy_set_pause(params, phy, vars);
7168
7169         /* Restart autoneg */
7170         msleep(500);
7171         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
7172         DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
7173                    ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
7174         return 0;
7175 }
7176
7177 static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
7178                                  struct link_params *params,
7179                                  struct link_vars *vars)
7180 {
7181         struct bnx2x *bp = params->bp;
7182         u8 link_up = 0;
7183         u16 val1, val2;
7184         u16 link_status = 0;
7185         u16 an1000_status = 0;
7186
7187         bnx2x_cl45_read(bp, phy,
7188                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
7189
7190         DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
7191
7192         /* Clear the interrupt LASI status register */
7193         bnx2x_cl45_read(bp, phy,
7194                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
7195         bnx2x_cl45_read(bp, phy,
7196                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
7197         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
7198         /* Clear MSG-OUT */
7199         bnx2x_cl45_read(bp, phy,
7200                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
7201
7202         /* Check the LASI */
7203         bnx2x_cl45_read(bp, phy,
7204                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
7205
7206         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
7207
7208         /* Check the link status */
7209         bnx2x_cl45_read(bp, phy,
7210                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
7211         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
7212
7213         bnx2x_cl45_read(bp, phy,
7214                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
7215         bnx2x_cl45_read(bp, phy,
7216                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
7217         link_up = ((val1 & 4) == 4);
7218         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
7219
7220         if (link_up &&
7221              ((phy->req_line_speed != SPEED_10000))) {
7222                 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
7223                         return 0;
7224         }
7225         bnx2x_cl45_read(bp, phy,
7226                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
7227         bnx2x_cl45_read(bp, phy,
7228                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
7229
7230         /* Check the link status on 1.1.2 */
7231         bnx2x_cl45_read(bp, phy,
7232                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
7233         bnx2x_cl45_read(bp, phy,
7234                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
7235         DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
7236                    "an_link_status=0x%x\n", val2, val1, an1000_status);
7237
7238         link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
7239         if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
7240                 /* The SNR will improve about 2dbby changing the BW and FEE main
7241                  * tap. The 1st write to change FFE main tap is set before
7242                  * restart AN. Change PLL Bandwidth in EDC register
7243                  */
7244                 bnx2x_cl45_write(bp, phy,
7245                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
7246                                  0x26BC);
7247
7248                 /* Change CDR Bandwidth in EDC register */
7249                 bnx2x_cl45_write(bp, phy,
7250                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
7251                                  0x0333);
7252         }
7253         bnx2x_cl45_read(bp, phy,
7254                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
7255                         &link_status);
7256
7257         /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
7258         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
7259                 link_up = 1;
7260                 vars->line_speed = SPEED_10000;
7261                 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
7262                            params->port);
7263         } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
7264                 link_up = 1;
7265                 vars->line_speed = SPEED_2500;
7266                 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
7267                            params->port);
7268         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
7269                 link_up = 1;
7270                 vars->line_speed = SPEED_1000;
7271                 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
7272                            params->port);
7273         } else {
7274                 link_up = 0;
7275                 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
7276                            params->port);
7277         }
7278
7279         if (link_up) {
7280                 /* Swap polarity if required */
7281                 if (params->lane_config &
7282                     PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
7283                         /* Configure the 8073 to swap P and N of the KR lines */
7284                         bnx2x_cl45_read(bp, phy,
7285                                         MDIO_XS_DEVAD,
7286                                         MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
7287                         /* Set bit 3 to invert Rx in 1G mode and clear this bit
7288                          * when it`s in 10G mode.
7289                          */
7290                         if (vars->line_speed == SPEED_1000) {
7291                                 DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
7292                                               "the 8073\n");
7293                                 val1 |= (1<<3);
7294                         } else
7295                                 val1 &= ~(1<<3);
7296
7297                         bnx2x_cl45_write(bp, phy,
7298                                          MDIO_XS_DEVAD,
7299                                          MDIO_XS_REG_8073_RX_CTRL_PCIE,
7300                                          val1);
7301                 }
7302                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
7303                 bnx2x_8073_resolve_fc(phy, params, vars);
7304                 vars->duplex = DUPLEX_FULL;
7305         }
7306
7307         if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
7308                 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
7309                                 MDIO_AN_REG_LP_AUTO_NEG2, &val1);
7310
7311                 if (val1 & (1<<5))
7312                         vars->link_status |=
7313                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
7314                 if (val1 & (1<<7))
7315                         vars->link_status |=
7316                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
7317         }
7318
7319         return link_up;
7320 }
7321
7322 static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
7323                                   struct link_params *params)
7324 {
7325         struct bnx2x *bp = params->bp;
7326         u8 gpio_port;
7327         if (CHIP_IS_E2(bp))
7328                 gpio_port = BP_PATH(bp);
7329         else
7330                 gpio_port = params->port;
7331         DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
7332            gpio_port);
7333         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7334                        MISC_REGISTERS_GPIO_OUTPUT_LOW,
7335                        gpio_port);
7336 }
7337
7338 /******************************************************************/
7339 /*                      BCM8705 PHY SECTION                       */
7340 /******************************************************************/
7341 static int bnx2x_8705_config_init(struct bnx2x_phy *phy,
7342                                   struct link_params *params,
7343                                   struct link_vars *vars)
7344 {
7345         struct bnx2x *bp = params->bp;
7346         DP(NETIF_MSG_LINK, "init 8705\n");
7347         /* Restore normal power mode*/
7348         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7349                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
7350         /* HW reset */
7351         bnx2x_ext_phy_hw_reset(bp, params->port);
7352         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
7353         bnx2x_wait_reset_complete(bp, phy, params);
7354
7355         bnx2x_cl45_write(bp, phy,
7356                          MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
7357         bnx2x_cl45_write(bp, phy,
7358                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
7359         bnx2x_cl45_write(bp, phy,
7360                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
7361         bnx2x_cl45_write(bp, phy,
7362                          MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
7363         /* BCM8705 doesn't have microcode, hence the 0 */
7364         bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
7365         return 0;
7366 }
7367
7368 static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
7369                                  struct link_params *params,
7370                                  struct link_vars *vars)
7371 {
7372         u8 link_up = 0;
7373         u16 val1, rx_sd;
7374         struct bnx2x *bp = params->bp;
7375         DP(NETIF_MSG_LINK, "read status 8705\n");
7376         bnx2x_cl45_read(bp, phy,
7377                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7378         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
7379
7380         bnx2x_cl45_read(bp, phy,
7381                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7382         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
7383
7384         bnx2x_cl45_read(bp, phy,
7385                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
7386
7387         bnx2x_cl45_read(bp, phy,
7388                       MDIO_PMA_DEVAD, 0xc809, &val1);
7389         bnx2x_cl45_read(bp, phy,
7390                       MDIO_PMA_DEVAD, 0xc809, &val1);
7391
7392         DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
7393         link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
7394         if (link_up) {
7395                 vars->line_speed = SPEED_10000;
7396                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
7397         }
7398         return link_up;
7399 }
7400
7401 /******************************************************************/
7402 /*                      SFP+ module Section                       */
7403 /******************************************************************/
7404 static void bnx2x_set_disable_pmd_transmit(struct link_params *params,
7405                                            struct bnx2x_phy *phy,
7406                                            u8 pmd_dis)
7407 {
7408         struct bnx2x *bp = params->bp;
7409         /* Disable transmitter only for bootcodes which can enable it afterwards
7410          * (for D3 link)
7411          */
7412         if (pmd_dis) {
7413                 if (params->feature_config_flags &
7414                      FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED)
7415                         DP(NETIF_MSG_LINK, "Disabling PMD transmitter\n");
7416                 else {
7417                         DP(NETIF_MSG_LINK, "NOT disabling PMD transmitter\n");
7418                         return;
7419                 }
7420         } else
7421                 DP(NETIF_MSG_LINK, "Enabling PMD transmitter\n");
7422         bnx2x_cl45_write(bp, phy,
7423                          MDIO_PMA_DEVAD,
7424                          MDIO_PMA_REG_TX_DISABLE, pmd_dis);
7425 }
7426
7427 static u8 bnx2x_get_gpio_port(struct link_params *params)
7428 {
7429         u8 gpio_port;
7430         u32 swap_val, swap_override;
7431         struct bnx2x *bp = params->bp;
7432         if (CHIP_IS_E2(bp))
7433                 gpio_port = BP_PATH(bp);
7434         else
7435                 gpio_port = params->port;
7436         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7437         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7438         return gpio_port ^ (swap_val && swap_override);
7439 }
7440
7441 static void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params,
7442                                            struct bnx2x_phy *phy,
7443                                            u8 tx_en)
7444 {
7445         u16 val;
7446         u8 port = params->port;
7447         struct bnx2x *bp = params->bp;
7448         u32 tx_en_mode;
7449
7450         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
7451         tx_en_mode = REG_RD(bp, params->shmem_base +
7452                             offsetof(struct shmem_region,
7453                                      dev_info.port_hw_config[port].sfp_ctrl)) &
7454                 PORT_HW_CFG_TX_LASER_MASK;
7455         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
7456                            "mode = %x\n", tx_en, port, tx_en_mode);
7457         switch (tx_en_mode) {
7458         case PORT_HW_CFG_TX_LASER_MDIO:
7459
7460                 bnx2x_cl45_read(bp, phy,
7461                                 MDIO_PMA_DEVAD,
7462                                 MDIO_PMA_REG_PHY_IDENTIFIER,
7463                                 &val);
7464
7465                 if (tx_en)
7466                         val &= ~(1<<15);
7467                 else
7468                         val |= (1<<15);
7469
7470                 bnx2x_cl45_write(bp, phy,
7471                                  MDIO_PMA_DEVAD,
7472                                  MDIO_PMA_REG_PHY_IDENTIFIER,
7473                                  val);
7474         break;
7475         case PORT_HW_CFG_TX_LASER_GPIO0:
7476         case PORT_HW_CFG_TX_LASER_GPIO1:
7477         case PORT_HW_CFG_TX_LASER_GPIO2:
7478         case PORT_HW_CFG_TX_LASER_GPIO3:
7479         {
7480                 u16 gpio_pin;
7481                 u8 gpio_port, gpio_mode;
7482                 if (tx_en)
7483                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
7484                 else
7485                         gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
7486
7487                 gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
7488                 gpio_port = bnx2x_get_gpio_port(params);
7489                 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
7490                 break;
7491         }
7492         default:
7493                 DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
7494                 break;
7495         }
7496 }
7497
7498 static void bnx2x_sfp_set_transmitter(struct link_params *params,
7499                                       struct bnx2x_phy *phy,
7500                                       u8 tx_en)
7501 {
7502         struct bnx2x *bp = params->bp;
7503         DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en);
7504         if (CHIP_IS_E3(bp))
7505                 bnx2x_sfp_e3_set_transmitter(params, phy, tx_en);
7506         else
7507                 bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en);
7508 }
7509
7510 static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7511                                              struct link_params *params,
7512                                              u16 addr, u8 byte_cnt, u8 *o_buf)
7513 {
7514         struct bnx2x *bp = params->bp;
7515         u16 val = 0;
7516         u16 i;
7517         if (byte_cnt > SFP_EEPROM_PAGE_SIZE) {
7518                 DP(NETIF_MSG_LINK,
7519                    "Reading from eeprom is limited to 0xf\n");
7520                 return -EINVAL;
7521         }
7522         /* Set the read command byte count */
7523         bnx2x_cl45_write(bp, phy,
7524                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7525                          (byte_cnt | 0xa000));
7526
7527         /* Set the read command address */
7528         bnx2x_cl45_write(bp, phy,
7529                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7530                          addr);
7531
7532         /* Activate read command */
7533         bnx2x_cl45_write(bp, phy,
7534                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7535                          0x2c0f);
7536
7537         /* Wait up to 500us for command complete status */
7538         for (i = 0; i < 100; i++) {
7539                 bnx2x_cl45_read(bp, phy,
7540                                 MDIO_PMA_DEVAD,
7541                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7542                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7543                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7544                         break;
7545                 udelay(5);
7546         }
7547
7548         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7549                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7550                 DP(NETIF_MSG_LINK,
7551                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7552                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7553                 return -EINVAL;
7554         }
7555
7556         /* Read the buffer */
7557         for (i = 0; i < byte_cnt; i++) {
7558                 bnx2x_cl45_read(bp, phy,
7559                                 MDIO_PMA_DEVAD,
7560                                 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
7561                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
7562         }
7563
7564         for (i = 0; i < 100; i++) {
7565                 bnx2x_cl45_read(bp, phy,
7566                                 MDIO_PMA_DEVAD,
7567                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7568                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7569                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
7570                         return 0;
7571                  usleep_range(1000, 2000);
7572         }
7573         return -EINVAL;
7574 }
7575
7576 static void bnx2x_warpcore_power_module(struct link_params *params,
7577                                         struct bnx2x_phy *phy,
7578                                         u8 power)
7579 {
7580         u32 pin_cfg;
7581         struct bnx2x *bp = params->bp;
7582
7583         pin_cfg = (REG_RD(bp, params->shmem_base +
7584                           offsetof(struct shmem_region,
7585                         dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
7586                         PORT_HW_CFG_E3_PWR_DIS_MASK) >>
7587                         PORT_HW_CFG_E3_PWR_DIS_SHIFT;
7588
7589         if (pin_cfg == PIN_CFG_NA)
7590                 return;
7591         DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
7592                        power, pin_cfg);
7593         /* Low ==> corresponding SFP+ module is powered
7594          * high ==> the SFP+ module is powered down
7595          */
7596         bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
7597 }
7598 static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7599                                                  struct link_params *params,
7600                                                  u16 addr, u8 byte_cnt,
7601                                                  u8 *o_buf)
7602 {
7603         int rc = 0;
7604         u8 i, j = 0, cnt = 0;
7605         u32 data_array[4];
7606         u16 addr32;
7607         struct bnx2x *bp = params->bp;
7608
7609         if (byte_cnt > SFP_EEPROM_PAGE_SIZE) {
7610                 DP(NETIF_MSG_LINK,
7611                    "Reading from eeprom is limited to 16 bytes\n");
7612                 return -EINVAL;
7613         }
7614
7615         /* 4 byte aligned address */
7616         addr32 = addr & (~0x3);
7617         do {
7618                 if (cnt == I2C_WA_PWR_ITER) {
7619                         bnx2x_warpcore_power_module(params, phy, 0);
7620                         /* Note that 100us are not enough here */
7621                         usleep_range(1000,1000);
7622                         bnx2x_warpcore_power_module(params, phy, 1);
7623                 }
7624                 rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
7625                                     data_array);
7626         } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT));
7627
7628         if (rc == 0) {
7629                 for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
7630                         o_buf[j] = *((u8 *)data_array + i);
7631                         j++;
7632                 }
7633         }
7634
7635         return rc;
7636 }
7637
7638 static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7639                                              struct link_params *params,
7640                                              u16 addr, u8 byte_cnt, u8 *o_buf)
7641 {
7642         struct bnx2x *bp = params->bp;
7643         u16 val, i;
7644
7645         if (byte_cnt > SFP_EEPROM_PAGE_SIZE) {
7646                 DP(NETIF_MSG_LINK,
7647                    "Reading from eeprom is limited to 0xf\n");
7648                 return -EINVAL;
7649         }
7650
7651         /* Need to read from 1.8000 to clear it */
7652         bnx2x_cl45_read(bp, phy,
7653                         MDIO_PMA_DEVAD,
7654                         MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7655                         &val);
7656
7657         /* Set the read command byte count */
7658         bnx2x_cl45_write(bp, phy,
7659                          MDIO_PMA_DEVAD,
7660                          MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7661                          ((byte_cnt < 2) ? 2 : byte_cnt));
7662
7663         /* Set the read command address */
7664         bnx2x_cl45_write(bp, phy,
7665                          MDIO_PMA_DEVAD,
7666                          MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7667                          addr);
7668         /* Set the destination address */
7669         bnx2x_cl45_write(bp, phy,
7670                          MDIO_PMA_DEVAD,
7671                          0x8004,
7672                          MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
7673
7674         /* Activate read command */
7675         bnx2x_cl45_write(bp, phy,
7676                          MDIO_PMA_DEVAD,
7677                          MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7678                          0x8002);
7679         /* Wait appropriate time for two-wire command to finish before
7680          * polling the status register
7681          */
7682          usleep_range(1000, 2000);
7683
7684         /* Wait up to 500us for command complete status */
7685         for (i = 0; i < 100; i++) {
7686                 bnx2x_cl45_read(bp, phy,
7687                                 MDIO_PMA_DEVAD,
7688                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7689                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7690                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7691                         break;
7692                 udelay(5);
7693         }
7694
7695         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7696                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7697                 DP(NETIF_MSG_LINK,
7698                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7699                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7700                 return -EFAULT;
7701         }
7702
7703         /* Read the buffer */
7704         for (i = 0; i < byte_cnt; i++) {
7705                 bnx2x_cl45_read(bp, phy,
7706                                 MDIO_PMA_DEVAD,
7707                                 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
7708                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
7709         }
7710
7711         for (i = 0; i < 100; i++) {
7712                 bnx2x_cl45_read(bp, phy,
7713                                 MDIO_PMA_DEVAD,
7714                                 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7715                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7716                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
7717                         return 0;
7718                  usleep_range(1000, 2000);
7719         }
7720
7721         return -EINVAL;
7722 }
7723
7724 int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7725                                  struct link_params *params, u16 addr,
7726                                  u8 byte_cnt, u8 *o_buf)
7727 {
7728         int rc = -EOPNOTSUPP;
7729         switch (phy->type) {
7730         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7731                 rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
7732                                                        byte_cnt, o_buf);
7733         break;
7734         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7735         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7736                 rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
7737                                                        byte_cnt, o_buf);
7738         break;
7739         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
7740                 rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
7741                                                            byte_cnt, o_buf);
7742         break;
7743         }
7744         return rc;
7745 }
7746
7747 static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
7748                               struct link_params *params,
7749                               u16 *edc_mode)
7750 {
7751         struct bnx2x *bp = params->bp;
7752         u32 sync_offset = 0, phy_idx, media_types;
7753         u8 val[2], check_limiting_mode = 0;
7754         *edc_mode = EDC_MODE_LIMITING;
7755
7756         phy->media_type = ETH_PHY_UNSPECIFIED;
7757         /* First check for copper cable */
7758         if (bnx2x_read_sfp_module_eeprom(phy,
7759                                          params,
7760                                          SFP_EEPROM_CON_TYPE_ADDR,
7761                                          2,
7762                                          (u8 *)val) != 0) {
7763                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
7764                 return -EINVAL;
7765         }
7766
7767         switch (val[0]) {
7768         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
7769         {
7770                 u8 copper_module_type;
7771                 phy->media_type = ETH_PHY_DA_TWINAX;
7772                 /* Check if its active cable (includes SFP+ module)
7773                  * of passive cable
7774                  */
7775                 if (bnx2x_read_sfp_module_eeprom(phy,
7776                                                params,
7777                                                SFP_EEPROM_FC_TX_TECH_ADDR,
7778                                                1,
7779                                                &copper_module_type) != 0) {
7780                         DP(NETIF_MSG_LINK,
7781                                 "Failed to read copper-cable-type"
7782                                 " from SFP+ EEPROM\n");
7783                         return -EINVAL;
7784                 }
7785
7786                 if (copper_module_type &
7787                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
7788                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
7789                         check_limiting_mode = 1;
7790                 } else if (copper_module_type &
7791                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
7792                                 DP(NETIF_MSG_LINK,
7793                                    "Passive Copper cable detected\n");
7794                                 *edc_mode =
7795                                       EDC_MODE_PASSIVE_DAC;
7796                 } else {
7797                         DP(NETIF_MSG_LINK,
7798                            "Unknown copper-cable-type 0x%x !!!\n",
7799                            copper_module_type);
7800                         return -EINVAL;
7801                 }
7802                 break;
7803         }
7804         case SFP_EEPROM_CON_TYPE_VAL_LC:
7805                 check_limiting_mode = 1;
7806                 if ((val[1] & (SFP_EEPROM_COMP_CODE_SR_MASK |
7807                                SFP_EEPROM_COMP_CODE_LR_MASK |
7808                                SFP_EEPROM_COMP_CODE_LRM_MASK)) == 0) {
7809                         DP(NETIF_MSG_LINK, "1G Optic module detected\n");
7810                         phy->media_type = ETH_PHY_SFP_1G_FIBER;
7811                         phy->req_line_speed = SPEED_1000;
7812                 } else {
7813                         int idx, cfg_idx = 0;
7814                         DP(NETIF_MSG_LINK, "10G Optic module detected\n");
7815                         for (idx = INT_PHY; idx < MAX_PHYS; idx++) {
7816                                 if (params->phy[idx].type == phy->type) {
7817                                         cfg_idx = LINK_CONFIG_IDX(idx);
7818                                         break;
7819                                 }
7820                         }
7821                         phy->media_type = ETH_PHY_SFPP_10G_FIBER;
7822                         phy->req_line_speed = params->req_line_speed[cfg_idx];
7823                 }
7824                 break;
7825         default:
7826                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
7827                          val[0]);
7828                 return -EINVAL;
7829         }
7830         sync_offset = params->shmem_base +
7831                 offsetof(struct shmem_region,
7832                          dev_info.port_hw_config[params->port].media_type);
7833         media_types = REG_RD(bp, sync_offset);
7834         /* Update media type for non-PMF sync */
7835         for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
7836                 if (&(params->phy[phy_idx]) == phy) {
7837                         media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
7838                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
7839                         media_types |= ((phy->media_type &
7840                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
7841                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
7842                         break;
7843                 }
7844         }
7845         REG_WR(bp, sync_offset, media_types);
7846         if (check_limiting_mode) {
7847                 u8 options[SFP_EEPROM_OPTIONS_SIZE];
7848                 if (bnx2x_read_sfp_module_eeprom(phy,
7849                                                  params,
7850                                                  SFP_EEPROM_OPTIONS_ADDR,
7851                                                  SFP_EEPROM_OPTIONS_SIZE,
7852                                                  options) != 0) {
7853                         DP(NETIF_MSG_LINK,
7854                            "Failed to read Option field from module EEPROM\n");
7855                         return -EINVAL;
7856                 }
7857                 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
7858                         *edc_mode = EDC_MODE_LINEAR;
7859                 else
7860                         *edc_mode = EDC_MODE_LIMITING;
7861         }
7862         DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
7863         return 0;
7864 }
7865 /* This function read the relevant field from the module (SFP+), and verify it
7866  * is compliant with this board
7867  */
7868 static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
7869                                    struct link_params *params)
7870 {
7871         struct bnx2x *bp = params->bp;
7872         u32 val, cmd;
7873         u32 fw_resp, fw_cmd_param;
7874         char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
7875         char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
7876         phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
7877         val = REG_RD(bp, params->shmem_base +
7878                          offsetof(struct shmem_region, dev_info.
7879                                   port_feature_config[params->port].config));
7880         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
7881             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
7882                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
7883                 return 0;
7884         }
7885
7886         if (params->feature_config_flags &
7887             FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
7888                 /* Use specific phy request */
7889                 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
7890         } else if (params->feature_config_flags &
7891                    FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
7892                 /* Use first phy request only in case of non-dual media*/
7893                 if (DUAL_MEDIA(params)) {
7894                         DP(NETIF_MSG_LINK,
7895                            "FW does not support OPT MDL verification\n");
7896                         return -EINVAL;
7897                 }
7898                 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
7899         } else {
7900                 /* No support in OPT MDL detection */
7901                 DP(NETIF_MSG_LINK,
7902                    "FW does not support OPT MDL verification\n");
7903                 return -EINVAL;
7904         }
7905
7906         fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
7907         fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
7908         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
7909                 DP(NETIF_MSG_LINK, "Approved module\n");
7910                 return 0;
7911         }
7912
7913         /* Format the warning message */
7914         if (bnx2x_read_sfp_module_eeprom(phy,
7915                                          params,
7916                                          SFP_EEPROM_VENDOR_NAME_ADDR,
7917                                          SFP_EEPROM_VENDOR_NAME_SIZE,
7918                                          (u8 *)vendor_name))
7919                 vendor_name[0] = '\0';
7920         else
7921                 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
7922         if (bnx2x_read_sfp_module_eeprom(phy,
7923                                          params,
7924                                          SFP_EEPROM_PART_NO_ADDR,
7925                                          SFP_EEPROM_PART_NO_SIZE,
7926                                          (u8 *)vendor_pn))
7927                 vendor_pn[0] = '\0';
7928         else
7929                 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
7930
7931         netdev_err(bp->dev,  "Warning: Unqualified SFP+ module detected,"
7932                               " Port %d from %s part number %s\n",
7933                          params->port, vendor_name, vendor_pn);
7934         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
7935             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG)
7936                 phy->flags |= FLAGS_SFP_NOT_APPROVED;
7937         return -EINVAL;
7938 }
7939
7940 static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
7941                                                  struct link_params *params)
7942
7943 {
7944         u8 val;
7945         struct bnx2x *bp = params->bp;
7946         u16 timeout;
7947         /* Initialization time after hot-plug may take up to 300ms for
7948          * some phys type ( e.g. JDSU )
7949          */
7950
7951         for (timeout = 0; timeout < 60; timeout++) {
7952                 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
7953                     == 0) {
7954                         DP(NETIF_MSG_LINK,
7955                            "SFP+ module initialization took %d ms\n",
7956                            timeout * 5);
7957                         return 0;
7958                 }
7959                 usleep_range(5000, 10000);
7960         }
7961         return -EINVAL;
7962 }
7963
7964 static void bnx2x_8727_power_module(struct bnx2x *bp,
7965                                     struct bnx2x_phy *phy,
7966                                     u8 is_power_up) {
7967         /* Make sure GPIOs are not using for LED mode */
7968         u16 val;
7969         /* In the GPIO register, bit 4 is use to determine if the GPIOs are
7970          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
7971          * output
7972          * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
7973          * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
7974          * where the 1st bit is the over-current(only input), and 2nd bit is
7975          * for power( only output )
7976          *
7977          * In case of NOC feature is disabled and power is up, set GPIO control
7978          *  as input to enable listening of over-current indication
7979          */
7980         if (phy->flags & FLAGS_NOC)
7981                 return;
7982         if (is_power_up)
7983                 val = (1<<4);
7984         else
7985                 /* Set GPIO control to OUTPUT, and set the power bit
7986                  * to according to the is_power_up
7987                  */
7988                 val = (1<<1);
7989
7990         bnx2x_cl45_write(bp, phy,
7991                          MDIO_PMA_DEVAD,
7992                          MDIO_PMA_REG_8727_GPIO_CTRL,
7993                          val);
7994 }
7995
7996 static int bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
7997                                         struct bnx2x_phy *phy,
7998                                         u16 edc_mode)
7999 {
8000         u16 cur_limiting_mode;
8001
8002         bnx2x_cl45_read(bp, phy,
8003                         MDIO_PMA_DEVAD,
8004                         MDIO_PMA_REG_ROM_VER2,
8005                         &cur_limiting_mode);
8006         DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
8007                  cur_limiting_mode);
8008
8009         if (edc_mode == EDC_MODE_LIMITING) {
8010                 DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n");
8011                 bnx2x_cl45_write(bp, phy,
8012                                  MDIO_PMA_DEVAD,
8013                                  MDIO_PMA_REG_ROM_VER2,
8014                                  EDC_MODE_LIMITING);
8015         } else { /* LRM mode ( default )*/
8016
8017                 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
8018
8019                 /* Changing to LRM mode takes quite few seconds. So do it only
8020                  * if current mode is limiting (default is LRM)
8021                  */
8022                 if (cur_limiting_mode != EDC_MODE_LIMITING)
8023                         return 0;
8024
8025                 bnx2x_cl45_write(bp, phy,
8026                                  MDIO_PMA_DEVAD,
8027                                  MDIO_PMA_REG_LRM_MODE,
8028                                  0);
8029                 bnx2x_cl45_write(bp, phy,
8030                                  MDIO_PMA_DEVAD,
8031                                  MDIO_PMA_REG_ROM_VER2,
8032                                  0x128);
8033                 bnx2x_cl45_write(bp, phy,
8034                                  MDIO_PMA_DEVAD,
8035                                  MDIO_PMA_REG_MISC_CTRL0,
8036                                  0x4008);
8037                 bnx2x_cl45_write(bp, phy,
8038                                  MDIO_PMA_DEVAD,
8039                                  MDIO_PMA_REG_LRM_MODE,
8040                                  0xaaaa);
8041         }
8042         return 0;
8043 }
8044
8045 static int bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
8046                                         struct bnx2x_phy *phy,
8047                                         u16 edc_mode)
8048 {
8049         u16 phy_identifier;
8050         u16 rom_ver2_val;
8051         bnx2x_cl45_read(bp, phy,
8052                         MDIO_PMA_DEVAD,
8053                         MDIO_PMA_REG_PHY_IDENTIFIER,
8054                         &phy_identifier);
8055
8056         bnx2x_cl45_write(bp, phy,
8057                          MDIO_PMA_DEVAD,
8058                          MDIO_PMA_REG_PHY_IDENTIFIER,
8059                          (phy_identifier & ~(1<<9)));
8060
8061         bnx2x_cl45_read(bp, phy,
8062                         MDIO_PMA_DEVAD,
8063                         MDIO_PMA_REG_ROM_VER2,
8064                         &rom_ver2_val);
8065         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
8066         bnx2x_cl45_write(bp, phy,
8067                          MDIO_PMA_DEVAD,
8068                          MDIO_PMA_REG_ROM_VER2,
8069                          (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
8070
8071         bnx2x_cl45_write(bp, phy,
8072                          MDIO_PMA_DEVAD,
8073                          MDIO_PMA_REG_PHY_IDENTIFIER,
8074                          (phy_identifier | (1<<9)));
8075
8076         return 0;
8077 }
8078
8079 static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
8080                                      struct link_params *params,
8081                                      u32 action)
8082 {
8083         struct bnx2x *bp = params->bp;
8084         u16 val;
8085         switch (action) {
8086         case DISABLE_TX:
8087                 bnx2x_sfp_set_transmitter(params, phy, 0);
8088                 break;
8089         case ENABLE_TX:
8090                 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
8091                         bnx2x_sfp_set_transmitter(params, phy, 1);
8092                 break;
8093         case PHY_INIT:
8094                 bnx2x_cl45_write(bp, phy,
8095                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8096                                  (1<<2) | (1<<5));
8097                 bnx2x_cl45_write(bp, phy,
8098                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
8099                                  0);
8100                 bnx2x_cl45_write(bp, phy,
8101                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x0006);
8102                 /* Make MOD_ABS give interrupt on change */
8103                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8104                                 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8105                                 &val);
8106                 val |= (1<<12);
8107                 if (phy->flags & FLAGS_NOC)
8108                         val |= (3<<5);
8109                 /* Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
8110                  * status which reflect SFP+ module over-current
8111                  */
8112                 if (!(phy->flags & FLAGS_NOC))
8113                         val &= 0xff8f; /* Reset bits 4-6 */
8114                 bnx2x_cl45_write(bp, phy,
8115                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8116                                  val);
8117
8118                 /* Set 2-wire transfer rate of SFP+ module EEPROM
8119                  * to 100Khz since some DACs(direct attached cables) do
8120                  * not work at 400Khz.
8121                  */
8122                 bnx2x_cl45_write(bp, phy,
8123                                  MDIO_PMA_DEVAD,
8124                                  MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
8125                                  0xa001);
8126                 break;
8127         default:
8128                 DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
8129                    action);
8130                 return;
8131         }
8132 }
8133
8134 static void bnx2x_set_e1e2_module_fault_led(struct link_params *params,
8135                                            u8 gpio_mode)
8136 {
8137         struct bnx2x *bp = params->bp;
8138
8139         u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
8140                             offsetof(struct shmem_region,
8141                         dev_info.port_hw_config[params->port].sfp_ctrl)) &
8142                 PORT_HW_CFG_FAULT_MODULE_LED_MASK;
8143         switch (fault_led_gpio) {
8144         case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
8145                 return;
8146         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
8147         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
8148         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
8149         case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
8150         {
8151                 u8 gpio_port = bnx2x_get_gpio_port(params);
8152                 u16 gpio_pin = fault_led_gpio -
8153                         PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
8154                 DP(NETIF_MSG_LINK, "Set fault module-detected led "
8155                                    "pin %x port %x mode %x\n",
8156                                gpio_pin, gpio_port, gpio_mode);
8157                 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
8158         }
8159         break;
8160         default:
8161                 DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
8162                                fault_led_gpio);
8163         }
8164 }
8165
8166 static void bnx2x_set_e3_module_fault_led(struct link_params *params,
8167                                           u8 gpio_mode)
8168 {
8169         u32 pin_cfg;
8170         u8 port = params->port;
8171         struct bnx2x *bp = params->bp;
8172         pin_cfg = (REG_RD(bp, params->shmem_base +
8173                          offsetof(struct shmem_region,
8174                                   dev_info.port_hw_config[port].e3_sfp_ctrl)) &
8175                 PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
8176                 PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
8177         DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n",
8178                        gpio_mode, pin_cfg);
8179         bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode);
8180 }
8181
8182 static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
8183                                            u8 gpio_mode)
8184 {
8185         struct bnx2x *bp = params->bp;
8186         DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode);
8187         if (CHIP_IS_E3(bp)) {
8188                 /* Low ==> if SFP+ module is supported otherwise
8189                  * High ==> if SFP+ module is not on the approved vendor list
8190                  */
8191                 bnx2x_set_e3_module_fault_led(params, gpio_mode);
8192         } else
8193                 bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
8194 }
8195
8196 static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy,
8197                                     struct link_params *params)
8198 {
8199         struct bnx2x *bp = params->bp;
8200         bnx2x_warpcore_power_module(params, phy, 0);
8201         /* Put Warpcore in low power mode */
8202         REG_WR(bp, MISC_REG_WC0_RESET, 0x0c0e);
8203
8204         /* Put LCPLL in low power mode */
8205         REG_WR(bp, MISC_REG_LCPLL_E40_PWRDWN, 1);
8206         REG_WR(bp, MISC_REG_LCPLL_E40_RESETB_ANA, 0);
8207         REG_WR(bp, MISC_REG_LCPLL_E40_RESETB_DIG, 0);
8208 }
8209
8210 static void bnx2x_power_sfp_module(struct link_params *params,
8211                                    struct bnx2x_phy *phy,
8212                                    u8 power)
8213 {
8214         struct bnx2x *bp = params->bp;
8215         DP(NETIF_MSG_LINK, "Setting SFP+ power to %x\n", power);
8216
8217         switch (phy->type) {
8218         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8219         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8220                 bnx2x_8727_power_module(params->bp, phy, power);
8221                 break;
8222         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
8223                 bnx2x_warpcore_power_module(params, phy, power);
8224                 break;
8225         default:
8226                 break;
8227         }
8228 }
8229 static void bnx2x_warpcore_set_limiting_mode(struct link_params *params,
8230                                              struct bnx2x_phy *phy,
8231                                              u16 edc_mode)
8232 {
8233         u16 val = 0;
8234         u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
8235         struct bnx2x *bp = params->bp;
8236
8237         u8 lane = bnx2x_get_warpcore_lane(phy, params);
8238         /* This is a global register which controls all lanes */
8239         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
8240                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
8241         val &= ~(0xf << (lane << 2));
8242
8243         switch (edc_mode) {
8244         case EDC_MODE_LINEAR:
8245         case EDC_MODE_LIMITING:
8246                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
8247                 break;
8248         case EDC_MODE_PASSIVE_DAC:
8249                 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
8250                 break;
8251         default:
8252                 break;
8253         }
8254
8255         val |= (mode << (lane << 2));
8256         bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
8257                          MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
8258         /* A must read */
8259         bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
8260                         MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
8261
8262         /* Restart microcode to re-read the new mode */
8263         bnx2x_warpcore_reset_lane(bp, phy, 1);
8264         bnx2x_warpcore_reset_lane(bp, phy, 0);
8265
8266 }
8267
8268 static void bnx2x_set_limiting_mode(struct link_params *params,
8269                                     struct bnx2x_phy *phy,
8270                                     u16 edc_mode)
8271 {
8272         switch (phy->type) {
8273         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
8274                 bnx2x_8726_set_limiting_mode(params->bp, phy, edc_mode);
8275                 break;
8276         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8277         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8278                 bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode);
8279                 break;
8280         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
8281                 bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode);
8282                 break;
8283         }
8284 }
8285
8286 int bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
8287                                struct link_params *params)
8288 {
8289         struct bnx2x *bp = params->bp;
8290         u16 edc_mode;
8291         int rc = 0;
8292
8293         u32 val = REG_RD(bp, params->shmem_base +
8294                              offsetof(struct shmem_region, dev_info.
8295                                      port_feature_config[params->port].config));
8296
8297         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
8298                  params->port);
8299         /* Power up module */
8300         bnx2x_power_sfp_module(params, phy, 1);
8301         if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
8302                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
8303                 return -EINVAL;
8304         } else if (bnx2x_verify_sfp_module(phy, params) != 0) {
8305                 /* Check SFP+ module compatibility */
8306                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
8307                 rc = -EINVAL;
8308                 /* Turn on fault module-detected led */
8309                 bnx2x_set_sfp_module_fault_led(params,
8310                                                MISC_REGISTERS_GPIO_HIGH);
8311
8312                 /* Check if need to power down the SFP+ module */
8313                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8314                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
8315                         DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
8316                         bnx2x_power_sfp_module(params, phy, 0);
8317                         return rc;
8318                 }
8319         } else {
8320                 /* Turn off fault module-detected led */
8321                 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
8322         }
8323
8324         /* Check and set limiting mode / LRM mode on 8726. On 8727 it
8325          * is done automatically
8326          */
8327         bnx2x_set_limiting_mode(params, phy, edc_mode);
8328
8329         /* Enable transmit for this module if the module is approved, or
8330          * if unapproved modules should also enable the Tx laser
8331          */
8332         if (rc == 0 ||
8333             (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
8334             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
8335                 bnx2x_sfp_set_transmitter(params, phy, 1);
8336         else
8337                 bnx2x_sfp_set_transmitter(params, phy, 0);
8338
8339         return rc;
8340 }
8341
8342 void bnx2x_handle_module_detect_int(struct link_params *params)
8343 {
8344         struct bnx2x *bp = params->bp;
8345         struct bnx2x_phy *phy;
8346         u32 gpio_val;
8347         u8 gpio_num, gpio_port;
8348         if (CHIP_IS_E3(bp))
8349                 phy = &params->phy[INT_PHY];
8350         else
8351                 phy = &params->phy[EXT_PHY1];
8352
8353         if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base,
8354                                       params->port, &gpio_num, &gpio_port) ==
8355             -EINVAL) {
8356                 DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n");
8357                 return;
8358         }
8359
8360         /* Set valid module led off */
8361         bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
8362
8363         /* Get current gpio val reflecting module plugged in / out*/
8364         gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
8365
8366         /* Call the handling function in case module is detected */
8367         if (gpio_val == 0) {
8368                 bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
8369                 bnx2x_set_aer_mmd(params, phy);
8370
8371                 bnx2x_power_sfp_module(params, phy, 1);
8372                 bnx2x_set_gpio_int(bp, gpio_num,
8373                                    MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
8374                                    gpio_port);
8375                 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) {
8376                         bnx2x_sfp_module_detection(phy, params);
8377                         if (CHIP_IS_E3(bp)) {
8378                                 u16 rx_tx_in_reset;
8379                                 /* In case WC is out of reset, reconfigure the
8380                                  * link speed while taking into account 1G
8381                                  * module limitation.
8382                                  */
8383                                 bnx2x_cl45_read(bp, phy,
8384                                                 MDIO_WC_DEVAD,
8385                                                 MDIO_WC_REG_DIGITAL5_MISC6,
8386                                                 &rx_tx_in_reset);
8387                                 if (!rx_tx_in_reset) {
8388                                         bnx2x_warpcore_reset_lane(bp, phy, 1);
8389                                         bnx2x_warpcore_config_sfi(phy, params);
8390                                         bnx2x_warpcore_reset_lane(bp, phy, 0);
8391                                 }
8392                         }
8393                 } else {
8394                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
8395                 }
8396         } else {
8397                 u32 val = REG_RD(bp, params->shmem_base +
8398                                  offsetof(struct shmem_region, dev_info.
8399                                           port_feature_config[params->port].
8400                                           config));
8401                 bnx2x_set_gpio_int(bp, gpio_num,
8402                                    MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
8403                                    gpio_port);
8404                 /* Module was plugged out.
8405                  * Disable transmit for this module
8406                  */
8407                 phy->media_type = ETH_PHY_NOT_PRESENT;
8408                 if (((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8409                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) ||
8410                     CHIP_IS_E3(bp))
8411                         bnx2x_sfp_set_transmitter(params, phy, 0);
8412         }
8413 }
8414
8415 /******************************************************************/
8416 /*              Used by 8706 and 8727                             */
8417 /******************************************************************/
8418 static void bnx2x_sfp_mask_fault(struct bnx2x *bp,
8419                                  struct bnx2x_phy *phy,
8420                                  u16 alarm_status_offset,
8421                                  u16 alarm_ctrl_offset)
8422 {
8423         u16 alarm_status, val;
8424         bnx2x_cl45_read(bp, phy,
8425                         MDIO_PMA_DEVAD, alarm_status_offset,
8426                         &alarm_status);
8427         bnx2x_cl45_read(bp, phy,
8428                         MDIO_PMA_DEVAD, alarm_status_offset,
8429                         &alarm_status);
8430         /* Mask or enable the fault event. */
8431         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
8432         if (alarm_status & (1<<0))
8433                 val &= ~(1<<0);
8434         else
8435                 val |= (1<<0);
8436         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
8437 }
8438 /******************************************************************/
8439 /*              common BCM8706/BCM8726 PHY SECTION                */
8440 /******************************************************************/
8441 static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
8442                                       struct link_params *params,
8443                                       struct link_vars *vars)
8444 {
8445         u8 link_up = 0;
8446         u16 val1, val2, rx_sd, pcs_status;
8447         struct bnx2x *bp = params->bp;
8448         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
8449         /* Clear RX Alarm*/
8450         bnx2x_cl45_read(bp, phy,
8451                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
8452
8453         bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
8454                              MDIO_PMA_LASI_TXCTRL);
8455
8456         /* Clear LASI indication*/
8457         bnx2x_cl45_read(bp, phy,
8458                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8459         bnx2x_cl45_read(bp, phy,
8460                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
8461         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
8462
8463         bnx2x_cl45_read(bp, phy,
8464                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8465         bnx2x_cl45_read(bp, phy,
8466                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
8467         bnx2x_cl45_read(bp, phy,
8468                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8469         bnx2x_cl45_read(bp, phy,
8470                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8471
8472         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
8473                         " link_status 0x%x\n", rx_sd, pcs_status, val2);
8474         /* Link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
8475          * are set, or if the autoneg bit 1 is set
8476          */
8477         link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
8478         if (link_up) {
8479                 if (val2 & (1<<1))
8480                         vars->line_speed = SPEED_1000;
8481                 else
8482                         vars->line_speed = SPEED_10000;
8483                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
8484                 vars->duplex = DUPLEX_FULL;
8485         }
8486
8487         /* Capture 10G link fault. Read twice to clear stale value. */
8488         if (vars->line_speed == SPEED_10000) {
8489                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8490                             MDIO_PMA_LASI_TXSTAT, &val1);
8491                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8492                             MDIO_PMA_LASI_TXSTAT, &val1);
8493                 if (val1 & (1<<0))
8494                         vars->fault_detected = 1;
8495         }
8496
8497         return link_up;
8498 }
8499
8500 /******************************************************************/
8501 /*                      BCM8706 PHY SECTION                       */
8502 /******************************************************************/
8503 static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
8504                                  struct link_params *params,
8505                                  struct link_vars *vars)
8506 {
8507         u32 tx_en_mode;
8508         u16 cnt, val, tmp1;
8509         struct bnx2x *bp = params->bp;
8510
8511         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
8512                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8513         /* HW reset */
8514         bnx2x_ext_phy_hw_reset(bp, params->port);
8515         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
8516         bnx2x_wait_reset_complete(bp, phy, params);
8517
8518         /* Wait until fw is loaded */
8519         for (cnt = 0; cnt < 100; cnt++) {
8520                 bnx2x_cl45_read(bp, phy,
8521                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
8522                 if (val)
8523                         break;
8524                 usleep_range(10000, 20000);
8525         }
8526         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
8527         if ((params->feature_config_flags &
8528              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8529                 u8 i;
8530                 u16 reg;
8531                 for (i = 0; i < 4; i++) {
8532                         reg = MDIO_XS_8706_REG_BANK_RX0 +
8533                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
8534                                    MDIO_XS_8706_REG_BANK_RX0);
8535                         bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
8536                         /* Clear first 3 bits of the control */
8537                         val &= ~0x7;
8538                         /* Set control bits according to configuration */
8539                         val |= (phy->rx_preemphasis[i] & 0x7);
8540                         DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
8541                                    " reg 0x%x <-- val 0x%x\n", reg, val);
8542                         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
8543                 }
8544         }
8545         /* Force speed */
8546         if (phy->req_line_speed == SPEED_10000) {
8547                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
8548
8549                 bnx2x_cl45_write(bp, phy,
8550                                  MDIO_PMA_DEVAD,
8551                                  MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
8552                 bnx2x_cl45_write(bp, phy,
8553                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
8554                                  0);
8555                 /* Arm LASI for link and Tx fault. */
8556                 bnx2x_cl45_write(bp, phy,
8557                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
8558         } else {
8559                 /* Force 1Gbps using autoneg with 1G advertisement */
8560
8561                 /* Allow CL37 through CL73 */
8562                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
8563                 bnx2x_cl45_write(bp, phy,
8564                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8565
8566                 /* Enable Full-Duplex advertisement on CL37 */
8567                 bnx2x_cl45_write(bp, phy,
8568                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
8569                 /* Enable CL37 AN */
8570                 bnx2x_cl45_write(bp, phy,
8571                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8572                 /* 1G support */
8573                 bnx2x_cl45_write(bp, phy,
8574                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
8575
8576                 /* Enable clause 73 AN */
8577                 bnx2x_cl45_write(bp, phy,
8578                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8579                 bnx2x_cl45_write(bp, phy,
8580                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8581                                  0x0400);
8582                 bnx2x_cl45_write(bp, phy,
8583                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
8584                                  0x0004);
8585         }
8586         bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8587
8588         /* If TX Laser is controlled by GPIO_0, do not let PHY go into low
8589          * power mode, if TX Laser is disabled
8590          */
8591
8592         tx_en_mode = REG_RD(bp, params->shmem_base +
8593                             offsetof(struct shmem_region,
8594                                 dev_info.port_hw_config[params->port].sfp_ctrl))
8595                         & PORT_HW_CFG_TX_LASER_MASK;
8596
8597         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
8598                 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
8599                 bnx2x_cl45_read(bp, phy,
8600                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
8601                 tmp1 |= 0x1;
8602                 bnx2x_cl45_write(bp, phy,
8603                         MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
8604         }
8605
8606         return 0;
8607 }
8608
8609 static int bnx2x_8706_read_status(struct bnx2x_phy *phy,
8610                                   struct link_params *params,
8611                                   struct link_vars *vars)
8612 {
8613         return bnx2x_8706_8726_read_status(phy, params, vars);
8614 }
8615
8616 /******************************************************************/
8617 /*                      BCM8726 PHY SECTION                       */
8618 /******************************************************************/
8619 static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
8620                                        struct link_params *params)
8621 {
8622         struct bnx2x *bp = params->bp;
8623         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
8624         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
8625 }
8626
8627 static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
8628                                          struct link_params *params)
8629 {
8630         struct bnx2x *bp = params->bp;
8631         /* Need to wait 100ms after reset */
8632         msleep(100);
8633
8634         /* Micro controller re-boot */
8635         bnx2x_cl45_write(bp, phy,
8636                          MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
8637
8638         /* Set soft reset */
8639         bnx2x_cl45_write(bp, phy,
8640                          MDIO_PMA_DEVAD,
8641                          MDIO_PMA_REG_GEN_CTRL,
8642                          MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
8643
8644         bnx2x_cl45_write(bp, phy,
8645                          MDIO_PMA_DEVAD,
8646                          MDIO_PMA_REG_MISC_CTRL1, 0x0001);
8647
8648         bnx2x_cl45_write(bp, phy,
8649                          MDIO_PMA_DEVAD,
8650                          MDIO_PMA_REG_GEN_CTRL,
8651                          MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
8652
8653         /* Wait for 150ms for microcode load */
8654         msleep(150);
8655
8656         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
8657         bnx2x_cl45_write(bp, phy,
8658                          MDIO_PMA_DEVAD,
8659                          MDIO_PMA_REG_MISC_CTRL1, 0x0000);
8660
8661         msleep(200);
8662         bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8663 }
8664
8665 static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
8666                                  struct link_params *params,
8667                                  struct link_vars *vars)
8668 {
8669         struct bnx2x *bp = params->bp;
8670         u16 val1;
8671         u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
8672         if (link_up) {
8673                 bnx2x_cl45_read(bp, phy,
8674                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
8675                                 &val1);
8676                 if (val1 & (1<<15)) {
8677                         DP(NETIF_MSG_LINK, "Tx is disabled\n");
8678                         link_up = 0;
8679                         vars->line_speed = 0;
8680                 }
8681         }
8682         return link_up;
8683 }
8684
8685
8686 static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
8687                                   struct link_params *params,
8688                                   struct link_vars *vars)
8689 {
8690         struct bnx2x *bp = params->bp;
8691         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
8692
8693         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
8694         bnx2x_wait_reset_complete(bp, phy, params);
8695
8696         bnx2x_8726_external_rom_boot(phy, params);
8697
8698         /* Need to call module detected on initialization since the module
8699          * detection triggered by actual module insertion might occur before
8700          * driver is loaded, and when driver is loaded, it reset all
8701          * registers, including the transmitter
8702          */
8703         bnx2x_sfp_module_detection(phy, params);
8704
8705         if (phy->req_line_speed == SPEED_1000) {
8706                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
8707                 bnx2x_cl45_write(bp, phy,
8708                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
8709                 bnx2x_cl45_write(bp, phy,
8710                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
8711                 bnx2x_cl45_write(bp, phy,
8712                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
8713                 bnx2x_cl45_write(bp, phy,
8714                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8715                                  0x400);
8716         } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
8717                    (phy->speed_cap_mask &
8718                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
8719                    ((phy->speed_cap_mask &
8720                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
8721                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
8722                 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
8723                 /* Set Flow control */
8724                 bnx2x_ext_phy_set_pause(params, phy, vars);
8725                 bnx2x_cl45_write(bp, phy,
8726                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
8727                 bnx2x_cl45_write(bp, phy,
8728                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8729                 bnx2x_cl45_write(bp, phy,
8730                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
8731                 bnx2x_cl45_write(bp, phy,
8732                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8733                 bnx2x_cl45_write(bp, phy,
8734                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8735                 /* Enable RX-ALARM control to receive interrupt for 1G speed
8736                  * change
8737                  */
8738                 bnx2x_cl45_write(bp, phy,
8739                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
8740                 bnx2x_cl45_write(bp, phy,
8741                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8742                                  0x400);
8743
8744         } else { /* Default 10G. Set only LASI control */
8745                 bnx2x_cl45_write(bp, phy,
8746                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
8747         }
8748
8749         /* Set TX PreEmphasis if needed */
8750         if ((params->feature_config_flags &
8751              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8752                 DP(NETIF_MSG_LINK,
8753                    "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8754                          phy->tx_preemphasis[0],
8755                          phy->tx_preemphasis[1]);
8756                 bnx2x_cl45_write(bp, phy,
8757                                  MDIO_PMA_DEVAD,
8758                                  MDIO_PMA_REG_8726_TX_CTRL1,
8759                                  phy->tx_preemphasis[0]);
8760
8761                 bnx2x_cl45_write(bp, phy,
8762                                  MDIO_PMA_DEVAD,
8763                                  MDIO_PMA_REG_8726_TX_CTRL2,
8764                                  phy->tx_preemphasis[1]);
8765         }
8766
8767         return 0;
8768
8769 }
8770
8771 static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
8772                                   struct link_params *params)
8773 {
8774         struct bnx2x *bp = params->bp;
8775         DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
8776         /* Set serial boot control for external load */
8777         bnx2x_cl45_write(bp, phy,
8778                          MDIO_PMA_DEVAD,
8779                          MDIO_PMA_REG_GEN_CTRL, 0x0001);
8780 }
8781
8782 /******************************************************************/
8783 /*                      BCM8727 PHY SECTION                       */
8784 /******************************************************************/
8785
8786 static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
8787                                     struct link_params *params, u8 mode)
8788 {
8789         struct bnx2x *bp = params->bp;
8790         u16 led_mode_bitmask = 0;
8791         u16 gpio_pins_bitmask = 0;
8792         u16 val;
8793         /* Only NOC flavor requires to set the LED specifically */
8794         if (!(phy->flags & FLAGS_NOC))
8795                 return;
8796         switch (mode) {
8797         case LED_MODE_FRONT_PANEL_OFF:
8798         case LED_MODE_OFF:
8799                 led_mode_bitmask = 0;
8800                 gpio_pins_bitmask = 0x03;
8801                 break;
8802         case LED_MODE_ON:
8803                 led_mode_bitmask = 0;
8804                 gpio_pins_bitmask = 0x02;
8805                 break;
8806         case LED_MODE_OPER:
8807                 led_mode_bitmask = 0x60;
8808                 gpio_pins_bitmask = 0x11;
8809                 break;
8810         }
8811         bnx2x_cl45_read(bp, phy,
8812                         MDIO_PMA_DEVAD,
8813                         MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8814                         &val);
8815         val &= 0xff8f;
8816         val |= led_mode_bitmask;
8817         bnx2x_cl45_write(bp, phy,
8818                          MDIO_PMA_DEVAD,
8819                          MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8820                          val);
8821         bnx2x_cl45_read(bp, phy,
8822                         MDIO_PMA_DEVAD,
8823                         MDIO_PMA_REG_8727_GPIO_CTRL,
8824                         &val);
8825         val &= 0xffe0;
8826         val |= gpio_pins_bitmask;
8827         bnx2x_cl45_write(bp, phy,
8828                          MDIO_PMA_DEVAD,
8829                          MDIO_PMA_REG_8727_GPIO_CTRL,
8830                          val);
8831 }
8832 static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
8833                                 struct link_params *params) {
8834         u32 swap_val, swap_override;
8835         u8 port;
8836         /* The PHY reset is controlled by GPIO 1. Fake the port number
8837          * to cancel the swap done in set_gpio()
8838          */
8839         struct bnx2x *bp = params->bp;
8840         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
8841         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
8842         port = (swap_val && swap_override) ^ 1;
8843         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
8844                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
8845 }
8846
8847 static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
8848                                     struct link_params *params)
8849 {
8850         struct bnx2x *bp = params->bp;
8851         u16 tmp1, val;
8852         /* Set option 1G speed */
8853         if ((phy->req_line_speed == SPEED_1000) ||
8854             (phy->media_type == ETH_PHY_SFP_1G_FIBER)) {
8855                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
8856                 bnx2x_cl45_write(bp, phy,
8857                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
8858                 bnx2x_cl45_write(bp, phy,
8859                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
8860                 bnx2x_cl45_read(bp, phy,
8861                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
8862                 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
8863                 /* Power down the XAUI until link is up in case of dual-media
8864                  * and 1G
8865                  */
8866                 if (DUAL_MEDIA(params)) {
8867                         bnx2x_cl45_read(bp, phy,
8868                                         MDIO_PMA_DEVAD,
8869                                         MDIO_PMA_REG_8727_PCS_GP, &val);
8870                         val |= (3<<10);
8871                         bnx2x_cl45_write(bp, phy,
8872                                          MDIO_PMA_DEVAD,
8873                                          MDIO_PMA_REG_8727_PCS_GP, val);
8874                 }
8875         } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
8876                    ((phy->speed_cap_mask &
8877                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
8878                    ((phy->speed_cap_mask &
8879                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
8880                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
8881
8882                 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
8883                 bnx2x_cl45_write(bp, phy,
8884                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
8885                 bnx2x_cl45_write(bp, phy,
8886                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
8887         } else {
8888                 /* Since the 8727 has only single reset pin, need to set the 10G
8889                  * registers although it is default
8890                  */
8891                 bnx2x_cl45_write(bp, phy,
8892                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
8893                                  0x0020);
8894                 bnx2x_cl45_write(bp, phy,
8895                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
8896                 bnx2x_cl45_write(bp, phy,
8897                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
8898                 bnx2x_cl45_write(bp, phy,
8899                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
8900                                  0x0008);
8901         }
8902 }
8903
8904 static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
8905                                   struct link_params *params,
8906                                   struct link_vars *vars)
8907 {
8908         u32 tx_en_mode;
8909         u16 tmp1, mod_abs, tmp2;
8910         struct bnx2x *bp = params->bp;
8911         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
8912
8913         bnx2x_wait_reset_complete(bp, phy, params);
8914
8915         DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
8916
8917         bnx2x_8727_specific_func(phy, params, PHY_INIT);
8918         /* Initially configure MOD_ABS to interrupt when module is
8919          * presence( bit 8)
8920          */
8921         bnx2x_cl45_read(bp, phy,
8922                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
8923         /* Set EDC off by setting OPTXLOS signal input to low (bit 9).
8924          * When the EDC is off it locks onto a reference clock and avoids
8925          * becoming 'lost'
8926          */
8927         mod_abs &= ~(1<<8);
8928         if (!(phy->flags & FLAGS_NOC))
8929                 mod_abs &= ~(1<<9);
8930         bnx2x_cl45_write(bp, phy,
8931                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8932
8933         /* Enable/Disable PHY transmitter output */
8934         bnx2x_set_disable_pmd_transmit(params, phy, 0);
8935
8936         bnx2x_8727_power_module(bp, phy, 1);
8937
8938         bnx2x_cl45_read(bp, phy,
8939                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
8940
8941         bnx2x_cl45_read(bp, phy,
8942                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
8943
8944         bnx2x_8727_config_speed(phy, params);
8945
8946
8947         /* Set TX PreEmphasis if needed */
8948         if ((params->feature_config_flags &
8949              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8950                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8951                            phy->tx_preemphasis[0],
8952                            phy->tx_preemphasis[1]);
8953                 bnx2x_cl45_write(bp, phy,
8954                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
8955                                  phy->tx_preemphasis[0]);
8956
8957                 bnx2x_cl45_write(bp, phy,
8958                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
8959                                  phy->tx_preemphasis[1]);
8960         }
8961
8962         /* If TX Laser is controlled by GPIO_0, do not let PHY go into low
8963          * power mode, if TX Laser is disabled
8964          */
8965         tx_en_mode = REG_RD(bp, params->shmem_base +
8966                             offsetof(struct shmem_region,
8967                                 dev_info.port_hw_config[params->port].sfp_ctrl))
8968                         & PORT_HW_CFG_TX_LASER_MASK;
8969
8970         if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
8971
8972                 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
8973                 bnx2x_cl45_read(bp, phy,
8974                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
8975                 tmp2 |= 0x1000;
8976                 tmp2 &= 0xFFEF;
8977                 bnx2x_cl45_write(bp, phy,
8978                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
8979                 bnx2x_cl45_read(bp, phy,
8980                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
8981                                 &tmp2);
8982                 bnx2x_cl45_write(bp, phy,
8983                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
8984                                  (tmp2 & 0x7fff));
8985         }
8986
8987         return 0;
8988 }
8989
8990 static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
8991                                       struct link_params *params)
8992 {
8993         struct bnx2x *bp = params->bp;
8994         u16 mod_abs, rx_alarm_status;
8995         u32 val = REG_RD(bp, params->shmem_base +
8996                              offsetof(struct shmem_region, dev_info.
8997                                       port_feature_config[params->port].
8998                                       config));
8999         bnx2x_cl45_read(bp, phy,
9000                         MDIO_PMA_DEVAD,
9001                         MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
9002         if (mod_abs & (1<<8)) {
9003
9004                 /* Module is absent */
9005                 DP(NETIF_MSG_LINK,
9006                    "MOD_ABS indication show module is absent\n");
9007                 phy->media_type = ETH_PHY_NOT_PRESENT;
9008                 /* 1. Set mod_abs to detect next module
9009                  *    presence event
9010                  * 2. Set EDC off by setting OPTXLOS signal input to low
9011                  *    (bit 9).
9012                  *    When the EDC is off it locks onto a reference clock and
9013                  *    avoids becoming 'lost'.
9014                  */
9015                 mod_abs &= ~(1<<8);
9016                 if (!(phy->flags & FLAGS_NOC))
9017                         mod_abs &= ~(1<<9);
9018                 bnx2x_cl45_write(bp, phy,
9019                                  MDIO_PMA_DEVAD,
9020                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
9021
9022                 /* Clear RX alarm since it stays up as long as
9023                  * the mod_abs wasn't changed
9024                  */
9025                 bnx2x_cl45_read(bp, phy,
9026                                 MDIO_PMA_DEVAD,
9027                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
9028
9029         } else {
9030                 /* Module is present */
9031                 DP(NETIF_MSG_LINK,
9032                    "MOD_ABS indication show module is present\n");
9033                 /* First disable transmitter, and if the module is ok, the
9034                  * module_detection will enable it
9035                  * 1. Set mod_abs to detect next module absent event ( bit 8)
9036                  * 2. Restore the default polarity of the OPRXLOS signal and
9037                  * this signal will then correctly indicate the presence or
9038                  * absence of the Rx signal. (bit 9)
9039                  */
9040                 mod_abs |= (1<<8);
9041                 if (!(phy->flags & FLAGS_NOC))
9042                         mod_abs |= (1<<9);
9043                 bnx2x_cl45_write(bp, phy,
9044                                  MDIO_PMA_DEVAD,
9045                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
9046
9047                 /* Clear RX alarm since it stays up as long as the mod_abs
9048                  * wasn't changed. This is need to be done before calling the
9049                  * module detection, otherwise it will clear* the link update
9050                  * alarm
9051                  */
9052                 bnx2x_cl45_read(bp, phy,
9053                                 MDIO_PMA_DEVAD,
9054                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
9055
9056
9057                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9058                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
9059                         bnx2x_sfp_set_transmitter(params, phy, 0);
9060
9061                 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
9062                         bnx2x_sfp_module_detection(phy, params);
9063                 else
9064                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
9065
9066                 /* Reconfigure link speed based on module type limitations */
9067                 bnx2x_8727_config_speed(phy, params);
9068         }
9069
9070         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
9071                    rx_alarm_status);
9072         /* No need to check link status in case of module plugged in/out */
9073 }
9074
9075 static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
9076                                  struct link_params *params,
9077                                  struct link_vars *vars)
9078
9079 {
9080         struct bnx2x *bp = params->bp;
9081         u8 link_up = 0, oc_port = params->port;
9082         u16 link_status = 0;
9083         u16 rx_alarm_status, lasi_ctrl, val1;
9084
9085         /* If PHY is not initialized, do not check link status */
9086         bnx2x_cl45_read(bp, phy,
9087                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
9088                         &lasi_ctrl);
9089         if (!lasi_ctrl)
9090                 return 0;
9091
9092         /* Check the LASI on Rx */
9093         bnx2x_cl45_read(bp, phy,
9094                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
9095                         &rx_alarm_status);
9096         vars->line_speed = 0;
9097         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
9098
9099         bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
9100                              MDIO_PMA_LASI_TXCTRL);
9101
9102         bnx2x_cl45_read(bp, phy,
9103                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
9104
9105         DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
9106
9107         /* Clear MSG-OUT */
9108         bnx2x_cl45_read(bp, phy,
9109                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
9110
9111         /* If a module is present and there is need to check
9112          * for over current
9113          */
9114         if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
9115                 /* Check over-current using 8727 GPIO0 input*/
9116                 bnx2x_cl45_read(bp, phy,
9117                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
9118                                 &val1);
9119
9120                 if ((val1 & (1<<8)) == 0) {
9121                         if (!CHIP_IS_E1x(bp))
9122                                 oc_port = BP_PATH(bp) + (params->port << 1);
9123                         DP(NETIF_MSG_LINK,
9124                            "8727 Power fault has been detected on port %d\n",
9125                            oc_port);
9126                         netdev_err(bp->dev, "Error: Power fault on Port %d has "
9127                                             "been detected and the power to "
9128                                             "that SFP+ module has been removed "
9129                                             "to prevent failure of the card. "
9130                                             "Please remove the SFP+ module and "
9131                                             "restart the system to clear this "
9132                                             "error.\n",
9133                          oc_port);
9134                         /* Disable all RX_ALARMs except for mod_abs */
9135                         bnx2x_cl45_write(bp, phy,
9136                                          MDIO_PMA_DEVAD,
9137                                          MDIO_PMA_LASI_RXCTRL, (1<<5));
9138
9139                         bnx2x_cl45_read(bp, phy,
9140                                         MDIO_PMA_DEVAD,
9141                                         MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
9142                         /* Wait for module_absent_event */
9143                         val1 |= (1<<8);
9144                         bnx2x_cl45_write(bp, phy,
9145                                          MDIO_PMA_DEVAD,
9146                                          MDIO_PMA_REG_PHY_IDENTIFIER, val1);
9147                         /* Clear RX alarm */
9148                         bnx2x_cl45_read(bp, phy,
9149                                 MDIO_PMA_DEVAD,
9150                                 MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
9151                         return 0;
9152                 }
9153         } /* Over current check */
9154
9155         /* When module absent bit is set, check module */
9156         if (rx_alarm_status & (1<<5)) {
9157                 bnx2x_8727_handle_mod_abs(phy, params);
9158                 /* Enable all mod_abs and link detection bits */
9159                 bnx2x_cl45_write(bp, phy,
9160                                  MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9161                                  ((1<<5) | (1<<2)));
9162         }
9163
9164         if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) {
9165                 DP(NETIF_MSG_LINK, "Enabling 8727 TX laser\n");
9166                 bnx2x_sfp_set_transmitter(params, phy, 1);
9167         } else {
9168                 DP(NETIF_MSG_LINK, "Tx is disabled\n");
9169                 return 0;
9170         }
9171
9172         bnx2x_cl45_read(bp, phy,
9173                         MDIO_PMA_DEVAD,
9174                         MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
9175
9176         /* Bits 0..2 --> speed detected,
9177          * Bits 13..15--> link is down
9178          */
9179         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
9180                 link_up = 1;
9181                 vars->line_speed = SPEED_10000;
9182                 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
9183                            params->port);
9184         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
9185                 link_up = 1;
9186                 vars->line_speed = SPEED_1000;
9187                 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
9188                            params->port);
9189         } else {
9190                 link_up = 0;
9191                 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
9192                            params->port);
9193         }
9194
9195         /* Capture 10G link fault. */
9196         if (vars->line_speed == SPEED_10000) {
9197                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
9198                             MDIO_PMA_LASI_TXSTAT, &val1);
9199
9200                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
9201                             MDIO_PMA_LASI_TXSTAT, &val1);
9202
9203                 if (val1 & (1<<0)) {
9204                         vars->fault_detected = 1;
9205                 }
9206         }
9207
9208         if (link_up) {
9209                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
9210                 vars->duplex = DUPLEX_FULL;
9211                 DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
9212         }
9213
9214         if ((DUAL_MEDIA(params)) &&
9215             (phy->req_line_speed == SPEED_1000)) {
9216                 bnx2x_cl45_read(bp, phy,
9217                                 MDIO_PMA_DEVAD,
9218                                 MDIO_PMA_REG_8727_PCS_GP, &val1);
9219                 /* In case of dual-media board and 1G, power up the XAUI side,
9220                  * otherwise power it down. For 10G it is done automatically
9221                  */
9222                 if (link_up)
9223                         val1 &= ~(3<<10);
9224                 else
9225                         val1 |= (3<<10);
9226                 bnx2x_cl45_write(bp, phy,
9227                                  MDIO_PMA_DEVAD,
9228                                  MDIO_PMA_REG_8727_PCS_GP, val1);
9229         }
9230         return link_up;
9231 }
9232
9233 static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
9234                                   struct link_params *params)
9235 {
9236         struct bnx2x *bp = params->bp;
9237
9238         /* Enable/Disable PHY transmitter output */
9239         bnx2x_set_disable_pmd_transmit(params, phy, 1);
9240
9241         /* Disable Transmitter */
9242         bnx2x_sfp_set_transmitter(params, phy, 0);
9243         /* Clear LASI */
9244         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
9245
9246 }
9247
9248 /******************************************************************/
9249 /*              BCM8481/BCM84823/BCM84833 PHY SECTION             */
9250 /******************************************************************/
9251 static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
9252                                             struct bnx2x *bp,
9253                                             u8 port)
9254 {
9255         u16 val, fw_ver1, fw_ver2, cnt;
9256
9257         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9258                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
9259                 bnx2x_save_spirom_version(bp, port, fw_ver1 & 0xfff,
9260                                 phy->ver_addr);
9261         } else {
9262                 /* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
9263                 /* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
9264                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
9265                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
9266                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
9267                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
9268                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
9269
9270                 for (cnt = 0; cnt < 100; cnt++) {
9271                         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
9272                         if (val & 1)
9273                                 break;
9274                         udelay(5);
9275                 }
9276                 if (cnt == 100) {
9277                         DP(NETIF_MSG_LINK, "Unable to read 848xx "
9278                                         "phy fw version(1)\n");
9279                         bnx2x_save_spirom_version(bp, port, 0,
9280                                                   phy->ver_addr);
9281                         return;
9282                 }
9283
9284
9285                 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
9286                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
9287                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
9288                 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
9289                 for (cnt = 0; cnt < 100; cnt++) {
9290                         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
9291                         if (val & 1)
9292                                 break;
9293                         udelay(5);
9294                 }
9295                 if (cnt == 100) {
9296                         DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw "
9297                                         "version(2)\n");
9298                         bnx2x_save_spirom_version(bp, port, 0,
9299                                                   phy->ver_addr);
9300                         return;
9301                 }
9302
9303                 /* lower 16 bits of the register SPI_FW_STATUS */
9304                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
9305                 /* upper 16 bits of register SPI_FW_STATUS */
9306                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
9307
9308                 bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
9309                                           phy->ver_addr);
9310         }
9311
9312 }
9313 static void bnx2x_848xx_set_led(struct bnx2x *bp,
9314                                 struct bnx2x_phy *phy)
9315 {
9316         u16 val, offset;
9317
9318         /* PHYC_CTL_LED_CTL */
9319         bnx2x_cl45_read(bp, phy,
9320                         MDIO_PMA_DEVAD,
9321                         MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
9322         val &= 0xFE00;
9323         val |= 0x0092;
9324
9325         bnx2x_cl45_write(bp, phy,
9326                          MDIO_PMA_DEVAD,
9327                          MDIO_PMA_REG_8481_LINK_SIGNAL, val);
9328
9329         bnx2x_cl45_write(bp, phy,
9330                          MDIO_PMA_DEVAD,
9331                          MDIO_PMA_REG_8481_LED1_MASK,
9332                          0x80);
9333
9334         bnx2x_cl45_write(bp, phy,
9335                          MDIO_PMA_DEVAD,
9336                          MDIO_PMA_REG_8481_LED2_MASK,
9337                          0x18);
9338
9339         /* Select activity source by Tx and Rx, as suggested by PHY AE */
9340         bnx2x_cl45_write(bp, phy,
9341                          MDIO_PMA_DEVAD,
9342                          MDIO_PMA_REG_8481_LED3_MASK,
9343                          0x0006);
9344
9345         /* Select the closest activity blink rate to that in 10/100/1000 */
9346         bnx2x_cl45_write(bp, phy,
9347                         MDIO_PMA_DEVAD,
9348                         MDIO_PMA_REG_8481_LED3_BLINK,
9349                         0);
9350
9351         /* Configure the blink rate to ~15.9 Hz */
9352         bnx2x_cl45_write(bp, phy,
9353                         MDIO_PMA_DEVAD,
9354                         MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
9355                         MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ);
9356
9357         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
9358                 offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1;
9359         else
9360                 offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
9361
9362         bnx2x_cl45_read(bp, phy,
9363                         MDIO_PMA_DEVAD, offset, &val);
9364         val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
9365         bnx2x_cl45_write(bp, phy,
9366                          MDIO_PMA_DEVAD, offset, val);
9367
9368         /* 'Interrupt Mask' */
9369         bnx2x_cl45_write(bp, phy,
9370                          MDIO_AN_DEVAD,
9371                          0xFFFB, 0xFFFD);
9372 }
9373
9374 static void bnx2x_848xx_specific_func(struct bnx2x_phy *phy,
9375                                       struct link_params *params,
9376                                       u32 action)
9377 {
9378         struct bnx2x *bp = params->bp;
9379         switch (action) {
9380         case PHY_INIT:
9381                 if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9382                         /* Save spirom version */
9383                         bnx2x_save_848xx_spirom_version(phy, bp, params->port);
9384                 }
9385                 /* This phy uses the NIG latch mechanism since link indication
9386                  * arrives through its LED4 and not via its LASI signal, so we
9387                  * get steady signal instead of clear on read
9388                  */
9389                 bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
9390                               1 << NIG_LATCH_BC_ENABLE_MI_INT);
9391
9392                 bnx2x_848xx_set_led(bp, phy);
9393                 break;
9394         }
9395 }
9396
9397 static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
9398                                        struct link_params *params,
9399                                        struct link_vars *vars)
9400 {
9401         struct bnx2x *bp = params->bp;
9402         u16 autoneg_val, an_1000_val, an_10_100_val, an_10g_val;
9403
9404         bnx2x_848xx_specific_func(phy, params, PHY_INIT);
9405         bnx2x_cl45_write(bp, phy,
9406                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
9407
9408         /* set 1000 speed advertisement */
9409         bnx2x_cl45_read(bp, phy,
9410                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9411                         &an_1000_val);
9412
9413         bnx2x_ext_phy_set_pause(params, phy, vars);
9414         bnx2x_cl45_read(bp, phy,
9415                         MDIO_AN_DEVAD,
9416                         MDIO_AN_REG_8481_LEGACY_AN_ADV,
9417                         &an_10_100_val);
9418         bnx2x_cl45_read(bp, phy,
9419                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
9420                         &autoneg_val);
9421         /* Disable forced speed */
9422         autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
9423         an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
9424
9425         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9426              (phy->speed_cap_mask &
9427              PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
9428             (phy->req_line_speed == SPEED_1000)) {
9429                 an_1000_val |= (1<<8);
9430                 autoneg_val |= (1<<9 | 1<<12);
9431                 if (phy->req_duplex == DUPLEX_FULL)
9432                         an_1000_val |= (1<<9);
9433                 DP(NETIF_MSG_LINK, "Advertising 1G\n");
9434         } else
9435                 an_1000_val &= ~((1<<8) | (1<<9));
9436
9437         bnx2x_cl45_write(bp, phy,
9438                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9439                          an_1000_val);
9440
9441         /* set 100 speed advertisement */
9442         if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
9443              (phy->speed_cap_mask &
9444               (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
9445                PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))) {
9446                 an_10_100_val |= (1<<7);
9447                 /* Enable autoneg and restart autoneg for legacy speeds */
9448                 autoneg_val |= (1<<9 | 1<<12);
9449
9450                 if (phy->req_duplex == DUPLEX_FULL)
9451                         an_10_100_val |= (1<<8);
9452                 DP(NETIF_MSG_LINK, "Advertising 100M\n");
9453         }
9454         /* set 10 speed advertisement */
9455         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9456              (phy->speed_cap_mask &
9457               (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
9458                PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) &&
9459              (phy->supported &
9460               (SUPPORTED_10baseT_Half |
9461                SUPPORTED_10baseT_Full)))) {
9462                 an_10_100_val |= (1<<5);
9463                 autoneg_val |= (1<<9 | 1<<12);
9464                 if (phy->req_duplex == DUPLEX_FULL)
9465                         an_10_100_val |= (1<<6);
9466                 DP(NETIF_MSG_LINK, "Advertising 10M\n");
9467         }
9468
9469         /* Only 10/100 are allowed to work in FORCE mode */
9470         if ((phy->req_line_speed == SPEED_100) &&
9471             (phy->supported &
9472              (SUPPORTED_100baseT_Half |
9473               SUPPORTED_100baseT_Full))) {
9474                 autoneg_val |= (1<<13);
9475                 /* Enabled AUTO-MDIX when autoneg is disabled */
9476                 bnx2x_cl45_write(bp, phy,
9477                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9478                                  (1<<15 | 1<<9 | 7<<0));
9479                 /* The PHY needs this set even for forced link. */
9480                 an_10_100_val |= (1<<8) | (1<<7);
9481                 DP(NETIF_MSG_LINK, "Setting 100M force\n");
9482         }
9483         if ((phy->req_line_speed == SPEED_10) &&
9484             (phy->supported &
9485              (SUPPORTED_10baseT_Half |
9486               SUPPORTED_10baseT_Full))) {
9487                 /* Enabled AUTO-MDIX when autoneg is disabled */
9488                 bnx2x_cl45_write(bp, phy,
9489                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9490                                  (1<<15 | 1<<9 | 7<<0));
9491                 DP(NETIF_MSG_LINK, "Setting 10M force\n");
9492         }
9493
9494         bnx2x_cl45_write(bp, phy,
9495                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
9496                          an_10_100_val);
9497
9498         if (phy->req_duplex == DUPLEX_FULL)
9499                 autoneg_val |= (1<<8);
9500
9501         /* Always write this if this is not 84833.
9502          * For 84833, write it only when it's a forced speed.
9503          */
9504         if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
9505                 ((autoneg_val & (1<<12)) == 0))
9506                 bnx2x_cl45_write(bp, phy,
9507                          MDIO_AN_DEVAD,
9508                          MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
9509
9510         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9511             (phy->speed_cap_mask &
9512              PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
9513                 (phy->req_line_speed == SPEED_10000)) {
9514                         DP(NETIF_MSG_LINK, "Advertising 10G\n");
9515                         /* Restart autoneg for 10G*/
9516
9517                         bnx2x_cl45_read(bp, phy,
9518                                         MDIO_AN_DEVAD,
9519                                         MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9520                                         &an_10g_val);
9521                         bnx2x_cl45_write(bp, phy,
9522                                          MDIO_AN_DEVAD,
9523                                          MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9524                                          an_10g_val | 0x1000);
9525                         bnx2x_cl45_write(bp, phy,
9526                                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
9527                                          0x3200);
9528         } else
9529                 bnx2x_cl45_write(bp, phy,
9530                                  MDIO_AN_DEVAD,
9531                                  MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9532                                  1);
9533
9534         return 0;
9535 }
9536
9537 static int bnx2x_8481_config_init(struct bnx2x_phy *phy,
9538                                   struct link_params *params,
9539                                   struct link_vars *vars)
9540 {
9541         struct bnx2x *bp = params->bp;
9542         /* Restore normal power mode*/
9543         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
9544                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9545
9546         /* HW reset */
9547         bnx2x_ext_phy_hw_reset(bp, params->port);
9548         bnx2x_wait_reset_complete(bp, phy, params);
9549
9550         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
9551         return bnx2x_848xx_cmn_config_init(phy, params, vars);
9552 }
9553
9554 #define PHY84833_CMDHDLR_WAIT 300
9555 #define PHY84833_CMDHDLR_MAX_ARGS 5
9556 static int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
9557                                    struct link_params *params,
9558                    u16 fw_cmd,
9559                    u16 cmd_args[], int argc)
9560 {
9561         int idx;
9562         u16 val;
9563         struct bnx2x *bp = params->bp;
9564         /* Write CMD_OPEN_OVERRIDE to STATUS reg */
9565         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9566                         MDIO_84833_CMD_HDLR_STATUS,
9567                         PHY84833_STATUS_CMD_OPEN_OVERRIDE);
9568         for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) {
9569                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9570                                 MDIO_84833_CMD_HDLR_STATUS, &val);
9571                 if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS)
9572                         break;
9573                  usleep_range(1000, 2000);
9574         }
9575         if (idx >= PHY84833_CMDHDLR_WAIT) {
9576                 DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n");
9577                 return -EINVAL;
9578         }
9579
9580         /* Prepare argument(s) and issue command */
9581         for (idx = 0; idx < argc; idx++) {
9582                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9583                                 MDIO_84833_CMD_HDLR_DATA1 + idx,
9584                                 cmd_args[idx]);
9585         }
9586         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9587                         MDIO_84833_CMD_HDLR_COMMAND, fw_cmd);
9588         for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) {
9589                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9590                                 MDIO_84833_CMD_HDLR_STATUS, &val);
9591                 if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) ||
9592                         (val == PHY84833_STATUS_CMD_COMPLETE_ERROR))
9593                         break;
9594                  usleep_range(1000, 2000);
9595         }
9596         if ((idx >= PHY84833_CMDHDLR_WAIT) ||
9597                 (val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
9598                 DP(NETIF_MSG_LINK, "FW cmd failed.\n");
9599                 return -EINVAL;
9600         }
9601         /* Gather returning data */
9602         for (idx = 0; idx < argc; idx++) {
9603                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9604                                 MDIO_84833_CMD_HDLR_DATA1 + idx,
9605                                 &cmd_args[idx]);
9606         }
9607         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9608                         MDIO_84833_CMD_HDLR_STATUS,
9609                         PHY84833_STATUS_CMD_CLEAR_COMPLETE);
9610         return 0;
9611 }
9612
9613
9614 static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
9615                                    struct link_params *params,
9616                                    struct link_vars *vars)
9617 {
9618         u32 pair_swap;
9619         u16 data[PHY84833_CMDHDLR_MAX_ARGS];
9620         int status;
9621         struct bnx2x *bp = params->bp;
9622
9623         /* Check for configuration. */
9624         pair_swap = REG_RD(bp, params->shmem_base +
9625                            offsetof(struct shmem_region,
9626                         dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
9627                 PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
9628
9629         if (pair_swap == 0)
9630                 return 0;
9631
9632         /* Only the second argument is used for this command */
9633         data[1] = (u16)pair_swap;
9634
9635         status = bnx2x_84833_cmd_hdlr(phy, params,
9636                 PHY84833_CMD_SET_PAIR_SWAP, data, PHY84833_CMDHDLR_MAX_ARGS);
9637         if (status == 0)
9638                 DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]);
9639
9640         return status;
9641 }
9642
9643 static u8 bnx2x_84833_get_reset_gpios(struct bnx2x *bp,
9644                                       u32 shmem_base_path[],
9645                                       u32 chip_id)
9646 {
9647         u32 reset_pin[2];
9648         u32 idx;
9649         u8 reset_gpios;
9650         if (CHIP_IS_E3(bp)) {
9651                 /* Assume that these will be GPIOs, not EPIOs. */
9652                 for (idx = 0; idx < 2; idx++) {
9653                         /* Map config param to register bit. */
9654                         reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
9655                                 offsetof(struct shmem_region,
9656                                 dev_info.port_hw_config[0].e3_cmn_pin_cfg));
9657                         reset_pin[idx] = (reset_pin[idx] &
9658                                 PORT_HW_CFG_E3_PHY_RESET_MASK) >>
9659                                 PORT_HW_CFG_E3_PHY_RESET_SHIFT;
9660                         reset_pin[idx] -= PIN_CFG_GPIO0_P0;
9661                         reset_pin[idx] = (1 << reset_pin[idx]);
9662                 }
9663                 reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
9664         } else {
9665                 /* E2, look from diff place of shmem. */
9666                 for (idx = 0; idx < 2; idx++) {
9667                         reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
9668                                 offsetof(struct shmem_region,
9669                                 dev_info.port_hw_config[0].default_cfg));
9670                         reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
9671                         reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
9672                         reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
9673                         reset_pin[idx] = (1 << reset_pin[idx]);
9674                 }
9675                 reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
9676         }
9677
9678         return reset_gpios;
9679 }
9680
9681 static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
9682                                 struct link_params *params)
9683 {
9684         struct bnx2x *bp = params->bp;
9685         u8 reset_gpios;
9686         u32 other_shmem_base_addr = REG_RD(bp, params->shmem2_base +
9687                                 offsetof(struct shmem2_region,
9688                                 other_shmem_base_addr));
9689
9690         u32 shmem_base_path[2];
9691
9692         /* Work around for 84833 LED failure inside RESET status */
9693         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
9694                 MDIO_AN_REG_8481_LEGACY_MII_CTRL,
9695                 MDIO_AN_REG_8481_MII_CTRL_FORCE_1G);
9696         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
9697                 MDIO_AN_REG_8481_1G_100T_EXT_CTRL,
9698                 MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF);
9699
9700         shmem_base_path[0] = params->shmem_base;
9701         shmem_base_path[1] = other_shmem_base_addr;
9702
9703         reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path,
9704                                                   params->chip_id);
9705
9706         bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
9707         udelay(10);
9708         DP(NETIF_MSG_LINK, "84833 hw reset on pin values 0x%x\n",
9709                 reset_gpios);
9710
9711         return 0;
9712 }
9713
9714 static int bnx2x_8483x_disable_eee(struct bnx2x_phy *phy,
9715                                    struct link_params *params,
9716                                    struct link_vars *vars)
9717 {
9718         int rc;
9719         struct bnx2x *bp = params->bp;
9720         u16 cmd_args = 0;
9721
9722         DP(NETIF_MSG_LINK, "Don't Advertise 10GBase-T EEE\n");
9723
9724         /* Prevent Phy from working in EEE and advertising it */
9725         rc = bnx2x_84833_cmd_hdlr(phy, params,
9726                 PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1);
9727         if (rc) {
9728                 DP(NETIF_MSG_LINK, "EEE disable failed.\n");
9729                 return rc;
9730         }
9731
9732         return bnx2x_eee_disable(phy, params, vars);
9733 }
9734
9735 static int bnx2x_8483x_enable_eee(struct bnx2x_phy *phy,
9736                                    struct link_params *params,
9737                                    struct link_vars *vars)
9738 {
9739         int rc;
9740         struct bnx2x *bp = params->bp;
9741         u16 cmd_args = 1;
9742
9743         rc = bnx2x_84833_cmd_hdlr(phy, params,
9744                 PHY84833_CMD_SET_EEE_MODE, &cmd_args, 1);
9745         if (rc) {
9746                 DP(NETIF_MSG_LINK, "EEE enable failed.\n");
9747                 return rc;
9748         }
9749
9750         return bnx2x_eee_advertise(phy, params, vars, SHMEM_EEE_10G_ADV);
9751 }
9752
9753 #define PHY84833_CONSTANT_LATENCY 1193
9754 static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
9755                                    struct link_params *params,
9756                                    struct link_vars *vars)
9757 {
9758         struct bnx2x *bp = params->bp;
9759         u8 port, initialize = 1;
9760         u16 val;
9761         u32 actual_phy_selection, cms_enable;
9762         u16 cmd_args[PHY84833_CMDHDLR_MAX_ARGS];
9763         int rc = 0;
9764
9765          usleep_range(1000, 2000);
9766
9767         if (!(CHIP_IS_E1x(bp)))
9768                 port = BP_PATH(bp);
9769         else
9770                 port = params->port;
9771
9772         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9773                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
9774                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
9775                                port);
9776         } else {
9777                 /* MDIO reset */
9778                 bnx2x_cl45_write(bp, phy,
9779                                 MDIO_PMA_DEVAD,
9780                                 MDIO_PMA_REG_CTRL, 0x8000);
9781         }
9782
9783         bnx2x_wait_reset_complete(bp, phy, params);
9784
9785         /* Wait for GPHY to come out of reset */
9786         msleep(50);
9787         if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9788                 /* BCM84823 requires that XGXS links up first @ 10G for normal
9789                  * behavior.
9790                  */
9791                 u16 temp;
9792                 temp = vars->line_speed;
9793                 vars->line_speed = SPEED_10000;
9794                 bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
9795                 bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
9796                 vars->line_speed = temp;
9797         }
9798
9799         bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9800                         MDIO_CTL_REG_84823_MEDIA, &val);
9801         val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9802                  MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
9803                  MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
9804                  MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
9805                  MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
9806
9807         if (CHIP_IS_E3(bp)) {
9808                 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9809                          MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
9810         } else {
9811                 val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
9812                         MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
9813         }
9814
9815         actual_phy_selection = bnx2x_phy_selection(params);
9816
9817         switch (actual_phy_selection) {
9818         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
9819                 /* Do nothing. Essentially this is like the priority copper */
9820                 break;
9821         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
9822                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
9823                 break;
9824         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
9825                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
9826                 break;
9827         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
9828                 /* Do nothing here. The first PHY won't be initialized at all */
9829                 break;
9830         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
9831                 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
9832                 initialize = 0;
9833                 break;
9834         }
9835         if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
9836                 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
9837
9838         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9839                          MDIO_CTL_REG_84823_MEDIA, val);
9840         DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
9841                    params->multi_phy_config, val);
9842
9843         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9844                 bnx2x_84833_pair_swap_cfg(phy, params, vars);
9845
9846                 /* Keep AutogrEEEn disabled. */
9847                 cmd_args[0] = 0x0;
9848                 cmd_args[1] = 0x0;
9849                 cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
9850                 cmd_args[3] = PHY84833_CONSTANT_LATENCY;
9851                 rc = bnx2x_84833_cmd_hdlr(phy, params,
9852                         PHY84833_CMD_SET_EEE_MODE, cmd_args,
9853                         PHY84833_CMDHDLR_MAX_ARGS);
9854                 if (rc)
9855                         DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n");
9856         }
9857         if (initialize)
9858                 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
9859         else
9860                 bnx2x_save_848xx_spirom_version(phy, bp, params->port);
9861         /* 84833 PHY has a better feature and doesn't need to support this. */
9862         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9863                 cms_enable = REG_RD(bp, params->shmem_base +
9864                         offsetof(struct shmem_region,
9865                         dev_info.port_hw_config[params->port].default_cfg)) &
9866                         PORT_HW_CFG_ENABLE_CMS_MASK;
9867
9868                 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9869                                 MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
9870                 if (cms_enable)
9871                         val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
9872                 else
9873                         val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
9874                 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9875                                  MDIO_CTL_REG_84823_USER_CTRL_REG, val);
9876         }
9877
9878         bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9879                         MDIO_84833_TOP_CFG_FW_REV, &val);
9880
9881         /* Configure EEE support */
9882         if ((val >= MDIO_84833_TOP_CFG_FW_EEE) &&
9883             (val != MDIO_84833_TOP_CFG_FW_NO_EEE) &&
9884             bnx2x_eee_has_cap(params)) {
9885                 rc = bnx2x_eee_initial_config(params, vars, SHMEM_EEE_10G_ADV);
9886                 if (rc) {
9887                         DP(NETIF_MSG_LINK, "Failed to configure EEE timers\n");
9888                         bnx2x_8483x_disable_eee(phy, params, vars);
9889                         return rc;
9890                 }
9891
9892                 if ((params->req_duplex[actual_phy_selection] == DUPLEX_FULL) &&
9893                     (params->eee_mode & EEE_MODE_ADV_LPI) &&
9894                     (bnx2x_eee_calc_timer(params) ||
9895                      !(params->eee_mode & EEE_MODE_ENABLE_LPI)))
9896                         rc = bnx2x_8483x_enable_eee(phy, params, vars);
9897                 else
9898                         rc = bnx2x_8483x_disable_eee(phy, params, vars);
9899                 if (rc) {
9900                         DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n");
9901                         return rc;
9902                 }
9903         } else {
9904                 vars->eee_status &= ~SHMEM_EEE_SUPPORTED_MASK;
9905         }
9906
9907         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9908                 /* Bring PHY out of super isolate mode as the final step. */
9909                 bnx2x_cl45_read(bp, phy,
9910                                 MDIO_CTL_DEVAD,
9911                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
9912                 val &= ~MDIO_84833_SUPER_ISOLATE;
9913                 bnx2x_cl45_write(bp, phy,
9914                                 MDIO_CTL_DEVAD,
9915                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
9916         }
9917         return rc;
9918 }
9919
9920 static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
9921                                   struct link_params *params,
9922                                   struct link_vars *vars)
9923 {
9924         struct bnx2x *bp = params->bp;
9925         u16 val, val1, val2;
9926         u8 link_up = 0;
9927
9928
9929         /* Check 10G-BaseT link status */
9930         /* Check PMD signal ok */
9931         bnx2x_cl45_read(bp, phy,
9932                         MDIO_AN_DEVAD, 0xFFFA, &val1);
9933         bnx2x_cl45_read(bp, phy,
9934                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
9935                         &val2);
9936         DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
9937
9938         /* Check link 10G */
9939         if (val2 & (1<<11)) {
9940                 vars->line_speed = SPEED_10000;
9941                 vars->duplex = DUPLEX_FULL;
9942                 link_up = 1;
9943                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
9944         } else { /* Check Legacy speed link */
9945                 u16 legacy_status, legacy_speed;
9946
9947                 /* Enable expansion register 0x42 (Operation mode status) */
9948                 bnx2x_cl45_write(bp, phy,
9949                                  MDIO_AN_DEVAD,
9950                                  MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
9951
9952                 /* Get legacy speed operation status */
9953                 bnx2x_cl45_read(bp, phy,
9954                                 MDIO_AN_DEVAD,
9955                                 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
9956                                 &legacy_status);
9957
9958                 DP(NETIF_MSG_LINK, "Legacy speed status = 0x%x\n",
9959                    legacy_status);
9960                 link_up = ((legacy_status & (1<<11)) == (1<<11));
9961                 legacy_speed = (legacy_status & (3<<9));
9962                 if (legacy_speed == (0<<9))
9963                         vars->line_speed = SPEED_10;
9964                 else if (legacy_speed == (1<<9))
9965                         vars->line_speed = SPEED_100;
9966                 else if (legacy_speed == (2<<9))
9967                         vars->line_speed = SPEED_1000;
9968                 else { /* Should not happen: Treat as link down */
9969                         vars->line_speed = 0;
9970                         link_up = 0;
9971                 }
9972
9973                 if (link_up) {
9974                         if (legacy_status & (1<<8))
9975                                 vars->duplex = DUPLEX_FULL;
9976                         else
9977                                 vars->duplex = DUPLEX_HALF;
9978
9979                         DP(NETIF_MSG_LINK,
9980                            "Link is up in %dMbps, is_duplex_full= %d\n",
9981                            vars->line_speed,
9982                            (vars->duplex == DUPLEX_FULL));
9983                         /* Check legacy speed AN resolution */
9984                         bnx2x_cl45_read(bp, phy,
9985                                         MDIO_AN_DEVAD,
9986                                         MDIO_AN_REG_8481_LEGACY_MII_STATUS,
9987                                         &val);
9988                         if (val & (1<<5))
9989                                 vars->link_status |=
9990                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
9991                         bnx2x_cl45_read(bp, phy,
9992                                         MDIO_AN_DEVAD,
9993                                         MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
9994                                         &val);
9995                         if ((val & (1<<0)) == 0)
9996                                 vars->link_status |=
9997                                         LINK_STATUS_PARALLEL_DETECTION_USED;
9998                 }
9999         }
10000         if (link_up) {
10001                 DP(NETIF_MSG_LINK, "BCM848x3: link speed is %d\n",
10002                            vars->line_speed);
10003                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10004
10005                 /* Read LP advertised speeds */
10006                 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
10007                                 MDIO_AN_REG_CL37_FC_LP, &val);
10008                 if (val & (1<<5))
10009                         vars->link_status |=
10010                                 LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
10011                 if (val & (1<<6))
10012                         vars->link_status |=
10013                                 LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
10014                 if (val & (1<<7))
10015                         vars->link_status |=
10016                                 LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
10017                 if (val & (1<<8))
10018                         vars->link_status |=
10019                                 LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
10020                 if (val & (1<<9))
10021                         vars->link_status |=
10022                                 LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
10023
10024                 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
10025                                 MDIO_AN_REG_1000T_STATUS, &val);
10026
10027                 if (val & (1<<10))
10028                         vars->link_status |=
10029                                 LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
10030                 if (val & (1<<11))
10031                         vars->link_status |=
10032                                 LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
10033
10034                 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
10035                                 MDIO_AN_REG_MASTER_STATUS, &val);
10036
10037                 if (val & (1<<11))
10038                         vars->link_status |=
10039                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
10040
10041                 /* Determine if EEE was negotiated */
10042                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
10043                         bnx2x_eee_an_resolve(phy, params, vars);
10044         }
10045
10046         return link_up;
10047 }
10048
10049
10050 static int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
10051 {
10052         int status = 0;
10053         u32 spirom_ver;
10054         spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
10055         status = bnx2x_format_ver(spirom_ver, str, len);
10056         return status;
10057 }
10058
10059 static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
10060                                 struct link_params *params)
10061 {
10062         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10063                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
10064         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10065                        MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
10066 }
10067
10068 static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
10069                                         struct link_params *params)
10070 {
10071         bnx2x_cl45_write(params->bp, phy,
10072                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
10073         bnx2x_cl45_write(params->bp, phy,
10074                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
10075 }
10076
10077 static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
10078                                    struct link_params *params)
10079 {
10080         struct bnx2x *bp = params->bp;
10081         u8 port;
10082         u16 val16;
10083
10084         if (!(CHIP_IS_E1x(bp)))
10085                 port = BP_PATH(bp);
10086         else
10087                 port = params->port;
10088
10089         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
10090                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
10091                                MISC_REGISTERS_GPIO_OUTPUT_LOW,
10092                                port);
10093         } else {
10094                 bnx2x_cl45_read(bp, phy,
10095                                 MDIO_CTL_DEVAD,
10096                                 MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val16);
10097                 val16 |= MDIO_84833_SUPER_ISOLATE;
10098                 bnx2x_cl45_write(bp, phy,
10099                                  MDIO_CTL_DEVAD,
10100                                  MDIO_84833_TOP_CFG_XGPHY_STRAP1, val16);
10101         }
10102 }
10103
10104 static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
10105                                      struct link_params *params, u8 mode)
10106 {
10107         struct bnx2x *bp = params->bp;
10108         u16 val;
10109         u8 port;
10110
10111         if (!(CHIP_IS_E1x(bp)))
10112                 port = BP_PATH(bp);
10113         else
10114                 port = params->port;
10115
10116         switch (mode) {
10117         case LED_MODE_OFF:
10118
10119                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", port);
10120
10121                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
10122                     SHARED_HW_CFG_LED_EXTPHY1) {
10123
10124                         /* Set LED masks */
10125                         bnx2x_cl45_write(bp, phy,
10126                                         MDIO_PMA_DEVAD,
10127                                         MDIO_PMA_REG_8481_LED1_MASK,
10128                                         0x0);
10129
10130                         bnx2x_cl45_write(bp, phy,
10131                                         MDIO_PMA_DEVAD,
10132                                         MDIO_PMA_REG_8481_LED2_MASK,
10133                                         0x0);
10134
10135                         bnx2x_cl45_write(bp, phy,
10136                                         MDIO_PMA_DEVAD,
10137                                         MDIO_PMA_REG_8481_LED3_MASK,
10138                                         0x0);
10139
10140                         bnx2x_cl45_write(bp, phy,
10141                                         MDIO_PMA_DEVAD,
10142                                         MDIO_PMA_REG_8481_LED5_MASK,
10143                                         0x0);
10144
10145                 } else {
10146                         bnx2x_cl45_write(bp, phy,
10147                                          MDIO_PMA_DEVAD,
10148                                          MDIO_PMA_REG_8481_LED1_MASK,
10149                                          0x0);
10150                 }
10151                 break;
10152         case LED_MODE_FRONT_PANEL_OFF:
10153
10154                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
10155                    port);
10156
10157                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
10158                     SHARED_HW_CFG_LED_EXTPHY1) {
10159
10160                         /* Set LED masks */
10161                         bnx2x_cl45_write(bp, phy,
10162                                          MDIO_PMA_DEVAD,
10163                                          MDIO_PMA_REG_8481_LED1_MASK,
10164                                          0x0);
10165
10166                         bnx2x_cl45_write(bp, phy,
10167                                          MDIO_PMA_DEVAD,
10168                                          MDIO_PMA_REG_8481_LED2_MASK,
10169                                          0x0);
10170
10171                         bnx2x_cl45_write(bp, phy,
10172                                          MDIO_PMA_DEVAD,
10173                                          MDIO_PMA_REG_8481_LED3_MASK,
10174                                          0x0);
10175
10176                         bnx2x_cl45_write(bp, phy,
10177                                          MDIO_PMA_DEVAD,
10178                                          MDIO_PMA_REG_8481_LED5_MASK,
10179                                          0x20);
10180
10181                 } else {
10182                         bnx2x_cl45_write(bp, phy,
10183                                          MDIO_PMA_DEVAD,
10184                                          MDIO_PMA_REG_8481_LED1_MASK,
10185                                          0x0);
10186                 }
10187                 break;
10188         case LED_MODE_ON:
10189
10190                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", port);
10191
10192                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
10193                     SHARED_HW_CFG_LED_EXTPHY1) {
10194                         /* Set control reg */
10195                         bnx2x_cl45_read(bp, phy,
10196                                         MDIO_PMA_DEVAD,
10197                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
10198                                         &val);
10199                         val &= 0x8000;
10200                         val |= 0x2492;
10201
10202                         bnx2x_cl45_write(bp, phy,
10203                                          MDIO_PMA_DEVAD,
10204                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
10205                                          val);
10206
10207                         /* Set LED masks */
10208                         bnx2x_cl45_write(bp, phy,
10209                                          MDIO_PMA_DEVAD,
10210                                          MDIO_PMA_REG_8481_LED1_MASK,
10211                                          0x0);
10212
10213                         bnx2x_cl45_write(bp, phy,
10214                                          MDIO_PMA_DEVAD,
10215                                          MDIO_PMA_REG_8481_LED2_MASK,
10216                                          0x20);
10217
10218                         bnx2x_cl45_write(bp, phy,
10219                                          MDIO_PMA_DEVAD,
10220                                          MDIO_PMA_REG_8481_LED3_MASK,
10221                                          0x20);
10222
10223                         bnx2x_cl45_write(bp, phy,
10224                                          MDIO_PMA_DEVAD,
10225                                          MDIO_PMA_REG_8481_LED5_MASK,
10226                                          0x0);
10227                 } else {
10228                         bnx2x_cl45_write(bp, phy,
10229                                          MDIO_PMA_DEVAD,
10230                                          MDIO_PMA_REG_8481_LED1_MASK,
10231                                          0x20);
10232                 }
10233                 break;
10234
10235         case LED_MODE_OPER:
10236
10237                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", port);
10238
10239                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
10240                     SHARED_HW_CFG_LED_EXTPHY1) {
10241
10242                         /* Set control reg */
10243                         bnx2x_cl45_read(bp, phy,
10244                                         MDIO_PMA_DEVAD,
10245                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
10246                                         &val);
10247
10248                         if (!((val &
10249                                MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
10250                           >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
10251                                 DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n");
10252                                 bnx2x_cl45_write(bp, phy,
10253                                                  MDIO_PMA_DEVAD,
10254                                                  MDIO_PMA_REG_8481_LINK_SIGNAL,
10255                                                  0xa492);
10256                         }
10257
10258                         /* Set LED masks */
10259                         bnx2x_cl45_write(bp, phy,
10260                                          MDIO_PMA_DEVAD,
10261                                          MDIO_PMA_REG_8481_LED1_MASK,
10262                                          0x10);
10263
10264                         bnx2x_cl45_write(bp, phy,
10265                                          MDIO_PMA_DEVAD,
10266                                          MDIO_PMA_REG_8481_LED2_MASK,
10267                                          0x80);
10268
10269                         bnx2x_cl45_write(bp, phy,
10270                                          MDIO_PMA_DEVAD,
10271                                          MDIO_PMA_REG_8481_LED3_MASK,
10272                                          0x98);
10273
10274                         bnx2x_cl45_write(bp, phy,
10275                                          MDIO_PMA_DEVAD,
10276                                          MDIO_PMA_REG_8481_LED5_MASK,
10277                                          0x40);
10278
10279                 } else {
10280                         bnx2x_cl45_write(bp, phy,
10281                                          MDIO_PMA_DEVAD,
10282                                          MDIO_PMA_REG_8481_LED1_MASK,
10283                                          0x80);
10284
10285                         /* Tell LED3 to blink on source */
10286                         bnx2x_cl45_read(bp, phy,
10287                                         MDIO_PMA_DEVAD,
10288                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
10289                                         &val);
10290                         val &= ~(7<<6);
10291                         val |= (1<<6); /* A83B[8:6]= 1 */
10292                         bnx2x_cl45_write(bp, phy,
10293                                          MDIO_PMA_DEVAD,
10294                                          MDIO_PMA_REG_8481_LINK_SIGNAL,
10295                                          val);
10296                 }
10297                 break;
10298         }
10299
10300         /* This is a workaround for E3+84833 until autoneg
10301          * restart is fixed in f/w
10302          */
10303         if (CHIP_IS_E3(bp)) {
10304                 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
10305                                 MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
10306         }
10307 }
10308
10309 /******************************************************************/
10310 /*                      54618SE PHY SECTION                       */
10311 /******************************************************************/
10312 static void bnx2x_54618se_specific_func(struct bnx2x_phy *phy,
10313                                         struct link_params *params,
10314                                         u32 action)
10315 {
10316         struct bnx2x *bp = params->bp;
10317         u16 temp;
10318         switch (action) {
10319         case PHY_INIT:
10320                 /* Configure LED4: set to INTR (0x6). */
10321                 /* Accessing shadow register 0xe. */
10322                 bnx2x_cl22_write(bp, phy,
10323                                  MDIO_REG_GPHY_SHADOW,
10324                                  MDIO_REG_GPHY_SHADOW_LED_SEL2);
10325                 bnx2x_cl22_read(bp, phy,
10326                                 MDIO_REG_GPHY_SHADOW,
10327                                 &temp);
10328                 temp &= ~(0xf << 4);
10329                 temp |= (0x6 << 4);
10330                 bnx2x_cl22_write(bp, phy,
10331                                  MDIO_REG_GPHY_SHADOW,
10332                                  MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
10333                 /* Configure INTR based on link status change. */
10334                 bnx2x_cl22_write(bp, phy,
10335                                  MDIO_REG_INTR_MASK,
10336                                  ~MDIO_REG_INTR_MASK_LINK_STATUS);
10337                 break;
10338         }
10339 }
10340
10341 static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
10342                                                struct link_params *params,
10343                                                struct link_vars *vars)
10344 {
10345         struct bnx2x *bp = params->bp;
10346         u8 port;
10347         u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
10348         u32 cfg_pin;
10349
10350         DP(NETIF_MSG_LINK, "54618SE cfg init\n");
10351         usleep_range(1000, 2000);
10352
10353         /* This works with E3 only, no need to check the chip
10354          * before determining the port.
10355          */
10356         port = params->port;
10357
10358         cfg_pin = (REG_RD(bp, params->shmem_base +
10359                         offsetof(struct shmem_region,
10360                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
10361                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
10362                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
10363
10364         /* Drive pin high to bring the GPHY out of reset. */
10365         bnx2x_set_cfg_pin(bp, cfg_pin, 1);
10366
10367         /* wait for GPHY to reset */
10368         msleep(50);
10369
10370         /* reset phy */
10371         bnx2x_cl22_write(bp, phy,
10372                          MDIO_PMA_REG_CTRL, 0x8000);
10373         bnx2x_wait_reset_complete(bp, phy, params);
10374
10375         /* Wait for GPHY to reset */
10376         msleep(50);
10377
10378
10379         bnx2x_54618se_specific_func(phy, params, PHY_INIT);
10380         /* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
10381         bnx2x_cl22_write(bp, phy,
10382                         MDIO_REG_GPHY_SHADOW,
10383                         MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
10384         bnx2x_cl22_read(bp, phy,
10385                         MDIO_REG_GPHY_SHADOW,
10386                         &temp);
10387         temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
10388         bnx2x_cl22_write(bp, phy,
10389                         MDIO_REG_GPHY_SHADOW,
10390                         MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
10391
10392         /* Set up fc */
10393         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
10394         bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
10395         fc_val = 0;
10396         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
10397                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
10398                 fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
10399
10400         if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
10401                         MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
10402                 fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
10403
10404         /* Read all advertisement */
10405         bnx2x_cl22_read(bp, phy,
10406                         0x09,
10407                         &an_1000_val);
10408
10409         bnx2x_cl22_read(bp, phy,
10410                         0x04,
10411                         &an_10_100_val);
10412
10413         bnx2x_cl22_read(bp, phy,
10414                         MDIO_PMA_REG_CTRL,
10415                         &autoneg_val);
10416
10417         /* Disable forced speed */
10418         autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
10419         an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
10420                            (1<<11));
10421
10422         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10423                         (phy->speed_cap_mask &
10424                         PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
10425                         (phy->req_line_speed == SPEED_1000)) {
10426                 an_1000_val |= (1<<8);
10427                 autoneg_val |= (1<<9 | 1<<12);
10428                 if (phy->req_duplex == DUPLEX_FULL)
10429                         an_1000_val |= (1<<9);
10430                 DP(NETIF_MSG_LINK, "Advertising 1G\n");
10431         } else
10432                 an_1000_val &= ~((1<<8) | (1<<9));
10433
10434         bnx2x_cl22_write(bp, phy,
10435                         0x09,
10436                         an_1000_val);
10437         bnx2x_cl22_read(bp, phy,
10438                         0x09,
10439                         &an_1000_val);
10440
10441         /* Set 100 speed advertisement */
10442         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10443                         (phy->speed_cap_mask &
10444                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
10445                         PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
10446                 an_10_100_val |= (1<<7);
10447                 /* Enable autoneg and restart autoneg for legacy speeds */
10448                 autoneg_val |= (1<<9 | 1<<12);
10449
10450                 if (phy->req_duplex == DUPLEX_FULL)
10451                         an_10_100_val |= (1<<8);
10452                 DP(NETIF_MSG_LINK, "Advertising 100M\n");
10453         }
10454
10455         /* Set 10 speed advertisement */
10456         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10457                         (phy->speed_cap_mask &
10458                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
10459                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
10460                 an_10_100_val |= (1<<5);
10461                 autoneg_val |= (1<<9 | 1<<12);
10462                 if (phy->req_duplex == DUPLEX_FULL)
10463                         an_10_100_val |= (1<<6);
10464                 DP(NETIF_MSG_LINK, "Advertising 10M\n");
10465         }
10466
10467         /* Only 10/100 are allowed to work in FORCE mode */
10468         if (phy->req_line_speed == SPEED_100) {
10469                 autoneg_val |= (1<<13);
10470                 /* Enabled AUTO-MDIX when autoneg is disabled */
10471                 bnx2x_cl22_write(bp, phy,
10472                                 0x18,
10473                                 (1<<15 | 1<<9 | 7<<0));
10474                 DP(NETIF_MSG_LINK, "Setting 100M force\n");
10475         }
10476         if (phy->req_line_speed == SPEED_10) {
10477                 /* Enabled AUTO-MDIX when autoneg is disabled */
10478                 bnx2x_cl22_write(bp, phy,
10479                                 0x18,
10480                                 (1<<15 | 1<<9 | 7<<0));
10481                 DP(NETIF_MSG_LINK, "Setting 10M force\n");
10482         }
10483
10484         if ((phy->flags & FLAGS_EEE) && bnx2x_eee_has_cap(params)) {
10485                 int rc;
10486
10487                 bnx2x_cl22_write(bp, phy, MDIO_REG_GPHY_EXP_ACCESS,
10488                                  MDIO_REG_GPHY_EXP_ACCESS_TOP |
10489                                  MDIO_REG_GPHY_EXP_TOP_2K_BUF);
10490                 bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, &temp);
10491                 temp &= 0xfffe;
10492                 bnx2x_cl22_write(bp, phy, MDIO_REG_GPHY_EXP_ACCESS_GATE, temp);
10493
10494                 rc = bnx2x_eee_initial_config(params, vars, SHMEM_EEE_1G_ADV);
10495                 if (rc) {
10496                         DP(NETIF_MSG_LINK, "Failed to configure EEE timers\n");
10497                         bnx2x_eee_disable(phy, params, vars);
10498                 } else if ((params->eee_mode & EEE_MODE_ADV_LPI) &&
10499                            (phy->req_duplex == DUPLEX_FULL) &&
10500                            (bnx2x_eee_calc_timer(params) ||
10501                             !(params->eee_mode & EEE_MODE_ENABLE_LPI))) {
10502                         /* Need to advertise EEE only when requested,
10503                          * and either no LPI assertion was requested,
10504                          * or it was requested and a valid timer was set.
10505                          * Also notice full duplex is required for EEE.
10506                          */
10507                         bnx2x_eee_advertise(phy, params, vars,
10508                                             SHMEM_EEE_1G_ADV);
10509                 } else {
10510                         DP(NETIF_MSG_LINK, "Don't Advertise 1GBase-T EEE\n");
10511                         bnx2x_eee_disable(phy, params, vars);
10512                 }
10513         } else {
10514                 vars->eee_status &= ~SHMEM_EEE_1G_ADV <<
10515                                     SHMEM_EEE_SUPPORTED_SHIFT;
10516
10517                 if (phy->flags & FLAGS_EEE) {
10518                         /* Handle legacy auto-grEEEn */
10519                         if (params->feature_config_flags &
10520                             FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
10521                                 temp = 6;
10522                                 DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
10523                         } else {
10524                                 temp = 0;
10525                                 DP(NETIF_MSG_LINK, "Don't Adv. EEE\n");
10526                         }
10527                         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
10528                                          MDIO_AN_REG_EEE_ADV, temp);
10529                 }
10530         }
10531
10532         bnx2x_cl22_write(bp, phy,
10533                         0x04,
10534                         an_10_100_val | fc_val);
10535
10536         if (phy->req_duplex == DUPLEX_FULL)
10537                 autoneg_val |= (1<<8);
10538
10539         bnx2x_cl22_write(bp, phy,
10540                         MDIO_PMA_REG_CTRL, autoneg_val);
10541
10542         return 0;
10543 }
10544
10545
10546 static void bnx2x_5461x_set_link_led(struct bnx2x_phy *phy,
10547                                        struct link_params *params, u8 mode)
10548 {
10549         struct bnx2x *bp = params->bp;
10550         u16 temp;
10551
10552         bnx2x_cl22_write(bp, phy,
10553                 MDIO_REG_GPHY_SHADOW,
10554                 MDIO_REG_GPHY_SHADOW_LED_SEL1);
10555         bnx2x_cl22_read(bp, phy,
10556                 MDIO_REG_GPHY_SHADOW,
10557                 &temp);
10558         temp &= 0xff00;
10559
10560         DP(NETIF_MSG_LINK, "54618x set link led (mode=%x)\n", mode);
10561         switch (mode) {
10562         case LED_MODE_FRONT_PANEL_OFF:
10563         case LED_MODE_OFF:
10564                 temp |= 0x00ee;
10565                 break;
10566         case LED_MODE_OPER:
10567                 temp |= 0x0001;
10568                 break;
10569         case LED_MODE_ON:
10570                 temp |= 0x00ff;
10571                 break;
10572         default:
10573                 break;
10574         }
10575         bnx2x_cl22_write(bp, phy,
10576                 MDIO_REG_GPHY_SHADOW,
10577                 MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
10578         return;
10579 }
10580
10581
10582 static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
10583                                      struct link_params *params)
10584 {
10585         struct bnx2x *bp = params->bp;
10586         u32 cfg_pin;
10587         u8 port;
10588
10589         /* In case of no EPIO routed to reset the GPHY, put it
10590          * in low power mode.
10591          */
10592         bnx2x_cl22_write(bp, phy, MDIO_PMA_REG_CTRL, 0x800);
10593         /* This works with E3 only, no need to check the chip
10594          * before determining the port.
10595          */
10596         port = params->port;
10597         cfg_pin = (REG_RD(bp, params->shmem_base +
10598                         offsetof(struct shmem_region,
10599                         dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
10600                         PORT_HW_CFG_E3_PHY_RESET_MASK) >>
10601                         PORT_HW_CFG_E3_PHY_RESET_SHIFT;
10602
10603         /* Drive pin low to put GPHY in reset. */
10604         bnx2x_set_cfg_pin(bp, cfg_pin, 0);
10605 }
10606
10607 static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
10608                                     struct link_params *params,
10609                                     struct link_vars *vars)
10610 {
10611         struct bnx2x *bp = params->bp;
10612         u16 val;
10613         u8 link_up = 0;
10614         u16 legacy_status, legacy_speed;
10615
10616         /* Get speed operation status */
10617         bnx2x_cl22_read(bp, phy,
10618                         MDIO_REG_GPHY_AUX_STATUS,
10619                         &legacy_status);
10620         DP(NETIF_MSG_LINK, "54618SE read_status: 0x%x\n", legacy_status);
10621
10622         /* Read status to clear the PHY interrupt. */
10623         bnx2x_cl22_read(bp, phy,
10624                         MDIO_REG_INTR_STATUS,
10625                         &val);
10626
10627         link_up = ((legacy_status & (1<<2)) == (1<<2));
10628
10629         if (link_up) {
10630                 legacy_speed = (legacy_status & (7<<8));
10631                 if (legacy_speed == (7<<8)) {
10632                         vars->line_speed = SPEED_1000;
10633                         vars->duplex = DUPLEX_FULL;
10634                 } else if (legacy_speed == (6<<8)) {
10635                         vars->line_speed = SPEED_1000;
10636                         vars->duplex = DUPLEX_HALF;
10637                 } else if (legacy_speed == (5<<8)) {
10638                         vars->line_speed = SPEED_100;
10639                         vars->duplex = DUPLEX_FULL;
10640                 }
10641                 /* Omitting 100Base-T4 for now */
10642                 else if (legacy_speed == (3<<8)) {
10643                         vars->line_speed = SPEED_100;
10644                         vars->duplex = DUPLEX_HALF;
10645                 } else if (legacy_speed == (2<<8)) {
10646                         vars->line_speed = SPEED_10;
10647                         vars->duplex = DUPLEX_FULL;
10648                 } else if (legacy_speed == (1<<8)) {
10649                         vars->line_speed = SPEED_10;
10650                         vars->duplex = DUPLEX_HALF;
10651                 } else /* Should not happen */
10652                         vars->line_speed = 0;
10653
10654                 DP(NETIF_MSG_LINK,
10655                    "Link is up in %dMbps, is_duplex_full= %d\n",
10656                    vars->line_speed,
10657                    (vars->duplex == DUPLEX_FULL));
10658
10659                 /* Check legacy speed AN resolution */
10660                 bnx2x_cl22_read(bp, phy,
10661                                 0x01,
10662                                 &val);
10663                 if (val & (1<<5))
10664                         vars->link_status |=
10665                                 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
10666                 bnx2x_cl22_read(bp, phy,
10667                                 0x06,
10668                                 &val);
10669                 if ((val & (1<<0)) == 0)
10670                         vars->link_status |=
10671                                 LINK_STATUS_PARALLEL_DETECTION_USED;
10672
10673                 DP(NETIF_MSG_LINK, "BCM54618SE: link speed is %d\n",
10674                            vars->line_speed);
10675
10676                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10677
10678                 if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
10679                         /* Report LP advertised speeds */
10680                         bnx2x_cl22_read(bp, phy, 0x5, &val);
10681
10682                         if (val & (1<<5))
10683                                 vars->link_status |=
10684                                   LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
10685                         if (val & (1<<6))
10686                                 vars->link_status |=
10687                                   LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
10688                         if (val & (1<<7))
10689                                 vars->link_status |=
10690                                   LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
10691                         if (val & (1<<8))
10692                                 vars->link_status |=
10693                                   LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
10694                         if (val & (1<<9))
10695                                 vars->link_status |=
10696                                   LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
10697
10698                         bnx2x_cl22_read(bp, phy, 0xa, &val);
10699                         if (val & (1<<10))
10700                                 vars->link_status |=
10701                                   LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
10702                         if (val & (1<<11))
10703                                 vars->link_status |=
10704                                   LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
10705
10706                         if ((phy->flags & FLAGS_EEE) &&
10707                             bnx2x_eee_has_cap(params))
10708                                 bnx2x_eee_an_resolve(phy, params, vars);
10709                 }
10710         }
10711         return link_up;
10712 }
10713
10714 static void bnx2x_54618se_config_loopback(struct bnx2x_phy *phy,
10715                                           struct link_params *params)
10716 {
10717         struct bnx2x *bp = params->bp;
10718         u16 val;
10719         u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
10720
10721         DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54618se\n");
10722
10723         /* Enable master/slave manual mmode and set to master */
10724         /* mii write 9 [bits set 11 12] */
10725         bnx2x_cl22_write(bp, phy, 0x09, 3<<11);
10726
10727         /* forced 1G and disable autoneg */
10728         /* set val [mii read 0] */
10729         /* set val [expr $val & [bits clear 6 12 13]] */
10730         /* set val [expr $val | [bits set 6 8]] */
10731         /* mii write 0 $val */
10732         bnx2x_cl22_read(bp, phy, 0x00, &val);
10733         val &= ~((1<<6) | (1<<12) | (1<<13));
10734         val |= (1<<6) | (1<<8);
10735         bnx2x_cl22_write(bp, phy, 0x00, val);
10736
10737         /* Set external loopback and Tx using 6dB coding */
10738         /* mii write 0x18 7 */
10739         /* set val [mii read 0x18] */
10740         /* mii write 0x18 [expr $val | [bits set 10 15]] */
10741         bnx2x_cl22_write(bp, phy, 0x18, 7);
10742         bnx2x_cl22_read(bp, phy, 0x18, &val);
10743         bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15));
10744
10745         /* This register opens the gate for the UMAC despite its name */
10746         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
10747
10748         /* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
10749          * length used by the MAC receive logic to check frames.
10750          */
10751         REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
10752 }
10753
10754 /******************************************************************/
10755 /*                      SFX7101 PHY SECTION                       */
10756 /******************************************************************/
10757 static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
10758                                        struct link_params *params)
10759 {
10760         struct bnx2x *bp = params->bp;
10761         /* SFX7101_XGXS_TEST1 */
10762         bnx2x_cl45_write(bp, phy,
10763                          MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
10764 }
10765
10766 static int bnx2x_7101_config_init(struct bnx2x_phy *phy,
10767                                   struct link_params *params,
10768                                   struct link_vars *vars)
10769 {
10770         u16 fw_ver1, fw_ver2, val;
10771         struct bnx2x *bp = params->bp;
10772         DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
10773
10774         /* Restore normal power mode*/
10775         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
10776                        MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10777         /* HW reset */
10778         bnx2x_ext_phy_hw_reset(bp, params->port);
10779         bnx2x_wait_reset_complete(bp, phy, params);
10780
10781         bnx2x_cl45_write(bp, phy,
10782                          MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
10783         DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
10784         bnx2x_cl45_write(bp, phy,
10785                          MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
10786
10787         bnx2x_ext_phy_set_pause(params, phy, vars);
10788         /* Restart autoneg */
10789         bnx2x_cl45_read(bp, phy,
10790                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
10791         val |= 0x200;
10792         bnx2x_cl45_write(bp, phy,
10793                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
10794
10795         /* Save spirom version */
10796         bnx2x_cl45_read(bp, phy,
10797                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
10798
10799         bnx2x_cl45_read(bp, phy,
10800                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
10801         bnx2x_save_spirom_version(bp, params->port,
10802                                   (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
10803         return 0;
10804 }
10805
10806 static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
10807                                  struct link_params *params,
10808                                  struct link_vars *vars)
10809 {
10810         struct bnx2x *bp = params->bp;
10811         u8 link_up;
10812         u16 val1, val2;
10813         bnx2x_cl45_read(bp, phy,
10814                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
10815         bnx2x_cl45_read(bp, phy,
10816                         MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
10817         DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
10818                    val2, val1);
10819         bnx2x_cl45_read(bp, phy,
10820                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
10821         bnx2x_cl45_read(bp, phy,
10822                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
10823         DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
10824                    val2, val1);
10825         link_up = ((val1 & 4) == 4);
10826         /* If link is up print the AN outcome of the SFX7101 PHY */
10827         if (link_up) {
10828                 bnx2x_cl45_read(bp, phy,
10829                                 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
10830                                 &val2);
10831                 vars->line_speed = SPEED_10000;
10832                 vars->duplex = DUPLEX_FULL;
10833                 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
10834                            val2, (val2 & (1<<14)));
10835                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
10836                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10837
10838                 /* Read LP advertised speeds */
10839                 if (val2 & (1<<11))
10840                         vars->link_status |=
10841                                 LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
10842         }
10843         return link_up;
10844 }
10845
10846 static int bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
10847 {
10848         if (*len < 5)
10849                 return -EINVAL;
10850         str[0] = (spirom_ver & 0xFF);
10851         str[1] = (spirom_ver & 0xFF00) >> 8;
10852         str[2] = (spirom_ver & 0xFF0000) >> 16;
10853         str[3] = (spirom_ver & 0xFF000000) >> 24;
10854         str[4] = '\0';
10855         *len -= 5;
10856         return 0;
10857 }
10858
10859 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
10860 {
10861         u16 val, cnt;
10862
10863         bnx2x_cl45_read(bp, phy,
10864                         MDIO_PMA_DEVAD,
10865                         MDIO_PMA_REG_7101_RESET, &val);
10866
10867         for (cnt = 0; cnt < 10; cnt++) {
10868                 msleep(50);
10869                 /* Writes a self-clearing reset */
10870                 bnx2x_cl45_write(bp, phy,
10871                                  MDIO_PMA_DEVAD,
10872                                  MDIO_PMA_REG_7101_RESET,
10873                                  (val | (1<<15)));
10874                 /* Wait for clear */
10875                 bnx2x_cl45_read(bp, phy,
10876                                 MDIO_PMA_DEVAD,
10877                                 MDIO_PMA_REG_7101_RESET, &val);
10878
10879                 if ((val & (1<<15)) == 0)
10880                         break;
10881         }
10882 }
10883
10884 static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
10885                                 struct link_params *params) {
10886         /* Low power mode is controlled by GPIO 2 */
10887         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
10888                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10889         /* The PHY reset is controlled by GPIO 1 */
10890         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10891                        MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10892 }
10893
10894 static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
10895                                     struct link_params *params, u8 mode)
10896 {
10897         u16 val = 0;
10898         struct bnx2x *bp = params->bp;
10899         switch (mode) {
10900         case LED_MODE_FRONT_PANEL_OFF:
10901         case LED_MODE_OFF:
10902                 val = 2;
10903                 break;
10904         case LED_MODE_ON:
10905                 val = 1;
10906                 break;
10907         case LED_MODE_OPER:
10908                 val = 0;
10909                 break;
10910         }
10911         bnx2x_cl45_write(bp, phy,
10912                          MDIO_PMA_DEVAD,
10913                          MDIO_PMA_REG_7107_LINK_LED_CNTL,
10914                          val);
10915 }
10916
10917 /******************************************************************/
10918 /*                      STATIC PHY DECLARATION                    */
10919 /******************************************************************/
10920
10921 static struct bnx2x_phy phy_null = {
10922         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
10923         .addr           = 0,
10924         .def_md_devad   = 0,
10925         .flags          = FLAGS_INIT_XGXS_FIRST,
10926         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10927         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10928         .mdio_ctrl      = 0,
10929         .supported      = 0,
10930         .media_type     = ETH_PHY_NOT_PRESENT,
10931         .ver_addr       = 0,
10932         .req_flow_ctrl  = 0,
10933         .req_line_speed = 0,
10934         .speed_cap_mask = 0,
10935         .req_duplex     = 0,
10936         .rsrv           = 0,
10937         .config_init    = (config_init_t)NULL,
10938         .read_status    = (read_status_t)NULL,
10939         .link_reset     = (link_reset_t)NULL,
10940         .config_loopback = (config_loopback_t)NULL,
10941         .format_fw_ver  = (format_fw_ver_t)NULL,
10942         .hw_reset       = (hw_reset_t)NULL,
10943         .set_link_led   = (set_link_led_t)NULL,
10944         .phy_specific_func = (phy_specific_func_t)NULL
10945 };
10946
10947 static struct bnx2x_phy phy_serdes = {
10948         .type           = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
10949         .addr           = 0xff,
10950         .def_md_devad   = 0,
10951         .flags          = 0,
10952         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10953         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10954         .mdio_ctrl      = 0,
10955         .supported      = (SUPPORTED_10baseT_Half |
10956                            SUPPORTED_10baseT_Full |
10957                            SUPPORTED_100baseT_Half |
10958                            SUPPORTED_100baseT_Full |
10959                            SUPPORTED_1000baseT_Full |
10960                            SUPPORTED_2500baseX_Full |
10961                            SUPPORTED_TP |
10962                            SUPPORTED_Autoneg |
10963                            SUPPORTED_Pause |
10964                            SUPPORTED_Asym_Pause),
10965         .media_type     = ETH_PHY_BASE_T,
10966         .ver_addr       = 0,
10967         .req_flow_ctrl  = 0,
10968         .req_line_speed = 0,
10969         .speed_cap_mask = 0,
10970         .req_duplex     = 0,
10971         .rsrv           = 0,
10972         .config_init    = (config_init_t)bnx2x_xgxs_config_init,
10973         .read_status    = (read_status_t)bnx2x_link_settings_status,
10974         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
10975         .config_loopback = (config_loopback_t)NULL,
10976         .format_fw_ver  = (format_fw_ver_t)NULL,
10977         .hw_reset       = (hw_reset_t)NULL,
10978         .set_link_led   = (set_link_led_t)NULL,
10979         .phy_specific_func = (phy_specific_func_t)NULL
10980 };
10981
10982 static struct bnx2x_phy phy_xgxs = {
10983         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
10984         .addr           = 0xff,
10985         .def_md_devad   = 0,
10986         .flags          = 0,
10987         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10988         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10989         .mdio_ctrl      = 0,
10990         .supported      = (SUPPORTED_10baseT_Half |
10991                            SUPPORTED_10baseT_Full |
10992                            SUPPORTED_100baseT_Half |
10993                            SUPPORTED_100baseT_Full |
10994                            SUPPORTED_1000baseT_Full |
10995                            SUPPORTED_2500baseX_Full |
10996                            SUPPORTED_10000baseT_Full |
10997                            SUPPORTED_FIBRE |
10998                            SUPPORTED_Autoneg |
10999                            SUPPORTED_Pause |
11000                            SUPPORTED_Asym_Pause),
11001         .media_type     = ETH_PHY_CX4,
11002         .ver_addr       = 0,
11003         .req_flow_ctrl  = 0,
11004         .req_line_speed = 0,
11005         .speed_cap_mask = 0,
11006         .req_duplex     = 0,
11007         .rsrv           = 0,
11008         .config_init    = (config_init_t)bnx2x_xgxs_config_init,
11009         .read_status    = (read_status_t)bnx2x_link_settings_status,
11010         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
11011         .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
11012         .format_fw_ver  = (format_fw_ver_t)NULL,
11013         .hw_reset       = (hw_reset_t)NULL,
11014         .set_link_led   = (set_link_led_t)NULL,
11015         .phy_specific_func = (phy_specific_func_t)bnx2x_xgxs_specific_func
11016 };
11017 static struct bnx2x_phy phy_warpcore = {
11018         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
11019         .addr           = 0xff,
11020         .def_md_devad   = 0,
11021         .flags          = (FLAGS_HW_LOCK_REQUIRED |
11022                            FLAGS_TX_ERROR_CHECK),
11023         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11024         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11025         .mdio_ctrl      = 0,
11026         .supported      = (SUPPORTED_10baseT_Half |
11027                            SUPPORTED_10baseT_Full |
11028                            SUPPORTED_100baseT_Half |
11029                            SUPPORTED_100baseT_Full |
11030                            SUPPORTED_1000baseT_Full |
11031                            SUPPORTED_10000baseT_Full |
11032                            SUPPORTED_20000baseKR2_Full |
11033                            SUPPORTED_20000baseMLD2_Full |
11034                            SUPPORTED_FIBRE |
11035                            SUPPORTED_Autoneg |
11036                            SUPPORTED_Pause |
11037                            SUPPORTED_Asym_Pause),
11038         .media_type     = ETH_PHY_UNSPECIFIED,
11039         .ver_addr       = 0,
11040         .req_flow_ctrl  = 0,
11041         .req_line_speed = 0,
11042         .speed_cap_mask = 0,
11043         /* req_duplex = */0,
11044         /* rsrv = */0,
11045         .config_init    = (config_init_t)bnx2x_warpcore_config_init,
11046         .read_status    = (read_status_t)bnx2x_warpcore_read_status,
11047         .link_reset     = (link_reset_t)bnx2x_warpcore_link_reset,
11048         .config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback,
11049         .format_fw_ver  = (format_fw_ver_t)NULL,
11050         .hw_reset       = (hw_reset_t)bnx2x_warpcore_hw_reset,
11051         .set_link_led   = (set_link_led_t)NULL,
11052         .phy_specific_func = (phy_specific_func_t)NULL
11053 };
11054
11055
11056 static struct bnx2x_phy phy_7101 = {
11057         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
11058         .addr           = 0xff,
11059         .def_md_devad   = 0,
11060         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
11061         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11062         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11063         .mdio_ctrl      = 0,
11064         .supported      = (SUPPORTED_10000baseT_Full |
11065                            SUPPORTED_TP |
11066                            SUPPORTED_Autoneg |
11067                            SUPPORTED_Pause |
11068                            SUPPORTED_Asym_Pause),
11069         .media_type     = ETH_PHY_BASE_T,
11070         .ver_addr       = 0,
11071         .req_flow_ctrl  = 0,
11072         .req_line_speed = 0,
11073         .speed_cap_mask = 0,
11074         .req_duplex     = 0,
11075         .rsrv           = 0,
11076         .config_init    = (config_init_t)bnx2x_7101_config_init,
11077         .read_status    = (read_status_t)bnx2x_7101_read_status,
11078         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
11079         .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
11080         .format_fw_ver  = (format_fw_ver_t)bnx2x_7101_format_ver,
11081         .hw_reset       = (hw_reset_t)bnx2x_7101_hw_reset,
11082         .set_link_led   = (set_link_led_t)bnx2x_7101_set_link_led,
11083         .phy_specific_func = (phy_specific_func_t)NULL
11084 };
11085 static struct bnx2x_phy phy_8073 = {
11086         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
11087         .addr           = 0xff,
11088         .def_md_devad   = 0,
11089         .flags          = FLAGS_HW_LOCK_REQUIRED,
11090         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11091         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11092         .mdio_ctrl      = 0,
11093         .supported      = (SUPPORTED_10000baseT_Full |
11094                            SUPPORTED_2500baseX_Full |
11095                            SUPPORTED_1000baseT_Full |
11096                            SUPPORTED_FIBRE |
11097                            SUPPORTED_Autoneg |
11098                            SUPPORTED_Pause |
11099                            SUPPORTED_Asym_Pause),
11100         .media_type     = ETH_PHY_KR,
11101         .ver_addr       = 0,
11102         .req_flow_ctrl  = 0,
11103         .req_line_speed = 0,
11104         .speed_cap_mask = 0,
11105         .req_duplex     = 0,
11106         .rsrv           = 0,
11107         .config_init    = (config_init_t)bnx2x_8073_config_init,
11108         .read_status    = (read_status_t)bnx2x_8073_read_status,
11109         .link_reset     = (link_reset_t)bnx2x_8073_link_reset,
11110         .config_loopback = (config_loopback_t)NULL,
11111         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
11112         .hw_reset       = (hw_reset_t)NULL,
11113         .set_link_led   = (set_link_led_t)NULL,
11114         .phy_specific_func = (phy_specific_func_t)bnx2x_8073_specific_func
11115 };
11116 static struct bnx2x_phy phy_8705 = {
11117         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
11118         .addr           = 0xff,
11119         .def_md_devad   = 0,
11120         .flags          = FLAGS_INIT_XGXS_FIRST,
11121         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11122         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11123         .mdio_ctrl      = 0,
11124         .supported      = (SUPPORTED_10000baseT_Full |
11125                            SUPPORTED_FIBRE |
11126                            SUPPORTED_Pause |
11127                            SUPPORTED_Asym_Pause),
11128         .media_type     = ETH_PHY_XFP_FIBER,
11129         .ver_addr       = 0,
11130         .req_flow_ctrl  = 0,
11131         .req_line_speed = 0,
11132         .speed_cap_mask = 0,
11133         .req_duplex     = 0,
11134         .rsrv           = 0,
11135         .config_init    = (config_init_t)bnx2x_8705_config_init,
11136         .read_status    = (read_status_t)bnx2x_8705_read_status,
11137         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
11138         .config_loopback = (config_loopback_t)NULL,
11139         .format_fw_ver  = (format_fw_ver_t)bnx2x_null_format_ver,
11140         .hw_reset       = (hw_reset_t)NULL,
11141         .set_link_led   = (set_link_led_t)NULL,
11142         .phy_specific_func = (phy_specific_func_t)NULL
11143 };
11144 static struct bnx2x_phy phy_8706 = {
11145         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
11146         .addr           = 0xff,
11147         .def_md_devad   = 0,
11148         .flags          = FLAGS_INIT_XGXS_FIRST,
11149         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11150         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11151         .mdio_ctrl      = 0,
11152         .supported      = (SUPPORTED_10000baseT_Full |
11153                            SUPPORTED_1000baseT_Full |
11154                            SUPPORTED_FIBRE |
11155                            SUPPORTED_Pause |
11156                            SUPPORTED_Asym_Pause),
11157         .media_type     = ETH_PHY_SFPP_10G_FIBER,
11158         .ver_addr       = 0,
11159         .req_flow_ctrl  = 0,
11160         .req_line_speed = 0,
11161         .speed_cap_mask = 0,
11162         .req_duplex     = 0,
11163         .rsrv           = 0,
11164         .config_init    = (config_init_t)bnx2x_8706_config_init,
11165         .read_status    = (read_status_t)bnx2x_8706_read_status,
11166         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
11167         .config_loopback = (config_loopback_t)NULL,
11168         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
11169         .hw_reset       = (hw_reset_t)NULL,
11170         .set_link_led   = (set_link_led_t)NULL,
11171         .phy_specific_func = (phy_specific_func_t)NULL
11172 };
11173
11174 static struct bnx2x_phy phy_8726 = {
11175         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
11176         .addr           = 0xff,
11177         .def_md_devad   = 0,
11178         .flags          = (FLAGS_HW_LOCK_REQUIRED |
11179                            FLAGS_INIT_XGXS_FIRST |
11180                            FLAGS_TX_ERROR_CHECK),
11181         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11182         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11183         .mdio_ctrl      = 0,
11184         .supported      = (SUPPORTED_10000baseT_Full |
11185                            SUPPORTED_1000baseT_Full |
11186                            SUPPORTED_Autoneg |
11187                            SUPPORTED_FIBRE |
11188                            SUPPORTED_Pause |
11189                            SUPPORTED_Asym_Pause),
11190         .media_type     = ETH_PHY_NOT_PRESENT,
11191         .ver_addr       = 0,
11192         .req_flow_ctrl  = 0,
11193         .req_line_speed = 0,
11194         .speed_cap_mask = 0,
11195         .req_duplex     = 0,
11196         .rsrv           = 0,
11197         .config_init    = (config_init_t)bnx2x_8726_config_init,
11198         .read_status    = (read_status_t)bnx2x_8726_read_status,
11199         .link_reset     = (link_reset_t)bnx2x_8726_link_reset,
11200         .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
11201         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
11202         .hw_reset       = (hw_reset_t)NULL,
11203         .set_link_led   = (set_link_led_t)NULL,
11204         .phy_specific_func = (phy_specific_func_t)NULL
11205 };
11206
11207 static struct bnx2x_phy phy_8727 = {
11208         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
11209         .addr           = 0xff,
11210         .def_md_devad   = 0,
11211         .flags          = (FLAGS_FAN_FAILURE_DET_REQ |
11212                            FLAGS_TX_ERROR_CHECK),
11213         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11214         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11215         .mdio_ctrl      = 0,
11216         .supported      = (SUPPORTED_10000baseT_Full |
11217                            SUPPORTED_1000baseT_Full |
11218                            SUPPORTED_FIBRE |
11219                            SUPPORTED_Pause |
11220                            SUPPORTED_Asym_Pause),
11221         .media_type     = ETH_PHY_NOT_PRESENT,
11222         .ver_addr       = 0,
11223         .req_flow_ctrl  = 0,
11224         .req_line_speed = 0,
11225         .speed_cap_mask = 0,
11226         .req_duplex     = 0,
11227         .rsrv           = 0,
11228         .config_init    = (config_init_t)bnx2x_8727_config_init,
11229         .read_status    = (read_status_t)bnx2x_8727_read_status,
11230         .link_reset     = (link_reset_t)bnx2x_8727_link_reset,
11231         .config_loopback = (config_loopback_t)NULL,
11232         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
11233         .hw_reset       = (hw_reset_t)bnx2x_8727_hw_reset,
11234         .set_link_led   = (set_link_led_t)bnx2x_8727_set_link_led,
11235         .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
11236 };
11237 static struct bnx2x_phy phy_8481 = {
11238         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
11239         .addr           = 0xff,
11240         .def_md_devad   = 0,
11241         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
11242                           FLAGS_REARM_LATCH_SIGNAL,
11243         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11244         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11245         .mdio_ctrl      = 0,
11246         .supported      = (SUPPORTED_10baseT_Half |
11247                            SUPPORTED_10baseT_Full |
11248                            SUPPORTED_100baseT_Half |
11249                            SUPPORTED_100baseT_Full |
11250                            SUPPORTED_1000baseT_Full |
11251                            SUPPORTED_10000baseT_Full |
11252                            SUPPORTED_TP |
11253                            SUPPORTED_Autoneg |
11254                            SUPPORTED_Pause |
11255                            SUPPORTED_Asym_Pause),
11256         .media_type     = ETH_PHY_BASE_T,
11257         .ver_addr       = 0,
11258         .req_flow_ctrl  = 0,
11259         .req_line_speed = 0,
11260         .speed_cap_mask = 0,
11261         .req_duplex     = 0,
11262         .rsrv           = 0,
11263         .config_init    = (config_init_t)bnx2x_8481_config_init,
11264         .read_status    = (read_status_t)bnx2x_848xx_read_status,
11265         .link_reset     = (link_reset_t)bnx2x_8481_link_reset,
11266         .config_loopback = (config_loopback_t)NULL,
11267         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
11268         .hw_reset       = (hw_reset_t)bnx2x_8481_hw_reset,
11269         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
11270         .phy_specific_func = (phy_specific_func_t)NULL
11271 };
11272
11273 static struct bnx2x_phy phy_84823 = {
11274         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
11275         .addr           = 0xff,
11276         .def_md_devad   = 0,
11277         .flags          = (FLAGS_FAN_FAILURE_DET_REQ |
11278                            FLAGS_REARM_LATCH_SIGNAL |
11279                            FLAGS_TX_ERROR_CHECK),
11280         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11281         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11282         .mdio_ctrl      = 0,
11283         .supported      = (SUPPORTED_10baseT_Half |
11284                            SUPPORTED_10baseT_Full |
11285                            SUPPORTED_100baseT_Half |
11286                            SUPPORTED_100baseT_Full |
11287                            SUPPORTED_1000baseT_Full |
11288                            SUPPORTED_10000baseT_Full |
11289                            SUPPORTED_TP |
11290                            SUPPORTED_Autoneg |
11291                            SUPPORTED_Pause |
11292                            SUPPORTED_Asym_Pause),
11293         .media_type     = ETH_PHY_BASE_T,
11294         .ver_addr       = 0,
11295         .req_flow_ctrl  = 0,
11296         .req_line_speed = 0,
11297         .speed_cap_mask = 0,
11298         .req_duplex     = 0,
11299         .rsrv           = 0,
11300         .config_init    = (config_init_t)bnx2x_848x3_config_init,
11301         .read_status    = (read_status_t)bnx2x_848xx_read_status,
11302         .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
11303         .config_loopback = (config_loopback_t)NULL,
11304         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
11305         .hw_reset       = (hw_reset_t)NULL,
11306         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
11307         .phy_specific_func = (phy_specific_func_t)bnx2x_848xx_specific_func
11308 };
11309
11310 static struct bnx2x_phy phy_84833 = {
11311         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
11312         .addr           = 0xff,
11313         .def_md_devad   = 0,
11314         .flags          = (FLAGS_FAN_FAILURE_DET_REQ |
11315                            FLAGS_REARM_LATCH_SIGNAL |
11316                            FLAGS_TX_ERROR_CHECK),
11317         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11318         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11319         .mdio_ctrl      = 0,
11320         .supported      = (SUPPORTED_100baseT_Half |
11321                            SUPPORTED_100baseT_Full |
11322                            SUPPORTED_1000baseT_Full |
11323                            SUPPORTED_10000baseT_Full |
11324                            SUPPORTED_TP |
11325                            SUPPORTED_Autoneg |
11326                            SUPPORTED_Pause |
11327                            SUPPORTED_Asym_Pause),
11328         .media_type     = ETH_PHY_BASE_T,
11329         .ver_addr       = 0,
11330         .req_flow_ctrl  = 0,
11331         .req_line_speed = 0,
11332         .speed_cap_mask = 0,
11333         .req_duplex     = 0,
11334         .rsrv           = 0,
11335         .config_init    = (config_init_t)bnx2x_848x3_config_init,
11336         .read_status    = (read_status_t)bnx2x_848xx_read_status,
11337         .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
11338         .config_loopback = (config_loopback_t)NULL,
11339         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
11340         .hw_reset       = (hw_reset_t)bnx2x_84833_hw_reset_phy,
11341         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
11342         .phy_specific_func = (phy_specific_func_t)bnx2x_848xx_specific_func
11343 };
11344
11345 static struct bnx2x_phy phy_54618se = {
11346         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE,
11347         .addr           = 0xff,
11348         .def_md_devad   = 0,
11349         .flags          = FLAGS_INIT_XGXS_FIRST,
11350         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11351         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11352         .mdio_ctrl      = 0,
11353         .supported      = (SUPPORTED_10baseT_Half |
11354                            SUPPORTED_10baseT_Full |
11355                            SUPPORTED_100baseT_Half |
11356                            SUPPORTED_100baseT_Full |
11357                            SUPPORTED_1000baseT_Full |
11358                            SUPPORTED_TP |
11359                            SUPPORTED_Autoneg |
11360                            SUPPORTED_Pause |
11361                            SUPPORTED_Asym_Pause),
11362         .media_type     = ETH_PHY_BASE_T,
11363         .ver_addr       = 0,
11364         .req_flow_ctrl  = 0,
11365         .req_line_speed = 0,
11366         .speed_cap_mask = 0,
11367         /* req_duplex = */0,
11368         /* rsrv = */0,
11369         .config_init    = (config_init_t)bnx2x_54618se_config_init,
11370         .read_status    = (read_status_t)bnx2x_54618se_read_status,
11371         .link_reset     = (link_reset_t)bnx2x_54618se_link_reset,
11372         .config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
11373         .format_fw_ver  = (format_fw_ver_t)NULL,
11374         .hw_reset       = (hw_reset_t)NULL,
11375         .set_link_led   = (set_link_led_t)bnx2x_5461x_set_link_led,
11376         .phy_specific_func = (phy_specific_func_t)bnx2x_54618se_specific_func
11377 };
11378 /*****************************************************************/
11379 /*                                                               */
11380 /* Populate the phy according. Main function: bnx2x_populate_phy   */
11381 /*                                                               */
11382 /*****************************************************************/
11383
11384 static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
11385                                      struct bnx2x_phy *phy, u8 port,
11386                                      u8 phy_index)
11387 {
11388         /* Get the 4 lanes xgxs config rx and tx */
11389         u32 rx = 0, tx = 0, i;
11390         for (i = 0; i < 2; i++) {
11391                 /* INT_PHY and EXT_PHY1 share the same value location in
11392                  * the shmem. When num_phys is greater than 1, than this value
11393                  * applies only to EXT_PHY1
11394                  */
11395                 if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
11396                         rx = REG_RD(bp, shmem_base +
11397                                     offsetof(struct shmem_region,
11398                           dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
11399
11400                         tx = REG_RD(bp, shmem_base +
11401                                     offsetof(struct shmem_region,
11402                           dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
11403                 } else {
11404                         rx = REG_RD(bp, shmem_base +
11405                                     offsetof(struct shmem_region,
11406                          dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11407
11408                         tx = REG_RD(bp, shmem_base +
11409                                     offsetof(struct shmem_region,
11410                          dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11411                 }
11412
11413                 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
11414                 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
11415
11416                 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
11417                 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
11418         }
11419 }
11420
11421 static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
11422                                     u8 phy_index, u8 port)
11423 {
11424         u32 ext_phy_config = 0;
11425         switch (phy_index) {
11426         case EXT_PHY1:
11427                 ext_phy_config = REG_RD(bp, shmem_base +
11428                                               offsetof(struct shmem_region,
11429                         dev_info.port_hw_config[port].external_phy_config));
11430                 break;
11431         case EXT_PHY2:
11432                 ext_phy_config = REG_RD(bp, shmem_base +
11433                                               offsetof(struct shmem_region,
11434                         dev_info.port_hw_config[port].external_phy_config2));
11435                 break;
11436         default:
11437                 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
11438                 return -EINVAL;
11439         }
11440
11441         return ext_phy_config;
11442 }
11443 static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
11444                                   struct bnx2x_phy *phy)
11445 {
11446         u32 phy_addr;
11447         u32 chip_id;
11448         u32 switch_cfg = (REG_RD(bp, shmem_base +
11449                                        offsetof(struct shmem_region,
11450                         dev_info.port_feature_config[port].link_config)) &
11451                           PORT_FEATURE_CONNECTED_SWITCH_MASK);
11452         chip_id = (REG_RD(bp, MISC_REG_CHIP_NUM) << 16) |
11453                 ((REG_RD(bp, MISC_REG_CHIP_REV) & 0xf) << 12);
11454
11455         DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id);
11456         if (USES_WARPCORE(bp)) {
11457                 u32 serdes_net_if;
11458                 phy_addr = REG_RD(bp,
11459                                   MISC_REG_WC0_CTRL_PHY_ADDR);
11460                 *phy = phy_warpcore;
11461                 if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
11462                         phy->flags |= FLAGS_4_PORT_MODE;
11463                 else
11464                         phy->flags &= ~FLAGS_4_PORT_MODE;
11465                         /* Check Dual mode */
11466                 serdes_net_if = (REG_RD(bp, shmem_base +
11467                                         offsetof(struct shmem_region, dev_info.
11468                                         port_hw_config[port].default_cfg)) &
11469                                  PORT_HW_CFG_NET_SERDES_IF_MASK);
11470                 /* Set the appropriate supported and flags indications per
11471                  * interface type of the chip
11472                  */
11473                 switch (serdes_net_if) {
11474                 case PORT_HW_CFG_NET_SERDES_IF_SGMII:
11475                         phy->supported &= (SUPPORTED_10baseT_Half |
11476                                            SUPPORTED_10baseT_Full |
11477                                            SUPPORTED_100baseT_Half |
11478                                            SUPPORTED_100baseT_Full |
11479                                            SUPPORTED_1000baseT_Full |
11480                                            SUPPORTED_FIBRE |
11481                                            SUPPORTED_Autoneg |
11482                                            SUPPORTED_Pause |
11483                                            SUPPORTED_Asym_Pause);
11484                         phy->media_type = ETH_PHY_BASE_T;
11485                         break;
11486                 case PORT_HW_CFG_NET_SERDES_IF_XFI:
11487                         phy->media_type = ETH_PHY_XFP_FIBER;
11488                         break;
11489                 case PORT_HW_CFG_NET_SERDES_IF_SFI:
11490                         phy->supported &= (SUPPORTED_1000baseT_Full |
11491                                            SUPPORTED_10000baseT_Full |
11492                                            SUPPORTED_FIBRE |
11493                                            SUPPORTED_Pause |
11494                                            SUPPORTED_Asym_Pause);
11495                         phy->media_type = ETH_PHY_SFPP_10G_FIBER;
11496                         break;
11497                 case PORT_HW_CFG_NET_SERDES_IF_KR:
11498                         phy->media_type = ETH_PHY_KR;
11499                         phy->supported &= (SUPPORTED_1000baseT_Full |
11500                                            SUPPORTED_10000baseT_Full |
11501                                            SUPPORTED_FIBRE |
11502                                            SUPPORTED_Autoneg |
11503                                            SUPPORTED_Pause |
11504                                            SUPPORTED_Asym_Pause);
11505                         break;
11506                 case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
11507                         phy->media_type = ETH_PHY_KR;
11508                         phy->flags |= FLAGS_WC_DUAL_MODE;
11509                         phy->supported &= (SUPPORTED_20000baseMLD2_Full |
11510                                            SUPPORTED_FIBRE |
11511                                            SUPPORTED_Pause |
11512                                            SUPPORTED_Asym_Pause);
11513                         break;
11514                 case PORT_HW_CFG_NET_SERDES_IF_KR2:
11515                         phy->media_type = ETH_PHY_KR;
11516                         phy->flags |= FLAGS_WC_DUAL_MODE;
11517                         phy->supported &= (SUPPORTED_20000baseKR2_Full |
11518                                            SUPPORTED_FIBRE |
11519                                            SUPPORTED_Pause |
11520                                            SUPPORTED_Asym_Pause);
11521                         break;
11522                 default:
11523                         DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n",
11524                                        serdes_net_if);
11525                         break;
11526                 }
11527
11528                 /* Enable MDC/MDIO work-around for E3 A0 since free running MDC
11529                  * was not set as expected. For B0, ECO will be enabled so there
11530                  * won't be an issue there
11531                  */
11532                 if (CHIP_REV(bp) == CHIP_REV_Ax)
11533                         phy->flags |= FLAGS_MDC_MDIO_WA;
11534                 else
11535                         phy->flags |= FLAGS_MDC_MDIO_WA_B0;
11536         } else {
11537                 switch (switch_cfg) {
11538                 case SWITCH_CFG_1G:
11539                         phy_addr = REG_RD(bp,
11540                                           NIG_REG_SERDES0_CTRL_PHY_ADDR +
11541                                           port * 0x10);
11542                         *phy = phy_serdes;
11543                         break;
11544                 case SWITCH_CFG_10G:
11545                         phy_addr = REG_RD(bp,
11546                                           NIG_REG_XGXS0_CTRL_PHY_ADDR +
11547                                           port * 0x18);
11548                         *phy = phy_xgxs;
11549                         break;
11550                 default:
11551                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
11552                         return -EINVAL;
11553                 }
11554         }
11555         phy->addr = (u8)phy_addr;
11556         phy->mdio_ctrl = bnx2x_get_emac_base(bp,
11557                                             SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
11558                                             port);
11559         if (CHIP_IS_E2(bp))
11560                 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
11561         else
11562                 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
11563
11564         DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
11565                    port, phy->addr, phy->mdio_ctrl);
11566
11567         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
11568         return 0;
11569 }
11570
11571 static int bnx2x_populate_ext_phy(struct bnx2x *bp,
11572                                   u8 phy_index,
11573                                   u32 shmem_base,
11574                                   u32 shmem2_base,
11575                                   u8 port,
11576                                   struct bnx2x_phy *phy)
11577 {
11578         u32 ext_phy_config, phy_type, config2;
11579         u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
11580         ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
11581                                                   phy_index, port);
11582         phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
11583         /* Select the phy type */
11584         switch (phy_type) {
11585         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
11586                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
11587                 *phy = phy_8073;
11588                 break;
11589         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
11590                 *phy = phy_8705;
11591                 break;
11592         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
11593                 *phy = phy_8706;
11594                 break;
11595         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
11596                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11597                 *phy = phy_8726;
11598                 break;
11599         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
11600                 /* BCM8727_NOC => BCM8727 no over current */
11601                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11602                 *phy = phy_8727;
11603                 phy->flags |= FLAGS_NOC;
11604                 break;
11605         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
11606         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
11607                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11608                 *phy = phy_8727;
11609                 break;
11610         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
11611                 *phy = phy_8481;
11612                 break;
11613         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
11614                 *phy = phy_84823;
11615                 break;
11616         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
11617                 *phy = phy_84833;
11618                 break;
11619         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
11620         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
11621                 *phy = phy_54618se;
11622                 if (phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
11623                         phy->flags |= FLAGS_EEE;
11624                 break;
11625         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
11626                 *phy = phy_7101;
11627                 break;
11628         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
11629                 *phy = phy_null;
11630                 return -EINVAL;
11631         default:
11632                 *phy = phy_null;
11633                 /* In case external PHY wasn't found */
11634                 if ((phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
11635                     (phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
11636                         return -EINVAL;
11637                 return 0;
11638         }
11639
11640         phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
11641         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
11642
11643         /* The shmem address of the phy version is located on different
11644          * structures. In case this structure is too old, do not set
11645          * the address
11646          */
11647         config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
11648                                         dev_info.shared_hw_config.config2));
11649         if (phy_index == EXT_PHY1) {
11650                 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
11651                                 port_mb[port].ext_phy_fw_version);
11652
11653                 /* Check specific mdc mdio settings */
11654                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
11655                         mdc_mdio_access = config2 &
11656                         SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
11657         } else {
11658                 u32 size = REG_RD(bp, shmem2_base);
11659
11660                 if (size >
11661                     offsetof(struct shmem2_region, ext_phy_fw_version2)) {
11662                         phy->ver_addr = shmem2_base +
11663                             offsetof(struct shmem2_region,
11664                                      ext_phy_fw_version2[port]);
11665                 }
11666                 /* Check specific mdc mdio settings */
11667                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
11668                         mdc_mdio_access = (config2 &
11669                         SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
11670                         (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
11671                          SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
11672         }
11673         phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
11674
11675         if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
11676             (phy->ver_addr)) {
11677                 /* Remove 100Mb link supported for BCM84833 when phy fw
11678                  * version lower than or equal to 1.39
11679                  */
11680                 u32 raw_ver = REG_RD(bp, phy->ver_addr);
11681                 if (((raw_ver & 0x7F) <= 39) &&
11682                     (((raw_ver & 0xF80) >> 7) <= 1))
11683                         phy->supported &= ~(SUPPORTED_100baseT_Half |
11684                                             SUPPORTED_100baseT_Full);
11685         }
11686
11687         /* In case mdc/mdio_access of the external phy is different than the
11688          * mdc/mdio access of the XGXS, a HW lock must be taken in each access
11689          * to prevent one port interfere with another port's CL45 operations.
11690          */
11691         if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
11692                 phy->flags |= FLAGS_HW_LOCK_REQUIRED;
11693         DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
11694                    phy_type, port, phy_index);
11695         DP(NETIF_MSG_LINK, "             addr=0x%x, mdio_ctl=0x%x\n",
11696                    phy->addr, phy->mdio_ctrl);
11697         return 0;
11698 }
11699
11700 static int bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
11701                               u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
11702 {
11703         int status = 0;
11704         phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
11705         if (phy_index == INT_PHY)
11706                 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
11707         status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
11708                                         port, phy);
11709         return status;
11710 }
11711
11712 static void bnx2x_phy_def_cfg(struct link_params *params,
11713                               struct bnx2x_phy *phy,
11714                               u8 phy_index)
11715 {
11716         struct bnx2x *bp = params->bp;
11717         u32 link_config;
11718         /* Populate the default phy configuration for MF mode */
11719         if (phy_index == EXT_PHY2) {
11720                 link_config = REG_RD(bp, params->shmem_base +
11721                                      offsetof(struct shmem_region, dev_info.
11722                         port_feature_config[params->port].link_config2));
11723                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
11724                                              offsetof(struct shmem_region,
11725                                                       dev_info.
11726                         port_hw_config[params->port].speed_capability_mask2));
11727         } else {
11728                 link_config = REG_RD(bp, params->shmem_base +
11729                                      offsetof(struct shmem_region, dev_info.
11730                                 port_feature_config[params->port].link_config));
11731                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
11732                                              offsetof(struct shmem_region,
11733                                                       dev_info.
11734                         port_hw_config[params->port].speed_capability_mask));
11735         }
11736         DP(NETIF_MSG_LINK,
11737            "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x\n",
11738            phy_index, link_config, phy->speed_cap_mask);
11739
11740         phy->req_duplex = DUPLEX_FULL;
11741         switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
11742         case PORT_FEATURE_LINK_SPEED_10M_HALF:
11743                 phy->req_duplex = DUPLEX_HALF;
11744         case PORT_FEATURE_LINK_SPEED_10M_FULL:
11745                 phy->req_line_speed = SPEED_10;
11746                 break;
11747         case PORT_FEATURE_LINK_SPEED_100M_HALF:
11748                 phy->req_duplex = DUPLEX_HALF;
11749         case PORT_FEATURE_LINK_SPEED_100M_FULL:
11750                 phy->req_line_speed = SPEED_100;
11751                 break;
11752         case PORT_FEATURE_LINK_SPEED_1G:
11753                 phy->req_line_speed = SPEED_1000;
11754                 break;
11755         case PORT_FEATURE_LINK_SPEED_2_5G:
11756                 phy->req_line_speed = SPEED_2500;
11757                 break;
11758         case PORT_FEATURE_LINK_SPEED_10G_CX4:
11759                 phy->req_line_speed = SPEED_10000;
11760                 break;
11761         default:
11762                 phy->req_line_speed = SPEED_AUTO_NEG;
11763                 break;
11764         }
11765
11766         switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
11767         case PORT_FEATURE_FLOW_CONTROL_AUTO:
11768                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
11769                 break;
11770         case PORT_FEATURE_FLOW_CONTROL_TX:
11771                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
11772                 break;
11773         case PORT_FEATURE_FLOW_CONTROL_RX:
11774                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
11775                 break;
11776         case PORT_FEATURE_FLOW_CONTROL_BOTH:
11777                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
11778                 break;
11779         default:
11780                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11781                 break;
11782         }
11783 }
11784
11785 u32 bnx2x_phy_selection(struct link_params *params)
11786 {
11787         u32 phy_config_swapped, prio_cfg;
11788         u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
11789
11790         phy_config_swapped = params->multi_phy_config &
11791                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11792
11793         prio_cfg = params->multi_phy_config &
11794                         PORT_HW_CFG_PHY_SELECTION_MASK;
11795
11796         if (phy_config_swapped) {
11797                 switch (prio_cfg) {
11798                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
11799                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
11800                      break;
11801                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
11802                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
11803                      break;
11804                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
11805                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
11806                      break;
11807                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
11808                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
11809                      break;
11810                 }
11811         } else
11812                 return_cfg = prio_cfg;
11813
11814         return return_cfg;
11815 }
11816
11817
11818 int bnx2x_phy_probe(struct link_params *params)
11819 {
11820         u8 phy_index, actual_phy_idx;
11821         u32 phy_config_swapped, sync_offset, media_types;
11822         struct bnx2x *bp = params->bp;
11823         struct bnx2x_phy *phy;
11824         params->num_phys = 0;
11825         DP(NETIF_MSG_LINK, "Begin phy probe\n");
11826         phy_config_swapped = params->multi_phy_config &
11827                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11828
11829         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
11830               phy_index++) {
11831                 actual_phy_idx = phy_index;
11832                 if (phy_config_swapped) {
11833                         if (phy_index == EXT_PHY1)
11834                                 actual_phy_idx = EXT_PHY2;
11835                         else if (phy_index == EXT_PHY2)
11836                                 actual_phy_idx = EXT_PHY1;
11837                 }
11838                 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
11839                                " actual_phy_idx %x\n", phy_config_swapped,
11840                            phy_index, actual_phy_idx);
11841                 phy = &params->phy[actual_phy_idx];
11842                 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
11843                                        params->shmem2_base, params->port,
11844                                        phy) != 0) {
11845                         params->num_phys = 0;
11846                         DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
11847                                    phy_index);
11848                         for (phy_index = INT_PHY;
11849                               phy_index < MAX_PHYS;
11850                               phy_index++)
11851                                 *phy = phy_null;
11852                         return -EINVAL;
11853                 }
11854                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
11855                         break;
11856
11857                 if (params->feature_config_flags &
11858                     FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET)
11859                         phy->flags &= ~FLAGS_TX_ERROR_CHECK;
11860
11861                 sync_offset = params->shmem_base +
11862                         offsetof(struct shmem_region,
11863                         dev_info.port_hw_config[params->port].media_type);
11864                 media_types = REG_RD(bp, sync_offset);
11865
11866                 /* Update media type for non-PMF sync only for the first time
11867                  * In case the media type changes afterwards, it will be updated
11868                  * using the update_status function
11869                  */
11870                 if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
11871                                     (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
11872                                      actual_phy_idx))) == 0) {
11873                         media_types |= ((phy->media_type &
11874                                         PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
11875                                 (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
11876                                  actual_phy_idx));
11877                 }
11878                 REG_WR(bp, sync_offset, media_types);
11879
11880                 bnx2x_phy_def_cfg(params, phy, phy_index);
11881                 params->num_phys++;
11882         }
11883
11884         DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
11885         return 0;
11886 }
11887
11888 void bnx2x_init_bmac_loopback(struct link_params *params,
11889                               struct link_vars *vars)
11890 {
11891         struct bnx2x *bp = params->bp;
11892                 vars->link_up = 1;
11893                 vars->line_speed = SPEED_10000;
11894                 vars->duplex = DUPLEX_FULL;
11895                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11896                 vars->mac_type = MAC_TYPE_BMAC;
11897
11898                 vars->phy_flags = PHY_XGXS_FLAG;
11899
11900                 bnx2x_xgxs_deassert(params);
11901
11902                 /* set bmac loopback */
11903                 bnx2x_bmac_enable(params, vars, 1, 1);
11904
11905                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11906 }
11907
11908 void bnx2x_init_emac_loopback(struct link_params *params,
11909                               struct link_vars *vars)
11910 {
11911         struct bnx2x *bp = params->bp;
11912                 vars->link_up = 1;
11913                 vars->line_speed = SPEED_1000;
11914                 vars->duplex = DUPLEX_FULL;
11915                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11916                 vars->mac_type = MAC_TYPE_EMAC;
11917
11918                 vars->phy_flags = PHY_XGXS_FLAG;
11919
11920                 bnx2x_xgxs_deassert(params);
11921                 /* set bmac loopback */
11922                 bnx2x_emac_enable(params, vars, 1);
11923                 bnx2x_emac_program(params, vars);
11924                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11925 }
11926
11927 void bnx2x_init_xmac_loopback(struct link_params *params,
11928                               struct link_vars *vars)
11929 {
11930         struct bnx2x *bp = params->bp;
11931         vars->link_up = 1;
11932         if (!params->req_line_speed[0])
11933                 vars->line_speed = SPEED_10000;
11934         else
11935                 vars->line_speed = params->req_line_speed[0];
11936         vars->duplex = DUPLEX_FULL;
11937         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11938         vars->mac_type = MAC_TYPE_XMAC;
11939         vars->phy_flags = PHY_XGXS_FLAG;
11940         /* Set WC to loopback mode since link is required to provide clock
11941          * to the XMAC in 20G mode
11942          */
11943         bnx2x_set_aer_mmd(params, &params->phy[0]);
11944         bnx2x_warpcore_reset_lane(bp, &params->phy[0], 0);
11945         params->phy[INT_PHY].config_loopback(
11946                         &params->phy[INT_PHY],
11947                         params);
11948
11949         bnx2x_xmac_enable(params, vars, 1);
11950         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11951 }
11952
11953 void bnx2x_init_umac_loopback(struct link_params *params,
11954                               struct link_vars *vars)
11955 {
11956         struct bnx2x *bp = params->bp;
11957         vars->link_up = 1;
11958         vars->line_speed = SPEED_1000;
11959         vars->duplex = DUPLEX_FULL;
11960         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11961         vars->mac_type = MAC_TYPE_UMAC;
11962         vars->phy_flags = PHY_XGXS_FLAG;
11963         bnx2x_umac_enable(params, vars, 1);
11964
11965         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11966 }
11967
11968 void bnx2x_init_xgxs_loopback(struct link_params *params,
11969                               struct link_vars *vars)
11970 {
11971         struct bnx2x *bp = params->bp;
11972                 vars->link_up = 1;
11973                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11974                 vars->duplex = DUPLEX_FULL;
11975         if (params->req_line_speed[0] == SPEED_1000)
11976                         vars->line_speed = SPEED_1000;
11977         else
11978                         vars->line_speed = SPEED_10000;
11979
11980         if (!USES_WARPCORE(bp))
11981                 bnx2x_xgxs_deassert(params);
11982         bnx2x_link_initialize(params, vars);
11983
11984         if (params->req_line_speed[0] == SPEED_1000) {
11985                 if (USES_WARPCORE(bp))
11986                         bnx2x_umac_enable(params, vars, 0);
11987                 else {
11988                         bnx2x_emac_program(params, vars);
11989                         bnx2x_emac_enable(params, vars, 0);
11990                 }
11991         } else {
11992                 if (USES_WARPCORE(bp))
11993                         bnx2x_xmac_enable(params, vars, 0);
11994                 else
11995                         bnx2x_bmac_enable(params, vars, 0, 1);
11996         }
11997
11998                 if (params->loopback_mode == LOOPBACK_XGXS) {
11999                         /* set 10G XGXS loopback */
12000                         params->phy[INT_PHY].config_loopback(
12001                                 &params->phy[INT_PHY],
12002                                 params);
12003
12004                 } else {
12005                         /* set external phy loopback */
12006                         u8 phy_index;
12007                         for (phy_index = EXT_PHY1;
12008                               phy_index < params->num_phys; phy_index++) {
12009                                 if (params->phy[phy_index].config_loopback)
12010                                         params->phy[phy_index].config_loopback(
12011                                                 &params->phy[phy_index],
12012                                                 params);
12013                         }
12014                 }
12015                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
12016
12017         bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
12018 }
12019
12020 static void bnx2x_set_rx_filter(struct link_params *params, u8 en)
12021 {
12022         struct bnx2x *bp = params->bp;
12023         u8 val = en * 0x1F;
12024
12025         /* Open the gate between the NIG to the BRB */
12026         if (!CHIP_IS_E1x(bp))
12027                 val |= en * 0x20;
12028         REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK + params->port*4, val);
12029
12030         if (!CHIP_IS_E1(bp)) {
12031                 REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + params->port*4,
12032                        en*0x3);
12033         }
12034
12035         REG_WR(bp, (params->port ? NIG_REG_LLH1_BRB1_NOT_MCP :
12036                     NIG_REG_LLH0_BRB1_NOT_MCP), en);
12037 }
12038 static int bnx2x_avoid_link_flap(struct link_params *params,
12039                                             struct link_vars *vars)
12040 {
12041         u32 phy_idx;
12042         u32 dont_clear_stat, lfa_sts;
12043         struct bnx2x *bp = params->bp;
12044
12045         /* Sync the link parameters */
12046         bnx2x_link_status_update(params, vars);
12047
12048         /*
12049          * The module verification was already done by previous link owner,
12050          * so this call is meant only to get warning message
12051          */
12052
12053         for (phy_idx = INT_PHY; phy_idx < params->num_phys; phy_idx++) {
12054                 struct bnx2x_phy *phy = &params->phy[phy_idx];
12055                 if (phy->phy_specific_func) {
12056                         DP(NETIF_MSG_LINK, "Calling PHY specific func\n");
12057                         phy->phy_specific_func(phy, params, PHY_INIT);
12058                 }
12059                 if ((phy->media_type == ETH_PHY_SFPP_10G_FIBER) ||
12060                     (phy->media_type == ETH_PHY_SFP_1G_FIBER) ||
12061                     (phy->media_type == ETH_PHY_DA_TWINAX))
12062                         bnx2x_verify_sfp_module(phy, params);
12063         }
12064         lfa_sts = REG_RD(bp, params->lfa_base +
12065                          offsetof(struct shmem_lfa,
12066                                   lfa_sts));
12067
12068         dont_clear_stat = lfa_sts & SHMEM_LFA_DONT_CLEAR_STAT;
12069
12070         /* Re-enable the NIG/MAC */
12071         if (CHIP_IS_E3(bp)) {
12072                 if (!dont_clear_stat) {
12073                         REG_WR(bp, GRCBASE_MISC +
12074                                MISC_REGISTERS_RESET_REG_2_CLEAR,
12075                                (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
12076                                 params->port));
12077                         REG_WR(bp, GRCBASE_MISC +
12078                                MISC_REGISTERS_RESET_REG_2_SET,
12079                                (MISC_REGISTERS_RESET_REG_2_MSTAT0 <<
12080                                 params->port));
12081                 }
12082                 if (vars->line_speed < SPEED_10000)
12083                         bnx2x_umac_enable(params, vars, 0);
12084                 else
12085                         bnx2x_xmac_enable(params, vars, 0);
12086         } else {
12087                 if (vars->line_speed < SPEED_10000)
12088                         bnx2x_emac_enable(params, vars, 0);
12089                 else
12090                         bnx2x_bmac_enable(params, vars, 0, !dont_clear_stat);
12091         }
12092
12093         /* Increment LFA count */
12094         lfa_sts = ((lfa_sts & ~LINK_FLAP_AVOIDANCE_COUNT_MASK) |
12095                    (((((lfa_sts & LINK_FLAP_AVOIDANCE_COUNT_MASK) >>
12096                        LINK_FLAP_AVOIDANCE_COUNT_OFFSET) + 1) & 0xff)
12097                     << LINK_FLAP_AVOIDANCE_COUNT_OFFSET));
12098         /* Clear link flap reason */
12099         lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
12100
12101         REG_WR(bp, params->lfa_base +
12102                offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
12103
12104         /* Disable NIG DRAIN */
12105         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
12106
12107         /* Enable interrupts */
12108         bnx2x_link_int_enable(params);
12109         return 0;
12110 }
12111
12112 static void bnx2x_cannot_avoid_link_flap(struct link_params *params,
12113                                          struct link_vars *vars,
12114                                          int lfa_status)
12115 {
12116         u32 lfa_sts, cfg_idx, tmp_val;
12117         struct bnx2x *bp = params->bp;
12118
12119         bnx2x_link_reset(params, vars, 1);
12120
12121         if (!params->lfa_base)
12122                 return;
12123         /* Store the new link parameters */
12124         REG_WR(bp, params->lfa_base +
12125                offsetof(struct shmem_lfa, req_duplex),
12126                params->req_duplex[0] | (params->req_duplex[1] << 16));
12127
12128         REG_WR(bp, params->lfa_base +
12129                offsetof(struct shmem_lfa, req_flow_ctrl),
12130                params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16));
12131
12132         REG_WR(bp, params->lfa_base +
12133                offsetof(struct shmem_lfa, req_line_speed),
12134                params->req_line_speed[0] | (params->req_line_speed[1] << 16));
12135
12136         for (cfg_idx = 0; cfg_idx < SHMEM_LINK_CONFIG_SIZE; cfg_idx++) {
12137                 REG_WR(bp, params->lfa_base +
12138                        offsetof(struct shmem_lfa,
12139                                 speed_cap_mask[cfg_idx]),
12140                        params->speed_cap_mask[cfg_idx]);
12141         }
12142
12143         tmp_val = REG_RD(bp, params->lfa_base +
12144                          offsetof(struct shmem_lfa, additional_config));
12145         tmp_val &= ~REQ_FC_AUTO_ADV_MASK;
12146         tmp_val |= params->req_fc_auto_adv;
12147
12148         REG_WR(bp, params->lfa_base +
12149                offsetof(struct shmem_lfa, additional_config), tmp_val);
12150
12151         lfa_sts = REG_RD(bp, params->lfa_base +
12152                          offsetof(struct shmem_lfa, lfa_sts));
12153
12154         /* Clear the "Don't Clear Statistics" bit, and set reason */
12155         lfa_sts &= ~SHMEM_LFA_DONT_CLEAR_STAT;
12156
12157         /* Set link flap reason */
12158         lfa_sts &= ~LFA_LINK_FLAP_REASON_MASK;
12159         lfa_sts |= ((lfa_status & LFA_LINK_FLAP_REASON_MASK) <<
12160                     LFA_LINK_FLAP_REASON_OFFSET);
12161
12162         /* Increment link flap counter */
12163         lfa_sts = ((lfa_sts & ~LINK_FLAP_COUNT_MASK) |
12164                    (((((lfa_sts & LINK_FLAP_COUNT_MASK) >>
12165                        LINK_FLAP_COUNT_OFFSET) + 1) & 0xff)
12166                     << LINK_FLAP_COUNT_OFFSET));
12167         REG_WR(bp, params->lfa_base +
12168                offsetof(struct shmem_lfa, lfa_sts), lfa_sts);
12169         /* Proceed with regular link initialization */
12170 }
12171
12172 int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
12173 {
12174         int lfa_status;
12175         struct bnx2x *bp = params->bp;
12176         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
12177         DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
12178                    params->req_line_speed[0], params->req_flow_ctrl[0]);
12179         DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
12180                    params->req_line_speed[1], params->req_flow_ctrl[1]);
12181         vars->link_status = 0;
12182         vars->phy_link_up = 0;
12183         vars->link_up = 0;
12184         vars->line_speed = 0;
12185         vars->duplex = DUPLEX_FULL;
12186         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
12187         vars->mac_type = MAC_TYPE_NONE;
12188         vars->phy_flags = 0;
12189         /* Driver opens NIG-BRB filters */
12190         bnx2x_set_rx_filter(params, 1);
12191         /* Check if link flap can be avoided */
12192         lfa_status = bnx2x_check_lfa(params);
12193
12194         if (lfa_status == 0) {
12195                 DP(NETIF_MSG_LINK, "Link Flap Avoidance in progress\n");
12196                 return bnx2x_avoid_link_flap(params, vars);
12197         }
12198
12199         DP(NETIF_MSG_LINK, "Cannot avoid link flap lfa_sta=0x%x\n",
12200                        lfa_status);
12201         bnx2x_cannot_avoid_link_flap(params, vars, lfa_status);
12202
12203         /* Disable attentions */
12204         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
12205                        (NIG_MASK_XGXS0_LINK_STATUS |
12206                         NIG_MASK_XGXS0_LINK10G |
12207                         NIG_MASK_SERDES0_LINK_STATUS |
12208                         NIG_MASK_MI_INT));
12209
12210         bnx2x_emac_init(params, vars);
12211
12212         if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
12213                 vars->link_status |= LINK_STATUS_PFC_ENABLED;
12214
12215         if (params->num_phys == 0) {
12216                 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
12217                 return -EINVAL;
12218         }
12219         set_phy_vars(params, vars);
12220
12221         DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
12222         switch (params->loopback_mode) {
12223         case LOOPBACK_BMAC:
12224                 bnx2x_init_bmac_loopback(params, vars);
12225                 break;
12226         case LOOPBACK_EMAC:
12227                 bnx2x_init_emac_loopback(params, vars);
12228                 break;
12229         case LOOPBACK_XMAC:
12230                 bnx2x_init_xmac_loopback(params, vars);
12231                 break;
12232         case LOOPBACK_UMAC:
12233                 bnx2x_init_umac_loopback(params, vars);
12234                 break;
12235         case LOOPBACK_XGXS:
12236         case LOOPBACK_EXT_PHY:
12237                 bnx2x_init_xgxs_loopback(params, vars);
12238                 break;
12239         default:
12240                 if (!CHIP_IS_E3(bp)) {
12241                         if (params->switch_cfg == SWITCH_CFG_10G)
12242                                 bnx2x_xgxs_deassert(params);
12243                         else
12244                                 bnx2x_serdes_deassert(bp, params->port);
12245                 }
12246                 bnx2x_link_initialize(params, vars);
12247                 msleep(30);
12248                 bnx2x_link_int_enable(params);
12249                 break;
12250         }
12251         bnx2x_update_mng(params, vars->link_status);
12252
12253         bnx2x_update_mng_eee(params, vars->eee_status);
12254         return 0;
12255 }
12256
12257 int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
12258                      u8 reset_ext_phy)
12259 {
12260         struct bnx2x *bp = params->bp;
12261         u8 phy_index, port = params->port, clear_latch_ind = 0;
12262         DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
12263         /* Disable attentions */
12264         vars->link_status = 0;
12265         bnx2x_update_mng(params, vars->link_status);
12266         vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
12267                               SHMEM_EEE_ACTIVE_BIT);
12268         bnx2x_update_mng_eee(params, vars->eee_status);
12269         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
12270                        (NIG_MASK_XGXS0_LINK_STATUS |
12271                         NIG_MASK_XGXS0_LINK10G |
12272                         NIG_MASK_SERDES0_LINK_STATUS |
12273                         NIG_MASK_MI_INT));
12274
12275         /* Activate nig drain */
12276         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
12277
12278         /* Disable nig egress interface */
12279         if (!CHIP_IS_E3(bp)) {
12280                 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
12281                 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
12282         }
12283
12284                 if (!CHIP_IS_E3(bp)) {
12285                         bnx2x_set_bmac_rx(bp, params->chip_id, port, 0);
12286                 } else {
12287                         bnx2x_set_xmac_rxtx(params, 0);
12288                         bnx2x_set_umac_rxtx(params, 0);
12289                 }
12290         /* Disable emac */
12291         if (!CHIP_IS_E3(bp))
12292                 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
12293
12294         usleep_range(10000, 20000);
12295         /* The PHY reset is controlled by GPIO 1
12296          * Hold it as vars low
12297          */
12298          /* Clear link led */
12299         bnx2x_set_mdio_clk(bp, params->chip_id, port);
12300         bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
12301
12302         if (reset_ext_phy) {
12303                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
12304                       phy_index++) {
12305                         if (params->phy[phy_index].link_reset) {
12306                                 bnx2x_set_aer_mmd(params,
12307                                                   &params->phy[phy_index]);
12308                                 params->phy[phy_index].link_reset(
12309                                         &params->phy[phy_index],
12310                                         params);
12311                         }
12312                         if (params->phy[phy_index].flags &
12313                             FLAGS_REARM_LATCH_SIGNAL)
12314                                 clear_latch_ind = 1;
12315                 }
12316         }
12317
12318         if (clear_latch_ind) {
12319                 /* Clear latching indication */
12320                 bnx2x_rearm_latch_signal(bp, port, 0);
12321                 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
12322                                1 << NIG_LATCH_BC_ENABLE_MI_INT);
12323         }
12324         if (params->phy[INT_PHY].link_reset)
12325                 params->phy[INT_PHY].link_reset(
12326                         &params->phy[INT_PHY], params);
12327
12328         /* Disable nig ingress interface */
12329         if (!CHIP_IS_E3(bp)) {
12330                 /* Reset BigMac */
12331                 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
12332                        (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
12333                 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
12334                 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
12335         } else {
12336                 u32 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
12337                 bnx2x_set_xumac_nig(params, 0, 0);
12338                 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
12339                     MISC_REGISTERS_RESET_REG_2_XMAC)
12340                         REG_WR(bp, xmac_base + XMAC_REG_CTRL,
12341                                XMAC_CTRL_REG_SOFT_RESET);
12342         }
12343         vars->link_up = 0;
12344         vars->phy_flags = 0;
12345         return 0;
12346 }
12347 int bnx2x_lfa_reset(struct link_params *params,
12348                                struct link_vars *vars)
12349 {
12350         struct bnx2x *bp = params->bp;
12351         vars->link_up = 0;
12352         vars->phy_flags = 0;
12353         if (!params->lfa_base)
12354                 return bnx2x_link_reset(params, vars, 1);
12355         /*
12356          * Activate NIG drain so that during this time the device won't send
12357          * anything while it is unable to response.
12358          */
12359         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 1);
12360
12361         /*
12362          * Close gracefully the gate from BMAC to NIG such that no half packets
12363          * are passed.
12364          */
12365         if (!CHIP_IS_E3(bp))
12366                 bnx2x_set_bmac_rx(bp, params->chip_id, params->port, 0);
12367
12368         if (CHIP_IS_E3(bp)) {
12369                 bnx2x_set_xmac_rxtx(params, 0);
12370                 bnx2x_set_umac_rxtx(params, 0);
12371         }
12372         /* Wait 10ms for the pipe to clean up*/
12373         usleep_range(10000, 20000);
12374
12375         /* Clean the NIG-BRB using the network filters in a way that will
12376          * not cut a packet in the middle.
12377          */
12378         bnx2x_set_rx_filter(params, 0);
12379
12380         /*
12381          * Re-open the gate between the BMAC and the NIG, after verifying the
12382          * gate to the BRB is closed, otherwise packets may arrive to the
12383          * firmware before driver had initialized it. The target is to achieve
12384          * minimum management protocol down time.
12385          */
12386         if (!CHIP_IS_E3(bp))
12387                 bnx2x_set_bmac_rx(bp, params->chip_id, params->port, 1);
12388
12389         if (CHIP_IS_E3(bp)) {
12390                 bnx2x_set_xmac_rxtx(params, 1);
12391                 bnx2x_set_umac_rxtx(params, 1);
12392         }
12393         /* Disable NIG drain */
12394         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
12395         return 0;
12396 }
12397
12398 /****************************************************************************/
12399 /*                              Common function                             */
12400 /****************************************************************************/
12401 static int bnx2x_8073_common_init_phy(struct bnx2x *bp,
12402                                       u32 shmem_base_path[],
12403                                       u32 shmem2_base_path[], u8 phy_index,
12404                                       u32 chip_id)
12405 {
12406         struct bnx2x_phy phy[PORT_MAX];
12407         struct bnx2x_phy *phy_blk[PORT_MAX];
12408         u16 val;
12409         s8 port = 0;
12410         s8 port_of_path = 0;
12411         u32 swap_val, swap_override;
12412         swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
12413         swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
12414         port ^= (swap_val && swap_override);
12415         bnx2x_ext_phy_hw_reset(bp, port);
12416         /* PART1 - Reset both phys */
12417         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12418                 u32 shmem_base, shmem2_base;
12419                 /* In E2, same phy is using for port0 of the two paths */
12420                 if (CHIP_IS_E1x(bp)) {
12421                         shmem_base = shmem_base_path[0];
12422                         shmem2_base = shmem2_base_path[0];
12423                         port_of_path = port;
12424                 } else {
12425                         shmem_base = shmem_base_path[port];
12426                         shmem2_base = shmem2_base_path[port];
12427                         port_of_path = 0;
12428                 }
12429
12430                 /* Extract the ext phy address for the port */
12431                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12432                                        port_of_path, &phy[port]) !=
12433                     0) {
12434                         DP(NETIF_MSG_LINK, "populate_phy failed\n");
12435                         return -EINVAL;
12436                 }
12437                 /* Disable attentions */
12438                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
12439                                port_of_path*4,
12440                                (NIG_MASK_XGXS0_LINK_STATUS |
12441                                 NIG_MASK_XGXS0_LINK10G |
12442                                 NIG_MASK_SERDES0_LINK_STATUS |
12443                                 NIG_MASK_MI_INT));
12444
12445                 /* Need to take the phy out of low power mode in order
12446                  * to write to access its registers
12447                  */
12448                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
12449                                MISC_REGISTERS_GPIO_OUTPUT_HIGH,
12450                                port);
12451
12452                 /* Reset the phy */
12453                 bnx2x_cl45_write(bp, &phy[port],
12454                                  MDIO_PMA_DEVAD,
12455                                  MDIO_PMA_REG_CTRL,
12456                                  1<<15);
12457         }
12458
12459         /* Add delay of 150ms after reset */
12460         msleep(150);
12461
12462         if (phy[PORT_0].addr & 0x1) {
12463                 phy_blk[PORT_0] = &(phy[PORT_1]);
12464                 phy_blk[PORT_1] = &(phy[PORT_0]);
12465         } else {
12466                 phy_blk[PORT_0] = &(phy[PORT_0]);
12467                 phy_blk[PORT_1] = &(phy[PORT_1]);
12468         }
12469
12470         /* PART2 - Download firmware to both phys */
12471         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12472                 if (CHIP_IS_E1x(bp))
12473                         port_of_path = port;
12474                 else
12475                         port_of_path = 0;
12476
12477                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
12478                            phy_blk[port]->addr);
12479                 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
12480                                                       port_of_path))
12481                         return -EINVAL;
12482
12483                 /* Only set bit 10 = 1 (Tx power down) */
12484                 bnx2x_cl45_read(bp, phy_blk[port],
12485                                 MDIO_PMA_DEVAD,
12486                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
12487
12488                 /* Phase1 of TX_POWER_DOWN reset */
12489                 bnx2x_cl45_write(bp, phy_blk[port],
12490                                  MDIO_PMA_DEVAD,
12491                                  MDIO_PMA_REG_TX_POWER_DOWN,
12492                                  (val | 1<<10));
12493         }
12494
12495         /* Toggle Transmitter: Power down and then up with 600ms delay
12496          * between
12497          */
12498         msleep(600);
12499
12500         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
12501         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12502                 /* Phase2 of POWER_DOWN_RESET */
12503                 /* Release bit 10 (Release Tx power down) */
12504                 bnx2x_cl45_read(bp, phy_blk[port],
12505                                 MDIO_PMA_DEVAD,
12506                                 MDIO_PMA_REG_TX_POWER_DOWN, &val);
12507
12508                 bnx2x_cl45_write(bp, phy_blk[port],
12509                                 MDIO_PMA_DEVAD,
12510                                 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
12511                 usleep_range(15000, 30000);
12512
12513                 /* Read modify write the SPI-ROM version select register */
12514                 bnx2x_cl45_read(bp, phy_blk[port],
12515                                 MDIO_PMA_DEVAD,
12516                                 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
12517                 bnx2x_cl45_write(bp, phy_blk[port],
12518                                  MDIO_PMA_DEVAD,
12519                                  MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
12520
12521                 /* set GPIO2 back to LOW */
12522                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
12523                                MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
12524         }
12525         return 0;
12526 }
12527 static int bnx2x_8726_common_init_phy(struct bnx2x *bp,
12528                                       u32 shmem_base_path[],
12529                                       u32 shmem2_base_path[], u8 phy_index,
12530                                       u32 chip_id)
12531 {
12532         u32 val;
12533         s8 port;
12534         struct bnx2x_phy phy;
12535         /* Use port1 because of the static port-swap */
12536         /* Enable the module detection interrupt */
12537         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
12538         val |= ((1<<MISC_REGISTERS_GPIO_3)|
12539                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
12540         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
12541
12542         bnx2x_ext_phy_hw_reset(bp, 0);
12543         usleep_range(5000, 10000);
12544         for (port = 0; port < PORT_MAX; port++) {
12545                 u32 shmem_base, shmem2_base;
12546
12547                 /* In E2, same phy is using for port0 of the two paths */
12548                 if (CHIP_IS_E1x(bp)) {
12549                         shmem_base = shmem_base_path[0];
12550                         shmem2_base = shmem2_base_path[0];
12551                 } else {
12552                         shmem_base = shmem_base_path[port];
12553                         shmem2_base = shmem2_base_path[port];
12554                 }
12555                 /* Extract the ext phy address for the port */
12556                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12557                                        port, &phy) !=
12558                     0) {
12559                         DP(NETIF_MSG_LINK, "populate phy failed\n");
12560                         return -EINVAL;
12561                 }
12562
12563                 /* Reset phy*/
12564                 bnx2x_cl45_write(bp, &phy,
12565                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
12566
12567
12568                 /* Set fault module detected LED on */
12569                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
12570                                MISC_REGISTERS_GPIO_HIGH,
12571                                port);
12572         }
12573
12574         return 0;
12575 }
12576 static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
12577                                          u8 *io_gpio, u8 *io_port)
12578 {
12579
12580         u32 phy_gpio_reset = REG_RD(bp, shmem_base +
12581                                           offsetof(struct shmem_region,
12582                                 dev_info.port_hw_config[PORT_0].default_cfg));
12583         switch (phy_gpio_reset) {
12584         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
12585                 *io_gpio = 0;
12586                 *io_port = 0;
12587                 break;
12588         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
12589                 *io_gpio = 1;
12590                 *io_port = 0;
12591                 break;
12592         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
12593                 *io_gpio = 2;
12594                 *io_port = 0;
12595                 break;
12596         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
12597                 *io_gpio = 3;
12598                 *io_port = 0;
12599                 break;
12600         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
12601                 *io_gpio = 0;
12602                 *io_port = 1;
12603                 break;
12604         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
12605                 *io_gpio = 1;
12606                 *io_port = 1;
12607                 break;
12608         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
12609                 *io_gpio = 2;
12610                 *io_port = 1;
12611                 break;
12612         case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
12613                 *io_gpio = 3;
12614                 *io_port = 1;
12615                 break;
12616         default:
12617                 /* Don't override the io_gpio and io_port */
12618                 break;
12619         }
12620 }
12621
12622 static int bnx2x_8727_common_init_phy(struct bnx2x *bp,
12623                                       u32 shmem_base_path[],
12624                                       u32 shmem2_base_path[], u8 phy_index,
12625                                       u32 chip_id)
12626 {
12627         s8 port, reset_gpio;
12628         u32 swap_val, swap_override;
12629         struct bnx2x_phy phy[PORT_MAX];
12630         struct bnx2x_phy *phy_blk[PORT_MAX];
12631         s8 port_of_path;
12632         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
12633         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
12634
12635         reset_gpio = MISC_REGISTERS_GPIO_1;
12636         port = 1;
12637
12638         /* Retrieve the reset gpio/port which control the reset.
12639          * Default is GPIO1, PORT1
12640          */
12641         bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
12642                                      (u8 *)&reset_gpio, (u8 *)&port);
12643
12644         /* Calculate the port based on port swap */
12645         port ^= (swap_val && swap_override);
12646
12647         /* Initiate PHY reset*/
12648         bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
12649                        port);
12650          usleep_range(1000, 2000);
12651         bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
12652                        port);
12653
12654         usleep_range(5000, 10000);
12655
12656         /* PART1 - Reset both phys */
12657         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12658                 u32 shmem_base, shmem2_base;
12659
12660                 /* In E2, same phy is using for port0 of the two paths */
12661                 if (CHIP_IS_E1x(bp)) {
12662                         shmem_base = shmem_base_path[0];
12663                         shmem2_base = shmem2_base_path[0];
12664                         port_of_path = port;
12665                 } else {
12666                         shmem_base = shmem_base_path[port];
12667                         shmem2_base = shmem2_base_path[port];
12668                         port_of_path = 0;
12669                 }
12670
12671                 /* Extract the ext phy address for the port */
12672                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12673                                        port_of_path, &phy[port]) !=
12674                                        0) {
12675                         DP(NETIF_MSG_LINK, "populate phy failed\n");
12676                         return -EINVAL;
12677                 }
12678                 /* disable attentions */
12679                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
12680                                port_of_path*4,
12681                                (NIG_MASK_XGXS0_LINK_STATUS |
12682                                 NIG_MASK_XGXS0_LINK10G |
12683                                 NIG_MASK_SERDES0_LINK_STATUS |
12684                                 NIG_MASK_MI_INT));
12685
12686
12687                 /* Reset the phy */
12688                 bnx2x_cl45_write(bp, &phy[port],
12689                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
12690         }
12691
12692         /* Add delay of 150ms after reset */
12693         msleep(150);
12694         if (phy[PORT_0].addr & 0x1) {
12695                 phy_blk[PORT_0] = &(phy[PORT_1]);
12696                 phy_blk[PORT_1] = &(phy[PORT_0]);
12697         } else {
12698                 phy_blk[PORT_0] = &(phy[PORT_0]);
12699                 phy_blk[PORT_1] = &(phy[PORT_1]);
12700         }
12701         /* PART2 - Download firmware to both phys */
12702         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12703                 if (CHIP_IS_E1x(bp))
12704                         port_of_path = port;
12705                 else
12706                         port_of_path = 0;
12707                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
12708                            phy_blk[port]->addr);
12709                 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
12710                                                       port_of_path))
12711                         return -EINVAL;
12712                 /* Disable PHY transmitter output */
12713                 bnx2x_cl45_write(bp, phy_blk[port],
12714                                  MDIO_PMA_DEVAD,
12715                                  MDIO_PMA_REG_TX_DISABLE, 1);
12716
12717         }
12718         return 0;
12719 }
12720
12721 static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
12722                                                 u32 shmem_base_path[],
12723                                                 u32 shmem2_base_path[],
12724                                                 u8 phy_index,
12725                                                 u32 chip_id)
12726 {
12727         u8 reset_gpios;
12728         reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id);
12729         bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
12730         udelay(10);
12731         bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
12732         DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n",
12733                 reset_gpios);
12734         return 0;
12735 }
12736
12737 static int bnx2x_84833_pre_init_phy(struct bnx2x *bp,
12738                                                struct bnx2x_phy *phy)
12739 {
12740         u16 val, cnt;
12741         /* Wait for FW completing its initialization. */
12742         for (cnt = 0; cnt < 1500; cnt++) {
12743                 bnx2x_cl45_read(bp, phy,
12744                                 MDIO_PMA_DEVAD,
12745                                 MDIO_PMA_REG_CTRL, &val);
12746                 if (!(val & (1<<15)))
12747                         break;
12748                  usleep_range(1000, 2000);
12749         }
12750         if (cnt >= 1500) {
12751                 DP(NETIF_MSG_LINK, "84833 reset timeout\n");
12752                 return -EINVAL;
12753         }
12754
12755         /* Put the port in super isolate mode. */
12756         bnx2x_cl45_read(bp, phy,
12757                         MDIO_CTL_DEVAD,
12758                         MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
12759         val |= MDIO_84833_SUPER_ISOLATE;
12760         bnx2x_cl45_write(bp, phy,
12761                          MDIO_CTL_DEVAD,
12762                          MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
12763
12764         /* Save spirom version */
12765         bnx2x_save_848xx_spirom_version(phy, bp, PORT_0);
12766         return 0;
12767 }
12768
12769 int bnx2x_pre_init_phy(struct bnx2x *bp,
12770                                   u32 shmem_base,
12771                                   u32 shmem2_base,
12772                                   u32 chip_id)
12773 {
12774         int rc = 0;
12775         struct bnx2x_phy phy;
12776         bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
12777         if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, shmem2_base,
12778                                PORT_0, &phy)) {
12779                 DP(NETIF_MSG_LINK, "populate_phy failed\n");
12780                 return -EINVAL;
12781         }
12782         switch (phy.type) {
12783         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
12784                 rc = bnx2x_84833_pre_init_phy(bp, &phy);
12785                 break;
12786         default:
12787                 break;
12788         }
12789         return rc;
12790 }
12791
12792 static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
12793                                      u32 shmem2_base_path[], u8 phy_index,
12794                                      u32 ext_phy_type, u32 chip_id)
12795 {
12796         int rc = 0;
12797
12798         switch (ext_phy_type) {
12799         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
12800                 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
12801                                                 shmem2_base_path,
12802                                                 phy_index, chip_id);
12803                 break;
12804         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
12805         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
12806         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
12807                 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
12808                                                 shmem2_base_path,
12809                                                 phy_index, chip_id);
12810                 break;
12811
12812         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
12813                 /* GPIO1 affects both ports, so there's need to pull
12814                  * it for single port alone
12815                  */
12816                 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
12817                                                 shmem2_base_path,
12818                                                 phy_index, chip_id);
12819                 break;
12820         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
12821                 /* GPIO3's are linked, and so both need to be toggled
12822                  * to obtain required 2us pulse.
12823                  */
12824                 rc = bnx2x_84833_common_init_phy(bp, shmem_base_path,
12825                                                 shmem2_base_path,
12826                                                 phy_index, chip_id);
12827                 break;
12828         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
12829                 rc = -EINVAL;
12830                 break;
12831         default:
12832                 DP(NETIF_MSG_LINK,
12833                            "ext_phy 0x%x common init not required\n",
12834                            ext_phy_type);
12835                 break;
12836         }
12837
12838         if (rc)
12839                 netdev_err(bp->dev,  "Warning: PHY was not initialized,"
12840                                       " Port %d\n",
12841                          0);
12842         return rc;
12843 }
12844
12845 int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
12846                           u32 shmem2_base_path[], u32 chip_id)
12847 {
12848         int rc = 0;
12849         u32 phy_ver, val;
12850         u8 phy_index = 0;
12851         u32 ext_phy_type, ext_phy_config;
12852         bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
12853         bnx2x_set_mdio_clk(bp, chip_id, PORT_1);
12854         DP(NETIF_MSG_LINK, "Begin common phy init\n");
12855         if (CHIP_IS_E3(bp)) {
12856                 /* Enable EPIO */
12857                 val = REG_RD(bp, MISC_REG_GEN_PURP_HWG);
12858                 REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1);
12859         }
12860         /* Check if common init was already done */
12861         phy_ver = REG_RD(bp, shmem_base_path[0] +
12862                          offsetof(struct shmem_region,
12863                                   port_mb[PORT_0].ext_phy_fw_version));
12864         if (phy_ver) {
12865                 DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
12866                                phy_ver);
12867                 return 0;
12868         }
12869
12870         /* Read the ext_phy_type for arbitrary port(0) */
12871         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12872               phy_index++) {
12873                 ext_phy_config = bnx2x_get_ext_phy_config(bp,
12874                                                           shmem_base_path[0],
12875                                                           phy_index, 0);
12876                 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
12877                 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
12878                                                 shmem2_base_path,
12879                                                 phy_index, ext_phy_type,
12880                                                 chip_id);
12881         }
12882         return rc;
12883 }
12884
12885 static void bnx2x_check_over_curr(struct link_params *params,
12886                                   struct link_vars *vars)
12887 {
12888         struct bnx2x *bp = params->bp;
12889         u32 cfg_pin;
12890         u8 port = params->port;
12891         u32 pin_val;
12892
12893         cfg_pin = (REG_RD(bp, params->shmem_base +
12894                           offsetof(struct shmem_region,
12895                                dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
12896                    PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
12897                 PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
12898
12899         /* Ignore check if no external input PIN available */
12900         if (bnx2x_get_cfg_pin(bp, cfg_pin, &pin_val) != 0)
12901                 return;
12902
12903         if (!pin_val) {
12904                 if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
12905                         netdev_err(bp->dev, "Error:  Power fault on Port %d has"
12906                                             " been detected and the power to "
12907                                             "that SFP+ module has been removed"
12908                                             " to prevent failure of the card."
12909                                             " Please remove the SFP+ module and"
12910                                             " restart the system to clear this"
12911                                             " error.\n",
12912                          params->port);
12913                         vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
12914                 }
12915         } else
12916                 vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
12917 }
12918
12919 /* Returns 0 if no change occured since last check; 1 otherwise. */
12920 static u8 bnx2x_analyze_link_error(struct link_params *params,
12921                                     struct link_vars *vars, u32 status,
12922                                     u32 phy_flag, u32 link_flag, u8 notify)
12923 {
12924         struct bnx2x *bp = params->bp;
12925         /* Compare new value with previous value */
12926         u8 led_mode;
12927         u32 old_status = (vars->phy_flags & phy_flag) ? 1 : 0;
12928
12929         if ((status ^ old_status) == 0)
12930                 return 0;
12931
12932         /* If values differ */
12933         switch (phy_flag) {
12934         case PHY_HALF_OPEN_CONN_FLAG:
12935                 DP(NETIF_MSG_LINK, "Analyze Remote Fault\n");
12936                 break;
12937         case PHY_SFP_TX_FAULT_FLAG:
12938                 DP(NETIF_MSG_LINK, "Analyze TX Fault\n");
12939                 break;
12940         default:
12941                 DP(NETIF_MSG_LINK, "Analyze UNKOWN\n");
12942         }
12943         DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up,
12944            old_status, status);
12945
12946         /* a. Update shmem->link_status accordingly
12947          * b. Update link_vars->link_up
12948          */
12949         if (status) {
12950                 vars->link_status &= ~LINK_STATUS_LINK_UP;
12951                 vars->link_status |= link_flag;
12952                 vars->link_up = 0;
12953                 vars->phy_flags |= phy_flag;
12954
12955                 /* activate nig drain */
12956                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 1);
12957                 /* Set LED mode to off since the PHY doesn't know about these
12958                  * errors
12959                  */
12960                 led_mode = LED_MODE_OFF;
12961         } else {
12962                 vars->link_status |= LINK_STATUS_LINK_UP;
12963                 vars->link_status &= ~link_flag;
12964                 vars->link_up = 1;
12965                 vars->phy_flags &= ~phy_flag;
12966                 led_mode = LED_MODE_OPER;
12967
12968                 /* Clear nig drain */
12969                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
12970         }
12971         bnx2x_sync_link(params, vars);
12972         /* Update the LED according to the link state */
12973         bnx2x_set_led(params, vars, led_mode, SPEED_10000);
12974
12975         /* Update link status in the shared memory */
12976         bnx2x_update_mng(params, vars->link_status);
12977
12978         /* C. Trigger General Attention */
12979         vars->periodic_flags |= PERIODIC_FLAGS_LINK_EVENT;
12980         if (notify)
12981                 bnx2x_notify_link_changed(bp);
12982
12983         return 1;
12984 }
12985
12986 /******************************************************************************
12987 * Description:
12988 *       This function checks for half opened connection change indication.
12989 *       When such change occurs, it calls the bnx2x_analyze_link_error
12990 *       to check if Remote Fault is set or cleared. Reception of remote fault
12991 *       status message in the MAC indicates that the peer's MAC has detected
12992 *       a fault, for example, due to break in the TX side of fiber.
12993 *
12994 ******************************************************************************/
12995 int bnx2x_check_half_open_conn(struct link_params *params,
12996                                 struct link_vars *vars,
12997                                 u8 notify)
12998 {
12999         struct bnx2x *bp = params->bp;
13000         u32 lss_status = 0;
13001         u32 mac_base;
13002         /* In case link status is physically up @ 10G do */
13003         if (((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) ||
13004             (REG_RD(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4)))
13005                 return 0;
13006
13007         if (CHIP_IS_E3(bp) &&
13008             (REG_RD(bp, MISC_REG_RESET_REG_2) &
13009               (MISC_REGISTERS_RESET_REG_2_XMAC))) {
13010                 /* Check E3 XMAC */
13011                 /* Note that link speed cannot be queried here, since it may be
13012                  * zero while link is down. In case UMAC is active, LSS will
13013                  * simply not be set
13014                  */
13015                 mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
13016
13017                 /* Clear stick bits (Requires rising edge) */
13018                 REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
13019                 REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
13020                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
13021                        XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
13022                 if (REG_RD(bp, mac_base + XMAC_REG_RX_LSS_STATUS))
13023                         lss_status = 1;
13024
13025                 bnx2x_analyze_link_error(params, vars, lss_status,
13026                                          PHY_HALF_OPEN_CONN_FLAG,
13027                                          LINK_STATUS_NONE, notify);
13028         } else if (REG_RD(bp, MISC_REG_RESET_REG_2) &
13029                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
13030                 /* Check E1X / E2 BMAC */
13031                 u32 lss_status_reg;
13032                 u32 wb_data[2];
13033                 mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
13034                         NIG_REG_INGRESS_BMAC0_MEM;
13035                 /*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
13036                 if (CHIP_IS_E2(bp))
13037                         lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
13038                 else
13039                         lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
13040
13041                 REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2);
13042                 lss_status = (wb_data[0] > 0);
13043
13044                 bnx2x_analyze_link_error(params, vars, lss_status,
13045                                          PHY_HALF_OPEN_CONN_FLAG,
13046                                          LINK_STATUS_NONE, notify);
13047         }
13048         return 0;
13049 }
13050 static void bnx2x_sfp_tx_fault_detection(struct bnx2x_phy *phy,
13051                                          struct link_params *params,
13052                                          struct link_vars *vars)
13053 {
13054         struct bnx2x *bp = params->bp;
13055         u32 cfg_pin, value = 0;
13056         u8 led_change, port = params->port;
13057
13058         /* Get The SFP+ TX_Fault controlling pin ([eg]pio) */
13059         cfg_pin = (REG_RD(bp, params->shmem_base + offsetof(struct shmem_region,
13060                           dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
13061                    PORT_HW_CFG_E3_TX_FAULT_MASK) >>
13062                   PORT_HW_CFG_E3_TX_FAULT_SHIFT;
13063
13064         if (bnx2x_get_cfg_pin(bp, cfg_pin, &value)) {
13065                 DP(NETIF_MSG_LINK, "Failed to read pin 0x%02x\n", cfg_pin);
13066                 return;
13067         }
13068
13069         led_change = bnx2x_analyze_link_error(params, vars, value,
13070                                               PHY_SFP_TX_FAULT_FLAG,
13071                                               LINK_STATUS_SFP_TX_FAULT, 1);
13072
13073         if (led_change) {
13074                 /* Change TX_Fault led, set link status for further syncs */
13075                 u8 led_mode;
13076
13077                 if (vars->phy_flags & PHY_SFP_TX_FAULT_FLAG) {
13078                         led_mode = MISC_REGISTERS_GPIO_HIGH;
13079                         vars->link_status |= LINK_STATUS_SFP_TX_FAULT;
13080                 } else {
13081                         led_mode = MISC_REGISTERS_GPIO_LOW;
13082                         vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
13083                 }
13084
13085                 /* If module is unapproved, led should be on regardless */
13086                 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) {
13087                         DP(NETIF_MSG_LINK, "Change TX_Fault LED: ->%x\n",
13088                            led_mode);
13089                         bnx2x_set_e3_module_fault_led(params, led_mode);
13090                 }
13091         }
13092 }
13093 void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
13094 {
13095         u16 phy_idx;
13096         struct bnx2x *bp = params->bp;
13097         for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
13098                 if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
13099                         bnx2x_set_aer_mmd(params, &params->phy[phy_idx]);
13100                         if (bnx2x_check_half_open_conn(params, vars, 1) !=
13101                             0)
13102                                 DP(NETIF_MSG_LINK, "Fault detection failed\n");
13103                         break;
13104                 }
13105         }
13106
13107         if (CHIP_IS_E3(bp)) {
13108                 struct bnx2x_phy *phy = &params->phy[INT_PHY];
13109                 bnx2x_set_aer_mmd(params, phy);
13110                 bnx2x_check_over_curr(params, vars);
13111                 if (vars->rx_tx_asic_rst)
13112                         bnx2x_warpcore_config_runtime(phy, params, vars);
13113
13114                 if ((REG_RD(bp, params->shmem_base +
13115                             offsetof(struct shmem_region, dev_info.
13116                                 port_hw_config[params->port].default_cfg))
13117                     & PORT_HW_CFG_NET_SERDES_IF_MASK) ==
13118                     PORT_HW_CFG_NET_SERDES_IF_SFI) {
13119                         if (bnx2x_is_sfp_module_plugged(phy, params)) {
13120                                 bnx2x_sfp_tx_fault_detection(phy, params, vars);
13121                         } else if (vars->link_status &
13122                                 LINK_STATUS_SFP_TX_FAULT) {
13123                                 /* Clean trail, interrupt corrects the leds */
13124                                 vars->link_status &= ~LINK_STATUS_SFP_TX_FAULT;
13125                                 vars->phy_flags &= ~PHY_SFP_TX_FAULT_FLAG;
13126                                 /* Update link status in the shared memory */
13127                                 bnx2x_update_mng(params, vars->link_status);
13128                         }
13129                 }
13130
13131         }
13132
13133 }
13134
13135 u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
13136 {
13137         u8 phy_index;
13138         struct bnx2x_phy phy;
13139         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
13140               phy_index++) {
13141                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
13142                                        0, &phy) != 0) {
13143                         DP(NETIF_MSG_LINK, "populate phy failed\n");
13144                         return 0;
13145                 }
13146
13147                 if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
13148                         return 1;
13149         }
13150         return 0;
13151 }
13152
13153 u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
13154                              u32 shmem_base,
13155                              u32 shmem2_base,
13156                              u8 port)
13157 {
13158         u8 phy_index, fan_failure_det_req = 0;
13159         struct bnx2x_phy phy;
13160         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
13161               phy_index++) {
13162                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
13163                                        port, &phy)
13164                     != 0) {
13165                         DP(NETIF_MSG_LINK, "populate phy failed\n");
13166                         return 0;
13167                 }
13168                 fan_failure_det_req |= (phy.flags &
13169                                         FLAGS_FAN_FAILURE_DET_REQ);
13170         }
13171         return fan_failure_det_req;
13172 }
13173
13174 void bnx2x_hw_reset_phy(struct link_params *params)
13175 {
13176         u8 phy_index;
13177         struct bnx2x *bp = params->bp;
13178         bnx2x_update_mng(params, 0);
13179         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
13180                        (NIG_MASK_XGXS0_LINK_STATUS |
13181                         NIG_MASK_XGXS0_LINK10G |
13182                         NIG_MASK_SERDES0_LINK_STATUS |
13183                         NIG_MASK_MI_INT));
13184
13185         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
13186               phy_index++) {
13187                 if (params->phy[phy_index].hw_reset) {
13188                         params->phy[phy_index].hw_reset(
13189                                 &params->phy[phy_index],
13190                                 params);
13191                         params->phy[phy_index] = phy_null;
13192                 }
13193         }
13194 }
13195
13196 void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars,
13197                             u32 chip_id, u32 shmem_base, u32 shmem2_base,
13198                             u8 port)
13199 {
13200         u8 gpio_num = 0xff, gpio_port = 0xff, phy_index;
13201         u32 val;
13202         u32 offset, aeu_mask, swap_val, swap_override, sync_offset;
13203         if (CHIP_IS_E3(bp)) {
13204                 if (bnx2x_get_mod_abs_int_cfg(bp, chip_id,
13205                                               shmem_base,
13206                                               port,
13207                                               &gpio_num,
13208                                               &gpio_port) != 0)
13209                         return;
13210         } else {
13211                 struct bnx2x_phy phy;
13212                 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
13213                       phy_index++) {
13214                         if (bnx2x_populate_phy(bp, phy_index, shmem_base,
13215                                                shmem2_base, port, &phy)
13216                             != 0) {
13217                                 DP(NETIF_MSG_LINK, "populate phy failed\n");
13218                                 return;
13219                         }
13220                         if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
13221                                 gpio_num = MISC_REGISTERS_GPIO_3;
13222                                 gpio_port = port;
13223                                 break;
13224                         }
13225                 }
13226         }
13227
13228         if (gpio_num == 0xff)
13229                 return;
13230
13231         /* Set GPIO3 to trigger SFP+ module insertion/removal */
13232         bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port);
13233
13234         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
13235         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
13236         gpio_port ^= (swap_val && swap_override);
13237
13238         vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
13239                 (gpio_num + (gpio_port << 2));
13240
13241         sync_offset = shmem_base +
13242                 offsetof(struct shmem_region,
13243                          dev_info.port_hw_config[port].aeu_int_mask);
13244         REG_WR(bp, sync_offset, vars->aeu_int_mask);
13245
13246         DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
13247                        gpio_num, gpio_port, vars->aeu_int_mask);
13248
13249         if (port == 0)
13250                 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
13251         else
13252                 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
13253
13254         /* Open appropriate AEU for interrupts */
13255         aeu_mask = REG_RD(bp, offset);
13256         aeu_mask |= vars->aeu_int_mask;
13257         REG_WR(bp, offset, aeu_mask);
13258
13259         /* Enable the GPIO to trigger interrupt */
13260         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
13261         val |= 1 << (gpio_num + (gpio_port << 2));
13262         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
13263 }