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