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