9e1f19a00ab1f8042c543f7e0209aebb7aa9d627
[pandora-kernel.git] / 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 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2050 {
2051         struct bnx2x *bp = params->bp;
2052         u8 port = params->port;
2053         u8 ext_phy_addr = ((params->ext_phy_config &
2054                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2055                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2056         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2057
2058         /* Need to wait 200ms after reset */
2059         msleep(200);
2060         /* Boot port from external ROM
2061          * Set ser_boot_ctl bit in the MISC_CTRL1 register
2062          */
2063         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2064                             MDIO_PMA_DEVAD,
2065                             MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2066
2067         /* Reset internal microprocessor */
2068         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2069                           MDIO_PMA_DEVAD,
2070                           MDIO_PMA_REG_GEN_CTRL,
2071                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2072         /* set micro reset = 0 */
2073         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2074                             MDIO_PMA_DEVAD,
2075                             MDIO_PMA_REG_GEN_CTRL,
2076                             MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2077         /* Reset internal microprocessor */
2078         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2079                           MDIO_PMA_DEVAD,
2080                           MDIO_PMA_REG_GEN_CTRL,
2081                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2082         /* wait for 100ms for code download via SPI port */
2083         msleep(100);
2084
2085         /* Clear ser_boot_ctl bit */
2086         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2087                             MDIO_PMA_DEVAD,
2088                             MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2089         /* Wait 100ms */
2090         msleep(100);
2091
2092         bnx2x_save_bcm_spirom_ver(bp, port,
2093                                 ext_phy_type,
2094                                 ext_phy_addr,
2095                                 params->shmem_base);
2096 }
2097
2098 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2099 {
2100         /* This is only required for 8073A1, version 102 only */
2101
2102         struct bnx2x *bp = params->bp;
2103         u8 ext_phy_addr = ((params->ext_phy_config &
2104                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2105                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2106         u16 val;
2107
2108         /* Read 8073 HW revision*/
2109         bnx2x_cl45_read(bp, params->port,
2110                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2111                       ext_phy_addr,
2112                       MDIO_PMA_DEVAD,
2113                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2114
2115         if (val != 1) {
2116                 /* No need to workaround in 8073 A1 */
2117                 return 0;
2118         }
2119
2120         bnx2x_cl45_read(bp, params->port,
2121                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2122                       ext_phy_addr,
2123                       MDIO_PMA_DEVAD,
2124                       MDIO_PMA_REG_ROM_VER2, &val);
2125
2126         /* SNR should be applied only for version 0x102 */
2127         if (val != 0x102)
2128                 return 0;
2129
2130         return 1;
2131 }
2132
2133 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2134 {
2135         struct bnx2x *bp = params->bp;
2136         u8 ext_phy_addr = ((params->ext_phy_config &
2137                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2138                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2139         u16 val, cnt, cnt1 ;
2140
2141         bnx2x_cl45_read(bp, params->port,
2142                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2143                       ext_phy_addr,
2144                       MDIO_PMA_DEVAD,
2145                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2146
2147         if (val > 0) {
2148                 /* No need to workaround in 8073 A1 */
2149                 return 0;
2150         }
2151         /* XAUI workaround in 8073 A0: */
2152
2153         /* After loading the boot ROM and restarting Autoneg,
2154         poll Dev1, Reg $C820: */
2155
2156         for (cnt = 0; cnt < 1000; cnt++) {
2157                 bnx2x_cl45_read(bp, params->port,
2158                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2159                               ext_phy_addr,
2160                               MDIO_PMA_DEVAD,
2161                               MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
2162                               &val);
2163                   /* If bit [14] = 0 or bit [13] = 0, continue on with
2164                    system initialization (XAUI work-around not required,
2165                     as these bits indicate 2.5G or 1G link up). */
2166                 if (!(val & (1<<14)) || !(val & (1<<13))) {
2167                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2168                         return 0;
2169                 } else if (!(val & (1<<15))) {
2170                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2171                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2172                           it's MSB (bit 15) goes to 1 (indicating that the
2173                           XAUI workaround has completed),
2174                           then continue on with system initialization.*/
2175                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2176                                 bnx2x_cl45_read(bp, params->port,
2177                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2178                                         ext_phy_addr,
2179                                         MDIO_PMA_DEVAD,
2180                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
2181                                 if (val & (1<<15)) {
2182                                         DP(NETIF_MSG_LINK,
2183                                           "XAUI workaround has completed\n");
2184                                         return 0;
2185                                  }
2186                                  msleep(3);
2187                         }
2188                         break;
2189                 }
2190                 msleep(3);
2191         }
2192         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2193         return -EINVAL;
2194
2195 }
2196
2197 static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
2198                                                   u8 ext_phy_addr,
2199                                                   u32 ext_phy_type,
2200                                                   u32 shmem_base)
2201 {
2202         /* Boot port from external ROM  */
2203         /* EDC grst */
2204         bnx2x_cl45_write(bp, port,
2205                        ext_phy_type,
2206                        ext_phy_addr,
2207                        MDIO_PMA_DEVAD,
2208                        MDIO_PMA_REG_GEN_CTRL,
2209                        0x0001);
2210
2211         /* ucode reboot and rst */
2212         bnx2x_cl45_write(bp, port,
2213                        ext_phy_type,
2214                        ext_phy_addr,
2215                        MDIO_PMA_DEVAD,
2216                        MDIO_PMA_REG_GEN_CTRL,
2217                        0x008c);
2218
2219         bnx2x_cl45_write(bp, port,
2220                        ext_phy_type,
2221                        ext_phy_addr,
2222                        MDIO_PMA_DEVAD,
2223                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2224
2225         /* Reset internal microprocessor */
2226         bnx2x_cl45_write(bp, port,
2227                        ext_phy_type,
2228                        ext_phy_addr,
2229                        MDIO_PMA_DEVAD,
2230                        MDIO_PMA_REG_GEN_CTRL,
2231                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2232
2233         /* Release srst bit */
2234         bnx2x_cl45_write(bp, port,
2235                        ext_phy_type,
2236                        ext_phy_addr,
2237                        MDIO_PMA_DEVAD,
2238                        MDIO_PMA_REG_GEN_CTRL,
2239                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2240
2241         /* wait for 100ms for code download via SPI port */
2242         msleep(100);
2243
2244         /* Clear ser_boot_ctl bit */
2245         bnx2x_cl45_write(bp, port,
2246                        ext_phy_type,
2247                        ext_phy_addr,
2248                        MDIO_PMA_DEVAD,
2249                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2250
2251         bnx2x_save_bcm_spirom_ver(bp, port,
2252                                 ext_phy_type,
2253                                 ext_phy_addr,
2254                                 shmem_base);
2255 }
2256
2257 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2258                                           u8 ext_phy_addr,
2259                                           u32 shmem_base)
2260 {
2261         bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
2262                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2263                                          shmem_base);
2264 }
2265
2266 static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
2267                                           u8 ext_phy_addr,
2268                                           u32 shmem_base)
2269 {
2270         bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
2271                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2272                                          shmem_base);
2273
2274 }
2275
2276 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2277 {
2278         struct bnx2x *bp = params->bp;
2279         u8 port = params->port;
2280         u8 ext_phy_addr = ((params->ext_phy_config &
2281                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2282                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2283         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2284
2285         /* Need to wait 100ms after reset */
2286         msleep(100);
2287
2288         /* Set serial boot control for external load */
2289         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2290                        MDIO_PMA_DEVAD,
2291                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2292
2293         /* Micro controller re-boot */
2294         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2295                        MDIO_PMA_DEVAD,
2296                        MDIO_PMA_REG_GEN_CTRL,
2297                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2298
2299         /* Set soft reset */
2300         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2301                        MDIO_PMA_DEVAD,
2302                        MDIO_PMA_REG_GEN_CTRL,
2303                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2304
2305         /* Set PLL register value to be same like in P13 ver */
2306         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2307                        MDIO_PMA_DEVAD,
2308                        MDIO_PMA_REG_PLL_CTRL,
2309                        0x73A0);
2310
2311         /* Clear soft reset.
2312         Will automatically reset micro-controller re-boot */
2313         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2314                        MDIO_PMA_DEVAD,
2315                        MDIO_PMA_REG_GEN_CTRL,
2316                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2317
2318         /* wait for 150ms for microcode load */
2319         msleep(150);
2320
2321         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2322         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2323                        MDIO_PMA_DEVAD,
2324                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2325
2326         msleep(200);
2327         bnx2x_save_bcm_spirom_ver(bp, port,
2328                                 ext_phy_type,
2329                                 ext_phy_addr,
2330                                 params->shmem_base);
2331 }
2332
2333 static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port,
2334                                     u32 ext_phy_type, u8 ext_phy_addr,
2335                                     u8 tx_en)
2336 {
2337         u16 val;
2338         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2339                  tx_en, port);
2340         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2341         bnx2x_cl45_read(bp, port,
2342                       ext_phy_type,
2343                       ext_phy_addr,
2344                       MDIO_PMA_DEVAD,
2345                       MDIO_PMA_REG_PHY_IDENTIFIER,
2346                       &val);
2347
2348         if (tx_en)
2349                 val &= ~(1<<15);
2350         else
2351                 val |= (1<<15);
2352
2353         bnx2x_cl45_write(bp, port,
2354                        ext_phy_type,
2355                        ext_phy_addr,
2356                        MDIO_PMA_DEVAD,
2357                        MDIO_PMA_REG_PHY_IDENTIFIER,
2358                        val);
2359 }
2360
2361 static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
2362                                           u16 addr, u8 byte_cnt, u8 *o_buf)
2363 {
2364         struct bnx2x *bp = params->bp;
2365         u16 val = 0;
2366         u16 i;
2367         u8 port = params->port;
2368         u8 ext_phy_addr = ((params->ext_phy_config &
2369                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2370                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2371         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2372         if (byte_cnt > 16) {
2373                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2374                             " is limited to 0xf\n");
2375                 return -EINVAL;
2376         }
2377         /* Set the read command byte count */
2378         bnx2x_cl45_write(bp, port,
2379                        ext_phy_type,
2380                        ext_phy_addr,
2381                        MDIO_PMA_DEVAD,
2382                        MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2383                        (byte_cnt | 0xa000));
2384
2385         /* Set the read command address */
2386         bnx2x_cl45_write(bp, port,
2387                        ext_phy_type,
2388                        ext_phy_addr,
2389                        MDIO_PMA_DEVAD,
2390                        MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2391                        addr);
2392
2393         /* Activate read command */
2394         bnx2x_cl45_write(bp, port,
2395                        ext_phy_type,
2396                        ext_phy_addr,
2397                        MDIO_PMA_DEVAD,
2398                        MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2399                        0x2c0f);
2400
2401         /* Wait up to 500us for command complete status */
2402         for (i = 0; i < 100; i++) {
2403                 bnx2x_cl45_read(bp, port,
2404                               ext_phy_type,
2405                               ext_phy_addr,
2406                               MDIO_PMA_DEVAD,
2407                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2408                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2409                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2410                         break;
2411                 udelay(5);
2412         }
2413
2414         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2415                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2416                 DP(NETIF_MSG_LINK,
2417                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2418                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2419                 return -EINVAL;
2420         }
2421
2422         /* Read the buffer */
2423         for (i = 0; i < byte_cnt; i++) {
2424                 bnx2x_cl45_read(bp, port,
2425                               ext_phy_type,
2426                               ext_phy_addr,
2427                               MDIO_PMA_DEVAD,
2428                               MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2429                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2430         }
2431
2432         for (i = 0; i < 100; i++) {
2433                 bnx2x_cl45_read(bp, port,
2434                               ext_phy_type,
2435                               ext_phy_addr,
2436                               MDIO_PMA_DEVAD,
2437                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2438                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2439                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2440                         return 0;;
2441                 msleep(1);
2442         }
2443         return -EINVAL;
2444 }
2445
2446 static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
2447                                           u16 addr, u8 byte_cnt, u8 *o_buf)
2448 {
2449         struct bnx2x *bp = params->bp;
2450         u16 val, i;
2451         u8 port = params->port;
2452         u8 ext_phy_addr = ((params->ext_phy_config &
2453                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2454                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2455         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2456
2457         if (byte_cnt > 16) {
2458                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2459                             " is limited to 0xf\n");
2460                 return -EINVAL;
2461         }
2462
2463         /* Need to read from 1.8000 to clear it */
2464         bnx2x_cl45_read(bp, port,
2465                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2466                       ext_phy_addr,
2467                       MDIO_PMA_DEVAD,
2468                       MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2469                       &val);
2470
2471         /* Set the read command byte count */
2472         bnx2x_cl45_write(bp, port,
2473                        ext_phy_type,
2474                        ext_phy_addr,
2475                        MDIO_PMA_DEVAD,
2476                        MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2477                        ((byte_cnt < 2) ? 2 : byte_cnt));
2478
2479         /* Set the read command address */
2480         bnx2x_cl45_write(bp, port,
2481                        ext_phy_type,
2482                        ext_phy_addr,
2483                        MDIO_PMA_DEVAD,
2484                        MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2485                        addr);
2486         /* Set the destination address */
2487         bnx2x_cl45_write(bp, port,
2488                        ext_phy_type,
2489                        ext_phy_addr,
2490                        MDIO_PMA_DEVAD,
2491                        0x8004,
2492                        MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
2493
2494         /* Activate read command */
2495         bnx2x_cl45_write(bp, port,
2496                        ext_phy_type,
2497                        ext_phy_addr,
2498                        MDIO_PMA_DEVAD,
2499                        MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2500                        0x8002);
2501         /* Wait appropriate time for two-wire command to finish before
2502         polling the status register */
2503         msleep(1);
2504
2505         /* Wait up to 500us for command complete status */
2506         for (i = 0; i < 100; i++) {
2507                 bnx2x_cl45_read(bp, port,
2508                               ext_phy_type,
2509                               ext_phy_addr,
2510                               MDIO_PMA_DEVAD,
2511                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2512                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2513                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2514                         break;
2515                 udelay(5);
2516         }
2517
2518         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2519                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2520                 DP(NETIF_MSG_LINK,
2521                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2522                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2523                 return -EINVAL;
2524         }
2525
2526         /* Read the buffer */
2527         for (i = 0; i < byte_cnt; i++) {
2528                 bnx2x_cl45_read(bp, port,
2529                               ext_phy_type,
2530                               ext_phy_addr,
2531                               MDIO_PMA_DEVAD,
2532                               MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
2533                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
2534         }
2535
2536         for (i = 0; i < 100; i++) {
2537                 bnx2x_cl45_read(bp, port,
2538                               ext_phy_type,
2539                               ext_phy_addr,
2540                               MDIO_PMA_DEVAD,
2541                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2542                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2543                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2544                         return 0;;
2545                 msleep(1);
2546         }
2547
2548         return -EINVAL;
2549 }
2550
2551 u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2552                                      u8 byte_cnt, u8 *o_buf)
2553 {
2554         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2555
2556         if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
2557                 return bnx2x_8726_read_sfp_module_eeprom(params, addr,
2558                                                        byte_cnt, o_buf);
2559         else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
2560                 return bnx2x_8727_read_sfp_module_eeprom(params, addr,
2561                                                        byte_cnt, o_buf);
2562         return -EINVAL;
2563 }
2564
2565 static u8 bnx2x_get_edc_mode(struct link_params *params,
2566                                   u16 *edc_mode)
2567 {
2568         struct bnx2x *bp = params->bp;
2569         u8 val, check_limiting_mode = 0;
2570         *edc_mode = EDC_MODE_LIMITING;
2571
2572         /* First check for copper cable */
2573         if (bnx2x_read_sfp_module_eeprom(params,
2574                                        SFP_EEPROM_CON_TYPE_ADDR,
2575                                        1,
2576                                        &val) != 0) {
2577                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
2578                 return -EINVAL;
2579         }
2580
2581         switch (val) {
2582         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2583         {
2584                 u8 copper_module_type;
2585                 /* Check if its active cable( includes SFP+ module)
2586                 of passive cable*/
2587                 if (bnx2x_read_sfp_module_eeprom(params,
2588                                                SFP_EEPROM_FC_TX_TECH_ADDR,
2589                                                1,
2590                                                &copper_module_type) !=
2591                     0) {
2592                         DP(NETIF_MSG_LINK,
2593                                 "Failed to read copper-cable-type"
2594                                 " from SFP+ EEPROM\n");
2595                         return -EINVAL;
2596                 }
2597
2598                 if (copper_module_type &
2599                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2600                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2601                         check_limiting_mode = 1;
2602                 } else if (copper_module_type &
2603                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2604                                 DP(NETIF_MSG_LINK, "Passive Copper"
2605                                             " cable detected\n");
2606                                 *edc_mode =
2607                                       EDC_MODE_PASSIVE_DAC;
2608                 } else {
2609                         DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2610                                      "type 0x%x !!!\n", copper_module_type);
2611                         return -EINVAL;
2612                 }
2613                 break;
2614         }
2615         case SFP_EEPROM_CON_TYPE_VAL_LC:
2616                 DP(NETIF_MSG_LINK, "Optic module detected\n");
2617                 check_limiting_mode = 1;
2618                 break;
2619
2620         default:
2621                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2622                          val);
2623                 return -EINVAL;
2624         }
2625
2626         if (check_limiting_mode) {
2627                 u8 options[SFP_EEPROM_OPTIONS_SIZE];
2628                 if (bnx2x_read_sfp_module_eeprom(params,
2629                                                SFP_EEPROM_OPTIONS_ADDR,
2630                                                SFP_EEPROM_OPTIONS_SIZE,
2631                                                options) != 0) {
2632                         DP(NETIF_MSG_LINK, "Failed to read Option"
2633                                 " field from module EEPROM\n");
2634                         return -EINVAL;
2635                 }
2636                 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
2637                         *edc_mode = EDC_MODE_LINEAR;
2638                 else
2639                         *edc_mode = EDC_MODE_LIMITING;
2640         }
2641         DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
2642         return 0;
2643 }
2644
2645 /* This function read the relevant field from the module ( SFP+ ),
2646         and verify it is compliant with this board */
2647 static u8 bnx2x_verify_sfp_module(struct link_params *params)
2648 {
2649         struct bnx2x *bp = params->bp;
2650         u32 val;
2651         u32 fw_resp;
2652         char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
2653         char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
2654
2655         val = REG_RD(bp, params->shmem_base +
2656                          offsetof(struct shmem_region, dev_info.
2657                                   port_feature_config[params->port].config));
2658         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2659             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
2660                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2661                 return 0;
2662         }
2663
2664         /* Ask the FW to validate the module */
2665         if (!(params->feature_config_flags &
2666               FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) {
2667                 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
2668                             "verification\n");
2669                 return -EINVAL;
2670         }
2671
2672         fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL);
2673         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
2674                 DP(NETIF_MSG_LINK, "Approved module\n");
2675                 return 0;
2676         }
2677
2678         /* format the warning message */
2679         if (bnx2x_read_sfp_module_eeprom(params,
2680                                        SFP_EEPROM_VENDOR_NAME_ADDR,
2681                                        SFP_EEPROM_VENDOR_NAME_SIZE,
2682                                        (u8 *)vendor_name))
2683                 vendor_name[0] = '\0';
2684         else
2685                 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
2686         if (bnx2x_read_sfp_module_eeprom(params,
2687                                        SFP_EEPROM_PART_NO_ADDR,
2688                                        SFP_EEPROM_PART_NO_SIZE,
2689                                        (u8 *)vendor_pn))
2690                 vendor_pn[0] = '\0';
2691         else
2692                 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
2693
2694         printk(KERN_INFO PFX  "Warning: "
2695                          "Unqualified SFP+ module "
2696                          "detected on %s, Port %d from %s part number %s\n"
2697                         , bp->dev->name, params->port,
2698                         vendor_name, vendor_pn);
2699         return -EINVAL;
2700 }
2701
2702 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2703                                         u16 edc_mode)
2704 {
2705         struct bnx2x *bp = params->bp;
2706         u8 port = params->port;
2707         u8 ext_phy_addr = ((params->ext_phy_config &
2708                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2709                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2710         u16 cur_limiting_mode;
2711
2712         bnx2x_cl45_read(bp, port,
2713                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2714                       ext_phy_addr,
2715                       MDIO_PMA_DEVAD,
2716                       MDIO_PMA_REG_ROM_VER2,
2717                       &cur_limiting_mode);
2718         DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
2719                  cur_limiting_mode);
2720
2721         if (edc_mode == EDC_MODE_LIMITING) {
2722                 DP(NETIF_MSG_LINK,
2723                          "Setting LIMITING MODE\n");
2724                 bnx2x_cl45_write(bp, port,
2725                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2726                                ext_phy_addr,
2727                                MDIO_PMA_DEVAD,
2728                                MDIO_PMA_REG_ROM_VER2,
2729                                EDC_MODE_LIMITING);
2730         } else { /* LRM mode ( default )*/
2731
2732                 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
2733
2734                 /* Changing to LRM mode takes quite few seconds.
2735                 So do it only if current mode is limiting
2736                 ( default is LRM )*/
2737                 if (cur_limiting_mode != EDC_MODE_LIMITING)
2738                         return 0;
2739
2740                 bnx2x_cl45_write(bp, port,
2741                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2742                                ext_phy_addr,
2743                                MDIO_PMA_DEVAD,
2744                                MDIO_PMA_REG_LRM_MODE,
2745                                0);
2746                 bnx2x_cl45_write(bp, port,
2747                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2748                                ext_phy_addr,
2749                                MDIO_PMA_DEVAD,
2750                                MDIO_PMA_REG_ROM_VER2,
2751                                0x128);
2752                 bnx2x_cl45_write(bp, port,
2753                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2754                                ext_phy_addr,
2755                                MDIO_PMA_DEVAD,
2756                                MDIO_PMA_REG_MISC_CTRL0,
2757                                0x4008);
2758                 bnx2x_cl45_write(bp, port,
2759                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2760                                ext_phy_addr,
2761                                MDIO_PMA_DEVAD,
2762                                MDIO_PMA_REG_LRM_MODE,
2763                                0xaaaa);
2764         }
2765         return 0;
2766 }
2767
2768 static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
2769                                         u16 edc_mode)
2770 {
2771         struct bnx2x *bp = params->bp;
2772         u8 port = params->port;
2773         u16 phy_identifier;
2774         u16 rom_ver2_val;
2775         u8 ext_phy_addr = ((params->ext_phy_config &
2776                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2777                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2778
2779         bnx2x_cl45_read(bp, port,
2780                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2781                        ext_phy_addr,
2782                        MDIO_PMA_DEVAD,
2783                        MDIO_PMA_REG_PHY_IDENTIFIER,
2784                        &phy_identifier);
2785
2786         bnx2x_cl45_write(bp, port,
2787                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2788                        ext_phy_addr,
2789                        MDIO_PMA_DEVAD,
2790                        MDIO_PMA_REG_PHY_IDENTIFIER,
2791                        (phy_identifier & ~(1<<9)));
2792
2793         bnx2x_cl45_read(bp, port,
2794                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2795                       ext_phy_addr,
2796                       MDIO_PMA_DEVAD,
2797                       MDIO_PMA_REG_ROM_VER2,
2798                       &rom_ver2_val);
2799         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
2800         bnx2x_cl45_write(bp, port,
2801                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2802                        ext_phy_addr,
2803                        MDIO_PMA_DEVAD,
2804                        MDIO_PMA_REG_ROM_VER2,
2805                        (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
2806
2807         bnx2x_cl45_write(bp, port,
2808                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2809                        ext_phy_addr,
2810                        MDIO_PMA_DEVAD,
2811                        MDIO_PMA_REG_PHY_IDENTIFIER,
2812                        (phy_identifier | (1<<9)));
2813
2814         return 0;
2815 }
2816
2817
2818 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2819 {
2820         u8 val;
2821         struct bnx2x *bp = params->bp;
2822         u16 timeout;
2823         /* Initialization time after hot-plug may take up to 300ms for some
2824         phys type ( e.g. JDSU ) */
2825         for (timeout = 0; timeout < 60; timeout++) {
2826                 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2827                     == 0) {
2828                         DP(NETIF_MSG_LINK, "SFP+ module initialization "
2829                                      "took %d ms\n", timeout * 5);
2830                         return 0;
2831                 }
2832                 msleep(5);
2833         }
2834         return -EINVAL;
2835 }
2836
2837 static void bnx2x_8727_power_module(struct bnx2x *bp,
2838                                   struct link_params *params,
2839                                   u8 ext_phy_addr, u8 is_power_up) {
2840         /* Make sure GPIOs are not using for LED mode */
2841         u16 val;
2842         u8 port = params->port;
2843         /*
2844          * In the GPIO register, bit 4 is use to detemine if the GPIOs are
2845          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
2846          * output
2847          * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
2848          * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
2849          * where the 1st bit is the over-current(only input), and 2nd bit is
2850          * for power( only output )
2851         */
2852
2853         /*
2854          * In case of NOC feature is disabled and power is up, set GPIO control
2855          *  as input to enable listening of over-current indication
2856          */
2857
2858         if (!(params->feature_config_flags &
2859               FEATURE_CONFIG_BCM8727_NOC) && is_power_up)
2860                 val = (1<<4);
2861         else
2862                 /*
2863                  * Set GPIO control to OUTPUT, and set the power bit
2864                  * to according to the is_power_up
2865                  */
2866                 val = ((!(is_power_up)) << 1);
2867
2868         bnx2x_cl45_write(bp, port,
2869                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2870                        ext_phy_addr,
2871                        MDIO_PMA_DEVAD,
2872                        MDIO_PMA_REG_8727_GPIO_CTRL,
2873                        val);
2874 }
2875
2876 static u8 bnx2x_sfp_module_detection(struct link_params *params)
2877 {
2878         struct bnx2x *bp = params->bp;
2879         u16 edc_mode;
2880         u8 rc = 0;
2881         u8 ext_phy_addr = ((params->ext_phy_config &
2882                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2883                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2884         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2885         u32 val = REG_RD(bp, params->shmem_base +
2886                              offsetof(struct shmem_region, dev_info.
2887                                      port_feature_config[params->port].config));
2888
2889         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2890                  params->port);
2891
2892         if (bnx2x_get_edc_mode(params, &edc_mode) != 0) {
2893                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2894                 return -EINVAL;
2895         } else if (bnx2x_verify_sfp_module(params) !=
2896                    0) {
2897                 /* check SFP+ module compatibility */
2898                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2899                 rc = -EINVAL;
2900                 /* Turn on fault module-detected led */
2901                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2902                                   MISC_REGISTERS_GPIO_HIGH,
2903                                   params->port);
2904                 if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
2905                     ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2906                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
2907                         /* Shutdown SFP+ module */
2908                         DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
2909                         bnx2x_8727_power_module(bp, params,
2910                                               ext_phy_addr, 0);
2911                         return rc;
2912                 }
2913         } else {
2914                 /* Turn off fault module-detected led */
2915                 DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
2916                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2917                                           MISC_REGISTERS_GPIO_LOW,
2918                                           params->port);
2919         }
2920
2921         /* power up the SFP module */
2922         if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
2923                 bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
2924
2925         /* Check and set limiting mode / LRM mode on 8726.
2926         On 8727 it is done automatically */
2927         if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
2928                 bnx2x_bcm8726_set_limiting_mode(params, edc_mode);
2929         else
2930                 bnx2x_bcm8727_set_limiting_mode(params, edc_mode);
2931         /*
2932          * Enable transmit for this module if the module is approved, or
2933          * if unapproved modules should also enable the Tx laser
2934          */
2935         if (rc == 0 ||
2936             (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
2937             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
2938                 bnx2x_sfp_set_transmitter(bp, params->port,
2939                                         ext_phy_type, ext_phy_addr, 1);
2940         else
2941                 bnx2x_sfp_set_transmitter(bp, params->port,
2942                                         ext_phy_type, ext_phy_addr, 0);
2943
2944         return rc;
2945 }
2946
2947 void bnx2x_handle_module_detect_int(struct link_params *params)
2948 {
2949         struct bnx2x *bp = params->bp;
2950         u32 gpio_val;
2951         u8 port = params->port;
2952         /* Set valid module led off */
2953         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2954                           MISC_REGISTERS_GPIO_HIGH,
2955                           params->port);
2956
2957         /* Get current gpio val refelecting module plugged in / out*/
2958         gpio_val = bnx2x_get_gpio(bp,  MISC_REGISTERS_GPIO_3, port);
2959
2960         /* Call the handling function in case module is detected */
2961         if (gpio_val == 0) {
2962
2963                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2964                                       MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2965                                       port);
2966
2967                 if (bnx2x_wait_for_sfp_module_initialized(params) ==
2968                     0)
2969                         bnx2x_sfp_module_detection(params);
2970                 else
2971                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2972         } else {
2973                 u8 ext_phy_addr = ((params->ext_phy_config &
2974                                     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2975                                    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2976                 u32 ext_phy_type =
2977                         XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2978                 u32 val = REG_RD(bp, params->shmem_base +
2979                                      offsetof(struct shmem_region, dev_info.
2980                                               port_feature_config[params->port].
2981                                               config));
2982
2983                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2984                                       MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2985                                       port);
2986                 /* Module was plugged out. */
2987                 /* Disable transmit for this module */
2988                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2989                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
2990                         bnx2x_sfp_set_transmitter(bp, params->port,
2991                                                 ext_phy_type, ext_phy_addr, 0);
2992         }
2993 }
2994
2995 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2996 {
2997         struct bnx2x *bp = params->bp;
2998         u8 port = params->port;
2999         u8 ext_phy_addr = ((params->ext_phy_config &
3000                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3001                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3002         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3003
3004         /* Force KR or KX */
3005         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3006                        MDIO_PMA_DEVAD,
3007                        MDIO_PMA_REG_CTRL,
3008                        0x2040);
3009         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3010                        MDIO_PMA_DEVAD,
3011                        MDIO_PMA_REG_10G_CTRL2,
3012                        0x000b);
3013         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3014                        MDIO_PMA_DEVAD,
3015                        MDIO_PMA_REG_BCM_CTRL,
3016                        0x0000);
3017         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3018                        MDIO_AN_DEVAD,
3019                        MDIO_AN_REG_CTRL,
3020                        0x0000);
3021 }
3022 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
3023 {
3024         struct bnx2x *bp = params->bp;
3025         u8 port = params->port;
3026         u16 val;
3027         u8 ext_phy_addr = ((params->ext_phy_config &
3028                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3029                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3030         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3031
3032         bnx2x_cl45_read(bp, params->port,
3033                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3034                       ext_phy_addr,
3035                       MDIO_PMA_DEVAD,
3036                       MDIO_PMA_REG_8073_CHIP_REV, &val);
3037
3038         if (val == 0) {
3039                 /* Mustn't set low power mode in 8073 A0 */
3040                 return;
3041         }
3042
3043         /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
3044         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3045                        MDIO_XS_DEVAD,
3046                        MDIO_XS_PLL_SEQUENCER, &val);
3047         val &= ~(1<<13);
3048         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3049                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3050
3051         /* PLL controls */
3052         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3053                        MDIO_XS_DEVAD, 0x805E, 0x1077);
3054         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3055                        MDIO_XS_DEVAD, 0x805D, 0x0000);
3056         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3057                        MDIO_XS_DEVAD, 0x805C, 0x030B);
3058         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3059                        MDIO_XS_DEVAD, 0x805B, 0x1240);
3060         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3061                        MDIO_XS_DEVAD, 0x805A, 0x2490);
3062
3063         /* Tx Controls */
3064         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3065                        MDIO_XS_DEVAD, 0x80A7, 0x0C74);
3066         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3067                        MDIO_XS_DEVAD, 0x80A6, 0x9041);
3068         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3069                        MDIO_XS_DEVAD, 0x80A5, 0x4640);
3070
3071         /* Rx Controls */
3072         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3073                        MDIO_XS_DEVAD, 0x80FE, 0x01C4);
3074         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3075                        MDIO_XS_DEVAD, 0x80FD, 0x9249);
3076         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3077                        MDIO_XS_DEVAD, 0x80FC, 0x2015);
3078
3079         /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
3080         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3081                        MDIO_XS_DEVAD,
3082                        MDIO_XS_PLL_SEQUENCER, &val);
3083         val |= (1<<13);
3084         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3085                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3086 }
3087
3088 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
3089                                   struct link_vars *vars)
3090 {
3091
3092         struct bnx2x *bp = params->bp;
3093         u16 cl37_val;
3094         u8 ext_phy_addr = ((params->ext_phy_config &
3095                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3096                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3097         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3098
3099         bnx2x_cl45_read(bp, params->port,
3100                       ext_phy_type,
3101                       ext_phy_addr,
3102                       MDIO_AN_DEVAD,
3103                       MDIO_AN_REG_CL37_FC_LD, &cl37_val);
3104
3105         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3106         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3107
3108         if ((vars->ieee_fc &
3109             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
3110             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
3111                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
3112         }
3113         if ((vars->ieee_fc &
3114             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3115             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3116                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3117         }
3118         if ((vars->ieee_fc &
3119             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3120             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3121                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3122         }
3123         DP(NETIF_MSG_LINK,
3124                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
3125
3126         bnx2x_cl45_write(bp, params->port,
3127                        ext_phy_type,
3128                        ext_phy_addr,
3129                        MDIO_AN_DEVAD,
3130                        MDIO_AN_REG_CL37_FC_LD, cl37_val);
3131         msleep(500);
3132 }
3133
3134 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3135                                   struct link_vars *vars)
3136 {
3137         struct bnx2x *bp = params->bp;
3138         u16 val;
3139         u8 ext_phy_addr = ((params->ext_phy_config &
3140                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3141                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3142         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3143
3144         /* read modify write pause advertizing */
3145         bnx2x_cl45_read(bp, params->port,
3146                       ext_phy_type,
3147                       ext_phy_addr,
3148                       MDIO_AN_DEVAD,
3149                       MDIO_AN_REG_ADV_PAUSE, &val);
3150
3151         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3152
3153         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3154
3155         if ((vars->ieee_fc &
3156             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3157             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3158                 val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3159         }
3160         if ((vars->ieee_fc &
3161             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3162             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3163                 val |=
3164                  MDIO_AN_REG_ADV_PAUSE_PAUSE;
3165         }
3166         DP(NETIF_MSG_LINK,
3167                  "Ext phy AN advertize 0x%x\n", val);
3168         bnx2x_cl45_write(bp, params->port,
3169                        ext_phy_type,
3170                        ext_phy_addr,
3171                        MDIO_AN_DEVAD,
3172                        MDIO_AN_REG_ADV_PAUSE, val);
3173 }
3174 static void bnx2x_set_preemphasis(struct link_params *params)
3175 {
3176         u16 bank, i = 0;
3177         struct bnx2x *bp = params->bp;
3178
3179         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
3180               bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
3181                         CL45_WR_OVER_CL22(bp, params->port,
3182                                               params->phy_addr,
3183                                               bank,
3184                                               MDIO_RX0_RX_EQ_BOOST,
3185                                               params->xgxs_config_rx[i]);
3186         }
3187
3188         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
3189                       bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
3190                         CL45_WR_OVER_CL22(bp, params->port,
3191                                               params->phy_addr,
3192                                               bank,
3193                                               MDIO_TX0_TX_DRIVER,
3194                                               params->xgxs_config_tx[i]);
3195         }
3196 }
3197
3198
3199 static void bnx2x_8481_set_led4(struct link_params *params,
3200                               u32 ext_phy_type, u8 ext_phy_addr)
3201 {
3202         struct bnx2x *bp = params->bp;
3203
3204         /* PHYC_CTL_LED_CTL */
3205         bnx2x_cl45_write(bp, params->port,
3206                        ext_phy_type,
3207                        ext_phy_addr,
3208                        MDIO_PMA_DEVAD,
3209                        MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482);
3210
3211         /* Unmask LED4 for 10G link */
3212         bnx2x_cl45_write(bp, params->port,
3213                        ext_phy_type,
3214                        ext_phy_addr,
3215                        MDIO_PMA_DEVAD,
3216                        MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6));
3217         /* 'Interrupt Mask' */
3218         bnx2x_cl45_write(bp, params->port,
3219                        ext_phy_type,
3220                        ext_phy_addr,
3221                        MDIO_AN_DEVAD,
3222                        0xFFFB, 0xFFFD);
3223 }
3224 static void bnx2x_8481_set_legacy_led_mode(struct link_params *params,
3225                                          u32 ext_phy_type, u8 ext_phy_addr)
3226 {
3227         struct bnx2x *bp = params->bp;
3228
3229         /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */
3230         /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */
3231         bnx2x_cl45_write(bp, params->port,
3232                        ext_phy_type,
3233                        ext_phy_addr,
3234                        MDIO_AN_DEVAD,
3235                        MDIO_AN_REG_8481_LEGACY_SHADOW,
3236                        (1<<15) | (0xd << 10) | (0xc<<4) | 0xe);
3237 }
3238
3239 static void bnx2x_8481_set_10G_led_mode(struct link_params *params,
3240                                       u32 ext_phy_type, u8 ext_phy_addr)
3241 {
3242         struct bnx2x *bp = params->bp;
3243         u16 val1;
3244
3245         /* LED1 (10G Link) */
3246         /* Enable continuse based on source 7(10G-link) */
3247         bnx2x_cl45_read(bp, params->port,
3248                        ext_phy_type,
3249                        ext_phy_addr,
3250                        MDIO_PMA_DEVAD,
3251                        MDIO_PMA_REG_8481_LINK_SIGNAL,
3252                        &val1);
3253         /* Set bit 2 to 0, and bits [1:0] to 10 */
3254         val1 &= ~((1<<0) | (1<<2)); /* Clear bits 0,2*/
3255         val1 |= (1<<1); /* Set bit 1 */
3256
3257         bnx2x_cl45_write(bp, params->port,
3258                        ext_phy_type,
3259                        ext_phy_addr,
3260                        MDIO_PMA_DEVAD,
3261                        MDIO_PMA_REG_8481_LINK_SIGNAL,
3262                        val1);
3263
3264         /* Unmask LED1 for 10G link */
3265         bnx2x_cl45_read(bp, params->port,
3266                       ext_phy_type,
3267                       ext_phy_addr,
3268                       MDIO_PMA_DEVAD,
3269                       MDIO_PMA_REG_8481_LED1_MASK,
3270                       &val1);
3271         /* Set bit 2 to 0, and bits [1:0] to 10 */
3272         val1 |= (1<<7);
3273         bnx2x_cl45_write(bp, params->port,
3274                        ext_phy_type,
3275                        ext_phy_addr,
3276                        MDIO_PMA_DEVAD,
3277                        MDIO_PMA_REG_8481_LED1_MASK,
3278                        val1);
3279
3280         /* LED2 (1G/100/10G Link) */
3281         /* Mask LED2 for 10G link */
3282         bnx2x_cl45_write(bp, params->port,
3283                        ext_phy_type,
3284                        ext_phy_addr,
3285                        MDIO_PMA_DEVAD,
3286                        MDIO_PMA_REG_8481_LED2_MASK,
3287                        0);
3288
3289         /* LED3 (10G/1G/100/10G Activity) */
3290         bnx2x_cl45_read(bp, params->port,
3291                       ext_phy_type,
3292                       ext_phy_addr,
3293                       MDIO_PMA_DEVAD,
3294                       MDIO_PMA_REG_8481_LINK_SIGNAL,
3295                       &val1);
3296         /* Enable blink based on source 4(Activity) */
3297         val1 &= ~((1<<7) | (1<<8)); /* Clear bits 7,8 */
3298         val1 |= (1<<6); /* Set only bit 6 */
3299         bnx2x_cl45_write(bp, params->port,
3300                        ext_phy_type,
3301                        ext_phy_addr,
3302                        MDIO_PMA_DEVAD,
3303                        MDIO_PMA_REG_8481_LINK_SIGNAL,
3304                        val1);
3305
3306         bnx2x_cl45_read(bp, params->port,
3307                       ext_phy_type,
3308                       ext_phy_addr,
3309                       MDIO_PMA_DEVAD,
3310                       MDIO_PMA_REG_8481_LED3_MASK,
3311                       &val1);
3312         val1 |= (1<<4); /* Unmask LED3 for 10G link */
3313         bnx2x_cl45_write(bp, params->port,
3314                        ext_phy_type,
3315                        ext_phy_addr,
3316                        MDIO_PMA_DEVAD,
3317                        MDIO_PMA_REG_8481_LED3_MASK,
3318                        val1);
3319 }
3320
3321
3322 static void bnx2x_init_internal_phy(struct link_params *params,
3323                                 struct link_vars *vars)
3324 {
3325         struct bnx2x *bp = params->bp;
3326         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
3327                 if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
3328                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3329                     (params->feature_config_flags &
3330                      FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
3331                         bnx2x_set_preemphasis(params);
3332
3333                 /* forced speed requested? */
3334                 if (vars->line_speed != SPEED_AUTO_NEG) {
3335                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3336
3337                         /* disable autoneg */
3338                         bnx2x_set_autoneg(params, vars);
3339
3340                         /* program speed and duplex */
3341                         bnx2x_program_serdes(params, vars);
3342
3343                 } else { /* AN_mode */
3344                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
3345
3346                         /* AN enabled */
3347                         bnx2x_set_brcm_cl37_advertisment(params);
3348
3349                         /* program duplex & pause advertisement (for aneg) */
3350                         bnx2x_set_ieee_aneg_advertisment(params,
3351                                                        vars->ieee_fc);
3352
3353                         /* enable autoneg */
3354                         bnx2x_set_autoneg(params, vars);
3355
3356                         /* enable and restart AN */
3357                         bnx2x_restart_autoneg(params);
3358                 }
3359
3360         } else { /* SGMII mode */
3361                 DP(NETIF_MSG_LINK, "SGMII\n");
3362
3363                 bnx2x_initialize_sgmii_process(params, vars);
3364         }
3365 }
3366
3367 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
3368 {
3369         struct bnx2x *bp = params->bp;
3370         u32 ext_phy_type;
3371         u8 ext_phy_addr;
3372         u16 cnt;
3373         u16 ctrl = 0;
3374         u16 val = 0;
3375         u8 rc = 0;
3376         if (vars->phy_flags & PHY_XGXS_FLAG) {
3377                 ext_phy_addr = ((params->ext_phy_config &
3378                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3379                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3380
3381                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3382                 /* Make sure that the soft reset is off (expect for the 8072:
3383                  * due to the lock, it will be done inside the specific
3384                  * handling)
3385                  */
3386                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3387                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3388                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
3389                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3390                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3391                         /* Wait for soft reset to get cleared upto 1 sec */
3392                         for (cnt = 0; cnt < 1000; cnt++) {
3393                                 bnx2x_cl45_read(bp, params->port,
3394                                               ext_phy_type,
3395                                               ext_phy_addr,
3396                                               MDIO_PMA_DEVAD,
3397                                               MDIO_PMA_REG_CTRL, &ctrl);
3398                                 if (!(ctrl & (1<<15)))
3399                                         break;
3400                                 msleep(1);
3401                         }
3402                         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3403                                  ctrl, cnt);
3404                 }
3405
3406                 switch (ext_phy_type) {
3407                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3408                         break;
3409
3410                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3411                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
3412
3413                         bnx2x_cl45_write(bp, params->port,
3414                                        ext_phy_type,
3415                                        ext_phy_addr,
3416                                        MDIO_PMA_DEVAD,
3417                                        MDIO_PMA_REG_MISC_CTRL,
3418                                        0x8288);
3419                         bnx2x_cl45_write(bp, params->port,
3420                                        ext_phy_type,
3421                                        ext_phy_addr,
3422                                        MDIO_PMA_DEVAD,
3423                                        MDIO_PMA_REG_PHY_IDENTIFIER,
3424                                        0x7fbf);
3425                         bnx2x_cl45_write(bp, params->port,
3426                                        ext_phy_type,
3427                                        ext_phy_addr,
3428                                        MDIO_PMA_DEVAD,
3429                                        MDIO_PMA_REG_CMU_PLL_BYPASS,
3430                                        0x0100);
3431                         bnx2x_cl45_write(bp, params->port,
3432                                        ext_phy_type,
3433                                        ext_phy_addr,
3434                                        MDIO_WIS_DEVAD,
3435                                        MDIO_WIS_REG_LASI_CNTL, 0x1);
3436
3437                         /* BCM8705 doesn't have microcode, hence the 0 */
3438                         bnx2x_save_spirom_version(bp, params->port,
3439                                                 params->shmem_base, 0);
3440                         break;
3441
3442                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3443                         /* Wait until fw is loaded */
3444                         for (cnt = 0; cnt < 100; cnt++) {
3445                                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3446                                               ext_phy_addr, MDIO_PMA_DEVAD,
3447                                               MDIO_PMA_REG_ROM_VER1, &val);
3448                                 if (val)
3449                                         break;
3450                                 msleep(10);
3451                         }
3452                         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3453                                 "after %d ms\n", cnt);
3454                         if ((params->feature_config_flags &
3455                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3456                                 u8 i;
3457                                 u16 reg;
3458                                 for (i = 0; i < 4; i++) {
3459                                         reg = MDIO_XS_8706_REG_BANK_RX0 +
3460                                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
3461                                                    MDIO_XS_8706_REG_BANK_RX0);
3462                                         bnx2x_cl45_read(bp, params->port,
3463                                                       ext_phy_type,
3464                                                       ext_phy_addr,
3465                                                       MDIO_XS_DEVAD,
3466                                                       reg, &val);
3467                                         /* Clear first 3 bits of the control */
3468                                         val &= ~0x7;
3469                                         /* Set control bits according to
3470                                         configuation */
3471                                         val |= (params->xgxs_config_rx[i] &
3472                                                 0x7);
3473                                         DP(NETIF_MSG_LINK, "Setting RX"
3474                                                  "Equalizer to BCM8706 reg 0x%x"
3475                                                  " <-- val 0x%x\n", reg, val);
3476                                         bnx2x_cl45_write(bp, params->port,
3477                                                        ext_phy_type,
3478                                                        ext_phy_addr,
3479                                                        MDIO_XS_DEVAD,
3480                                                        reg, val);
3481                                 }
3482                         }
3483                         /* Force speed */
3484                         /* First enable LASI */
3485                         bnx2x_cl45_write(bp, params->port,
3486                                        ext_phy_type,
3487                                        ext_phy_addr,
3488                                        MDIO_PMA_DEVAD,
3489                                        MDIO_PMA_REG_RX_ALARM_CTRL,
3490                                        0x0400);
3491                         bnx2x_cl45_write(bp, params->port,
3492                                        ext_phy_type,
3493                                        ext_phy_addr,
3494                                        MDIO_PMA_DEVAD,
3495                                        MDIO_PMA_REG_LASI_CTRL, 0x0004);
3496
3497                         if (params->req_line_speed == SPEED_10000) {
3498                                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3499
3500                                 bnx2x_cl45_write(bp, params->port,
3501                                                ext_phy_type,
3502                                                ext_phy_addr,
3503                                                MDIO_PMA_DEVAD,
3504                                                MDIO_PMA_REG_DIGITAL_CTRL,
3505                                                0x400);
3506                         } else {
3507                                 /* Force 1Gbps using autoneg with 1G
3508                                 advertisment */
3509
3510                                 /* Allow CL37 through CL73 */
3511                                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3512                                 bnx2x_cl45_write(bp, params->port,
3513                                                ext_phy_type,
3514                                                ext_phy_addr,
3515                                                MDIO_AN_DEVAD,
3516                                                MDIO_AN_REG_CL37_CL73,
3517                                                0x040c);
3518
3519                                 /* Enable Full-Duplex advertisment on CL37 */
3520                                 bnx2x_cl45_write(bp, params->port,
3521                                                ext_phy_type,
3522                                                ext_phy_addr,
3523                                                MDIO_AN_DEVAD,
3524                                                MDIO_AN_REG_CL37_FC_LP,
3525                                                0x0020);
3526                                 /* Enable CL37 AN */
3527                                 bnx2x_cl45_write(bp, params->port,
3528                                                ext_phy_type,
3529                                                ext_phy_addr,
3530                                                MDIO_AN_DEVAD,
3531                                                MDIO_AN_REG_CL37_AN,
3532                                                0x1000);
3533                                 /* 1G support */
3534                                 bnx2x_cl45_write(bp, params->port,
3535                                                ext_phy_type,
3536                                                ext_phy_addr,
3537                                                MDIO_AN_DEVAD,
3538                                                MDIO_AN_REG_ADV, (1<<5));
3539
3540                                 /* Enable clause 73 AN */
3541                                 bnx2x_cl45_write(bp, params->port,
3542                                                ext_phy_type,
3543                                                ext_phy_addr,
3544                                                MDIO_AN_DEVAD,
3545                                                MDIO_AN_REG_CTRL,
3546                                                0x1200);
3547
3548                         }
3549                         bnx2x_save_bcm_spirom_ver(bp, params->port,
3550                                                 ext_phy_type,
3551                                                 ext_phy_addr,
3552                                                 params->shmem_base);
3553                         break;
3554                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3555                         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3556                         bnx2x_bcm8726_external_rom_boot(params);
3557
3558                         /* Need to call module detected on initialization since
3559                         the module detection triggered by actual module
3560                         insertion might occur before driver is loaded, and when
3561                         driver is loaded, it reset all registers, including the
3562                         transmitter */
3563                         bnx2x_sfp_module_detection(params);
3564
3565                         /* Set Flow control */
3566                         bnx2x_ext_phy_set_pause(params, vars);
3567                         if (params->req_line_speed == SPEED_1000) {
3568                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3569                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3570                                                ext_phy_addr, MDIO_PMA_DEVAD,
3571                                                MDIO_PMA_REG_CTRL, 0x40);
3572                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3573                                                ext_phy_addr, MDIO_PMA_DEVAD,
3574                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
3575                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3576                                                ext_phy_addr, MDIO_PMA_DEVAD,
3577                                                MDIO_PMA_REG_LASI_CTRL, 0x5);
3578                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3579                                                ext_phy_addr, MDIO_PMA_DEVAD,
3580                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3581                                                0x400);
3582                         } else if ((params->req_line_speed ==
3583                                     SPEED_AUTO_NEG) &&
3584                                    ((params->speed_cap_mask &
3585                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3586                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3587                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3588                                                ext_phy_addr, MDIO_AN_DEVAD,
3589                                                MDIO_AN_REG_ADV, 0x20);
3590                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3591                                                ext_phy_addr, MDIO_AN_DEVAD,
3592                                                MDIO_AN_REG_CL37_CL73, 0x040c);
3593                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3594                                                ext_phy_addr, MDIO_AN_DEVAD,
3595                                                MDIO_AN_REG_CL37_FC_LD, 0x0020);
3596                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3597                                                ext_phy_addr, MDIO_AN_DEVAD,
3598                                                MDIO_AN_REG_CL37_AN, 0x1000);
3599                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3600                                                ext_phy_addr, MDIO_AN_DEVAD,
3601                                                MDIO_AN_REG_CTRL, 0x1200);
3602
3603                                 /* Enable RX-ALARM control to receive
3604                                 interrupt for 1G speed change */
3605                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3606                                                ext_phy_addr, MDIO_PMA_DEVAD,
3607                                                MDIO_PMA_REG_LASI_CTRL, 0x4);
3608                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3609                                                ext_phy_addr, MDIO_PMA_DEVAD,
3610                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3611                                                0x400);
3612
3613                         } else { /* Default 10G. Set only LASI control */
3614                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3615                                                ext_phy_addr, MDIO_PMA_DEVAD,
3616                                                MDIO_PMA_REG_LASI_CTRL, 1);
3617                         }
3618
3619                         /* Set TX PreEmphasis if needed */
3620                         if ((params->feature_config_flags &
3621                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3622                                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3623                                          "TX_CTRL2 0x%x\n",
3624                                          params->xgxs_config_tx[0],
3625                                          params->xgxs_config_tx[1]);
3626                                 bnx2x_cl45_write(bp, params->port,
3627                                                ext_phy_type,
3628                                                ext_phy_addr,
3629                                                MDIO_PMA_DEVAD,
3630                                                MDIO_PMA_REG_8726_TX_CTRL1,
3631                                                params->xgxs_config_tx[0]);
3632
3633                                 bnx2x_cl45_write(bp, params->port,
3634                                                ext_phy_type,
3635                                                ext_phy_addr,
3636                                                MDIO_PMA_DEVAD,
3637                                                MDIO_PMA_REG_8726_TX_CTRL2,
3638                                                params->xgxs_config_tx[1]);
3639                         }
3640                         break;
3641                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3642                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3643                 {
3644                         u16 tmp1;
3645                         u16 rx_alarm_ctrl_val;
3646                         u16 lasi_ctrl_val;
3647                         if (ext_phy_type ==
3648                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3649                                 rx_alarm_ctrl_val = 0x400;
3650                                 lasi_ctrl_val = 0x0004;
3651                         } else {
3652                                 rx_alarm_ctrl_val = (1<<2);
3653                                 lasi_ctrl_val = 0x0004;
3654                         }
3655
3656                         /* enable LASI */
3657                         bnx2x_cl45_write(bp, params->port,
3658                                    ext_phy_type,
3659                                    ext_phy_addr,
3660                                    MDIO_PMA_DEVAD,
3661                                    MDIO_PMA_REG_RX_ALARM_CTRL,
3662                                    rx_alarm_ctrl_val);
3663
3664                         bnx2x_cl45_write(bp, params->port,
3665                                        ext_phy_type,
3666                                        ext_phy_addr,
3667                                        MDIO_PMA_DEVAD,
3668                                        MDIO_PMA_REG_LASI_CTRL,
3669                                        lasi_ctrl_val);
3670
3671                         bnx2x_8073_set_pause_cl37(params, vars);
3672
3673                         if (ext_phy_type ==
3674                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
3675                                 bnx2x_bcm8072_external_rom_boot(params);
3676                         } else {
3677
3678                                 /* In case of 8073 with long xaui lines,
3679                                 don't set the 8073 xaui low power*/
3680                                 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3681                         }
3682
3683                         bnx2x_cl45_read(bp, params->port,
3684                                       ext_phy_type,
3685                                       ext_phy_addr,
3686                                       MDIO_PMA_DEVAD,
3687                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
3688                                       &tmp1);
3689
3690                         bnx2x_cl45_read(bp, params->port,
3691                                       ext_phy_type,
3692                                       ext_phy_addr,
3693                                       MDIO_PMA_DEVAD,
3694                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
3695
3696                         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3697                                              "0x%x\n", tmp1);
3698
3699                         /* If this is forced speed, set to KR or KX
3700                          * (all other are not supported)
3701                          */
3702                         if (params->loopback_mode == LOOPBACK_EXT) {
3703                                 bnx2x_bcm807x_force_10G(params);
3704                                 DP(NETIF_MSG_LINK,
3705                                         "Forced speed 10G on 807X\n");
3706                                 break;
3707                         } else {
3708                                 bnx2x_cl45_write(bp, params->port,
3709                                                ext_phy_type, ext_phy_addr,
3710                                                MDIO_PMA_DEVAD,
3711                                                MDIO_PMA_REG_BCM_CTRL,
3712                                                0x0002);
3713                         }
3714                         if (params->req_line_speed != SPEED_AUTO_NEG) {
3715                                 if (params->req_line_speed == SPEED_10000) {
3716                                         val = (1<<7);
3717                                 } else if (params->req_line_speed ==
3718                                            SPEED_2500) {
3719                                         val = (1<<5);
3720                                         /* Note that 2.5G works only
3721                                         when used with 1G advertisment */
3722                                 } else
3723                                         val = (1<<5);
3724                         } else {
3725
3726                                 val = 0;
3727                                 if (params->speed_cap_mask &
3728                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3729                                         val |= (1<<7);
3730
3731                                 /* Note that 2.5G works only when
3732                                 used with 1G advertisment */
3733                                 if (params->speed_cap_mask &
3734                                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3735                                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3736                                         val |= (1<<5);
3737                                 DP(NETIF_MSG_LINK,
3738                                          "807x autoneg val = 0x%x\n", val);
3739                         }
3740
3741                         bnx2x_cl45_write(bp, params->port,
3742                                        ext_phy_type,
3743                                        ext_phy_addr,
3744                                        MDIO_AN_DEVAD,
3745                                        MDIO_AN_REG_ADV, val);
3746
3747                         if (ext_phy_type ==
3748                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3749
3750                                 bnx2x_cl45_read(bp, params->port,
3751                                               ext_phy_type,
3752                                               ext_phy_addr,
3753                                               MDIO_AN_DEVAD,
3754                                               MDIO_AN_REG_8073_2_5G, &tmp1);
3755
3756                                 if (((params->speed_cap_mask &
3757                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3758                                      (params->req_line_speed ==
3759                                       SPEED_AUTO_NEG)) ||
3760                                     (params->req_line_speed ==
3761                                      SPEED_2500)) {
3762                                         u16 phy_ver;
3763                                         /* Allow 2.5G for A1 and above */
3764                                         bnx2x_cl45_read(bp, params->port,
3765                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3766                                          ext_phy_addr,
3767                                          MDIO_PMA_DEVAD,
3768                                          MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
3769                                         DP(NETIF_MSG_LINK, "Add 2.5G\n");
3770                                         if (phy_ver > 0)
3771                                                 tmp1 |= 1;
3772                                         else
3773                                                 tmp1 &= 0xfffe;
3774                                 } else {
3775                                         DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3776                                         tmp1 &= 0xfffe;
3777                                 }
3778
3779                                 bnx2x_cl45_write(bp, params->port,
3780                                                ext_phy_type,
3781                                                ext_phy_addr,
3782                                                MDIO_AN_DEVAD,
3783                                                MDIO_AN_REG_8073_2_5G, tmp1);
3784                         }
3785
3786                         /* Add support for CL37 (passive mode) II */
3787
3788                         bnx2x_cl45_read(bp, params->port,
3789                                        ext_phy_type,
3790                                        ext_phy_addr,
3791                                        MDIO_AN_DEVAD,
3792                                        MDIO_AN_REG_CL37_FC_LD,
3793                                        &tmp1);
3794
3795                         bnx2x_cl45_write(bp, params->port,
3796                                        ext_phy_type,
3797                                        ext_phy_addr,
3798                                        MDIO_AN_DEVAD,
3799                                        MDIO_AN_REG_CL37_FC_LD, (tmp1 |
3800                                        ((params->req_duplex == DUPLEX_FULL) ?
3801                                        0x20 : 0x40)));
3802
3803                         /* Add support for CL37 (passive mode) III */
3804                         bnx2x_cl45_write(bp, params->port,
3805                                        ext_phy_type,
3806                                        ext_phy_addr,
3807                                        MDIO_AN_DEVAD,
3808                                        MDIO_AN_REG_CL37_AN, 0x1000);
3809
3810                         if (ext_phy_type ==
3811                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3812                                 /* The SNR will improve about 2db by changing
3813                                 BW and FEE main tap. Rest commands are executed
3814                                 after link is up*/
3815                                 /*Change FFE main cursor to 5 in EDC register*/
3816                                 if (bnx2x_8073_is_snr_needed(params))
3817                                         bnx2x_cl45_write(bp, params->port,
3818                                                     ext_phy_type,
3819                                                     ext_phy_addr,
3820                                                     MDIO_PMA_DEVAD,
3821                                                     MDIO_PMA_REG_EDC_FFE_MAIN,
3822                                                     0xFB0C);
3823
3824                                 /* Enable FEC (Forware Error Correction)
3825                                 Request in the AN */
3826                                 bnx2x_cl45_read(bp, params->port,
3827                                               ext_phy_type,
3828                                               ext_phy_addr,
3829                                               MDIO_AN_DEVAD,
3830                                               MDIO_AN_REG_ADV2, &tmp1);
3831
3832                                 tmp1 |= (1<<15);
3833
3834                                 bnx2x_cl45_write(bp, params->port,
3835                                                ext_phy_type,
3836                                                ext_phy_addr,
3837                                                MDIO_AN_DEVAD,
3838                                                MDIO_AN_REG_ADV2, tmp1);
3839
3840                         }
3841
3842                         bnx2x_ext_phy_set_pause(params, vars);
3843
3844                         /* Restart autoneg */
3845                         msleep(500);
3846                         bnx2x_cl45_write(bp, params->port,
3847                                        ext_phy_type,
3848                                        ext_phy_addr,
3849                                        MDIO_AN_DEVAD,
3850                                        MDIO_AN_REG_CTRL, 0x1200);
3851                         DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
3852                            "Advertise 1G=%x, 10G=%x\n",
3853                            ((val & (1<<5)) > 0),
3854                            ((val & (1<<7)) > 0));
3855                         break;
3856                 }
3857
3858                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
3859                 {
3860                         u16 tmp1;
3861                         u16 rx_alarm_ctrl_val;
3862                         u16 lasi_ctrl_val;
3863
3864                         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
3865
3866                         u16 mod_abs;
3867                         rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
3868                         lasi_ctrl_val = 0x0004;
3869
3870                         DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
3871                         /* enable LASI */
3872                         bnx2x_cl45_write(bp, params->port,
3873                                        ext_phy_type,
3874                                        ext_phy_addr,
3875                                        MDIO_PMA_DEVAD,
3876                                        MDIO_PMA_REG_RX_ALARM_CTRL,
3877                                        rx_alarm_ctrl_val);
3878
3879                         bnx2x_cl45_write(bp, params->port,
3880                                        ext_phy_type,
3881                                        ext_phy_addr,
3882                                        MDIO_PMA_DEVAD,
3883                                        MDIO_PMA_REG_LASI_CTRL,
3884                                        lasi_ctrl_val);
3885
3886                         /* Initially configure  MOD_ABS to interrupt when
3887                         module is presence( bit 8) */
3888                         bnx2x_cl45_read(bp, params->port,
3889                                       ext_phy_type,
3890                                       ext_phy_addr,
3891                                       MDIO_PMA_DEVAD,
3892                                       MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
3893                         /* Set EDC off by setting OPTXLOS signal input to low
3894                         (bit 9).
3895                         When the EDC is off it locks onto a reference clock and
3896                         avoids becoming 'lost'.*/
3897                         mod_abs &= ~((1<<8) | (1<<9));
3898                         bnx2x_cl45_write(bp, params->port,
3899                                        ext_phy_type,
3900                                        ext_phy_addr,
3901                                        MDIO_PMA_DEVAD,
3902                                        MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
3903
3904                         /* Make MOD_ABS give interrupt on change */
3905                         bnx2x_cl45_read(bp, params->port,
3906                                       ext_phy_type,
3907                                       ext_phy_addr,
3908                                       MDIO_PMA_DEVAD,
3909                                       MDIO_PMA_REG_8727_PCS_OPT_CTRL,
3910                                       &val);
3911                         val |= (1<<12);
3912                         bnx2x_cl45_write(bp, params->port,
3913                                        ext_phy_type,
3914                                        ext_phy_addr,
3915                                        MDIO_PMA_DEVAD,
3916                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
3917                                        val);
3918
3919                         /* Set 8727 GPIOs to input to allow reading from the
3920                         8727 GPIO0 status which reflect SFP+ module
3921                         over-current */
3922
3923                         bnx2x_cl45_read(bp, params->port,
3924                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3925                                        ext_phy_addr,
3926                                        MDIO_PMA_DEVAD,
3927                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
3928                                        &val);
3929                         val &= 0xff8f; /* Reset bits 4-6 */
3930                         bnx2x_cl45_write(bp, params->port,
3931                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3932                                        ext_phy_addr,
3933                                        MDIO_PMA_DEVAD,
3934                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
3935                                        val);
3936
3937                         bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
3938                         bnx2x_bcm8073_set_xaui_low_power_mode(params);
3939
3940                         bnx2x_cl45_read(bp, params->port,
3941                                       ext_phy_type,
3942                                       ext_phy_addr,
3943                                       MDIO_PMA_DEVAD,
3944                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
3945                                       &tmp1);
3946
3947                         bnx2x_cl45_read(bp, params->port,
3948                                       ext_phy_type,
3949                                       ext_phy_addr,
3950                                       MDIO_PMA_DEVAD,
3951                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
3952
3953                         /* Set option 1G speed */
3954                         if (params->req_line_speed == SPEED_1000) {
3955
3956                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3957                                 bnx2x_cl45_write(bp, params->port,
3958                                                ext_phy_type,
3959                                                ext_phy_addr,
3960                                                MDIO_PMA_DEVAD,
3961                                                MDIO_PMA_REG_CTRL, 0x40);
3962                                 bnx2x_cl45_write(bp, params->port,
3963                                                ext_phy_type,
3964                                                ext_phy_addr,
3965                                                MDIO_PMA_DEVAD,
3966                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
3967                                 bnx2x_cl45_read(bp, params->port,
3968                                       ext_phy_type,
3969                                       ext_phy_addr,
3970                                       MDIO_PMA_DEVAD,
3971                                       MDIO_PMA_REG_10G_CTRL2, &tmp1);
3972                                 DP(NETIF_MSG_LINK, "1.7 = 0x%x \n", tmp1);
3973
3974                         } else if ((params->req_line_speed ==
3975                                     SPEED_AUTO_NEG) &&
3976                                    ((params->speed_cap_mask &
3977                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3978
3979                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3980                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3981                                                ext_phy_addr, MDIO_AN_DEVAD,
3982                                                MDIO_PMA_REG_8727_MISC_CTRL, 0);
3983                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3984                                                ext_phy_addr, MDIO_AN_DEVAD,
3985                                                MDIO_AN_REG_CL37_AN, 0x1300);
3986                         } else {
3987                                 /* Since the 8727 has only single reset pin,
3988                                 need to set the 10G registers although it is
3989                                 default */
3990                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3991                                                ext_phy_addr, MDIO_AN_DEVAD,
3992                                                MDIO_AN_REG_CTRL, 0x0020);
3993                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3994                                                ext_phy_addr, MDIO_AN_DEVAD,
3995                                                0x7, 0x0100);
3996                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3997                                                ext_phy_addr, MDIO_PMA_DEVAD,
3998                                                MDIO_PMA_REG_CTRL, 0x2040);
3999                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4000                                                ext_phy_addr, MDIO_PMA_DEVAD,
4001                                                MDIO_PMA_REG_10G_CTRL2, 0x0008);
4002                         }
4003
4004                         /* Set 2-wire transfer rate to 400Khz since 100Khz
4005                         is not operational */
4006                         bnx2x_cl45_write(bp, params->port,
4007                                        ext_phy_type,
4008                                        ext_phy_addr,
4009                                        MDIO_PMA_DEVAD,
4010                                        MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
4011                                        0xa101);
4012
4013                         /* Set TX PreEmphasis if needed */
4014                         if ((params->feature_config_flags &
4015                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
4016                                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
4017                                          "TX_CTRL2 0x%x\n",
4018                                          params->xgxs_config_tx[0],
4019                                          params->xgxs_config_tx[1]);
4020                                 bnx2x_cl45_write(bp, params->port,
4021                                                ext_phy_type,
4022                                                ext_phy_addr,
4023                                                MDIO_PMA_DEVAD,
4024                                                MDIO_PMA_REG_8727_TX_CTRL1,
4025                                                params->xgxs_config_tx[0]);
4026
4027                                 bnx2x_cl45_write(bp, params->port,
4028                                                ext_phy_type,
4029                                                ext_phy_addr,
4030                                                MDIO_PMA_DEVAD,
4031                                                MDIO_PMA_REG_8727_TX_CTRL2,
4032                                                params->xgxs_config_tx[1]);
4033                         }
4034
4035                         break;
4036                 }
4037
4038                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4039                 {
4040                         u16 fw_ver1, fw_ver2;
4041                         DP(NETIF_MSG_LINK,
4042                                 "Setting the SFX7101 LASI indication\n");
4043
4044                         bnx2x_cl45_write(bp, params->port,
4045                                        ext_phy_type,
4046                                        ext_phy_addr,
4047                                        MDIO_PMA_DEVAD,
4048                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
4049                         DP(NETIF_MSG_LINK,
4050                           "Setting the SFX7101 LED to blink on traffic\n");
4051                         bnx2x_cl45_write(bp, params->port,
4052                                        ext_phy_type,
4053                                        ext_phy_addr,
4054                                        MDIO_PMA_DEVAD,
4055                                        MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
4056
4057                         bnx2x_ext_phy_set_pause(params, vars);
4058                         /* Restart autoneg */
4059                         bnx2x_cl45_read(bp, params->port,
4060                                       ext_phy_type,
4061                                       ext_phy_addr,
4062                                       MDIO_AN_DEVAD,
4063                                       MDIO_AN_REG_CTRL, &val);
4064                         val |= 0x200;
4065                         bnx2x_cl45_write(bp, params->port,
4066                                        ext_phy_type,
4067                                        ext_phy_addr,
4068                                        MDIO_AN_DEVAD,
4069                                        MDIO_AN_REG_CTRL, val);
4070
4071                         /* Save spirom version */
4072                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4073                                       ext_phy_addr, MDIO_PMA_DEVAD,
4074                                       MDIO_PMA_REG_7101_VER1, &fw_ver1);
4075
4076                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4077                                       ext_phy_addr, MDIO_PMA_DEVAD,
4078                                       MDIO_PMA_REG_7101_VER2, &fw_ver2);
4079
4080                         bnx2x_save_spirom_version(params->bp, params->port,
4081                                                 params->shmem_base,
4082                                                 (u32)(fw_ver1<<16 | fw_ver2));
4083
4084                         break;
4085                 }
4086                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
4087                         /* This phy uses the NIG latch mechanism since link
4088                                 indication arrives through its LED4 and not via
4089                                 its LASI signal, so we get steady signal
4090                                 instead of clear on read */
4091                         bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
4092                                     1 << NIG_LATCH_BC_ENABLE_MI_INT);
4093
4094                         bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
4095                         if (params->req_line_speed == SPEED_AUTO_NEG) {
4096
4097                                 u16 autoneg_val, an_1000_val, an_10_100_val;
4098                                 /* set 1000 speed advertisement */
4099                                 bnx2x_cl45_read(bp, params->port,
4100                                               ext_phy_type,
4101                                               ext_phy_addr,
4102                                               MDIO_AN_DEVAD,
4103                                               MDIO_AN_REG_8481_1000T_CTRL,
4104                                               &an_1000_val);
4105
4106                                 if (params->speed_cap_mask &
4107                                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
4108                                         an_1000_val |= (1<<8);
4109                                         if (params->req_duplex == DUPLEX_FULL)
4110                                                 an_1000_val |= (1<<9);
4111                                         DP(NETIF_MSG_LINK, "Advertising 1G\n");
4112                                 } else
4113                                         an_1000_val &= ~((1<<8) | (1<<9));
4114
4115                                 bnx2x_cl45_write(bp, params->port,
4116                                                ext_phy_type,
4117                                                ext_phy_addr,
4118                                                MDIO_AN_DEVAD,
4119                                                MDIO_AN_REG_8481_1000T_CTRL,
4120                                                an_1000_val);
4121
4122                                 /* set 100 speed advertisement */
4123                                 bnx2x_cl45_read(bp, params->port,
4124                                               ext_phy_type,
4125                                               ext_phy_addr,
4126                                               MDIO_AN_DEVAD,
4127                                               MDIO_AN_REG_8481_LEGACY_AN_ADV,
4128                                               &an_10_100_val);
4129
4130                                 if (params->speed_cap_mask &
4131                                  (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
4132                                   PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) {
4133                                         an_10_100_val |= (1<<7);
4134                                         if (params->req_duplex == DUPLEX_FULL)
4135                                                 an_10_100_val |= (1<<8);
4136                                         DP(NETIF_MSG_LINK,
4137                                                 "Advertising 100M\n");
4138                                 } else
4139                                         an_10_100_val &= ~((1<<7) | (1<<8));
4140
4141                                 /* set 10 speed advertisement */
4142                                 if (params->speed_cap_mask &
4143                                   (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
4144                                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) {
4145                                         an_10_100_val |= (1<<5);
4146                                         if (params->req_duplex == DUPLEX_FULL)
4147                                                 an_10_100_val |= (1<<6);
4148                                         DP(NETIF_MSG_LINK, "Advertising 10M\n");
4149                                      }
4150                                 else
4151                                         an_10_100_val &= ~((1<<5) | (1<<6));
4152
4153                                 bnx2x_cl45_write(bp, params->port,
4154                                                ext_phy_type,
4155                                                ext_phy_addr,
4156                                                MDIO_AN_DEVAD,
4157                                                MDIO_AN_REG_8481_LEGACY_AN_ADV,
4158                                                an_10_100_val);
4159
4160                                 bnx2x_cl45_read(bp, params->port,
4161                                               ext_phy_type,
4162                                               ext_phy_addr,
4163                                               MDIO_AN_DEVAD,
4164                                               MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4165                                               &autoneg_val);
4166
4167                                 /* Disable forced speed */
4168                                 autoneg_val &= ~(1<<6|1<<13);
4169
4170                                 /* Enable autoneg and restart autoneg
4171                                 for legacy speeds */
4172                                 autoneg_val |= (1<<9|1<<12);
4173
4174                                 if (params->req_duplex == DUPLEX_FULL)
4175                                         autoneg_val |= (1<<8);
4176                                 else
4177                                         autoneg_val &= ~(1<<8);
4178
4179                                 bnx2x_cl45_write(bp, params->port,
4180                                                ext_phy_type,
4181                                                ext_phy_addr,
4182                                                MDIO_AN_DEVAD,
4183                                                MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4184                                                autoneg_val);
4185
4186                                 if (params->speed_cap_mask &
4187                                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
4188                                         DP(NETIF_MSG_LINK, "Advertising 10G\n");
4189                                         /* Restart autoneg for 10G*/
4190                         bnx2x_cl45_read(bp, params->port,
4191                                       ext_phy_type,
4192                                       ext_phy_addr,
4193                                       MDIO_AN_DEVAD,
4194                                       MDIO_AN_REG_CTRL, &val);
4195                         val |= 0x200;
4196                         bnx2x_cl45_write(bp, params->port,
4197                                        ext_phy_type,
4198                                        ext_phy_addr,
4199                                        MDIO_AN_DEVAD,
4200                                        MDIO_AN_REG_CTRL, val);
4201                                 }
4202                         } else {
4203                                 /* Force speed */
4204                                 u16 autoneg_ctrl, pma_ctrl;
4205                                 bnx2x_cl45_read(bp, params->port,
4206                                               ext_phy_type,
4207                                               ext_phy_addr,
4208                                               MDIO_AN_DEVAD,
4209                                               MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4210                                               &autoneg_ctrl);
4211
4212                                 /* Disable autoneg */
4213                                 autoneg_ctrl &= ~(1<<12);
4214
4215                                 /* Set 1000 force */
4216                                 switch (params->req_line_speed) {
4217                                 case SPEED_10000:
4218                                         DP(NETIF_MSG_LINK,
4219                                                 "Unable to set 10G force !\n");
4220                                         break;
4221                                 case SPEED_1000:
4222                                         bnx2x_cl45_read(bp, params->port,
4223                                                       ext_phy_type,
4224                                                       ext_phy_addr,
4225                                                       MDIO_PMA_DEVAD,
4226                                                       MDIO_PMA_REG_CTRL,
4227                                                       &pma_ctrl);
4228                                         autoneg_ctrl &= ~(1<<13);
4229                                         autoneg_ctrl |= (1<<6);
4230                                         pma_ctrl &= ~(1<<13);
4231                                         pma_ctrl |= (1<<6);
4232                                         DP(NETIF_MSG_LINK,
4233                                                 "Setting 1000M force\n");
4234                                         bnx2x_cl45_write(bp, params->port,
4235                                                        ext_phy_type,
4236                                                        ext_phy_addr,
4237                                                        MDIO_PMA_DEVAD,
4238                                                        MDIO_PMA_REG_CTRL,
4239                                                        pma_ctrl);
4240                                         break;
4241                                 case SPEED_100:
4242                                         autoneg_ctrl |= (1<<13);
4243                                         autoneg_ctrl &= ~(1<<6);
4244                                         DP(NETIF_MSG_LINK,
4245                                                 "Setting 100M force\n");
4246                                         break;
4247                                 case SPEED_10:
4248                                         autoneg_ctrl &= ~(1<<13);
4249                                         autoneg_ctrl &= ~(1<<6);
4250                                         DP(NETIF_MSG_LINK,
4251                                                 "Setting 10M force\n");
4252                                         break;
4253                                 }
4254
4255                                 /* Duplex mode */
4256                                 if (params->req_duplex == DUPLEX_FULL) {
4257                                         autoneg_ctrl |= (1<<8);
4258                                         DP(NETIF_MSG_LINK,
4259                                                 "Setting full duplex\n");
4260                                 } else
4261                                         autoneg_ctrl &= ~(1<<8);
4262
4263                                 /* Update autoneg ctrl and pma ctrl */
4264                                 bnx2x_cl45_write(bp, params->port,
4265                                                ext_phy_type,
4266                                                ext_phy_addr,
4267                                                MDIO_AN_DEVAD,
4268                                                MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4269                                                autoneg_ctrl);
4270                         }
4271
4272                         bnx2x_save_bcm_spirom_ver(bp, params->port,
4273                                                 ext_phy_type,
4274                                                 ext_phy_addr,
4275                                                 params->shmem_base);
4276
4277                         break;
4278                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4279                         DP(NETIF_MSG_LINK,
4280                                  "XGXS PHY Failure detected 0x%x\n",
4281                                  params->ext_phy_config);
4282                         rc = -EINVAL;
4283                         break;
4284                 default:
4285                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
4286                                   params->ext_phy_config);
4287                         rc = -EINVAL;
4288                         break;
4289                 }
4290
4291         } else { /* SerDes */
4292
4293                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4294                 switch (ext_phy_type) {
4295                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
4296                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
4297                         break;
4298
4299                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
4300                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
4301                         break;
4302
4303                 default:
4304                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
4305                            params->ext_phy_config);
4306                         break;
4307                 }
4308         }
4309         return rc;
4310 }
4311
4312 static void bnx2x_8727_handle_mod_abs(struct link_params *params)
4313 {
4314         struct bnx2x *bp = params->bp;
4315         u16 mod_abs, rx_alarm_status;
4316         u8 ext_phy_addr = ((params->ext_phy_config &
4317                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4318                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4319         u32 val = REG_RD(bp, params->shmem_base +
4320                              offsetof(struct shmem_region, dev_info.
4321                                       port_feature_config[params->port].
4322                                       config));
4323         bnx2x_cl45_read(bp, params->port,
4324                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4325                       ext_phy_addr,
4326                       MDIO_PMA_DEVAD,
4327                       MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4328         if (mod_abs & (1<<8)) {
4329
4330                 /* Module is absent */
4331                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4332                             "show module is absent\n");
4333
4334                 /* 1. Set mod_abs to detect next module
4335                 presence event
4336                    2. Set EDC off by setting OPTXLOS signal input to low
4337                         (bit 9).
4338                         When the EDC is off it locks onto a reference clock and
4339                         avoids becoming 'lost'.*/
4340                 mod_abs &= ~((1<<8)|(1<<9));
4341                 bnx2x_cl45_write(bp, params->port,
4342                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4343                                ext_phy_addr,
4344                                MDIO_PMA_DEVAD,
4345                                MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4346
4347                 /* Clear RX alarm since it stays up as long as
4348                 the mod_abs wasn't changed */
4349                 bnx2x_cl45_read(bp, params->port,
4350                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4351                               ext_phy_addr,
4352                               MDIO_PMA_DEVAD,
4353                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4354
4355         } else {
4356                 /* Module is present */
4357                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4358                             "show module is present\n");
4359                 /* First thing, disable transmitter,
4360                 and if the module is ok, the
4361                 module_detection will enable it*/
4362
4363                 /* 1. Set mod_abs to detect next module
4364                 absent event ( bit 8)
4365                    2. Restore the default polarity of the OPRXLOS signal and
4366                 this signal will then correctly indicate the presence or
4367                 absence of the Rx signal. (bit 9) */
4368                 mod_abs |= ((1<<8)|(1<<9));
4369                 bnx2x_cl45_write(bp, params->port,
4370                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4371                        ext_phy_addr,
4372                        MDIO_PMA_DEVAD,
4373                        MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4374
4375                 /* Clear RX alarm since it stays up as long as
4376                 the mod_abs wasn't changed. This is need to be done
4377                 before calling the module detection, otherwise it will clear
4378                 the link update alarm */
4379                 bnx2x_cl45_read(bp, params->port,
4380                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4381                               ext_phy_addr,
4382                               MDIO_PMA_DEVAD,
4383                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4384
4385
4386                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4387                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
4388                         bnx2x_sfp_set_transmitter(bp, params->port,
4389                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4390                                         ext_phy_addr, 0);
4391
4392                 if (bnx2x_wait_for_sfp_module_initialized(params)
4393                     == 0)
4394                         bnx2x_sfp_module_detection(params);
4395                 else
4396                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
4397         }
4398
4399         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4400                  rx_alarm_status);
4401         /* No need to check link status in case of
4402         module plugged in/out */
4403 }
4404
4405
4406 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
4407                                  struct link_vars *vars,
4408                                  u8 is_mi_int)
4409 {
4410         struct bnx2x *bp = params->bp;
4411         u32 ext_phy_type;
4412         u8 ext_phy_addr;
4413         u16 val1 = 0, val2;
4414         u16 rx_sd, pcs_status;
4415         u8 ext_phy_link_up = 0;
4416         u8 port = params->port;
4417         if (vars->phy_flags & PHY_XGXS_FLAG) {
4418                 ext_phy_addr = ((params->ext_phy_config &
4419                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4420                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4421
4422                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4423                 switch (ext_phy_type) {
4424                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4425                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
4426                         ext_phy_link_up = 1;
4427                         break;
4428
4429                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4430                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
4431                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4432                                       ext_phy_addr,
4433                                       MDIO_WIS_DEVAD,
4434                                       MDIO_WIS_REG_LASI_STATUS, &val1);
4435                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4436
4437                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4438                                       ext_phy_addr,
4439                                       MDIO_WIS_DEVAD,
4440                                       MDIO_WIS_REG_LASI_STATUS, &val1);
4441                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4442
4443                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4444                                       ext_phy_addr,
4445                                       MDIO_PMA_DEVAD,
4446                                       MDIO_PMA_REG_RX_SD, &rx_sd);
4447
4448                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4449                                       ext_phy_addr,
4450                                       1,
4451                                       0xc809, &val1);
4452                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4453                                       ext_phy_addr,
4454                                       1,
4455                                       0xc809, &val1);
4456
4457                         DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4458                         ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9))
4459                                            && ((val1 & (1<<8)) == 0));
4460                         if (ext_phy_link_up)
4461                                 vars->line_speed = SPEED_10000;
4462                         break;
4463
4464                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4465                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4466                         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
4467                         /* Clear RX Alarm*/
4468                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4469                                       ext_phy_addr,
4470                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
4471                                       &val2);
4472                         /* clear LASI indication*/
4473                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4474                                       ext_phy_addr,
4475                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4476                                       &val1);
4477                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4478                                       ext_phy_addr,
4479                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4480                                       &val2);
4481                         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
4482                                      "0x%x\n", val1, val2);
4483
4484                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4485                                       ext_phy_addr,
4486                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
4487                                       &rx_sd);
4488                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4489                                       ext_phy_addr,
4490                                       MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
4491                                       &pcs_status);
4492                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4493                                       ext_phy_addr,
4494                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4495                                       &val2);
4496                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4497                                       ext_phy_addr,
4498                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4499                                       &val2);
4500
4501                         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
4502                            "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
4503                            rx_sd, pcs_status, val2);
4504                         /* link is up if both bit 0 of pmd_rx_sd and
4505                          * bit 0 of pcs_status are set, or if the autoneg bit
4506                            1 is set
4507                          */
4508                         ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
4509                                            (val2 & (1<<1)));
4510                         if (ext_phy_link_up) {
4511                                 if (ext_phy_type ==
4512                                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
4513                                         /* If transmitter is disabled,
4514                                         ignore false link up indication */
4515                                         bnx2x_cl45_read(bp, params->port,
4516                                                    ext_phy_type,
4517                                                    ext_phy_addr,
4518                                                    MDIO_PMA_DEVAD,
4519                                                    MDIO_PMA_REG_PHY_IDENTIFIER,
4520                                                    &val1);
4521                                         if (val1 & (1<<15)) {
4522                                                 DP(NETIF_MSG_LINK, "Tx is "
4523                                                             "disabled\n");
4524                                                 ext_phy_link_up = 0;
4525                                                 break;
4526                                         }
4527                                 }
4528
4529                                 if (val2 & (1<<1))
4530                                         vars->line_speed = SPEED_1000;
4531                                 else
4532                                         vars->line_speed = SPEED_10000;
4533                         }
4534                         break;
4535
4536                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4537                 {
4538                         u16 link_status = 0;
4539                         u16 rx_alarm_status;
4540                         /* Check the LASI */
4541                         bnx2x_cl45_read(bp, params->port,
4542                                       ext_phy_type,
4543                                       ext_phy_addr,
4544                                       MDIO_PMA_DEVAD,
4545                                       MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4546
4547                         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4548                                  rx_alarm_status);
4549
4550                         bnx2x_cl45_read(bp, params->port,
4551                                       ext_phy_type,
4552                                       ext_phy_addr,
4553                                       MDIO_PMA_DEVAD,
4554                                       MDIO_PMA_REG_LASI_STATUS, &val1);
4555
4556                         DP(NETIF_MSG_LINK,
4557                                  "8727 LASI status 0x%x\n",
4558                                  val1);
4559
4560                         /* Clear MSG-OUT */
4561                         bnx2x_cl45_read(bp, params->port,
4562                                       ext_phy_type,
4563                                       ext_phy_addr,
4564                                       MDIO_PMA_DEVAD,
4565                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
4566                                       &val1);
4567
4568                         /*
4569                          * If a module is present and there is need to check
4570                          * for over current
4571                          */
4572                         if (!(params->feature_config_flags &
4573                               FEATURE_CONFIG_BCM8727_NOC) &&
4574                             !(rx_alarm_status & (1<<5))) {
4575                                 /* Check over-current using 8727 GPIO0 input*/
4576                                 bnx2x_cl45_read(bp, params->port,
4577                                               ext_phy_type,
4578                                               ext_phy_addr,
4579                                               MDIO_PMA_DEVAD,
4580                                               MDIO_PMA_REG_8727_GPIO_CTRL,
4581                                               &val1);
4582
4583                                 if ((val1 & (1<<8)) == 0) {
4584                                         DP(NETIF_MSG_LINK, "8727 Power fault"
4585                                                  " has been detected on port"
4586                                                  " %d\n", params->port);
4587                                         printk(KERN_ERR PFX  "Error:  Power"
4588                                                  " fault on %s Port %d has"
4589                                                  " been detected and the"
4590                                                  " power to that SFP+ module"
4591                                                  " has been removed to prevent"
4592                                                  " failure of the card. Please"
4593                                                  " remove the SFP+ module and"
4594                                                  " restart the system to clear"
4595                                                  " this error.\n"
4596                         , bp->dev->name, params->port);
4597                                         /*
4598                                          * Disable all RX_ALARMs except for
4599                                          * mod_abs
4600                                          */
4601                                         bnx2x_cl45_write(bp, params->port,
4602                                                      ext_phy_type,
4603                                                      ext_phy_addr,
4604                                                      MDIO_PMA_DEVAD,
4605                                                      MDIO_PMA_REG_RX_ALARM_CTRL,
4606                                                      (1<<5));
4607
4608                                         bnx2x_cl45_read(bp, params->port,
4609                                                     ext_phy_type,
4610                                                     ext_phy_addr,
4611                                                     MDIO_PMA_DEVAD,
4612                                                     MDIO_PMA_REG_PHY_IDENTIFIER,
4613                                                     &val1);
4614                                         /* Wait for module_absent_event */
4615                                         val1 |= (1<<8);
4616                                         bnx2x_cl45_write(bp, params->port,
4617                                                     ext_phy_type,
4618                                                     ext_phy_addr,
4619                                                     MDIO_PMA_DEVAD,
4620                                                     MDIO_PMA_REG_PHY_IDENTIFIER,
4621                                                     val1);
4622                                         /* Clear RX alarm */
4623                                         bnx2x_cl45_read(bp, params->port,
4624                                                       ext_phy_type,
4625                                                       ext_phy_addr,
4626                                                       MDIO_PMA_DEVAD,
4627                                                       MDIO_PMA_REG_RX_ALARM,
4628                                                       &rx_alarm_status);
4629                                         break;
4630                                 }
4631                         } /* Over current check */
4632
4633                         /* When module absent bit is set, check module */
4634                         if (rx_alarm_status & (1<<5)) {
4635                                 bnx2x_8727_handle_mod_abs(params);
4636                                 /* Enable all mod_abs and link detection bits */
4637                                 bnx2x_cl45_write(bp, params->port,
4638                                                ext_phy_type,
4639                                                ext_phy_addr,
4640                                                MDIO_PMA_DEVAD,
4641                                                MDIO_PMA_REG_RX_ALARM_CTRL,
4642                                                ((1<<5) | (1<<2)));
4643                         }
4644
4645                         /* If transmitter is disabled,
4646                         ignore false link up indication */
4647                         bnx2x_cl45_read(bp, params->port,
4648                                       ext_phy_type,
4649                                       ext_phy_addr,
4650                                       MDIO_PMA_DEVAD,
4651                                       MDIO_PMA_REG_PHY_IDENTIFIER,
4652                                       &val1);
4653                         if (val1 & (1<<15)) {
4654                                 DP(NETIF_MSG_LINK, "Tx is disabled\n");
4655                                 ext_phy_link_up = 0;
4656                                 break;
4657                         }
4658
4659                         bnx2x_cl45_read(bp, params->port,
4660                                       ext_phy_type,
4661                                       ext_phy_addr,
4662                                       MDIO_PMA_DEVAD,
4663                                       MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4664                                       &link_status);
4665
4666                         /* Bits 0..2 --> speed detected,
4667                            bits 13..15--> link is down */
4668                         if ((link_status & (1<<2)) &&
4669                             (!(link_status & (1<<15)))) {
4670                                 ext_phy_link_up = 1;
4671                                 vars->line_speed = SPEED_10000;
4672                         } else if ((link_status & (1<<0)) &&
4673                                    (!(link_status & (1<<13)))) {
4674                                 ext_phy_link_up = 1;
4675                                 vars->line_speed = SPEED_1000;
4676                                 DP(NETIF_MSG_LINK,
4677                                          "port %x: External link"
4678                                          " up in 1G\n", params->port);
4679                         } else {
4680                                 ext_phy_link_up = 0;
4681                                 DP(NETIF_MSG_LINK,
4682                                          "port %x: External link"
4683                                          " is down\n", params->port);
4684                         }
4685                         break;
4686                 }
4687
4688                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4689                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4690                 {
4691                         u16 link_status = 0;
4692                         u16 an1000_status = 0;
4693                         if (ext_phy_type ==
4694                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
4695                                 bnx2x_cl45_read(bp, params->port,
4696                                       ext_phy_type,
4697                                       ext_phy_addr,
4698                                       MDIO_PCS_DEVAD,
4699                                       MDIO_PCS_REG_LASI_STATUS, &val1);
4700                         bnx2x_cl45_read(bp, params->port,
4701                                       ext_phy_type,
4702                                       ext_phy_addr,
4703                                       MDIO_PCS_DEVAD,
4704                                       MDIO_PCS_REG_LASI_STATUS, &val2);
4705                         DP(NETIF_MSG_LINK,
4706                                  "870x LASI status 0x%x->0x%x\n",
4707                                   val1, val2);
4708
4709                         } else {
4710                                 /* In 8073, port1 is directed through emac0 and
4711                                  * port0 is directed through emac1
4712                                  */
4713                                 bnx2x_cl45_read(bp, params->port,
4714                                               ext_phy_type,
4715                                               ext_phy_addr,
4716                                               MDIO_PMA_DEVAD,
4717                                               MDIO_PMA_REG_LASI_STATUS, &val1);
4718
4719                                 DP(NETIF_MSG_LINK,
4720                                          "8703 LASI status 0x%x\n",
4721                                           val1);
4722                         }
4723
4724                         /* clear the interrupt LASI status register */
4725                         bnx2x_cl45_read(bp, params->port,
4726                                       ext_phy_type,
4727                                       ext_phy_addr,
4728                                       MDIO_PCS_DEVAD,
4729                                       MDIO_PCS_REG_STATUS, &val2);
4730                         bnx2x_cl45_read(bp, params->port,
4731                                       ext_phy_type,
4732                                       ext_phy_addr,
4733                                       MDIO_PCS_DEVAD,
4734                                       MDIO_PCS_REG_STATUS, &val1);
4735                         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
4736                            val2, val1);
4737                         /* Clear MSG-OUT */
4738                         bnx2x_cl45_read(bp, params->port,
4739                                       ext_phy_type,
4740                                       ext_phy_addr,
4741                                       MDIO_PMA_DEVAD,
4742                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
4743                                       &val1);
4744
4745                         /* Check the LASI */
4746                         bnx2x_cl45_read(bp, params->port,
4747                                       ext_phy_type,
4748                                       ext_phy_addr,
4749                                       MDIO_PMA_DEVAD,
4750                                       MDIO_PMA_REG_RX_ALARM, &val2);
4751
4752                         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
4753
4754                         /* Check the link status */
4755                         bnx2x_cl45_read(bp, params->port,
4756                                       ext_phy_type,
4757                                       ext_phy_addr,
4758                                       MDIO_PCS_DEVAD,
4759                                       MDIO_PCS_REG_STATUS, &val2);
4760                         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
4761
4762                         bnx2x_cl45_read(bp, params->port,
4763                                       ext_phy_type,
4764                                       ext_phy_addr,
4765                                       MDIO_PMA_DEVAD,
4766                                       MDIO_PMA_REG_STATUS, &val2);
4767                         bnx2x_cl45_read(bp, params->port,
4768                                       ext_phy_type,
4769                                       ext_phy_addr,
4770                                       MDIO_PMA_DEVAD,
4771                                       MDIO_PMA_REG_STATUS, &val1);
4772                         ext_phy_link_up = ((val1 & 4) == 4);
4773                         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
4774                         if (ext_phy_type ==
4775                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4776
4777                                 if (ext_phy_link_up &&
4778                                     ((params->req_line_speed !=
4779                                         SPEED_10000))) {
4780                                         if (bnx2x_bcm8073_xaui_wa(params)
4781                                              != 0) {
4782                                                 ext_phy_link_up = 0;
4783                                                 break;
4784                                         }
4785                                 }
4786                                 bnx2x_cl45_read(bp, params->port,
4787                                               ext_phy_type,
4788                                               ext_phy_addr,
4789                                               MDIO_AN_DEVAD,
4790                                               MDIO_AN_REG_LINK_STATUS,
4791                                               &an1000_status);
4792                                 bnx2x_cl45_read(bp, params->port,
4793                                               ext_phy_type,
4794                                               ext_phy_addr,
4795                                               MDIO_AN_DEVAD,
4796                                               MDIO_AN_REG_LINK_STATUS,
4797                                               &an1000_status);
4798
4799                                 /* Check the link status on 1.1.2 */
4800                                 bnx2x_cl45_read(bp, params->port,
4801                                               ext_phy_type,
4802                                               ext_phy_addr,
4803                                               MDIO_PMA_DEVAD,
4804                                               MDIO_PMA_REG_STATUS, &val2);
4805                                 bnx2x_cl45_read(bp, params->port,
4806                                               ext_phy_type,
4807                                               ext_phy_addr,
4808                                               MDIO_PMA_DEVAD,
4809                                               MDIO_PMA_REG_STATUS, &val1);
4810                                 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
4811                                              "an_link_status=0x%x\n",
4812                                           val2, val1, an1000_status);
4813
4814                                 ext_phy_link_up = (((val1 & 4) == 4) ||
4815                                                 (an1000_status & (1<<1)));
4816                                 if (ext_phy_link_up &&
4817                                     bnx2x_8073_is_snr_needed(params)) {
4818                                         /* The SNR will improve about 2dbby
4819                                         changing the BW and FEE main tap.*/
4820
4821                                         /* The 1st write to change FFE main
4822                                         tap is set before restart AN */
4823                                         /* Change PLL Bandwidth in EDC
4824                                         register */
4825                                         bnx2x_cl45_write(bp, port, ext_phy_type,
4826                                                     ext_phy_addr,
4827                                                     MDIO_PMA_DEVAD,
4828                                                     MDIO_PMA_REG_PLL_BANDWIDTH,
4829                                                     0x26BC);
4830
4831                                         /* Change CDR Bandwidth in EDC
4832                                         register */
4833                                         bnx2x_cl45_write(bp, port, ext_phy_type,
4834                                                     ext_phy_addr,
4835                                                     MDIO_PMA_DEVAD,
4836                                                     MDIO_PMA_REG_CDR_BANDWIDTH,
4837                                                     0x0333);
4838
4839
4840                                 }
4841                                 bnx2x_cl45_read(bp, params->port,
4842                                            ext_phy_type,
4843                                            ext_phy_addr,
4844                                            MDIO_PMA_DEVAD,
4845                                            MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4846                                            &link_status);
4847
4848                                 /* Bits 0..2 --> speed detected,
4849                                    bits 13..15--> link is down */
4850                                 if ((link_status & (1<<2)) &&
4851                                     (!(link_status & (1<<15)))) {
4852                                         ext_phy_link_up = 1;
4853                                         vars->line_speed = SPEED_10000;
4854                                         DP(NETIF_MSG_LINK,
4855                                                  "port %x: External link"
4856                                                  " up in 10G\n", params->port);
4857                                 } else if ((link_status & (1<<1)) &&
4858                                            (!(link_status & (1<<14)))) {
4859                                         ext_phy_link_up = 1;
4860                                         vars->line_speed = SPEED_2500;
4861                                         DP(NETIF_MSG_LINK,
4862                                                  "port %x: External link"
4863                                                  " up in 2.5G\n", params->port);
4864                                 } else if ((link_status & (1<<0)) &&
4865                                            (!(link_status & (1<<13)))) {
4866                                         ext_phy_link_up = 1;
4867                                         vars->line_speed = SPEED_1000;
4868                                         DP(NETIF_MSG_LINK,
4869                                                  "port %x: External link"
4870                                                  " up in 1G\n", params->port);
4871                                 } else {
4872                                         ext_phy_link_up = 0;
4873                                         DP(NETIF_MSG_LINK,
4874                                                  "port %x: External link"
4875                                                  " is down\n", params->port);
4876                                 }
4877                         } else {
4878                                 /* See if 1G link is up for the 8072 */
4879                                 bnx2x_cl45_read(bp, params->port,
4880                                               ext_phy_type,
4881                                               ext_phy_addr,
4882                                               MDIO_AN_DEVAD,
4883                                               MDIO_AN_REG_LINK_STATUS,
4884                                               &an1000_status);
4885                                 bnx2x_cl45_read(bp, params->port,
4886                                               ext_phy_type,
4887                                               ext_phy_addr,
4888                                               MDIO_AN_DEVAD,
4889                                               MDIO_AN_REG_LINK_STATUS,
4890                                               &an1000_status);
4891                                 if (an1000_status & (1<<1)) {
4892                                         ext_phy_link_up = 1;
4893                                         vars->line_speed = SPEED_1000;
4894                                         DP(NETIF_MSG_LINK,
4895                                                  "port %x: External link"
4896                                                  " up in 1G\n", params->port);
4897                                 } else if (ext_phy_link_up) {
4898                                         ext_phy_link_up = 1;
4899                                         vars->line_speed = SPEED_10000;
4900                                         DP(NETIF_MSG_LINK,
4901                                                  "port %x: External link"
4902                                                  " up in 10G\n", params->port);
4903                                 }
4904                         }
4905
4906
4907                         break;
4908                 }
4909                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4910                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4911                                       ext_phy_addr,
4912                                       MDIO_PMA_DEVAD,
4913                                       MDIO_PMA_REG_LASI_STATUS, &val2);
4914                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4915                                       ext_phy_addr,
4916                                       MDIO_PMA_DEVAD,
4917                                       MDIO_PMA_REG_LASI_STATUS, &val1);
4918                         DP(NETIF_MSG_LINK,
4919                                  "10G-base-T LASI status 0x%x->0x%x\n",
4920                                   val2, val1);
4921                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4922                                       ext_phy_addr,
4923                                       MDIO_PMA_DEVAD,
4924                                       MDIO_PMA_REG_STATUS, &val2);
4925                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4926                                       ext_phy_addr,
4927                                       MDIO_PMA_DEVAD,
4928                                       MDIO_PMA_REG_STATUS, &val1);
4929                         DP(NETIF_MSG_LINK,
4930                                  "10G-base-T PMA status 0x%x->0x%x\n",
4931                                  val2, val1);
4932                         ext_phy_link_up = ((val1 & 4) == 4);
4933                         /* if link is up
4934                          * print the AN outcome of the SFX7101 PHY
4935                          */
4936                         if (ext_phy_link_up) {
4937                                 bnx2x_cl45_read(bp, params->port,
4938                                               ext_phy_type,
4939                                               ext_phy_addr,
4940                                               MDIO_AN_DEVAD,
4941                                               MDIO_AN_REG_MASTER_STATUS,
4942                                               &val2);
4943                                 vars->line_speed = SPEED_10000;
4944                                 DP(NETIF_MSG_LINK,
4945                                          "SFX7101 AN status 0x%x->Master=%x\n",
4946                                           val2,
4947                                          (val2 & (1<<14)));
4948                         }
4949                         break;
4950                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
4951                         /* Check 10G-BaseT link status */
4952                         /* Check PMD signal ok */
4953                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4954                                                       ext_phy_addr,
4955                                                       MDIO_AN_DEVAD,
4956                                                       0xFFFA,
4957                                                       &val1);
4958                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4959                                       ext_phy_addr,
4960                                       MDIO_PMA_DEVAD,
4961                                       MDIO_PMA_REG_8481_PMD_SIGNAL,
4962                                       &val2);
4963                         DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2);
4964
4965                         /* Check link 10G */
4966                         if (val2 & (1<<11)) {
4967                                 vars->line_speed = SPEED_10000;
4968                                 ext_phy_link_up = 1;
4969                                 bnx2x_8481_set_10G_led_mode(params,
4970                                                           ext_phy_type,
4971                                                           ext_phy_addr);
4972                         } else { /* Check Legacy speed link */
4973                                 u16 legacy_status, legacy_speed;
4974
4975                                 /* Enable expansion register 0x42
4976                                 (Operation mode status) */
4977                                 bnx2x_cl45_write(bp, params->port,
4978                                          ext_phy_type,
4979                                          ext_phy_addr,
4980                                          MDIO_AN_DEVAD,
4981                                          MDIO_AN_REG_8481_EXPANSION_REG_ACCESS,
4982                                          0xf42);
4983
4984                                 /* Get legacy speed operation status */
4985                                 bnx2x_cl45_read(bp, params->port,
4986                                           ext_phy_type,
4987                                           ext_phy_addr,
4988                                           MDIO_AN_DEVAD,
4989                                           MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
4990                                           &legacy_status);
4991
4992                                 DP(NETIF_MSG_LINK, "Legacy speed status"
4993                                              " = 0x%x\n", legacy_status);
4994                                 ext_phy_link_up = ((legacy_status & (1<<11))
4995                                                    == (1<<11));
4996                                 if (ext_phy_link_up) {
4997                                         legacy_speed = (legacy_status & (3<<9));
4998                                         if (legacy_speed == (0<<9))
4999                                                 vars->line_speed = SPEED_10;
5000                                         else if (legacy_speed == (1<<9))
5001                                                 vars->line_speed =
5002                                                         SPEED_100;
5003                                         else if (legacy_speed == (2<<9))
5004                                                 vars->line_speed =
5005                                                         SPEED_1000;
5006                                         else /* Should not happen */
5007                                                 vars->line_speed = 0;
5008
5009                                         if (legacy_status & (1<<8))
5010                                                 vars->duplex = DUPLEX_FULL;
5011                                         else
5012                                                 vars->duplex = DUPLEX_HALF;
5013
5014                                         DP(NETIF_MSG_LINK, "Link is up "
5015                                                      "in %dMbps, is_duplex_full"
5016                                                      "= %d\n",
5017                                                 vars->line_speed,
5018                                                 (vars->duplex == DUPLEX_FULL));
5019                                         bnx2x_8481_set_legacy_led_mode(params,
5020                                                                  ext_phy_type,
5021                                                                  ext_phy_addr);
5022                                 }
5023                         }
5024
5025                         break;
5026                 default:
5027                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
5028                            params->ext_phy_config);
5029                         ext_phy_link_up = 0;
5030                         break;
5031                 }
5032
5033         } else { /* SerDes */
5034                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5035                 switch (ext_phy_type) {
5036                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
5037                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
5038                         ext_phy_link_up = 1;
5039                         break;
5040
5041                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
5042                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
5043                         ext_phy_link_up = 1;
5044                         break;
5045
5046                 default:
5047                         DP(NETIF_MSG_LINK,
5048                                  "BAD SerDes ext_phy_config 0x%x\n",
5049                                  params->ext_phy_config);
5050                         ext_phy_link_up = 0;
5051                         break;
5052                 }
5053         }
5054
5055         return ext_phy_link_up;
5056 }
5057
5058 static void bnx2x_link_int_enable(struct link_params *params)
5059 {
5060         u8 port = params->port;
5061         u32 ext_phy_type;
5062         u32 mask;
5063         struct bnx2x *bp = params->bp;
5064         /* setting the status to report on link up
5065            for either XGXS or SerDes */
5066
5067         if (params->switch_cfg == SWITCH_CFG_10G) {
5068                 mask = (NIG_MASK_XGXS0_LINK10G |
5069                         NIG_MASK_XGXS0_LINK_STATUS);
5070                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5071                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5072                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5073                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
5074                     (ext_phy_type !=
5075                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
5076                         mask |= NIG_MASK_MI_INT;
5077                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5078                 }
5079
5080         } else { /* SerDes */
5081                 mask = NIG_MASK_SERDES0_LINK_STATUS;
5082                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5083                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5084                 if ((ext_phy_type !=
5085                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5086                     (ext_phy_type !=
5087                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
5088                         mask |= NIG_MASK_MI_INT;
5089                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5090                 }
5091         }
5092         bnx2x_bits_en(bp,
5093                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5094                       mask);
5095         DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
5096                  (params->switch_cfg == SWITCH_CFG_10G),
5097                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5098
5099         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5100                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5101                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5102                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5103         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5104            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5105            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5106 }
5107
5108 static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
5109                                         u8 is_mi_int)
5110 {
5111         u32 latch_status = 0, is_mi_int_status;
5112         /* Disable the MI INT ( external phy int )
5113          * by writing 1 to the status register. Link down indication
5114          * is high-active-signal, so in this case we need to write the
5115          * status to clear the XOR
5116          */
5117         /* Read Latched signals */
5118         latch_status = REG_RD(bp,
5119                                   NIG_REG_LATCH_STATUS_0 + port*8);
5120         is_mi_int_status = REG_RD(bp,
5121                                   NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
5122         DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
5123                      "latch_status = 0x%x\n",
5124                  is_mi_int, is_mi_int_status, latch_status);
5125         /* Handle only those with latched-signal=up.*/
5126         if (latch_status & 1) {
5127                 /* For all latched-signal=up,Write original_signal to status */
5128                 if (is_mi_int)
5129                         bnx2x_bits_en(bp,
5130                                     NIG_REG_STATUS_INTERRUPT_PORT0
5131                                     + port*4,
5132                                     NIG_STATUS_EMAC0_MI_INT);
5133                 else
5134                         bnx2x_bits_dis(bp,
5135                                      NIG_REG_STATUS_INTERRUPT_PORT0
5136                                      + port*4,
5137                                      NIG_STATUS_EMAC0_MI_INT);
5138                 /* For all latched-signal=up : Re-Arm Latch signals */
5139                 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
5140                            (latch_status & 0xfffe) | (latch_status & 1));
5141         }
5142 }
5143 /*
5144  * link management
5145  */
5146 static void bnx2x_link_int_ack(struct link_params *params,
5147                              struct link_vars *vars, u8 is_10g,
5148                              u8 is_mi_int)
5149 {
5150         struct bnx2x *bp = params->bp;
5151         u8 port = params->port;
5152
5153         /* first reset all status
5154          * we assume only one line will be change at a time */
5155         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5156                      (NIG_STATUS_XGXS0_LINK10G |
5157                       NIG_STATUS_XGXS0_LINK_STATUS |
5158                       NIG_STATUS_SERDES0_LINK_STATUS));
5159         if (XGXS_EXT_PHY_TYPE(params->ext_phy_config)
5160             == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) {
5161                 bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
5162         }
5163         if (vars->phy_link_up) {
5164                 if (is_10g) {
5165                         /* Disable the 10G link interrupt
5166                          * by writing 1 to the status register
5167                          */
5168                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
5169                         bnx2x_bits_en(bp,
5170                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5171                                       NIG_STATUS_XGXS0_LINK10G);
5172
5173                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
5174                         /* Disable the link interrupt
5175                          * by writing 1 to the relevant lane
5176                          * in the status register
5177                          */
5178                         u32 ser_lane = ((params->lane_config &
5179                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5180                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5181
5182                         DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
5183                                  vars->line_speed);
5184                         bnx2x_bits_en(bp,
5185                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5186                                       ((1 << ser_lane) <<
5187                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
5188
5189                 } else { /* SerDes */
5190                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
5191                         /* Disable the link interrupt
5192                          * by writing 1 to the status register
5193                          */
5194                         bnx2x_bits_en(bp,
5195                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5196                                       NIG_STATUS_SERDES0_LINK_STATUS);
5197                 }
5198
5199         } else { /* link_down */
5200         }
5201 }
5202
5203 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
5204 {
5205         u8 *str_ptr = str;
5206         u32 mask = 0xf0000000;
5207         u8 shift = 8*4;
5208         u8 digit;
5209         if (len < 10) {
5210                 /* Need more than 10chars for this format */
5211                 *str_ptr = '\0';
5212                 return -EINVAL;
5213         }
5214         while (shift > 0) {
5215
5216                 shift -= 4;
5217                 digit = ((num & mask) >> shift);
5218                 if (digit < 0xa)
5219                         *str_ptr = digit + '0';
5220                 else
5221                         *str_ptr = digit - 0xa + 'a';
5222                 str_ptr++;
5223                 mask = mask >> 4;
5224                 if (shift == 4*4) {
5225                         *str_ptr = ':';
5226                         str_ptr++;
5227                 }
5228         }
5229         *str_ptr = '\0';
5230         return 0;
5231 }
5232
5233
5234 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
5235                            u32 ext_phy_type)
5236 {
5237         u32 cnt = 0;
5238         u16 ctrl = 0;
5239         /* Enable EMAC0 in to enable MDIO */
5240         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
5241                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
5242         msleep(5);
5243
5244         /* take ext phy out of reset */
5245         bnx2x_set_gpio(bp,
5246                           MISC_REGISTERS_GPIO_2,
5247                           MISC_REGISTERS_GPIO_HIGH,
5248                           port);
5249
5250         bnx2x_set_gpio(bp,
5251                           MISC_REGISTERS_GPIO_1,
5252                           MISC_REGISTERS_GPIO_HIGH,
5253                           port);
5254
5255         /* wait for 5ms */
5256         msleep(5);
5257
5258         for (cnt = 0; cnt < 1000; cnt++) {
5259                 msleep(1);
5260                 bnx2x_cl45_read(bp, port,
5261                               ext_phy_type,
5262                               ext_phy_addr,
5263                               MDIO_PMA_DEVAD,
5264                               MDIO_PMA_REG_CTRL,
5265                               &ctrl);
5266                 if (!(ctrl & (1<<15))) {
5267                         DP(NETIF_MSG_LINK, "Reset completed\n\n");
5268                                 break;
5269                 }
5270         }
5271 }
5272
5273 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
5274 {
5275         /* put sf to reset */
5276         bnx2x_set_gpio(bp,
5277                           MISC_REGISTERS_GPIO_1,
5278                           MISC_REGISTERS_GPIO_LOW,
5279                           port);
5280         bnx2x_set_gpio(bp,
5281                           MISC_REGISTERS_GPIO_2,
5282                           MISC_REGISTERS_GPIO_LOW,
5283                           port);
5284 }
5285
5286 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
5287                               u8 *version, u16 len)
5288 {
5289         struct bnx2x *bp;
5290         u32 ext_phy_type = 0;
5291         u32 spirom_ver = 0;
5292         u8 status = 0 ;
5293
5294         if (version == NULL || params == NULL)
5295                 return -EINVAL;
5296         bp = params->bp;
5297
5298         spirom_ver = REG_RD(bp, params->shmem_base +
5299                    offsetof(struct shmem_region,
5300                             port_mb[params->port].ext_phy_fw_version));
5301
5302         /* reset the returned value to zero */
5303         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5304         switch (ext_phy_type) {
5305         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5306
5307                 if (len < 5)
5308                         return -EINVAL;
5309
5310                 version[0] = (spirom_ver & 0xFF);
5311                 version[1] = (spirom_ver & 0xFF00) >> 8;
5312                 version[2] = (spirom_ver & 0xFF0000) >> 16;
5313                 version[3] = (spirom_ver & 0xFF000000) >> 24;
5314                 version[4] = '\0';
5315
5316                 break;
5317         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5318         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5319         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
5320         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5321         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5322         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5323         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5324                 status = bnx2x_format_ver(spirom_ver, version, len);
5325                 break;
5326         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5327                 break;
5328
5329         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5330                 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
5331                                     " type is FAILURE!\n");
5332                 status = -EINVAL;
5333                 break;
5334
5335         default:
5336                 break;
5337         }
5338         return status;
5339 }
5340
5341 static void bnx2x_set_xgxs_loopback(struct link_params *params,
5342                                   struct link_vars *vars,
5343                                   u8 is_10g)
5344 {
5345         u8 port = params->port;
5346         struct bnx2x *bp = params->bp;
5347
5348         if (is_10g) {
5349                 u32 md_devad;
5350
5351                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
5352
5353                 /* change the uni_phy_addr in the nig */
5354                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
5355                                           port*0x18));
5356
5357                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
5358
5359                 bnx2x_cl45_write(bp, port, 0,
5360                                params->phy_addr,
5361                                5,
5362                                (MDIO_REG_BANK_AER_BLOCK +
5363                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
5364                                0x2800);
5365
5366                 bnx2x_cl45_write(bp, port, 0,
5367                                params->phy_addr,
5368                                5,
5369                                (MDIO_REG_BANK_CL73_IEEEB0 +
5370                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5371                                0x6041);
5372                 msleep(200);
5373                 /* set aer mmd back */
5374                 bnx2x_set_aer_mmd(params, vars);
5375
5376                 /* and md_devad */
5377                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5378                             md_devad);
5379
5380         } else {
5381                 u16 mii_control;
5382
5383                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
5384
5385                 CL45_RD_OVER_CL22(bp, port,
5386                                       params->phy_addr,
5387                                       MDIO_REG_BANK_COMBO_IEEE0,
5388                                       MDIO_COMBO_IEEE0_MII_CONTROL,
5389                                       &mii_control);
5390
5391                 CL45_WR_OVER_CL22(bp, port,
5392                                       params->phy_addr,
5393                                       MDIO_REG_BANK_COMBO_IEEE0,
5394                                       MDIO_COMBO_IEEE0_MII_CONTROL,
5395                                       (mii_control |
5396                                        MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
5397         }
5398 }
5399
5400
5401 static void bnx2x_ext_phy_loopback(struct link_params *params)
5402 {
5403         struct bnx2x *bp = params->bp;
5404         u8 ext_phy_addr;
5405         u32 ext_phy_type;
5406
5407         if (params->switch_cfg == SWITCH_CFG_10G) {
5408                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5409                 /* CL37 Autoneg Enabled */
5410                 ext_phy_addr = ((params->ext_phy_config &
5411                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5412                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5413                 switch (ext_phy_type) {
5414                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5415                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5416                         DP(NETIF_MSG_LINK,
5417                                 "ext_phy_loopback: We should not get here\n");
5418                         break;
5419                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5420                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
5421                         break;
5422                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5423                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
5424                         break;
5425                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5426                         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
5427                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
5428                                        ext_phy_addr,
5429                                        MDIO_PMA_DEVAD,
5430                                        MDIO_PMA_REG_CTRL,
5431                                        0x0001);
5432                         break;
5433                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5434                         /* SFX7101_XGXS_TEST1 */
5435                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
5436                                        ext_phy_addr,
5437                                        MDIO_XS_DEVAD,
5438                                        MDIO_XS_SFX7101_XGXS_TEST1,
5439                                        0x100);
5440                         DP(NETIF_MSG_LINK,
5441                                 "ext_phy_loopback: set ext phy loopback\n");
5442                         break;
5443                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5444
5445                         break;
5446                 } /* switch external PHY type */
5447         } else {
5448                 /* serdes */
5449                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5450                 ext_phy_addr = (params->ext_phy_config  &
5451                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
5452                 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
5453         }
5454 }
5455
5456
5457 /*
5458  *------------------------------------------------------------------------
5459  * bnx2x_override_led_value -
5460  *
5461  * Override the led value of the requsted led
5462  *
5463  *------------------------------------------------------------------------
5464  */
5465 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
5466                           u32 led_idx, u32 value)
5467 {
5468         u32 reg_val;
5469
5470         /* If port 0 then use EMAC0, else use EMAC1*/
5471         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5472
5473         DP(NETIF_MSG_LINK,
5474                  "bnx2x_override_led_value() port %x led_idx %d value %d\n",
5475                  port, led_idx, value);
5476
5477         switch (led_idx) {
5478         case 0: /* 10MB led */
5479                 /* Read the current value of the LED register in
5480                 the EMAC block */
5481                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5482                 /* Set the OVERRIDE bit to 1 */
5483                 reg_val |= EMAC_LED_OVERRIDE;
5484                 /* If value is 1, set the 10M_OVERRIDE bit,
5485                 otherwise reset it.*/
5486                 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
5487                         (reg_val & ~EMAC_LED_10MB_OVERRIDE);
5488                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5489                 break;
5490         case 1: /*100MB led    */
5491                 /*Read the current value of the LED register in
5492                 the EMAC block */
5493                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5494                 /*  Set the OVERRIDE bit to 1 */
5495                 reg_val |= EMAC_LED_OVERRIDE;
5496                 /*  If value is 1, set the 100M_OVERRIDE bit,
5497                 otherwise reset it.*/
5498                 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
5499                         (reg_val & ~EMAC_LED_100MB_OVERRIDE);
5500                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5501                 break;
5502         case 2: /* 1000MB led */
5503                 /* Read the current value of the LED register in the
5504                 EMAC block */
5505                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5506                 /* Set the OVERRIDE bit to 1 */
5507                 reg_val |= EMAC_LED_OVERRIDE;
5508                 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
5509                 reset it. */
5510                 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
5511                         (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
5512                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5513                 break;
5514         case 3: /* 2500MB led */
5515                 /*  Read the current value of the LED register in the
5516                 EMAC block*/
5517                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5518                 /* Set the OVERRIDE bit to 1 */
5519                 reg_val |= EMAC_LED_OVERRIDE;
5520                 /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
5521                 reset it.*/
5522                 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
5523                         (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
5524                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5525                 break;
5526         case 4: /*10G led */
5527                 if (port == 0) {
5528                         REG_WR(bp, NIG_REG_LED_10G_P0,
5529                                     value);
5530                 } else {
5531                         REG_WR(bp, NIG_REG_LED_10G_P1,
5532                                     value);
5533                 }
5534                 break;
5535         case 5: /* TRAFFIC led */
5536                 /* Find if the traffic control is via BMAC or EMAC */
5537                 if (port == 0)
5538                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
5539                 else
5540                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
5541
5542                 /*  Override the traffic led in the EMAC:*/
5543                 if (reg_val == 1) {
5544                         /* Read the current value of the LED register in
5545                         the EMAC block */
5546                         reg_val = REG_RD(bp, emac_base +
5547                                              EMAC_REG_EMAC_LED);
5548                         /* Set the TRAFFIC_OVERRIDE bit to 1 */
5549                         reg_val |= EMAC_LED_OVERRIDE;
5550                         /* If value is 1, set the TRAFFIC bit, otherwise
5551                         reset it.*/
5552                         reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
5553                                 (reg_val & ~EMAC_LED_TRAFFIC);
5554                         REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5555                 } else { /* Override the traffic led in the BMAC: */
5556                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5557                                    + port*4, 1);
5558                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
5559                                     value);
5560                 }
5561                 break;
5562         default:
5563                 DP(NETIF_MSG_LINK,
5564                          "bnx2x_override_led_value() unknown led index %d "
5565                          "(should be 0-5)\n", led_idx);
5566                 return -EINVAL;
5567         }
5568
5569         return 0;
5570 }
5571
5572
5573 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
5574                u16 hw_led_mode, u32 chip_id)
5575 {
5576         u8 rc = 0;
5577         u32 tmp;
5578         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5579         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5580         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5581                  speed, hw_led_mode);
5582         switch (mode) {
5583         case LED_MODE_OFF:
5584                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
5585                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5586                            SHARED_HW_CFG_LED_MAC1);
5587
5588                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5589                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
5590                 break;
5591
5592         case LED_MODE_OPER:
5593                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
5594                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
5595                            port*4, 0);
5596                 /* Set blinking rate to ~15.9Hz */
5597                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
5598                            LED_BLINK_RATE_VAL);
5599                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
5600                            port*4, 1);
5601                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5602                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
5603                             (tmp & (~EMAC_LED_OVERRIDE)));
5604
5605                 if (!CHIP_IS_E1H(bp) &&
5606                     ((speed == SPEED_2500) ||
5607                      (speed == SPEED_1000) ||
5608                      (speed == SPEED_100) ||
5609                      (speed == SPEED_10))) {
5610                         /* On Everest 1 Ax chip versions for speeds less than
5611                         10G LED scheme is different */
5612                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5613                                    + port*4, 1);
5614                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
5615                                    port*4, 0);
5616                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
5617                                    port*4, 1);
5618                 }
5619                 break;
5620
5621         default:
5622                 rc = -EINVAL;
5623                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
5624                          mode);
5625                 break;
5626         }
5627         return rc;
5628
5629 }
5630
5631 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
5632 {
5633         struct bnx2x *bp = params->bp;
5634         u16 gp_status = 0;
5635
5636         CL45_RD_OVER_CL22(bp, params->port,
5637                               params->phy_addr,
5638                               MDIO_REG_BANK_GP_STATUS,
5639                               MDIO_GP_STATUS_TOP_AN_STATUS1,
5640                               &gp_status);
5641         /* link is up only if both local phy and external phy are up */
5642         if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
5643             bnx2x_ext_phy_is_link_up(params, vars, 1))
5644                 return 0;
5645
5646         return -ESRCH;
5647 }
5648
5649 static u8 bnx2x_link_initialize(struct link_params *params,
5650                               struct link_vars *vars)
5651 {
5652         struct bnx2x *bp = params->bp;
5653         u8 port = params->port;
5654         u8 rc = 0;
5655         u8 non_ext_phy;
5656         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5657         /* Activate the external PHY */
5658         bnx2x_ext_phy_reset(params, vars);
5659
5660         bnx2x_set_aer_mmd(params, vars);
5661
5662         if (vars->phy_flags & PHY_XGXS_FLAG)
5663                 bnx2x_set_master_ln(params);
5664
5665         rc = bnx2x_reset_unicore(params);
5666         /* reset the SerDes and wait for reset bit return low */
5667         if (rc != 0)
5668                 return rc;
5669
5670         bnx2x_set_aer_mmd(params, vars);
5671
5672         /* setting the masterLn_def again after the reset */
5673         if (vars->phy_flags & PHY_XGXS_FLAG) {
5674                 bnx2x_set_master_ln(params);
5675                 bnx2x_set_swap_lanes(params);
5676         }
5677
5678         if (vars->phy_flags & PHY_XGXS_FLAG) {
5679                 if ((params->req_line_speed &&
5680                     ((params->req_line_speed == SPEED_100) ||
5681                      (params->req_line_speed == SPEED_10))) ||
5682                     (!params->req_line_speed &&
5683                      (params->speed_cap_mask >=
5684                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5685                      (params->speed_cap_mask <
5686                        PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5687                      ))  {
5688                         vars->phy_flags |= PHY_SGMII_FLAG;
5689                 } else {
5690                         vars->phy_flags &= ~PHY_SGMII_FLAG;
5691                 }
5692         }
5693         /* In case of external phy existance, the line speed would be the
5694          line speed linked up by the external phy. In case it is direct only,
5695           then the line_speed during initialization will be equal to the
5696            req_line_speed*/
5697         vars->line_speed = params->req_line_speed;
5698
5699         bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
5700
5701         /* init ext phy and enable link state int */
5702         non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
5703                        (params->loopback_mode == LOOPBACK_XGXS_10));
5704
5705         if (non_ext_phy ||
5706             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
5707             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
5708             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
5709             (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5710                 if (params->req_line_speed == SPEED_AUTO_NEG)
5711                         bnx2x_set_parallel_detection(params, vars->phy_flags);
5712                 bnx2x_init_internal_phy(params, vars);
5713         }
5714
5715         if (!non_ext_phy)
5716                 rc |= bnx2x_ext_phy_init(params, vars);
5717
5718         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5719                      (NIG_STATUS_XGXS0_LINK10G |
5720                       NIG_STATUS_XGXS0_LINK_STATUS |
5721                       NIG_STATUS_SERDES0_LINK_STATUS));
5722
5723         return rc;
5724
5725 }
5726
5727
5728 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
5729 {
5730         struct bnx2x *bp = params->bp;
5731
5732         u32 val;
5733         DP(NETIF_MSG_LINK, "Phy Initialization started \n");
5734         DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
5735                   params->req_line_speed, params->req_flow_ctrl);
5736         vars->link_status = 0;
5737         vars->phy_link_up = 0;
5738         vars->link_up = 0;
5739         vars->line_speed = 0;
5740         vars->duplex = DUPLEX_FULL;
5741         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5742         vars->mac_type = MAC_TYPE_NONE;
5743
5744         if (params->switch_cfg ==  SWITCH_CFG_1G)
5745                 vars->phy_flags = PHY_SERDES_FLAG;
5746         else
5747                 vars->phy_flags = PHY_XGXS_FLAG;
5748
5749
5750         /* disable attentions */
5751         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
5752                        (NIG_MASK_XGXS0_LINK_STATUS |
5753                         NIG_MASK_XGXS0_LINK10G |
5754                         NIG_MASK_SERDES0_LINK_STATUS |
5755                         NIG_MASK_MI_INT));
5756
5757         bnx2x_emac_init(params, vars);
5758
5759         if (CHIP_REV_IS_FPGA(bp)) {
5760                 vars->link_up = 1;
5761                 vars->line_speed = SPEED_10000;
5762                 vars->duplex = DUPLEX_FULL;
5763                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5764                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5765                 /* enable on E1.5 FPGA */
5766                 if (CHIP_IS_E1H(bp)) {
5767                         vars->flow_ctrl |=
5768                                 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
5769                         vars->link_status |=
5770                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
5771                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
5772                 }
5773
5774                 bnx2x_emac_enable(params, vars, 0);
5775                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5776                 /* disable drain */
5777                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
5778                                     + params->port*4, 0);
5779
5780                 /* update shared memory */
5781                 bnx2x_update_mng(params, vars->link_status);
5782
5783                 return 0;
5784
5785         } else
5786         if (CHIP_REV_IS_EMUL(bp)) {
5787
5788                 vars->link_up = 1;
5789                 vars->line_speed = SPEED_10000;
5790                 vars->duplex = DUPLEX_FULL;
5791                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5792                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5793
5794                 bnx2x_bmac_enable(params, vars, 0);
5795
5796                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5797                 /* Disable drain */
5798                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
5799                                     + params->port*4, 0);
5800
5801                 /* update shared memory */
5802                 bnx2x_update_mng(params, vars->link_status);
5803
5804                 return 0;
5805
5806         } else
5807         if (params->loopback_mode == LOOPBACK_BMAC) {
5808                 vars->link_up = 1;
5809                 vars->line_speed = SPEED_10000;
5810                 vars->duplex = DUPLEX_FULL;
5811                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5812                 vars->mac_type = MAC_TYPE_BMAC;
5813
5814                 vars->phy_flags = PHY_XGXS_FLAG;
5815
5816                 bnx2x_phy_deassert(params, vars->phy_flags);
5817                 /* set bmac loopback */
5818                 bnx2x_bmac_enable(params, vars, 1);
5819
5820                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5821                     params->port*4, 0);
5822         } else if (params->loopback_mode == LOOPBACK_EMAC) {
5823                 vars->link_up = 1;
5824                 vars->line_speed = SPEED_1000;
5825                 vars->duplex = DUPLEX_FULL;
5826                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5827                 vars->mac_type = MAC_TYPE_EMAC;
5828
5829                 vars->phy_flags = PHY_XGXS_FLAG;
5830
5831                 bnx2x_phy_deassert(params, vars->phy_flags);
5832                 /* set bmac loopback */
5833                 bnx2x_emac_enable(params, vars, 1);
5834                 bnx2x_emac_program(params, vars->line_speed,
5835                                               vars->duplex);
5836                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5837                     params->port*4, 0);
5838         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
5839                   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5840                 vars->link_up = 1;
5841                 vars->line_speed = SPEED_10000;
5842                 vars->duplex = DUPLEX_FULL;
5843                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5844
5845                 vars->phy_flags = PHY_XGXS_FLAG;
5846
5847                 val = REG_RD(bp,
5848                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
5849                                  params->port*0x18);
5850                 params->phy_addr = (u8)val;
5851
5852                 bnx2x_phy_deassert(params, vars->phy_flags);
5853                 bnx2x_link_initialize(params, vars);
5854
5855                 vars->mac_type = MAC_TYPE_BMAC;
5856
5857                 bnx2x_bmac_enable(params, vars, 0);
5858
5859                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
5860                         /* set 10G XGXS loopback */
5861                         bnx2x_set_xgxs_loopback(params, vars, 1);
5862                 } else {
5863                         /* set external phy loopback */
5864                         bnx2x_ext_phy_loopback(params);
5865                 }
5866                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5867                             params->port*4, 0);
5868
5869                 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
5870                             vars->line_speed, params->hw_led_mode,
5871                             params->chip_id);
5872
5873         } else
5874         /* No loopback */
5875         {
5876
5877                 bnx2x_phy_deassert(params, vars->phy_flags);
5878                 switch (params->switch_cfg) {
5879                 case SWITCH_CFG_1G:
5880                         vars->phy_flags |= PHY_SERDES_FLAG;
5881                         if ((params->ext_phy_config &
5882                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
5883                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
5884                                 vars->phy_flags |=
5885                                         PHY_SGMII_FLAG;
5886                         }
5887
5888                         val = REG_RD(bp,
5889                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
5890                                          params->port*0x10);
5891
5892                         params->phy_addr = (u8)val;
5893
5894                         break;
5895                 case SWITCH_CFG_10G:
5896                         vars->phy_flags |= PHY_XGXS_FLAG;
5897                         val = REG_RD(bp,
5898                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
5899                                  params->port*0x18);
5900                         params->phy_addr = (u8)val;
5901
5902                         break;
5903                 default:
5904                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
5905                         return -EINVAL;
5906                         break;
5907                 }
5908                 DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
5909
5910                 bnx2x_link_initialize(params, vars);
5911                 msleep(30);
5912                 bnx2x_link_int_enable(params);
5913         }
5914         return 0;
5915 }
5916
5917 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
5918 {
5919         DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
5920
5921         /* Set serial boot control for external load */
5922         bnx2x_cl45_write(bp, port,
5923                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
5924                        MDIO_PMA_DEVAD,
5925                        MDIO_PMA_REG_GEN_CTRL, 0x0001);
5926 }
5927
5928 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
5929                   u8 reset_ext_phy)
5930 {
5931
5932         struct bnx2x *bp = params->bp;
5933         u32 ext_phy_config = params->ext_phy_config;
5934         u16 hw_led_mode = params->hw_led_mode;
5935         u32 chip_id = params->chip_id;
5936         u8 port = params->port;
5937         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
5938         u32 val = REG_RD(bp, params->shmem_base +
5939                              offsetof(struct shmem_region, dev_info.
5940                                       port_feature_config[params->port].
5941                                       config));
5942
5943         /* disable attentions */
5944
5945         vars->link_status = 0;
5946         bnx2x_update_mng(params, vars->link_status);
5947         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5948                      (NIG_MASK_XGXS0_LINK_STATUS |
5949                       NIG_MASK_XGXS0_LINK10G |
5950                       NIG_MASK_SERDES0_LINK_STATUS |
5951                       NIG_MASK_MI_INT));
5952
5953         /* activate nig drain */
5954         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
5955
5956         /* disable nig egress interface */
5957         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
5958         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
5959
5960         /* Stop BigMac rx */
5961         bnx2x_bmac_rx_disable(bp, port);
5962
5963         /* disable emac */
5964         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5965
5966         msleep(10);
5967         /* The PHY reset is controled by GPIO 1
5968          * Hold it as vars low
5969          */
5970          /* clear link led */
5971         bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
5972         if (reset_ext_phy) {
5973                 switch (ext_phy_type) {
5974                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5975                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5976                         break;
5977
5978                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
5979                 {
5980
5981                         /* Disable Transmitter */
5982                         u8 ext_phy_addr = ((params->ext_phy_config &
5983                                     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5984                                    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5985                         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
5986                             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5987                                 bnx2x_sfp_set_transmitter(bp, port,
5988                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
5989                                         ext_phy_addr, 0);
5990                         break;
5991                 }
5992                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5993                         DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
5994                                  "low power mode\n",
5995                                  port);
5996                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5997                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
5998                                           port);
5999                         break;
6000                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6001                 {
6002                         u8 ext_phy_addr = ((params->ext_phy_config &
6003                                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
6004                                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
6005                         /* Set soft reset */
6006                         bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
6007                         break;
6008                 }
6009                 default:
6010                         /* HW reset */
6011                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6012                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6013                                           port);
6014                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6015                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6016                                           port);
6017                         DP(NETIF_MSG_LINK, "reset external PHY\n");
6018                 }
6019         }
6020         /* reset the SerDes/XGXS */
6021         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6022                (0x1ff << (port*16)));
6023
6024         /* reset BigMac */
6025         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
6026                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6027
6028         /* disable nig ingress interface */
6029         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
6030         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
6031         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6032         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6033         vars->link_up = 0;
6034         return 0;
6035 }
6036
6037 static u8 bnx2x_update_link_down(struct link_params *params,
6038                                struct link_vars *vars)
6039 {
6040         struct bnx2x *bp = params->bp;
6041         u8 port = params->port;
6042         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
6043         bnx2x_set_led(bp, port, LED_MODE_OFF,
6044                     0, params->hw_led_mode,
6045                     params->chip_id);
6046
6047         /* indicate no mac active */
6048         vars->mac_type = MAC_TYPE_NONE;
6049
6050         /* update shared memory */
6051         vars->link_status = 0;
6052         vars->line_speed = 0;
6053         bnx2x_update_mng(params, vars->link_status);
6054
6055         /* activate nig drain */
6056         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6057
6058         /* disable emac */
6059         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6060
6061         msleep(10);
6062
6063         /* reset BigMac */
6064         bnx2x_bmac_rx_disable(bp, params->port);
6065         REG_WR(bp, GRCBASE_MISC +
6066                    MISC_REGISTERS_RESET_REG_2_CLEAR,
6067                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6068         return 0;
6069 }
6070
6071 static u8 bnx2x_update_link_up(struct link_params *params,
6072                              struct link_vars *vars,
6073                              u8 link_10g, u32 gp_status)
6074 {
6075         struct bnx2x *bp = params->bp;
6076         u8 port = params->port;
6077         u8 rc = 0;
6078         vars->link_status |= LINK_STATUS_LINK_UP;
6079         if (link_10g) {
6080                 bnx2x_bmac_enable(params, vars, 0);
6081                 bnx2x_set_led(bp, port, LED_MODE_OPER,
6082                             SPEED_10000, params->hw_led_mode,
6083                             params->chip_id);
6084
6085         } else {
6086                 bnx2x_emac_enable(params, vars, 0);
6087                 rc = bnx2x_emac_program(params, vars->line_speed,
6088                                       vars->duplex);
6089
6090                 /* AN complete? */
6091                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
6092                         if (!(vars->phy_flags &
6093                               PHY_SGMII_FLAG))
6094                                 bnx2x_set_gmii_tx_driver(params);
6095                 }
6096         }
6097
6098         /* PBF - link up */
6099         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6100                               vars->line_speed);
6101
6102         /* disable drain */
6103         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6104
6105         /* update shared memory */
6106         bnx2x_update_mng(params, vars->link_status);
6107         msleep(20);
6108         return rc;
6109 }
6110 /* This function should called upon link interrupt */
6111 /* In case vars->link_up, driver needs to
6112         1. Update the pbf
6113         2. Disable drain
6114         3. Update the shared memory
6115         4. Indicate link up
6116         5. Set LEDs
6117    Otherwise,
6118         1. Update shared memory
6119         2. Reset BigMac
6120         3. Report link down
6121         4. Unset LEDs
6122 */
6123 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6124 {
6125         struct bnx2x *bp = params->bp;
6126         u8 port = params->port;
6127         u16 gp_status;
6128         u8 link_10g;
6129         u8 ext_phy_link_up, rc = 0;
6130         u32 ext_phy_type;
6131         u8 is_mi_int = 0;
6132
6133         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6134                  port, (vars->phy_flags & PHY_XGXS_FLAG),
6135                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6136
6137         is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6138                                     port*0x18) > 0);
6139         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6140                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6141                  is_mi_int,
6142                  REG_RD(bp,
6143                             NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6144
6145         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6146           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6147           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6148
6149         /* disable emac */
6150         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6151
6152         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
6153
6154         /* Check external link change only for non-direct */
6155         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int);
6156
6157         /* Read gp_status */
6158         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
6159                               MDIO_REG_BANK_GP_STATUS,
6160                               MDIO_GP_STATUS_TOP_AN_STATUS1,
6161                               &gp_status);
6162
6163         rc = bnx2x_link_settings_status(params, vars, gp_status,
6164                                       ext_phy_link_up);
6165         if (rc != 0)
6166                 return rc;
6167
6168         /* anything 10 and over uses the bmac */
6169         link_10g = ((vars->line_speed == SPEED_10000) ||
6170                     (vars->line_speed == SPEED_12000) ||
6171                     (vars->line_speed == SPEED_12500) ||
6172                     (vars->line_speed == SPEED_13000) ||
6173                     (vars->line_speed == SPEED_15000) ||
6174                     (vars->line_speed == SPEED_16000));
6175
6176         bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
6177
6178         /* In case external phy link is up, and internal link is down
6179         ( not initialized yet probably after link initialization, it needs
6180         to be initialized.
6181         Note that after link down-up as result of cable plug,
6182         the xgxs link would probably become up again without the need to
6183         initialize it*/
6184
6185         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
6186             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
6187             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
6188             (ext_phy_link_up && !vars->phy_link_up))
6189                 bnx2x_init_internal_phy(params, vars);
6190
6191         /* link is up only if both local phy and external phy are up */
6192         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
6193
6194         if (vars->link_up)
6195                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
6196         else
6197                 rc = bnx2x_update_link_down(params, vars);
6198
6199         return rc;
6200 }
6201
6202 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6203 {
6204         u8 ext_phy_addr[PORT_MAX];
6205         u16 val;
6206         s8 port;
6207
6208         /* PART1 - Reset both phys */
6209         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6210                 /* Extract the ext phy address for the port */
6211                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6212                                         offsetof(struct shmem_region,
6213                    dev_info.port_hw_config[port].external_phy_config));
6214
6215                 /* disable attentions */
6216                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6217                              (NIG_MASK_XGXS0_LINK_STATUS |
6218                               NIG_MASK_XGXS0_LINK10G |
6219                               NIG_MASK_SERDES0_LINK_STATUS |
6220                               NIG_MASK_MI_INT));
6221
6222                 ext_phy_addr[port] =
6223                         ((ext_phy_config &
6224                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
6225                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
6226
6227                 /* Need to take the phy out of low power mode in order
6228                         to write to access its registers */
6229                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6230                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6231
6232                 /* Reset the phy */
6233                 bnx2x_cl45_write(bp, port,
6234                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6235                                ext_phy_addr[port],
6236                                MDIO_PMA_DEVAD,
6237                                MDIO_PMA_REG_CTRL,
6238                                1<<15);
6239         }
6240
6241         /* Add delay of 150ms after reset */
6242         msleep(150);
6243
6244         /* PART2 - Download firmware to both phys */
6245         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6246                 u16 fw_ver1;
6247
6248                 bnx2x_bcm8073_external_rom_boot(bp, port,
6249                                               ext_phy_addr[port], shmem_base);
6250
6251                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6252                               ext_phy_addr[port],
6253                               MDIO_PMA_DEVAD,
6254                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6255                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6256                         DP(NETIF_MSG_LINK,
6257                                  "bnx2x_8073_common_init_phy port %x:"
6258                                  "Download failed. fw version = 0x%x\n",
6259                                  port, fw_ver1);
6260                         return -EINVAL;
6261                 }
6262
6263                 /* Only set bit 10 = 1 (Tx power down) */
6264                 bnx2x_cl45_read(bp, port,
6265                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6266                               ext_phy_addr[port],
6267                               MDIO_PMA_DEVAD,
6268                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
6269
6270                 /* Phase1 of TX_POWER_DOWN reset */
6271                 bnx2x_cl45_write(bp, port,
6272                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6273                                ext_phy_addr[port],
6274                                MDIO_PMA_DEVAD,
6275                                MDIO_PMA_REG_TX_POWER_DOWN,
6276                                (val | 1<<10));
6277         }
6278
6279         /* Toggle Transmitter: Power down and then up with 600ms
6280            delay between */
6281         msleep(600);
6282
6283         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
6284         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6285                 /* Phase2 of POWER_DOWN_RESET */
6286                 /* Release bit 10 (Release Tx power down) */
6287                 bnx2x_cl45_read(bp, port,
6288                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6289                               ext_phy_addr[port],
6290                               MDIO_PMA_DEVAD,
6291                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
6292
6293                 bnx2x_cl45_write(bp, port,
6294                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6295                                ext_phy_addr[port],
6296                                MDIO_PMA_DEVAD,
6297                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
6298                 msleep(15);
6299
6300                 /* Read modify write the SPI-ROM version select register */
6301                 bnx2x_cl45_read(bp, port,
6302                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6303                               ext_phy_addr[port],
6304                               MDIO_PMA_DEVAD,
6305                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
6306                 bnx2x_cl45_write(bp, port,
6307                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6308                               ext_phy_addr[port],
6309                               MDIO_PMA_DEVAD,
6310                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
6311
6312                 /* set GPIO2 back to LOW */
6313                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6314                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6315         }
6316         return 0;
6317
6318 }
6319
6320 static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6321 {
6322         u8 ext_phy_addr[PORT_MAX];
6323         s8 port;
6324         u32 swap_val, swap_override;
6325         DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
6326         swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
6327         swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
6328
6329         bnx2x_hw_reset(bp, 1 ^ (swap_val && swap_override));
6330         msleep(5);
6331
6332         /* PART1 - Reset both phys */
6333         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6334                 /* Extract the ext phy address for the port */
6335                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6336                                         offsetof(struct shmem_region,
6337                    dev_info.port_hw_config[port].external_phy_config));
6338
6339                 /* disable attentions */
6340                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6341                              (NIG_MASK_XGXS0_LINK_STATUS |
6342                               NIG_MASK_XGXS0_LINK10G |
6343                               NIG_MASK_SERDES0_LINK_STATUS |
6344                               NIG_MASK_MI_INT));
6345
6346                 ext_phy_addr[port] = ((ext_phy_config &
6347                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
6348                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
6349
6350                 /* Reset the phy */
6351                 bnx2x_cl45_write(bp, port,
6352                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6353                                ext_phy_addr[port],
6354                                MDIO_PMA_DEVAD,
6355                                MDIO_PMA_REG_CTRL,
6356                                1<<15);
6357         }
6358
6359         /* Add delay of 150ms after reset */
6360         msleep(150);
6361
6362         /* PART2 - Download firmware to both phys */
6363         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6364                 u16 fw_ver1;
6365
6366                 bnx2x_bcm8727_external_rom_boot(bp, port,
6367                                               ext_phy_addr[port], shmem_base);
6368
6369                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6370                               ext_phy_addr[port],
6371                               MDIO_PMA_DEVAD,
6372                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6373                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6374                         DP(NETIF_MSG_LINK,
6375                                  "bnx2x_8073_common_init_phy port %x:"
6376                                  "Download failed. fw version = 0x%x\n",
6377                                  port, fw_ver1);
6378                         return -EINVAL;
6379                 }
6380
6381         }
6382
6383
6384
6385         return 0;
6386 }
6387
6388
6389 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6390 {
6391         u8 ext_phy_addr;
6392         u32 val;
6393         s8 port;
6394         /* Use port1 because of the static port-swap */
6395         /* Enable the module detection interrupt */
6396         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
6397         val |= ((1<<MISC_REGISTERS_GPIO_3)|
6398                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
6399         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
6400
6401         bnx2x_hw_reset(bp, 1);
6402         msleep(5);
6403         for (port = 0; port < PORT_MAX; port++) {
6404                 /* Extract the ext phy address for the port */
6405                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6406                                         offsetof(struct shmem_region,
6407                         dev_info.port_hw_config[port].external_phy_config));
6408
6409                 ext_phy_addr =
6410                         ((ext_phy_config &
6411                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
6412                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
6413                 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
6414                          ext_phy_addr);
6415
6416                 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
6417
6418                 /* Set fault module detected LED on */
6419                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6420                                   MISC_REGISTERS_GPIO_HIGH,
6421                                   port);
6422         }
6423
6424         return 0;
6425 }
6426
6427 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6428 {
6429         u8 rc = 0;
6430         u32 ext_phy_type;
6431
6432         DP(NETIF_MSG_LINK, "Begin common phy init\n");
6433
6434         /* Read the ext_phy_type for arbitrary port(0) */
6435         ext_phy_type = XGXS_EXT_PHY_TYPE(
6436                         REG_RD(bp, shmem_base +
6437                            offsetof(struct shmem_region,
6438                              dev_info.port_hw_config[0].external_phy_config)));
6439
6440         switch (ext_phy_type) {
6441         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6442         {
6443                 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
6444                 break;
6445         }
6446
6447         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6448         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6449                 rc = bnx2x_8727_common_init_phy(bp, shmem_base);
6450                 break;
6451
6452         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6453                 /* GPIO1 affects both ports, so there's need to pull
6454                 it for single port alone */
6455                 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
6456
6457                 break;
6458         default:
6459                 DP(NETIF_MSG_LINK,
6460                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
6461                          ext_phy_type);
6462                 break;
6463         }
6464
6465         return rc;
6466 }
6467
6468
6469
6470 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
6471 {
6472         u16 val, cnt;
6473
6474         bnx2x_cl45_read(bp, port,
6475                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6476                       phy_addr,
6477                       MDIO_PMA_DEVAD,
6478                       MDIO_PMA_REG_7101_RESET, &val);
6479
6480         for (cnt = 0; cnt < 10; cnt++) {
6481                 msleep(50);
6482                 /* Writes a self-clearing reset */
6483                 bnx2x_cl45_write(bp, port,
6484                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6485                                phy_addr,
6486                                MDIO_PMA_DEVAD,
6487                                MDIO_PMA_REG_7101_RESET,
6488                                (val | (1<<15)));
6489                 /* Wait for clear */
6490                 bnx2x_cl45_read(bp, port,
6491                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6492                               phy_addr,
6493                               MDIO_PMA_DEVAD,
6494                               MDIO_PMA_REG_7101_RESET, &val);
6495
6496                 if ((val & (1<<15)) == 0)
6497                         break;
6498         }
6499 }
6500 #define RESERVED_SIZE 256
6501 /* max application is 160K bytes - data at end of RAM */
6502 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
6503
6504 /* Header is 14 bytes */
6505 #define HEADER_SIZE 14
6506 #define DATA_OFFSET HEADER_SIZE
6507
6508 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
6509         bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
6510                         ext_phy_addr, \
6511                         MDIO_PCS_DEVAD, \
6512                         MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
6513
6514 /* Programs an image to DSP's flash via the SPI port*/
6515 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
6516                                      u8 ext_phy_addr,
6517                                      char data[], u32 size)
6518 {
6519         const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
6520         /* Doesn't include last trans!*/
6521         const u16 last_trans_size = size%4; /* Num bytes on last trans */
6522         u16 trans_cnt, byte_cnt;
6523         u32 data_index;
6524         u16 tmp;
6525         u16 code_started = 0;
6526         u16 image_revision1, image_revision2;
6527         u16 cnt;
6528
6529         DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
6530         /* Going to flash*/
6531         if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
6532                 /* This very often will be the case, because the image is built
6533                 with 160Kbytes size whereas the total image size must actually
6534                 be 160Kbytes-RESERVED_SIZE */
6535                 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
6536                          "truncated to %d bytes\n", size, MAX_APP_SIZE);
6537                 size = MAX_APP_SIZE+HEADER_SIZE;
6538         }
6539         DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
6540         DP(NETIF_MSG_LINK, "          %c%c\n", data[0x150], data[0x151]);
6541         /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
6542            and issuing a reset.*/
6543
6544         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6545                           MISC_REGISTERS_GPIO_HIGH, port);
6546
6547         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
6548
6549         /* wait 0.5 sec */
6550         for (cnt = 0; cnt < 100; cnt++)
6551                 msleep(5);
6552
6553         /* Make sure we can access the DSP
6554            And it's in the correct mode (waiting for download) */
6555
6556         bnx2x_cl45_read(bp, port,
6557                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6558                       ext_phy_addr,
6559                       MDIO_PCS_DEVAD,
6560                       MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
6561
6562         if (tmp != 0x000A) {
6563                 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
6564                          "Expected 0x000A, read 0x%04X\n", tmp);
6565                 DP(NETIF_MSG_LINK, "Download failed\n");
6566                 return -EINVAL;
6567         }
6568
6569         /* Mux the SPI interface away from the internal processor */
6570         bnx2x_cl45_write(bp, port,
6571                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6572                        ext_phy_addr,
6573                        MDIO_PCS_DEVAD,
6574                        MDIO_PCS_REG_7101_SPI_MUX, 1);
6575
6576         /* Reset the SPI port */
6577         bnx2x_cl45_write(bp, port,
6578                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6579                        ext_phy_addr,
6580                        MDIO_PCS_DEVAD,
6581                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
6582         bnx2x_cl45_write(bp, port,
6583                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6584                        ext_phy_addr,
6585                        MDIO_PCS_DEVAD,
6586                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
6587                        (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
6588         bnx2x_cl45_write(bp, port,
6589                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6590                        ext_phy_addr,
6591                        MDIO_PCS_DEVAD,
6592                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
6593
6594         /* Erase the flash */
6595         bnx2x_cl45_write(bp, port,
6596                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6597                        ext_phy_addr,
6598                        MDIO_PCS_DEVAD,
6599                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6600                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
6601
6602         bnx2x_cl45_write(bp, port,
6603                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6604                        ext_phy_addr,
6605                        MDIO_PCS_DEVAD,
6606                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6607                        1);
6608
6609         SPI_START_TRANSFER(bp, port, ext_phy_addr);
6610         bnx2x_cl45_write(bp, port,
6611                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6612                        ext_phy_addr,
6613                        MDIO_PCS_DEVAD,
6614                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6615                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
6616
6617         bnx2x_cl45_write(bp, port,
6618                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6619                        ext_phy_addr,
6620                        MDIO_PCS_DEVAD,
6621                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6622                        1);
6623         SPI_START_TRANSFER(bp, port, ext_phy_addr);
6624
6625         /* Wait 10 seconds, the maximum time for the erase to complete */
6626         DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
6627         for (cnt = 0; cnt < 1000; cnt++)
6628                 msleep(10);
6629
6630         DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
6631         data_index = 0;
6632         for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
6633                 bnx2x_cl45_write(bp, port,
6634                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6635                              ext_phy_addr,
6636                              MDIO_PCS_DEVAD,
6637                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6638                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
6639
6640                 bnx2x_cl45_write(bp, port,
6641                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6642                                ext_phy_addr,
6643                                MDIO_PCS_DEVAD,
6644                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6645                                1);
6646                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
6647
6648                 bnx2x_cl45_write(bp, port,
6649                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6650                                ext_phy_addr,
6651                                MDIO_PCS_DEVAD,
6652                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6653                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
6654
6655                 /* Bits 23-16 of address */
6656                 bnx2x_cl45_write(bp, port,
6657                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6658                                ext_phy_addr,
6659                                MDIO_PCS_DEVAD,
6660                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6661                                (data_index>>16));
6662                 /* Bits 15-8 of address */
6663                 bnx2x_cl45_write(bp, port,
6664                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6665                                ext_phy_addr,
6666                                MDIO_PCS_DEVAD,
6667                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6668                                (data_index>>8));
6669
6670                 /* Bits 7-0 of address */
6671                 bnx2x_cl45_write(bp, port,
6672                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6673                                ext_phy_addr,
6674                                MDIO_PCS_DEVAD,
6675                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6676                                ((u16)data_index));
6677
6678                 byte_cnt = 0;
6679                 while (byte_cnt < 4 && data_index < size) {
6680                         bnx2x_cl45_write(bp, port,
6681                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6682                                        ext_phy_addr,
6683                                MDIO_PCS_DEVAD,
6684                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6685                                data[data_index++]);
6686                         byte_cnt++;
6687                 }
6688
6689                 bnx2x_cl45_write(bp, port,
6690                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6691                                ext_phy_addr,
6692                                MDIO_PCS_DEVAD,
6693                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6694                                byte_cnt+4);
6695
6696                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
6697                 msleep(5); /* Wait 5 ms minimum between transs */
6698
6699                 /* Let the user know something's going on.*/
6700                 /* a pacifier ever 4K */
6701                 if ((data_index % 1023) == 0)
6702                         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
6703         }
6704
6705         DP(NETIF_MSG_LINK, "\n");
6706         /* Transfer the last block if there is data remaining */
6707         if (last_trans_size) {
6708                 bnx2x_cl45_write(bp, port,
6709                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6710                         ext_phy_addr,
6711                         MDIO_PCS_DEVAD,
6712                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6713                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
6714
6715                 bnx2x_cl45_write(bp, port,
6716                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6717                                ext_phy_addr,
6718                                MDIO_PCS_DEVAD,
6719                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6720                                1);
6721
6722                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
6723
6724                 bnx2x_cl45_write(bp, port,
6725                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6726                              ext_phy_addr,
6727                              MDIO_PCS_DEVAD,
6728                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6729                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
6730
6731                 /* Bits 23-16 of address */
6732                 bnx2x_cl45_write(bp, port,
6733                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6734                                ext_phy_addr,
6735                                MDIO_PCS_DEVAD,
6736                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6737                                (data_index>>16));
6738                 /* Bits 15-8 of address */
6739                 bnx2x_cl45_write(bp, port,
6740                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6741                                ext_phy_addr,
6742                                MDIO_PCS_DEVAD,
6743                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6744                                (data_index>>8));
6745
6746                 /* Bits 7-0 of address */
6747                 bnx2x_cl45_write(bp, port,
6748                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6749                                ext_phy_addr,
6750                                MDIO_PCS_DEVAD,
6751                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6752                                ((u16)data_index));
6753
6754                 byte_cnt = 0;
6755                 while (byte_cnt < last_trans_size && data_index < size) {
6756                         /* Bits 7-0 of address */
6757                         bnx2x_cl45_write(bp, port,
6758                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6759                                 ext_phy_addr,
6760                                 MDIO_PCS_DEVAD,
6761                                 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
6762                                 data[data_index++]);
6763                         byte_cnt++;
6764                 }
6765
6766                 bnx2x_cl45_write(bp, port,
6767                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6768                                ext_phy_addr,
6769                                MDIO_PCS_DEVAD,
6770                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
6771                                byte_cnt+4);
6772
6773                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
6774         }
6775
6776         /* DSP Remove Download Mode */
6777         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6778                           MISC_REGISTERS_GPIO_LOW, port);
6779
6780         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
6781
6782         /* wait 0.5 sec to allow it to run */
6783         for (cnt = 0; cnt < 100; cnt++)
6784                 msleep(5);
6785
6786         bnx2x_hw_reset(bp, port);
6787
6788         for (cnt = 0; cnt < 100; cnt++)
6789                 msleep(5);
6790
6791         /* Check that the code is started. In case the download
6792         checksum failed, the code won't be started. */
6793         bnx2x_cl45_read(bp, port,
6794                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6795                       ext_phy_addr,
6796                       MDIO_PCS_DEVAD,
6797                       MDIO_PCS_REG_7101_DSP_ACCESS,
6798                       &tmp);
6799
6800         code_started = (tmp & (1<<4));
6801         if (!code_started) {
6802                 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
6803                 return -EINVAL;
6804         }
6805
6806         /* Verify that the file revision is now equal to the image
6807         revision within the DSP */
6808         bnx2x_cl45_read(bp, port,
6809                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6810                       ext_phy_addr,
6811                       MDIO_PMA_DEVAD,
6812                       MDIO_PMA_REG_7101_VER1,
6813                       &image_revision1);
6814
6815         bnx2x_cl45_read(bp, port,
6816                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6817                       ext_phy_addr,
6818                       MDIO_PMA_DEVAD,
6819                       MDIO_PMA_REG_7101_VER2,
6820                       &image_revision2);
6821
6822         if (data[0x14e] != (image_revision2&0xFF) ||
6823             data[0x14f] != ((image_revision2&0xFF00)>>8) ||
6824             data[0x150] != (image_revision1&0xFF) ||
6825             data[0x151] != ((image_revision1&0xFF00)>>8)) {
6826                 DP(NETIF_MSG_LINK, "Download failed.\n");
6827                 return -EINVAL;
6828         }
6829         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
6830         return 0;
6831 }
6832
6833 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
6834                       u8 driver_loaded, char data[], u32 size)
6835 {
6836         u8 rc = 0;
6837         u32 ext_phy_type;
6838         u8 ext_phy_addr;
6839         ext_phy_addr = ((ext_phy_config &
6840                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
6841                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
6842
6843         ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6844
6845         switch (ext_phy_type) {
6846         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
6847         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6848         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
6849         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
6850                 DP(NETIF_MSG_LINK,
6851                         "Flash download not supported for this ext phy\n");
6852                 rc = -EINVAL;
6853                 break;
6854         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
6855                 /* Take ext phy out of reset */
6856                 if (!driver_loaded)
6857                         bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
6858                 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
6859                                                 data, size);
6860                 if (!driver_loaded)
6861                         bnx2x_turn_off_sf(bp, port);
6862                 break;
6863         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
6864         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
6865         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
6866         default:
6867                 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
6868                 rc = -EINVAL;
6869                 break;
6870         }
6871         return rc;
6872 }
6873