bnx2x: Fix BCM8726 ROM load seq
[safe/jmp/linux-2.6] / drivers / net / bnx2x_link.c
1 /* Copyright 2008-2009 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 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24
25 #include "bnx2x.h"
26
27 /********************************************************/
28 #define ETH_HLEN                        14
29 #define ETH_OVREHEAD            (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
30 #define ETH_MIN_PACKET_SIZE             60
31 #define ETH_MAX_PACKET_SIZE             1500
32 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
33 #define MDIO_ACCESS_TIMEOUT             1000
34 #define BMAC_CONTROL_RX_ENABLE  2
35
36 /***********************************************************/
37 /*                      Shortcut definitions               */
38 /***********************************************************/
39
40 #define NIG_LATCH_BC_ENABLE_MI_INT 0
41
42 #define NIG_STATUS_EMAC0_MI_INT \
43                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
44 #define NIG_STATUS_XGXS0_LINK10G \
45                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
46 #define NIG_STATUS_XGXS0_LINK_STATUS \
47                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
48 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
49                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
50 #define NIG_STATUS_SERDES0_LINK_STATUS \
51                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
52 #define NIG_MASK_MI_INT \
53                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
54 #define NIG_MASK_XGXS0_LINK10G \
55                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
56 #define NIG_MASK_XGXS0_LINK_STATUS \
57                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
58 #define NIG_MASK_SERDES0_LINK_STATUS \
59                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
60
61 #define MDIO_AN_CL73_OR_37_COMPLETE \
62                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
63                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
64
65 #define XGXS_RESET_BITS \
66         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
67          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
68          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
69          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
70          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
71
72 #define SERDES_RESET_BITS \
73         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
74          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
75          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
76          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
77
78 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
79 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
80 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
81 #define AUTONEG_PARALLEL \
82                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
83 #define AUTONEG_SGMII_FIBER_AUTODET \
84                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
85 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
86
87 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
88                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
89 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
90                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
91 #define GP_STATUS_SPEED_MASK \
92                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
93 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
94 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
95 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
96 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
97 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
98 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
99 #define GP_STATUS_10G_HIG \
100                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
101 #define GP_STATUS_10G_CX4 \
102                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
103 #define GP_STATUS_12G_HIG \
104                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
105 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
106 #define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
107 #define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
108 #define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
109 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
110 #define GP_STATUS_10G_KX4 \
111                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
112
113 #define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
114 #define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
115 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
116 #define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
117 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
118 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
119 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
120 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
121 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
122 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
123 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
124 #define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
125 #define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
126 #define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
127 #define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
128 #define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
129 #define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
130 #define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
131 #define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
132 #define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
133 #define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
134 #define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
135 #define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
136
137 #define PHY_XGXS_FLAG                   0x1
138 #define PHY_SGMII_FLAG                  0x2
139 #define PHY_SERDES_FLAG                 0x4
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
165
166 /**********************************************************/
167 /*                     INTERFACE                          */
168 /**********************************************************/
169 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
170         bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
171                 DEFAULT_PHY_DEV_ADDR, \
172                 (_bank + (_addr & 0xf)), \
173                 _val)
174
175 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
176         bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
177                 DEFAULT_PHY_DEV_ADDR, \
178                 (_bank + (_addr & 0xf)), \
179                 _val)
180
181 static void bnx2x_set_serdes_access(struct link_params *params)
182 {
183         struct bnx2x *bp = params->bp;
184         u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
185
186         /* Set Clause 22 */
187         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
188         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
189         udelay(500);
190         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
191         udelay(500);
192          /* Set Clause 45 */
193         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
194 }
195 static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
196 {
197         struct bnx2x *bp = params->bp;
198
199         if (phy_flags & PHY_XGXS_FLAG) {
200                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
201                            params->port*0x18, 0);
202                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
203                            DEFAULT_PHY_DEV_ADDR);
204         } else {
205                 bnx2x_set_serdes_access(params);
206
207                 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
208                            params->port*0x10,
209                            DEFAULT_PHY_DEV_ADDR);
210         }
211 }
212
213 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
214 {
215         u32 val = REG_RD(bp, reg);
216
217         val |= bits;
218         REG_WR(bp, reg, val);
219         return val;
220 }
221
222 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
223 {
224         u32 val = REG_RD(bp, reg);
225
226         val &= ~bits;
227         REG_WR(bp, reg, val);
228         return val;
229 }
230
231 static void bnx2x_emac_init(struct link_params *params,
232                            struct link_vars *vars)
233 {
234         /* reset and unreset the emac core */
235         struct bnx2x *bp = params->bp;
236         u8 port = params->port;
237         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
238         u32 val;
239         u16 timeout;
240
241         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
242                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
243         udelay(5);
244         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
245                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
246
247         /* init emac - use read-modify-write */
248         /* self clear reset */
249         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
250         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
251
252         timeout = 200;
253         do {
254                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
255                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
256                 if (!timeout) {
257                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
258                         return;
259                 }
260                 timeout--;
261         } while (val & EMAC_MODE_RESET);
262
263         /* Set mac address */
264         val = ((params->mac_addr[0] << 8) |
265                 params->mac_addr[1]);
266         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
267
268         val = ((params->mac_addr[2] << 24) |
269                (params->mac_addr[3] << 16) |
270                (params->mac_addr[4] << 8) |
271                 params->mac_addr[5]);
272         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
273 }
274
275 static u8 bnx2x_emac_enable(struct link_params *params,
276                           struct link_vars *vars, u8 lb)
277 {
278         struct bnx2x *bp = params->bp;
279         u8 port = params->port;
280         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
281         u32 val;
282
283         DP(NETIF_MSG_LINK, "enabling EMAC\n");
284
285         /* enable emac and not bmac */
286         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
287
288         /* for paladium */
289         if (CHIP_REV_IS_EMUL(bp)) {
290                 /* Use lane 1 (of lanes 0-3) */
291                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
292                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
293                             port*4, 1);
294         }
295         /* for fpga */
296         else
297
298         if (CHIP_REV_IS_FPGA(bp)) {
299                 /* Use lane 1 (of lanes 0-3) */
300                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
301
302                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
303                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
304                             0);
305         } else
306         /* ASIC */
307         if (vars->phy_flags & PHY_XGXS_FLAG) {
308                 u32 ser_lane = ((params->lane_config &
309                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
310                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
311
312                 DP(NETIF_MSG_LINK, "XGXS\n");
313                 /* select the master lanes (out of 0-3) */
314                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
315                            port*4, ser_lane);
316                 /* select XGXS */
317                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
318                            port*4, 1);
319
320         } else { /* SerDes */
321                 DP(NETIF_MSG_LINK, "SerDes\n");
322                 /* select SerDes */
323                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
324                            port*4, 0);
325         }
326
327         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
328                     EMAC_RX_MODE_RESET);
329         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
330                     EMAC_TX_MODE_RESET);
331
332         if (CHIP_REV_IS_SLOW(bp)) {
333                 /* config GMII mode */
334                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
335                 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
336                             (val | EMAC_MODE_PORT_GMII));
337         } else { /* ASIC */
338                 /* pause enable/disable */
339                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
340                                EMAC_RX_MODE_FLOW_EN);
341                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
342                         bnx2x_bits_en(bp, emac_base +
343                                     EMAC_REG_EMAC_RX_MODE,
344                                     EMAC_RX_MODE_FLOW_EN);
345
346                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
347                              (EMAC_TX_MODE_EXT_PAUSE_EN |
348                               EMAC_TX_MODE_FLOW_EN));
349                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
350                         bnx2x_bits_en(bp, emac_base +
351                                     EMAC_REG_EMAC_TX_MODE,
352                                    (EMAC_TX_MODE_EXT_PAUSE_EN |
353                                     EMAC_TX_MODE_FLOW_EN));
354         }
355
356         /* KEEP_VLAN_TAG, promiscuous */
357         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
358         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
359         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
360
361         /* Set Loopback */
362         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
363         if (lb)
364                 val |= 0x810;
365         else
366                 val &= ~0x810;
367         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
368
369         /* enable emac */
370         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
371
372         /* enable emac for jumbo packets */
373         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
374                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
375                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
376
377         /* strip CRC */
378         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
379
380         /* disable the NIG in/out to the bmac */
381         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
382         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
383         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
384
385         /* enable the NIG in/out to the emac */
386         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
387         val = 0;
388         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
389                 val = 1;
390
391         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
392         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
393
394         if (CHIP_REV_IS_EMUL(bp)) {
395                 /* take the BigMac out of reset */
396                 REG_WR(bp,
397                            GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
398                            (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
399
400                 /* enable access for bmac registers */
401                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
402         } else
403                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
404
405         vars->mac_type = MAC_TYPE_EMAC;
406         return 0;
407 }
408
409
410
411 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
412                           u8 is_lb)
413 {
414         struct bnx2x *bp = params->bp;
415         u8 port = params->port;
416         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
417                                NIG_REG_INGRESS_BMAC0_MEM;
418         u32 wb_data[2];
419         u32 val;
420
421         DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
422         /* reset and unreset the BigMac */
423         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
424                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
425         msleep(1);
426
427         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
428                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
429
430         /* enable access for bmac registers */
431         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
432
433         /* XGXS control */
434         wb_data[0] = 0x3c;
435         wb_data[1] = 0;
436         REG_WR_DMAE(bp, bmac_addr +
437                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
438                       wb_data, 2);
439
440         /* tx MAC SA */
441         wb_data[0] = ((params->mac_addr[2] << 24) |
442                        (params->mac_addr[3] << 16) |
443                        (params->mac_addr[4] << 8) |
444                         params->mac_addr[5]);
445         wb_data[1] = ((params->mac_addr[0] << 8) |
446                         params->mac_addr[1]);
447         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
448                     wb_data, 2);
449
450         /* tx control */
451         val = 0xc0;
452         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
453                 val |= 0x800000;
454         wb_data[0] = val;
455         wb_data[1] = 0;
456         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
457                         wb_data, 2);
458
459         /* mac control */
460         val = 0x3;
461         if (is_lb) {
462                 val |= 0x4;
463                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
464         }
465         wb_data[0] = val;
466         wb_data[1] = 0;
467         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
468                     wb_data, 2);
469
470         /* set rx mtu */
471         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
472         wb_data[1] = 0;
473         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
474                         wb_data, 2);
475
476         /* rx control set to don't strip crc */
477         val = 0x14;
478         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
479                 val |= 0x20;
480         wb_data[0] = val;
481         wb_data[1] = 0;
482         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
483                         wb_data, 2);
484
485         /* set tx mtu */
486         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
487         wb_data[1] = 0;
488         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
489                         wb_data, 2);
490
491         /* set cnt max size */
492         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
493         wb_data[1] = 0;
494         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
495                     wb_data, 2);
496
497         /* configure safc */
498         wb_data[0] = 0x1000200;
499         wb_data[1] = 0;
500         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
501                     wb_data, 2);
502         /* fix for emulation */
503         if (CHIP_REV_IS_EMUL(bp)) {
504                 wb_data[0] = 0xf000;
505                 wb_data[1] = 0;
506                 REG_WR_DMAE(bp,
507                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
508                             wb_data, 2);
509         }
510
511         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
512         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
513         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
514         val = 0;
515         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
516                 val = 1;
517         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
518         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
519         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
520         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
521         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
522         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
523
524         vars->mac_type = MAC_TYPE_BMAC;
525         return 0;
526 }
527
528 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
529 {
530         struct bnx2x *bp = params->bp;
531         u32 val;
532
533         if (phy_flags & PHY_XGXS_FLAG) {
534                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
535                 val = XGXS_RESET_BITS;
536
537         } else { /* SerDes */
538                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
539                 val = SERDES_RESET_BITS;
540         }
541
542         val = val << (params->port*16);
543
544         /* reset and unreset the SerDes/XGXS */
545         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
546                     val);
547         udelay(500);
548         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
549                     val);
550         bnx2x_set_phy_mdio(params, phy_flags);
551 }
552
553 void bnx2x_link_status_update(struct link_params *params,
554                             struct link_vars   *vars)
555 {
556         struct bnx2x *bp = params->bp;
557         u8 link_10g;
558         u8 port = params->port;
559
560         if (params->switch_cfg ==  SWITCH_CFG_1G)
561                 vars->phy_flags = PHY_SERDES_FLAG;
562         else
563                 vars->phy_flags = PHY_XGXS_FLAG;
564         vars->link_status = REG_RD(bp, params->shmem_base +
565                                           offsetof(struct shmem_region,
566                                            port_mb[port].link_status));
567
568         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
569
570         if (vars->link_up) {
571                 DP(NETIF_MSG_LINK, "phy link up\n");
572
573                 vars->phy_link_up = 1;
574                 vars->duplex = DUPLEX_FULL;
575                 switch (vars->link_status &
576                                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
577                         case LINK_10THD:
578                                 vars->duplex = DUPLEX_HALF;
579                                 /* fall thru */
580                         case LINK_10TFD:
581                                 vars->line_speed = SPEED_10;
582                                 break;
583
584                         case LINK_100TXHD:
585                                 vars->duplex = DUPLEX_HALF;
586                                 /* fall thru */
587                         case LINK_100T4:
588                         case LINK_100TXFD:
589                                 vars->line_speed = SPEED_100;
590                                 break;
591
592                         case LINK_1000THD:
593                                 vars->duplex = DUPLEX_HALF;
594                                 /* fall thru */
595                         case LINK_1000TFD:
596                                 vars->line_speed = SPEED_1000;
597                                 break;
598
599                         case LINK_2500THD:
600                                 vars->duplex = DUPLEX_HALF;
601                                 /* fall thru */
602                         case LINK_2500TFD:
603                                 vars->line_speed = SPEED_2500;
604                                 break;
605
606                         case LINK_10GTFD:
607                                 vars->line_speed = SPEED_10000;
608                                 break;
609
610                         case LINK_12GTFD:
611                                 vars->line_speed = SPEED_12000;
612                                 break;
613
614                         case LINK_12_5GTFD:
615                                 vars->line_speed = SPEED_12500;
616                                 break;
617
618                         case LINK_13GTFD:
619                                 vars->line_speed = SPEED_13000;
620                                 break;
621
622                         case LINK_15GTFD:
623                                 vars->line_speed = SPEED_15000;
624                                 break;
625
626                         case LINK_16GTFD:
627                                 vars->line_speed = SPEED_16000;
628                                 break;
629
630                         default:
631                                 break;
632                 }
633
634                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
635                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
636                 else
637                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
638
639                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
640                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
641                 else
642                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
643
644                 if (vars->phy_flags & PHY_XGXS_FLAG) {
645                         if (vars->line_speed &&
646                             ((vars->line_speed == SPEED_10) ||
647                              (vars->line_speed == SPEED_100))) {
648                                 vars->phy_flags |= PHY_SGMII_FLAG;
649                         } else {
650                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
651                         }
652                 }
653
654                 /* anything 10 and over uses the bmac */
655                 link_10g = ((vars->line_speed == SPEED_10000) ||
656                             (vars->line_speed == SPEED_12000) ||
657                             (vars->line_speed == SPEED_12500) ||
658                             (vars->line_speed == SPEED_13000) ||
659                             (vars->line_speed == SPEED_15000) ||
660                             (vars->line_speed == SPEED_16000));
661                 if (link_10g)
662                         vars->mac_type = MAC_TYPE_BMAC;
663                 else
664                         vars->mac_type = MAC_TYPE_EMAC;
665
666         } else { /* link down */
667                 DP(NETIF_MSG_LINK, "phy link down\n");
668
669                 vars->phy_link_up = 0;
670
671                 vars->line_speed = 0;
672                 vars->duplex = DUPLEX_FULL;
673                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
674
675                 /* indicate no mac active */
676                 vars->mac_type = MAC_TYPE_NONE;
677         }
678
679         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
680                  vars->link_status, vars->phy_link_up);
681         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
682                  vars->line_speed, vars->duplex, vars->flow_ctrl);
683 }
684
685 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
686 {
687         struct bnx2x *bp = params->bp;
688
689         REG_WR(bp, params->shmem_base +
690                    offsetof(struct shmem_region,
691                             port_mb[params->port].link_status),
692                         link_status);
693 }
694
695 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
696 {
697         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
698                 NIG_REG_INGRESS_BMAC0_MEM;
699         u32 wb_data[2];
700         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
701
702         /* Only if the bmac is out of reset */
703         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
704                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
705             nig_bmac_enable) {
706
707                 /* Clear Rx Enable bit in BMAC_CONTROL register */
708                 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
709                             wb_data, 2);
710                 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
711                 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
712                             wb_data, 2);
713
714                 msleep(1);
715         }
716 }
717
718 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
719                          u32 line_speed)
720 {
721         struct bnx2x *bp = params->bp;
722         u8 port = params->port;
723         u32 init_crd, crd;
724         u32 count = 1000;
725
726         /* disable port */
727         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
728
729         /* wait for init credit */
730         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
731         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
732         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
733
734         while ((init_crd != crd) && count) {
735                 msleep(5);
736
737                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
738                 count--;
739         }
740         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
741         if (init_crd != crd) {
742                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
743                           init_crd, crd);
744                 return -EINVAL;
745         }
746
747         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
748             line_speed == SPEED_10 ||
749             line_speed == SPEED_100 ||
750             line_speed == SPEED_1000 ||
751             line_speed == SPEED_2500) {
752                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
753                 /* update threshold */
754                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
755                 /* update init credit */
756                 init_crd = 778;         /* (800-18-4) */
757
758         } else {
759                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
760                               ETH_OVREHEAD)/16;
761                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
762                 /* update threshold */
763                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
764                 /* update init credit */
765                 switch (line_speed) {
766                 case SPEED_10000:
767                         init_crd = thresh + 553 - 22;
768                         break;
769
770                 case SPEED_12000:
771                         init_crd = thresh + 664 - 22;
772                         break;
773
774                 case SPEED_13000:
775                         init_crd = thresh + 742 - 22;
776                         break;
777
778                 case SPEED_16000:
779                         init_crd = thresh + 778 - 22;
780                         break;
781                 default:
782                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
783                                   line_speed);
784                         return -EINVAL;
785                 }
786         }
787         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
788         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
789                  line_speed, init_crd);
790
791         /* probe the credit changes */
792         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
793         msleep(5);
794         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
795
796         /* enable port */
797         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
798         return 0;
799 }
800
801 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
802 {
803         u32 emac_base;
804
805         switch (ext_phy_type) {
806         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
807         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
808         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
809                 /* All MDC/MDIO is directed through single EMAC */
810                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
811                         emac_base = GRCBASE_EMAC0;
812                 else
813                         emac_base = GRCBASE_EMAC1;
814                 break;
815         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
816                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
817                 break;
818         default:
819                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
820                 break;
821         }
822         return emac_base;
823
824 }
825
826 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
827                   u8 phy_addr, u8 devad, u16 reg, u16 val)
828 {
829         u32 tmp, saved_mode;
830         u8 i, rc = 0;
831         u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
832
833         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
834          * (a value of 49==0x31) and make sure that the AUTO poll is off
835          */
836
837         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
838         tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
839                              EMAC_MDIO_MODE_CLOCK_CNT);
840         tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
841                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
842         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
843         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
844         udelay(40);
845
846         /* address */
847
848         tmp = ((phy_addr << 21) | (devad << 16) | reg |
849                EMAC_MDIO_COMM_COMMAND_ADDRESS |
850                EMAC_MDIO_COMM_START_BUSY);
851         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
852
853         for (i = 0; i < 50; i++) {
854                 udelay(10);
855
856                 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
857                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
858                         udelay(5);
859                         break;
860                 }
861         }
862         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
863                 DP(NETIF_MSG_LINK, "write phy register failed\n");
864                 rc = -EFAULT;
865         } else {
866                 /* data */
867                 tmp = ((phy_addr << 21) | (devad << 16) | val |
868                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
869                        EMAC_MDIO_COMM_START_BUSY);
870                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
871
872                 for (i = 0; i < 50; i++) {
873                         udelay(10);
874
875                         tmp = REG_RD(bp, mdio_ctrl +
876                                          EMAC_REG_EMAC_MDIO_COMM);
877                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
878                                 udelay(5);
879                                 break;
880                         }
881                 }
882                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
883                         DP(NETIF_MSG_LINK, "write phy register failed\n");
884                         rc = -EFAULT;
885                 }
886         }
887
888         /* Restore the saved mode */
889         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
890
891         return rc;
892 }
893
894 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
895                  u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
896 {
897         u32 val, saved_mode;
898         u16 i;
899         u8 rc = 0;
900
901         u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
902         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
903          * (a value of 49==0x31) and make sure that the AUTO poll is off
904          */
905
906         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
907         val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
908                              EMAC_MDIO_MODE_CLOCK_CNT));
909         val |= (EMAC_MDIO_MODE_CLAUSE_45 |
910                 (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
911         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
912         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
913         udelay(40);
914
915         /* address */
916         val = ((phy_addr << 21) | (devad << 16) | reg |
917                EMAC_MDIO_COMM_COMMAND_ADDRESS |
918                EMAC_MDIO_COMM_START_BUSY);
919         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
920
921         for (i = 0; i < 50; i++) {
922                 udelay(10);
923
924                 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
925                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
926                         udelay(5);
927                         break;
928                 }
929         }
930         if (val & EMAC_MDIO_COMM_START_BUSY) {
931                 DP(NETIF_MSG_LINK, "read phy register failed\n");
932
933                 *ret_val = 0;
934                 rc = -EFAULT;
935
936         } else {
937                 /* data */
938                 val = ((phy_addr << 21) | (devad << 16) |
939                        EMAC_MDIO_COMM_COMMAND_READ_45 |
940                        EMAC_MDIO_COMM_START_BUSY);
941                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
942
943                 for (i = 0; i < 50; i++) {
944                         udelay(10);
945
946                         val = REG_RD(bp, mdio_ctrl +
947                                           EMAC_REG_EMAC_MDIO_COMM);
948                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
949                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
950                                 break;
951                         }
952                 }
953                 if (val & EMAC_MDIO_COMM_START_BUSY) {
954                         DP(NETIF_MSG_LINK, "read phy register failed\n");
955
956                         *ret_val = 0;
957                         rc = -EFAULT;
958                 }
959         }
960
961         /* Restore the saved mode */
962         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
963
964         return rc;
965 }
966
967 static void bnx2x_set_aer_mmd(struct link_params *params,
968                             struct link_vars   *vars)
969 {
970         struct bnx2x *bp = params->bp;
971         u32 ser_lane;
972         u16 offset;
973
974         ser_lane = ((params->lane_config &
975                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
976                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
977
978         offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
979                 (params->phy_addr + ser_lane) : 0;
980
981         CL45_WR_OVER_CL22(bp, params->port,
982                               params->phy_addr,
983                               MDIO_REG_BANK_AER_BLOCK,
984                               MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
985 }
986
987 static void bnx2x_set_master_ln(struct link_params *params)
988 {
989         struct bnx2x *bp = params->bp;
990         u16 new_master_ln, ser_lane;
991         ser_lane =  ((params->lane_config &
992                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
993                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
994
995         /* set the master_ln for AN */
996         CL45_RD_OVER_CL22(bp, params->port,
997                               params->phy_addr,
998                               MDIO_REG_BANK_XGXS_BLOCK2,
999                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1000                               &new_master_ln);
1001
1002         CL45_WR_OVER_CL22(bp, params->port,
1003                               params->phy_addr,
1004                               MDIO_REG_BANK_XGXS_BLOCK2 ,
1005                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1006                               (new_master_ln | ser_lane));
1007 }
1008
1009 static u8 bnx2x_reset_unicore(struct link_params *params)
1010 {
1011         struct bnx2x *bp = params->bp;
1012         u16 mii_control;
1013         u16 i;
1014
1015         CL45_RD_OVER_CL22(bp, params->port,
1016                               params->phy_addr,
1017                               MDIO_REG_BANK_COMBO_IEEE0,
1018                               MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1019
1020         /* reset the unicore */
1021         CL45_WR_OVER_CL22(bp, params->port,
1022                               params->phy_addr,
1023                               MDIO_REG_BANK_COMBO_IEEE0,
1024                               MDIO_COMBO_IEEE0_MII_CONTROL,
1025                               (mii_control |
1026                                MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1027         if (params->switch_cfg == SWITCH_CFG_1G)
1028                 bnx2x_set_serdes_access(params);
1029
1030         /* wait for the reset to self clear */
1031         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1032                 udelay(5);
1033
1034                 /* the reset erased the previous bank value */
1035                 CL45_RD_OVER_CL22(bp, params->port,
1036                                       params->phy_addr,
1037                               MDIO_REG_BANK_COMBO_IEEE0,
1038                               MDIO_COMBO_IEEE0_MII_CONTROL,
1039                               &mii_control);
1040
1041                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1042                         udelay(5);
1043                         return 0;
1044                 }
1045         }
1046
1047         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1048         return -EINVAL;
1049
1050 }
1051
1052 static void bnx2x_set_swap_lanes(struct link_params *params)
1053 {
1054         struct bnx2x *bp = params->bp;
1055         /* Each two bits represents a lane number:
1056            No swap is 0123 => 0x1b no need to enable the swap */
1057         u16 ser_lane, rx_lane_swap, tx_lane_swap;
1058
1059         ser_lane = ((params->lane_config &
1060                          PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1061                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1062         rx_lane_swap = ((params->lane_config &
1063                              PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1064                             PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1065         tx_lane_swap = ((params->lane_config &
1066                              PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1067                             PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1068
1069         if (rx_lane_swap != 0x1b) {
1070                 CL45_WR_OVER_CL22(bp, params->port,
1071                                       params->phy_addr,
1072                                     MDIO_REG_BANK_XGXS_BLOCK2,
1073                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1074                                     (rx_lane_swap |
1075                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1076                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1077         } else {
1078                 CL45_WR_OVER_CL22(bp, params->port,
1079                                       params->phy_addr,
1080                                       MDIO_REG_BANK_XGXS_BLOCK2,
1081                                       MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1082         }
1083
1084         if (tx_lane_swap != 0x1b) {
1085                 CL45_WR_OVER_CL22(bp, params->port,
1086                                       params->phy_addr,
1087                                       MDIO_REG_BANK_XGXS_BLOCK2,
1088                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1089                                       (tx_lane_swap |
1090                                        MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1091         } else {
1092                 CL45_WR_OVER_CL22(bp, params->port,
1093                                       params->phy_addr,
1094                                       MDIO_REG_BANK_XGXS_BLOCK2,
1095                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1096         }
1097 }
1098
1099 static void bnx2x_set_parallel_detection(struct link_params *params,
1100                                        u8                phy_flags)
1101 {
1102         struct bnx2x *bp = params->bp;
1103         u16 control2;
1104
1105         CL45_RD_OVER_CL22(bp, params->port,
1106                               params->phy_addr,
1107                               MDIO_REG_BANK_SERDES_DIGITAL,
1108                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1109                               &control2);
1110         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1111                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1112         else
1113                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1114         DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n",
1115                 params->speed_cap_mask, control2);
1116         CL45_WR_OVER_CL22(bp, params->port,
1117                               params->phy_addr,
1118                               MDIO_REG_BANK_SERDES_DIGITAL,
1119                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1120                               control2);
1121
1122         if ((phy_flags & PHY_XGXS_FLAG) &&
1123              (params->speed_cap_mask &
1124                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
1125                 DP(NETIF_MSG_LINK, "XGXS\n");
1126
1127                 CL45_WR_OVER_CL22(bp, params->port,
1128                                       params->phy_addr,
1129                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1130                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1131                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1132
1133                 CL45_RD_OVER_CL22(bp, params->port,
1134                                       params->phy_addr,
1135                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1136                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1137                                 &control2);
1138
1139
1140                 control2 |=
1141                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1142
1143                 CL45_WR_OVER_CL22(bp, params->port,
1144                                       params->phy_addr,
1145                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1146                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1147                                 control2);
1148
1149                 /* Disable parallel detection of HiG */
1150                 CL45_WR_OVER_CL22(bp, params->port,
1151                                       params->phy_addr,
1152                                 MDIO_REG_BANK_XGXS_BLOCK2,
1153                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1154                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1155                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1156         }
1157 }
1158
1159 static void bnx2x_set_autoneg(struct link_params *params,
1160                             struct link_vars *vars,
1161                             u8 enable_cl73)
1162 {
1163         struct bnx2x *bp = params->bp;
1164         u16 reg_val;
1165
1166         /* CL37 Autoneg */
1167
1168         CL45_RD_OVER_CL22(bp, params->port,
1169                               params->phy_addr,
1170                               MDIO_REG_BANK_COMBO_IEEE0,
1171                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1172
1173         /* CL37 Autoneg Enabled */
1174         if (vars->line_speed == SPEED_AUTO_NEG)
1175                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1176         else /* CL37 Autoneg Disabled */
1177                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1178                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1179
1180         CL45_WR_OVER_CL22(bp, params->port,
1181                               params->phy_addr,
1182                               MDIO_REG_BANK_COMBO_IEEE0,
1183                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1184
1185         /* Enable/Disable Autodetection */
1186
1187         CL45_RD_OVER_CL22(bp, params->port,
1188                               params->phy_addr,
1189                               MDIO_REG_BANK_SERDES_DIGITAL,
1190                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1191         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
1192                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
1193         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
1194         if (vars->line_speed == SPEED_AUTO_NEG)
1195                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1196         else
1197                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1198
1199         CL45_WR_OVER_CL22(bp, params->port,
1200                               params->phy_addr,
1201                               MDIO_REG_BANK_SERDES_DIGITAL,
1202                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1203
1204         /* Enable TetonII and BAM autoneg */
1205         CL45_RD_OVER_CL22(bp, params->port,
1206                               params->phy_addr,
1207                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1208                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1209                           &reg_val);
1210         if (vars->line_speed == SPEED_AUTO_NEG) {
1211                 /* Enable BAM aneg Mode and TetonII aneg Mode */
1212                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1213                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1214         } else {
1215                 /* TetonII and BAM Autoneg Disabled */
1216                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1217                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1218         }
1219         CL45_WR_OVER_CL22(bp, params->port,
1220                               params->phy_addr,
1221                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1222                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1223                               reg_val);
1224
1225         if (enable_cl73) {
1226                 /* Enable Cl73 FSM status bits */
1227                 CL45_WR_OVER_CL22(bp, params->port,
1228                                       params->phy_addr,
1229                                       MDIO_REG_BANK_CL73_USERB0,
1230                                     MDIO_CL73_USERB0_CL73_UCTRL,
1231                                       0xe);
1232
1233                 /* Enable BAM Station Manager*/
1234                 CL45_WR_OVER_CL22(bp, params->port,
1235                         params->phy_addr,
1236                         MDIO_REG_BANK_CL73_USERB0,
1237                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1238                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1239                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1240                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
1241
1242                 /* Advertise CL73 link speeds */
1243                         CL45_RD_OVER_CL22(bp, params->port,
1244                                               params->phy_addr,
1245                                               MDIO_REG_BANK_CL73_IEEEB1,
1246                                               MDIO_CL73_IEEEB1_AN_ADV2,
1247                                               &reg_val);
1248                 if (params->speed_cap_mask &
1249                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1250                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1251                 if (params->speed_cap_mask &
1252                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1253                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1254
1255                         CL45_WR_OVER_CL22(bp, params->port,
1256                                               params->phy_addr,
1257                                               MDIO_REG_BANK_CL73_IEEEB1,
1258                                               MDIO_CL73_IEEEB1_AN_ADV2,
1259                                       reg_val);
1260
1261                 /* CL73 Autoneg Enabled */
1262                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1263
1264         } else /* CL73 Autoneg Disabled */
1265                 reg_val = 0;
1266
1267         CL45_WR_OVER_CL22(bp, params->port,
1268                               params->phy_addr,
1269                               MDIO_REG_BANK_CL73_IEEEB0,
1270                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1271 }
1272
1273 /* program SerDes, forced speed */
1274 static void bnx2x_program_serdes(struct link_params *params,
1275                                struct link_vars *vars)
1276 {
1277         struct bnx2x *bp = params->bp;
1278         u16 reg_val;
1279
1280         /* program duplex, disable autoneg and sgmii*/
1281         CL45_RD_OVER_CL22(bp, params->port,
1282                               params->phy_addr,
1283                               MDIO_REG_BANK_COMBO_IEEE0,
1284                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1285         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1286                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1287                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
1288         if (params->req_duplex == DUPLEX_FULL)
1289                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1290         CL45_WR_OVER_CL22(bp, params->port,
1291                               params->phy_addr,
1292                               MDIO_REG_BANK_COMBO_IEEE0,
1293                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1294
1295         /* program speed
1296            - needed only if the speed is greater than 1G (2.5G or 10G) */
1297         CL45_RD_OVER_CL22(bp, params->port,
1298                                       params->phy_addr,
1299                                       MDIO_REG_BANK_SERDES_DIGITAL,
1300                                       MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1301         /* clearing the speed value before setting the right speed */
1302         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1303
1304         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1305                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1306
1307         if (!((vars->line_speed == SPEED_1000) ||
1308               (vars->line_speed == SPEED_100) ||
1309               (vars->line_speed == SPEED_10))) {
1310
1311                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1312                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1313                 if (vars->line_speed == SPEED_10000)
1314                         reg_val |=
1315                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1316                 if (vars->line_speed == SPEED_13000)
1317                         reg_val |=
1318                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1319         }
1320
1321         CL45_WR_OVER_CL22(bp, params->port,
1322                                       params->phy_addr,
1323                                       MDIO_REG_BANK_SERDES_DIGITAL,
1324                                       MDIO_SERDES_DIGITAL_MISC1, reg_val);
1325
1326 }
1327
1328 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1329 {
1330         struct bnx2x *bp = params->bp;
1331         u16 val = 0;
1332
1333         /* configure the 48 bits for BAM AN */
1334
1335         /* set extended capabilities */
1336         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1337                 val |= MDIO_OVER_1G_UP1_2_5G;
1338         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1339                 val |= MDIO_OVER_1G_UP1_10G;
1340         CL45_WR_OVER_CL22(bp, params->port,
1341                               params->phy_addr,
1342                               MDIO_REG_BANK_OVER_1G,
1343                               MDIO_OVER_1G_UP1, val);
1344
1345         CL45_WR_OVER_CL22(bp, params->port,
1346                               params->phy_addr,
1347                               MDIO_REG_BANK_OVER_1G,
1348                               MDIO_OVER_1G_UP3, 0x400);
1349 }
1350
1351 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
1352 {
1353         struct bnx2x *bp = params->bp;
1354         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1355         /* resolve pause mode and advertisement
1356          * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1357
1358         switch (params->req_flow_ctrl) {
1359         case BNX2X_FLOW_CTRL_AUTO:
1360                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1361                         *ieee_fc |=
1362                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1363                 } else {
1364                         *ieee_fc |=
1365                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1366                 }
1367                 break;
1368         case BNX2X_FLOW_CTRL_TX:
1369                 *ieee_fc |=
1370                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1371                 break;
1372
1373         case BNX2X_FLOW_CTRL_RX:
1374         case BNX2X_FLOW_CTRL_BOTH:
1375                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1376                 break;
1377
1378         case BNX2X_FLOW_CTRL_NONE:
1379         default:
1380                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1381                 break;
1382         }
1383         DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
1384 }
1385
1386 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1387                                            u16 ieee_fc)
1388 {
1389         struct bnx2x *bp = params->bp;
1390         u16 val;
1391         /* for AN, we are always publishing full duplex */
1392
1393         CL45_WR_OVER_CL22(bp, params->port,
1394                               params->phy_addr,
1395                               MDIO_REG_BANK_COMBO_IEEE0,
1396                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
1397         CL45_RD_OVER_CL22(bp, params->port,
1398                               params->phy_addr,
1399                               MDIO_REG_BANK_CL73_IEEEB1,
1400                               MDIO_CL73_IEEEB1_AN_ADV1, &val);
1401         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
1402         val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
1403         CL45_WR_OVER_CL22(bp, params->port,
1404                               params->phy_addr,
1405                               MDIO_REG_BANK_CL73_IEEEB1,
1406                               MDIO_CL73_IEEEB1_AN_ADV1, val);
1407 }
1408
1409 static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
1410 {
1411         struct bnx2x *bp = params->bp;
1412         u16 mii_control;
1413
1414         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1415         /* Enable and restart BAM/CL37 aneg */
1416
1417         if (enable_cl73) {
1418                 CL45_RD_OVER_CL22(bp, params->port,
1419                                       params->phy_addr,
1420                                       MDIO_REG_BANK_CL73_IEEEB0,
1421                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1422                                       &mii_control);
1423
1424                 CL45_WR_OVER_CL22(bp, params->port,
1425                                 params->phy_addr,
1426                                 MDIO_REG_BANK_CL73_IEEEB0,
1427                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1428                                 (mii_control |
1429                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1430                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1431         } else {
1432
1433                 CL45_RD_OVER_CL22(bp, params->port,
1434                                       params->phy_addr,
1435                                       MDIO_REG_BANK_COMBO_IEEE0,
1436                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1437                                       &mii_control);
1438                 DP(NETIF_MSG_LINK,
1439                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1440                          mii_control);
1441                 CL45_WR_OVER_CL22(bp, params->port,
1442                                       params->phy_addr,
1443                                       MDIO_REG_BANK_COMBO_IEEE0,
1444                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1445                                       (mii_control |
1446                                        MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1447                                        MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1448         }
1449 }
1450
1451 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1452                                          struct link_vars *vars)
1453 {
1454         struct bnx2x *bp = params->bp;
1455         u16 control1;
1456
1457         /* in SGMII mode, the unicore is always slave */
1458
1459         CL45_RD_OVER_CL22(bp, params->port,
1460                               params->phy_addr,
1461                               MDIO_REG_BANK_SERDES_DIGITAL,
1462                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1463                       &control1);
1464         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1465         /* set sgmii mode (and not fiber) */
1466         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1467                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1468                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1469         CL45_WR_OVER_CL22(bp, params->port,
1470                               params->phy_addr,
1471                               MDIO_REG_BANK_SERDES_DIGITAL,
1472                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1473                               control1);
1474
1475         /* if forced speed */
1476         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1477                 /* set speed, disable autoneg */
1478                 u16 mii_control;
1479
1480                 CL45_RD_OVER_CL22(bp, params->port,
1481                                       params->phy_addr,
1482                                       MDIO_REG_BANK_COMBO_IEEE0,
1483                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1484                                       &mii_control);
1485                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1486                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1487                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1488
1489                 switch (vars->line_speed) {
1490                 case SPEED_100:
1491                         mii_control |=
1492                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1493                         break;
1494                 case SPEED_1000:
1495                         mii_control |=
1496                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1497                         break;
1498                 case SPEED_10:
1499                         /* there is nothing to set for 10M */
1500                         break;
1501                 default:
1502                         /* invalid speed for SGMII */
1503                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1504                                   vars->line_speed);
1505                         break;
1506                 }
1507
1508                 /* setting the full duplex */
1509                 if (params->req_duplex == DUPLEX_FULL)
1510                         mii_control |=
1511                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1512                 CL45_WR_OVER_CL22(bp, params->port,
1513                                       params->phy_addr,
1514                                       MDIO_REG_BANK_COMBO_IEEE0,
1515                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1516                                       mii_control);
1517
1518         } else { /* AN mode */
1519                 /* enable and restart AN */
1520                 bnx2x_restart_autoneg(params, 0);
1521         }
1522 }
1523
1524
1525 /*
1526  * link management
1527  */
1528
1529 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1530 {                                               /*  LD      LP   */
1531         switch (pause_result) {                 /* ASYM P ASYM P */
1532         case 0xb:                               /*   1  0   1  1 */
1533                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1534                 break;
1535
1536         case 0xe:                               /*   1  1   1  0 */
1537                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1538                 break;
1539
1540         case 0x5:                               /*   0  1   0  1 */
1541         case 0x7:                               /*   0  1   1  1 */
1542         case 0xd:                               /*   1  1   0  1 */
1543         case 0xf:                               /*   1  1   1  1 */
1544                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1545                 break;
1546
1547         default:
1548                 break;
1549         }
1550 }
1551
1552 static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params,
1553                                   struct link_vars *vars)
1554 {
1555         struct bnx2x *bp = params->bp;
1556         u8 ext_phy_addr;
1557         u16 ld_pause;           /* local */
1558         u16 lp_pause;           /* link partner */
1559         u16 an_complete;        /* AN complete */
1560         u16 pause_result;
1561         u8 ret = 0;
1562         u32 ext_phy_type;
1563         u8 port = params->port;
1564         ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
1565         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1566         /* read twice */
1567
1568         bnx2x_cl45_read(bp, port,
1569                       ext_phy_type,
1570                       ext_phy_addr,
1571                       MDIO_AN_DEVAD,
1572                       MDIO_AN_REG_STATUS, &an_complete);
1573         bnx2x_cl45_read(bp, port,
1574                       ext_phy_type,
1575                       ext_phy_addr,
1576                       MDIO_AN_DEVAD,
1577                       MDIO_AN_REG_STATUS, &an_complete);
1578
1579         if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1580                 ret = 1;
1581                 bnx2x_cl45_read(bp, port,
1582                               ext_phy_type,
1583                               ext_phy_addr,
1584                               MDIO_AN_DEVAD,
1585                               MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1586                 bnx2x_cl45_read(bp, port,
1587                               ext_phy_type,
1588                               ext_phy_addr,
1589                               MDIO_AN_DEVAD,
1590                               MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1591                 pause_result = (ld_pause &
1592                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1593                 pause_result |= (lp_pause &
1594                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1595                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1596                    pause_result);
1597                 bnx2x_pause_resolve(vars, pause_result);
1598                 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1599                      ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1600                         bnx2x_cl45_read(bp, port,
1601                                       ext_phy_type,
1602                                       ext_phy_addr,
1603                                       MDIO_AN_DEVAD,
1604                                       MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1605
1606                         bnx2x_cl45_read(bp, port,
1607                                       ext_phy_type,
1608                                       ext_phy_addr,
1609                                       MDIO_AN_DEVAD,
1610                                       MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1611                         pause_result = (ld_pause &
1612                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1613                         pause_result |= (lp_pause &
1614                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1615
1616                         bnx2x_pause_resolve(vars, pause_result);
1617                         DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1618                                  pause_result);
1619                 }
1620         }
1621         return ret;
1622 }
1623
1624 static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
1625 {
1626         struct bnx2x *bp = params->bp;
1627         u16 pd_10g, status2_1000x;
1628         CL45_RD_OVER_CL22(bp, params->port,
1629                               params->phy_addr,
1630                               MDIO_REG_BANK_SERDES_DIGITAL,
1631                               MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
1632                               &status2_1000x);
1633         CL45_RD_OVER_CL22(bp, params->port,
1634                               params->phy_addr,
1635                               MDIO_REG_BANK_SERDES_DIGITAL,
1636                               MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
1637                               &status2_1000x);
1638         if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
1639                 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
1640                          params->port);
1641                 return 1;
1642         }
1643
1644         CL45_RD_OVER_CL22(bp, params->port,
1645                               params->phy_addr,
1646                               MDIO_REG_BANK_10G_PARALLEL_DETECT,
1647                               MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
1648                               &pd_10g);
1649
1650         if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
1651                 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
1652                          params->port);
1653                 return 1;
1654         }
1655         return 0;
1656 }
1657
1658 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1659                                   struct link_vars *vars,
1660                                   u32 gp_status)
1661 {
1662         struct bnx2x *bp = params->bp;
1663         u16 ld_pause;   /* local driver */
1664         u16 lp_pause;   /* link partner */
1665         u16 pause_result;
1666
1667         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1668
1669         /* resolve from gp_status in case of AN complete and not sgmii */
1670         if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1671             (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1672             (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1673             (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1674              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1675                 if (bnx2x_direct_parallel_detect_used(params)) {
1676                         vars->flow_ctrl = params->req_fc_auto_adv;
1677                         return;
1678                 }
1679                 if ((gp_status &
1680                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
1681                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
1682                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
1683                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
1684
1685                         CL45_RD_OVER_CL22(bp, params->port,
1686                                               params->phy_addr,
1687                                               MDIO_REG_BANK_CL73_IEEEB1,
1688                                               MDIO_CL73_IEEEB1_AN_ADV1,
1689                                               &ld_pause);
1690                         CL45_RD_OVER_CL22(bp, params->port,
1691                                              params->phy_addr,
1692                                              MDIO_REG_BANK_CL73_IEEEB1,
1693                                              MDIO_CL73_IEEEB1_AN_LP_ADV1,
1694                                              &lp_pause);
1695                         pause_result = (ld_pause &
1696                                         MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
1697                                         >> 8;
1698                         pause_result |= (lp_pause &
1699                                         MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
1700                                         >> 10;
1701                         DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
1702                                  pause_result);
1703                 } else {
1704
1705                         CL45_RD_OVER_CL22(bp, params->port,
1706                                               params->phy_addr,
1707                                               MDIO_REG_BANK_COMBO_IEEE0,
1708                                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1709                                               &ld_pause);
1710                         CL45_RD_OVER_CL22(bp, params->port,
1711                                params->phy_addr,
1712                                MDIO_REG_BANK_COMBO_IEEE0,
1713                                MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1714                                &lp_pause);
1715                         pause_result = (ld_pause &
1716                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1717                         pause_result |= (lp_pause &
1718                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1719                         DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
1720                                  pause_result);
1721                 }
1722                 bnx2x_pause_resolve(vars, pause_result);
1723         } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1724                    (bnx2x_ext_phy_resolve_fc(params, vars))) {
1725                 return;
1726         } else {
1727                 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1728                         vars->flow_ctrl = params->req_fc_auto_adv;
1729                 else
1730                         vars->flow_ctrl = params->req_flow_ctrl;
1731         }
1732         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1733 }
1734
1735 static void bnx2x_check_fallback_to_cl37(struct link_params *params)
1736 {
1737         struct bnx2x *bp = params->bp;
1738         u16 rx_status, ustat_val, cl37_fsm_recieved;
1739         DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
1740         /* Step 1: Make sure signal is detected */
1741         CL45_RD_OVER_CL22(bp, params->port,
1742                               params->phy_addr,
1743                               MDIO_REG_BANK_RX0,
1744                               MDIO_RX0_RX_STATUS,
1745                               &rx_status);
1746         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
1747             (MDIO_RX0_RX_STATUS_SIGDET)) {
1748                 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
1749                              "rx_status(0x80b0) = 0x%x\n", rx_status);
1750                 CL45_WR_OVER_CL22(bp, params->port,
1751                                       params->phy_addr,
1752                                       MDIO_REG_BANK_CL73_IEEEB0,
1753                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1754                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
1755                 return;
1756         }
1757         /* Step 2: Check CL73 state machine */
1758         CL45_RD_OVER_CL22(bp, params->port,
1759                               params->phy_addr,
1760                               MDIO_REG_BANK_CL73_USERB0,
1761                               MDIO_CL73_USERB0_CL73_USTAT1,
1762                               &ustat_val);
1763         if ((ustat_val &
1764              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
1765               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
1766             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
1767               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
1768                 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
1769                              "ustat_val(0x8371) = 0x%x\n", ustat_val);
1770                 return;
1771         }
1772         /* Step 3: Check CL37 Message Pages received to indicate LP
1773         supports only CL37 */
1774         CL45_RD_OVER_CL22(bp, params->port,
1775                               params->phy_addr,
1776                               MDIO_REG_BANK_REMOTE_PHY,
1777                               MDIO_REMOTE_PHY_MISC_RX_STATUS,
1778                               &cl37_fsm_recieved);
1779         if ((cl37_fsm_recieved &
1780              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
1781              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
1782             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
1783               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
1784                 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
1785                              "misc_rx_status(0x8330) = 0x%x\n",
1786                          cl37_fsm_recieved);
1787                 return;
1788         }
1789         /* The combined cl37/cl73 fsm state information indicating that we are
1790         connected to a device which does not support cl73, but does support
1791         cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
1792         /* Disable CL73 */
1793         CL45_WR_OVER_CL22(bp, params->port,
1794                               params->phy_addr,
1795                               MDIO_REG_BANK_CL73_IEEEB0,
1796                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1797                               0);
1798         /* Restart CL37 autoneg */
1799         bnx2x_restart_autoneg(params, 0);
1800         DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
1801 }
1802 static u8 bnx2x_link_settings_status(struct link_params *params,
1803                                    struct link_vars *vars,
1804                                    u32 gp_status,
1805                                    u8 ext_phy_link_up)
1806 {
1807         struct bnx2x *bp = params->bp;
1808         u16 new_line_speed;
1809         u8 rc = 0;
1810         vars->link_status = 0;
1811
1812         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1813                 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1814                          gp_status);
1815
1816                 vars->phy_link_up = 1;
1817                 vars->link_status |= LINK_STATUS_LINK_UP;
1818
1819                 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1820                         vars->duplex = DUPLEX_FULL;
1821                 else
1822                         vars->duplex = DUPLEX_HALF;
1823
1824                 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1825
1826                 switch (gp_status & GP_STATUS_SPEED_MASK) {
1827                 case GP_STATUS_10M:
1828                         new_line_speed = SPEED_10;
1829                         if (vars->duplex == DUPLEX_FULL)
1830                                 vars->link_status |= LINK_10TFD;
1831                         else
1832                                 vars->link_status |= LINK_10THD;
1833                         break;
1834
1835                 case GP_STATUS_100M:
1836                         new_line_speed = SPEED_100;
1837                         if (vars->duplex == DUPLEX_FULL)
1838                                 vars->link_status |= LINK_100TXFD;
1839                         else
1840                                 vars->link_status |= LINK_100TXHD;
1841                         break;
1842
1843                 case GP_STATUS_1G:
1844                 case GP_STATUS_1G_KX:
1845                         new_line_speed = SPEED_1000;
1846                         if (vars->duplex == DUPLEX_FULL)
1847                                 vars->link_status |= LINK_1000TFD;
1848                         else
1849                                 vars->link_status |= LINK_1000THD;
1850                         break;
1851
1852                 case GP_STATUS_2_5G:
1853                         new_line_speed = SPEED_2500;
1854                         if (vars->duplex == DUPLEX_FULL)
1855                                 vars->link_status |= LINK_2500TFD;
1856                         else
1857                                 vars->link_status |= LINK_2500THD;
1858                         break;
1859
1860                 case GP_STATUS_5G:
1861                 case GP_STATUS_6G:
1862                         DP(NETIF_MSG_LINK,
1863                                  "link speed unsupported  gp_status 0x%x\n",
1864                                   gp_status);
1865                         return -EINVAL;
1866
1867                 case GP_STATUS_10G_KX4:
1868                 case GP_STATUS_10G_HIG:
1869                 case GP_STATUS_10G_CX4:
1870                         new_line_speed = SPEED_10000;
1871                         vars->link_status |= LINK_10GTFD;
1872                         break;
1873
1874                 case GP_STATUS_12G_HIG:
1875                         new_line_speed = SPEED_12000;
1876                         vars->link_status |= LINK_12GTFD;
1877                         break;
1878
1879                 case GP_STATUS_12_5G:
1880                         new_line_speed = SPEED_12500;
1881                         vars->link_status |= LINK_12_5GTFD;
1882                         break;
1883
1884                 case GP_STATUS_13G:
1885                         new_line_speed = SPEED_13000;
1886                         vars->link_status |= LINK_13GTFD;
1887                         break;
1888
1889                 case GP_STATUS_15G:
1890                         new_line_speed = SPEED_15000;
1891                         vars->link_status |= LINK_15GTFD;
1892                         break;
1893
1894                 case GP_STATUS_16G:
1895                         new_line_speed = SPEED_16000;
1896                         vars->link_status |= LINK_16GTFD;
1897                         break;
1898
1899                 default:
1900                         DP(NETIF_MSG_LINK,
1901                                   "link speed unsupported gp_status 0x%x\n",
1902                                   gp_status);
1903                         return -EINVAL;
1904                 }
1905
1906                 /* Upon link speed change set the NIG into drain mode.
1907                 Comes to deals with possible FIFO glitch due to clk change
1908                 when speed is decreased without link down indicator */
1909                 if (new_line_speed != vars->line_speed) {
1910                         if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) !=
1911                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT &&
1912                             ext_phy_link_up) {
1913                                 DP(NETIF_MSG_LINK, "Internal link speed %d is"
1914                                             " different than the external"
1915                                             " link speed %d\n", new_line_speed,
1916                                           vars->line_speed);
1917                                 vars->phy_link_up = 0;
1918                                 return 0;
1919                         }
1920                         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1921                                     + params->port*4, 0);
1922                         msleep(1);
1923                 }
1924                 vars->line_speed = new_line_speed;
1925                 vars->link_status |= LINK_STATUS_SERDES_LINK;
1926
1927                 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1928                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1929                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1930                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1931                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1932                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1933                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
1934                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1935                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
1936                         vars->autoneg = AUTO_NEG_ENABLED;
1937
1938                         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1939                                 vars->autoneg |= AUTO_NEG_COMPLETE;
1940                                 vars->link_status |=
1941                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1942                         }
1943
1944                         vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1945                         vars->link_status |=
1946                                 LINK_STATUS_PARALLEL_DETECTION_USED;
1947
1948                 }
1949                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1950                         vars->link_status |=
1951                                 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1952
1953                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1954                         vars->link_status |=
1955                                 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1956
1957         } else { /* link_down */
1958                 DP(NETIF_MSG_LINK, "phy link down\n");
1959
1960                 vars->phy_link_up = 0;
1961
1962                 vars->duplex = DUPLEX_FULL;
1963                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1964                 vars->autoneg = AUTO_NEG_DISABLED;
1965                 vars->mac_type = MAC_TYPE_NONE;
1966
1967                 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1968                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1969                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT))) {
1970                         /* Check signal is detected */
1971                         bnx2x_check_fallback_to_cl37(params);
1972                 }
1973         }
1974
1975         DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
1976                  gp_status, vars->phy_link_up, vars->line_speed);
1977         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
1978                  " autoneg 0x%x\n",
1979                  vars->duplex,
1980                  vars->flow_ctrl, vars->autoneg);
1981         DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1982
1983         return rc;
1984 }
1985
1986 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
1987 {
1988         struct bnx2x *bp = params->bp;
1989         u16 lp_up2;
1990         u16 tx_driver;
1991         u16 bank;
1992
1993         /* read precomp */
1994         CL45_RD_OVER_CL22(bp, params->port,
1995                               params->phy_addr,
1996                               MDIO_REG_BANK_OVER_1G,
1997                               MDIO_OVER_1G_LP_UP2, &lp_up2);
1998
1999         /* bits [10:7] at lp_up2, positioned at [15:12] */
2000         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
2001                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
2002                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
2003
2004         if (lp_up2 == 0)
2005                 return;
2006
2007         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
2008               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
2009                 CL45_RD_OVER_CL22(bp, params->port,
2010                                       params->phy_addr,
2011                                       bank,
2012                                       MDIO_TX0_TX_DRIVER, &tx_driver);
2013
2014                 /* replace tx_driver bits [15:12] */
2015                 if (lp_up2 !=
2016                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
2017                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
2018                         tx_driver |= lp_up2;
2019                         CL45_WR_OVER_CL22(bp, params->port,
2020                                               params->phy_addr,
2021                                               bank,
2022                                               MDIO_TX0_TX_DRIVER, tx_driver);
2023                 }
2024         }
2025 }
2026
2027 static u8 bnx2x_emac_program(struct link_params *params,
2028                            u32 line_speed, u32 duplex)
2029 {
2030         struct bnx2x *bp = params->bp;
2031         u8 port = params->port;
2032         u16 mode = 0;
2033
2034         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
2035         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
2036                      EMAC_REG_EMAC_MODE,
2037                      (EMAC_MODE_25G_MODE |
2038                      EMAC_MODE_PORT_MII_10M |
2039                      EMAC_MODE_HALF_DUPLEX));
2040         switch (line_speed) {
2041         case SPEED_10:
2042                 mode |= EMAC_MODE_PORT_MII_10M;
2043                 break;
2044
2045         case SPEED_100:
2046                 mode |= EMAC_MODE_PORT_MII;
2047                 break;
2048
2049         case SPEED_1000:
2050                 mode |= EMAC_MODE_PORT_GMII;
2051                 break;
2052
2053         case SPEED_2500:
2054                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
2055                 break;
2056
2057         default:
2058                 /* 10G not valid for EMAC */
2059                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
2060                 return -EINVAL;
2061         }
2062
2063         if (duplex == DUPLEX_HALF)
2064                 mode |= EMAC_MODE_HALF_DUPLEX;
2065         bnx2x_bits_en(bp,
2066                     GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
2067                     mode);
2068
2069         bnx2x_set_led(params, LED_MODE_OPER, line_speed);
2070         return 0;
2071 }
2072
2073 /*****************************************************************************/
2074 /*                           External Phy section                            */
2075 /*****************************************************************************/
2076 void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
2077 {
2078         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2079                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
2080         msleep(1);
2081         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2082                       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
2083 }
2084
2085 static void bnx2x_ext_phy_reset(struct link_params *params,
2086                               struct link_vars   *vars)
2087 {
2088         struct bnx2x *bp = params->bp;
2089         u32 ext_phy_type;
2090         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2091
2092         DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
2093         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2094         /* The PHY reset is controled by GPIO 1
2095          * Give it 1ms of reset pulse
2096          */
2097         if (vars->phy_flags & PHY_XGXS_FLAG) {
2098
2099                 switch (ext_phy_type) {
2100                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2101                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
2102                         break;
2103
2104                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2105                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2106                         DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
2107
2108                         /* Restore normal power mode*/
2109                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2110                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2111                                           params->port);
2112
2113                         /* HW reset */
2114                         bnx2x_ext_phy_hw_reset(bp, params->port);
2115
2116                         bnx2x_cl45_write(bp, params->port,
2117                                        ext_phy_type,
2118                                        ext_phy_addr,
2119                                        MDIO_PMA_DEVAD,
2120                                        MDIO_PMA_REG_CTRL, 0xa040);
2121                         break;
2122
2123                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
2124                         break;
2125
2126                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
2127
2128                         /* Restore normal power mode*/
2129                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2130                                           MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2131                                           params->port);
2132
2133                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2134                                           MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2135                                           params->port);
2136
2137                         bnx2x_cl45_write(bp, params->port,
2138                                        ext_phy_type,
2139                                        ext_phy_addr,
2140                                        MDIO_PMA_DEVAD,
2141                                        MDIO_PMA_REG_CTRL,
2142                                        1<<15);
2143                         break;
2144
2145                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2146                         DP(NETIF_MSG_LINK, "XGXS 8072\n");
2147
2148                         /* Unset Low Power Mode and SW reset */
2149                         /* Restore normal power mode*/
2150                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2151                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2152                                           params->port);
2153
2154                         bnx2x_cl45_write(bp, params->port,
2155                                        ext_phy_type,
2156                                        ext_phy_addr,
2157                                        MDIO_PMA_DEVAD,
2158                                        MDIO_PMA_REG_CTRL,
2159                                        1<<15);
2160                         break;
2161
2162                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2163                         DP(NETIF_MSG_LINK, "XGXS 8073\n");
2164
2165                         /* Restore normal power mode*/
2166                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2167                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2168                                           params->port);
2169
2170                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2171                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2172                                           params->port);
2173                         break;
2174
2175                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2176                         DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
2177
2178                         /* Restore normal power mode*/
2179                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2180                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2181                                           params->port);
2182
2183                         /* HW reset */
2184                         bnx2x_ext_phy_hw_reset(bp, params->port);
2185                         break;
2186
2187                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
2188                         /* Restore normal power mode*/
2189                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2190                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2191                                           params->port);
2192
2193                         /* HW reset */
2194                         bnx2x_ext_phy_hw_reset(bp, params->port);
2195
2196                         bnx2x_cl45_write(bp, params->port,
2197                                        ext_phy_type,
2198                                        ext_phy_addr,
2199                                        MDIO_PMA_DEVAD,
2200                                        MDIO_PMA_REG_CTRL,
2201                                        1<<15);
2202                         break;
2203                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
2204                         break;
2205                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2206                         DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
2207                         break;
2208
2209                 default:
2210                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2211                            params->ext_phy_config);
2212                         break;
2213                 }
2214
2215         } else { /* SerDes */
2216                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2217                 switch (ext_phy_type) {
2218                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2219                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
2220                         break;
2221
2222                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2223                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
2224                         bnx2x_ext_phy_hw_reset(bp, params->port);
2225                         break;
2226
2227                 default:
2228                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2229                                  params->ext_phy_config);
2230                         break;
2231                 }
2232         }
2233 }
2234
2235 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2236                                     u32 shmem_base, u32 spirom_ver)
2237 {
2238         DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
2239                  (u16)(spirom_ver>>16), (u16)spirom_ver, port);
2240         REG_WR(bp, shmem_base +
2241                    offsetof(struct shmem_region,
2242                             port_mb[port].ext_phy_fw_version),
2243                         spirom_ver);
2244 }
2245
2246 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
2247                                     u32 ext_phy_type, u8 ext_phy_addr,
2248                                     u32 shmem_base)
2249 {
2250         u16 fw_ver1, fw_ver2;
2251
2252         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2253                       MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2254         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2255                       MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2256         bnx2x_save_spirom_version(bp, port, shmem_base,
2257                                 (u32)(fw_ver1<<16 | fw_ver2));
2258 }
2259
2260
2261 static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port,
2262                                          u8 ext_phy_addr, u32 shmem_base)
2263 {
2264         u16 val, fw_ver1, fw_ver2, cnt;
2265         /* For the 32 bits registers in 8481, access via MDIO2ARM interface.*/
2266         /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
2267         bnx2x_cl45_write(bp, port,
2268                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2269                        ext_phy_addr, MDIO_PMA_DEVAD,
2270                        0xA819, 0x0014);
2271         bnx2x_cl45_write(bp, port,
2272                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2273                        ext_phy_addr,
2274                        MDIO_PMA_DEVAD,
2275                        0xA81A,
2276                        0xc200);
2277         bnx2x_cl45_write(bp, port,
2278                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2279                        ext_phy_addr,
2280                        MDIO_PMA_DEVAD,
2281                        0xA81B,
2282                        0x0000);
2283         bnx2x_cl45_write(bp, port,
2284                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2285                        ext_phy_addr,
2286                        MDIO_PMA_DEVAD,
2287                        0xA81C,
2288                        0x0300);
2289         bnx2x_cl45_write(bp, port,
2290                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2291                        ext_phy_addr,
2292                        MDIO_PMA_DEVAD,
2293                        0xA817,
2294                        0x0009);
2295
2296         for (cnt = 0; cnt < 100; cnt++) {
2297                 bnx2x_cl45_read(bp, port,
2298                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2299                               ext_phy_addr,
2300                               MDIO_PMA_DEVAD,
2301                               0xA818,
2302                               &val);
2303                 if (val & 1)
2304                         break;
2305                 udelay(5);
2306         }
2307         if (cnt == 100) {
2308                 DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n");
2309                 bnx2x_save_spirom_version(bp, port,
2310                                         shmem_base, 0);
2311                 return;
2312         }
2313
2314
2315         /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
2316         bnx2x_cl45_write(bp, port,
2317                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2318                        ext_phy_addr, MDIO_PMA_DEVAD,
2319                        0xA819, 0x0000);
2320         bnx2x_cl45_write(bp, port,
2321                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2322                        ext_phy_addr, MDIO_PMA_DEVAD,
2323                        0xA81A, 0xc200);
2324         bnx2x_cl45_write(bp, port,
2325                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2326                        ext_phy_addr, MDIO_PMA_DEVAD,
2327                        0xA817, 0x000A);
2328         for (cnt = 0; cnt < 100; cnt++) {
2329                 bnx2x_cl45_read(bp, port,
2330                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2331                               ext_phy_addr,
2332                               MDIO_PMA_DEVAD,
2333                               0xA818,
2334                               &val);
2335                 if (val & 1)
2336                         break;
2337                 udelay(5);
2338         }
2339         if (cnt == 100) {
2340                 DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(2)\n");
2341                 bnx2x_save_spirom_version(bp, port,
2342                                         shmem_base, 0);
2343                 return;
2344         }
2345
2346         /* lower 16 bits of the register SPI_FW_STATUS */
2347         bnx2x_cl45_read(bp, port,
2348                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2349                       ext_phy_addr,
2350                       MDIO_PMA_DEVAD,
2351                       0xA81B,
2352                       &fw_ver1);
2353         /* upper 16 bits of register SPI_FW_STATUS */
2354         bnx2x_cl45_read(bp, port,
2355                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2356                       ext_phy_addr,
2357                       MDIO_PMA_DEVAD,
2358                       0xA81C,
2359                       &fw_ver2);
2360
2361         bnx2x_save_spirom_version(bp, port,
2362                                 shmem_base, (fw_ver2<<16) | fw_ver1);
2363 }
2364
2365 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2366 {
2367         struct bnx2x *bp = params->bp;
2368         u8 port = params->port;
2369         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2370         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2371
2372         /* Need to wait 200ms after reset */
2373         msleep(200);
2374         /* Boot port from external ROM
2375          * Set ser_boot_ctl bit in the MISC_CTRL1 register
2376          */
2377         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2378                             MDIO_PMA_DEVAD,
2379                             MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2380
2381         /* Reset internal microprocessor */
2382         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2383                           MDIO_PMA_DEVAD,
2384                           MDIO_PMA_REG_GEN_CTRL,
2385                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2386         /* set micro reset = 0 */
2387         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2388                             MDIO_PMA_DEVAD,
2389                             MDIO_PMA_REG_GEN_CTRL,
2390                             MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2391         /* Reset internal microprocessor */
2392         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2393                           MDIO_PMA_DEVAD,
2394                           MDIO_PMA_REG_GEN_CTRL,
2395                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2396         /* wait for 100ms for code download via SPI port */
2397         msleep(100);
2398
2399         /* Clear ser_boot_ctl bit */
2400         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2401                             MDIO_PMA_DEVAD,
2402                             MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2403         /* Wait 100ms */
2404         msleep(100);
2405
2406         bnx2x_save_bcm_spirom_ver(bp, port,
2407                                 ext_phy_type,
2408                                 ext_phy_addr,
2409                                 params->shmem_base);
2410 }
2411
2412 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2413 {
2414         /* This is only required for 8073A1, version 102 only */
2415
2416         struct bnx2x *bp = params->bp;
2417         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2418         u16 val;
2419
2420         /* Read 8073 HW revision*/
2421         bnx2x_cl45_read(bp, params->port,
2422                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2423                       ext_phy_addr,
2424                       MDIO_PMA_DEVAD,
2425                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2426
2427         if (val != 1) {
2428                 /* No need to workaround in 8073 A1 */
2429                 return 0;
2430         }
2431
2432         bnx2x_cl45_read(bp, params->port,
2433                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2434                       ext_phy_addr,
2435                       MDIO_PMA_DEVAD,
2436                       MDIO_PMA_REG_ROM_VER2, &val);
2437
2438         /* SNR should be applied only for version 0x102 */
2439         if (val != 0x102)
2440                 return 0;
2441
2442         return 1;
2443 }
2444
2445 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2446 {
2447         struct bnx2x *bp = params->bp;
2448         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2449         u16 val, cnt, cnt1 ;
2450
2451         bnx2x_cl45_read(bp, params->port,
2452                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2453                       ext_phy_addr,
2454                       MDIO_PMA_DEVAD,
2455                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2456
2457         if (val > 0) {
2458                 /* No need to workaround in 8073 A1 */
2459                 return 0;
2460         }
2461         /* XAUI workaround in 8073 A0: */
2462
2463         /* After loading the boot ROM and restarting Autoneg,
2464         poll Dev1, Reg $C820: */
2465
2466         for (cnt = 0; cnt < 1000; cnt++) {
2467                 bnx2x_cl45_read(bp, params->port,
2468                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2469                               ext_phy_addr,
2470                               MDIO_PMA_DEVAD,
2471                               MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
2472                               &val);
2473                   /* If bit [14] = 0 or bit [13] = 0, continue on with
2474                    system initialization (XAUI work-around not required,
2475                     as these bits indicate 2.5G or 1G link up). */
2476                 if (!(val & (1<<14)) || !(val & (1<<13))) {
2477                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2478                         return 0;
2479                 } else if (!(val & (1<<15))) {
2480                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2481                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2482                           it's MSB (bit 15) goes to 1 (indicating that the
2483                           XAUI workaround has completed),
2484                           then continue on with system initialization.*/
2485                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2486                                 bnx2x_cl45_read(bp, params->port,
2487                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2488                                         ext_phy_addr,
2489                                         MDIO_PMA_DEVAD,
2490                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
2491                                 if (val & (1<<15)) {
2492                                         DP(NETIF_MSG_LINK,
2493                                           "XAUI workaround has completed\n");
2494                                         return 0;
2495                                  }
2496                                  msleep(3);
2497                         }
2498                         break;
2499                 }
2500                 msleep(3);
2501         }
2502         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2503         return -EINVAL;
2504 }
2505
2506 static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
2507                                                   u8 ext_phy_addr,
2508                                                   u32 ext_phy_type,
2509                                                   u32 shmem_base)
2510 {
2511         /* Boot port from external ROM  */
2512         /* EDC grst */
2513         bnx2x_cl45_write(bp, port,
2514                        ext_phy_type,
2515                        ext_phy_addr,
2516                        MDIO_PMA_DEVAD,
2517                        MDIO_PMA_REG_GEN_CTRL,
2518                        0x0001);
2519
2520         /* ucode reboot and rst */
2521         bnx2x_cl45_write(bp, port,
2522                        ext_phy_type,
2523                        ext_phy_addr,
2524                        MDIO_PMA_DEVAD,
2525                        MDIO_PMA_REG_GEN_CTRL,
2526                        0x008c);
2527
2528         bnx2x_cl45_write(bp, port,
2529                        ext_phy_type,
2530                        ext_phy_addr,
2531                        MDIO_PMA_DEVAD,
2532                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2533
2534         /* Reset internal microprocessor */
2535         bnx2x_cl45_write(bp, port,
2536                        ext_phy_type,
2537                        ext_phy_addr,
2538                        MDIO_PMA_DEVAD,
2539                        MDIO_PMA_REG_GEN_CTRL,
2540                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2541
2542         /* Release srst bit */
2543         bnx2x_cl45_write(bp, port,
2544                        ext_phy_type,
2545                        ext_phy_addr,
2546                        MDIO_PMA_DEVAD,
2547                        MDIO_PMA_REG_GEN_CTRL,
2548                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2549
2550         /* wait for 100ms for code download via SPI port */
2551         msleep(100);
2552
2553         /* Clear ser_boot_ctl bit */
2554         bnx2x_cl45_write(bp, port,
2555                        ext_phy_type,
2556                        ext_phy_addr,
2557                        MDIO_PMA_DEVAD,
2558                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2559
2560         bnx2x_save_bcm_spirom_ver(bp, port,
2561                                 ext_phy_type,
2562                                 ext_phy_addr,
2563                                 shmem_base);
2564 }
2565
2566 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2567                                           u8 ext_phy_addr,
2568                                           u32 shmem_base)
2569 {
2570         bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
2571                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2572                                          shmem_base);
2573 }
2574
2575 static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
2576                                           u8 ext_phy_addr,
2577                                           u32 shmem_base)
2578 {
2579         bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
2580                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2581                                          shmem_base);
2582
2583 }
2584
2585 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2586 {
2587         struct bnx2x *bp = params->bp;
2588         u8 port = params->port;
2589         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2590         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2591
2592         /* Need to wait 100ms after reset */
2593         msleep(100);
2594
2595         /* Micro controller re-boot */
2596         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2597                        MDIO_PMA_DEVAD,
2598                        MDIO_PMA_REG_GEN_CTRL,
2599                        0x018B);
2600
2601         /* Set soft reset */
2602         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2603                        MDIO_PMA_DEVAD,
2604                        MDIO_PMA_REG_GEN_CTRL,
2605                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2606
2607         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2608                        MDIO_PMA_DEVAD,
2609                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2610
2611         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2612                        MDIO_PMA_DEVAD,
2613                        MDIO_PMA_REG_GEN_CTRL,
2614                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2615
2616         /* wait for 150ms for microcode load */
2617         msleep(150);
2618
2619         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2620         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2621                        MDIO_PMA_DEVAD,
2622                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2623
2624         msleep(200);
2625         bnx2x_save_bcm_spirom_ver(bp, port,
2626                                 ext_phy_type,
2627                                 ext_phy_addr,
2628                                 params->shmem_base);
2629 }
2630
2631 static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port,
2632                                     u32 ext_phy_type, u8 ext_phy_addr,
2633                                     u8 tx_en)
2634 {
2635         u16 val;
2636
2637         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2638                  tx_en, port);
2639         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2640         bnx2x_cl45_read(bp, port,
2641                       ext_phy_type,
2642                       ext_phy_addr,
2643                       MDIO_PMA_DEVAD,
2644                       MDIO_PMA_REG_PHY_IDENTIFIER,
2645                       &val);
2646
2647         if (tx_en)
2648                 val &= ~(1<<15);
2649         else
2650                 val |= (1<<15);
2651
2652         bnx2x_cl45_write(bp, port,
2653                        ext_phy_type,
2654                        ext_phy_addr,
2655                        MDIO_PMA_DEVAD,
2656                        MDIO_PMA_REG_PHY_IDENTIFIER,
2657                        val);
2658 }
2659
2660 static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
2661                                           u16 addr, u8 byte_cnt, u8 *o_buf)
2662 {
2663         struct bnx2x *bp = params->bp;
2664         u16 val = 0;
2665         u16 i;
2666         u8 port = params->port;
2667         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2668         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2669
2670         if (byte_cnt > 16) {
2671                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2672                             " is limited to 0xf\n");
2673                 return -EINVAL;
2674         }
2675         /* Set the read command byte count */
2676         bnx2x_cl45_write(bp, port,
2677                        ext_phy_type,
2678                        ext_phy_addr,
2679                        MDIO_PMA_DEVAD,
2680                        MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2681                        (byte_cnt | 0xa000));
2682
2683         /* Set the read command address */
2684         bnx2x_cl45_write(bp, port,
2685                        ext_phy_type,
2686                        ext_phy_addr,
2687                        MDIO_PMA_DEVAD,
2688                        MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2689                        addr);
2690
2691         /* Activate read command */
2692         bnx2x_cl45_write(bp, port,
2693                        ext_phy_type,
2694                        ext_phy_addr,
2695                        MDIO_PMA_DEVAD,
2696                        MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2697                        0x2c0f);
2698
2699         /* Wait up to 500us for command complete status */
2700         for (i = 0; i < 100; i++) {
2701                 bnx2x_cl45_read(bp, port,
2702                               ext_phy_type,
2703                               ext_phy_addr,
2704                               MDIO_PMA_DEVAD,
2705                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2706                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2707                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2708                         break;
2709                 udelay(5);
2710         }
2711
2712         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2713                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2714                 DP(NETIF_MSG_LINK,
2715                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2716                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2717                 return -EINVAL;
2718         }
2719
2720         /* Read the buffer */
2721         for (i = 0; i < byte_cnt; i++) {
2722                 bnx2x_cl45_read(bp, port,
2723                               ext_phy_type,
2724                               ext_phy_addr,
2725                               MDIO_PMA_DEVAD,
2726                               MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2727                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2728         }
2729
2730         for (i = 0; i < 100; i++) {
2731                 bnx2x_cl45_read(bp, port,
2732                               ext_phy_type,
2733                               ext_phy_addr,
2734                               MDIO_PMA_DEVAD,
2735                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2736                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2737                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2738                         return 0;;
2739                 msleep(1);
2740         }
2741         return -EINVAL;
2742 }
2743
2744 static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
2745                                           u16 addr, u8 byte_cnt, u8 *o_buf)
2746 {
2747         struct bnx2x *bp = params->bp;
2748         u16 val, i;
2749         u8 port = params->port;
2750         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2751         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2752
2753         if (byte_cnt > 16) {
2754                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2755                             " is limited to 0xf\n");
2756                 return -EINVAL;
2757         }
2758
2759         /* Need to read from 1.8000 to clear it */
2760         bnx2x_cl45_read(bp, port,
2761                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2762                       ext_phy_addr,
2763                       MDIO_PMA_DEVAD,
2764                       MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2765                       &val);
2766
2767         /* Set the read command byte count */
2768         bnx2x_cl45_write(bp, port,
2769                        ext_phy_type,
2770                        ext_phy_addr,
2771                        MDIO_PMA_DEVAD,
2772                        MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2773                        ((byte_cnt < 2) ? 2 : byte_cnt));
2774
2775         /* Set the read command address */
2776         bnx2x_cl45_write(bp, port,
2777                        ext_phy_type,
2778                        ext_phy_addr,
2779                        MDIO_PMA_DEVAD,
2780                        MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2781                        addr);
2782         /* Set the destination address */
2783         bnx2x_cl45_write(bp, port,
2784                        ext_phy_type,
2785                        ext_phy_addr,
2786                        MDIO_PMA_DEVAD,
2787                        0x8004,
2788                        MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
2789
2790         /* Activate read command */
2791         bnx2x_cl45_write(bp, port,
2792                        ext_phy_type,
2793                        ext_phy_addr,
2794                        MDIO_PMA_DEVAD,
2795                        MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2796                        0x8002);
2797         /* Wait appropriate time for two-wire command to finish before
2798         polling the status register */
2799         msleep(1);
2800
2801         /* Wait up to 500us for command complete status */
2802         for (i = 0; i < 100; i++) {
2803                 bnx2x_cl45_read(bp, port,
2804                               ext_phy_type,
2805                               ext_phy_addr,
2806                               MDIO_PMA_DEVAD,
2807                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2808                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2809                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2810                         break;
2811                 udelay(5);
2812         }
2813
2814         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2815                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2816                 DP(NETIF_MSG_LINK,
2817                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2818                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2819                 return -EINVAL;
2820         }
2821
2822         /* Read the buffer */
2823         for (i = 0; i < byte_cnt; i++) {
2824                 bnx2x_cl45_read(bp, port,
2825                               ext_phy_type,
2826                               ext_phy_addr,
2827                               MDIO_PMA_DEVAD,
2828                               MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
2829                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
2830         }
2831
2832         for (i = 0; i < 100; i++) {
2833                 bnx2x_cl45_read(bp, port,
2834                               ext_phy_type,
2835                               ext_phy_addr,
2836                               MDIO_PMA_DEVAD,
2837                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2838                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2839                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2840                         return 0;;
2841                 msleep(1);
2842         }
2843
2844         return -EINVAL;
2845 }
2846
2847 u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2848                                      u8 byte_cnt, u8 *o_buf)
2849 {
2850         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2851
2852         if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
2853                 return bnx2x_8726_read_sfp_module_eeprom(params, addr,
2854                                                        byte_cnt, o_buf);
2855         else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
2856                 return bnx2x_8727_read_sfp_module_eeprom(params, addr,
2857                                                        byte_cnt, o_buf);
2858         return -EINVAL;
2859 }
2860
2861 static u8 bnx2x_get_edc_mode(struct link_params *params,
2862                                   u16 *edc_mode)
2863 {
2864         struct bnx2x *bp = params->bp;
2865         u8 val, check_limiting_mode = 0;
2866         *edc_mode = EDC_MODE_LIMITING;
2867
2868         /* First check for copper cable */
2869         if (bnx2x_read_sfp_module_eeprom(params,
2870                                        SFP_EEPROM_CON_TYPE_ADDR,
2871                                        1,
2872                                        &val) != 0) {
2873                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
2874                 return -EINVAL;
2875         }
2876
2877         switch (val) {
2878         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2879         {
2880                 u8 copper_module_type;
2881
2882                 /* Check if its active cable( includes SFP+ module)
2883                 of passive cable*/
2884                 if (bnx2x_read_sfp_module_eeprom(params,
2885                                                SFP_EEPROM_FC_TX_TECH_ADDR,
2886                                                1,
2887                                                &copper_module_type) !=
2888                     0) {
2889                         DP(NETIF_MSG_LINK,
2890                                 "Failed to read copper-cable-type"
2891                                 " from SFP+ EEPROM\n");
2892                         return -EINVAL;
2893                 }
2894
2895                 if (copper_module_type &
2896                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2897                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2898                         check_limiting_mode = 1;
2899                 } else if (copper_module_type &
2900                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2901                                 DP(NETIF_MSG_LINK, "Passive Copper"
2902                                             " cable detected\n");
2903                                 *edc_mode =
2904                                       EDC_MODE_PASSIVE_DAC;
2905                 } else {
2906                         DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2907                                      "type 0x%x !!!\n", copper_module_type);
2908                         return -EINVAL;
2909                 }
2910                 break;
2911         }
2912         case SFP_EEPROM_CON_TYPE_VAL_LC:
2913                 DP(NETIF_MSG_LINK, "Optic module detected\n");
2914                 check_limiting_mode = 1;
2915                 break;
2916         default:
2917                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2918                          val);
2919                 return -EINVAL;
2920         }
2921
2922         if (check_limiting_mode) {
2923                 u8 options[SFP_EEPROM_OPTIONS_SIZE];
2924                 if (bnx2x_read_sfp_module_eeprom(params,
2925                                                SFP_EEPROM_OPTIONS_ADDR,
2926                                                SFP_EEPROM_OPTIONS_SIZE,
2927                                                options) != 0) {
2928                         DP(NETIF_MSG_LINK, "Failed to read Option"
2929                                 " field from module EEPROM\n");
2930                         return -EINVAL;
2931                 }
2932                 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
2933                         *edc_mode = EDC_MODE_LINEAR;
2934                 else
2935                         *edc_mode = EDC_MODE_LIMITING;
2936         }
2937         DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
2938         return 0;
2939 }
2940
2941 /* This function read the relevant field from the module ( SFP+ ),
2942         and verify it is compliant with this board */
2943 static u8 bnx2x_verify_sfp_module(struct link_params *params)
2944 {
2945         struct bnx2x *bp = params->bp;
2946         u32 val;
2947         u32 fw_resp;
2948         char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
2949         char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
2950
2951         val = REG_RD(bp, params->shmem_base +
2952                          offsetof(struct shmem_region, dev_info.
2953                                   port_feature_config[params->port].config));
2954         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2955             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
2956                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2957                 return 0;
2958         }
2959
2960         /* Ask the FW to validate the module */
2961         if (!(params->feature_config_flags &
2962               FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) {
2963                 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
2964                             "verification\n");
2965                 return -EINVAL;
2966         }
2967
2968         fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL);
2969         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
2970                 DP(NETIF_MSG_LINK, "Approved module\n");
2971                 return 0;
2972         }
2973
2974         /* format the warning message */
2975         if (bnx2x_read_sfp_module_eeprom(params,
2976                                        SFP_EEPROM_VENDOR_NAME_ADDR,
2977                                        SFP_EEPROM_VENDOR_NAME_SIZE,
2978                                        (u8 *)vendor_name))
2979                 vendor_name[0] = '\0';
2980         else
2981                 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
2982         if (bnx2x_read_sfp_module_eeprom(params,
2983                                        SFP_EEPROM_PART_NO_ADDR,
2984                                        SFP_EEPROM_PART_NO_SIZE,
2985                                        (u8 *)vendor_pn))
2986                 vendor_pn[0] = '\0';
2987         else
2988                 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
2989
2990         printk(KERN_INFO PFX  "Warning: "
2991                          "Unqualified SFP+ module "
2992                          "detected on %s, Port %d from %s part number %s\n"
2993                         , bp->dev->name, params->port,
2994                         vendor_name, vendor_pn);
2995         return -EINVAL;
2996 }
2997
2998 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2999                                         u16 edc_mode)
3000 {
3001         struct bnx2x *bp = params->bp;
3002         u8 port = params->port;
3003         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3004         u16 cur_limiting_mode;
3005
3006         bnx2x_cl45_read(bp, port,
3007                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3008                       ext_phy_addr,
3009                       MDIO_PMA_DEVAD,
3010                       MDIO_PMA_REG_ROM_VER2,
3011                       &cur_limiting_mode);
3012         DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
3013                  cur_limiting_mode);
3014
3015         if (edc_mode == EDC_MODE_LIMITING) {
3016                 DP(NETIF_MSG_LINK,
3017                          "Setting LIMITING MODE\n");
3018                 bnx2x_cl45_write(bp, port,
3019                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3020                                ext_phy_addr,
3021                                MDIO_PMA_DEVAD,
3022                                MDIO_PMA_REG_ROM_VER2,
3023                                EDC_MODE_LIMITING);
3024         } else { /* LRM mode ( default )*/
3025
3026                 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
3027
3028                 /* Changing to LRM mode takes quite few seconds.
3029                 So do it only if current mode is limiting
3030                 ( default is LRM )*/
3031                 if (cur_limiting_mode != EDC_MODE_LIMITING)
3032                         return 0;
3033
3034                 bnx2x_cl45_write(bp, port,
3035                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3036                                ext_phy_addr,
3037                                MDIO_PMA_DEVAD,
3038                                MDIO_PMA_REG_LRM_MODE,
3039                                0);
3040                 bnx2x_cl45_write(bp, port,
3041                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3042                                ext_phy_addr,
3043                                MDIO_PMA_DEVAD,
3044                                MDIO_PMA_REG_ROM_VER2,
3045                                0x128);
3046                 bnx2x_cl45_write(bp, port,
3047                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3048                                ext_phy_addr,
3049                                MDIO_PMA_DEVAD,
3050                                MDIO_PMA_REG_MISC_CTRL0,
3051                                0x4008);
3052                 bnx2x_cl45_write(bp, port,
3053                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3054                                ext_phy_addr,
3055                                MDIO_PMA_DEVAD,
3056                                MDIO_PMA_REG_LRM_MODE,
3057                                0xaaaa);
3058         }
3059         return 0;
3060 }
3061
3062 static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
3063                                         u16 edc_mode)
3064 {
3065         struct bnx2x *bp = params->bp;
3066         u8 port = params->port;
3067         u16 phy_identifier;
3068         u16 rom_ver2_val;
3069         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3070
3071         bnx2x_cl45_read(bp, port,
3072                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3073                        ext_phy_addr,
3074                        MDIO_PMA_DEVAD,
3075                        MDIO_PMA_REG_PHY_IDENTIFIER,
3076                        &phy_identifier);
3077
3078         bnx2x_cl45_write(bp, port,
3079                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3080                        ext_phy_addr,
3081                        MDIO_PMA_DEVAD,
3082                        MDIO_PMA_REG_PHY_IDENTIFIER,
3083                        (phy_identifier & ~(1<<9)));
3084
3085         bnx2x_cl45_read(bp, port,
3086                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3087                       ext_phy_addr,
3088                       MDIO_PMA_DEVAD,
3089                       MDIO_PMA_REG_ROM_VER2,
3090                       &rom_ver2_val);
3091         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
3092         bnx2x_cl45_write(bp, port,
3093                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3094                        ext_phy_addr,
3095                        MDIO_PMA_DEVAD,
3096                        MDIO_PMA_REG_ROM_VER2,
3097                        (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
3098
3099         bnx2x_cl45_write(bp, port,
3100                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3101                        ext_phy_addr,
3102                        MDIO_PMA_DEVAD,
3103                        MDIO_PMA_REG_PHY_IDENTIFIER,
3104                        (phy_identifier | (1<<9)));
3105
3106         return 0;
3107 }
3108
3109
3110 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
3111 {
3112         u8 val;
3113         struct bnx2x *bp = params->bp;
3114         u16 timeout;
3115         /* Initialization time after hot-plug may take up to 300ms for some
3116         phys type ( e.g. JDSU ) */
3117         for (timeout = 0; timeout < 60; timeout++) {
3118                 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
3119                     == 0) {
3120                         DP(NETIF_MSG_LINK, "SFP+ module initialization "
3121                                      "took %d ms\n", timeout * 5);
3122                         return 0;
3123                 }
3124                 msleep(5);
3125         }
3126         return -EINVAL;
3127 }
3128
3129 static void bnx2x_8727_power_module(struct bnx2x *bp,
3130                                   struct link_params *params,
3131                                   u8 ext_phy_addr, u8 is_power_up) {
3132         /* Make sure GPIOs are not using for LED mode */
3133         u16 val;
3134         u8 port = params->port;
3135         /*
3136          * In the GPIO register, bit 4 is use to detemine if the GPIOs are
3137          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
3138          * output
3139          * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
3140          * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
3141          * where the 1st bit is the over-current(only input), and 2nd bit is
3142          * for power( only output )
3143         */
3144
3145         /*
3146          * In case of NOC feature is disabled and power is up, set GPIO control
3147          *  as input to enable listening of over-current indication
3148          */
3149
3150         if (!(params->feature_config_flags &
3151               FEATURE_CONFIG_BCM8727_NOC) && is_power_up)
3152                 val = (1<<4);
3153         else
3154                 /*
3155                  * Set GPIO control to OUTPUT, and set the power bit
3156                  * to according to the is_power_up
3157                  */
3158                 val = ((!(is_power_up)) << 1);
3159
3160         bnx2x_cl45_write(bp, port,
3161                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3162                        ext_phy_addr,
3163                        MDIO_PMA_DEVAD,
3164                        MDIO_PMA_REG_8727_GPIO_CTRL,
3165                        val);
3166 }
3167
3168 static u8 bnx2x_sfp_module_detection(struct link_params *params)
3169 {
3170         struct bnx2x *bp = params->bp;
3171         u16 edc_mode;
3172         u8 rc = 0;
3173         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3174         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3175         u32 val = REG_RD(bp, params->shmem_base +
3176                              offsetof(struct shmem_region, dev_info.
3177                                      port_feature_config[params->port].config));
3178
3179         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
3180                  params->port);
3181
3182         if (bnx2x_get_edc_mode(params, &edc_mode) != 0) {
3183                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
3184                 return -EINVAL;
3185         } else if (bnx2x_verify_sfp_module(params) !=
3186                    0) {
3187                 /* check SFP+ module compatibility */
3188                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
3189                 rc = -EINVAL;
3190                 /* Turn on fault module-detected led */
3191                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
3192                                   MISC_REGISTERS_GPIO_HIGH,
3193                                   params->port);
3194                 if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
3195                     ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
3196                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
3197                         /* Shutdown SFP+ module */
3198                         DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
3199                         bnx2x_8727_power_module(bp, params,
3200                                               ext_phy_addr, 0);
3201                         return rc;
3202                 }
3203         } else {
3204                 /* Turn off fault module-detected led */
3205                 DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
3206                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
3207                                           MISC_REGISTERS_GPIO_LOW,
3208                                           params->port);
3209         }
3210
3211         /* power up the SFP module */
3212         if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
3213                 bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
3214
3215         /* Check and set limiting mode / LRM mode on 8726.
3216         On 8727 it is done automatically */
3217         if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
3218                 bnx2x_bcm8726_set_limiting_mode(params, edc_mode);
3219         else
3220                 bnx2x_bcm8727_set_limiting_mode(params, edc_mode);
3221         /*
3222          * Enable transmit for this module if the module is approved, or
3223          * if unapproved modules should also enable the Tx laser
3224          */
3225         if (rc == 0 ||
3226             (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
3227             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
3228                 bnx2x_sfp_set_transmitter(bp, params->port,
3229                                         ext_phy_type, ext_phy_addr, 1);
3230         else
3231                 bnx2x_sfp_set_transmitter(bp, params->port,
3232                                         ext_phy_type, ext_phy_addr, 0);
3233
3234         return rc;
3235 }
3236
3237 void bnx2x_handle_module_detect_int(struct link_params *params)
3238 {
3239         struct bnx2x *bp = params->bp;
3240         u32 gpio_val;
3241         u8 port = params->port;
3242
3243         /* Set valid module led off */
3244         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
3245                           MISC_REGISTERS_GPIO_HIGH,
3246                           params->port);
3247
3248         /* Get current gpio val refelecting module plugged in / out*/
3249         gpio_val = bnx2x_get_gpio(bp,  MISC_REGISTERS_GPIO_3, port);
3250
3251         /* Call the handling function in case module is detected */
3252         if (gpio_val == 0) {
3253
3254                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
3255                                       MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
3256                                       port);
3257
3258                 if (bnx2x_wait_for_sfp_module_initialized(params) ==
3259                     0)
3260                         bnx2x_sfp_module_detection(params);
3261                 else
3262                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
3263         } else {
3264                 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3265
3266                 u32 ext_phy_type =
3267                         XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3268                 u32 val = REG_RD(bp, params->shmem_base +
3269                                      offsetof(struct shmem_region, dev_info.
3270                                               port_feature_config[params->port].
3271                                               config));
3272
3273                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
3274                                       MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
3275                                       port);
3276                 /* Module was plugged out. */
3277                 /* Disable transmit for this module */
3278                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
3279                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
3280                         bnx2x_sfp_set_transmitter(bp, params->port,
3281                                                 ext_phy_type, ext_phy_addr, 0);
3282         }
3283 }
3284
3285 static void bnx2x_bcm807x_force_10G(struct link_params *params)
3286 {
3287         struct bnx2x *bp = params->bp;
3288         u8 port = params->port;
3289         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3290         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3291
3292         /* Force KR or KX */
3293         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3294                        MDIO_PMA_DEVAD,
3295                        MDIO_PMA_REG_CTRL,
3296                        0x2040);
3297         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3298                        MDIO_PMA_DEVAD,
3299                        MDIO_PMA_REG_10G_CTRL2,
3300                        0x000b);
3301         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3302                        MDIO_PMA_DEVAD,
3303                        MDIO_PMA_REG_BCM_CTRL,
3304                        0x0000);
3305         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3306                        MDIO_AN_DEVAD,
3307                        MDIO_AN_REG_CTRL,
3308                        0x0000);
3309 }
3310
3311 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
3312 {
3313         struct bnx2x *bp = params->bp;
3314         u8 port = params->port;
3315         u16 val;
3316         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3317         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3318
3319         bnx2x_cl45_read(bp, params->port,
3320                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3321                       ext_phy_addr,
3322                       MDIO_PMA_DEVAD,
3323                       MDIO_PMA_REG_8073_CHIP_REV, &val);
3324
3325         if (val == 0) {
3326                 /* Mustn't set low power mode in 8073 A0 */
3327                 return;
3328         }
3329
3330         /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
3331         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3332                        MDIO_XS_DEVAD,
3333                        MDIO_XS_PLL_SEQUENCER, &val);
3334         val &= ~(1<<13);
3335         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3336                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3337
3338         /* PLL controls */
3339         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3340                        MDIO_XS_DEVAD, 0x805E, 0x1077);
3341         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3342                        MDIO_XS_DEVAD, 0x805D, 0x0000);
3343         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3344                        MDIO_XS_DEVAD, 0x805C, 0x030B);
3345         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3346                        MDIO_XS_DEVAD, 0x805B, 0x1240);
3347         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3348                        MDIO_XS_DEVAD, 0x805A, 0x2490);
3349
3350         /* Tx Controls */
3351         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3352                        MDIO_XS_DEVAD, 0x80A7, 0x0C74);
3353         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3354                        MDIO_XS_DEVAD, 0x80A6, 0x9041);
3355         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3356                        MDIO_XS_DEVAD, 0x80A5, 0x4640);
3357
3358         /* Rx Controls */
3359         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3360                        MDIO_XS_DEVAD, 0x80FE, 0x01C4);
3361         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3362                        MDIO_XS_DEVAD, 0x80FD, 0x9249);
3363         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3364                        MDIO_XS_DEVAD, 0x80FC, 0x2015);
3365
3366         /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
3367         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3368                        MDIO_XS_DEVAD,
3369                        MDIO_XS_PLL_SEQUENCER, &val);
3370         val |= (1<<13);
3371         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3372                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3373 }
3374
3375 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
3376                                   struct link_vars *vars)
3377 {
3378         struct bnx2x *bp = params->bp;
3379         u16 cl37_val;
3380         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3381         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3382
3383         bnx2x_cl45_read(bp, params->port,
3384                       ext_phy_type,
3385                       ext_phy_addr,
3386                       MDIO_AN_DEVAD,
3387                       MDIO_AN_REG_CL37_FC_LD, &cl37_val);
3388
3389         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3390         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3391
3392         if ((vars->ieee_fc &
3393             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
3394             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
3395                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
3396         }
3397         if ((vars->ieee_fc &
3398             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3399             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3400                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3401         }
3402         if ((vars->ieee_fc &
3403             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3404             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3405                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3406         }
3407         DP(NETIF_MSG_LINK,
3408                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
3409
3410         bnx2x_cl45_write(bp, params->port,
3411                        ext_phy_type,
3412                        ext_phy_addr,
3413                        MDIO_AN_DEVAD,
3414                        MDIO_AN_REG_CL37_FC_LD, cl37_val);
3415         msleep(500);
3416 }
3417
3418 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3419                                   struct link_vars *vars)
3420 {
3421         struct bnx2x *bp = params->bp;
3422         u16 val;
3423         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3424         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3425
3426         /* read modify write pause advertizing */
3427         bnx2x_cl45_read(bp, params->port,
3428                       ext_phy_type,
3429                       ext_phy_addr,
3430                       MDIO_AN_DEVAD,
3431                       MDIO_AN_REG_ADV_PAUSE, &val);
3432
3433         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3434
3435         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3436
3437         if ((vars->ieee_fc &
3438             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3439             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3440                 val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3441         }
3442         if ((vars->ieee_fc &
3443             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3444             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3445                 val |=
3446                  MDIO_AN_REG_ADV_PAUSE_PAUSE;
3447         }
3448         DP(NETIF_MSG_LINK,
3449                  "Ext phy AN advertize 0x%x\n", val);
3450         bnx2x_cl45_write(bp, params->port,
3451                        ext_phy_type,
3452                        ext_phy_addr,
3453                        MDIO_AN_DEVAD,
3454                        MDIO_AN_REG_ADV_PAUSE, val);
3455 }
3456 static void bnx2x_set_preemphasis(struct link_params *params)
3457 {
3458         u16 bank, i = 0;
3459         struct bnx2x *bp = params->bp;
3460
3461         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
3462               bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
3463                         CL45_WR_OVER_CL22(bp, params->port,
3464                                               params->phy_addr,
3465                                               bank,
3466                                               MDIO_RX0_RX_EQ_BOOST,
3467                                               params->xgxs_config_rx[i]);
3468         }
3469
3470         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
3471                       bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
3472                         CL45_WR_OVER_CL22(bp, params->port,
3473                                               params->phy_addr,
3474                                               bank,
3475                                               MDIO_TX0_TX_DRIVER,
3476                                               params->xgxs_config_tx[i]);
3477         }
3478 }
3479
3480
3481 static void bnx2x_8481_set_led4(struct link_params *params,
3482                               u32 ext_phy_type, u8 ext_phy_addr)
3483 {
3484         struct bnx2x *bp = params->bp;
3485
3486         /* PHYC_CTL_LED_CTL */
3487         bnx2x_cl45_write(bp, params->port,
3488                        ext_phy_type,
3489                        ext_phy_addr,
3490                        MDIO_PMA_DEVAD,
3491                        MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482);
3492
3493         /* Unmask LED4 for 10G link */
3494         bnx2x_cl45_write(bp, params->port,
3495                        ext_phy_type,
3496                        ext_phy_addr,
3497                        MDIO_PMA_DEVAD,
3498                        MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6));
3499         /* 'Interrupt Mask' */
3500         bnx2x_cl45_write(bp, params->port,
3501                        ext_phy_type,
3502                        ext_phy_addr,
3503                        MDIO_AN_DEVAD,
3504                        0xFFFB, 0xFFFD);
3505 }
3506 static void bnx2x_8481_set_legacy_led_mode(struct link_params *params,
3507                                          u32 ext_phy_type, u8 ext_phy_addr)
3508 {
3509         struct bnx2x *bp = params->bp;
3510
3511         /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */
3512         /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */
3513         bnx2x_cl45_write(bp, params->port,
3514                        ext_phy_type,
3515                        ext_phy_addr,
3516                        MDIO_AN_DEVAD,
3517                        MDIO_AN_REG_8481_LEGACY_SHADOW,
3518                        (1<<15) | (0xd << 10) | (0xc<<4) | 0xe);
3519 }
3520
3521 static void bnx2x_8481_set_10G_led_mode(struct link_params *params,
3522                                       u32 ext_phy_type, u8 ext_phy_addr)
3523 {
3524         struct bnx2x *bp = params->bp;
3525         u16 val1;
3526
3527         /* LED1 (10G Link) */
3528         /* Enable continuse based on source 7(10G-link) */
3529         bnx2x_cl45_read(bp, params->port,
3530                        ext_phy_type,
3531                        ext_phy_addr,
3532                        MDIO_PMA_DEVAD,
3533                        MDIO_PMA_REG_8481_LINK_SIGNAL,
3534                        &val1);
3535         /* Set bit 2 to 0, and bits [1:0] to 10 */
3536         val1 &= ~((1<<0) | (1<<2)); /* Clear bits 0,2*/
3537         val1 |= (1<<1); /* Set bit 1 */
3538
3539         bnx2x_cl45_write(bp, params->port,
3540                        ext_phy_type,
3541                        ext_phy_addr,
3542                        MDIO_PMA_DEVAD,
3543                        MDIO_PMA_REG_8481_LINK_SIGNAL,
3544                        val1);
3545
3546         /* Unmask LED1 for 10G link */
3547         bnx2x_cl45_read(bp, params->port,
3548                       ext_phy_type,
3549                       ext_phy_addr,
3550                       MDIO_PMA_DEVAD,
3551                       MDIO_PMA_REG_8481_LED1_MASK,
3552                       &val1);
3553         /* Set bit 2 to 0, and bits [1:0] to 10 */
3554         val1 |= (1<<7);
3555         bnx2x_cl45_write(bp, params->port,
3556                        ext_phy_type,
3557                        ext_phy_addr,
3558                        MDIO_PMA_DEVAD,
3559                        MDIO_PMA_REG_8481_LED1_MASK,
3560                        val1);
3561
3562         /* LED2 (1G/100/10G Link) */
3563         /* Mask LED2 for 10G link */
3564         bnx2x_cl45_write(bp, params->port,
3565                        ext_phy_type,
3566                        ext_phy_addr,
3567                        MDIO_PMA_DEVAD,
3568                        MDIO_PMA_REG_8481_LED2_MASK,
3569                        0);
3570
3571         /* LED3 (10G/1G/100/10G Activity) */
3572         bnx2x_cl45_read(bp, params->port,
3573                       ext_phy_type,
3574                       ext_phy_addr,
3575                       MDIO_PMA_DEVAD,
3576                       MDIO_PMA_REG_8481_LINK_SIGNAL,
3577                       &val1);
3578         /* Enable blink based on source 4(Activity) */
3579         val1 &= ~((1<<7) | (1<<8)); /* Clear bits 7,8 */
3580         val1 |= (1<<6); /* Set only bit 6 */
3581         bnx2x_cl45_write(bp, params->port,
3582                        ext_phy_type,
3583                        ext_phy_addr,
3584                        MDIO_PMA_DEVAD,
3585                        MDIO_PMA_REG_8481_LINK_SIGNAL,
3586                        val1);
3587
3588         bnx2x_cl45_read(bp, params->port,
3589                       ext_phy_type,
3590                       ext_phy_addr,
3591                       MDIO_PMA_DEVAD,
3592                       MDIO_PMA_REG_8481_LED3_MASK,
3593                       &val1);
3594         val1 |= (1<<4); /* Unmask LED3 for 10G link */
3595         bnx2x_cl45_write(bp, params->port,
3596                        ext_phy_type,
3597                        ext_phy_addr,
3598                        MDIO_PMA_DEVAD,
3599                        MDIO_PMA_REG_8481_LED3_MASK,
3600                        val1);
3601 }
3602
3603
3604 static void bnx2x_init_internal_phy(struct link_params *params,
3605                                   struct link_vars *vars,
3606                                   u8 enable_cl73)
3607 {
3608         struct bnx2x *bp = params->bp;
3609
3610         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
3611                 if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
3612                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3613                     (params->feature_config_flags &
3614                      FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
3615                         bnx2x_set_preemphasis(params);
3616
3617                 /* forced speed requested? */
3618                 if (vars->line_speed != SPEED_AUTO_NEG ||
3619                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
3620                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3621                           params->loopback_mode == LOOPBACK_EXT)) {
3622                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3623
3624                         /* disable autoneg */
3625                         bnx2x_set_autoneg(params, vars, 0);
3626
3627                         /* program speed and duplex */
3628                         bnx2x_program_serdes(params, vars);
3629
3630                 } else { /* AN_mode */
3631                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
3632
3633                         /* AN enabled */
3634                         bnx2x_set_brcm_cl37_advertisment(params);
3635
3636                         /* program duplex & pause advertisement (for aneg) */
3637                         bnx2x_set_ieee_aneg_advertisment(params,
3638                                                        vars->ieee_fc);
3639
3640                         /* enable autoneg */
3641                         bnx2x_set_autoneg(params, vars, enable_cl73);
3642
3643                         /* enable and restart AN */
3644                         bnx2x_restart_autoneg(params, enable_cl73);
3645                 }
3646
3647         } else { /* SGMII mode */
3648                 DP(NETIF_MSG_LINK, "SGMII\n");
3649
3650                 bnx2x_initialize_sgmii_process(params, vars);
3651         }
3652 }
3653
3654 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
3655 {
3656         struct bnx2x *bp = params->bp;
3657         u32 ext_phy_type;
3658         u8 ext_phy_addr;
3659         u16 cnt;
3660         u16 ctrl = 0;
3661         u16 val = 0;
3662         u8 rc = 0;
3663
3664         if (vars->phy_flags & PHY_XGXS_FLAG) {
3665                 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3666
3667                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3668                 /* Make sure that the soft reset is off (expect for the 8072:
3669                  * due to the lock, it will be done inside the specific
3670                  * handling)
3671                  */
3672                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3673                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3674                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
3675                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3676                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3677                         /* Wait for soft reset to get cleared upto 1 sec */
3678                         for (cnt = 0; cnt < 1000; cnt++) {
3679                                 bnx2x_cl45_read(bp, params->port,
3680                                               ext_phy_type,
3681                                               ext_phy_addr,
3682                                               MDIO_PMA_DEVAD,
3683                                               MDIO_PMA_REG_CTRL, &ctrl);
3684                                 if (!(ctrl & (1<<15)))
3685                                         break;
3686                                 msleep(1);
3687                         }
3688                         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3689                                  ctrl, cnt);
3690                 }
3691
3692                 switch (ext_phy_type) {
3693                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3694                         break;
3695
3696                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3697                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
3698
3699                         bnx2x_cl45_write(bp, params->port,
3700                                        ext_phy_type,
3701                                        ext_phy_addr,
3702                                        MDIO_PMA_DEVAD,
3703                                        MDIO_PMA_REG_MISC_CTRL,
3704                                        0x8288);
3705                         bnx2x_cl45_write(bp, params->port,
3706                                        ext_phy_type,
3707                                        ext_phy_addr,
3708                                        MDIO_PMA_DEVAD,
3709                                        MDIO_PMA_REG_PHY_IDENTIFIER,
3710                                        0x7fbf);
3711                         bnx2x_cl45_write(bp, params->port,
3712                                        ext_phy_type,
3713                                        ext_phy_addr,
3714                                        MDIO_PMA_DEVAD,
3715                                        MDIO_PMA_REG_CMU_PLL_BYPASS,
3716                                        0x0100);
3717                         bnx2x_cl45_write(bp, params->port,
3718                                        ext_phy_type,
3719                                        ext_phy_addr,
3720                                        MDIO_WIS_DEVAD,
3721                                        MDIO_WIS_REG_LASI_CNTL, 0x1);
3722
3723                         /* BCM8705 doesn't have microcode, hence the 0 */
3724                         bnx2x_save_spirom_version(bp, params->port,
3725                                                 params->shmem_base, 0);
3726                         break;
3727
3728                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3729                         /* Wait until fw is loaded */
3730                         for (cnt = 0; cnt < 100; cnt++) {
3731                                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3732                                               ext_phy_addr, MDIO_PMA_DEVAD,
3733                                               MDIO_PMA_REG_ROM_VER1, &val);
3734                                 if (val)
3735                                         break;
3736                                 msleep(10);
3737                         }
3738                         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3739                                 "after %d ms\n", cnt);
3740                         if ((params->feature_config_flags &
3741                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3742                                 u8 i;
3743                                 u16 reg;
3744                                 for (i = 0; i < 4; i++) {
3745                                         reg = MDIO_XS_8706_REG_BANK_RX0 +
3746                                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
3747                                                    MDIO_XS_8706_REG_BANK_RX0);
3748                                         bnx2x_cl45_read(bp, params->port,
3749                                                       ext_phy_type,
3750                                                       ext_phy_addr,
3751                                                       MDIO_XS_DEVAD,
3752                                                       reg, &val);
3753                                         /* Clear first 3 bits of the control */
3754                                         val &= ~0x7;
3755                                         /* Set control bits according to
3756                                         configuation */
3757                                         val |= (params->xgxs_config_rx[i] &
3758                                                 0x7);
3759                                         DP(NETIF_MSG_LINK, "Setting RX"
3760                                                  "Equalizer to BCM8706 reg 0x%x"
3761                                                  " <-- val 0x%x\n", reg, val);
3762                                         bnx2x_cl45_write(bp, params->port,
3763                                                        ext_phy_type,
3764                                                        ext_phy_addr,
3765                                                        MDIO_XS_DEVAD,
3766                                                        reg, val);
3767                                 }
3768                         }
3769                         /* Force speed */
3770                         if (params->req_line_speed == SPEED_10000) {
3771                                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3772
3773                                 bnx2x_cl45_write(bp, params->port,
3774                                                ext_phy_type,
3775                                                ext_phy_addr,
3776                                                MDIO_PMA_DEVAD,
3777                                                MDIO_PMA_REG_DIGITAL_CTRL,
3778                                                0x400);
3779                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3780                                                ext_phy_addr, MDIO_PMA_DEVAD,
3781                                                MDIO_PMA_REG_LASI_CTRL, 1);
3782                         } else {
3783                                 /* Force 1Gbps using autoneg with 1G
3784                                 advertisment */
3785
3786                                 /* Allow CL37 through CL73 */
3787                                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3788                                 bnx2x_cl45_write(bp, params->port,
3789                                                ext_phy_type,
3790                                                ext_phy_addr,
3791                                                MDIO_AN_DEVAD,
3792                                                MDIO_AN_REG_CL37_CL73,
3793                                                0x040c);
3794
3795                                 /* Enable Full-Duplex advertisment on CL37 */
3796                                 bnx2x_cl45_write(bp, params->port,
3797                                                ext_phy_type,
3798                                                ext_phy_addr,
3799                                                MDIO_AN_DEVAD,
3800                                                MDIO_AN_REG_CL37_FC_LP,
3801                                                0x0020);
3802                                 /* Enable CL37 AN */
3803                                 bnx2x_cl45_write(bp, params->port,
3804                                                ext_phy_type,
3805                                                ext_phy_addr,
3806                                                MDIO_AN_DEVAD,
3807                                                MDIO_AN_REG_CL37_AN,
3808                                                0x1000);
3809                                 /* 1G support */
3810                                 bnx2x_cl45_write(bp, params->port,
3811                                                ext_phy_type,
3812                                                ext_phy_addr,
3813                                                MDIO_AN_DEVAD,
3814                                                MDIO_AN_REG_ADV, (1<<5));
3815
3816                                 /* Enable clause 73 AN */
3817                                 bnx2x_cl45_write(bp, params->port,
3818                                                ext_phy_type,
3819                                                ext_phy_addr,
3820                                                MDIO_AN_DEVAD,
3821                                                MDIO_AN_REG_CTRL,
3822                                                0x1200);
3823                                 bnx2x_cl45_write(bp, params->port,
3824                                                ext_phy_type,
3825                                                ext_phy_addr,
3826                                                MDIO_PMA_DEVAD,
3827                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3828                                                0x0400);
3829                                 bnx2x_cl45_write(bp, params->port,
3830                                                ext_phy_type,
3831                                                ext_phy_addr,
3832                                                MDIO_PMA_DEVAD,
3833                                                MDIO_PMA_REG_LASI_CTRL, 0x0004);
3834
3835                         }
3836                         bnx2x_save_bcm_spirom_ver(bp, params->port,
3837                                                 ext_phy_type,
3838                                                 ext_phy_addr,
3839                                                 params->shmem_base);
3840                         break;
3841                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3842                         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3843                         bnx2x_bcm8726_external_rom_boot(params);
3844
3845                         /* Need to call module detected on initialization since
3846                         the module detection triggered by actual module
3847                         insertion might occur before driver is loaded, and when
3848                         driver is loaded, it reset all registers, including the
3849                         transmitter */
3850                         bnx2x_sfp_module_detection(params);
3851
3852                         /* Set Flow control */
3853                         bnx2x_ext_phy_set_pause(params, vars);
3854                         if (params->req_line_speed == SPEED_1000) {
3855                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3856                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3857                                                ext_phy_addr, MDIO_PMA_DEVAD,
3858                                                MDIO_PMA_REG_CTRL, 0x40);
3859                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3860                                                ext_phy_addr, MDIO_PMA_DEVAD,
3861                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
3862                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3863                                                ext_phy_addr, MDIO_PMA_DEVAD,
3864                                                MDIO_PMA_REG_LASI_CTRL, 0x5);
3865                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3866                                                ext_phy_addr, MDIO_PMA_DEVAD,
3867                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3868                                                0x400);
3869                         } else if ((params->req_line_speed ==
3870                                     SPEED_AUTO_NEG) &&
3871                                    ((params->speed_cap_mask &
3872                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3873                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3874                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3875                                                ext_phy_addr, MDIO_AN_DEVAD,
3876                                                MDIO_AN_REG_ADV, 0x20);
3877                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3878                                                ext_phy_addr, MDIO_AN_DEVAD,
3879                                                MDIO_AN_REG_CL37_CL73, 0x040c);
3880                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3881                                                ext_phy_addr, MDIO_AN_DEVAD,
3882                                                MDIO_AN_REG_CL37_FC_LD, 0x0020);
3883                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3884                                                ext_phy_addr, MDIO_AN_DEVAD,
3885                                                MDIO_AN_REG_CL37_AN, 0x1000);
3886                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3887                                                ext_phy_addr, MDIO_AN_DEVAD,
3888                                                MDIO_AN_REG_CTRL, 0x1200);
3889
3890                                 /* Enable RX-ALARM control to receive
3891                                 interrupt for 1G speed change */
3892                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3893                                                ext_phy_addr, MDIO_PMA_DEVAD,
3894                                                MDIO_PMA_REG_LASI_CTRL, 0x4);
3895                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3896                                                ext_phy_addr, MDIO_PMA_DEVAD,
3897                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3898                                                0x400);
3899
3900                         } else { /* Default 10G. Set only LASI control */
3901                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3902                                                ext_phy_addr, MDIO_PMA_DEVAD,
3903                                                MDIO_PMA_REG_LASI_CTRL, 1);
3904                         }
3905
3906                         /* Set TX PreEmphasis if needed */
3907                         if ((params->feature_config_flags &
3908                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3909                                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3910                                          "TX_CTRL2 0x%x\n",
3911                                          params->xgxs_config_tx[0],
3912                                          params->xgxs_config_tx[1]);
3913                                 bnx2x_cl45_write(bp, params->port,
3914                                                ext_phy_type,
3915                                                ext_phy_addr,
3916                                                MDIO_PMA_DEVAD,
3917                                                MDIO_PMA_REG_8726_TX_CTRL1,
3918                                                params->xgxs_config_tx[0]);
3919
3920                                 bnx2x_cl45_write(bp, params->port,
3921                                                ext_phy_type,
3922                                                ext_phy_addr,
3923                                                MDIO_PMA_DEVAD,
3924                                                MDIO_PMA_REG_8726_TX_CTRL2,
3925                                                params->xgxs_config_tx[1]);
3926                         }
3927                         break;
3928                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3929                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3930                 {
3931                         u16 tmp1;
3932                         u16 rx_alarm_ctrl_val;
3933                         u16 lasi_ctrl_val;
3934                         if (ext_phy_type ==
3935                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3936                                 rx_alarm_ctrl_val = 0x400;
3937                                 lasi_ctrl_val = 0x0004;
3938                         } else {
3939                                 rx_alarm_ctrl_val = (1<<2);
3940                                 lasi_ctrl_val = 0x0004;
3941                         }
3942
3943                         /* enable LASI */
3944                         bnx2x_cl45_write(bp, params->port,
3945                                    ext_phy_type,
3946                                    ext_phy_addr,
3947                                    MDIO_PMA_DEVAD,
3948                                    MDIO_PMA_REG_RX_ALARM_CTRL,
3949                                    rx_alarm_ctrl_val);
3950
3951                         bnx2x_cl45_write(bp, params->port,
3952                                        ext_phy_type,
3953                                        ext_phy_addr,
3954                                        MDIO_PMA_DEVAD,
3955                                        MDIO_PMA_REG_LASI_CTRL,
3956                                        lasi_ctrl_val);
3957
3958                         bnx2x_8073_set_pause_cl37(params, vars);
3959
3960                         if (ext_phy_type ==
3961                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)
3962                                 bnx2x_bcm8072_external_rom_boot(params);
3963                         else
3964                                 /* In case of 8073 with long xaui lines,
3965                                 don't set the 8073 xaui low power*/
3966                                 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3967
3968                         bnx2x_cl45_read(bp, params->port,
3969                                       ext_phy_type,
3970                                       ext_phy_addr,
3971                                       MDIO_PMA_DEVAD,
3972                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
3973                                       &tmp1);
3974
3975                         bnx2x_cl45_read(bp, params->port,
3976                                       ext_phy_type,
3977                                       ext_phy_addr,
3978                                       MDIO_PMA_DEVAD,
3979                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
3980
3981                         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3982                                              "0x%x\n", tmp1);
3983
3984                         /* If this is forced speed, set to KR or KX
3985                          * (all other are not supported)
3986                          */
3987                         if (params->loopback_mode == LOOPBACK_EXT) {
3988                                 bnx2x_bcm807x_force_10G(params);
3989                                 DP(NETIF_MSG_LINK,
3990                                         "Forced speed 10G on 807X\n");
3991                                 break;
3992                         } else {
3993                                 bnx2x_cl45_write(bp, params->port,
3994                                                ext_phy_type, ext_phy_addr,
3995                                                MDIO_PMA_DEVAD,
3996                                                MDIO_PMA_REG_BCM_CTRL,
3997                                                0x0002);
3998                         }
3999                         if (params->req_line_speed != SPEED_AUTO_NEG) {
4000                                 if (params->req_line_speed == SPEED_10000) {
4001                                         val = (1<<7);
4002                                 } else if (params->req_line_speed ==
4003                                            SPEED_2500) {
4004                                         val = (1<<5);
4005                                         /* Note that 2.5G works only
4006                                         when used with 1G advertisment */
4007                                 } else
4008                                         val = (1<<5);
4009                         } else {
4010
4011                                 val = 0;
4012                                 if (params->speed_cap_mask &
4013                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4014                                         val |= (1<<7);
4015
4016                                 /* Note that 2.5G works only when
4017                                 used with 1G advertisment */
4018                                 if (params->speed_cap_mask &
4019                                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
4020                                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
4021                                         val |= (1<<5);
4022                                 DP(NETIF_MSG_LINK,
4023                                          "807x autoneg val = 0x%x\n", val);
4024                         }
4025
4026                         bnx2x_cl45_write(bp, params->port,
4027                                        ext_phy_type,
4028                                        ext_phy_addr,
4029                                        MDIO_AN_DEVAD,
4030                                        MDIO_AN_REG_ADV, val);
4031                         if (ext_phy_type ==
4032                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4033                                 bnx2x_cl45_read(bp, params->port,
4034                                               ext_phy_type,
4035                                               ext_phy_addr,
4036                                               MDIO_AN_DEVAD,
4037                                               MDIO_AN_REG_8073_2_5G, &tmp1);
4038
4039                                 if (((params->speed_cap_mask &
4040                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
4041                                      (params->req_line_speed ==
4042                                       SPEED_AUTO_NEG)) ||
4043                                     (params->req_line_speed ==
4044                                      SPEED_2500)) {
4045                                         u16 phy_ver;
4046                                         /* Allow 2.5G for A1 and above */
4047                                         bnx2x_cl45_read(bp, params->port,
4048                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4049                                          ext_phy_addr,
4050                                          MDIO_PMA_DEVAD,
4051                                          MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
4052                                         DP(NETIF_MSG_LINK, "Add 2.5G\n");
4053                                         if (phy_ver > 0)
4054                                                 tmp1 |= 1;
4055                                         else
4056                                                 tmp1 &= 0xfffe;
4057                                 } else {
4058                                         DP(NETIF_MSG_LINK, "Disable 2.5G\n");
4059                                         tmp1 &= 0xfffe;
4060                                 }
4061
4062                                 bnx2x_cl45_write(bp, params->port,
4063                                                ext_phy_type,
4064                                                ext_phy_addr,
4065                                                MDIO_AN_DEVAD,
4066                                                MDIO_AN_REG_8073_2_5G, tmp1);
4067                         }
4068
4069                         /* Add support for CL37 (passive mode) II */
4070
4071                         bnx2x_cl45_read(bp, params->port,
4072                                        ext_phy_type,
4073                                        ext_phy_addr,
4074                                        MDIO_AN_DEVAD,
4075                                        MDIO_AN_REG_CL37_FC_LD,
4076                                        &tmp1);
4077
4078                         bnx2x_cl45_write(bp, params->port,
4079                                        ext_phy_type,
4080                                        ext_phy_addr,
4081                                        MDIO_AN_DEVAD,
4082                                        MDIO_AN_REG_CL37_FC_LD, (tmp1 |
4083                                        ((params->req_duplex == DUPLEX_FULL) ?
4084                                        0x20 : 0x40)));
4085
4086                         /* Add support for CL37 (passive mode) III */
4087                         bnx2x_cl45_write(bp, params->port,
4088                                        ext_phy_type,
4089                                        ext_phy_addr,
4090                                        MDIO_AN_DEVAD,
4091                                        MDIO_AN_REG_CL37_AN, 0x1000);
4092
4093                         if (ext_phy_type ==
4094                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4095                                 /* The SNR will improve about 2db by changing
4096                                 BW and FEE main tap. Rest commands are executed
4097                                 after link is up*/
4098                                 /*Change FFE main cursor to 5 in EDC register*/
4099                                 if (bnx2x_8073_is_snr_needed(params))
4100                                         bnx2x_cl45_write(bp, params->port,
4101                                                     ext_phy_type,
4102                                                     ext_phy_addr,
4103                                                     MDIO_PMA_DEVAD,
4104                                                     MDIO_PMA_REG_EDC_FFE_MAIN,
4105                                                     0xFB0C);
4106
4107                                 /* Enable FEC (Forware Error Correction)
4108                                 Request in the AN */
4109                                 bnx2x_cl45_read(bp, params->port,
4110                                               ext_phy_type,
4111                                               ext_phy_addr,
4112                                               MDIO_AN_DEVAD,
4113                                               MDIO_AN_REG_ADV2, &tmp1);
4114
4115                                 tmp1 |= (1<<15);
4116
4117                                 bnx2x_cl45_write(bp, params->port,
4118                                                ext_phy_type,
4119                                                ext_phy_addr,
4120                                                MDIO_AN_DEVAD,
4121                                                MDIO_AN_REG_ADV2, tmp1);
4122
4123                         }
4124
4125                         bnx2x_ext_phy_set_pause(params, vars);
4126
4127                         /* Restart autoneg */
4128                         msleep(500);
4129                         bnx2x_cl45_write(bp, params->port,
4130                                        ext_phy_type,
4131                                        ext_phy_addr,
4132                                        MDIO_AN_DEVAD,
4133                                        MDIO_AN_REG_CTRL, 0x1200);
4134                         DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
4135                            "Advertise 1G=%x, 10G=%x\n",
4136                            ((val & (1<<5)) > 0),
4137                            ((val & (1<<7)) > 0));
4138                         break;
4139                 }
4140
4141                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4142                 {
4143                         u16 tmp1;
4144                         u16 rx_alarm_ctrl_val;
4145                         u16 lasi_ctrl_val;
4146
4147                         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
4148
4149                         u16 mod_abs;
4150                         rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
4151                         lasi_ctrl_val = 0x0004;
4152
4153                         DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
4154                         /* enable LASI */
4155                         bnx2x_cl45_write(bp, params->port,
4156                                        ext_phy_type,
4157                                        ext_phy_addr,
4158                                        MDIO_PMA_DEVAD,
4159                                        MDIO_PMA_REG_RX_ALARM_CTRL,
4160                                        rx_alarm_ctrl_val);
4161
4162                         bnx2x_cl45_write(bp, params->port,
4163                                        ext_phy_type,
4164                                        ext_phy_addr,
4165                                        MDIO_PMA_DEVAD,
4166                                        MDIO_PMA_REG_LASI_CTRL,
4167                                        lasi_ctrl_val);
4168
4169                         /* Initially configure  MOD_ABS to interrupt when
4170                         module is presence( bit 8) */
4171                         bnx2x_cl45_read(bp, params->port,
4172                                       ext_phy_type,
4173                                       ext_phy_addr,
4174                                       MDIO_PMA_DEVAD,
4175                                       MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4176                         /* Set EDC off by setting OPTXLOS signal input to low
4177                         (bit 9).
4178                         When the EDC is off it locks onto a reference clock and
4179                         avoids becoming 'lost'.*/
4180                         mod_abs &= ~((1<<8) | (1<<9));
4181                         bnx2x_cl45_write(bp, params->port,
4182                                        ext_phy_type,
4183                                        ext_phy_addr,
4184                                        MDIO_PMA_DEVAD,
4185                                        MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4186
4187                         /* Make MOD_ABS give interrupt on change */
4188                         bnx2x_cl45_read(bp, params->port,
4189                                       ext_phy_type,
4190                                       ext_phy_addr,
4191                                       MDIO_PMA_DEVAD,
4192                                       MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4193                                       &val);
4194                         val |= (1<<12);
4195                         bnx2x_cl45_write(bp, params->port,
4196                                        ext_phy_type,
4197                                        ext_phy_addr,
4198                                        MDIO_PMA_DEVAD,
4199                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4200                                        val);
4201
4202                         /* Set 8727 GPIOs to input to allow reading from the
4203                         8727 GPIO0 status which reflect SFP+ module
4204                         over-current */
4205
4206                         bnx2x_cl45_read(bp, params->port,
4207                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4208                                        ext_phy_addr,
4209                                        MDIO_PMA_DEVAD,
4210                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4211                                        &val);
4212                         val &= 0xff8f; /* Reset bits 4-6 */
4213                         bnx2x_cl45_write(bp, params->port,
4214                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4215                                        ext_phy_addr,
4216                                        MDIO_PMA_DEVAD,
4217                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4218                                        val);
4219
4220                         bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
4221                         bnx2x_bcm8073_set_xaui_low_power_mode(params);
4222
4223                         bnx2x_cl45_read(bp, params->port,
4224                                       ext_phy_type,
4225                                       ext_phy_addr,
4226                                       MDIO_PMA_DEVAD,
4227                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
4228                                       &tmp1);
4229
4230                         bnx2x_cl45_read(bp, params->port,
4231                                       ext_phy_type,
4232                                       ext_phy_addr,
4233                                       MDIO_PMA_DEVAD,
4234                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
4235
4236                         /* Set option 1G speed */
4237                         if (params->req_line_speed == SPEED_1000) {
4238
4239                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
4240                                 bnx2x_cl45_write(bp, params->port,
4241                                                ext_phy_type,
4242                                                ext_phy_addr,
4243                                                MDIO_PMA_DEVAD,
4244                                                MDIO_PMA_REG_CTRL, 0x40);
4245                                 bnx2x_cl45_write(bp, params->port,
4246                                                ext_phy_type,
4247                                                ext_phy_addr,
4248                                                MDIO_PMA_DEVAD,
4249                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
4250                                 bnx2x_cl45_read(bp, params->port,
4251                                       ext_phy_type,
4252                                       ext_phy_addr,
4253                                       MDIO_PMA_DEVAD,
4254                                       MDIO_PMA_REG_10G_CTRL2, &tmp1);
4255                                 DP(NETIF_MSG_LINK, "1.7 = 0x%x \n", tmp1);
4256
4257                         } else if ((params->req_line_speed ==
4258                                     SPEED_AUTO_NEG) &&
4259                                    ((params->speed_cap_mask &
4260                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
4261
4262                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
4263                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4264                                                ext_phy_addr, MDIO_AN_DEVAD,
4265                                                MDIO_PMA_REG_8727_MISC_CTRL, 0);
4266                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4267                                                ext_phy_addr, MDIO_AN_DEVAD,
4268                                                MDIO_AN_REG_CL37_AN, 0x1300);
4269                         } else {
4270                                 /* Since the 8727 has only single reset pin,
4271                                 need to set the 10G registers although it is
4272                                 default */
4273                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4274                                                ext_phy_addr, MDIO_AN_DEVAD,
4275                                                MDIO_AN_REG_CTRL, 0x0020);
4276                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4277                                                ext_phy_addr, MDIO_AN_DEVAD,
4278                                                0x7, 0x0100);
4279                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4280                                                ext_phy_addr, MDIO_PMA_DEVAD,
4281                                                MDIO_PMA_REG_CTRL, 0x2040);
4282                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4283                                                ext_phy_addr, MDIO_PMA_DEVAD,
4284                                                MDIO_PMA_REG_10G_CTRL2, 0x0008);
4285                         }
4286
4287                         /* Set 2-wire transfer rate to 400Khz since 100Khz
4288                         is not operational */
4289                         bnx2x_cl45_write(bp, params->port,
4290                                        ext_phy_type,
4291                                        ext_phy_addr,
4292                                        MDIO_PMA_DEVAD,
4293                                        MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
4294                                        0xa101);
4295
4296                         /* Set TX PreEmphasis if needed */
4297                         if ((params->feature_config_flags &
4298                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
4299                                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
4300                                          "TX_CTRL2 0x%x\n",
4301                                          params->xgxs_config_tx[0],
4302                                          params->xgxs_config_tx[1]);
4303                                 bnx2x_cl45_write(bp, params->port,
4304                                                ext_phy_type,
4305                                                ext_phy_addr,
4306                                                MDIO_PMA_DEVAD,
4307                                                MDIO_PMA_REG_8727_TX_CTRL1,
4308                                                params->xgxs_config_tx[0]);
4309
4310                                 bnx2x_cl45_write(bp, params->port,
4311                                                ext_phy_type,
4312                                                ext_phy_addr,
4313                                                MDIO_PMA_DEVAD,
4314                                                MDIO_PMA_REG_8727_TX_CTRL2,
4315                                                params->xgxs_config_tx[1]);
4316                         }
4317
4318                         break;
4319                 }
4320
4321                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4322                 {
4323                         u16 fw_ver1, fw_ver2;
4324                         DP(NETIF_MSG_LINK,
4325                                 "Setting the SFX7101 LASI indication\n");
4326
4327                         bnx2x_cl45_write(bp, params->port,
4328                                        ext_phy_type,
4329                                        ext_phy_addr,
4330                                        MDIO_PMA_DEVAD,
4331                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
4332                         DP(NETIF_MSG_LINK,
4333                           "Setting the SFX7101 LED to blink on traffic\n");
4334                         bnx2x_cl45_write(bp, params->port,
4335                                        ext_phy_type,
4336                                        ext_phy_addr,
4337                                        MDIO_PMA_DEVAD,
4338                                        MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
4339
4340                         bnx2x_ext_phy_set_pause(params, vars);
4341                         /* Restart autoneg */
4342                         bnx2x_cl45_read(bp, params->port,
4343                                       ext_phy_type,
4344                                       ext_phy_addr,
4345                                       MDIO_AN_DEVAD,
4346                                       MDIO_AN_REG_CTRL, &val);
4347                         val |= 0x200;
4348                         bnx2x_cl45_write(bp, params->port,
4349                                        ext_phy_type,
4350                                        ext_phy_addr,
4351                                        MDIO_AN_DEVAD,
4352                                        MDIO_AN_REG_CTRL, val);
4353
4354                         /* Save spirom version */
4355                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4356                                       ext_phy_addr, MDIO_PMA_DEVAD,
4357                                       MDIO_PMA_REG_7101_VER1, &fw_ver1);
4358
4359                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4360                                       ext_phy_addr, MDIO_PMA_DEVAD,
4361                                       MDIO_PMA_REG_7101_VER2, &fw_ver2);
4362
4363                         bnx2x_save_spirom_version(params->bp, params->port,
4364                                                 params->shmem_base,
4365                                                 (u32)(fw_ver1<<16 | fw_ver2));
4366                         break;
4367                 }
4368                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
4369                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
4370                         /* This phy uses the NIG latch mechanism since link
4371                                 indication arrives through its LED4 and not via
4372                                 its LASI signal, so we get steady signal
4373                                 instead of clear on read */
4374                         bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
4375                                     1 << NIG_LATCH_BC_ENABLE_MI_INT);
4376
4377                         bnx2x_cl45_write(bp, params->port,
4378                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
4379                                        ext_phy_addr,
4380                                        MDIO_PMA_DEVAD,
4381                                        MDIO_PMA_REG_CTRL, 0x0000);
4382
4383                         bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
4384                         if (params->req_line_speed == SPEED_AUTO_NEG) {
4385
4386                                 u16 autoneg_val, an_1000_val, an_10_100_val;
4387                                 /* set 1000 speed advertisement */
4388                                 bnx2x_cl45_read(bp, params->port,
4389                                               ext_phy_type,
4390                                               ext_phy_addr,
4391                                               MDIO_AN_DEVAD,
4392                                               MDIO_AN_REG_8481_1000T_CTRL,
4393                                               &an_1000_val);
4394
4395                                 if (params->speed_cap_mask &
4396                                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
4397                                         an_1000_val |= (1<<8);
4398                                         if (params->req_duplex == DUPLEX_FULL)
4399                                                 an_1000_val |= (1<<9);
4400                                         DP(NETIF_MSG_LINK, "Advertising 1G\n");
4401                                 } else
4402                                         an_1000_val &= ~((1<<8) | (1<<9));
4403
4404                                 bnx2x_cl45_write(bp, params->port,
4405                                                ext_phy_type,
4406                                                ext_phy_addr,
4407                                                MDIO_AN_DEVAD,
4408                                                MDIO_AN_REG_8481_1000T_CTRL,
4409                                                an_1000_val);
4410
4411                                 /* set 100 speed advertisement */
4412                                 bnx2x_cl45_read(bp, params->port,
4413                                               ext_phy_type,
4414                                               ext_phy_addr,
4415                                               MDIO_AN_DEVAD,
4416                                               MDIO_AN_REG_8481_LEGACY_AN_ADV,
4417                                               &an_10_100_val);
4418
4419                                 if (params->speed_cap_mask &
4420                                  (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
4421                                   PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) {
4422                                         an_10_100_val |= (1<<7);
4423                                         if (params->req_duplex == DUPLEX_FULL)
4424                                                 an_10_100_val |= (1<<8);
4425                                         DP(NETIF_MSG_LINK,
4426                                                 "Advertising 100M\n");
4427                                 } else
4428                                         an_10_100_val &= ~((1<<7) | (1<<8));
4429
4430                                 /* set 10 speed advertisement */
4431                                 if (params->speed_cap_mask &
4432                                   (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
4433                                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) {
4434                                         an_10_100_val |= (1<<5);
4435                                         if (params->req_duplex == DUPLEX_FULL)
4436                                                 an_10_100_val |= (1<<6);
4437                                         DP(NETIF_MSG_LINK, "Advertising 10M\n");
4438                                      }
4439                                 else
4440                                         an_10_100_val &= ~((1<<5) | (1<<6));
4441
4442                                 bnx2x_cl45_write(bp, params->port,
4443                                                ext_phy_type,
4444                                                ext_phy_addr,
4445                                                MDIO_AN_DEVAD,
4446                                                MDIO_AN_REG_8481_LEGACY_AN_ADV,
4447                                                an_10_100_val);
4448
4449                                 bnx2x_cl45_read(bp, params->port,
4450                                               ext_phy_type,
4451                                               ext_phy_addr,
4452                                               MDIO_AN_DEVAD,
4453                                               MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4454                                               &autoneg_val);
4455
4456                                 /* Disable forced speed */
4457                                 autoneg_val &= ~(1<<6|1<<13);
4458
4459                                 /* Enable autoneg and restart autoneg
4460                                 for legacy speeds */
4461                                 autoneg_val |= (1<<9|1<<12);
4462
4463                                 if (params->req_duplex == DUPLEX_FULL)
4464                                         autoneg_val |= (1<<8);
4465                                 else
4466                                         autoneg_val &= ~(1<<8);
4467
4468                                 bnx2x_cl45_write(bp, params->port,
4469                                                ext_phy_type,
4470                                                ext_phy_addr,
4471                                                MDIO_AN_DEVAD,
4472                                                MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4473                                                autoneg_val);
4474
4475                                 if (params->speed_cap_mask &
4476                                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
4477                                         DP(NETIF_MSG_LINK, "Advertising 10G\n");
4478                                         /* Restart autoneg for 10G*/
4479                         bnx2x_cl45_read(bp, params->port,
4480                                       ext_phy_type,
4481                                       ext_phy_addr,
4482                                       MDIO_AN_DEVAD,
4483                                       MDIO_AN_REG_CTRL, &val);
4484                         val |= 0x200;
4485                         bnx2x_cl45_write(bp, params->port,
4486                                        ext_phy_type,
4487                                        ext_phy_addr,
4488                                        MDIO_AN_DEVAD,
4489                                        MDIO_AN_REG_CTRL, val);
4490                                 }
4491                         } else {
4492                                 /* Force speed */
4493                                 u16 autoneg_ctrl, pma_ctrl;
4494                                 bnx2x_cl45_read(bp, params->port,
4495                                               ext_phy_type,
4496                                               ext_phy_addr,
4497                                               MDIO_AN_DEVAD,
4498                                               MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4499                                               &autoneg_ctrl);
4500
4501                                 /* Disable autoneg */
4502                                 autoneg_ctrl &= ~(1<<12);
4503
4504                                 /* Set 1000 force */
4505                                 switch (params->req_line_speed) {
4506                                 case SPEED_10000:
4507                                         DP(NETIF_MSG_LINK,
4508                                                 "Unable to set 10G force !\n");
4509                                         break;
4510                                 case SPEED_1000:
4511                                         bnx2x_cl45_read(bp, params->port,
4512                                                       ext_phy_type,
4513                                                       ext_phy_addr,
4514                                                       MDIO_PMA_DEVAD,
4515                                                       MDIO_PMA_REG_CTRL,
4516                                                       &pma_ctrl);
4517                                         autoneg_ctrl &= ~(1<<13);
4518                                         autoneg_ctrl |= (1<<6);
4519                                         pma_ctrl &= ~(1<<13);
4520                                         pma_ctrl |= (1<<6);
4521                                         DP(NETIF_MSG_LINK,
4522                                                 "Setting 1000M force\n");
4523                                         bnx2x_cl45_write(bp, params->port,
4524                                                        ext_phy_type,
4525                                                        ext_phy_addr,
4526                                                        MDIO_PMA_DEVAD,
4527                                                        MDIO_PMA_REG_CTRL,
4528                                                        pma_ctrl);
4529                                         break;
4530                                 case SPEED_100:
4531                                         autoneg_ctrl |= (1<<13);
4532                                         autoneg_ctrl &= ~(1<<6);
4533                                         DP(NETIF_MSG_LINK,
4534                                                 "Setting 100M force\n");
4535                                         break;
4536                                 case SPEED_10:
4537                                         autoneg_ctrl &= ~(1<<13);
4538                                         autoneg_ctrl &= ~(1<<6);
4539                                         DP(NETIF_MSG_LINK,
4540                                                 "Setting 10M force\n");
4541                                         break;
4542                                 }
4543
4544                                 /* Duplex mode */
4545                                 if (params->req_duplex == DUPLEX_FULL) {
4546                                         autoneg_ctrl |= (1<<8);
4547                                         DP(NETIF_MSG_LINK,
4548                                                 "Setting full duplex\n");
4549                                 } else
4550                                         autoneg_ctrl &= ~(1<<8);
4551
4552                                 /* Update autoneg ctrl and pma ctrl */
4553                                 bnx2x_cl45_write(bp, params->port,
4554                                                ext_phy_type,
4555                                                ext_phy_addr,
4556                                                MDIO_AN_DEVAD,
4557                                                MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4558                                                autoneg_ctrl);
4559                         }
4560
4561                         /* Save spirom version */
4562                         bnx2x_save_8481_spirom_version(bp, params->port,
4563                                                      ext_phy_addr,
4564                                                      params->shmem_base);
4565                         break;
4566                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4567                         DP(NETIF_MSG_LINK,
4568                                  "XGXS PHY Failure detected 0x%x\n",
4569                                  params->ext_phy_config);
4570                         rc = -EINVAL;
4571                         break;
4572                 default:
4573                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
4574                                   params->ext_phy_config);
4575                         rc = -EINVAL;
4576                         break;
4577                 }
4578
4579         } else { /* SerDes */
4580
4581                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4582                 switch (ext_phy_type) {
4583                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
4584                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
4585                         break;
4586
4587                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
4588                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
4589                         break;
4590
4591                 default:
4592                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
4593                            params->ext_phy_config);
4594                         break;
4595                 }
4596         }
4597         return rc;
4598 }
4599
4600 static void bnx2x_8727_handle_mod_abs(struct link_params *params)
4601 {
4602         struct bnx2x *bp = params->bp;
4603         u16 mod_abs, rx_alarm_status;
4604         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
4605         u32 val = REG_RD(bp, params->shmem_base +
4606                              offsetof(struct shmem_region, dev_info.
4607                                       port_feature_config[params->port].
4608                                       config));
4609         bnx2x_cl45_read(bp, params->port,
4610                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4611                       ext_phy_addr,
4612                       MDIO_PMA_DEVAD,
4613                       MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4614         if (mod_abs & (1<<8)) {
4615
4616                 /* Module is absent */
4617                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4618                             "show module is absent\n");
4619
4620                 /* 1. Set mod_abs to detect next module
4621                 presence event
4622                    2. Set EDC off by setting OPTXLOS signal input to low
4623                         (bit 9).
4624                         When the EDC is off it locks onto a reference clock and
4625                         avoids becoming 'lost'.*/
4626                 mod_abs &= ~((1<<8)|(1<<9));
4627                 bnx2x_cl45_write(bp, params->port,
4628                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4629                                ext_phy_addr,
4630                                MDIO_PMA_DEVAD,
4631                                MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4632
4633                 /* Clear RX alarm since it stays up as long as
4634                 the mod_abs wasn't changed */
4635                 bnx2x_cl45_read(bp, params->port,
4636                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4637                               ext_phy_addr,
4638                               MDIO_PMA_DEVAD,
4639                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4640
4641         } else {
4642                 /* Module is present */
4643                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4644                             "show module is present\n");
4645                 /* First thing, disable transmitter,
4646                 and if the module is ok, the
4647                 module_detection will enable it*/
4648
4649                 /* 1. Set mod_abs to detect next module
4650                 absent event ( bit 8)
4651                    2. Restore the default polarity of the OPRXLOS signal and
4652                 this signal will then correctly indicate the presence or
4653                 absence of the Rx signal. (bit 9) */
4654                 mod_abs |= ((1<<8)|(1<<9));
4655                 bnx2x_cl45_write(bp, params->port,
4656                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4657                        ext_phy_addr,
4658                        MDIO_PMA_DEVAD,
4659                        MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4660
4661                 /* Clear RX alarm since it stays up as long as
4662                 the mod_abs wasn't changed. This is need to be done
4663                 before calling the module detection, otherwise it will clear
4664                 the link update alarm */
4665                 bnx2x_cl45_read(bp, params->port,
4666                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4667                               ext_phy_addr,
4668                               MDIO_PMA_DEVAD,
4669                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4670
4671
4672                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4673                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
4674                         bnx2x_sfp_set_transmitter(bp, params->port,
4675                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4676                                         ext_phy_addr, 0);
4677
4678                 if (bnx2x_wait_for_sfp_module_initialized(params)
4679                     == 0)
4680                         bnx2x_sfp_module_detection(params);
4681                 else
4682                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
4683         }
4684
4685         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4686                  rx_alarm_status);
4687         /* No need to check link status in case of
4688         module plugged in/out */
4689 }
4690
4691
4692 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
4693                                  struct link_vars *vars,
4694                                  u8 is_mi_int)
4695 {
4696         struct bnx2x *bp = params->bp;
4697         u32 ext_phy_type;
4698         u8 ext_phy_addr;
4699         u16 val1 = 0, val2;
4700         u16 rx_sd, pcs_status;
4701         u8 ext_phy_link_up = 0;
4702         u8 port = params->port;
4703
4704         if (vars->phy_flags & PHY_XGXS_FLAG) {
4705                 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
4706                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4707                 switch (ext_phy_type) {
4708                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4709                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
4710                         ext_phy_link_up = 1;
4711                         break;
4712
4713                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4714                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
4715                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4716                                       ext_phy_addr,
4717                                       MDIO_WIS_DEVAD,
4718                                       MDIO_WIS_REG_LASI_STATUS, &val1);
4719                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4720
4721                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4722                                       ext_phy_addr,
4723                                       MDIO_WIS_DEVAD,
4724                                       MDIO_WIS_REG_LASI_STATUS, &val1);
4725                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4726
4727                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4728                                       ext_phy_addr,
4729                                       MDIO_PMA_DEVAD,
4730                                       MDIO_PMA_REG_RX_SD, &rx_sd);
4731
4732                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4733                                       ext_phy_addr,
4734                                       1,
4735                                       0xc809, &val1);
4736                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4737                                       ext_phy_addr,
4738                                       1,
4739                                       0xc809, &val1);
4740
4741                         DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4742                         ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9))
4743                                            && ((val1 & (1<<8)) == 0));
4744                         if (ext_phy_link_up)
4745                                 vars->line_speed = SPEED_10000;
4746                         break;
4747
4748                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4749                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4750                         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
4751                         /* Clear RX Alarm*/
4752                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4753                                       ext_phy_addr,
4754                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
4755                                       &val2);
4756                         /* clear LASI indication*/
4757                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4758                                       ext_phy_addr,
4759                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4760                                       &val1);
4761                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4762                                       ext_phy_addr,
4763                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4764                                       &val2);
4765                         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
4766                                      "0x%x\n", val1, val2);
4767
4768                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4769                                       ext_phy_addr,
4770                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
4771                                       &rx_sd);
4772                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4773                                       ext_phy_addr,
4774                                       MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
4775                                       &pcs_status);
4776                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4777                                       ext_phy_addr,
4778                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4779                                       &val2);
4780                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4781                                       ext_phy_addr,
4782                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4783                                       &val2);
4784
4785                         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
4786                            "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
4787                            rx_sd, pcs_status, val2);
4788                         /* link is up if both bit 0 of pmd_rx_sd and
4789                          * bit 0 of pcs_status are set, or if the autoneg bit
4790                            1 is set
4791                          */
4792                         ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
4793                                            (val2 & (1<<1)));
4794                         if (ext_phy_link_up) {
4795                                 if (ext_phy_type ==
4796                                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
4797                                         /* If transmitter is disabled,
4798                                         ignore false link up indication */
4799                                         bnx2x_cl45_read(bp, params->port,
4800                                                    ext_phy_type,
4801                                                    ext_phy_addr,
4802                                                    MDIO_PMA_DEVAD,
4803                                                    MDIO_PMA_REG_PHY_IDENTIFIER,
4804                                                    &val1);
4805                                         if (val1 & (1<<15)) {
4806                                                 DP(NETIF_MSG_LINK, "Tx is "
4807                                                             "disabled\n");
4808                                                 ext_phy_link_up = 0;
4809                                                 break;
4810                                         }
4811                                 }
4812                                 if (val2 & (1<<1))
4813                                         vars->line_speed = SPEED_1000;
4814                                 else
4815                                         vars->line_speed = SPEED_10000;
4816                         }
4817                         break;
4818
4819                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4820                 {
4821                         u16 link_status = 0;
4822                         u16 rx_alarm_status;
4823                         /* Check the LASI */
4824                         bnx2x_cl45_read(bp, params->port,
4825                                       ext_phy_type,
4826                                       ext_phy_addr,
4827                                       MDIO_PMA_DEVAD,
4828                                       MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4829
4830                         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4831                                  rx_alarm_status);
4832
4833                         bnx2x_cl45_read(bp, params->port,
4834                                       ext_phy_type,
4835                                       ext_phy_addr,
4836                                       MDIO_PMA_DEVAD,
4837                                       MDIO_PMA_REG_LASI_STATUS, &val1);
4838
4839                         DP(NETIF_MSG_LINK,
4840                                  "8727 LASI status 0x%x\n",
4841                                  val1);
4842
4843                         /* Clear MSG-OUT */
4844                         bnx2x_cl45_read(bp, params->port,
4845                                       ext_phy_type,
4846                                       ext_phy_addr,
4847                                       MDIO_PMA_DEVAD,
4848                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
4849                                       &val1);
4850
4851                         /*
4852                          * If a module is present and there is need to check
4853                          * for over current
4854                          */
4855                         if (!(params->feature_config_flags &
4856                               FEATURE_CONFIG_BCM8727_NOC) &&
4857                             !(rx_alarm_status & (1<<5))) {
4858                                 /* Check over-current using 8727 GPIO0 input*/
4859                                 bnx2x_cl45_read(bp, params->port,
4860                                               ext_phy_type,
4861                                               ext_phy_addr,
4862                                               MDIO_PMA_DEVAD,
4863                                               MDIO_PMA_REG_8727_GPIO_CTRL,
4864                                               &val1);
4865
4866                                 if ((val1 & (1<<8)) == 0) {
4867                                         DP(NETIF_MSG_LINK, "8727 Power fault"
4868                                                      " has been detected on "
4869                                                      "port %d\n",
4870                                                  params->port);
4871                                         printk(KERN_ERR PFX  "Error:  Power"
4872                                                  " fault on %s Port %d has"
4873                                                  " been detected and the"
4874                                                  " power to that SFP+ module"
4875                                                  " has been removed to prevent"
4876                                                  " failure of the card. Please"
4877                                                  " remove the SFP+ module and"
4878                                                  " restart the system to clear"
4879                                                  " this error.\n"
4880                         , bp->dev->name, params->port);
4881                                         /*
4882                                          * Disable all RX_ALARMs except for
4883                                          * mod_abs
4884                                          */
4885                                         bnx2x_cl45_write(bp, params->port,
4886                                                      ext_phy_type,
4887                                                      ext_phy_addr,
4888                                                      MDIO_PMA_DEVAD,
4889                                                      MDIO_PMA_REG_RX_ALARM_CTRL,
4890                                                      (1<<5));
4891
4892                                         bnx2x_cl45_read(bp, params->port,
4893                                                     ext_phy_type,
4894                                                     ext_phy_addr,
4895                                                     MDIO_PMA_DEVAD,
4896                                                     MDIO_PMA_REG_PHY_IDENTIFIER,
4897                                                     &val1);
4898                                         /* Wait for module_absent_event */
4899                                         val1 |= (1<<8);
4900                                         bnx2x_cl45_write(bp, params->port,
4901                                                     ext_phy_type,
4902                                                     ext_phy_addr,
4903                                                     MDIO_PMA_DEVAD,
4904                                                     MDIO_PMA_REG_PHY_IDENTIFIER,
4905                                                     val1);
4906                                         /* Clear RX alarm */
4907                                         bnx2x_cl45_read(bp, params->port,
4908                                                       ext_phy_type,
4909                                                       ext_phy_addr,
4910                                                       MDIO_PMA_DEVAD,
4911                                                       MDIO_PMA_REG_RX_ALARM,
4912                                                       &rx_alarm_status);
4913                                         break;
4914                                 }
4915                         } /* Over current check */
4916
4917                         /* When module absent bit is set, check module */
4918                         if (rx_alarm_status & (1<<5)) {
4919                                 bnx2x_8727_handle_mod_abs(params);
4920                                 /* Enable all mod_abs and link detection bits */
4921                                 bnx2x_cl45_write(bp, params->port,
4922                                                ext_phy_type,
4923                                                ext_phy_addr,
4924                                                MDIO_PMA_DEVAD,
4925                                                MDIO_PMA_REG_RX_ALARM_CTRL,
4926                                                ((1<<5) | (1<<2)));
4927                         }
4928
4929                         /* If transmitter is disabled,
4930                         ignore false link up indication */
4931                         bnx2x_cl45_read(bp, params->port,
4932                                       ext_phy_type,
4933                                       ext_phy_addr,
4934                                       MDIO_PMA_DEVAD,
4935                                       MDIO_PMA_REG_PHY_IDENTIFIER,
4936                                       &val1);
4937                         if (val1 & (1<<15)) {
4938                                 DP(NETIF_MSG_LINK, "Tx is disabled\n");
4939                                 ext_phy_link_up = 0;
4940                                 break;
4941                         }
4942
4943                         bnx2x_cl45_read(bp, params->port,
4944                                       ext_phy_type,
4945                                       ext_phy_addr,
4946                                       MDIO_PMA_DEVAD,
4947                                       MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4948                                       &link_status);
4949
4950                         /* Bits 0..2 --> speed detected,
4951                            bits 13..15--> link is down */
4952                         if ((link_status & (1<<2)) &&
4953                             (!(link_status & (1<<15)))) {
4954                                 ext_phy_link_up = 1;
4955                                 vars->line_speed = SPEED_10000;
4956                         } else if ((link_status & (1<<0)) &&
4957                                    (!(link_status & (1<<13)))) {
4958                                 ext_phy_link_up = 1;
4959                                 vars->line_speed = SPEED_1000;
4960                                 DP(NETIF_MSG_LINK,
4961                                          "port %x: External link"
4962                                          " up in 1G\n", params->port);
4963                         } else {
4964                                 ext_phy_link_up = 0;
4965                                 DP(NETIF_MSG_LINK,
4966                                          "port %x: External link"
4967                                          " is down\n", params->port);
4968                         }
4969                         break;
4970                 }
4971
4972                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4973                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4974                 {
4975                         u16 link_status = 0;
4976                         u16 an1000_status = 0;
4977
4978                         if (ext_phy_type ==
4979                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
4980                                 bnx2x_cl45_read(bp, params->port,
4981                                       ext_phy_type,
4982                                       ext_phy_addr,
4983                                       MDIO_PCS_DEVAD,
4984                                       MDIO_PCS_REG_LASI_STATUS, &val1);
4985                         bnx2x_cl45_read(bp, params->port,
4986                                       ext_phy_type,
4987                                       ext_phy_addr,
4988                                       MDIO_PCS_DEVAD,
4989                                       MDIO_PCS_REG_LASI_STATUS, &val2);
4990                         DP(NETIF_MSG_LINK,
4991                                  "870x LASI status 0x%x->0x%x\n",
4992                                   val1, val2);
4993                         } else {
4994                                 /* In 8073, port1 is directed through emac0 and
4995                                  * port0 is directed through emac1
4996                                  */
4997                                 bnx2x_cl45_read(bp, params->port,
4998                                               ext_phy_type,
4999                                               ext_phy_addr,
5000                                               MDIO_PMA_DEVAD,
5001                                               MDIO_PMA_REG_LASI_STATUS, &val1);
5002
5003                                 DP(NETIF_MSG_LINK,
5004                                          "8703 LASI status 0x%x\n",
5005                                           val1);
5006                         }
5007
5008                         /* clear the interrupt LASI status register */
5009                         bnx2x_cl45_read(bp, params->port,
5010                                       ext_phy_type,
5011                                       ext_phy_addr,
5012                                       MDIO_PCS_DEVAD,
5013                                       MDIO_PCS_REG_STATUS, &val2);
5014                         bnx2x_cl45_read(bp, params->port,
5015                                       ext_phy_type,
5016                                       ext_phy_addr,
5017                                       MDIO_PCS_DEVAD,
5018                                       MDIO_PCS_REG_STATUS, &val1);
5019                         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
5020                            val2, val1);
5021                         /* Clear MSG-OUT */
5022                         bnx2x_cl45_read(bp, params->port,
5023                                       ext_phy_type,
5024                                       ext_phy_addr,
5025                                       MDIO_PMA_DEVAD,
5026                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
5027                                       &val1);
5028
5029                         /* Check the LASI */
5030                         bnx2x_cl45_read(bp, params->port,
5031                                       ext_phy_type,
5032                                       ext_phy_addr,
5033                                       MDIO_PMA_DEVAD,
5034                                       MDIO_PMA_REG_RX_ALARM, &val2);
5035
5036                         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
5037
5038                         /* Check the link status */
5039                         bnx2x_cl45_read(bp, params->port,
5040                                       ext_phy_type,
5041                                       ext_phy_addr,
5042                                       MDIO_PCS_DEVAD,
5043                                       MDIO_PCS_REG_STATUS, &val2);
5044                         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
5045
5046                         bnx2x_cl45_read(bp, params->port,
5047                                       ext_phy_type,
5048                                       ext_phy_addr,
5049                                       MDIO_PMA_DEVAD,
5050                                       MDIO_PMA_REG_STATUS, &val2);
5051                         bnx2x_cl45_read(bp, params->port,
5052                                       ext_phy_type,
5053                                       ext_phy_addr,
5054                                       MDIO_PMA_DEVAD,
5055                                       MDIO_PMA_REG_STATUS, &val1);
5056                         ext_phy_link_up = ((val1 & 4) == 4);
5057                         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
5058                         if (ext_phy_type ==
5059                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
5060
5061                                 if (ext_phy_link_up &&
5062                                     ((params->req_line_speed !=
5063                                         SPEED_10000))) {
5064                                         if (bnx2x_bcm8073_xaui_wa(params)
5065                                              != 0) {
5066                                                 ext_phy_link_up = 0;
5067                                                 break;
5068                                         }
5069                                 }
5070                                 bnx2x_cl45_read(bp, params->port,
5071                                               ext_phy_type,
5072                                               ext_phy_addr,
5073                                               MDIO_AN_DEVAD,
5074                                               MDIO_AN_REG_LINK_STATUS,
5075                                               &an1000_status);
5076                                 bnx2x_cl45_read(bp, params->port,
5077                                               ext_phy_type,
5078                                               ext_phy_addr,
5079                                               MDIO_AN_DEVAD,
5080                                               MDIO_AN_REG_LINK_STATUS,
5081                                               &an1000_status);
5082
5083                                 /* Check the link status on 1.1.2 */
5084                                 bnx2x_cl45_read(bp, params->port,
5085                                               ext_phy_type,
5086                                               ext_phy_addr,
5087                                               MDIO_PMA_DEVAD,
5088                                               MDIO_PMA_REG_STATUS, &val2);
5089                                 bnx2x_cl45_read(bp, params->port,
5090                                               ext_phy_type,
5091                                               ext_phy_addr,
5092                                               MDIO_PMA_DEVAD,
5093                                               MDIO_PMA_REG_STATUS, &val1);
5094                                 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
5095                                              "an_link_status=0x%x\n",
5096                                           val2, val1, an1000_status);
5097
5098                                 ext_phy_link_up = (((val1 & 4) == 4) ||
5099                                                 (an1000_status & (1<<1)));
5100                                 if (ext_phy_link_up &&
5101                                     bnx2x_8073_is_snr_needed(params)) {
5102                                         /* The SNR will improve about 2dbby
5103                                         changing the BW and FEE main tap.*/
5104
5105                                         /* The 1st write to change FFE main
5106                                         tap is set before restart AN */
5107                                         /* Change PLL Bandwidth in EDC
5108                                         register */
5109                                         bnx2x_cl45_write(bp, port, ext_phy_type,
5110                                                     ext_phy_addr,
5111                                                     MDIO_PMA_DEVAD,
5112                                                     MDIO_PMA_REG_PLL_BANDWIDTH,
5113                                                     0x26BC);
5114
5115                                         /* Change CDR Bandwidth in EDC
5116                                         register */
5117                                         bnx2x_cl45_write(bp, port, ext_phy_type,
5118                                                     ext_phy_addr,
5119                                                     MDIO_PMA_DEVAD,
5120                                                     MDIO_PMA_REG_CDR_BANDWIDTH,
5121                                                     0x0333);
5122                                 }
5123                                 bnx2x_cl45_read(bp, params->port,
5124                                            ext_phy_type,
5125                                            ext_phy_addr,
5126                                            MDIO_PMA_DEVAD,
5127                                            MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
5128                                            &link_status);
5129
5130                                 /* Bits 0..2 --> speed detected,
5131                                    bits 13..15--> link is down */
5132                                 if ((link_status & (1<<2)) &&
5133                                     (!(link_status & (1<<15)))) {
5134                                         ext_phy_link_up = 1;
5135                                         vars->line_speed = SPEED_10000;
5136                                         DP(NETIF_MSG_LINK,
5137                                                  "port %x: External link"
5138                                                  " up in 10G\n", params->port);
5139                                 } else if ((link_status & (1<<1)) &&
5140                                            (!(link_status & (1<<14)))) {
5141                                         ext_phy_link_up = 1;
5142                                         vars->line_speed = SPEED_2500;
5143                                         DP(NETIF_MSG_LINK,
5144                                                  "port %x: External link"
5145                                                  " up in 2.5G\n", params->port);
5146                                 } else if ((link_status & (1<<0)) &&
5147                                            (!(link_status & (1<<13)))) {
5148                                         ext_phy_link_up = 1;
5149                                         vars->line_speed = SPEED_1000;
5150                                         DP(NETIF_MSG_LINK,
5151                                                  "port %x: External link"
5152                                                  " up in 1G\n", params->port);
5153                                 } else {
5154                                         ext_phy_link_up = 0;
5155                                         DP(NETIF_MSG_LINK,
5156                                                  "port %x: External link"
5157                                                  " is down\n", params->port);
5158                                 }
5159                         } else {
5160                                 /* See if 1G link is up for the 8072 */
5161                                 bnx2x_cl45_read(bp, params->port,
5162                                               ext_phy_type,
5163                                               ext_phy_addr,
5164                                               MDIO_AN_DEVAD,
5165                                               MDIO_AN_REG_LINK_STATUS,
5166                                               &an1000_status);
5167                                 bnx2x_cl45_read(bp, params->port,
5168                                               ext_phy_type,
5169                                               ext_phy_addr,
5170                                               MDIO_AN_DEVAD,
5171                                               MDIO_AN_REG_LINK_STATUS,
5172                                               &an1000_status);
5173                                 if (an1000_status & (1<<1)) {
5174                                         ext_phy_link_up = 1;
5175                                         vars->line_speed = SPEED_1000;
5176                                         DP(NETIF_MSG_LINK,
5177                                                  "port %x: External link"
5178                                                  " up in 1G\n", params->port);
5179                                 } else if (ext_phy_link_up) {
5180                                         ext_phy_link_up = 1;
5181                                         vars->line_speed = SPEED_10000;
5182                                         DP(NETIF_MSG_LINK,
5183                                                  "port %x: External link"
5184                                                  " up in 10G\n", params->port);
5185                                 }
5186                         }
5187
5188
5189                         break;
5190                 }
5191                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5192                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5193                                       ext_phy_addr,
5194                                       MDIO_PMA_DEVAD,
5195                                       MDIO_PMA_REG_LASI_STATUS, &val2);
5196                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5197                                       ext_phy_addr,
5198                                       MDIO_PMA_DEVAD,
5199                                       MDIO_PMA_REG_LASI_STATUS, &val1);
5200                         DP(NETIF_MSG_LINK,
5201                                  "10G-base-T LASI status 0x%x->0x%x\n",
5202                                   val2, val1);
5203                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5204                                       ext_phy_addr,
5205                                       MDIO_PMA_DEVAD,
5206                                       MDIO_PMA_REG_STATUS, &val2);
5207                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5208                                       ext_phy_addr,
5209                                       MDIO_PMA_DEVAD,
5210                                       MDIO_PMA_REG_STATUS, &val1);
5211                         DP(NETIF_MSG_LINK,
5212                                  "10G-base-T PMA status 0x%x->0x%x\n",
5213                                  val2, val1);
5214                         ext_phy_link_up = ((val1 & 4) == 4);
5215                         /* if link is up
5216                          * print the AN outcome of the SFX7101 PHY
5217                          */
5218                         if (ext_phy_link_up) {
5219                                 bnx2x_cl45_read(bp, params->port,
5220                                               ext_phy_type,
5221                                               ext_phy_addr,
5222                                               MDIO_AN_DEVAD,
5223                                               MDIO_AN_REG_MASTER_STATUS,
5224                                               &val2);
5225                                 vars->line_speed = SPEED_10000;
5226                                 DP(NETIF_MSG_LINK,
5227                                          "SFX7101 AN status 0x%x->Master=%x\n",
5228                                           val2,
5229                                          (val2 & (1<<14)));
5230                         }
5231                         break;
5232                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5233                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
5234                         /* Check 10G-BaseT link status */
5235                         /* Check PMD signal ok */
5236                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5237                                                       ext_phy_addr,
5238                                                       MDIO_AN_DEVAD,
5239                                                       0xFFFA,
5240                                                       &val1);
5241                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5242                                       ext_phy_addr,
5243                                       MDIO_PMA_DEVAD,
5244                                       MDIO_PMA_REG_8481_PMD_SIGNAL,
5245                                       &val2);
5246                         DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2);
5247
5248                         /* Check link 10G */
5249                         if (val2 & (1<<11)) {
5250                                 vars->line_speed = SPEED_10000;
5251                                 ext_phy_link_up = 1;
5252                                 bnx2x_8481_set_10G_led_mode(params,
5253                                                           ext_phy_type,
5254                                                           ext_phy_addr);
5255                         } else { /* Check Legacy speed link */
5256                                 u16 legacy_status, legacy_speed;
5257
5258                                 /* Enable expansion register 0x42
5259                                 (Operation mode status) */
5260                                 bnx2x_cl45_write(bp, params->port,
5261                                          ext_phy_type,
5262                                          ext_phy_addr,
5263                                          MDIO_AN_DEVAD,
5264                                          MDIO_AN_REG_8481_EXPANSION_REG_ACCESS,
5265                                          0xf42);
5266
5267                                 /* Get legacy speed operation status */
5268                                 bnx2x_cl45_read(bp, params->port,
5269                                           ext_phy_type,
5270                                           ext_phy_addr,
5271                                           MDIO_AN_DEVAD,
5272                                           MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
5273                                           &legacy_status);
5274
5275                                 DP(NETIF_MSG_LINK, "Legacy speed status"
5276                                              " = 0x%x\n", legacy_status);
5277                                 ext_phy_link_up = ((legacy_status & (1<<11))
5278                                                    == (1<<11));
5279                                 if (ext_phy_link_up) {
5280                                         legacy_speed = (legacy_status & (3<<9));
5281                                         if (legacy_speed == (0<<9))
5282                                                 vars->line_speed = SPEED_10;
5283                                         else if (legacy_speed == (1<<9))
5284                                                 vars->line_speed =
5285                                                         SPEED_100;
5286                                         else if (legacy_speed == (2<<9))
5287                                                 vars->line_speed =
5288                                                         SPEED_1000;
5289                                         else /* Should not happen */
5290                                                 vars->line_speed = 0;
5291
5292                                         if (legacy_status & (1<<8))
5293                                                 vars->duplex = DUPLEX_FULL;
5294                                         else
5295                                                 vars->duplex = DUPLEX_HALF;
5296
5297                                         DP(NETIF_MSG_LINK, "Link is up "
5298                                                      "in %dMbps, is_duplex_full"
5299                                                      "= %d\n",
5300                                                 vars->line_speed,
5301                                                 (vars->duplex == DUPLEX_FULL));
5302                                         bnx2x_8481_set_legacy_led_mode(params,
5303                                                                  ext_phy_type,
5304                                                                  ext_phy_addr);
5305                                 }
5306                         }
5307                         break;
5308                 default:
5309                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
5310                            params->ext_phy_config);
5311                         ext_phy_link_up = 0;
5312                         break;
5313                 }
5314                 /* Set SGMII mode for external phy */
5315                 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5316                         if (vars->line_speed < SPEED_1000)
5317                                 vars->phy_flags |= PHY_SGMII_FLAG;
5318                         else
5319                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
5320                 }
5321
5322         } else { /* SerDes */
5323                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5324                 switch (ext_phy_type) {
5325                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
5326                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
5327                         ext_phy_link_up = 1;
5328                         break;
5329
5330                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
5331                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
5332                         ext_phy_link_up = 1;
5333                         break;
5334
5335                 default:
5336                         DP(NETIF_MSG_LINK,
5337                                  "BAD SerDes ext_phy_config 0x%x\n",
5338                                  params->ext_phy_config);
5339                         ext_phy_link_up = 0;
5340                         break;
5341                 }
5342         }
5343
5344         return ext_phy_link_up;
5345 }
5346
5347 static void bnx2x_link_int_enable(struct link_params *params)
5348 {
5349         u8 port = params->port;
5350         u32 ext_phy_type;
5351         u32 mask;
5352         struct bnx2x *bp = params->bp;
5353
5354         /* setting the status to report on link up
5355            for either XGXS or SerDes */
5356
5357         if (params->switch_cfg == SWITCH_CFG_10G) {
5358                 mask = (NIG_MASK_XGXS0_LINK10G |
5359                         NIG_MASK_XGXS0_LINK_STATUS);
5360                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5361                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5362                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5363                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
5364                     (ext_phy_type !=
5365                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
5366                         mask |= NIG_MASK_MI_INT;
5367                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5368                 }
5369
5370         } else { /* SerDes */
5371                 mask = NIG_MASK_SERDES0_LINK_STATUS;
5372                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5373                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5374                 if ((ext_phy_type !=
5375                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5376                     (ext_phy_type !=
5377                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
5378                         mask |= NIG_MASK_MI_INT;
5379                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5380                 }
5381         }
5382         bnx2x_bits_en(bp,
5383                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5384                       mask);
5385
5386         DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
5387                  (params->switch_cfg == SWITCH_CFG_10G),
5388                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5389         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5390                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5391                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5392                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5393         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5394            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5395            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5396 }
5397
5398 static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
5399                                         u8 is_mi_int)
5400 {
5401         u32 latch_status = 0, is_mi_int_status;
5402         /* Disable the MI INT ( external phy int )
5403          * by writing 1 to the status register. Link down indication
5404          * is high-active-signal, so in this case we need to write the
5405          * status to clear the XOR
5406          */
5407         /* Read Latched signals */
5408         latch_status = REG_RD(bp,
5409                                   NIG_REG_LATCH_STATUS_0 + port*8);
5410         is_mi_int_status = REG_RD(bp,
5411                                   NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
5412         DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
5413                      "latch_status = 0x%x\n",
5414                  is_mi_int, is_mi_int_status, latch_status);
5415         /* Handle only those with latched-signal=up.*/
5416         if (latch_status & 1) {
5417                 /* For all latched-signal=up,Write original_signal to status */
5418                 if (is_mi_int)
5419                         bnx2x_bits_en(bp,
5420                                     NIG_REG_STATUS_INTERRUPT_PORT0
5421                                     + port*4,
5422                                     NIG_STATUS_EMAC0_MI_INT);
5423                 else
5424                         bnx2x_bits_dis(bp,
5425                                      NIG_REG_STATUS_INTERRUPT_PORT0
5426                                      + port*4,
5427                                      NIG_STATUS_EMAC0_MI_INT);
5428                 /* For all latched-signal=up : Re-Arm Latch signals */
5429                 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
5430                            (latch_status & 0xfffe) | (latch_status & 1));
5431         }
5432 }
5433 /*
5434  * link management
5435  */
5436 static void bnx2x_link_int_ack(struct link_params *params,
5437                              struct link_vars *vars, u8 is_10g,
5438                              u8 is_mi_int)
5439 {
5440         struct bnx2x *bp = params->bp;
5441         u8 port = params->port;
5442
5443         /* first reset all status
5444          * we assume only one line will be change at a time */
5445         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5446                      (NIG_STATUS_XGXS0_LINK10G |
5447                       NIG_STATUS_XGXS0_LINK_STATUS |
5448                       NIG_STATUS_SERDES0_LINK_STATUS));
5449         if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config)
5450                 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
5451         (XGXS_EXT_PHY_TYPE(params->ext_phy_config)
5452                 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) {
5453                 bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
5454         }
5455         if (vars->phy_link_up) {
5456                 if (is_10g) {
5457                         /* Disable the 10G link interrupt
5458                          * by writing 1 to the status register
5459                          */
5460                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
5461                         bnx2x_bits_en(bp,
5462                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5463                                       NIG_STATUS_XGXS0_LINK10G);
5464
5465                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
5466                         /* Disable the link interrupt
5467                          * by writing 1 to the relevant lane
5468                          * in the status register
5469                          */
5470                         u32 ser_lane = ((params->lane_config &
5471                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5472                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5473
5474                         DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
5475                                  vars->line_speed);
5476                         bnx2x_bits_en(bp,
5477                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5478                                       ((1 << ser_lane) <<
5479                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
5480
5481                 } else { /* SerDes */
5482                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
5483                         /* Disable the link interrupt
5484                          * by writing 1 to the status register
5485                          */
5486                         bnx2x_bits_en(bp,
5487                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5488                                       NIG_STATUS_SERDES0_LINK_STATUS);
5489                 }
5490
5491         } else { /* link_down */
5492         }
5493 }
5494
5495 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
5496 {
5497         u8 *str_ptr = str;
5498         u32 mask = 0xf0000000;
5499         u8 shift = 8*4;
5500         u8 digit;
5501         if (len < 10) {
5502                 /* Need more than 10chars for this format */
5503                 *str_ptr = '\0';
5504                 return -EINVAL;
5505         }
5506         while (shift > 0) {
5507
5508                 shift -= 4;
5509                 digit = ((num & mask) >> shift);
5510                 if (digit < 0xa)
5511                         *str_ptr = digit + '0';
5512                 else
5513                         *str_ptr = digit - 0xa + 'a';
5514                 str_ptr++;
5515                 mask = mask >> 4;
5516                 if (shift == 4*4) {
5517                         *str_ptr = ':';
5518                         str_ptr++;
5519                 }
5520         }
5521         *str_ptr = '\0';
5522         return 0;
5523 }
5524
5525 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
5526                               u8 *version, u16 len)
5527 {
5528         struct bnx2x *bp;
5529         u32 ext_phy_type = 0;
5530         u32 spirom_ver = 0;
5531         u8 status;
5532
5533         if (version == NULL || params == NULL)
5534                 return -EINVAL;
5535         bp = params->bp;
5536
5537         spirom_ver = REG_RD(bp, params->shmem_base +
5538                    offsetof(struct shmem_region,
5539                             port_mb[params->port].ext_phy_fw_version));
5540
5541         status = 0;
5542         /* reset the returned value to zero */
5543         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5544         switch (ext_phy_type) {
5545         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5546
5547                 if (len < 5)
5548                         return -EINVAL;
5549
5550                 version[0] = (spirom_ver & 0xFF);
5551                 version[1] = (spirom_ver & 0xFF00) >> 8;
5552                 version[2] = (spirom_ver & 0xFF0000) >> 16;
5553                 version[3] = (spirom_ver & 0xFF000000) >> 24;
5554                 version[4] = '\0';
5555
5556                 break;
5557         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5558         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5559         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
5560         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5561         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5562                 status = bnx2x_format_ver(spirom_ver, version, len);
5563                 break;
5564         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5565         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
5566                 spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 |
5567                         (spirom_ver & 0x7F);
5568                 status = bnx2x_format_ver(spirom_ver, version, len);
5569                 break;
5570         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5571         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5572                 version[0] = '\0';
5573                 break;
5574
5575         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5576                 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
5577                                     " type is FAILURE!\n");
5578                 status = -EINVAL;
5579                 break;
5580
5581         default:
5582                 break;
5583         }
5584         return status;
5585 }
5586
5587 static void bnx2x_set_xgxs_loopback(struct link_params *params,
5588                                   struct link_vars *vars,
5589                                   u8 is_10g)
5590 {
5591         u8 port = params->port;
5592         struct bnx2x *bp = params->bp;
5593
5594         if (is_10g) {
5595                 u32 md_devad;
5596
5597                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
5598
5599                 /* change the uni_phy_addr in the nig */
5600                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
5601                                           port*0x18));
5602
5603                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
5604
5605                 bnx2x_cl45_write(bp, port, 0,
5606                                params->phy_addr,
5607                                5,
5608                                (MDIO_REG_BANK_AER_BLOCK +
5609                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
5610                                0x2800);
5611
5612                 bnx2x_cl45_write(bp, port, 0,
5613                                params->phy_addr,
5614                                5,
5615                                (MDIO_REG_BANK_CL73_IEEEB0 +
5616                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5617                                0x6041);
5618                 msleep(200);
5619                 /* set aer mmd back */
5620                 bnx2x_set_aer_mmd(params, vars);
5621
5622                 /* and md_devad */
5623                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5624                             md_devad);
5625
5626         } else {
5627                 u16 mii_control;
5628
5629                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
5630
5631                 CL45_RD_OVER_CL22(bp, port,
5632                                       params->phy_addr,
5633                                       MDIO_REG_BANK_COMBO_IEEE0,
5634                                       MDIO_COMBO_IEEE0_MII_CONTROL,
5635                                       &mii_control);
5636
5637                 CL45_WR_OVER_CL22(bp, port,
5638                                       params->phy_addr,
5639                                       MDIO_REG_BANK_COMBO_IEEE0,
5640                                       MDIO_COMBO_IEEE0_MII_CONTROL,
5641                                       (mii_control |
5642                                        MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
5643         }
5644 }
5645
5646
5647 static void bnx2x_ext_phy_loopback(struct link_params *params)
5648 {
5649         struct bnx2x *bp = params->bp;
5650         u8 ext_phy_addr;
5651         u32 ext_phy_type;
5652
5653         if (params->switch_cfg == SWITCH_CFG_10G) {
5654                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5655                 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
5656                 /* CL37 Autoneg Enabled */
5657                 switch (ext_phy_type) {
5658                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5659                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5660                         DP(NETIF_MSG_LINK,
5661                                 "ext_phy_loopback: We should not get here\n");
5662                         break;
5663                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5664                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
5665                         break;
5666                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5667                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
5668                         break;
5669                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5670                         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
5671                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
5672                                        ext_phy_addr,
5673                                        MDIO_PMA_DEVAD,
5674                                        MDIO_PMA_REG_CTRL,
5675                                        0x0001);
5676                         break;
5677                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5678                         /* SFX7101_XGXS_TEST1 */
5679                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
5680                                        ext_phy_addr,
5681                                        MDIO_XS_DEVAD,
5682                                        MDIO_XS_SFX7101_XGXS_TEST1,
5683                                        0x100);
5684                         DP(NETIF_MSG_LINK,
5685                                 "ext_phy_loopback: set ext phy loopback\n");
5686                         break;
5687                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5688
5689                         break;
5690                 } /* switch external PHY type */
5691         } else {
5692                 /* serdes */
5693                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5694                 ext_phy_addr = (params->ext_phy_config  &
5695                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
5696                 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
5697         }
5698 }
5699
5700
5701 /*
5702  *------------------------------------------------------------------------
5703  * bnx2x_override_led_value -
5704  *
5705  * Override the led value of the requsted led
5706  *
5707  *------------------------------------------------------------------------
5708  */
5709 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
5710                           u32 led_idx, u32 value)
5711 {
5712         u32 reg_val;
5713
5714         /* If port 0 then use EMAC0, else use EMAC1*/
5715         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5716
5717         DP(NETIF_MSG_LINK,
5718                  "bnx2x_override_led_value() port %x led_idx %d value %d\n",
5719                  port, led_idx, value);
5720
5721         switch (led_idx) {
5722         case 0: /* 10MB led */
5723                 /* Read the current value of the LED register in
5724                 the EMAC block */
5725                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5726                 /* Set the OVERRIDE bit to 1 */
5727                 reg_val |= EMAC_LED_OVERRIDE;
5728                 /* If value is 1, set the 10M_OVERRIDE bit,
5729                 otherwise reset it.*/
5730                 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
5731                         (reg_val & ~EMAC_LED_10MB_OVERRIDE);
5732                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5733                 break;
5734         case 1: /*100MB led    */
5735                 /*Read the current value of the LED register in
5736                 the EMAC block */
5737                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5738                 /*  Set the OVERRIDE bit to 1 */
5739                 reg_val |= EMAC_LED_OVERRIDE;
5740                 /*  If value is 1, set the 100M_OVERRIDE bit,
5741                 otherwise reset it.*/
5742                 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
5743                         (reg_val & ~EMAC_LED_100MB_OVERRIDE);
5744                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5745                 break;
5746         case 2: /* 1000MB led */
5747                 /* Read the current value of the LED register in the
5748                 EMAC block */
5749                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5750                 /* Set the OVERRIDE bit to 1 */
5751                 reg_val |= EMAC_LED_OVERRIDE;
5752                 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
5753                 reset it. */
5754                 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
5755                         (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
5756                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5757                 break;
5758         case 3: /* 2500MB led */
5759                 /*  Read the current value of the LED register in the
5760                 EMAC block*/
5761                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5762                 /* Set the OVERRIDE bit to 1 */
5763                 reg_val |= EMAC_LED_OVERRIDE;
5764                 /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
5765                 reset it.*/
5766                 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
5767                         (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
5768                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5769                 break;
5770         case 4: /*10G led */
5771                 if (port == 0) {
5772                         REG_WR(bp, NIG_REG_LED_10G_P0,
5773                                     value);
5774                 } else {
5775                         REG_WR(bp, NIG_REG_LED_10G_P1,
5776                                     value);
5777                 }
5778                 break;
5779         case 5: /* TRAFFIC led */
5780                 /* Find if the traffic control is via BMAC or EMAC */
5781                 if (port == 0)
5782                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
5783                 else
5784                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
5785
5786                 /*  Override the traffic led in the EMAC:*/
5787                 if (reg_val == 1) {
5788                         /* Read the current value of the LED register in
5789                         the EMAC block */
5790                         reg_val = REG_RD(bp, emac_base +
5791                                              EMAC_REG_EMAC_LED);
5792                         /* Set the TRAFFIC_OVERRIDE bit to 1 */
5793                         reg_val |= EMAC_LED_OVERRIDE;
5794                         /* If value is 1, set the TRAFFIC bit, otherwise
5795                         reset it.*/
5796                         reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
5797                                 (reg_val & ~EMAC_LED_TRAFFIC);
5798                         REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5799                 } else { /* Override the traffic led in the BMAC: */
5800                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5801                                    + port*4, 1);
5802                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
5803                                     value);
5804                 }
5805                 break;
5806         default:
5807                 DP(NETIF_MSG_LINK,
5808                          "bnx2x_override_led_value() unknown led index %d "
5809                          "(should be 0-5)\n", led_idx);
5810                 return -EINVAL;
5811         }
5812
5813         return 0;
5814 }
5815
5816
5817 u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed)
5818 {
5819         u8 port = params->port;
5820         u16 hw_led_mode = params->hw_led_mode;
5821         u8 rc = 0;
5822         u32 tmp;
5823         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5824         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5825         struct bnx2x *bp = params->bp;
5826         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5827         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5828                  speed, hw_led_mode);
5829         switch (mode) {
5830         case LED_MODE_OFF:
5831                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
5832                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5833                            SHARED_HW_CFG_LED_MAC1);
5834
5835                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5836                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
5837                 break;
5838
5839         case LED_MODE_OPER:
5840                 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5841                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
5842                         REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
5843                 } else {
5844                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5845                                    hw_led_mode);
5846                 }
5847
5848                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
5849                            port*4, 0);
5850                 /* Set blinking rate to ~15.9Hz */
5851                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
5852                            LED_BLINK_RATE_VAL);
5853                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
5854                            port*4, 1);
5855                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5856                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
5857                             (tmp & (~EMAC_LED_OVERRIDE)));
5858
5859                 if (CHIP_IS_E1(bp) &&
5860                     ((speed == SPEED_2500) ||
5861                      (speed == SPEED_1000) ||
5862                      (speed == SPEED_100) ||
5863                      (speed == SPEED_10))) {
5864                         /* On Everest 1 Ax chip versions for speeds less than
5865                         10G LED scheme is different */
5866                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5867                                    + port*4, 1);
5868                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
5869                                    port*4, 0);
5870                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
5871                                    port*4, 1);
5872                 }
5873                 break;
5874
5875         default:
5876                 rc = -EINVAL;
5877                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
5878                          mode);
5879                 break;
5880         }
5881         return rc;
5882
5883 }
5884
5885 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
5886 {
5887         struct bnx2x *bp = params->bp;
5888         u16 gp_status = 0;
5889
5890         CL45_RD_OVER_CL22(bp, params->port,
5891                               params->phy_addr,
5892                               MDIO_REG_BANK_GP_STATUS,
5893                               MDIO_GP_STATUS_TOP_AN_STATUS1,
5894                               &gp_status);
5895         /* link is up only if both local phy and external phy are up */
5896         if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
5897             bnx2x_ext_phy_is_link_up(params, vars, 1))
5898                 return 0;
5899
5900         return -ESRCH;
5901 }
5902
5903 static u8 bnx2x_link_initialize(struct link_params *params,
5904                               struct link_vars *vars)
5905 {
5906         struct bnx2x *bp = params->bp;
5907         u8 port = params->port;
5908         u8 rc = 0;
5909         u8 non_ext_phy;
5910         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5911
5912         /* Activate the external PHY */
5913         bnx2x_ext_phy_reset(params, vars);
5914
5915         bnx2x_set_aer_mmd(params, vars);
5916
5917         if (vars->phy_flags & PHY_XGXS_FLAG)
5918                 bnx2x_set_master_ln(params);
5919
5920         rc = bnx2x_reset_unicore(params);
5921         /* reset the SerDes and wait for reset bit return low */
5922         if (rc != 0)
5923                 return rc;
5924
5925         bnx2x_set_aer_mmd(params, vars);
5926
5927         /* setting the masterLn_def again after the reset */
5928         if (vars->phy_flags & PHY_XGXS_FLAG) {
5929                 bnx2x_set_master_ln(params);
5930                 bnx2x_set_swap_lanes(params);
5931         }
5932
5933         if (vars->phy_flags & PHY_XGXS_FLAG) {
5934                 if ((params->req_line_speed &&
5935                     ((params->req_line_speed == SPEED_100) ||
5936                      (params->req_line_speed == SPEED_10))) ||
5937                     (!params->req_line_speed &&
5938                      (params->speed_cap_mask >=
5939                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5940                      (params->speed_cap_mask <
5941                        PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5942                      ))  {
5943                         vars->phy_flags |= PHY_SGMII_FLAG;
5944                 } else {
5945                         vars->phy_flags &= ~PHY_SGMII_FLAG;
5946                 }
5947         }
5948         /* In case of external phy existance, the line speed would be the
5949          line speed linked up by the external phy. In case it is direct only,
5950           then the line_speed during initialization will be equal to the
5951            req_line_speed*/
5952         vars->line_speed = params->req_line_speed;
5953
5954         bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
5955
5956         /* init ext phy and enable link state int */
5957         non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
5958                        (params->loopback_mode == LOOPBACK_XGXS_10));
5959
5960         if (non_ext_phy ||
5961             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
5962             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
5963             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
5964             (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5965                 if (params->req_line_speed == SPEED_AUTO_NEG)
5966                         bnx2x_set_parallel_detection(params, vars->phy_flags);
5967                 bnx2x_init_internal_phy(params, vars, non_ext_phy);
5968         }
5969
5970         if (!non_ext_phy)
5971                 rc |= bnx2x_ext_phy_init(params, vars);
5972
5973         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5974                      (NIG_STATUS_XGXS0_LINK10G |
5975                       NIG_STATUS_XGXS0_LINK_STATUS |
5976                       NIG_STATUS_SERDES0_LINK_STATUS));
5977
5978         return rc;
5979
5980 }
5981
5982
5983 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
5984 {
5985         struct bnx2x *bp = params->bp;
5986         u32 val;
5987
5988         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
5989         DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
5990                  params->req_line_speed, params->req_flow_ctrl);
5991         vars->link_status = 0;
5992         vars->phy_link_up = 0;
5993         vars->link_up = 0;
5994         vars->line_speed = 0;
5995         vars->duplex = DUPLEX_FULL;
5996         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5997         vars->mac_type = MAC_TYPE_NONE;
5998
5999         if (params->switch_cfg ==  SWITCH_CFG_1G)
6000                 vars->phy_flags = PHY_SERDES_FLAG;
6001         else
6002                 vars->phy_flags = PHY_XGXS_FLAG;
6003
6004         /* disable attentions */
6005         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
6006                        (NIG_MASK_XGXS0_LINK_STATUS |
6007                         NIG_MASK_XGXS0_LINK10G |
6008                         NIG_MASK_SERDES0_LINK_STATUS |
6009                         NIG_MASK_MI_INT));
6010
6011         bnx2x_emac_init(params, vars);
6012
6013         if (CHIP_REV_IS_FPGA(bp)) {
6014
6015                 vars->link_up = 1;
6016                 vars->line_speed = SPEED_10000;
6017                 vars->duplex = DUPLEX_FULL;
6018                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6019                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6020                 /* enable on E1.5 FPGA */
6021                 if (CHIP_IS_E1H(bp)) {
6022                         vars->flow_ctrl |=
6023                                         (BNX2X_FLOW_CTRL_TX |
6024                                          BNX2X_FLOW_CTRL_RX);
6025                         vars->link_status |=
6026                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
6027                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
6028                 }
6029
6030                 bnx2x_emac_enable(params, vars, 0);
6031                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6032                 /* disable drain */
6033                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
6034
6035                 /* update shared memory */
6036                 bnx2x_update_mng(params, vars->link_status);
6037
6038                 return 0;
6039
6040         } else
6041         if (CHIP_REV_IS_EMUL(bp)) {
6042
6043                 vars->link_up = 1;
6044                 vars->line_speed = SPEED_10000;
6045                 vars->duplex = DUPLEX_FULL;
6046                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6047                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6048
6049                 bnx2x_bmac_enable(params, vars, 0);
6050
6051                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6052                 /* Disable drain */
6053                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
6054                                     + params->port*4, 0);
6055
6056                 /* update shared memory */
6057                 bnx2x_update_mng(params, vars->link_status);
6058
6059                 return 0;
6060
6061         } else
6062         if (params->loopback_mode == LOOPBACK_BMAC) {
6063
6064                 vars->link_up = 1;
6065                 vars->line_speed = SPEED_10000;
6066                 vars->duplex = DUPLEX_FULL;
6067                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6068                 vars->mac_type = MAC_TYPE_BMAC;
6069
6070                 vars->phy_flags = PHY_XGXS_FLAG;
6071
6072                 bnx2x_phy_deassert(params, vars->phy_flags);
6073                 /* set bmac loopback */
6074                 bnx2x_bmac_enable(params, vars, 1);
6075
6076                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6077                     params->port*4, 0);
6078
6079         } else if (params->loopback_mode == LOOPBACK_EMAC) {
6080
6081                 vars->link_up = 1;
6082                 vars->line_speed = SPEED_1000;
6083                 vars->duplex = DUPLEX_FULL;
6084                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6085                 vars->mac_type = MAC_TYPE_EMAC;
6086
6087                 vars->phy_flags = PHY_XGXS_FLAG;
6088
6089                 bnx2x_phy_deassert(params, vars->phy_flags);
6090                 /* set bmac loopback */
6091                 bnx2x_emac_enable(params, vars, 1);
6092                 bnx2x_emac_program(params, vars->line_speed,
6093                                               vars->duplex);
6094                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6095                     params->port*4, 0);
6096
6097         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
6098                    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6099
6100                 vars->link_up = 1;
6101                 vars->line_speed = SPEED_10000;
6102                 vars->duplex = DUPLEX_FULL;
6103                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6104
6105                 vars->phy_flags = PHY_XGXS_FLAG;
6106
6107                 val = REG_RD(bp,
6108                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
6109                                  params->port*0x18);
6110                 params->phy_addr = (u8)val;
6111
6112                 bnx2x_phy_deassert(params, vars->phy_flags);
6113                 bnx2x_link_initialize(params, vars);
6114
6115                 vars->mac_type = MAC_TYPE_BMAC;
6116
6117                 bnx2x_bmac_enable(params, vars, 0);
6118
6119                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
6120                         /* set 10G XGXS loopback */
6121                         bnx2x_set_xgxs_loopback(params, vars, 1);
6122                 } else {
6123                         /* set external phy loopback */
6124                         bnx2x_ext_phy_loopback(params);
6125                 }
6126                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6127                             params->port*4, 0);
6128
6129                 bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed);
6130         } else
6131         /* No loopback */
6132         {
6133                 bnx2x_phy_deassert(params, vars->phy_flags);
6134                 switch (params->switch_cfg) {
6135                 case SWITCH_CFG_1G:
6136                         vars->phy_flags |= PHY_SERDES_FLAG;
6137                         if ((params->ext_phy_config &
6138                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
6139                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
6140                                 vars->phy_flags |= PHY_SGMII_FLAG;
6141                         }
6142
6143                         val = REG_RD(bp,
6144                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
6145                                          params->port*0x10);
6146
6147                         params->phy_addr = (u8)val;
6148
6149                         break;
6150                 case SWITCH_CFG_10G:
6151                         vars->phy_flags |= PHY_XGXS_FLAG;
6152                         val = REG_RD(bp,
6153                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
6154                                  params->port*0x18);
6155                         params->phy_addr = (u8)val;
6156
6157                         break;
6158                 default:
6159                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
6160                         return -EINVAL;
6161                 }
6162                 DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
6163
6164                 bnx2x_link_initialize(params, vars);
6165                 msleep(30);
6166                 bnx2x_link_int_enable(params);
6167         }
6168         return 0;
6169 }
6170
6171 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
6172 {
6173         DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
6174
6175         /* Set serial boot control for external load */
6176         bnx2x_cl45_write(bp, port,
6177                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
6178                        MDIO_PMA_DEVAD,
6179                        MDIO_PMA_REG_GEN_CTRL, 0x0001);
6180 }
6181
6182 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6183                   u8 reset_ext_phy)
6184 {
6185         struct bnx2x *bp = params->bp;
6186         u32 ext_phy_config = params->ext_phy_config;
6187         u8 port = params->port;
6188         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6189         u32 val = REG_RD(bp, params->shmem_base +
6190                              offsetof(struct shmem_region, dev_info.
6191                                       port_feature_config[params->port].
6192                                       config));
6193         DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
6194         /* disable attentions */
6195         vars->link_status = 0;
6196         bnx2x_update_mng(params, vars->link_status);
6197         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6198                      (NIG_MASK_XGXS0_LINK_STATUS |
6199                       NIG_MASK_XGXS0_LINK10G |
6200                       NIG_MASK_SERDES0_LINK_STATUS |
6201                       NIG_MASK_MI_INT));
6202
6203         /* activate nig drain */
6204         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6205
6206         /* disable nig egress interface */
6207         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6208         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6209
6210         /* Stop BigMac rx */
6211         bnx2x_bmac_rx_disable(bp, port);
6212
6213         /* disable emac */
6214         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6215
6216         msleep(10);
6217         /* The PHY reset is controled by GPIO 1
6218          * Hold it as vars low
6219          */
6220          /* clear link led */
6221         bnx2x_set_led(params, LED_MODE_OFF, 0);
6222         if (reset_ext_phy) {
6223                 switch (ext_phy_type) {
6224                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
6225                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
6226                         break;
6227
6228                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6229                 {
6230
6231                         /* Disable Transmitter */
6232                         u8 ext_phy_addr =
6233                                 XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6234                         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
6235                             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
6236                                 bnx2x_sfp_set_transmitter(bp, port,
6237                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6238                                         ext_phy_addr, 0);
6239                         break;
6240                 }
6241                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6242                         DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
6243                                  "low power mode\n",
6244                                  port);
6245                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6246                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6247                                           port);
6248                         break;
6249                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6250                 {
6251                         u8 ext_phy_addr =
6252                                 XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6253                         /* Set soft reset */
6254                         bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
6255                         break;
6256                 }
6257                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
6258                 {
6259                         u8 ext_phy_addr =
6260                                 XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6261                         bnx2x_cl45_write(bp, port,
6262                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6263                                        ext_phy_addr,
6264                                        MDIO_AN_DEVAD,
6265                                        MDIO_AN_REG_CTRL, 0x0000);
6266                         bnx2x_cl45_write(bp, port,
6267                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6268                                        ext_phy_addr,
6269                                        MDIO_PMA_DEVAD,
6270                                        MDIO_PMA_REG_CTRL, 1);
6271                         break;
6272                 }
6273                 default:
6274                         /* HW reset */
6275                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6276                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6277                                           port);
6278                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6279                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6280                                           port);
6281                         DP(NETIF_MSG_LINK, "reset external PHY\n");
6282                 }
6283         }
6284         /* reset the SerDes/XGXS */
6285         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6286                (0x1ff << (port*16)));
6287
6288         /* reset BigMac */
6289         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
6290                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6291
6292         /* disable nig ingress interface */
6293         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
6294         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
6295         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6296         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6297         vars->link_up = 0;
6298         return 0;
6299 }
6300
6301 static u8 bnx2x_update_link_down(struct link_params *params,
6302                                struct link_vars *vars)
6303 {
6304         struct bnx2x *bp = params->bp;
6305         u8 port = params->port;
6306
6307         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
6308         bnx2x_set_led(params, LED_MODE_OFF, 0);
6309
6310         /* indicate no mac active */
6311         vars->mac_type = MAC_TYPE_NONE;
6312
6313         /* update shared memory */
6314         vars->link_status = 0;
6315         vars->line_speed = 0;
6316         bnx2x_update_mng(params, vars->link_status);
6317
6318         /* activate nig drain */
6319         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6320
6321         /* disable emac */
6322         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6323
6324         msleep(10);
6325
6326         /* reset BigMac */
6327         bnx2x_bmac_rx_disable(bp, params->port);
6328         REG_WR(bp, GRCBASE_MISC +
6329                    MISC_REGISTERS_RESET_REG_2_CLEAR,
6330                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6331         return 0;
6332 }
6333
6334 static u8 bnx2x_update_link_up(struct link_params *params,
6335                              struct link_vars *vars,
6336                              u8 link_10g, u32 gp_status)
6337 {
6338         struct bnx2x *bp = params->bp;
6339         u8 port = params->port;
6340         u8 rc = 0;
6341
6342         vars->link_status |= LINK_STATUS_LINK_UP;
6343         if (link_10g) {
6344                 bnx2x_bmac_enable(params, vars, 0);
6345                 bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000);
6346         } else {
6347                 bnx2x_emac_enable(params, vars, 0);
6348                 rc = bnx2x_emac_program(params, vars->line_speed,
6349                                       vars->duplex);
6350
6351                 /* AN complete? */
6352                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
6353                         if (!(vars->phy_flags &
6354                               PHY_SGMII_FLAG))
6355                                 bnx2x_set_gmii_tx_driver(params);
6356                 }
6357         }
6358
6359         /* PBF - link up */
6360         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6361                               vars->line_speed);
6362
6363         /* disable drain */
6364         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6365
6366         /* update shared memory */
6367         bnx2x_update_mng(params, vars->link_status);
6368         msleep(20);
6369         return rc;
6370 }
6371 /* This function should called upon link interrupt */
6372 /* In case vars->link_up, driver needs to
6373         1. Update the pbf
6374         2. Disable drain
6375         3. Update the shared memory
6376         4. Indicate link up
6377         5. Set LEDs
6378    Otherwise,
6379         1. Update shared memory
6380         2. Reset BigMac
6381         3. Report link down
6382         4. Unset LEDs
6383 */
6384 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6385 {
6386         struct bnx2x *bp = params->bp;
6387         u8 port = params->port;
6388         u16 gp_status;
6389         u8 link_10g;
6390         u8 ext_phy_link_up, rc = 0;
6391         u32 ext_phy_type;
6392         u8 is_mi_int = 0;
6393
6394         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6395                  port, (vars->phy_flags & PHY_XGXS_FLAG),
6396                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6397
6398         is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6399                                     port*0x18) > 0);
6400         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6401                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6402                  is_mi_int,
6403                  REG_RD(bp,
6404                             NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6405
6406         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6407           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6408           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6409
6410         /* disable emac */
6411         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6412
6413         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
6414
6415         /* Check external link change only for non-direct */
6416         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int);
6417
6418         /* Read gp_status */
6419         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
6420                               MDIO_REG_BANK_GP_STATUS,
6421                               MDIO_GP_STATUS_TOP_AN_STATUS1,
6422                               &gp_status);
6423
6424         rc = bnx2x_link_settings_status(params, vars, gp_status,
6425                                       ext_phy_link_up);
6426         if (rc != 0)
6427                 return rc;
6428
6429         /* anything 10 and over uses the bmac */
6430         link_10g = ((vars->line_speed == SPEED_10000) ||
6431                     (vars->line_speed == SPEED_12000) ||
6432                     (vars->line_speed == SPEED_12500) ||
6433                     (vars->line_speed == SPEED_13000) ||
6434                     (vars->line_speed == SPEED_15000) ||
6435                     (vars->line_speed == SPEED_16000));
6436
6437         bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
6438
6439         /* In case external phy link is up, and internal link is down
6440         ( not initialized yet probably after link initialization, it needs
6441         to be initialized.
6442         Note that after link down-up as result of cable plug,
6443         the xgxs link would probably become up again without the need to
6444         initialize it*/
6445
6446         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
6447             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
6448             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) &&
6449             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
6450             (ext_phy_link_up && !vars->phy_link_up))
6451                 bnx2x_init_internal_phy(params, vars, 0);
6452
6453         /* link is up only if both local phy and external phy are up */
6454         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
6455
6456         if (vars->link_up)
6457                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
6458         else
6459                 rc = bnx2x_update_link_down(params, vars);
6460
6461         return rc;
6462 }
6463
6464 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6465 {
6466         u8 ext_phy_addr[PORT_MAX];
6467         u16 val;
6468         s8 port;
6469
6470         /* PART1 - Reset both phys */
6471         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6472                 /* Extract the ext phy address for the port */
6473                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6474                                         offsetof(struct shmem_region,
6475                    dev_info.port_hw_config[port].external_phy_config));
6476
6477                 /* disable attentions */
6478                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6479                              (NIG_MASK_XGXS0_LINK_STATUS |
6480                               NIG_MASK_XGXS0_LINK10G |
6481                               NIG_MASK_SERDES0_LINK_STATUS |
6482                               NIG_MASK_MI_INT));
6483
6484                 ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
6485
6486                 /* Need to take the phy out of low power mode in order
6487                         to write to access its registers */
6488                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6489                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6490
6491                 /* Reset the phy */
6492                 bnx2x_cl45_write(bp, port,
6493                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6494                                ext_phy_addr[port],
6495                                MDIO_PMA_DEVAD,
6496                                MDIO_PMA_REG_CTRL,
6497                                1<<15);
6498         }
6499
6500         /* Add delay of 150ms after reset */
6501         msleep(150);
6502
6503         /* PART2 - Download firmware to both phys */
6504         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6505                 u16 fw_ver1;
6506
6507                 bnx2x_bcm8073_external_rom_boot(bp, port,
6508                                               ext_phy_addr[port], shmem_base);
6509
6510                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6511                               ext_phy_addr[port],
6512                               MDIO_PMA_DEVAD,
6513                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6514                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6515                         DP(NETIF_MSG_LINK,
6516                                  "bnx2x_8073_common_init_phy port %x:"
6517                                  "Download failed. fw version = 0x%x\n",
6518                                  port, fw_ver1);
6519                         return -EINVAL;
6520                 }
6521
6522                 /* Only set bit 10 = 1 (Tx power down) */
6523                 bnx2x_cl45_read(bp, port,
6524                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6525                               ext_phy_addr[port],
6526                               MDIO_PMA_DEVAD,
6527                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
6528
6529                 /* Phase1 of TX_POWER_DOWN reset */
6530                 bnx2x_cl45_write(bp, port,
6531                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6532                                ext_phy_addr[port],
6533                                MDIO_PMA_DEVAD,
6534                                MDIO_PMA_REG_TX_POWER_DOWN,
6535                                (val | 1<<10));
6536         }
6537
6538         /* Toggle Transmitter: Power down and then up with 600ms
6539            delay between */
6540         msleep(600);
6541
6542         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
6543         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6544                 /* Phase2 of POWER_DOWN_RESET */
6545                 /* Release bit 10 (Release Tx power down) */
6546                 bnx2x_cl45_read(bp, port,
6547                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6548                               ext_phy_addr[port],
6549                               MDIO_PMA_DEVAD,
6550                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
6551
6552                 bnx2x_cl45_write(bp, port,
6553                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6554                                ext_phy_addr[port],
6555                                MDIO_PMA_DEVAD,
6556                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
6557                 msleep(15);
6558
6559                 /* Read modify write the SPI-ROM version select register */
6560                 bnx2x_cl45_read(bp, port,
6561                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6562                               ext_phy_addr[port],
6563                               MDIO_PMA_DEVAD,
6564                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
6565                 bnx2x_cl45_write(bp, port,
6566                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6567                               ext_phy_addr[port],
6568                               MDIO_PMA_DEVAD,
6569                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
6570
6571                 /* set GPIO2 back to LOW */
6572                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6573                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6574         }
6575         return 0;
6576
6577 }
6578
6579 static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6580 {
6581         u8 ext_phy_addr[PORT_MAX];
6582         s8 port, first_port, i;
6583         u32 swap_val, swap_override;
6584         DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
6585         swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
6586         swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
6587
6588         bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override));
6589         msleep(5);
6590
6591         if (swap_val && swap_override)
6592                 first_port = PORT_0;
6593         else
6594                 first_port = PORT_1;
6595
6596         /* PART1 - Reset both phys */
6597         for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
6598                 /* Extract the ext phy address for the port */
6599                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6600                                         offsetof(struct shmem_region,
6601                    dev_info.port_hw_config[port].external_phy_config));
6602
6603                 /* disable attentions */
6604                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6605                              (NIG_MASK_XGXS0_LINK_STATUS |
6606                               NIG_MASK_XGXS0_LINK10G |
6607                               NIG_MASK_SERDES0_LINK_STATUS |
6608                               NIG_MASK_MI_INT));
6609
6610                 ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
6611
6612                 /* Reset the phy */
6613                 bnx2x_cl45_write(bp, port,
6614                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6615                                ext_phy_addr[port],
6616                                MDIO_PMA_DEVAD,
6617                                MDIO_PMA_REG_CTRL,
6618                                1<<15);
6619         }
6620
6621         /* Add delay of 150ms after reset */
6622         msleep(150);
6623
6624         /* PART2 - Download firmware to both phys */
6625         for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
6626                 u16 fw_ver1;
6627
6628                 bnx2x_bcm8727_external_rom_boot(bp, port,
6629                                               ext_phy_addr[port], shmem_base);
6630
6631                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6632                               ext_phy_addr[port],
6633                               MDIO_PMA_DEVAD,
6634                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6635                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6636                         DP(NETIF_MSG_LINK,
6637                                  "bnx2x_8727_common_init_phy port %x:"
6638                                  "Download failed. fw version = 0x%x\n",
6639                                  port, fw_ver1);
6640                         return -EINVAL;
6641                 }
6642         }
6643
6644         return 0;
6645 }
6646
6647
6648 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6649 {
6650         u8 ext_phy_addr;
6651         u32 val;
6652         s8 port;
6653
6654         /* Use port1 because of the static port-swap */
6655         /* Enable the module detection interrupt */
6656         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
6657         val |= ((1<<MISC_REGISTERS_GPIO_3)|
6658                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
6659         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
6660
6661         bnx2x_ext_phy_hw_reset(bp, 1);
6662         msleep(5);
6663         for (port = 0; port < PORT_MAX; port++) {
6664                 /* Extract the ext phy address for the port */
6665                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6666                                         offsetof(struct shmem_region,
6667                         dev_info.port_hw_config[port].external_phy_config));
6668
6669                 ext_phy_addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
6670                 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
6671                          ext_phy_addr);
6672
6673                 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
6674
6675                 /* Set fault module detected LED on */
6676                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6677                                   MISC_REGISTERS_GPIO_HIGH,
6678                                   port);
6679         }
6680
6681         return 0;
6682 }
6683
6684
6685 static u8 bnx2x_84823_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6686 {
6687         /* HW reset */
6688         bnx2x_ext_phy_hw_reset(bp, 1);
6689         return 0;
6690 }
6691 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6692 {
6693         u8 rc = 0;
6694         u32 ext_phy_type;
6695
6696         DP(NETIF_MSG_LINK, "Begin common phy init\n");
6697
6698         /* Read the ext_phy_type for arbitrary port(0) */
6699         ext_phy_type = XGXS_EXT_PHY_TYPE(
6700                         REG_RD(bp, shmem_base +
6701                            offsetof(struct shmem_region,
6702                              dev_info.port_hw_config[0].external_phy_config)));
6703
6704         switch (ext_phy_type) {
6705         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6706         {
6707                 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
6708                 break;
6709         }
6710
6711         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6712         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6713                 rc = bnx2x_8727_common_init_phy(bp, shmem_base);
6714                 break;
6715
6716         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6717                 /* GPIO1 affects both ports, so there's need to pull
6718                 it for single port alone */
6719                 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
6720                 break;
6721         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
6722                 rc = bnx2x_84823_common_init_phy(bp, shmem_base);
6723                 break;
6724         default:
6725                 DP(NETIF_MSG_LINK,
6726                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
6727                          ext_phy_type);
6728                 break;
6729         }
6730
6731         return rc;
6732 }
6733
6734 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
6735 {
6736         u16 val, cnt;
6737
6738         bnx2x_cl45_read(bp, port,
6739                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6740                       phy_addr,
6741                       MDIO_PMA_DEVAD,
6742                       MDIO_PMA_REG_7101_RESET, &val);
6743
6744         for (cnt = 0; cnt < 10; cnt++) {
6745                 msleep(50);
6746                 /* Writes a self-clearing reset */
6747                 bnx2x_cl45_write(bp, port,
6748                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6749                                phy_addr,
6750                                MDIO_PMA_DEVAD,
6751                                MDIO_PMA_REG_7101_RESET,
6752                                (val | (1<<15)));
6753                 /* Wait for clear */
6754                 bnx2x_cl45_read(bp, port,
6755                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6756                               phy_addr,
6757                               MDIO_PMA_DEVAD,
6758                               MDIO_PMA_REG_7101_RESET, &val);
6759
6760                 if ((val & (1<<15)) == 0)
6761                         break;
6762         }
6763 }