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