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