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