fsl_pq_mdio: Fix iomem unmapping for non-eTSEC2.0 controllers
[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) | (1<<7)); /* Clear bits 0,2,7*/
3537         val1 |= ((1<<1) | (1<<6)); /* Set bit 1, 6 */
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         /* Unmask LED3 for 10G link */
3572         bnx2x_cl45_write(bp, params->port,
3573                        ext_phy_type,
3574                        ext_phy_addr,
3575                        MDIO_PMA_DEVAD,
3576                       MDIO_PMA_REG_8481_LED3_MASK,
3577                        0x6);
3578         bnx2x_cl45_write(bp, params->port,
3579                        ext_phy_type,
3580                        ext_phy_addr,
3581                        MDIO_PMA_DEVAD,
3582                        MDIO_PMA_REG_8481_LED3_BLINK,
3583                        0);
3584 }
3585
3586
3587 static void bnx2x_init_internal_phy(struct link_params *params,
3588                                   struct link_vars *vars,
3589                                   u8 enable_cl73)
3590 {
3591         struct bnx2x *bp = params->bp;
3592
3593         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
3594                 if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
3595                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3596                     (params->feature_config_flags &
3597                      FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
3598                         bnx2x_set_preemphasis(params);
3599
3600                 /* forced speed requested? */
3601                 if (vars->line_speed != SPEED_AUTO_NEG ||
3602                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
3603                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3604                           params->loopback_mode == LOOPBACK_EXT)) {
3605                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3606
3607                         /* disable autoneg */
3608                         bnx2x_set_autoneg(params, vars, 0);
3609
3610                         /* program speed and duplex */
3611                         bnx2x_program_serdes(params, vars);
3612
3613                 } else { /* AN_mode */
3614                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
3615
3616                         /* AN enabled */
3617                         bnx2x_set_brcm_cl37_advertisment(params);
3618
3619                         /* program duplex & pause advertisement (for aneg) */
3620                         bnx2x_set_ieee_aneg_advertisment(params,
3621                                                        vars->ieee_fc);
3622
3623                         /* enable autoneg */
3624                         bnx2x_set_autoneg(params, vars, enable_cl73);
3625
3626                         /* enable and restart AN */
3627                         bnx2x_restart_autoneg(params, enable_cl73);
3628                 }
3629
3630         } else { /* SGMII mode */
3631                 DP(NETIF_MSG_LINK, "SGMII\n");
3632
3633                 bnx2x_initialize_sgmii_process(params, vars);
3634         }
3635 }
3636
3637 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
3638 {
3639         struct bnx2x *bp = params->bp;
3640         u32 ext_phy_type;
3641         u8 ext_phy_addr;
3642         u16 cnt;
3643         u16 ctrl = 0;
3644         u16 val = 0;
3645         u8 rc = 0;
3646
3647         if (vars->phy_flags & PHY_XGXS_FLAG) {
3648                 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3649
3650                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3651                 /* Make sure that the soft reset is off (expect for the 8072:
3652                  * due to the lock, it will be done inside the specific
3653                  * handling)
3654                  */
3655                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3656                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3657                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
3658                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3659                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3660                         /* Wait for soft reset to get cleared upto 1 sec */
3661                         for (cnt = 0; cnt < 1000; cnt++) {
3662                                 bnx2x_cl45_read(bp, params->port,
3663                                               ext_phy_type,
3664                                               ext_phy_addr,
3665                                               MDIO_PMA_DEVAD,
3666                                               MDIO_PMA_REG_CTRL, &ctrl);
3667                                 if (!(ctrl & (1<<15)))
3668                                         break;
3669                                 msleep(1);
3670                         }
3671                         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3672                                  ctrl, cnt);
3673                 }
3674
3675                 switch (ext_phy_type) {
3676                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3677                         break;
3678
3679                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3680                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
3681
3682                         bnx2x_cl45_write(bp, params->port,
3683                                        ext_phy_type,
3684                                        ext_phy_addr,
3685                                        MDIO_PMA_DEVAD,
3686                                        MDIO_PMA_REG_MISC_CTRL,
3687                                        0x8288);
3688                         bnx2x_cl45_write(bp, params->port,
3689                                        ext_phy_type,
3690                                        ext_phy_addr,
3691                                        MDIO_PMA_DEVAD,
3692                                        MDIO_PMA_REG_PHY_IDENTIFIER,
3693                                        0x7fbf);
3694                         bnx2x_cl45_write(bp, params->port,
3695                                        ext_phy_type,
3696                                        ext_phy_addr,
3697                                        MDIO_PMA_DEVAD,
3698                                        MDIO_PMA_REG_CMU_PLL_BYPASS,
3699                                        0x0100);
3700                         bnx2x_cl45_write(bp, params->port,
3701                                        ext_phy_type,
3702                                        ext_phy_addr,
3703                                        MDIO_WIS_DEVAD,
3704                                        MDIO_WIS_REG_LASI_CNTL, 0x1);
3705
3706                         /* BCM8705 doesn't have microcode, hence the 0 */
3707                         bnx2x_save_spirom_version(bp, params->port,
3708                                                 params->shmem_base, 0);
3709                         break;
3710
3711                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3712                         /* Wait until fw is loaded */
3713                         for (cnt = 0; cnt < 100; cnt++) {
3714                                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3715                                               ext_phy_addr, MDIO_PMA_DEVAD,
3716                                               MDIO_PMA_REG_ROM_VER1, &val);
3717                                 if (val)
3718                                         break;
3719                                 msleep(10);
3720                         }
3721                         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3722                                 "after %d ms\n", cnt);
3723                         if ((params->feature_config_flags &
3724                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3725                                 u8 i;
3726                                 u16 reg;
3727                                 for (i = 0; i < 4; i++) {
3728                                         reg = MDIO_XS_8706_REG_BANK_RX0 +
3729                                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
3730                                                    MDIO_XS_8706_REG_BANK_RX0);
3731                                         bnx2x_cl45_read(bp, params->port,
3732                                                       ext_phy_type,
3733                                                       ext_phy_addr,
3734                                                       MDIO_XS_DEVAD,
3735                                                       reg, &val);
3736                                         /* Clear first 3 bits of the control */
3737                                         val &= ~0x7;
3738                                         /* Set control bits according to
3739                                         configuation */
3740                                         val |= (params->xgxs_config_rx[i] &
3741                                                 0x7);
3742                                         DP(NETIF_MSG_LINK, "Setting RX"
3743                                                  "Equalizer to BCM8706 reg 0x%x"
3744                                                  " <-- val 0x%x\n", reg, val);
3745                                         bnx2x_cl45_write(bp, params->port,
3746                                                        ext_phy_type,
3747                                                        ext_phy_addr,
3748                                                        MDIO_XS_DEVAD,
3749                                                        reg, val);
3750                                 }
3751                         }
3752                         /* Force speed */
3753                         if (params->req_line_speed == SPEED_10000) {
3754                                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3755
3756                                 bnx2x_cl45_write(bp, params->port,
3757                                                ext_phy_type,
3758                                                ext_phy_addr,
3759                                                MDIO_PMA_DEVAD,
3760                                                MDIO_PMA_REG_DIGITAL_CTRL,
3761                                                0x400);
3762                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3763                                                ext_phy_addr, MDIO_PMA_DEVAD,
3764                                                MDIO_PMA_REG_LASI_CTRL, 1);
3765                         } else {
3766                                 /* Force 1Gbps using autoneg with 1G
3767                                 advertisment */
3768
3769                                 /* Allow CL37 through CL73 */
3770                                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3771                                 bnx2x_cl45_write(bp, params->port,
3772                                                ext_phy_type,
3773                                                ext_phy_addr,
3774                                                MDIO_AN_DEVAD,
3775                                                MDIO_AN_REG_CL37_CL73,
3776                                                0x040c);
3777
3778                                 /* Enable Full-Duplex advertisment on CL37 */
3779                                 bnx2x_cl45_write(bp, params->port,
3780                                                ext_phy_type,
3781                                                ext_phy_addr,
3782                                                MDIO_AN_DEVAD,
3783                                                MDIO_AN_REG_CL37_FC_LP,
3784                                                0x0020);
3785                                 /* Enable CL37 AN */
3786                                 bnx2x_cl45_write(bp, params->port,
3787                                                ext_phy_type,
3788                                                ext_phy_addr,
3789                                                MDIO_AN_DEVAD,
3790                                                MDIO_AN_REG_CL37_AN,
3791                                                0x1000);
3792                                 /* 1G support */
3793                                 bnx2x_cl45_write(bp, params->port,
3794                                                ext_phy_type,
3795                                                ext_phy_addr,
3796                                                MDIO_AN_DEVAD,
3797                                                MDIO_AN_REG_ADV, (1<<5));
3798
3799                                 /* Enable clause 73 AN */
3800                                 bnx2x_cl45_write(bp, params->port,
3801                                                ext_phy_type,
3802                                                ext_phy_addr,
3803                                                MDIO_AN_DEVAD,
3804                                                MDIO_AN_REG_CTRL,
3805                                                0x1200);
3806                                 bnx2x_cl45_write(bp, params->port,
3807                                                ext_phy_type,
3808                                                ext_phy_addr,
3809                                                MDIO_PMA_DEVAD,
3810                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3811                                                0x0400);
3812                                 bnx2x_cl45_write(bp, params->port,
3813                                                ext_phy_type,
3814                                                ext_phy_addr,
3815                                                MDIO_PMA_DEVAD,
3816                                                MDIO_PMA_REG_LASI_CTRL, 0x0004);
3817
3818                         }
3819                         bnx2x_save_bcm_spirom_ver(bp, params->port,
3820                                                 ext_phy_type,
3821                                                 ext_phy_addr,
3822                                                 params->shmem_base);
3823                         break;
3824                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3825                         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3826                         bnx2x_bcm8726_external_rom_boot(params);
3827
3828                         /* Need to call module detected on initialization since
3829                         the module detection triggered by actual module
3830                         insertion might occur before driver is loaded, and when
3831                         driver is loaded, it reset all registers, including the
3832                         transmitter */
3833                         bnx2x_sfp_module_detection(params);
3834
3835                         /* Set Flow control */
3836                         bnx2x_ext_phy_set_pause(params, vars);
3837                         if (params->req_line_speed == SPEED_1000) {
3838                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3839                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3840                                                ext_phy_addr, MDIO_PMA_DEVAD,
3841                                                MDIO_PMA_REG_CTRL, 0x40);
3842                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3843                                                ext_phy_addr, MDIO_PMA_DEVAD,
3844                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
3845                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3846                                                ext_phy_addr, MDIO_PMA_DEVAD,
3847                                                MDIO_PMA_REG_LASI_CTRL, 0x5);
3848                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3849                                                ext_phy_addr, MDIO_PMA_DEVAD,
3850                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3851                                                0x400);
3852                         } else if ((params->req_line_speed ==
3853                                     SPEED_AUTO_NEG) &&
3854                                    ((params->speed_cap_mask &
3855                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3856                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3857                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3858                                                ext_phy_addr, MDIO_AN_DEVAD,
3859                                                MDIO_AN_REG_ADV, 0x20);
3860                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3861                                                ext_phy_addr, MDIO_AN_DEVAD,
3862                                                MDIO_AN_REG_CL37_CL73, 0x040c);
3863                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3864                                                ext_phy_addr, MDIO_AN_DEVAD,
3865                                                MDIO_AN_REG_CL37_FC_LD, 0x0020);
3866                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3867                                                ext_phy_addr, MDIO_AN_DEVAD,
3868                                                MDIO_AN_REG_CL37_AN, 0x1000);
3869                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3870                                                ext_phy_addr, MDIO_AN_DEVAD,
3871                                                MDIO_AN_REG_CTRL, 0x1200);
3872
3873                                 /* Enable RX-ALARM control to receive
3874                                 interrupt for 1G speed change */
3875                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3876                                                ext_phy_addr, MDIO_PMA_DEVAD,
3877                                                MDIO_PMA_REG_LASI_CTRL, 0x4);
3878                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3879                                                ext_phy_addr, MDIO_PMA_DEVAD,
3880                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3881                                                0x400);
3882
3883                         } else { /* Default 10G. Set only LASI control */
3884                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3885                                                ext_phy_addr, MDIO_PMA_DEVAD,
3886                                                MDIO_PMA_REG_LASI_CTRL, 1);
3887                         }
3888
3889                         /* Set TX PreEmphasis if needed */
3890                         if ((params->feature_config_flags &
3891                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3892                                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3893                                          "TX_CTRL2 0x%x\n",
3894                                          params->xgxs_config_tx[0],
3895                                          params->xgxs_config_tx[1]);
3896                                 bnx2x_cl45_write(bp, params->port,
3897                                                ext_phy_type,
3898                                                ext_phy_addr,
3899                                                MDIO_PMA_DEVAD,
3900                                                MDIO_PMA_REG_8726_TX_CTRL1,
3901                                                params->xgxs_config_tx[0]);
3902
3903                                 bnx2x_cl45_write(bp, params->port,
3904                                                ext_phy_type,
3905                                                ext_phy_addr,
3906                                                MDIO_PMA_DEVAD,
3907                                                MDIO_PMA_REG_8726_TX_CTRL2,
3908                                                params->xgxs_config_tx[1]);
3909                         }
3910                         break;
3911                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3912                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3913                 {
3914                         u16 tmp1;
3915                         u16 rx_alarm_ctrl_val;
3916                         u16 lasi_ctrl_val;
3917                         if (ext_phy_type ==
3918                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3919                                 rx_alarm_ctrl_val = 0x400;
3920                                 lasi_ctrl_val = 0x0004;
3921                         } else {
3922                                 rx_alarm_ctrl_val = (1<<2);
3923                                 lasi_ctrl_val = 0x0004;
3924                         }
3925
3926                         /* enable LASI */
3927                         bnx2x_cl45_write(bp, params->port,
3928                                    ext_phy_type,
3929                                    ext_phy_addr,
3930                                    MDIO_PMA_DEVAD,
3931                                    MDIO_PMA_REG_RX_ALARM_CTRL,
3932                                    rx_alarm_ctrl_val);
3933
3934                         bnx2x_cl45_write(bp, params->port,
3935                                        ext_phy_type,
3936                                        ext_phy_addr,
3937                                        MDIO_PMA_DEVAD,
3938                                        MDIO_PMA_REG_LASI_CTRL,
3939                                        lasi_ctrl_val);
3940
3941                         bnx2x_8073_set_pause_cl37(params, vars);
3942
3943                         if (ext_phy_type ==
3944                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)
3945                                 bnx2x_bcm8072_external_rom_boot(params);
3946                         else
3947                                 /* In case of 8073 with long xaui lines,
3948                                 don't set the 8073 xaui low power*/
3949                                 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3950
3951                         bnx2x_cl45_read(bp, params->port,
3952                                       ext_phy_type,
3953                                       ext_phy_addr,
3954                                       MDIO_PMA_DEVAD,
3955                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
3956                                       &tmp1);
3957
3958                         bnx2x_cl45_read(bp, params->port,
3959                                       ext_phy_type,
3960                                       ext_phy_addr,
3961                                       MDIO_PMA_DEVAD,
3962                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
3963
3964                         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3965                                              "0x%x\n", tmp1);
3966
3967                         /* If this is forced speed, set to KR or KX
3968                          * (all other are not supported)
3969                          */
3970                         if (params->loopback_mode == LOOPBACK_EXT) {
3971                                 bnx2x_bcm807x_force_10G(params);
3972                                 DP(NETIF_MSG_LINK,
3973                                         "Forced speed 10G on 807X\n");
3974                                 break;
3975                         } else {
3976                                 bnx2x_cl45_write(bp, params->port,
3977                                                ext_phy_type, ext_phy_addr,
3978                                                MDIO_PMA_DEVAD,
3979                                                MDIO_PMA_REG_BCM_CTRL,
3980                                                0x0002);
3981                         }
3982                         if (params->req_line_speed != SPEED_AUTO_NEG) {
3983                                 if (params->req_line_speed == SPEED_10000) {
3984                                         val = (1<<7);
3985                                 } else if (params->req_line_speed ==
3986                                            SPEED_2500) {
3987                                         val = (1<<5);
3988                                         /* Note that 2.5G works only
3989                                         when used with 1G advertisment */
3990                                 } else
3991                                         val = (1<<5);
3992                         } else {
3993
3994                                 val = 0;
3995                                 if (params->speed_cap_mask &
3996                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3997                                         val |= (1<<7);
3998
3999                                 /* Note that 2.5G works only when
4000                                 used with 1G advertisment */
4001                                 if (params->speed_cap_mask &
4002                                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
4003                                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
4004                                         val |= (1<<5);
4005                                 DP(NETIF_MSG_LINK,
4006                                          "807x autoneg val = 0x%x\n", val);
4007                         }
4008
4009                         bnx2x_cl45_write(bp, params->port,
4010                                        ext_phy_type,
4011                                        ext_phy_addr,
4012                                        MDIO_AN_DEVAD,
4013                                        MDIO_AN_REG_ADV, val);
4014                         if (ext_phy_type ==
4015                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4016                                 bnx2x_cl45_read(bp, params->port,
4017                                               ext_phy_type,
4018                                               ext_phy_addr,
4019                                               MDIO_AN_DEVAD,
4020                                               MDIO_AN_REG_8073_2_5G, &tmp1);
4021
4022                                 if (((params->speed_cap_mask &
4023                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
4024                                      (params->req_line_speed ==
4025                                       SPEED_AUTO_NEG)) ||
4026                                     (params->req_line_speed ==
4027                                      SPEED_2500)) {
4028                                         u16 phy_ver;
4029                                         /* Allow 2.5G for A1 and above */
4030                                         bnx2x_cl45_read(bp, params->port,
4031                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4032                                          ext_phy_addr,
4033                                          MDIO_PMA_DEVAD,
4034                                          MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
4035                                         DP(NETIF_MSG_LINK, "Add 2.5G\n");
4036                                         if (phy_ver > 0)
4037                                                 tmp1 |= 1;
4038                                         else
4039                                                 tmp1 &= 0xfffe;
4040                                 } else {
4041                                         DP(NETIF_MSG_LINK, "Disable 2.5G\n");
4042                                         tmp1 &= 0xfffe;
4043                                 }
4044
4045                                 bnx2x_cl45_write(bp, params->port,
4046                                                ext_phy_type,
4047                                                ext_phy_addr,
4048                                                MDIO_AN_DEVAD,
4049                                                MDIO_AN_REG_8073_2_5G, tmp1);
4050                         }
4051
4052                         /* Add support for CL37 (passive mode) II */
4053
4054                         bnx2x_cl45_read(bp, params->port,
4055                                        ext_phy_type,
4056                                        ext_phy_addr,
4057                                        MDIO_AN_DEVAD,
4058                                        MDIO_AN_REG_CL37_FC_LD,
4059                                        &tmp1);
4060
4061                         bnx2x_cl45_write(bp, params->port,
4062                                        ext_phy_type,
4063                                        ext_phy_addr,
4064                                        MDIO_AN_DEVAD,
4065                                        MDIO_AN_REG_CL37_FC_LD, (tmp1 |
4066                                        ((params->req_duplex == DUPLEX_FULL) ?
4067                                        0x20 : 0x40)));
4068
4069                         /* Add support for CL37 (passive mode) III */
4070                         bnx2x_cl45_write(bp, params->port,
4071                                        ext_phy_type,
4072                                        ext_phy_addr,
4073                                        MDIO_AN_DEVAD,
4074                                        MDIO_AN_REG_CL37_AN, 0x1000);
4075
4076                         if (ext_phy_type ==
4077                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4078                                 /* The SNR will improve about 2db by changing
4079                                 BW and FEE main tap. Rest commands are executed
4080                                 after link is up*/
4081                                 /*Change FFE main cursor to 5 in EDC register*/
4082                                 if (bnx2x_8073_is_snr_needed(params))
4083                                         bnx2x_cl45_write(bp, params->port,
4084                                                     ext_phy_type,
4085                                                     ext_phy_addr,
4086                                                     MDIO_PMA_DEVAD,
4087                                                     MDIO_PMA_REG_EDC_FFE_MAIN,
4088                                                     0xFB0C);
4089
4090                                 /* Enable FEC (Forware Error Correction)
4091                                 Request in the AN */
4092                                 bnx2x_cl45_read(bp, params->port,
4093                                               ext_phy_type,
4094                                               ext_phy_addr,
4095                                               MDIO_AN_DEVAD,
4096                                               MDIO_AN_REG_ADV2, &tmp1);
4097
4098                                 tmp1 |= (1<<15);
4099
4100                                 bnx2x_cl45_write(bp, params->port,
4101                                                ext_phy_type,
4102                                                ext_phy_addr,
4103                                                MDIO_AN_DEVAD,
4104                                                MDIO_AN_REG_ADV2, tmp1);
4105
4106                         }
4107
4108                         bnx2x_ext_phy_set_pause(params, vars);
4109
4110                         /* Restart autoneg */
4111                         msleep(500);
4112                         bnx2x_cl45_write(bp, params->port,
4113                                        ext_phy_type,
4114                                        ext_phy_addr,
4115                                        MDIO_AN_DEVAD,
4116                                        MDIO_AN_REG_CTRL, 0x1200);
4117                         DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
4118                            "Advertise 1G=%x, 10G=%x\n",
4119                            ((val & (1<<5)) > 0),
4120                            ((val & (1<<7)) > 0));
4121                         break;
4122                 }
4123
4124                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4125                 {
4126                         u16 tmp1;
4127                         u16 rx_alarm_ctrl_val;
4128                         u16 lasi_ctrl_val;
4129
4130                         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
4131
4132                         u16 mod_abs;
4133                         rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
4134                         lasi_ctrl_val = 0x0004;
4135
4136                         DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
4137                         /* enable LASI */
4138                         bnx2x_cl45_write(bp, params->port,
4139                                        ext_phy_type,
4140                                        ext_phy_addr,
4141                                        MDIO_PMA_DEVAD,
4142                                        MDIO_PMA_REG_RX_ALARM_CTRL,
4143                                        rx_alarm_ctrl_val);
4144
4145                         bnx2x_cl45_write(bp, params->port,
4146                                        ext_phy_type,
4147                                        ext_phy_addr,
4148                                        MDIO_PMA_DEVAD,
4149                                        MDIO_PMA_REG_LASI_CTRL,
4150                                        lasi_ctrl_val);
4151
4152                         /* Initially configure  MOD_ABS to interrupt when
4153                         module is presence( bit 8) */
4154                         bnx2x_cl45_read(bp, params->port,
4155                                       ext_phy_type,
4156                                       ext_phy_addr,
4157                                       MDIO_PMA_DEVAD,
4158                                       MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4159                         /* Set EDC off by setting OPTXLOS signal input to low
4160                         (bit 9).
4161                         When the EDC is off it locks onto a reference clock and
4162                         avoids becoming 'lost'.*/
4163                         mod_abs &= ~((1<<8) | (1<<9));
4164                         bnx2x_cl45_write(bp, params->port,
4165                                        ext_phy_type,
4166                                        ext_phy_addr,
4167                                        MDIO_PMA_DEVAD,
4168                                        MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4169
4170                         /* Make MOD_ABS give interrupt on change */
4171                         bnx2x_cl45_read(bp, params->port,
4172                                       ext_phy_type,
4173                                       ext_phy_addr,
4174                                       MDIO_PMA_DEVAD,
4175                                       MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4176                                       &val);
4177                         val |= (1<<12);
4178                         bnx2x_cl45_write(bp, params->port,
4179                                        ext_phy_type,
4180                                        ext_phy_addr,
4181                                        MDIO_PMA_DEVAD,
4182                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4183                                        val);
4184
4185                         /* Set 8727 GPIOs to input to allow reading from the
4186                         8727 GPIO0 status which reflect SFP+ module
4187                         over-current */
4188
4189                         bnx2x_cl45_read(bp, params->port,
4190                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4191                                        ext_phy_addr,
4192                                        MDIO_PMA_DEVAD,
4193                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4194                                        &val);
4195                         val &= 0xff8f; /* Reset bits 4-6 */
4196                         bnx2x_cl45_write(bp, params->port,
4197                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4198                                        ext_phy_addr,
4199                                        MDIO_PMA_DEVAD,
4200                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4201                                        val);
4202
4203                         bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
4204                         bnx2x_bcm8073_set_xaui_low_power_mode(params);
4205
4206                         bnx2x_cl45_read(bp, params->port,
4207                                       ext_phy_type,
4208                                       ext_phy_addr,
4209                                       MDIO_PMA_DEVAD,
4210                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
4211                                       &tmp1);
4212
4213                         bnx2x_cl45_read(bp, params->port,
4214                                       ext_phy_type,
4215                                       ext_phy_addr,
4216                                       MDIO_PMA_DEVAD,
4217                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
4218
4219                         /* Set option 1G speed */
4220                         if (params->req_line_speed == SPEED_1000) {
4221
4222                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
4223                                 bnx2x_cl45_write(bp, params->port,
4224                                                ext_phy_type,
4225                                                ext_phy_addr,
4226                                                MDIO_PMA_DEVAD,
4227                                                MDIO_PMA_REG_CTRL, 0x40);
4228                                 bnx2x_cl45_write(bp, params->port,
4229                                                ext_phy_type,
4230                                                ext_phy_addr,
4231                                                MDIO_PMA_DEVAD,
4232                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
4233                                 bnx2x_cl45_read(bp, params->port,
4234                                       ext_phy_type,
4235                                       ext_phy_addr,
4236                                       MDIO_PMA_DEVAD,
4237                                       MDIO_PMA_REG_10G_CTRL2, &tmp1);
4238                                 DP(NETIF_MSG_LINK, "1.7 = 0x%x \n", tmp1);
4239
4240                         } else if ((params->req_line_speed ==
4241                                     SPEED_AUTO_NEG) &&
4242                                    ((params->speed_cap_mask &
4243                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
4244
4245                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
4246                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4247                                                ext_phy_addr, MDIO_AN_DEVAD,
4248                                                MDIO_PMA_REG_8727_MISC_CTRL, 0);
4249                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4250                                                ext_phy_addr, MDIO_AN_DEVAD,
4251                                                MDIO_AN_REG_CL37_AN, 0x1300);
4252                         } else {
4253                                 /* Since the 8727 has only single reset pin,
4254                                 need to set the 10G registers although it is
4255                                 default */
4256                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4257                                                ext_phy_addr, MDIO_AN_DEVAD,
4258                                                MDIO_AN_REG_CTRL, 0x0020);
4259                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4260                                                ext_phy_addr, MDIO_AN_DEVAD,
4261                                                0x7, 0x0100);
4262                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4263                                                ext_phy_addr, MDIO_PMA_DEVAD,
4264                                                MDIO_PMA_REG_CTRL, 0x2040);
4265                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4266                                                ext_phy_addr, MDIO_PMA_DEVAD,
4267                                                MDIO_PMA_REG_10G_CTRL2, 0x0008);
4268                         }
4269
4270                         /* Set 2-wire transfer rate to 400Khz since 100Khz
4271                         is not operational */
4272                         bnx2x_cl45_write(bp, params->port,
4273                                        ext_phy_type,
4274                                        ext_phy_addr,
4275                                        MDIO_PMA_DEVAD,
4276                                        MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
4277                                        0xa101);
4278
4279                         /* Set TX PreEmphasis if needed */
4280                         if ((params->feature_config_flags &
4281                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
4282                                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
4283                                          "TX_CTRL2 0x%x\n",
4284                                          params->xgxs_config_tx[0],
4285                                          params->xgxs_config_tx[1]);
4286                                 bnx2x_cl45_write(bp, params->port,
4287                                                ext_phy_type,
4288                                                ext_phy_addr,
4289                                                MDIO_PMA_DEVAD,
4290                                                MDIO_PMA_REG_8727_TX_CTRL1,
4291                                                params->xgxs_config_tx[0]);
4292
4293                                 bnx2x_cl45_write(bp, params->port,
4294                                                ext_phy_type,
4295                                                ext_phy_addr,
4296                                                MDIO_PMA_DEVAD,
4297                                                MDIO_PMA_REG_8727_TX_CTRL2,
4298                                                params->xgxs_config_tx[1]);
4299                         }
4300
4301                         break;
4302                 }
4303
4304                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4305                 {
4306                         u16 fw_ver1, fw_ver2;
4307                         DP(NETIF_MSG_LINK,
4308                                 "Setting the SFX7101 LASI indication\n");
4309
4310                         bnx2x_cl45_write(bp, params->port,
4311                                        ext_phy_type,
4312                                        ext_phy_addr,
4313                                        MDIO_PMA_DEVAD,
4314                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
4315                         DP(NETIF_MSG_LINK,
4316                           "Setting the SFX7101 LED to blink on traffic\n");
4317                         bnx2x_cl45_write(bp, params->port,
4318                                        ext_phy_type,
4319                                        ext_phy_addr,
4320                                        MDIO_PMA_DEVAD,
4321                                        MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
4322
4323                         bnx2x_ext_phy_set_pause(params, vars);
4324                         /* Restart autoneg */
4325                         bnx2x_cl45_read(bp, params->port,
4326                                       ext_phy_type,
4327                                       ext_phy_addr,
4328                                       MDIO_AN_DEVAD,
4329                                       MDIO_AN_REG_CTRL, &val);
4330                         val |= 0x200;
4331                         bnx2x_cl45_write(bp, params->port,
4332                                        ext_phy_type,
4333                                        ext_phy_addr,
4334                                        MDIO_AN_DEVAD,
4335                                        MDIO_AN_REG_CTRL, val);
4336
4337                         /* Save spirom version */
4338                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4339                                       ext_phy_addr, MDIO_PMA_DEVAD,
4340                                       MDIO_PMA_REG_7101_VER1, &fw_ver1);
4341
4342                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4343                                       ext_phy_addr, MDIO_PMA_DEVAD,
4344                                       MDIO_PMA_REG_7101_VER2, &fw_ver2);
4345
4346                         bnx2x_save_spirom_version(params->bp, params->port,
4347                                                 params->shmem_base,
4348                                                 (u32)(fw_ver1<<16 | fw_ver2));
4349                         break;
4350                 }
4351                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
4352                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
4353                         /* This phy uses the NIG latch mechanism since link
4354                                 indication arrives through its LED4 and not via
4355                                 its LASI signal, so we get steady signal
4356                                 instead of clear on read */
4357                         bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
4358                                     1 << NIG_LATCH_BC_ENABLE_MI_INT);
4359
4360                         bnx2x_cl45_write(bp, params->port,
4361                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
4362                                        ext_phy_addr,
4363                                        MDIO_PMA_DEVAD,
4364                                        MDIO_PMA_REG_CTRL, 0x0000);
4365
4366                         bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
4367                         if (params->req_line_speed == SPEED_AUTO_NEG) {
4368
4369                                 u16 autoneg_val, an_1000_val, an_10_100_val;
4370                                 /* set 1000 speed advertisement */
4371                                 bnx2x_cl45_read(bp, params->port,
4372                                               ext_phy_type,
4373                                               ext_phy_addr,
4374                                               MDIO_AN_DEVAD,
4375                                               MDIO_AN_REG_8481_1000T_CTRL,
4376                                               &an_1000_val);
4377
4378                                 if (params->speed_cap_mask &
4379                                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
4380                                         an_1000_val |= (1<<8);
4381                                         if (params->req_duplex == DUPLEX_FULL)
4382                                                 an_1000_val |= (1<<9);
4383                                         DP(NETIF_MSG_LINK, "Advertising 1G\n");
4384                                 } else
4385                                         an_1000_val &= ~((1<<8) | (1<<9));
4386
4387                                 bnx2x_cl45_write(bp, params->port,
4388                                                ext_phy_type,
4389                                                ext_phy_addr,
4390                                                MDIO_AN_DEVAD,
4391                                                MDIO_AN_REG_8481_1000T_CTRL,
4392                                                an_1000_val);
4393
4394                                 /* set 100 speed advertisement */
4395                                 bnx2x_cl45_read(bp, params->port,
4396                                               ext_phy_type,
4397                                               ext_phy_addr,
4398                                               MDIO_AN_DEVAD,
4399                                               MDIO_AN_REG_8481_LEGACY_AN_ADV,
4400                                               &an_10_100_val);
4401
4402                                 if (params->speed_cap_mask &
4403                                  (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
4404                                   PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) {
4405                                         an_10_100_val |= (1<<7);
4406                                         if (params->req_duplex == DUPLEX_FULL)
4407                                                 an_10_100_val |= (1<<8);
4408                                         DP(NETIF_MSG_LINK,
4409                                                 "Advertising 100M\n");
4410                                 } else
4411                                         an_10_100_val &= ~((1<<7) | (1<<8));
4412
4413                                 /* set 10 speed advertisement */
4414                                 if (params->speed_cap_mask &
4415                                   (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
4416                                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) {
4417                                         an_10_100_val |= (1<<5);
4418                                         if (params->req_duplex == DUPLEX_FULL)
4419                                                 an_10_100_val |= (1<<6);
4420                                         DP(NETIF_MSG_LINK, "Advertising 10M\n");
4421                                      }
4422                                 else
4423                                         an_10_100_val &= ~((1<<5) | (1<<6));
4424
4425                                 bnx2x_cl45_write(bp, params->port,
4426                                                ext_phy_type,
4427                                                ext_phy_addr,
4428                                                MDIO_AN_DEVAD,
4429                                                MDIO_AN_REG_8481_LEGACY_AN_ADV,
4430                                                an_10_100_val);
4431
4432                                 bnx2x_cl45_read(bp, params->port,
4433                                               ext_phy_type,
4434                                               ext_phy_addr,
4435                                               MDIO_AN_DEVAD,
4436                                               MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4437                                               &autoneg_val);
4438
4439                                 /* Disable forced speed */
4440                                 autoneg_val &= ~(1<<6|1<<13);
4441
4442                                 /* Enable autoneg and restart autoneg
4443                                 for legacy speeds */
4444                                 autoneg_val |= (1<<9|1<<12);
4445
4446                                 if (params->req_duplex == DUPLEX_FULL)
4447                                         autoneg_val |= (1<<8);
4448                                 else
4449                                         autoneg_val &= ~(1<<8);
4450
4451                                 bnx2x_cl45_write(bp, params->port,
4452                                                ext_phy_type,
4453                                                ext_phy_addr,
4454                                                MDIO_AN_DEVAD,
4455                                                MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4456                                                autoneg_val);
4457
4458                                 if (params->speed_cap_mask &
4459                                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
4460                                         DP(NETIF_MSG_LINK, "Advertising 10G\n");
4461                                         /* Restart autoneg for 10G*/
4462
4463                         bnx2x_cl45_write(bp, params->port,
4464                                        ext_phy_type,
4465                                        ext_phy_addr,
4466                                        MDIO_AN_DEVAD,
4467                                        MDIO_AN_REG_CTRL, 0x3200);
4468                                 }
4469                         } else {
4470                                 /* Force speed */
4471                                 u16 autoneg_ctrl, pma_ctrl;
4472                                 bnx2x_cl45_read(bp, params->port,
4473                                               ext_phy_type,
4474                                               ext_phy_addr,
4475                                               MDIO_AN_DEVAD,
4476                                               MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4477                                               &autoneg_ctrl);
4478
4479                                 /* Disable autoneg */
4480                                 autoneg_ctrl &= ~(1<<12);
4481
4482                                 /* Set 1000 force */
4483                                 switch (params->req_line_speed) {
4484                                 case SPEED_10000:
4485                                         DP(NETIF_MSG_LINK,
4486                                                 "Unable to set 10G force !\n");
4487                                         break;
4488                                 case SPEED_1000:
4489                                         bnx2x_cl45_read(bp, params->port,
4490                                                       ext_phy_type,
4491                                                       ext_phy_addr,
4492                                                       MDIO_PMA_DEVAD,
4493                                                       MDIO_PMA_REG_CTRL,
4494                                                       &pma_ctrl);
4495                                         autoneg_ctrl &= ~(1<<13);
4496                                         autoneg_ctrl |= (1<<6);
4497                                         pma_ctrl &= ~(1<<13);
4498                                         pma_ctrl |= (1<<6);
4499                                         DP(NETIF_MSG_LINK,
4500                                                 "Setting 1000M force\n");
4501                                         bnx2x_cl45_write(bp, params->port,
4502                                                        ext_phy_type,
4503                                                        ext_phy_addr,
4504                                                        MDIO_PMA_DEVAD,
4505                                                        MDIO_PMA_REG_CTRL,
4506                                                        pma_ctrl);
4507                                         break;
4508                                 case SPEED_100:
4509                                         autoneg_ctrl |= (1<<13);
4510                                         autoneg_ctrl &= ~(1<<6);
4511                                         DP(NETIF_MSG_LINK,
4512                                                 "Setting 100M force\n");
4513                                         break;
4514                                 case SPEED_10:
4515                                         autoneg_ctrl &= ~(1<<13);
4516                                         autoneg_ctrl &= ~(1<<6);
4517                                         DP(NETIF_MSG_LINK,
4518                                                 "Setting 10M force\n");
4519                                         break;
4520                                 }
4521
4522                                 /* Duplex mode */
4523                                 if (params->req_duplex == DUPLEX_FULL) {
4524                                         autoneg_ctrl |= (1<<8);
4525                                         DP(NETIF_MSG_LINK,
4526                                                 "Setting full duplex\n");
4527                                 } else
4528                                         autoneg_ctrl &= ~(1<<8);
4529
4530                                 /* Update autoneg ctrl and pma ctrl */
4531                                 bnx2x_cl45_write(bp, params->port,
4532                                                ext_phy_type,
4533                                                ext_phy_addr,
4534                                                MDIO_AN_DEVAD,
4535                                                MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4536                                                autoneg_ctrl);
4537                         }
4538
4539                         /* Save spirom version */
4540                         bnx2x_save_8481_spirom_version(bp, params->port,
4541                                                      ext_phy_addr,
4542                                                      params->shmem_base);
4543                         break;
4544                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4545                         DP(NETIF_MSG_LINK,
4546                                  "XGXS PHY Failure detected 0x%x\n",
4547                                  params->ext_phy_config);
4548                         rc = -EINVAL;
4549                         break;
4550                 default:
4551                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
4552                                   params->ext_phy_config);
4553                         rc = -EINVAL;
4554                         break;
4555                 }
4556
4557         } else { /* SerDes */
4558
4559                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4560                 switch (ext_phy_type) {
4561                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
4562                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
4563                         break;
4564
4565                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
4566                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
4567                         break;
4568
4569                 default:
4570                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
4571                            params->ext_phy_config);
4572                         break;
4573                 }
4574         }
4575         return rc;
4576 }
4577
4578 static void bnx2x_8727_handle_mod_abs(struct link_params *params)
4579 {
4580         struct bnx2x *bp = params->bp;
4581         u16 mod_abs, rx_alarm_status;
4582         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
4583         u32 val = REG_RD(bp, params->shmem_base +
4584                              offsetof(struct shmem_region, dev_info.
4585                                       port_feature_config[params->port].
4586                                       config));
4587         bnx2x_cl45_read(bp, params->port,
4588                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4589                       ext_phy_addr,
4590                       MDIO_PMA_DEVAD,
4591                       MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4592         if (mod_abs & (1<<8)) {
4593
4594                 /* Module is absent */
4595                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4596                             "show module is absent\n");
4597
4598                 /* 1. Set mod_abs to detect next module
4599                 presence event
4600                    2. Set EDC off by setting OPTXLOS signal input to low
4601                         (bit 9).
4602                         When the EDC is off it locks onto a reference clock and
4603                         avoids becoming 'lost'.*/
4604                 mod_abs &= ~((1<<8)|(1<<9));
4605                 bnx2x_cl45_write(bp, params->port,
4606                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4607                                ext_phy_addr,
4608                                MDIO_PMA_DEVAD,
4609                                MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4610
4611                 /* Clear RX alarm since it stays up as long as
4612                 the mod_abs wasn't changed */
4613                 bnx2x_cl45_read(bp, params->port,
4614                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4615                               ext_phy_addr,
4616                               MDIO_PMA_DEVAD,
4617                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4618
4619         } else {
4620                 /* Module is present */
4621                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4622                             "show module is present\n");
4623                 /* First thing, disable transmitter,
4624                 and if the module is ok, the
4625                 module_detection will enable it*/
4626
4627                 /* 1. Set mod_abs to detect next module
4628                 absent event ( bit 8)
4629                    2. Restore the default polarity of the OPRXLOS signal and
4630                 this signal will then correctly indicate the presence or
4631                 absence of the Rx signal. (bit 9) */
4632                 mod_abs |= ((1<<8)|(1<<9));
4633                 bnx2x_cl45_write(bp, params->port,
4634                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4635                        ext_phy_addr,
4636                        MDIO_PMA_DEVAD,
4637                        MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4638
4639                 /* Clear RX alarm since it stays up as long as
4640                 the mod_abs wasn't changed. This is need to be done
4641                 before calling the module detection, otherwise it will clear
4642                 the link update alarm */
4643                 bnx2x_cl45_read(bp, params->port,
4644                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4645                               ext_phy_addr,
4646                               MDIO_PMA_DEVAD,
4647                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4648
4649
4650                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4651                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
4652                         bnx2x_sfp_set_transmitter(bp, params->port,
4653                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4654                                         ext_phy_addr, 0);
4655
4656                 if (bnx2x_wait_for_sfp_module_initialized(params)
4657                     == 0)
4658                         bnx2x_sfp_module_detection(params);
4659                 else
4660                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
4661         }
4662
4663         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4664                  rx_alarm_status);
4665         /* No need to check link status in case of
4666         module plugged in/out */
4667 }
4668
4669
4670 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
4671                                  struct link_vars *vars,
4672                                  u8 is_mi_int)
4673 {
4674         struct bnx2x *bp = params->bp;
4675         u32 ext_phy_type;
4676         u8 ext_phy_addr;
4677         u16 val1 = 0, val2;
4678         u16 rx_sd, pcs_status;
4679         u8 ext_phy_link_up = 0;
4680         u8 port = params->port;
4681
4682         if (vars->phy_flags & PHY_XGXS_FLAG) {
4683                 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
4684                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4685                 switch (ext_phy_type) {
4686                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4687                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
4688                         ext_phy_link_up = 1;
4689                         break;
4690
4691                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4692                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
4693                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4694                                       ext_phy_addr,
4695                                       MDIO_WIS_DEVAD,
4696                                       MDIO_WIS_REG_LASI_STATUS, &val1);
4697                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4698
4699                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4700                                       ext_phy_addr,
4701                                       MDIO_WIS_DEVAD,
4702                                       MDIO_WIS_REG_LASI_STATUS, &val1);
4703                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4704
4705                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4706                                       ext_phy_addr,
4707                                       MDIO_PMA_DEVAD,
4708                                       MDIO_PMA_REG_RX_SD, &rx_sd);
4709
4710                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4711                                       ext_phy_addr,
4712                                       1,
4713                                       0xc809, &val1);
4714                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4715                                       ext_phy_addr,
4716                                       1,
4717                                       0xc809, &val1);
4718
4719                         DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4720                         ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) &&
4721                                            ((val1 & (1<<8)) == 0));
4722                         if (ext_phy_link_up)
4723                                 vars->line_speed = SPEED_10000;
4724                         break;
4725
4726                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4727                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4728                         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
4729                         /* Clear RX Alarm*/
4730                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4731                                       ext_phy_addr,
4732                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
4733                                       &val2);
4734                         /* clear LASI indication*/
4735                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4736                                       ext_phy_addr,
4737                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4738                                       &val1);
4739                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4740                                       ext_phy_addr,
4741                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4742                                       &val2);
4743                         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
4744                                      "0x%x\n", val1, val2);
4745
4746                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4747                                       ext_phy_addr,
4748                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
4749                                       &rx_sd);
4750                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4751                                       ext_phy_addr,
4752                                       MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
4753                                       &pcs_status);
4754                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4755                                       ext_phy_addr,
4756                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4757                                       &val2);
4758                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4759                                       ext_phy_addr,
4760                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4761                                       &val2);
4762
4763                         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
4764                            "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
4765                            rx_sd, pcs_status, val2);
4766                         /* link is up if both bit 0 of pmd_rx_sd and
4767                          * bit 0 of pcs_status are set, or if the autoneg bit
4768                            1 is set
4769                          */
4770                         ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
4771                                            (val2 & (1<<1)));
4772                         if (ext_phy_link_up) {
4773                                 if (ext_phy_type ==
4774                                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
4775                                         /* If transmitter is disabled,
4776                                         ignore false link up indication */
4777                                         bnx2x_cl45_read(bp, params->port,
4778                                                    ext_phy_type,
4779                                                    ext_phy_addr,
4780                                                    MDIO_PMA_DEVAD,
4781                                                    MDIO_PMA_REG_PHY_IDENTIFIER,
4782                                                    &val1);
4783                                         if (val1 & (1<<15)) {
4784                                                 DP(NETIF_MSG_LINK, "Tx is "
4785                                                             "disabled\n");
4786                                                 ext_phy_link_up = 0;
4787                                                 break;
4788                                         }
4789                                 }
4790                                 if (val2 & (1<<1))
4791                                         vars->line_speed = SPEED_1000;
4792                                 else
4793                                         vars->line_speed = SPEED_10000;
4794                         }
4795                         break;
4796
4797                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4798                 {
4799                         u16 link_status = 0;
4800                         u16 rx_alarm_status;
4801                         /* Check the LASI */
4802                         bnx2x_cl45_read(bp, params->port,
4803                                       ext_phy_type,
4804                                       ext_phy_addr,
4805                                       MDIO_PMA_DEVAD,
4806                                       MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4807
4808                         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4809                                  rx_alarm_status);
4810
4811                         bnx2x_cl45_read(bp, params->port,
4812                                       ext_phy_type,
4813                                       ext_phy_addr,
4814                                       MDIO_PMA_DEVAD,
4815                                       MDIO_PMA_REG_LASI_STATUS, &val1);
4816
4817                         DP(NETIF_MSG_LINK,
4818                                  "8727 LASI status 0x%x\n",
4819                                  val1);
4820
4821                         /* Clear MSG-OUT */
4822                         bnx2x_cl45_read(bp, params->port,
4823                                       ext_phy_type,
4824                                       ext_phy_addr,
4825                                       MDIO_PMA_DEVAD,
4826                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
4827                                       &val1);
4828
4829                         /*
4830                          * If a module is present and there is need to check
4831                          * for over current
4832                          */
4833                         if (!(params->feature_config_flags &
4834                               FEATURE_CONFIG_BCM8727_NOC) &&
4835                             !(rx_alarm_status & (1<<5))) {
4836                                 /* Check over-current using 8727 GPIO0 input*/
4837                                 bnx2x_cl45_read(bp, params->port,
4838                                               ext_phy_type,
4839                                               ext_phy_addr,
4840                                               MDIO_PMA_DEVAD,
4841                                               MDIO_PMA_REG_8727_GPIO_CTRL,
4842                                               &val1);
4843
4844                                 if ((val1 & (1<<8)) == 0) {
4845                                         DP(NETIF_MSG_LINK, "8727 Power fault"
4846                                                      " has been detected on "
4847                                                      "port %d\n",
4848                                                  params->port);
4849                                         printk(KERN_ERR PFX  "Error:  Power"
4850                                                  " fault on %s Port %d has"
4851                                                  " been detected and the"
4852                                                  " power to that SFP+ module"
4853                                                  " has been removed to prevent"
4854                                                  " failure of the card. Please"
4855                                                  " remove the SFP+ module and"
4856                                                  " restart the system to clear"
4857                                                  " this error.\n"
4858                         , bp->dev->name, params->port);
4859                                         /*
4860                                          * Disable all RX_ALARMs except for
4861                                          * mod_abs
4862                                          */
4863                                         bnx2x_cl45_write(bp, params->port,
4864                                                      ext_phy_type,
4865                                                      ext_phy_addr,
4866                                                      MDIO_PMA_DEVAD,
4867                                                      MDIO_PMA_REG_RX_ALARM_CTRL,
4868                                                      (1<<5));
4869
4870                                         bnx2x_cl45_read(bp, params->port,
4871                                                     ext_phy_type,
4872                                                     ext_phy_addr,
4873                                                     MDIO_PMA_DEVAD,
4874                                                     MDIO_PMA_REG_PHY_IDENTIFIER,
4875                                                     &val1);
4876                                         /* Wait for module_absent_event */
4877                                         val1 |= (1<<8);
4878                                         bnx2x_cl45_write(bp, params->port,
4879                                                     ext_phy_type,
4880                                                     ext_phy_addr,
4881                                                     MDIO_PMA_DEVAD,
4882                                                     MDIO_PMA_REG_PHY_IDENTIFIER,
4883                                                     val1);
4884                                         /* Clear RX alarm */
4885                                         bnx2x_cl45_read(bp, params->port,
4886                                                       ext_phy_type,
4887                                                       ext_phy_addr,
4888                                                       MDIO_PMA_DEVAD,
4889                                                       MDIO_PMA_REG_RX_ALARM,
4890                                                       &rx_alarm_status);
4891                                         break;
4892                                 }
4893                         } /* Over current check */
4894
4895                         /* When module absent bit is set, check module */
4896                         if (rx_alarm_status & (1<<5)) {
4897                                 bnx2x_8727_handle_mod_abs(params);
4898                                 /* Enable all mod_abs and link detection bits */
4899                                 bnx2x_cl45_write(bp, params->port,
4900                                                ext_phy_type,
4901                                                ext_phy_addr,
4902                                                MDIO_PMA_DEVAD,
4903                                                MDIO_PMA_REG_RX_ALARM_CTRL,
4904                                                ((1<<5) | (1<<2)));
4905                         }
4906
4907                         /* If transmitter is disabled,
4908                         ignore false link up indication */
4909                         bnx2x_cl45_read(bp, params->port,
4910                                       ext_phy_type,
4911                                       ext_phy_addr,
4912                                       MDIO_PMA_DEVAD,
4913                                       MDIO_PMA_REG_PHY_IDENTIFIER,
4914                                       &val1);
4915                         if (val1 & (1<<15)) {
4916                                 DP(NETIF_MSG_LINK, "Tx is disabled\n");
4917                                 ext_phy_link_up = 0;
4918                                 break;
4919                         }
4920
4921                         bnx2x_cl45_read(bp, params->port,
4922                                       ext_phy_type,
4923                                       ext_phy_addr,
4924                                       MDIO_PMA_DEVAD,
4925                                       MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4926                                       &link_status);
4927
4928                         /* Bits 0..2 --> speed detected,
4929                            bits 13..15--> link is down */
4930                         if ((link_status & (1<<2)) &&
4931                             (!(link_status & (1<<15)))) {
4932                                 ext_phy_link_up = 1;
4933                                 vars->line_speed = SPEED_10000;
4934                         } else if ((link_status & (1<<0)) &&
4935                                    (!(link_status & (1<<13)))) {
4936                                 ext_phy_link_up = 1;
4937                                 vars->line_speed = SPEED_1000;
4938                                 DP(NETIF_MSG_LINK,
4939                                          "port %x: External link"
4940                                          " up in 1G\n", params->port);
4941                         } else {
4942                                 ext_phy_link_up = 0;
4943                                 DP(NETIF_MSG_LINK,
4944                                          "port %x: External link"
4945                                          " is down\n", params->port);
4946                         }
4947                         break;
4948                 }
4949
4950                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4951                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4952                 {
4953                         u16 link_status = 0;
4954                         u16 an1000_status = 0;
4955
4956                         if (ext_phy_type ==
4957                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
4958                                 bnx2x_cl45_read(bp, params->port,
4959                                       ext_phy_type,
4960                                       ext_phy_addr,
4961                                       MDIO_PCS_DEVAD,
4962                                       MDIO_PCS_REG_LASI_STATUS, &val1);
4963                         bnx2x_cl45_read(bp, params->port,
4964                                       ext_phy_type,
4965                                       ext_phy_addr,
4966                                       MDIO_PCS_DEVAD,
4967                                       MDIO_PCS_REG_LASI_STATUS, &val2);
4968                         DP(NETIF_MSG_LINK,
4969                                  "870x LASI status 0x%x->0x%x\n",
4970                                   val1, val2);
4971                         } else {
4972                                 /* In 8073, port1 is directed through emac0 and
4973                                  * port0 is directed through emac1
4974                                  */
4975                                 bnx2x_cl45_read(bp, params->port,
4976                                               ext_phy_type,
4977                                               ext_phy_addr,
4978                                               MDIO_PMA_DEVAD,
4979                                               MDIO_PMA_REG_LASI_STATUS, &val1);
4980
4981                                 DP(NETIF_MSG_LINK,
4982                                          "8703 LASI status 0x%x\n",
4983                                           val1);
4984                         }
4985
4986                         /* clear the interrupt LASI status register */
4987                         bnx2x_cl45_read(bp, params->port,
4988                                       ext_phy_type,
4989                                       ext_phy_addr,
4990                                       MDIO_PCS_DEVAD,
4991                                       MDIO_PCS_REG_STATUS, &val2);
4992                         bnx2x_cl45_read(bp, params->port,
4993                                       ext_phy_type,
4994                                       ext_phy_addr,
4995                                       MDIO_PCS_DEVAD,
4996                                       MDIO_PCS_REG_STATUS, &val1);
4997                         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
4998                            val2, val1);
4999                         /* Clear MSG-OUT */
5000                         bnx2x_cl45_read(bp, params->port,
5001                                       ext_phy_type,
5002                                       ext_phy_addr,
5003                                       MDIO_PMA_DEVAD,
5004                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
5005                                       &val1);
5006
5007                         /* Check the LASI */
5008                         bnx2x_cl45_read(bp, params->port,
5009                                       ext_phy_type,
5010                                       ext_phy_addr,
5011                                       MDIO_PMA_DEVAD,
5012                                       MDIO_PMA_REG_RX_ALARM, &val2);
5013
5014                         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
5015
5016                         /* Check the link status */
5017                         bnx2x_cl45_read(bp, params->port,
5018                                       ext_phy_type,
5019                                       ext_phy_addr,
5020                                       MDIO_PCS_DEVAD,
5021                                       MDIO_PCS_REG_STATUS, &val2);
5022                         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
5023
5024                         bnx2x_cl45_read(bp, params->port,
5025                                       ext_phy_type,
5026                                       ext_phy_addr,
5027                                       MDIO_PMA_DEVAD,
5028                                       MDIO_PMA_REG_STATUS, &val2);
5029                         bnx2x_cl45_read(bp, params->port,
5030                                       ext_phy_type,
5031                                       ext_phy_addr,
5032                                       MDIO_PMA_DEVAD,
5033                                       MDIO_PMA_REG_STATUS, &val1);
5034                         ext_phy_link_up = ((val1 & 4) == 4);
5035                         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
5036                         if (ext_phy_type ==
5037                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
5038
5039                                 if (ext_phy_link_up &&
5040                                     ((params->req_line_speed !=
5041                                         SPEED_10000))) {
5042                                         if (bnx2x_bcm8073_xaui_wa(params)
5043                                              != 0) {
5044                                                 ext_phy_link_up = 0;
5045                                                 break;
5046                                         }
5047                                 }
5048                                 bnx2x_cl45_read(bp, params->port,
5049                                               ext_phy_type,
5050                                               ext_phy_addr,
5051                                               MDIO_AN_DEVAD,
5052                                               MDIO_AN_REG_LINK_STATUS,
5053                                               &an1000_status);
5054                                 bnx2x_cl45_read(bp, params->port,
5055                                               ext_phy_type,
5056                                               ext_phy_addr,
5057                                               MDIO_AN_DEVAD,
5058                                               MDIO_AN_REG_LINK_STATUS,
5059                                               &an1000_status);
5060
5061                                 /* Check the link status on 1.1.2 */
5062                                 bnx2x_cl45_read(bp, params->port,
5063                                               ext_phy_type,
5064                                               ext_phy_addr,
5065                                               MDIO_PMA_DEVAD,
5066                                               MDIO_PMA_REG_STATUS, &val2);
5067                                 bnx2x_cl45_read(bp, params->port,
5068                                               ext_phy_type,
5069                                               ext_phy_addr,
5070                                               MDIO_PMA_DEVAD,
5071                                               MDIO_PMA_REG_STATUS, &val1);
5072                                 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
5073                                              "an_link_status=0x%x\n",
5074                                           val2, val1, an1000_status);
5075
5076                                 ext_phy_link_up = (((val1 & 4) == 4) ||
5077                                                 (an1000_status & (1<<1)));
5078                                 if (ext_phy_link_up &&
5079                                     bnx2x_8073_is_snr_needed(params)) {
5080                                         /* The SNR will improve about 2dbby
5081                                         changing the BW and FEE main tap.*/
5082
5083                                         /* The 1st write to change FFE main
5084                                         tap is set before restart AN */
5085                                         /* Change PLL Bandwidth in EDC
5086                                         register */
5087                                         bnx2x_cl45_write(bp, port, ext_phy_type,
5088                                                     ext_phy_addr,
5089                                                     MDIO_PMA_DEVAD,
5090                                                     MDIO_PMA_REG_PLL_BANDWIDTH,
5091                                                     0x26BC);
5092
5093                                         /* Change CDR Bandwidth in EDC
5094                                         register */
5095                                         bnx2x_cl45_write(bp, port, ext_phy_type,
5096                                                     ext_phy_addr,
5097                                                     MDIO_PMA_DEVAD,
5098                                                     MDIO_PMA_REG_CDR_BANDWIDTH,
5099                                                     0x0333);
5100                                 }
5101                                 bnx2x_cl45_read(bp, params->port,
5102                                            ext_phy_type,
5103                                            ext_phy_addr,
5104                                            MDIO_PMA_DEVAD,
5105                                            MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
5106                                            &link_status);
5107
5108                                 /* Bits 0..2 --> speed detected,
5109                                    bits 13..15--> link is down */
5110                                 if ((link_status & (1<<2)) &&
5111                                     (!(link_status & (1<<15)))) {
5112                                         ext_phy_link_up = 1;
5113                                         vars->line_speed = SPEED_10000;
5114                                         DP(NETIF_MSG_LINK,
5115                                                  "port %x: External link"
5116                                                  " up in 10G\n", params->port);
5117                                 } else if ((link_status & (1<<1)) &&
5118                                            (!(link_status & (1<<14)))) {
5119                                         ext_phy_link_up = 1;
5120                                         vars->line_speed = SPEED_2500;
5121                                         DP(NETIF_MSG_LINK,
5122                                                  "port %x: External link"
5123                                                  " up in 2.5G\n", params->port);
5124                                 } else if ((link_status & (1<<0)) &&
5125                                            (!(link_status & (1<<13)))) {
5126                                         ext_phy_link_up = 1;
5127                                         vars->line_speed = SPEED_1000;
5128                                         DP(NETIF_MSG_LINK,
5129                                                  "port %x: External link"
5130                                                  " up in 1G\n", params->port);
5131                                 } else {
5132                                         ext_phy_link_up = 0;
5133                                         DP(NETIF_MSG_LINK,
5134                                                  "port %x: External link"
5135                                                  " is down\n", params->port);
5136                                 }
5137                         } else {
5138                                 /* See if 1G link is up for the 8072 */
5139                                 bnx2x_cl45_read(bp, params->port,
5140                                               ext_phy_type,
5141                                               ext_phy_addr,
5142                                               MDIO_AN_DEVAD,
5143                                               MDIO_AN_REG_LINK_STATUS,
5144                                               &an1000_status);
5145                                 bnx2x_cl45_read(bp, params->port,
5146                                               ext_phy_type,
5147                                               ext_phy_addr,
5148                                               MDIO_AN_DEVAD,
5149                                               MDIO_AN_REG_LINK_STATUS,
5150                                               &an1000_status);
5151                                 if (an1000_status & (1<<1)) {
5152                                         ext_phy_link_up = 1;
5153                                         vars->line_speed = SPEED_1000;
5154                                         DP(NETIF_MSG_LINK,
5155                                                  "port %x: External link"
5156                                                  " up in 1G\n", params->port);
5157                                 } else if (ext_phy_link_up) {
5158                                         ext_phy_link_up = 1;
5159                                         vars->line_speed = SPEED_10000;
5160                                         DP(NETIF_MSG_LINK,
5161                                                  "port %x: External link"
5162                                                  " up in 10G\n", params->port);
5163                                 }
5164                         }
5165
5166
5167                         break;
5168                 }
5169                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5170                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5171                                       ext_phy_addr,
5172                                       MDIO_PMA_DEVAD,
5173                                       MDIO_PMA_REG_LASI_STATUS, &val2);
5174                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5175                                       ext_phy_addr,
5176                                       MDIO_PMA_DEVAD,
5177                                       MDIO_PMA_REG_LASI_STATUS, &val1);
5178                         DP(NETIF_MSG_LINK,
5179                                  "10G-base-T LASI status 0x%x->0x%x\n",
5180                                   val2, val1);
5181                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5182                                       ext_phy_addr,
5183                                       MDIO_PMA_DEVAD,
5184                                       MDIO_PMA_REG_STATUS, &val2);
5185                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5186                                       ext_phy_addr,
5187                                       MDIO_PMA_DEVAD,
5188                                       MDIO_PMA_REG_STATUS, &val1);
5189                         DP(NETIF_MSG_LINK,
5190                                  "10G-base-T PMA status 0x%x->0x%x\n",
5191                                  val2, val1);
5192                         ext_phy_link_up = ((val1 & 4) == 4);
5193                         /* if link is up
5194                          * print the AN outcome of the SFX7101 PHY
5195                          */
5196                         if (ext_phy_link_up) {
5197                                 bnx2x_cl45_read(bp, params->port,
5198                                               ext_phy_type,
5199                                               ext_phy_addr,
5200                                               MDIO_AN_DEVAD,
5201                                               MDIO_AN_REG_MASTER_STATUS,
5202                                               &val2);
5203                                 vars->line_speed = SPEED_10000;
5204                                 DP(NETIF_MSG_LINK,
5205                                          "SFX7101 AN status 0x%x->Master=%x\n",
5206                                           val2,
5207                                          (val2 & (1<<14)));
5208                         }
5209                         break;
5210                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5211                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
5212                         /* Check 10G-BaseT link status */
5213                         /* Check PMD signal ok */
5214                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5215                                                       ext_phy_addr,
5216                                                       MDIO_AN_DEVAD,
5217                                                       0xFFFA,
5218                                                       &val1);
5219                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5220                                       ext_phy_addr,
5221                                       MDIO_PMA_DEVAD,
5222                                       MDIO_PMA_REG_8481_PMD_SIGNAL,
5223                                       &val2);
5224                         DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2);
5225
5226                         /* Check link 10G */
5227                         if (val2 & (1<<11)) {
5228                                 vars->line_speed = SPEED_10000;
5229                                 ext_phy_link_up = 1;
5230                                 bnx2x_8481_set_10G_led_mode(params,
5231                                                           ext_phy_type,
5232                                                           ext_phy_addr);
5233                         } else { /* Check Legacy speed link */
5234                                 u16 legacy_status, legacy_speed;
5235
5236                                 /* Enable expansion register 0x42
5237                                 (Operation mode status) */
5238                                 bnx2x_cl45_write(bp, params->port,
5239                                          ext_phy_type,
5240                                          ext_phy_addr,
5241                                          MDIO_AN_DEVAD,
5242                                          MDIO_AN_REG_8481_EXPANSION_REG_ACCESS,
5243                                          0xf42);
5244
5245                                 /* Get legacy speed operation status */
5246                                 bnx2x_cl45_read(bp, params->port,
5247                                           ext_phy_type,
5248                                           ext_phy_addr,
5249                                           MDIO_AN_DEVAD,
5250                                           MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
5251                                           &legacy_status);
5252
5253                                 DP(NETIF_MSG_LINK, "Legacy speed status"
5254                                              " = 0x%x\n", legacy_status);
5255                                 ext_phy_link_up = ((legacy_status & (1<<11))
5256                                                    == (1<<11));
5257                                 if (ext_phy_link_up) {
5258                                         legacy_speed = (legacy_status & (3<<9));
5259                                         if (legacy_speed == (0<<9))
5260                                                 vars->line_speed = SPEED_10;
5261                                         else if (legacy_speed == (1<<9))
5262                                                 vars->line_speed =
5263                                                         SPEED_100;
5264                                         else if (legacy_speed == (2<<9))
5265                                                 vars->line_speed =
5266                                                         SPEED_1000;
5267                                         else /* Should not happen */
5268                                                 vars->line_speed = 0;
5269
5270                                         if (legacy_status & (1<<8))
5271                                                 vars->duplex = DUPLEX_FULL;
5272                                         else
5273                                                 vars->duplex = DUPLEX_HALF;
5274
5275                                         DP(NETIF_MSG_LINK, "Link is up "
5276                                                      "in %dMbps, is_duplex_full"
5277                                                      "= %d\n",
5278                                                 vars->line_speed,
5279                                                 (vars->duplex == DUPLEX_FULL));
5280                                         bnx2x_8481_set_legacy_led_mode(params,
5281                                                                  ext_phy_type,
5282                                                                  ext_phy_addr);
5283                                 }
5284                         }
5285                         break;
5286                 default:
5287                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
5288                            params->ext_phy_config);
5289                         ext_phy_link_up = 0;
5290                         break;
5291                 }
5292                 /* Set SGMII mode for external phy */
5293                 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5294                         if (vars->line_speed < SPEED_1000)
5295                                 vars->phy_flags |= PHY_SGMII_FLAG;
5296                         else
5297                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
5298                 }
5299
5300         } else { /* SerDes */
5301                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5302                 switch (ext_phy_type) {
5303                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
5304                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
5305                         ext_phy_link_up = 1;
5306                         break;
5307
5308                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
5309                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
5310                         ext_phy_link_up = 1;
5311                         break;
5312
5313                 default:
5314                         DP(NETIF_MSG_LINK,
5315                                  "BAD SerDes ext_phy_config 0x%x\n",
5316                                  params->ext_phy_config);
5317                         ext_phy_link_up = 0;
5318                         break;
5319                 }
5320         }
5321
5322         return ext_phy_link_up;
5323 }
5324
5325 static void bnx2x_link_int_enable(struct link_params *params)
5326 {
5327         u8 port = params->port;
5328         u32 ext_phy_type;
5329         u32 mask;
5330         struct bnx2x *bp = params->bp;
5331
5332         /* setting the status to report on link up
5333            for either XGXS or SerDes */
5334
5335         if (params->switch_cfg == SWITCH_CFG_10G) {
5336                 mask = (NIG_MASK_XGXS0_LINK10G |
5337                         NIG_MASK_XGXS0_LINK_STATUS);
5338                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5339                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5340                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5341                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
5342                     (ext_phy_type !=
5343                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
5344                         mask |= NIG_MASK_MI_INT;
5345                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5346                 }
5347
5348         } else { /* SerDes */
5349                 mask = NIG_MASK_SERDES0_LINK_STATUS;
5350                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5351                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5352                 if ((ext_phy_type !=
5353                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5354                     (ext_phy_type !=
5355                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
5356                         mask |= NIG_MASK_MI_INT;
5357                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5358                 }
5359         }
5360         bnx2x_bits_en(bp,
5361                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5362                       mask);
5363
5364         DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
5365                  (params->switch_cfg == SWITCH_CFG_10G),
5366                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5367         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5368                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5369                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5370                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5371         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5372            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5373            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5374 }
5375
5376 static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
5377                                         u8 is_mi_int)
5378 {
5379         u32 latch_status = 0, is_mi_int_status;
5380         /* Disable the MI INT ( external phy int )
5381          * by writing 1 to the status register. Link down indication
5382          * is high-active-signal, so in this case we need to write the
5383          * status to clear the XOR
5384          */
5385         /* Read Latched signals */
5386         latch_status = REG_RD(bp,
5387                                   NIG_REG_LATCH_STATUS_0 + port*8);
5388         is_mi_int_status = REG_RD(bp,
5389                                   NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
5390         DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
5391                      "latch_status = 0x%x\n",
5392                  is_mi_int, is_mi_int_status, latch_status);
5393         /* Handle only those with latched-signal=up.*/
5394         if (latch_status & 1) {
5395                 /* For all latched-signal=up,Write original_signal to status */
5396                 if (is_mi_int)
5397                         bnx2x_bits_en(bp,
5398                                     NIG_REG_STATUS_INTERRUPT_PORT0
5399                                     + port*4,
5400                                     NIG_STATUS_EMAC0_MI_INT);
5401                 else
5402                         bnx2x_bits_dis(bp,
5403                                      NIG_REG_STATUS_INTERRUPT_PORT0
5404                                      + port*4,
5405                                      NIG_STATUS_EMAC0_MI_INT);
5406                 /* For all latched-signal=up : Re-Arm Latch signals */
5407                 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
5408                            (latch_status & 0xfffe) | (latch_status & 1));
5409         }
5410 }
5411 /*
5412  * link management
5413  */
5414 static void bnx2x_link_int_ack(struct link_params *params,
5415                              struct link_vars *vars, u8 is_10g,
5416                              u8 is_mi_int)
5417 {
5418         struct bnx2x *bp = params->bp;
5419         u8 port = params->port;
5420
5421         /* first reset all status
5422          * we assume only one line will be change at a time */
5423         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5424                      (NIG_STATUS_XGXS0_LINK10G |
5425                       NIG_STATUS_XGXS0_LINK_STATUS |
5426                       NIG_STATUS_SERDES0_LINK_STATUS));
5427         if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config)
5428                 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
5429         (XGXS_EXT_PHY_TYPE(params->ext_phy_config)
5430                 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) {
5431                 bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
5432         }
5433         if (vars->phy_link_up) {
5434                 if (is_10g) {
5435                         /* Disable the 10G link interrupt
5436                          * by writing 1 to the status register
5437                          */
5438                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
5439                         bnx2x_bits_en(bp,
5440                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5441                                       NIG_STATUS_XGXS0_LINK10G);
5442
5443                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
5444                         /* Disable the link interrupt
5445                          * by writing 1 to the relevant lane
5446                          * in the status register
5447                          */
5448                         u32 ser_lane = ((params->lane_config &
5449                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5450                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5451
5452                         DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
5453                                  vars->line_speed);
5454                         bnx2x_bits_en(bp,
5455                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5456                                       ((1 << ser_lane) <<
5457                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
5458
5459                 } else { /* SerDes */
5460                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
5461                         /* Disable the link interrupt
5462                          * by writing 1 to the status register
5463                          */
5464                         bnx2x_bits_en(bp,
5465                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5466                                       NIG_STATUS_SERDES0_LINK_STATUS);
5467                 }
5468
5469         } else { /* link_down */
5470         }
5471 }
5472
5473 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
5474 {
5475         u8 *str_ptr = str;
5476         u32 mask = 0xf0000000;
5477         u8 shift = 8*4;
5478         u8 digit;
5479         if (len < 10) {
5480                 /* Need more than 10chars for this format */
5481                 *str_ptr = '\0';
5482                 return -EINVAL;
5483         }
5484         while (shift > 0) {
5485
5486                 shift -= 4;
5487                 digit = ((num & mask) >> shift);
5488                 if (digit < 0xa)
5489                         *str_ptr = digit + '0';
5490                 else
5491                         *str_ptr = digit - 0xa + 'a';
5492                 str_ptr++;
5493                 mask = mask >> 4;
5494                 if (shift == 4*4) {
5495                         *str_ptr = ':';
5496                         str_ptr++;
5497                 }
5498         }
5499         *str_ptr = '\0';
5500         return 0;
5501 }
5502
5503 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
5504                               u8 *version, u16 len)
5505 {
5506         struct bnx2x *bp;
5507         u32 ext_phy_type = 0;
5508         u32 spirom_ver = 0;
5509         u8 status;
5510
5511         if (version == NULL || params == NULL)
5512                 return -EINVAL;
5513         bp = params->bp;
5514
5515         spirom_ver = REG_RD(bp, params->shmem_base +
5516                    offsetof(struct shmem_region,
5517                             port_mb[params->port].ext_phy_fw_version));
5518
5519         status = 0;
5520         /* reset the returned value to zero */
5521         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5522         switch (ext_phy_type) {
5523         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5524
5525                 if (len < 5)
5526                         return -EINVAL;
5527
5528                 version[0] = (spirom_ver & 0xFF);
5529                 version[1] = (spirom_ver & 0xFF00) >> 8;
5530                 version[2] = (spirom_ver & 0xFF0000) >> 16;
5531                 version[3] = (spirom_ver & 0xFF000000) >> 24;
5532                 version[4] = '\0';
5533
5534                 break;
5535         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5536         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5537         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
5538         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5539         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5540                 status = bnx2x_format_ver(spirom_ver, version, len);
5541                 break;
5542         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5543         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
5544                 spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 |
5545                         (spirom_ver & 0x7F);
5546                 status = bnx2x_format_ver(spirom_ver, version, len);
5547                 break;
5548         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5549         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5550                 version[0] = '\0';
5551                 break;
5552
5553         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5554                 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
5555                                     " type is FAILURE!\n");
5556                 status = -EINVAL;
5557                 break;
5558
5559         default:
5560                 break;
5561         }
5562         return status;
5563 }
5564
5565 static void bnx2x_set_xgxs_loopback(struct link_params *params,
5566                                   struct link_vars *vars,
5567                                   u8 is_10g)
5568 {
5569         u8 port = params->port;
5570         struct bnx2x *bp = params->bp;
5571
5572         if (is_10g) {
5573                 u32 md_devad;
5574
5575                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
5576
5577                 /* change the uni_phy_addr in the nig */
5578                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
5579                                           port*0x18));
5580
5581                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
5582
5583                 bnx2x_cl45_write(bp, port, 0,
5584                                params->phy_addr,
5585                                5,
5586                                (MDIO_REG_BANK_AER_BLOCK +
5587                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
5588                                0x2800);
5589
5590                 bnx2x_cl45_write(bp, port, 0,
5591                                params->phy_addr,
5592                                5,
5593                                (MDIO_REG_BANK_CL73_IEEEB0 +
5594                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5595                                0x6041);
5596                 msleep(200);
5597                 /* set aer mmd back */
5598                 bnx2x_set_aer_mmd(params, vars);
5599
5600                 /* and md_devad */
5601                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5602                             md_devad);
5603
5604         } else {
5605                 u16 mii_control;
5606
5607                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
5608
5609                 CL45_RD_OVER_CL22(bp, port,
5610                                       params->phy_addr,
5611                                       MDIO_REG_BANK_COMBO_IEEE0,
5612                                       MDIO_COMBO_IEEE0_MII_CONTROL,
5613                                       &mii_control);
5614
5615                 CL45_WR_OVER_CL22(bp, port,
5616                                       params->phy_addr,
5617                                       MDIO_REG_BANK_COMBO_IEEE0,
5618                                       MDIO_COMBO_IEEE0_MII_CONTROL,
5619                                       (mii_control |
5620                                        MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
5621         }
5622 }
5623
5624
5625 static void bnx2x_ext_phy_loopback(struct link_params *params)
5626 {
5627         struct bnx2x *bp = params->bp;
5628         u8 ext_phy_addr;
5629         u32 ext_phy_type;
5630
5631         if (params->switch_cfg == SWITCH_CFG_10G) {
5632                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5633                 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
5634                 /* CL37 Autoneg Enabled */
5635                 switch (ext_phy_type) {
5636                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5637                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5638                         DP(NETIF_MSG_LINK,
5639                                 "ext_phy_loopback: We should not get here\n");
5640                         break;
5641                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5642                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
5643                         break;
5644                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5645                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
5646                         break;
5647                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5648                         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
5649                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
5650                                        ext_phy_addr,
5651                                        MDIO_PMA_DEVAD,
5652                                        MDIO_PMA_REG_CTRL,
5653                                        0x0001);
5654                         break;
5655                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5656                         /* SFX7101_XGXS_TEST1 */
5657                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
5658                                        ext_phy_addr,
5659                                        MDIO_XS_DEVAD,
5660                                        MDIO_XS_SFX7101_XGXS_TEST1,
5661                                        0x100);
5662                         DP(NETIF_MSG_LINK,
5663                                 "ext_phy_loopback: set ext phy loopback\n");
5664                         break;
5665                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5666
5667                         break;
5668                 } /* switch external PHY type */
5669         } else {
5670                 /* serdes */
5671                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5672                 ext_phy_addr = (params->ext_phy_config  &
5673                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
5674                 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
5675         }
5676 }
5677
5678
5679 /*
5680  *------------------------------------------------------------------------
5681  * bnx2x_override_led_value -
5682  *
5683  * Override the led value of the requsted led
5684  *
5685  *------------------------------------------------------------------------
5686  */
5687 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
5688                           u32 led_idx, u32 value)
5689 {
5690         u32 reg_val;
5691
5692         /* If port 0 then use EMAC0, else use EMAC1*/
5693         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5694
5695         DP(NETIF_MSG_LINK,
5696                  "bnx2x_override_led_value() port %x led_idx %d value %d\n",
5697                  port, led_idx, value);
5698
5699         switch (led_idx) {
5700         case 0: /* 10MB led */
5701                 /* Read the current value of the LED register in
5702                 the EMAC block */
5703                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5704                 /* Set the OVERRIDE bit to 1 */
5705                 reg_val |= EMAC_LED_OVERRIDE;
5706                 /* If value is 1, set the 10M_OVERRIDE bit,
5707                 otherwise reset it.*/
5708                 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
5709                         (reg_val & ~EMAC_LED_10MB_OVERRIDE);
5710                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5711                 break;
5712         case 1: /*100MB led    */
5713                 /*Read the current value of the LED register in
5714                 the EMAC block */
5715                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5716                 /*  Set the OVERRIDE bit to 1 */
5717                 reg_val |= EMAC_LED_OVERRIDE;
5718                 /*  If value is 1, set the 100M_OVERRIDE bit,
5719                 otherwise reset it.*/
5720                 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
5721                         (reg_val & ~EMAC_LED_100MB_OVERRIDE);
5722                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5723                 break;
5724         case 2: /* 1000MB led */
5725                 /* Read the current value of the LED register in the
5726                 EMAC block */
5727                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5728                 /* Set the OVERRIDE bit to 1 */
5729                 reg_val |= EMAC_LED_OVERRIDE;
5730                 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
5731                 reset it. */
5732                 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
5733                         (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
5734                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5735                 break;
5736         case 3: /* 2500MB led */
5737                 /*  Read the current value of the LED register in the
5738                 EMAC block*/
5739                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5740                 /* Set the OVERRIDE bit to 1 */
5741                 reg_val |= EMAC_LED_OVERRIDE;
5742                 /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
5743                 reset it.*/
5744                 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
5745                         (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
5746                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5747                 break;
5748         case 4: /*10G led */
5749                 if (port == 0) {
5750                         REG_WR(bp, NIG_REG_LED_10G_P0,
5751                                     value);
5752                 } else {
5753                         REG_WR(bp, NIG_REG_LED_10G_P1,
5754                                     value);
5755                 }
5756                 break;
5757         case 5: /* TRAFFIC led */
5758                 /* Find if the traffic control is via BMAC or EMAC */
5759                 if (port == 0)
5760                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
5761                 else
5762                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
5763
5764                 /*  Override the traffic led in the EMAC:*/
5765                 if (reg_val == 1) {
5766                         /* Read the current value of the LED register in
5767                         the EMAC block */
5768                         reg_val = REG_RD(bp, emac_base +
5769                                              EMAC_REG_EMAC_LED);
5770                         /* Set the TRAFFIC_OVERRIDE bit to 1 */
5771                         reg_val |= EMAC_LED_OVERRIDE;
5772                         /* If value is 1, set the TRAFFIC bit, otherwise
5773                         reset it.*/
5774                         reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
5775                                 (reg_val & ~EMAC_LED_TRAFFIC);
5776                         REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5777                 } else { /* Override the traffic led in the BMAC: */
5778                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5779                                    + port*4, 1);
5780                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
5781                                     value);
5782                 }
5783                 break;
5784         default:
5785                 DP(NETIF_MSG_LINK,
5786                          "bnx2x_override_led_value() unknown led index %d "
5787                          "(should be 0-5)\n", led_idx);
5788                 return -EINVAL;
5789         }
5790
5791         return 0;
5792 }
5793
5794
5795 u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed)
5796 {
5797         u8 port = params->port;
5798         u16 hw_led_mode = params->hw_led_mode;
5799         u8 rc = 0;
5800         u32 tmp;
5801         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5802         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5803         struct bnx2x *bp = params->bp;
5804         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5805         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5806                  speed, hw_led_mode);
5807         switch (mode) {
5808         case LED_MODE_OFF:
5809                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
5810                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5811                            SHARED_HW_CFG_LED_MAC1);
5812
5813                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5814                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
5815                 break;
5816
5817         case LED_MODE_OPER:
5818                 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5819                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
5820                         REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
5821                 } else {
5822                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5823                                    hw_led_mode);
5824                 }
5825
5826                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
5827                            port*4, 0);
5828                 /* Set blinking rate to ~15.9Hz */
5829                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
5830                            LED_BLINK_RATE_VAL);
5831                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
5832                            port*4, 1);
5833                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5834                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
5835                             (tmp & (~EMAC_LED_OVERRIDE)));
5836
5837                 if (CHIP_IS_E1(bp) &&
5838                     ((speed == SPEED_2500) ||
5839                      (speed == SPEED_1000) ||
5840                      (speed == SPEED_100) ||
5841                      (speed == SPEED_10))) {
5842                         /* On Everest 1 Ax chip versions for speeds less than
5843                         10G LED scheme is different */
5844                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5845                                    + port*4, 1);
5846                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
5847                                    port*4, 0);
5848                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
5849                                    port*4, 1);
5850                 }
5851                 break;
5852
5853         default:
5854                 rc = -EINVAL;
5855                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
5856                          mode);
5857                 break;
5858         }
5859         return rc;
5860
5861 }
5862
5863 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
5864 {
5865         struct bnx2x *bp = params->bp;
5866         u16 gp_status = 0;
5867
5868         CL45_RD_OVER_CL22(bp, params->port,
5869                               params->phy_addr,
5870                               MDIO_REG_BANK_GP_STATUS,
5871                               MDIO_GP_STATUS_TOP_AN_STATUS1,
5872                               &gp_status);
5873         /* link is up only if both local phy and external phy are up */
5874         if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
5875             bnx2x_ext_phy_is_link_up(params, vars, 1))
5876                 return 0;
5877
5878         return -ESRCH;
5879 }
5880
5881 static u8 bnx2x_link_initialize(struct link_params *params,
5882                               struct link_vars *vars)
5883 {
5884         struct bnx2x *bp = params->bp;
5885         u8 port = params->port;
5886         u8 rc = 0;
5887         u8 non_ext_phy;
5888         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5889
5890         /* Activate the external PHY */
5891         bnx2x_ext_phy_reset(params, vars);
5892
5893         bnx2x_set_aer_mmd(params, vars);
5894
5895         if (vars->phy_flags & PHY_XGXS_FLAG)
5896                 bnx2x_set_master_ln(params);
5897
5898         rc = bnx2x_reset_unicore(params);
5899         /* reset the SerDes and wait for reset bit return low */
5900         if (rc != 0)
5901                 return rc;
5902
5903         bnx2x_set_aer_mmd(params, vars);
5904
5905         /* setting the masterLn_def again after the reset */
5906         if (vars->phy_flags & PHY_XGXS_FLAG) {
5907                 bnx2x_set_master_ln(params);
5908                 bnx2x_set_swap_lanes(params);
5909         }
5910
5911         if (vars->phy_flags & PHY_XGXS_FLAG) {
5912                 if ((params->req_line_speed &&
5913                     ((params->req_line_speed == SPEED_100) ||
5914                      (params->req_line_speed == SPEED_10))) ||
5915                     (!params->req_line_speed &&
5916                      (params->speed_cap_mask >=
5917                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5918                      (params->speed_cap_mask <
5919                        PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5920                      ))  {
5921                         vars->phy_flags |= PHY_SGMII_FLAG;
5922                 } else {
5923                         vars->phy_flags &= ~PHY_SGMII_FLAG;
5924                 }
5925         }
5926         /* In case of external phy existance, the line speed would be the
5927          line speed linked up by the external phy. In case it is direct only,
5928           then the line_speed during initialization will be equal to the
5929            req_line_speed*/
5930         vars->line_speed = params->req_line_speed;
5931
5932         bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
5933
5934         /* init ext phy and enable link state int */
5935         non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
5936                        (params->loopback_mode == LOOPBACK_XGXS_10));
5937
5938         if (non_ext_phy ||
5939             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
5940             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
5941             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
5942             (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5943                 if (params->req_line_speed == SPEED_AUTO_NEG)
5944                         bnx2x_set_parallel_detection(params, vars->phy_flags);
5945                 bnx2x_init_internal_phy(params, vars, non_ext_phy);
5946         }
5947
5948         if (!non_ext_phy)
5949                 rc |= bnx2x_ext_phy_init(params, vars);
5950
5951         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5952                      (NIG_STATUS_XGXS0_LINK10G |
5953                       NIG_STATUS_XGXS0_LINK_STATUS |
5954                       NIG_STATUS_SERDES0_LINK_STATUS));
5955
5956         return rc;
5957
5958 }
5959
5960
5961 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
5962 {
5963         struct bnx2x *bp = params->bp;
5964         u32 val;
5965
5966         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
5967         DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
5968                  params->req_line_speed, params->req_flow_ctrl);
5969         vars->link_status = 0;
5970         vars->phy_link_up = 0;
5971         vars->link_up = 0;
5972         vars->line_speed = 0;
5973         vars->duplex = DUPLEX_FULL;
5974         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5975         vars->mac_type = MAC_TYPE_NONE;
5976
5977         if (params->switch_cfg ==  SWITCH_CFG_1G)
5978                 vars->phy_flags = PHY_SERDES_FLAG;
5979         else
5980                 vars->phy_flags = PHY_XGXS_FLAG;
5981
5982         /* disable attentions */
5983         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
5984                        (NIG_MASK_XGXS0_LINK_STATUS |
5985                         NIG_MASK_XGXS0_LINK10G |
5986                         NIG_MASK_SERDES0_LINK_STATUS |
5987                         NIG_MASK_MI_INT));
5988
5989         bnx2x_emac_init(params, vars);
5990
5991         if (CHIP_REV_IS_FPGA(bp)) {
5992
5993                 vars->link_up = 1;
5994                 vars->line_speed = SPEED_10000;
5995                 vars->duplex = DUPLEX_FULL;
5996                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5997                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5998                 /* enable on E1.5 FPGA */
5999                 if (CHIP_IS_E1H(bp)) {
6000                         vars->flow_ctrl |=
6001                                         (BNX2X_FLOW_CTRL_TX |
6002                                          BNX2X_FLOW_CTRL_RX);
6003                         vars->link_status |=
6004                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
6005                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
6006                 }
6007
6008                 bnx2x_emac_enable(params, vars, 0);
6009                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6010                 /* disable drain */
6011                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
6012
6013                 /* update shared memory */
6014                 bnx2x_update_mng(params, vars->link_status);
6015
6016                 return 0;
6017
6018         } else
6019         if (CHIP_REV_IS_EMUL(bp)) {
6020
6021                 vars->link_up = 1;
6022                 vars->line_speed = SPEED_10000;
6023                 vars->duplex = DUPLEX_FULL;
6024                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6025                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6026
6027                 bnx2x_bmac_enable(params, vars, 0);
6028
6029                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6030                 /* Disable drain */
6031                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
6032                                     + params->port*4, 0);
6033
6034                 /* update shared memory */
6035                 bnx2x_update_mng(params, vars->link_status);
6036
6037                 return 0;
6038
6039         } else
6040         if (params->loopback_mode == LOOPBACK_BMAC) {
6041
6042                 vars->link_up = 1;
6043                 vars->line_speed = SPEED_10000;
6044                 vars->duplex = DUPLEX_FULL;
6045                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6046                 vars->mac_type = MAC_TYPE_BMAC;
6047
6048                 vars->phy_flags = PHY_XGXS_FLAG;
6049
6050                 bnx2x_phy_deassert(params, vars->phy_flags);
6051                 /* set bmac loopback */
6052                 bnx2x_bmac_enable(params, vars, 1);
6053
6054                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6055                     params->port*4, 0);
6056
6057         } else if (params->loopback_mode == LOOPBACK_EMAC) {
6058
6059                 vars->link_up = 1;
6060                 vars->line_speed = SPEED_1000;
6061                 vars->duplex = DUPLEX_FULL;
6062                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6063                 vars->mac_type = MAC_TYPE_EMAC;
6064
6065                 vars->phy_flags = PHY_XGXS_FLAG;
6066
6067                 bnx2x_phy_deassert(params, vars->phy_flags);
6068                 /* set bmac loopback */
6069                 bnx2x_emac_enable(params, vars, 1);
6070                 bnx2x_emac_program(params, vars->line_speed,
6071                                               vars->duplex);
6072                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6073                     params->port*4, 0);
6074
6075         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
6076                    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6077
6078                 vars->link_up = 1;
6079                 vars->line_speed = SPEED_10000;
6080                 vars->duplex = DUPLEX_FULL;
6081                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6082
6083                 vars->phy_flags = PHY_XGXS_FLAG;
6084
6085                 val = REG_RD(bp,
6086                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
6087                                  params->port*0x18);
6088                 params->phy_addr = (u8)val;
6089
6090                 bnx2x_phy_deassert(params, vars->phy_flags);
6091                 bnx2x_link_initialize(params, vars);
6092
6093                 vars->mac_type = MAC_TYPE_BMAC;
6094
6095                 bnx2x_bmac_enable(params, vars, 0);
6096
6097                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
6098                         /* set 10G XGXS loopback */
6099                         bnx2x_set_xgxs_loopback(params, vars, 1);
6100                 } else {
6101                         /* set external phy loopback */
6102                         bnx2x_ext_phy_loopback(params);
6103                 }
6104                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6105                             params->port*4, 0);
6106
6107                 bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed);
6108         } else
6109         /* No loopback */
6110         {
6111                 bnx2x_phy_deassert(params, vars->phy_flags);
6112                 switch (params->switch_cfg) {
6113                 case SWITCH_CFG_1G:
6114                         vars->phy_flags |= PHY_SERDES_FLAG;
6115                         if ((params->ext_phy_config &
6116                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
6117                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
6118                                 vars->phy_flags |= PHY_SGMII_FLAG;
6119                         }
6120
6121                         val = REG_RD(bp,
6122                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
6123                                          params->port*0x10);
6124
6125                         params->phy_addr = (u8)val;
6126
6127                         break;
6128                 case SWITCH_CFG_10G:
6129                         vars->phy_flags |= PHY_XGXS_FLAG;
6130                         val = REG_RD(bp,
6131                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
6132                                  params->port*0x18);
6133                         params->phy_addr = (u8)val;
6134
6135                         break;
6136                 default:
6137                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
6138                         return -EINVAL;
6139                 }
6140                 DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
6141
6142                 bnx2x_link_initialize(params, vars);
6143                 msleep(30);
6144                 bnx2x_link_int_enable(params);
6145         }
6146         return 0;
6147 }
6148
6149 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
6150 {
6151         DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
6152
6153         /* Set serial boot control for external load */
6154         bnx2x_cl45_write(bp, port,
6155                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
6156                        MDIO_PMA_DEVAD,
6157                        MDIO_PMA_REG_GEN_CTRL, 0x0001);
6158 }
6159
6160 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6161                   u8 reset_ext_phy)
6162 {
6163         struct bnx2x *bp = params->bp;
6164         u32 ext_phy_config = params->ext_phy_config;
6165         u8 port = params->port;
6166         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6167         u32 val = REG_RD(bp, params->shmem_base +
6168                              offsetof(struct shmem_region, dev_info.
6169                                       port_feature_config[params->port].
6170                                       config));
6171         DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
6172         /* disable attentions */
6173         vars->link_status = 0;
6174         bnx2x_update_mng(params, vars->link_status);
6175         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6176                      (NIG_MASK_XGXS0_LINK_STATUS |
6177                       NIG_MASK_XGXS0_LINK10G |
6178                       NIG_MASK_SERDES0_LINK_STATUS |
6179                       NIG_MASK_MI_INT));
6180
6181         /* activate nig drain */
6182         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6183
6184         /* disable nig egress interface */
6185         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6186         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6187
6188         /* Stop BigMac rx */
6189         bnx2x_bmac_rx_disable(bp, port);
6190
6191         /* disable emac */
6192         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6193
6194         msleep(10);
6195         /* The PHY reset is controled by GPIO 1
6196          * Hold it as vars low
6197          */
6198          /* clear link led */
6199         bnx2x_set_led(params, LED_MODE_OFF, 0);
6200         if (reset_ext_phy) {
6201                 switch (ext_phy_type) {
6202                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
6203                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
6204                         break;
6205
6206                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6207                 {
6208
6209                         /* Disable Transmitter */
6210                         u8 ext_phy_addr =
6211                                 XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6212                         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
6213                             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
6214                                 bnx2x_sfp_set_transmitter(bp, port,
6215                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6216                                         ext_phy_addr, 0);
6217                         break;
6218                 }
6219                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6220                         DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
6221                                  "low power mode\n",
6222                                  port);
6223                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6224                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6225                                           port);
6226                         break;
6227                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6228                 {
6229                         u8 ext_phy_addr =
6230                                 XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6231                         /* Set soft reset */
6232                         bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
6233                         break;
6234                 }
6235                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
6236                 {
6237                         u8 ext_phy_addr =
6238                                 XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6239                         bnx2x_cl45_write(bp, port,
6240                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6241                                        ext_phy_addr,
6242                                        MDIO_AN_DEVAD,
6243                                        MDIO_AN_REG_CTRL, 0x0000);
6244                         bnx2x_cl45_write(bp, port,
6245                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6246                                        ext_phy_addr,
6247                                        MDIO_PMA_DEVAD,
6248                                        MDIO_PMA_REG_CTRL, 1);
6249                         break;
6250                 }
6251                 default:
6252                         /* HW reset */
6253                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6254                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6255                                           port);
6256                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6257                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6258                                           port);
6259                         DP(NETIF_MSG_LINK, "reset external PHY\n");
6260                 }
6261         }
6262         /* reset the SerDes/XGXS */
6263         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6264                (0x1ff << (port*16)));
6265
6266         /* reset BigMac */
6267         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
6268                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6269
6270         /* disable nig ingress interface */
6271         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
6272         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
6273         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6274         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6275         vars->link_up = 0;
6276         return 0;
6277 }
6278
6279 static u8 bnx2x_update_link_down(struct link_params *params,
6280                                struct link_vars *vars)
6281 {
6282         struct bnx2x *bp = params->bp;
6283         u8 port = params->port;
6284
6285         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
6286         bnx2x_set_led(params, LED_MODE_OFF, 0);
6287
6288         /* indicate no mac active */
6289         vars->mac_type = MAC_TYPE_NONE;
6290
6291         /* update shared memory */
6292         vars->link_status = 0;
6293         vars->line_speed = 0;
6294         bnx2x_update_mng(params, vars->link_status);
6295
6296         /* activate nig drain */
6297         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6298
6299         /* disable emac */
6300         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6301
6302         msleep(10);
6303
6304         /* reset BigMac */
6305         bnx2x_bmac_rx_disable(bp, params->port);
6306         REG_WR(bp, GRCBASE_MISC +
6307                    MISC_REGISTERS_RESET_REG_2_CLEAR,
6308                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6309         return 0;
6310 }
6311
6312 static u8 bnx2x_update_link_up(struct link_params *params,
6313                              struct link_vars *vars,
6314                              u8 link_10g, u32 gp_status)
6315 {
6316         struct bnx2x *bp = params->bp;
6317         u8 port = params->port;
6318         u8 rc = 0;
6319
6320         vars->link_status |= LINK_STATUS_LINK_UP;
6321         if (link_10g) {
6322                 bnx2x_bmac_enable(params, vars, 0);
6323                 bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000);
6324         } else {
6325                 rc = bnx2x_emac_program(params, vars->line_speed,
6326                                       vars->duplex);
6327
6328                 bnx2x_emac_enable(params, vars, 0);
6329
6330                 /* AN complete? */
6331                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
6332                         if (!(vars->phy_flags &
6333                               PHY_SGMII_FLAG))
6334                                 bnx2x_set_gmii_tx_driver(params);
6335                 }
6336         }
6337
6338         /* PBF - link up */
6339         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6340                               vars->line_speed);
6341
6342         /* disable drain */
6343         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6344
6345         /* update shared memory */
6346         bnx2x_update_mng(params, vars->link_status);
6347         msleep(20);
6348         return rc;
6349 }
6350 /* This function should called upon link interrupt */
6351 /* In case vars->link_up, driver needs to
6352         1. Update the pbf
6353         2. Disable drain
6354         3. Update the shared memory
6355         4. Indicate link up
6356         5. Set LEDs
6357    Otherwise,
6358         1. Update shared memory
6359         2. Reset BigMac
6360         3. Report link down
6361         4. Unset LEDs
6362 */
6363 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6364 {
6365         struct bnx2x *bp = params->bp;
6366         u8 port = params->port;
6367         u16 gp_status;
6368         u8 link_10g;
6369         u8 ext_phy_link_up, rc = 0;
6370         u32 ext_phy_type;
6371         u8 is_mi_int = 0;
6372
6373         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6374                  port, (vars->phy_flags & PHY_XGXS_FLAG),
6375                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6376
6377         is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6378                                     port*0x18) > 0);
6379         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6380                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6381                  is_mi_int,
6382                  REG_RD(bp,
6383                             NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6384
6385         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6386           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6387           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6388
6389         /* disable emac */
6390         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6391
6392         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
6393
6394         /* Check external link change only for non-direct */
6395         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int);
6396
6397         /* Read gp_status */
6398         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
6399                               MDIO_REG_BANK_GP_STATUS,
6400                               MDIO_GP_STATUS_TOP_AN_STATUS1,
6401                               &gp_status);
6402
6403         rc = bnx2x_link_settings_status(params, vars, gp_status,
6404                                       ext_phy_link_up);
6405         if (rc != 0)
6406                 return rc;
6407
6408         /* anything 10 and over uses the bmac */
6409         link_10g = ((vars->line_speed == SPEED_10000) ||
6410                     (vars->line_speed == SPEED_12000) ||
6411                     (vars->line_speed == SPEED_12500) ||
6412                     (vars->line_speed == SPEED_13000) ||
6413                     (vars->line_speed == SPEED_15000) ||
6414                     (vars->line_speed == SPEED_16000));
6415
6416         bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
6417
6418         /* In case external phy link is up, and internal link is down
6419         ( not initialized yet probably after link initialization, it needs
6420         to be initialized.
6421         Note that after link down-up as result of cable plug,
6422         the xgxs link would probably become up again without the need to
6423         initialize it*/
6424
6425         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
6426             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
6427             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) &&
6428             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
6429             (ext_phy_link_up && !vars->phy_link_up))
6430                 bnx2x_init_internal_phy(params, vars, 0);
6431
6432         /* link is up only if both local phy and external phy are up */
6433         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
6434
6435         if (vars->link_up)
6436                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
6437         else
6438                 rc = bnx2x_update_link_down(params, vars);
6439
6440         return rc;
6441 }
6442
6443 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6444 {
6445         u8 ext_phy_addr[PORT_MAX];
6446         u16 val;
6447         s8 port;
6448
6449         /* PART1 - Reset both phys */
6450         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6451                 /* Extract the ext phy address for the port */
6452                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6453                                         offsetof(struct shmem_region,
6454                    dev_info.port_hw_config[port].external_phy_config));
6455
6456                 /* disable attentions */
6457                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6458                              (NIG_MASK_XGXS0_LINK_STATUS |
6459                               NIG_MASK_XGXS0_LINK10G |
6460                               NIG_MASK_SERDES0_LINK_STATUS |
6461                               NIG_MASK_MI_INT));
6462
6463                 ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
6464
6465                 /* Need to take the phy out of low power mode in order
6466                         to write to access its registers */
6467                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6468                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6469
6470                 /* Reset the phy */
6471                 bnx2x_cl45_write(bp, port,
6472                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6473                                ext_phy_addr[port],
6474                                MDIO_PMA_DEVAD,
6475                                MDIO_PMA_REG_CTRL,
6476                                1<<15);
6477         }
6478
6479         /* Add delay of 150ms after reset */
6480         msleep(150);
6481
6482         /* PART2 - Download firmware to both phys */
6483         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6484                 u16 fw_ver1;
6485
6486                 bnx2x_bcm8073_external_rom_boot(bp, port,
6487                                               ext_phy_addr[port], shmem_base);
6488
6489                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6490                               ext_phy_addr[port],
6491                               MDIO_PMA_DEVAD,
6492                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6493                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6494                         DP(NETIF_MSG_LINK,
6495                                  "bnx2x_8073_common_init_phy port %x:"
6496                                  "Download failed. fw version = 0x%x\n",
6497                                  port, fw_ver1);
6498                         return -EINVAL;
6499                 }
6500
6501                 /* Only set bit 10 = 1 (Tx power down) */
6502                 bnx2x_cl45_read(bp, port,
6503                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6504                               ext_phy_addr[port],
6505                               MDIO_PMA_DEVAD,
6506                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
6507
6508                 /* Phase1 of TX_POWER_DOWN reset */
6509                 bnx2x_cl45_write(bp, port,
6510                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6511                                ext_phy_addr[port],
6512                                MDIO_PMA_DEVAD,
6513                                MDIO_PMA_REG_TX_POWER_DOWN,
6514                                (val | 1<<10));
6515         }
6516
6517         /* Toggle Transmitter: Power down and then up with 600ms
6518            delay between */
6519         msleep(600);
6520
6521         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
6522         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6523                 /* Phase2 of POWER_DOWN_RESET */
6524                 /* Release bit 10 (Release Tx power down) */
6525                 bnx2x_cl45_read(bp, port,
6526                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6527                               ext_phy_addr[port],
6528                               MDIO_PMA_DEVAD,
6529                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
6530
6531                 bnx2x_cl45_write(bp, port,
6532                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6533                                ext_phy_addr[port],
6534                                MDIO_PMA_DEVAD,
6535                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
6536                 msleep(15);
6537
6538                 /* Read modify write the SPI-ROM version select register */
6539                 bnx2x_cl45_read(bp, port,
6540                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6541                               ext_phy_addr[port],
6542                               MDIO_PMA_DEVAD,
6543                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
6544                 bnx2x_cl45_write(bp, port,
6545                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6546                               ext_phy_addr[port],
6547                               MDIO_PMA_DEVAD,
6548                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
6549
6550                 /* set GPIO2 back to LOW */
6551                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6552                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6553         }
6554         return 0;
6555
6556 }
6557
6558 static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6559 {
6560         u8 ext_phy_addr[PORT_MAX];
6561         s8 port, first_port, i;
6562         u32 swap_val, swap_override;
6563         DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
6564         swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
6565         swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
6566
6567         bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override));
6568         msleep(5);
6569
6570         if (swap_val && swap_override)
6571                 first_port = PORT_0;
6572         else
6573                 first_port = PORT_1;
6574
6575         /* PART1 - Reset both phys */
6576         for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
6577                 /* Extract the ext phy address for the port */
6578                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6579                                         offsetof(struct shmem_region,
6580                    dev_info.port_hw_config[port].external_phy_config));
6581
6582                 /* disable attentions */
6583                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6584                              (NIG_MASK_XGXS0_LINK_STATUS |
6585                               NIG_MASK_XGXS0_LINK10G |
6586                               NIG_MASK_SERDES0_LINK_STATUS |
6587                               NIG_MASK_MI_INT));
6588
6589                 ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
6590
6591                 /* Reset the phy */
6592                 bnx2x_cl45_write(bp, port,
6593                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6594                                ext_phy_addr[port],
6595                                MDIO_PMA_DEVAD,
6596                                MDIO_PMA_REG_CTRL,
6597                                1<<15);
6598         }
6599
6600         /* Add delay of 150ms after reset */
6601         msleep(150);
6602
6603         /* PART2 - Download firmware to both phys */
6604         for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
6605                 u16 fw_ver1;
6606
6607                 bnx2x_bcm8727_external_rom_boot(bp, port,
6608                                               ext_phy_addr[port], shmem_base);
6609
6610                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6611                               ext_phy_addr[port],
6612                               MDIO_PMA_DEVAD,
6613                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6614                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6615                         DP(NETIF_MSG_LINK,
6616                                  "bnx2x_8727_common_init_phy port %x:"
6617                                  "Download failed. fw version = 0x%x\n",
6618                                  port, fw_ver1);
6619                         return -EINVAL;
6620                 }
6621         }
6622
6623         return 0;
6624 }
6625
6626
6627 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6628 {
6629         u8 ext_phy_addr;
6630         u32 val;
6631         s8 port;
6632
6633         /* Use port1 because of the static port-swap */
6634         /* Enable the module detection interrupt */
6635         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
6636         val |= ((1<<MISC_REGISTERS_GPIO_3)|
6637                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
6638         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
6639
6640         bnx2x_ext_phy_hw_reset(bp, 1);
6641         msleep(5);
6642         for (port = 0; port < PORT_MAX; port++) {
6643                 /* Extract the ext phy address for the port */
6644                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6645                                         offsetof(struct shmem_region,
6646                         dev_info.port_hw_config[port].external_phy_config));
6647
6648                 ext_phy_addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
6649                 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
6650                          ext_phy_addr);
6651
6652                 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
6653
6654                 /* Set fault module detected LED on */
6655                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6656                                   MISC_REGISTERS_GPIO_HIGH,
6657                                   port);
6658         }
6659
6660         return 0;
6661 }
6662
6663
6664 static u8 bnx2x_84823_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6665 {
6666         /* HW reset */
6667         bnx2x_ext_phy_hw_reset(bp, 1);
6668         return 0;
6669 }
6670 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6671 {
6672         u8 rc = 0;
6673         u32 ext_phy_type;
6674
6675         DP(NETIF_MSG_LINK, "Begin common phy init\n");
6676
6677         /* Read the ext_phy_type for arbitrary port(0) */
6678         ext_phy_type = XGXS_EXT_PHY_TYPE(
6679                         REG_RD(bp, shmem_base +
6680                            offsetof(struct shmem_region,
6681                              dev_info.port_hw_config[0].external_phy_config)));
6682
6683         switch (ext_phy_type) {
6684         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6685         {
6686                 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
6687                 break;
6688         }
6689
6690         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6691         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6692                 rc = bnx2x_8727_common_init_phy(bp, shmem_base);
6693                 break;
6694
6695         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6696                 /* GPIO1 affects both ports, so there's need to pull
6697                 it for single port alone */
6698                 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
6699                 break;
6700         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
6701                 rc = bnx2x_84823_common_init_phy(bp, shmem_base);
6702                 break;
6703         default:
6704                 DP(NETIF_MSG_LINK,
6705                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
6706                          ext_phy_type);
6707                 break;
6708         }
6709
6710         return rc;
6711 }
6712
6713 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
6714 {
6715         u16 val, cnt;
6716
6717         bnx2x_cl45_read(bp, port,
6718                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6719                       phy_addr,
6720                       MDIO_PMA_DEVAD,
6721                       MDIO_PMA_REG_7101_RESET, &val);
6722
6723         for (cnt = 0; cnt < 10; cnt++) {
6724                 msleep(50);
6725                 /* Writes a self-clearing reset */
6726                 bnx2x_cl45_write(bp, port,
6727                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6728                                phy_addr,
6729                                MDIO_PMA_DEVAD,
6730                                MDIO_PMA_REG_7101_RESET,
6731                                (val | (1<<15)));
6732                 /* Wait for clear */
6733                 bnx2x_cl45_read(bp, port,
6734                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6735                               phy_addr,
6736                               MDIO_PMA_DEVAD,
6737                               MDIO_PMA_REG_7101_RESET, &val);
6738
6739                 if ((val & (1<<15)) == 0)
6740                         break;
6741         }
6742 }