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