]> err.no Git - linux-2.6/blob - drivers/net/bnx2x_link.c
3b63c8ce952ab5141cce185c611b4d4147610aa1
[linux-2.6] / drivers / net / bnx2x_link.c
1 /* Copyright 2008 Broadcom Corporation
2  *
3  * Unless you and Broadcom execute a separate written software license
4  * agreement governing use of this software, this software is licensed to you
5  * under the terms of the GNU General Public License version 2, available
6  * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7  *
8  * Notwithstanding the above, under no circumstances may you combine this
9  * software in any way with any other Broadcom software provided under a
10  * license other than the GPL, without Broadcom's express prior written
11  * consent.
12  *
13  * Written by Yaniv Rosner
14  *
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24 #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                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1695                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1696                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1697                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
1698                         vars->autoneg = AUTO_NEG_ENABLED;
1699
1700                         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1701                                 vars->autoneg |= AUTO_NEG_COMPLETE;
1702                                 vars->link_status |=
1703                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1704                         }
1705
1706                         vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1707                         vars->link_status |=
1708                                 LINK_STATUS_PARALLEL_DETECTION_USED;
1709
1710                 }
1711                 if (vars->flow_ctrl & FLOW_CTRL_TX)
1712                        vars->link_status |=
1713                         LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1714
1715                 if (vars->flow_ctrl & FLOW_CTRL_RX)
1716                        vars->link_status |=
1717                         LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1718
1719         } else { /* link_down */
1720                 DP(NETIF_MSG_LINK, "phy link down\n");
1721
1722                 vars->phy_link_up = 0;
1723
1724                 vars->duplex = DUPLEX_FULL;
1725                 vars->flow_ctrl = FLOW_CTRL_NONE;
1726                 vars->autoneg = AUTO_NEG_DISABLED;
1727                 vars->mac_type = MAC_TYPE_NONE;
1728         }
1729
1730         DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
1731                  gp_status, vars->phy_link_up, vars->line_speed);
1732         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
1733                  " autoneg 0x%x\n",
1734                  vars->duplex,
1735                  vars->flow_ctrl, vars->autoneg);
1736         DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1737
1738         return rc;
1739 }
1740
1741 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1742 {
1743         struct bnx2x *bp = params->bp;
1744         u16 lp_up2;
1745         u16 tx_driver;
1746
1747         /* read precomp */
1748
1749         CL45_RD_OVER_CL22(bp, params->port,
1750                               params->phy_addr,
1751                               MDIO_REG_BANK_OVER_1G,
1752                               MDIO_OVER_1G_LP_UP2, &lp_up2);
1753
1754         CL45_RD_OVER_CL22(bp, params->port,
1755                               params->phy_addr,
1756                               MDIO_REG_BANK_TX0,
1757                               MDIO_TX0_TX_DRIVER, &tx_driver);
1758
1759         /* bits [10:7] at lp_up2, positioned at [15:12] */
1760         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1761                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1762                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1763
1764         if ((lp_up2 != 0) &&
1765             (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1766                 /* replace tx_driver bits [15:12] */
1767                 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1768                 tx_driver |= lp_up2;
1769                 CL45_WR_OVER_CL22(bp, params->port,
1770                                       params->phy_addr,
1771                                       MDIO_REG_BANK_TX0,
1772                                       MDIO_TX0_TX_DRIVER, tx_driver);
1773         }
1774 }
1775
1776 static u8 bnx2x_emac_program(struct link_params *params,
1777                            u32 line_speed, u32 duplex)
1778 {
1779         struct bnx2x *bp = params->bp;
1780         u8 port = params->port;
1781         u16 mode = 0;
1782
1783         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1784         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1785                      EMAC_REG_EMAC_MODE,
1786                      (EMAC_MODE_25G_MODE |
1787                      EMAC_MODE_PORT_MII_10M |
1788                      EMAC_MODE_HALF_DUPLEX));
1789         switch (line_speed) {
1790         case SPEED_10:
1791                 mode |= EMAC_MODE_PORT_MII_10M;
1792                 break;
1793
1794         case SPEED_100:
1795                 mode |= EMAC_MODE_PORT_MII;
1796                 break;
1797
1798         case SPEED_1000:
1799                 mode |= EMAC_MODE_PORT_GMII;
1800                 break;
1801
1802         case SPEED_2500:
1803                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1804                 break;
1805
1806         default:
1807                 /* 10G not valid for EMAC */
1808                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1809                 return -EINVAL;
1810         }
1811
1812         if (duplex == DUPLEX_HALF)
1813                 mode |= EMAC_MODE_HALF_DUPLEX;
1814         bnx2x_bits_en(bp,
1815                     GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1816                     mode);
1817
1818         bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1819                     line_speed, params->hw_led_mode, params->chip_id);
1820         return 0;
1821 }
1822
1823 /*****************************************************************************/
1824 /*                           External Phy section                            */
1825 /*****************************************************************************/
1826 static void bnx2x_hw_reset(struct bnx2x *bp)
1827 {
1828         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1829                        MISC_REGISTERS_GPIO_OUTPUT_LOW);
1830         msleep(1);
1831         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1832                       MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1833 }
1834
1835 static void bnx2x_ext_phy_reset(struct link_params *params,
1836                               struct link_vars   *vars)
1837 {
1838         struct bnx2x *bp = params->bp;
1839         u32 ext_phy_type;
1840         u8 ext_phy_addr = ((params->ext_phy_config &
1841                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1842                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1843         DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1844         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1845         /* The PHY reset is controled by GPIO 1
1846          * Give it 1ms of reset pulse
1847          */
1848         if (vars->phy_flags & PHY_XGXS_FLAG) {
1849
1850                 switch (ext_phy_type) {
1851                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1852                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
1853                         break;
1854
1855                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1856                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1857                         DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1858
1859                         /* Restore normal power mode*/
1860                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1861                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1862
1863                         /* HW reset */
1864                         bnx2x_hw_reset(bp);
1865
1866                         bnx2x_cl45_write(bp, params->port,
1867                                        ext_phy_type,
1868                                        ext_phy_addr,
1869                                        MDIO_PMA_DEVAD,
1870                                        MDIO_PMA_REG_CTRL, 0xa040);
1871                         break;
1872                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1873                         /* Unset Low Power Mode and SW reset */
1874                         /* Restore normal power mode*/
1875                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1876                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1877
1878                         DP(NETIF_MSG_LINK, "XGXS 8072\n");
1879                         bnx2x_cl45_write(bp, params->port,
1880                                        ext_phy_type,
1881                                        ext_phy_addr,
1882                                        MDIO_PMA_DEVAD,
1883                                        MDIO_PMA_REG_CTRL,
1884                                        1<<15);
1885                         break;
1886                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1887                         {
1888                         u16 emac_base;
1889                         emac_base = (params->port) ? GRCBASE_EMAC0 :
1890                                         GRCBASE_EMAC1;
1891
1892                         /* Restore normal power mode*/
1893                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1894                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1895
1896                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1897                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1898
1899                         DP(NETIF_MSG_LINK, "XGXS 8073\n");
1900                         bnx2x_cl45_write(bp,
1901                                        params->port,
1902                                        ext_phy_type,
1903                                        ext_phy_addr,
1904                                        MDIO_PMA_DEVAD,
1905                                        MDIO_PMA_REG_CTRL,
1906                                        1<<15);
1907                         }
1908                         break;
1909
1910                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1911                         DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1912
1913                         /* Restore normal power mode*/
1914                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1915                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH);
1916
1917                         /* HW reset */
1918                         bnx2x_hw_reset(bp);
1919
1920                         break;
1921
1922                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1923                         DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1924                         break;
1925
1926                 default:
1927                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1928                            params->ext_phy_config);
1929                         break;
1930                 }
1931
1932         } else { /* SerDes */
1933                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1934                 switch (ext_phy_type) {
1935                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1936                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
1937                         break;
1938
1939                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1940                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
1941                         bnx2x_hw_reset(bp);
1942                         break;
1943
1944                 default:
1945                         DP(NETIF_MSG_LINK,
1946                                  "BAD SerDes ext_phy_config 0x%x\n",
1947                                  params->ext_phy_config);
1948                         break;
1949                 }
1950         }
1951 }
1952
1953 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
1954 {
1955         struct bnx2x *bp = params->bp;
1956         u8 port = params->port;
1957         u8 ext_phy_addr = ((params->ext_phy_config &
1958                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1959                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1960         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1961         u16 fw_ver1, fw_ver2;
1962
1963         /* Need to wait 200ms after reset */
1964         msleep(200);
1965         /* Boot port from external ROM
1966          * Set ser_boot_ctl bit in the MISC_CTRL1 register
1967          */
1968         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1969                             MDIO_PMA_DEVAD,
1970                             MDIO_PMA_REG_MISC_CTRL1, 0x0001);
1971
1972         /* Reset internal microprocessor */
1973         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1974                           MDIO_PMA_DEVAD,
1975                           MDIO_PMA_REG_GEN_CTRL,
1976                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
1977         /* set micro reset = 0 */
1978         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1979                             MDIO_PMA_DEVAD,
1980                             MDIO_PMA_REG_GEN_CTRL,
1981                             MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
1982         /* Reset internal microprocessor */
1983         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1984                           MDIO_PMA_DEVAD,
1985                           MDIO_PMA_REG_GEN_CTRL,
1986                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
1987         /* wait for 100ms for code download via SPI port */
1988         msleep(100);
1989
1990         /* Clear ser_boot_ctl bit */
1991         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1992                             MDIO_PMA_DEVAD,
1993                             MDIO_PMA_REG_MISC_CTRL1, 0x0000);
1994         /* Wait 100ms */
1995         msleep(100);
1996
1997         /* Print the PHY FW version */
1998         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
1999                             MDIO_PMA_DEVAD,
2000                             MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2001         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2002                             MDIO_PMA_DEVAD,
2003                             MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2004         DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2005 }
2006
2007 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2008 {
2009         /* This is only required for 8073A1, version 102 only */
2010
2011         struct bnx2x *bp = params->bp;
2012         u8 ext_phy_addr = ((params->ext_phy_config &
2013                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2014                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2015         u16 val;
2016
2017         /* Read 8073 HW revision*/
2018         bnx2x_cl45_read(bp, params->port,
2019                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2020                       ext_phy_addr,
2021                       MDIO_PMA_DEVAD,
2022                       0xc801, &val);
2023
2024         if (val != 1) {
2025                 /* No need to workaround in 8073 A1 */
2026                 return 0;
2027         }
2028
2029         bnx2x_cl45_read(bp, params->port,
2030                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2031                       ext_phy_addr,
2032                       MDIO_PMA_DEVAD,
2033                       MDIO_PMA_REG_ROM_VER2, &val);
2034
2035         /* SNR should be applied only for version 0x102 */
2036         if (val != 0x102)
2037                 return 0;
2038
2039         return 1;
2040 }
2041
2042 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2043 {
2044         struct bnx2x *bp = params->bp;
2045         u8 ext_phy_addr = ((params->ext_phy_config &
2046                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2047                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2048         u16 val, cnt, cnt1 ;
2049
2050         bnx2x_cl45_read(bp, params->port,
2051                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2052                       ext_phy_addr,
2053                       MDIO_PMA_DEVAD,
2054                       0xc801, &val);
2055
2056         if (val > 0) {
2057                 /* No need to workaround in 8073 A1 */
2058                 return 0;
2059         }
2060         /* XAUI workaround in 8073 A0: */
2061
2062         /* After loading the boot ROM and restarting Autoneg,
2063         poll Dev1, Reg $C820: */
2064
2065         for (cnt = 0; cnt < 1000; cnt++) {
2066                 bnx2x_cl45_read(bp, params->port,
2067                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2068                               ext_phy_addr,
2069                               MDIO_PMA_DEVAD,
2070                               0xc820, &val);
2071                   /* If bit [14] = 0 or bit [13] = 0, continue on with
2072                    system initialization (XAUI work-around not required,
2073                     as these bits indicate 2.5G or 1G link up). */
2074                 if (!(val & (1<<14)) || !(val & (1<<13))) {
2075                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2076                         return 0;
2077                 } else if (!(val & (1<<15))) {
2078                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2079                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2080                           it's MSB (bit 15) goes to 1 (indicating that the
2081                           XAUI workaround has completed),
2082                           then continue on with system initialization.*/
2083                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2084                                 bnx2x_cl45_read(bp, params->port,
2085                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2086                                         ext_phy_addr,
2087                                         MDIO_PMA_DEVAD,
2088                                         0xc841, &val);
2089                                 if (val & (1<<15)) {
2090                                         DP(NETIF_MSG_LINK,
2091                                           "XAUI workaround has completed\n");
2092                                         return 0;
2093                                  }
2094                                  msleep(3);
2095                         }
2096                         break;
2097                 }
2098                 msleep(3);
2099         }
2100         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2101         return -EINVAL;
2102
2103 }
2104
2105 static void bnx2x_bcm8073_external_rom_boot(struct link_params *params)
2106 {
2107         struct bnx2x *bp = params->bp;
2108         u8 port = params->port;
2109         u8 ext_phy_addr = ((params->ext_phy_config &
2110                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2111                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2112         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2113         u16 fw_ver1, fw_ver2, val;
2114         /* Need to wait 100ms after reset */
2115         msleep(100);
2116         /* Boot port from external ROM  */
2117         /* EDC grst */
2118         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2119                        MDIO_PMA_DEVAD,
2120                        MDIO_PMA_REG_GEN_CTRL,
2121                        0x0001);
2122
2123         /* ucode reboot and rst */
2124         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2125                        MDIO_PMA_DEVAD,
2126                        MDIO_PMA_REG_GEN_CTRL,
2127                        0x008c);
2128
2129         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2130                        MDIO_PMA_DEVAD,
2131                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2132
2133         /* Reset internal microprocessor */
2134         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2135                        MDIO_PMA_DEVAD,
2136                        MDIO_PMA_REG_GEN_CTRL,
2137                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2138
2139         /* Release srst bit */
2140         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2141                        MDIO_PMA_DEVAD,
2142                        MDIO_PMA_REG_GEN_CTRL,
2143                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2144
2145         /* wait for 100ms for code download via SPI port */
2146         msleep(100);
2147
2148         /* Clear ser_boot_ctl bit */
2149         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2150                        MDIO_PMA_DEVAD,
2151                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2152
2153         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2154                        MDIO_PMA_DEVAD,
2155                        MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2156         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2157                        MDIO_PMA_DEVAD,
2158                        MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2159         DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2160
2161         /* Only set bit 10 = 1 (Tx power down) */
2162         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2163                        MDIO_PMA_DEVAD,
2164                        MDIO_PMA_REG_TX_POWER_DOWN, &val);
2165
2166         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2167                        MDIO_PMA_DEVAD,
2168                        MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10));
2169
2170         msleep(600);
2171         /* Release bit 10 (Release Tx power down) */
2172         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2173                        MDIO_PMA_DEVAD,
2174                        MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
2175
2176 }
2177
2178 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2179 {
2180         struct bnx2x *bp = params->bp;
2181         u8 port = params->port;
2182         u16 val;
2183         u8 ext_phy_addr = ((params->ext_phy_config &
2184                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2185                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2186         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2187
2188         bnx2x_cl45_read(bp, params->port,
2189                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2190                       ext_phy_addr,
2191                       MDIO_PMA_DEVAD,
2192                       0xc801, &val);
2193
2194         if (val == 0) {
2195                 /* Mustn't set low power mode in 8073 A0 */
2196                 return;
2197         }
2198
2199         /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2200         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2201                        MDIO_XS_DEVAD,
2202                        MDIO_XS_PLL_SEQUENCER, &val);
2203         val &= ~(1<<13);
2204         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2205                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2206
2207         /* PLL controls */
2208         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2209                        MDIO_XS_DEVAD, 0x805E, 0x1077);
2210         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2211                        MDIO_XS_DEVAD, 0x805D, 0x0000);
2212         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2213                        MDIO_XS_DEVAD, 0x805C, 0x030B);
2214         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2215                        MDIO_XS_DEVAD, 0x805B, 0x1240);
2216         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2217                        MDIO_XS_DEVAD, 0x805A, 0x2490);
2218
2219         /* Tx Controls */
2220         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2221                        MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2222         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2223                        MDIO_XS_DEVAD, 0x80A6, 0x9041);
2224         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2225                        MDIO_XS_DEVAD, 0x80A5, 0x4640);
2226
2227         /* Rx Controls */
2228         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2229                        MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2230         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2231                        MDIO_XS_DEVAD, 0x80FD, 0x9249);
2232         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2233                        MDIO_XS_DEVAD, 0x80FC, 0x2015);
2234
2235         /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
2236         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2237                        MDIO_XS_DEVAD,
2238                        MDIO_XS_PLL_SEQUENCER, &val);
2239         val |= (1<<13);
2240         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2241                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2242 }
2243 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2244 {
2245         struct bnx2x *bp = params->bp;
2246         u8 port = params->port;
2247         u8 ext_phy_addr = ((params->ext_phy_config &
2248                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2249                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2250         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2251
2252         /* Force KR or KX */
2253         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2254                        MDIO_PMA_DEVAD,
2255                        MDIO_PMA_REG_CTRL,
2256                        0x2040);
2257         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2258                        MDIO_PMA_DEVAD,
2259                        MDIO_PMA_REG_10G_CTRL2,
2260                        0x000b);
2261         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2262                        MDIO_PMA_DEVAD,
2263                        MDIO_PMA_REG_BCM_CTRL,
2264                        0x0000);
2265         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2266                        MDIO_AN_DEVAD,
2267                        MDIO_AN_REG_CTRL,
2268                        0x0000);
2269 }
2270
2271 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2272                                   struct link_vars *vars)
2273 {
2274         struct bnx2x *bp = params->bp;
2275         u16 val;
2276         u8 ext_phy_addr = ((params->ext_phy_config &
2277                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2278                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2279         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2280
2281         /* read modify write pause advertizing */
2282         bnx2x_cl45_read(bp, params->port,
2283                       ext_phy_type,
2284                       ext_phy_addr,
2285                       MDIO_AN_DEVAD,
2286                       MDIO_AN_REG_ADV_PAUSE, &val);
2287
2288         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2289         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2290
2291         if (vars->ieee_fc &
2292             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2293                 val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2294         }
2295         if (vars->ieee_fc &
2296             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2297                 val |=
2298                  MDIO_AN_REG_ADV_PAUSE_PAUSE;
2299         }
2300         DP(NETIF_MSG_LINK,
2301                  "Ext phy AN advertize 0x%x\n", val);
2302         bnx2x_cl45_write(bp, params->port,
2303                        ext_phy_type,
2304                        ext_phy_addr,
2305                        MDIO_AN_DEVAD,
2306                        MDIO_AN_REG_ADV_PAUSE, val);
2307 }
2308
2309
2310 static void bnx2x_init_internal_phy(struct link_params *params,
2311                                 struct link_vars *vars)
2312 {
2313         struct bnx2x *bp = params->bp;
2314         u8 port = params->port;
2315         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2316                 u16 bank, rx_eq;
2317
2318                 rx_eq = ((params->serdes_config &
2319                           PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2320                          PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2321
2322                 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2323                 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2324                       bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2325                         CL45_WR_OVER_CL22(bp, port,
2326                                               params->phy_addr,
2327                                               bank ,
2328                                               MDIO_RX0_RX_EQ_BOOST,
2329                                               ((rx_eq &
2330                                 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2331                                 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2332                 }
2333
2334                 /* forced speed requested? */
2335                 if (vars->line_speed != SPEED_AUTO_NEG) {
2336                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2337
2338                         /* disable autoneg */
2339                         bnx2x_set_autoneg(params, vars);
2340
2341                         /* program speed and duplex */
2342                         bnx2x_program_serdes(params);
2343
2344                 } else { /* AN_mode */
2345                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2346
2347                         /* AN enabled */
2348                         bnx2x_set_brcm_cl37_advertisment(params);
2349
2350                         /* program duplex & pause advertisement (for aneg) */
2351                         bnx2x_set_ieee_aneg_advertisment(params,
2352                                                        &vars->ieee_fc);
2353
2354                         /* enable autoneg */
2355                         bnx2x_set_autoneg(params, vars);
2356
2357                         /* enable and restart AN */
2358                         bnx2x_restart_autoneg(params);
2359                 }
2360
2361         } else { /* SGMII mode */
2362                 DP(NETIF_MSG_LINK, "SGMII\n");
2363
2364                 bnx2x_initialize_sgmii_process(params);
2365         }
2366 }
2367
2368 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2369 {
2370         struct bnx2x *bp = params->bp;
2371         u32 ext_phy_type;
2372         u8 ext_phy_addr;
2373         u16 cnt;
2374         u16 ctrl = 0;
2375         u16 val = 0;
2376         u8 rc = 0;
2377         if (vars->phy_flags & PHY_XGXS_FLAG) {
2378                 ext_phy_addr = ((params->ext_phy_config &
2379                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2380                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2381
2382                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2383                 /* Make sure that the soft reset is off (expect for the 8072:
2384                  * due to the lock, it will be done inside the specific
2385                  * handling)
2386                  */
2387                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2388                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2389                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2390                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2391                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2392                         /* Wait for soft reset to get cleared upto 1 sec */
2393                         for (cnt = 0; cnt < 1000; cnt++) {
2394                                 bnx2x_cl45_read(bp, params->port,
2395                                               ext_phy_type,
2396                                               ext_phy_addr,
2397                                               MDIO_PMA_DEVAD,
2398                                               MDIO_PMA_REG_CTRL, &ctrl);
2399                                 if (!(ctrl & (1<<15)))
2400                                         break;
2401                                 msleep(1);
2402                         }
2403                         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2404                                  ctrl, cnt);
2405                 }
2406
2407                 switch (ext_phy_type) {
2408                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2409                         break;
2410
2411                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2412                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
2413
2414                         bnx2x_cl45_write(bp, params->port,
2415                                        ext_phy_type,
2416                                        ext_phy_addr,
2417                                        MDIO_PMA_DEVAD,
2418                                        MDIO_PMA_REG_MISC_CTRL,
2419                                        0x8288);
2420                         bnx2x_cl45_write(bp, params->port,
2421                                        ext_phy_type,
2422                                        ext_phy_addr,
2423                                        MDIO_PMA_DEVAD,
2424                                        MDIO_PMA_REG_PHY_IDENTIFIER,
2425                                        0x7fbf);
2426                         bnx2x_cl45_write(bp, params->port,
2427                                        ext_phy_type,
2428                                        ext_phy_addr,
2429                                        MDIO_PMA_DEVAD,
2430                                        MDIO_PMA_REG_CMU_PLL_BYPASS,
2431                                        0x0100);
2432                         bnx2x_cl45_write(bp, params->port,
2433                                        ext_phy_type,
2434                                        ext_phy_addr,
2435                                        MDIO_WIS_DEVAD,
2436                                        MDIO_WIS_REG_LASI_CNTL, 0x1);
2437                         break;
2438
2439                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2440                         DP(NETIF_MSG_LINK, "XGXS 8706\n");
2441
2442                         msleep(10);
2443                         /* Force speed */
2444                         /* First enable LASI */
2445                         bnx2x_cl45_write(bp, params->port,
2446                                        ext_phy_type,
2447                                        ext_phy_addr,
2448                                        MDIO_PMA_DEVAD,
2449                                        MDIO_PMA_REG_RX_ALARM_CTRL,
2450                                        0x0400);
2451                         bnx2x_cl45_write(bp, params->port,
2452                                        ext_phy_type,
2453                                        ext_phy_addr,
2454                                        MDIO_PMA_DEVAD,
2455                                        MDIO_PMA_REG_LASI_CTRL, 0x0004);
2456
2457                         if (params->req_line_speed == SPEED_10000) {
2458                                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
2459
2460                                 bnx2x_cl45_write(bp, params->port,
2461                                                ext_phy_type,
2462                                                ext_phy_addr,
2463                                                MDIO_PMA_DEVAD,
2464                                                MDIO_PMA_REG_DIGITAL_CTRL,
2465                                                0x400);
2466                         } else {
2467                                 /* Force 1Gbps using autoneg with 1G
2468                                 advertisment */
2469
2470                                 /* Allow CL37 through CL73 */
2471                                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
2472                                 bnx2x_cl45_write(bp, params->port,
2473                                                ext_phy_type,
2474                                                ext_phy_addr,
2475                                                MDIO_AN_DEVAD,
2476                                                MDIO_AN_REG_CL37_CL73,
2477                                                0x040c);
2478
2479                                 /* Enable Full-Duplex advertisment on CL37 */
2480                                 bnx2x_cl45_write(bp, params->port,
2481                                                ext_phy_type,
2482                                                ext_phy_addr,
2483                                                MDIO_AN_DEVAD,
2484                                                MDIO_AN_REG_CL37_FD,
2485                                                0x0020);
2486                                 /* Enable CL37 AN */
2487                                 bnx2x_cl45_write(bp, params->port,
2488                                                ext_phy_type,
2489                                                ext_phy_addr,
2490                                                MDIO_AN_DEVAD,
2491                                                MDIO_AN_REG_CL37_AN,
2492                                                0x1000);
2493                                 /* 1G support */
2494                                 bnx2x_cl45_write(bp, params->port,
2495                                                ext_phy_type,
2496                                                ext_phy_addr,
2497                                                MDIO_AN_DEVAD,
2498                                                MDIO_AN_REG_ADV, (1<<5));
2499
2500                                 /* Enable clause 73 AN */
2501                                 bnx2x_cl45_write(bp, params->port,
2502                                                ext_phy_type,
2503                                                ext_phy_addr,
2504                                                MDIO_AN_DEVAD,
2505                                                MDIO_AN_REG_CTRL,
2506                                                0x1200);
2507
2508                         }
2509
2510                         break;
2511
2512                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2513                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2514                 {
2515                         u16 tmp1;
2516                         u16 rx_alarm_ctrl_val;
2517                         u16 lasi_ctrl_val;
2518                         if (ext_phy_type ==
2519                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2520                                 rx_alarm_ctrl_val = 0x400;
2521                                 lasi_ctrl_val = 0x0004;
2522                         } else {
2523                                 /* In 8073, port1 is directed through emac0 and
2524                                  * port0 is directed through emac1
2525                                  */
2526                                 rx_alarm_ctrl_val = (1<<2);
2527                                 /*lasi_ctrl_val = 0x0005;*/
2528                                 lasi_ctrl_val = 0x0004;
2529                         }
2530
2531                         /* Wait for soft reset to get cleared upto 1 sec */
2532                         for (cnt = 0; cnt < 1000; cnt++) {
2533                                 bnx2x_cl45_read(bp, params->port,
2534                                               ext_phy_type,
2535                                               ext_phy_addr,
2536                                               MDIO_PMA_DEVAD,
2537                                               MDIO_PMA_REG_CTRL,
2538                                               &ctrl);
2539                                 if (!(ctrl & (1<<15)))
2540                                         break;
2541                                 msleep(1);
2542                         }
2543                         DP(NETIF_MSG_LINK,
2544                                 "807x control reg 0x%x (after %d ms)\n",
2545                                 ctrl, cnt);
2546
2547                         if (ext_phy_type ==
2548                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
2549                                 bnx2x_bcm8072_external_rom_boot(params);
2550                         } else {
2551                                 bnx2x_bcm8073_external_rom_boot(params);
2552                                 /* In case of 8073 with long xaui lines,
2553                                 don't set the 8073 xaui low power*/
2554                                 bnx2x_bcm8073_set_xaui_low_power_mode(params);
2555                         }
2556
2557                         /* enable LASI */
2558                         bnx2x_cl45_write(bp, params->port,
2559                                        ext_phy_type,
2560                                        ext_phy_addr,
2561                                        MDIO_PMA_DEVAD,
2562                                        MDIO_PMA_REG_RX_ALARM_CTRL,
2563                                        rx_alarm_ctrl_val);
2564
2565                         bnx2x_cl45_write(bp, params->port,
2566                                        ext_phy_type,
2567                                        ext_phy_addr,
2568                                        MDIO_PMA_DEVAD,
2569                                        MDIO_PMA_REG_LASI_CTRL,
2570                                        lasi_ctrl_val);
2571
2572                         bnx2x_cl45_read(bp, params->port,
2573                                       ext_phy_type,
2574                                       ext_phy_addr,
2575                                       MDIO_PMA_DEVAD,
2576                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
2577
2578                         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
2579                                              "0x%x\n", tmp1);
2580
2581                         /* If this is forced speed, set to KR or KX
2582                          * (all other are not supported)
2583                          */
2584                         if (!(params->req_line_speed == SPEED_AUTO_NEG)) {
2585                         if (params->req_line_speed == SPEED_10000) {
2586                                         bnx2x_bcm807x_force_10G(params);
2587                                         DP(NETIF_MSG_LINK,
2588                                            "Forced speed 10G on 807X\n");
2589                                         break;
2590                                 } else if (params->req_line_speed ==
2591                                            SPEED_2500) {
2592                                         val = (1<<5);
2593                                         /* Note that 2.5G works only
2594                                         when used with 1G advertisment */
2595                                 } else
2596                                         val = (1<<5);
2597                         } else {
2598
2599                                 val = 0;
2600                                 if (params->speed_cap_mask &
2601                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2602                                         val |= (1<<7);
2603
2604                                 if (params->speed_cap_mask &
2605                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2606                                         val |= (1<<5);
2607                                 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
2608                                 /*val = ((1<<5)|(1<<7));*/
2609                         }
2610
2611                         bnx2x_cl45_write(bp, params->port,
2612                                        ext_phy_type,
2613                                        ext_phy_addr,
2614                                        MDIO_AN_DEVAD,
2615                                        MDIO_AN_REG_ADV, val);
2616
2617                         if (ext_phy_type ==
2618                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2619                                 /* Disable 2.5Ghz */
2620                                 bnx2x_cl45_read(bp, params->port,
2621                                               ext_phy_type,
2622                                               ext_phy_addr,
2623                                               MDIO_AN_DEVAD,
2624                                               0x8329, &tmp1);
2625 /* SUPPORT_SPEED_CAPABILITY
2626                                 (Due to the nature of the link order, its not
2627                                 possible to enable 2.5G within the autoneg
2628                                 capabilities)
2629                                 if (params->speed_cap_mask &
2630                                 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
2631 */
2632                                 if (params->req_line_speed == SPEED_2500) {
2633                                         u16 phy_ver;
2634                                         /* Allow 2.5G for A1 and above */
2635                                         bnx2x_cl45_read(bp, params->port,
2636                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2637                                          ext_phy_addr,
2638                                          MDIO_PMA_DEVAD,
2639                                          0xc801, &phy_ver);
2640
2641                                         if (phy_ver > 0)
2642                                                 tmp1 |= 1;
2643                                         else
2644                                                 tmp1 &= 0xfffe;
2645                         }
2646                                 else
2647                                         tmp1 &= 0xfffe;
2648
2649                         bnx2x_cl45_write(bp, params->port,
2650                                        ext_phy_type,
2651                                        ext_phy_addr,
2652                                        MDIO_AN_DEVAD,
2653                                                0x8329, tmp1);
2654                         }
2655                         /* Add support for CL37 (passive mode) I */
2656                         bnx2x_cl45_write(bp, params->port,
2657                                        ext_phy_type,
2658                                        ext_phy_addr,
2659                                        MDIO_AN_DEVAD,
2660                                        MDIO_AN_REG_CL37_CL73, 0x040c);
2661                         /* Add support for CL37 (passive mode) II */
2662                         bnx2x_cl45_write(bp, params->port,
2663                                        ext_phy_type,
2664                                        ext_phy_addr,
2665                                        MDIO_AN_DEVAD,
2666                                        MDIO_AN_REG_CL37_FD, 0x20);
2667                         /* Add support for CL37 (passive mode) III */
2668                         bnx2x_cl45_write(bp, params->port,
2669                                        ext_phy_type,
2670                                        ext_phy_addr,
2671                                        MDIO_AN_DEVAD,
2672                                        MDIO_AN_REG_CL37_AN, 0x1000);
2673                         /* Restart autoneg */
2674                         msleep(500);
2675
2676                         if (ext_phy_type ==
2677                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2678
2679                         /* The SNR will improve about 2db by changing the
2680                                 BW and FEE main tap. Rest commands are executed
2681                                 after link is up*/
2682                         /* Change FFE main cursor to 5 in EDC register */
2683                                 if (bnx2x_8073_is_snr_needed(params))
2684                                         bnx2x_cl45_write(bp, params->port,
2685                                                     ext_phy_type,
2686                                                     ext_phy_addr,
2687                                                     MDIO_PMA_DEVAD,
2688                                                     MDIO_PMA_REG_EDC_FFE_MAIN,
2689                                                     0xFB0C);
2690
2691                         /* Enable FEC (Forware Error Correction)
2692                            Request in the AN */
2693                         bnx2x_cl45_read(bp, params->port,
2694                                       ext_phy_type,
2695                                       ext_phy_addr,
2696                                       MDIO_AN_DEVAD,
2697                                       MDIO_AN_REG_ADV2, &tmp1);
2698
2699                         tmp1 |= (1<<15);
2700
2701                         bnx2x_cl45_write(bp, params->port,
2702                                       ext_phy_type,
2703                                       ext_phy_addr,
2704                                       MDIO_AN_DEVAD,
2705                                       MDIO_AN_REG_ADV2, tmp1);
2706                         }
2707
2708                         bnx2x_ext_phy_set_pause(params, vars);
2709
2710                         bnx2x_cl45_write(bp, params->port,
2711                                        ext_phy_type,
2712                                        ext_phy_addr,
2713                                        MDIO_AN_DEVAD,
2714                                        MDIO_AN_REG_CTRL, 0x1200);
2715                         DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
2716                            "Advertise 1G=%x, 10G=%x\n",
2717                            ((val & (1<<5)) > 0),
2718                            ((val & (1<<7)) > 0));
2719                         break;
2720                 }
2721                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2722                         DP(NETIF_MSG_LINK,
2723                                 "Setting the SFX7101 LASI indication\n");
2724
2725                         bnx2x_cl45_write(bp, params->port,
2726                                        ext_phy_type,
2727                                        ext_phy_addr,
2728                                        MDIO_PMA_DEVAD,
2729                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
2730                         DP(NETIF_MSG_LINK,
2731                           "Setting the SFX7101 LED to blink on traffic\n");
2732                         bnx2x_cl45_write(bp, params->port,
2733                                        ext_phy_type,
2734                                        ext_phy_addr,
2735                                        MDIO_PMA_DEVAD,
2736                                        MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
2737
2738                         bnx2x_ext_phy_set_pause(params, vars);
2739                         /* Restart autoneg */
2740                         bnx2x_cl45_read(bp, params->port,
2741                                       ext_phy_type,
2742                                       ext_phy_addr,
2743                                       MDIO_AN_DEVAD,
2744                                       MDIO_AN_REG_CTRL, &val);
2745                         val |= 0x200;
2746                         bnx2x_cl45_write(bp, params->port,
2747                                        ext_phy_type,
2748                                        ext_phy_addr,
2749                                        MDIO_AN_DEVAD,
2750                                        MDIO_AN_REG_CTRL, val);
2751                         break;
2752                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2753                         DP(NETIF_MSG_LINK,
2754                                  "XGXS PHY Failure detected 0x%x\n",
2755                                  params->ext_phy_config);
2756                         rc = -EINVAL;
2757                         break;
2758                 default:
2759                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2760                                   params->ext_phy_config);
2761                         rc = -EINVAL;
2762                         break;
2763                 }
2764
2765         } else { /* SerDes */
2766
2767                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2768                 switch (ext_phy_type) {
2769                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2770                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
2771                         break;
2772
2773                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2774                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
2775                         break;
2776
2777                 default:
2778                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2779                            params->ext_phy_config);
2780                         break;
2781                 }
2782         }
2783         return rc;
2784 }
2785
2786
2787 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2788                                   struct link_vars *vars)
2789 {
2790         struct bnx2x *bp = params->bp;
2791         u32 ext_phy_type;
2792         u8 ext_phy_addr;
2793         u16 val1 = 0, val2;
2794         u16 rx_sd, pcs_status;
2795         u8 ext_phy_link_up = 0;
2796         u8 port = params->port;
2797         if (vars->phy_flags & PHY_XGXS_FLAG) {
2798                 ext_phy_addr = ((params->ext_phy_config &
2799                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2800                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2801
2802                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2803                 switch (ext_phy_type) {
2804                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2805                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
2806                         ext_phy_link_up = 1;
2807                         break;
2808
2809                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2810                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
2811                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2812                                       ext_phy_addr,
2813                                       MDIO_WIS_DEVAD,
2814                                       MDIO_WIS_REG_LASI_STATUS, &val1);
2815                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2816
2817                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2818                                       ext_phy_addr,
2819                                       MDIO_WIS_DEVAD,
2820                                       MDIO_WIS_REG_LASI_STATUS, &val1);
2821                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2822
2823                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2824                                       ext_phy_addr,
2825                                       MDIO_PMA_DEVAD,
2826                                       MDIO_PMA_REG_RX_SD, &rx_sd);
2827                         DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
2828                         ext_phy_link_up = (rx_sd & 0x1);
2829                         break;
2830
2831                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2832                         DP(NETIF_MSG_LINK, "XGXS 8706\n");
2833                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2834                                       ext_phy_addr,
2835                                       MDIO_PMA_DEVAD,
2836                                       MDIO_PMA_REG_LASI_STATUS, &val1);
2837                         DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2838
2839                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2840                                       ext_phy_addr,
2841                                       MDIO_PMA_DEVAD,
2842                                       MDIO_PMA_REG_LASI_STATUS, &val1);
2843                         DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2844
2845                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2846                                       ext_phy_addr,
2847                                       MDIO_PMA_DEVAD,
2848                                       MDIO_PMA_REG_RX_SD, &rx_sd);
2849                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2850                                       ext_phy_addr,
2851                                       MDIO_PCS_DEVAD,
2852                                       MDIO_PCS_REG_STATUS, &pcs_status);
2853
2854                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2855                                       ext_phy_addr,
2856                                       MDIO_AN_DEVAD,
2857                                       MDIO_AN_REG_LINK_STATUS, &val2);
2858                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2859                                       ext_phy_addr,
2860                                       MDIO_AN_DEVAD,
2861                                       MDIO_AN_REG_LINK_STATUS, &val2);
2862
2863                         DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
2864                            "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
2865                            rx_sd, pcs_status, val2);
2866                         /* link is up if both bit 0 of pmd_rx_sd and
2867                          * bit 0 of pcs_status are set, or if the autoneg bit
2868                            1 is set
2869                          */
2870                         ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2871                                            (val2 & (1<<1)));
2872                         if (ext_phy_link_up) {
2873                                 if (val2 & (1<<1))
2874                                         vars->line_speed = SPEED_1000;
2875                                 else
2876                                         vars->line_speed = SPEED_10000;
2877                         }
2878
2879                         /* clear LASI indication*/
2880                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2881                                       ext_phy_addr,
2882                                       MDIO_PMA_DEVAD,
2883                                       MDIO_PMA_REG_RX_ALARM, &val2);
2884                         break;
2885
2886                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2887                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2888                 {
2889                         if (ext_phy_type ==
2890                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2891                                 bnx2x_cl45_read(bp, params->port,
2892                                       ext_phy_type,
2893                                       ext_phy_addr,
2894                                       MDIO_PCS_DEVAD,
2895                                       MDIO_PCS_REG_LASI_STATUS, &val1);
2896                         bnx2x_cl45_read(bp, params->port,
2897                                       ext_phy_type,
2898                                       ext_phy_addr,
2899                                       MDIO_PCS_DEVAD,
2900                                       MDIO_PCS_REG_LASI_STATUS, &val2);
2901                         DP(NETIF_MSG_LINK,
2902                                  "870x LASI status 0x%x->0x%x\n",
2903                                   val1, val2);
2904
2905                         } else {
2906                                 /* In 8073, port1 is directed through emac0 and
2907                                  * port0 is directed through emac1
2908                                  */
2909                                 bnx2x_cl45_read(bp, params->port,
2910                                               ext_phy_type,
2911                                               ext_phy_addr,
2912                                               MDIO_PMA_DEVAD,
2913                                               MDIO_PMA_REG_LASI_STATUS, &val1);
2914
2915                                 bnx2x_cl45_read(bp, params->port,
2916                                               ext_phy_type,
2917                                               ext_phy_addr,
2918                                               MDIO_PMA_DEVAD,
2919                                               MDIO_PMA_REG_LASI_STATUS, &val2);
2920                                 DP(NETIF_MSG_LINK,
2921                                          "8703 LASI status 0x%x->0x%x\n",
2922                                           val1, val2);
2923                         }
2924
2925                         /* clear the interrupt LASI status register */
2926                         bnx2x_cl45_read(bp, params->port,
2927                                       ext_phy_type,
2928                                       ext_phy_addr,
2929                                       MDIO_PCS_DEVAD,
2930                                       MDIO_PCS_REG_STATUS, &val2);
2931                         bnx2x_cl45_read(bp, params->port,
2932                                       ext_phy_type,
2933                                       ext_phy_addr,
2934                                       MDIO_PCS_DEVAD,
2935                                       MDIO_PCS_REG_STATUS, &val1);
2936                         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
2937                            val2, val1);
2938                         /* Check the LASI */
2939                         bnx2x_cl45_read(bp, params->port,
2940                                       ext_phy_type,
2941                                       ext_phy_addr,
2942                                       MDIO_PMA_DEVAD,
2943                                       MDIO_PMA_REG_RX_ALARM, &val2);
2944                         bnx2x_cl45_read(bp, params->port,
2945                                       ext_phy_type,
2946                                       ext_phy_addr,
2947                                       MDIO_PMA_DEVAD,
2948                                       MDIO_PMA_REG_RX_ALARM,
2949                                       &val1);
2950                         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
2951                            val2, val1);
2952                         /* Check the link status */
2953                         bnx2x_cl45_read(bp, params->port,
2954                                       ext_phy_type,
2955                                       ext_phy_addr,
2956                                       MDIO_PCS_DEVAD,
2957                                       MDIO_PCS_REG_STATUS, &val2);
2958                         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
2959
2960                         bnx2x_cl45_read(bp, params->port,
2961                                       ext_phy_type,
2962                                       ext_phy_addr,
2963                                       MDIO_PMA_DEVAD,
2964                                       MDIO_PMA_REG_STATUS, &val2);
2965                         bnx2x_cl45_read(bp, params->port,
2966                                       ext_phy_type,
2967                                       ext_phy_addr,
2968                                       MDIO_PMA_DEVAD,
2969                                       MDIO_PMA_REG_STATUS, &val1);
2970                         ext_phy_link_up = ((val1 & 4) == 4);
2971                         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
2972                         if (ext_phy_type ==
2973                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2974                                 u16 an1000_status = 0;
2975                                 if (ext_phy_link_up &&
2976                                     (
2977                                      (params->req_line_speed != SPEED_10000)
2978                                      )) {
2979                                         if (bnx2x_bcm8073_xaui_wa(params)
2980                                              != 0) {
2981                                                 ext_phy_link_up = 0;
2982                                                 break;
2983                                         }
2984                                         bnx2x_cl45_read(bp, params->port,
2985                                                       ext_phy_type,
2986                                                       ext_phy_addr,
2987                                                       MDIO_XS_DEVAD,
2988                                                       0x8304,
2989                                                       &an1000_status);
2990                                         bnx2x_cl45_read(bp, params->port,
2991                                                       ext_phy_type,
2992                                                       ext_phy_addr,
2993                                                       MDIO_XS_DEVAD,
2994                                                       0x8304,
2995                                                       &an1000_status);
2996                                 }
2997                                 /* Check the link status on 1.1.2 */
2998                                 bnx2x_cl45_read(bp, params->port,
2999                                               ext_phy_type,
3000                                               ext_phy_addr,
3001                                               MDIO_PMA_DEVAD,
3002                                               MDIO_PMA_REG_STATUS, &val2);
3003                                 bnx2x_cl45_read(bp, params->port,
3004                                               ext_phy_type,
3005                                               ext_phy_addr,
3006                                               MDIO_PMA_DEVAD,
3007                                               MDIO_PMA_REG_STATUS, &val1);
3008                                 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3009                                              "an_link_status=0x%x\n",
3010                                           val2, val1, an1000_status);
3011
3012                                 ext_phy_link_up = (((val1 & 4) == 4) ||
3013                                                     (an1000_status & (1<<1)));
3014                                 if (ext_phy_link_up &&
3015                                     bnx2x_8073_is_snr_needed(params)) {
3016                                         /* The SNR will improve about 2dbby
3017                                         changing the BW and FEE main tap.*/
3018
3019                                         /* The 1st write to change FFE main
3020                                         tap is set before restart AN */
3021                                         /* Change PLL Bandwidth in EDC
3022                                         register */
3023                                         bnx2x_cl45_write(bp, port, ext_phy_type,
3024                                                     ext_phy_addr,
3025                                                     MDIO_PMA_DEVAD,
3026                                                     MDIO_PMA_REG_PLL_BANDWIDTH,
3027                                                     0x26BC);
3028
3029                                         /* Change CDR Bandwidth in EDC
3030                                         register */
3031                                         bnx2x_cl45_write(bp, port, ext_phy_type,
3032                                                     ext_phy_addr,
3033                                                     MDIO_PMA_DEVAD,
3034                                                     MDIO_PMA_REG_CDR_BANDWIDTH,
3035                                                     0x0333);
3036
3037                                 }
3038                         }
3039                         break;
3040                 }
3041                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3042                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3043                                       ext_phy_addr,
3044                                       MDIO_PMA_DEVAD,
3045                                       MDIO_PMA_REG_LASI_STATUS, &val2);
3046                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3047                                       ext_phy_addr,
3048                                       MDIO_PMA_DEVAD,
3049                                       MDIO_PMA_REG_LASI_STATUS, &val1);
3050                         DP(NETIF_MSG_LINK,
3051                                  "10G-base-T LASI status 0x%x->0x%x\n",
3052                                   val2, val1);
3053                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3054                                       ext_phy_addr,
3055                                       MDIO_PMA_DEVAD,
3056                                       MDIO_PMA_REG_STATUS, &val2);
3057                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3058                                       ext_phy_addr,
3059                                       MDIO_PMA_DEVAD,
3060                                       MDIO_PMA_REG_STATUS, &val1);
3061                         DP(NETIF_MSG_LINK,
3062                                  "10G-base-T PMA status 0x%x->0x%x\n",
3063                                  val2, val1);
3064                         ext_phy_link_up = ((val1 & 4) == 4);
3065                         /* if link is up
3066                          * print the AN outcome of the SFX7101 PHY
3067                          */
3068                         if (ext_phy_link_up) {
3069                                 bnx2x_cl45_read(bp, params->port,
3070                                               ext_phy_type,
3071                                               ext_phy_addr,
3072                                               MDIO_AN_DEVAD,
3073                                               MDIO_AN_REG_MASTER_STATUS,
3074                                               &val2);
3075                                 vars->line_speed = SPEED_10000;
3076                                 DP(NETIF_MSG_LINK,
3077                                          "SFX7101 AN status 0x%x->Master=%x\n",
3078                                           val2,
3079                                          (val2 & (1<<14)));
3080                         }
3081                         break;
3082
3083                 default:
3084                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3085                            params->ext_phy_config);
3086                         ext_phy_link_up = 0;
3087                         break;
3088                 }
3089
3090         } else { /* SerDes */
3091                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3092                 switch (ext_phy_type) {
3093                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3094                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
3095                         ext_phy_link_up = 1;
3096                         break;
3097
3098                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3099                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
3100                         ext_phy_link_up = 1;
3101                         break;
3102
3103                 default:
3104                         DP(NETIF_MSG_LINK,
3105                                  "BAD SerDes ext_phy_config 0x%x\n",
3106                                  params->ext_phy_config);
3107                         ext_phy_link_up = 0;
3108                         break;
3109                 }
3110         }
3111
3112         return ext_phy_link_up;
3113 }
3114
3115 static void bnx2x_link_int_enable(struct link_params *params)
3116 {
3117         u8 port = params->port;
3118         u32 ext_phy_type;
3119         u32 mask;
3120         struct bnx2x *bp = params->bp;
3121         /* setting the status to report on link up
3122            for either XGXS or SerDes */
3123
3124         if (params->switch_cfg == SWITCH_CFG_10G) {
3125                 mask = (NIG_MASK_XGXS0_LINK10G |
3126                         NIG_MASK_XGXS0_LINK_STATUS);
3127                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3128                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3129                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3130                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3131                     (ext_phy_type !=
3132                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3133                         mask |= NIG_MASK_MI_INT;
3134                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
3135                 }
3136
3137         } else { /* SerDes */
3138                 mask = NIG_MASK_SERDES0_LINK_STATUS;
3139                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3140                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3141                 if ((ext_phy_type !=
3142                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3143                     (ext_phy_type !=
3144                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3145                         mask |= NIG_MASK_MI_INT;
3146                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
3147                 }
3148         }
3149         bnx2x_bits_en(bp,
3150                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3151                       mask);
3152         DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3153                  (params->switch_cfg == SWITCH_CFG_10G),
3154                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3155
3156         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3157                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3158                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
3159                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
3160         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3161            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3162            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3163 }
3164
3165
3166 /*
3167  * link management
3168  */
3169 static void bnx2x_link_int_ack(struct link_params *params,
3170                              struct link_vars *vars, u16 is_10g)
3171 {
3172         struct bnx2x *bp = params->bp;
3173         u8 port = params->port;
3174
3175         /* first reset all status
3176          * we assume only one line will be change at a time */
3177         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3178                      (NIG_STATUS_XGXS0_LINK10G |
3179                       NIG_STATUS_XGXS0_LINK_STATUS |
3180                       NIG_STATUS_SERDES0_LINK_STATUS));
3181         if (vars->phy_link_up) {
3182                 if (is_10g) {
3183                         /* Disable the 10G link interrupt
3184                          * by writing 1 to the status register
3185                          */
3186                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
3187                         bnx2x_bits_en(bp,
3188                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3189                                       NIG_STATUS_XGXS0_LINK10G);
3190
3191                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
3192                         /* Disable the link interrupt
3193                          * by writing 1 to the relevant lane
3194                          * in the status register
3195                          */
3196                         u32 ser_lane = ((params->lane_config &
3197                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3198                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3199
3200                         DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
3201                         bnx2x_bits_en(bp,
3202                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3203                                       ((1 << ser_lane) <<
3204                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
3205
3206                 } else { /* SerDes */
3207                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
3208                         /* Disable the link interrupt
3209                          * by writing 1 to the status register
3210                          */
3211                         bnx2x_bits_en(bp,
3212                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3213                                       NIG_STATUS_SERDES0_LINK_STATUS);
3214                 }
3215
3216         } else { /* link_down */
3217         }
3218 }
3219
3220 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3221 {
3222         u8 *str_ptr = str;
3223         u32 mask = 0xf0000000;
3224         u8 shift = 8*4;
3225         u8 digit;
3226         if (len < 10) {
3227                 /* Need more then 10chars for this format */
3228                 *str_ptr = '\0';
3229                 return -EINVAL;
3230         }
3231         while (shift > 0) {
3232
3233                 shift -= 4;
3234                 digit = ((num & mask) >> shift);
3235                 if (digit < 0xa)
3236                         *str_ptr = digit + '0';
3237                 else
3238                         *str_ptr = digit - 0xa + 'a';
3239                 str_ptr++;
3240                 mask = mask >> 4;
3241                 if (shift == 4*4) {
3242                         *str_ptr = ':';
3243                         str_ptr++;
3244                 }
3245         }
3246         *str_ptr = '\0';
3247         return 0;
3248 }
3249
3250
3251 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
3252                            u32 ext_phy_type)
3253 {
3254         u32 cnt = 0;
3255         u16 ctrl = 0;
3256         /* Enable EMAC0 in to enable MDIO */
3257         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3258                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
3259         msleep(5);
3260
3261         /* take ext phy out of reset */
3262         bnx2x_set_gpio(bp,
3263                         MISC_REGISTERS_GPIO_2,
3264                         MISC_REGISTERS_GPIO_HIGH);
3265
3266         bnx2x_set_gpio(bp,
3267                         MISC_REGISTERS_GPIO_1,
3268                         MISC_REGISTERS_GPIO_HIGH);
3269
3270         /* wait for 5ms */
3271         msleep(5);
3272
3273         for (cnt = 0; cnt < 1000; cnt++) {
3274                 msleep(1);
3275                 bnx2x_cl45_read(bp, port,
3276                               ext_phy_type,
3277                               ext_phy_addr,
3278                               MDIO_PMA_DEVAD,
3279                               MDIO_PMA_REG_CTRL,
3280                                &ctrl);
3281                 if (!(ctrl & (1<<15))) {
3282                         DP(NETIF_MSG_LINK, "Reset completed\n\n");
3283                                 break;
3284                 }
3285         }
3286 }
3287
3288 static void bnx2x_turn_off_sf(struct bnx2x *bp)
3289 {
3290         /* put sf to reset */
3291         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_LOW);
3292         bnx2x_set_gpio(bp,
3293                         MISC_REGISTERS_GPIO_2,
3294                         MISC_REGISTERS_GPIO_LOW);
3295 }
3296
3297 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3298                               u8 *version, u16 len)
3299 {
3300         struct bnx2x *bp = params->bp;
3301         u32 ext_phy_type = 0;
3302         u16 val = 0;
3303         u8 ext_phy_addr = 0 ;
3304         u8 status = 0 ;
3305         u32 ver_num;
3306
3307         if (version == NULL || params == NULL)
3308                 return -EINVAL;
3309
3310         /* reset the returned value to zero */
3311         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3312         ext_phy_addr = ((params->ext_phy_config &
3313                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3314                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3315
3316         switch (ext_phy_type) {
3317         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3318
3319                 if (len < 5)
3320                         return -EINVAL;
3321
3322                 /* Take ext phy out of reset */
3323                 if (!driver_loaded)
3324                         bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3325                                        ext_phy_type);
3326
3327                 /*  wait for 1ms */
3328                 msleep(1);
3329
3330                 bnx2x_cl45_read(bp, params->port,
3331                               ext_phy_type,
3332                               ext_phy_addr,
3333                               MDIO_PMA_DEVAD,
3334                               MDIO_PMA_REG_7101_VER1, &val);
3335                 version[2] = (val & 0xFF);
3336                 version[3] = ((val & 0xFF00)>>8);
3337
3338                 bnx2x_cl45_read(bp, params->port,
3339                               ext_phy_type,
3340                               ext_phy_addr,
3341                               MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
3342                               &val);
3343                 version[0] = (val & 0xFF);
3344                 version[1] = ((val & 0xFF00)>>8);
3345                 version[4] = '\0';
3346
3347                 if (!driver_loaded)
3348                         bnx2x_turn_off_sf(bp);
3349                 break;
3350         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3351         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3352         {
3353                 /* Take ext phy out of reset */
3354                 if (!driver_loaded)
3355                         bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3356                                        ext_phy_type);
3357
3358                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3359                               ext_phy_addr,
3360                               MDIO_PMA_DEVAD,
3361                               MDIO_PMA_REG_ROM_VER1, &val);
3362                 ver_num = val<<16;
3363                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3364                               ext_phy_addr,
3365                               MDIO_PMA_DEVAD,
3366                               MDIO_PMA_REG_ROM_VER2, &val);
3367                 ver_num |= val;
3368                 status = bnx2x_format_ver(ver_num, version, len);
3369                 break;
3370         }
3371         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3372         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3373
3374                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3375                               ext_phy_addr,
3376                               MDIO_PMA_DEVAD,
3377                               MDIO_PMA_REG_ROM_VER1, &val);
3378                 ver_num = val<<16;
3379                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3380                               ext_phy_addr,
3381                               MDIO_PMA_DEVAD,
3382                               MDIO_PMA_REG_ROM_VER2, &val);
3383                 ver_num |= val;
3384                 status = bnx2x_format_ver(ver_num, version, len);
3385                 break;
3386
3387         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3388                 break;
3389
3390         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3391                 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
3392                                     " type is FAILURE!\n");
3393                 status = -EINVAL;
3394                 break;
3395
3396         default:
3397                 break;
3398         }
3399         return status;
3400 }
3401
3402 static void bnx2x_set_xgxs_loopback(struct link_params *params,
3403                                   struct link_vars *vars,
3404                                   u8 is_10g)
3405 {
3406         u8 port = params->port;
3407         struct bnx2x *bp = params->bp;
3408
3409         if (is_10g) {
3410                  u32 md_devad;
3411
3412                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3413
3414                 /* change the uni_phy_addr in the nig */
3415                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3416                                           port*0x18));
3417
3418                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3419
3420                 bnx2x_cl45_write(bp, port, 0,
3421                                params->phy_addr,
3422                                5,
3423                                (MDIO_REG_BANK_AER_BLOCK +
3424                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
3425                                0x2800);
3426
3427                 bnx2x_cl45_write(bp, port, 0,
3428                                params->phy_addr,
3429                                5,
3430                                (MDIO_REG_BANK_CL73_IEEEB0 +
3431                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3432                                0x6041);
3433
3434                 /* set aer mmd back */
3435                 bnx2x_set_aer_mmd(params, vars);
3436
3437                 /* and md_devad */
3438                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3439                             md_devad);
3440
3441         } else {
3442                 u16 mii_control;
3443
3444                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3445
3446                 CL45_RD_OVER_CL22(bp, port,
3447                                       params->phy_addr,
3448                                       MDIO_REG_BANK_COMBO_IEEE0,
3449                                       MDIO_COMBO_IEEE0_MII_CONTROL,
3450                                       &mii_control);
3451
3452                 CL45_WR_OVER_CL22(bp, port,
3453                                       params->phy_addr,
3454                                       MDIO_REG_BANK_COMBO_IEEE0,
3455                                       MDIO_COMBO_IEEE0_MII_CONTROL,
3456                                       (mii_control |
3457                                        MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
3458         }
3459 }
3460
3461
3462 static void bnx2x_ext_phy_loopback(struct link_params *params)
3463 {
3464         struct bnx2x *bp = params->bp;
3465         u8 ext_phy_addr;
3466         u32 ext_phy_type;
3467
3468         if (params->switch_cfg == SWITCH_CFG_10G) {
3469                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3470                 /* CL37 Autoneg Enabled */
3471                 ext_phy_addr = ((params->ext_phy_config &
3472                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3473                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3474                 switch (ext_phy_type) {
3475                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3476                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
3477                         DP(NETIF_MSG_LINK,
3478                                 "ext_phy_loopback: We should not get here\n");
3479                         break;
3480                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3481                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
3482                         break;
3483                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3484                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
3485                         break;
3486                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3487                         /* SFX7101_XGXS_TEST1 */
3488                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
3489                                        ext_phy_addr,
3490                                        MDIO_XS_DEVAD,
3491                                        MDIO_XS_SFX7101_XGXS_TEST1,
3492                                        0x100);
3493                         DP(NETIF_MSG_LINK,
3494                                 "ext_phy_loopback: set ext phy loopback\n");
3495                         break;
3496                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3497
3498                         break;
3499                 } /* switch external PHY type */
3500         } else {
3501                 /* serdes */
3502                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3503                 ext_phy_addr = (params->ext_phy_config  &
3504                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
3505                 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
3506         }
3507 }
3508
3509
3510 /*
3511  *------------------------------------------------------------------------
3512  * bnx2x_override_led_value -
3513  *
3514  * Override the led value of the requsted led
3515  *
3516  *------------------------------------------------------------------------
3517  */
3518 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
3519                           u32 led_idx, u32 value)
3520 {
3521         u32 reg_val;
3522
3523         /* If port 0 then use EMAC0, else use EMAC1*/
3524         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3525
3526         DP(NETIF_MSG_LINK,
3527                  "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3528                  port, led_idx, value);
3529
3530         switch (led_idx) {
3531         case 0: /* 10MB led */
3532                 /* Read the current value of the LED register in
3533                 the EMAC block */
3534                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3535                 /* Set the OVERRIDE bit to 1 */
3536                 reg_val |= EMAC_LED_OVERRIDE;
3537                 /* If value is 1, set the 10M_OVERRIDE bit,
3538                 otherwise reset it.*/
3539                 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
3540                         (reg_val & ~EMAC_LED_10MB_OVERRIDE);
3541                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3542                 break;
3543         case 1: /*100MB led    */
3544                 /*Read the current value of the LED register in
3545                 the EMAC block */
3546                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3547                 /*  Set the OVERRIDE bit to 1 */
3548                 reg_val |= EMAC_LED_OVERRIDE;
3549                 /*  If value is 1, set the 100M_OVERRIDE bit,
3550                 otherwise reset it.*/
3551                 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
3552                         (reg_val & ~EMAC_LED_100MB_OVERRIDE);
3553                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3554                 break;
3555         case 2: /* 1000MB led */
3556                 /* Read the current value of the LED register in the
3557                 EMAC block */
3558                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3559                 /* Set the OVERRIDE bit to 1 */
3560                 reg_val |= EMAC_LED_OVERRIDE;
3561                 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3562                 reset it. */
3563                 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
3564                         (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
3565                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3566                 break;
3567         case 3: /* 2500MB led */
3568                 /*  Read the current value of the LED register in the
3569                 EMAC block*/
3570                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3571                 /* Set the OVERRIDE bit to 1 */
3572                 reg_val |= EMAC_LED_OVERRIDE;
3573                 /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
3574                 reset it.*/
3575                 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
3576                         (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
3577                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3578                 break;
3579         case 4: /*10G led */
3580                 if (port == 0) {
3581                         REG_WR(bp, NIG_REG_LED_10G_P0,
3582                                     value);
3583                 } else {
3584                         REG_WR(bp, NIG_REG_LED_10G_P1,
3585                                     value);
3586                 }
3587                 break;
3588         case 5: /* TRAFFIC led */
3589                 /* Find if the traffic control is via BMAC or EMAC */
3590                 if (port == 0)
3591                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
3592                 else
3593                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
3594
3595                 /*  Override the traffic led in the EMAC:*/
3596                 if (reg_val == 1) {
3597                         /* Read the current value of the LED register in
3598                         the EMAC block */
3599                         reg_val = REG_RD(bp, emac_base +
3600                                              EMAC_REG_EMAC_LED);
3601                         /* Set the TRAFFIC_OVERRIDE bit to 1 */
3602                         reg_val |= EMAC_LED_OVERRIDE;
3603                         /* If value is 1, set the TRAFFIC bit, otherwise
3604                         reset it.*/
3605                         reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
3606                                 (reg_val & ~EMAC_LED_TRAFFIC);
3607                         REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3608                 } else { /* Override the traffic led in the BMAC: */
3609                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3610                                    + port*4, 1);
3611                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
3612                                     value);
3613                 }
3614                 break;
3615         default:
3616                 DP(NETIF_MSG_LINK,
3617                          "bnx2x_override_led_value() unknown led index %d "
3618                          "(should be 0-5)\n", led_idx);
3619                 return -EINVAL;
3620         }
3621
3622         return 0;
3623 }
3624
3625
3626 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3627                u16 hw_led_mode, u32 chip_id)
3628 {
3629         u8 rc = 0;
3630         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3631         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3632                  speed, hw_led_mode);
3633         switch (mode) {
3634         case LED_MODE_OFF:
3635                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3636                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3637                            SHARED_HW_CFG_LED_MAC1);
3638                 break;
3639
3640         case LED_MODE_OPER:
3641                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
3642                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
3643                            port*4, 0);
3644                 /* Set blinking rate to ~15.9Hz */
3645                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3646                            LED_BLINK_RATE_VAL);
3647                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3648                            port*4, 1);
3649                 if (!CHIP_IS_E1H(bp) &&
3650                     ((speed == SPEED_2500) ||
3651                      (speed == SPEED_1000) ||
3652                      (speed == SPEED_100) ||
3653                      (speed == SPEED_10))) {
3654                         /* On Everest 1 Ax chip versions for speeds less than
3655                         10G LED scheme is different */
3656                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3657                                    + port*4, 1);
3658                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3659                                    port*4, 0);
3660                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3661                                    port*4, 1);
3662                 }
3663                 break;
3664
3665         default:
3666                 rc = -EINVAL;
3667                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3668                          mode);
3669                 break;
3670         }
3671         return rc;
3672
3673 }
3674
3675 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
3676 {
3677         struct bnx2x *bp = params->bp;
3678         u16 gp_status = 0;
3679
3680         CL45_RD_OVER_CL22(bp, params->port,
3681                               params->phy_addr,
3682                               MDIO_REG_BANK_GP_STATUS,
3683                               MDIO_GP_STATUS_TOP_AN_STATUS1,
3684                               &gp_status);
3685         /* link is up only if both local phy and external phy are up */
3686         if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
3687             bnx2x_ext_phy_is_link_up(params, vars))
3688                 return 0;
3689
3690         return -ESRCH;
3691 }
3692
3693 static u8 bnx2x_link_initialize(struct link_params *params,
3694                               struct link_vars *vars)
3695 {
3696         struct bnx2x *bp = params->bp;
3697         u8 port = params->port;
3698         u8 rc = 0;
3699         u8 non_ext_phy;
3700         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3701         /* Activate the external PHY */
3702         bnx2x_ext_phy_reset(params, vars);
3703
3704         bnx2x_set_aer_mmd(params, vars);
3705
3706         if (vars->phy_flags & PHY_XGXS_FLAG)
3707                 bnx2x_set_master_ln(params);
3708
3709         rc = bnx2x_reset_unicore(params);
3710         /* reset the SerDes and wait for reset bit return low */
3711         if (rc != 0)
3712                 return rc;
3713
3714         bnx2x_set_aer_mmd(params, vars);
3715
3716         /* setting the masterLn_def again after the reset */
3717         if (vars->phy_flags & PHY_XGXS_FLAG) {
3718                 bnx2x_set_master_ln(params);
3719                 bnx2x_set_swap_lanes(params);
3720         }
3721
3722         if (vars->phy_flags & PHY_XGXS_FLAG) {
3723                 if (params->req_line_speed &&
3724                     ((params->req_line_speed == SPEED_100) ||
3725                      (params->req_line_speed == SPEED_10))) {
3726                         vars->phy_flags |= PHY_SGMII_FLAG;
3727                 } else {
3728                         vars->phy_flags &= ~PHY_SGMII_FLAG;
3729                 }
3730         }
3731         /* In case of external phy existance, the line speed would be the
3732          line speed linked up by the external phy. In case it is direct only,
3733           then the line_speed during initialization will be equal to the
3734            req_line_speed*/
3735         vars->line_speed = params->req_line_speed;
3736
3737         bnx2x_set_ieee_aneg_advertisment(params, &vars->ieee_fc);
3738
3739         /* init ext phy and enable link state int */
3740         non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3741                        (params->loopback_mode == LOOPBACK_XGXS_10) ||
3742                        (params->loopback_mode == LOOPBACK_EXT_PHY));
3743
3744         if (non_ext_phy ||
3745             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3746                 if (params->req_line_speed == SPEED_AUTO_NEG)
3747                         bnx2x_set_parallel_detection(params, vars->phy_flags);
3748                 bnx2x_init_internal_phy(params, vars);
3749         }
3750
3751         if (!non_ext_phy)
3752                 rc |= bnx2x_ext_phy_init(params, vars);
3753
3754         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3755                      (NIG_STATUS_XGXS0_LINK10G |
3756                       NIG_STATUS_XGXS0_LINK_STATUS |
3757                       NIG_STATUS_SERDES0_LINK_STATUS));
3758
3759         return rc;
3760
3761 }
3762
3763
3764 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3765 {
3766         struct bnx2x *bp = params->bp;
3767
3768         u32 val;
3769         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
3770         DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3771                   params->req_line_speed, params->req_flow_ctrl);
3772         vars->link_status = 0;
3773         vars->phy_link_up = 0;
3774         vars->link_up = 0;
3775         vars->line_speed = 0;
3776         vars->duplex = DUPLEX_FULL;
3777         vars->flow_ctrl = FLOW_CTRL_NONE;
3778         vars->mac_type = MAC_TYPE_NONE;
3779
3780         if (params->switch_cfg ==  SWITCH_CFG_1G)
3781                 vars->phy_flags = PHY_SERDES_FLAG;
3782         else
3783                 vars->phy_flags = PHY_XGXS_FLAG;
3784
3785         /* disable attentions */
3786         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3787                        (NIG_MASK_XGXS0_LINK_STATUS |
3788                         NIG_MASK_XGXS0_LINK10G |
3789                         NIG_MASK_SERDES0_LINK_STATUS |
3790                         NIG_MASK_MI_INT));
3791
3792         bnx2x_emac_init(params, vars);
3793
3794         if (CHIP_REV_IS_FPGA(bp)) {
3795                 vars->link_up = 1;
3796                 vars->line_speed = SPEED_10000;
3797                 vars->duplex = DUPLEX_FULL;
3798                 vars->flow_ctrl = FLOW_CTRL_NONE;
3799                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3800                 /* enable on E1.5 FPGA */
3801                 if (CHIP_IS_E1H(bp)) {
3802                         vars->flow_ctrl |=
3803                                 (FLOW_CTRL_TX | FLOW_CTRL_RX);
3804                         vars->link_status |=
3805                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
3806                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
3807                 }
3808
3809                 bnx2x_emac_enable(params, vars, 0);
3810                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3811                 /* disable drain */
3812                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3813                                     + params->port*4, 0);
3814
3815                 /* update shared memory */
3816                 bnx2x_update_mng(params, vars->link_status);
3817
3818                 return 0;
3819
3820         } else
3821         if (CHIP_REV_IS_EMUL(bp)) {
3822
3823                 vars->link_up = 1;
3824                 vars->line_speed = SPEED_10000;
3825                 vars->duplex = DUPLEX_FULL;
3826                 vars->flow_ctrl = FLOW_CTRL_NONE;
3827                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3828
3829                 bnx2x_bmac_enable(params, vars, 0);
3830
3831                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3832                 /* Disable drain */
3833                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3834                                     + params->port*4, 0);
3835
3836                 /* update shared memory */
3837                 bnx2x_update_mng(params, vars->link_status);
3838
3839                 return 0;
3840
3841         } else
3842         if (params->loopback_mode == LOOPBACK_BMAC) {
3843                 vars->link_up = 1;
3844                 vars->line_speed = SPEED_10000;
3845                 vars->duplex = DUPLEX_FULL;
3846                 vars->flow_ctrl = FLOW_CTRL_NONE;
3847                 vars->mac_type = MAC_TYPE_BMAC;
3848
3849                 vars->phy_flags = PHY_XGXS_FLAG;
3850
3851                 bnx2x_phy_deassert(params, vars->phy_flags);
3852                 /* set bmac loopback */
3853                 bnx2x_bmac_enable(params, vars, 1);
3854
3855                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3856                     params->port*4, 0);
3857         } else if (params->loopback_mode == LOOPBACK_EMAC) {
3858                 vars->link_up = 1;
3859                 vars->line_speed = SPEED_1000;
3860                 vars->duplex = DUPLEX_FULL;
3861                 vars->flow_ctrl = FLOW_CTRL_NONE;
3862                 vars->mac_type = MAC_TYPE_EMAC;
3863
3864                 vars->phy_flags = PHY_XGXS_FLAG;
3865
3866                 bnx2x_phy_deassert(params, vars->phy_flags);
3867                 /* set bmac loopback */
3868                 bnx2x_emac_enable(params, vars, 1);
3869                 bnx2x_emac_program(params, vars->line_speed,
3870                                               vars->duplex);
3871                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3872                     params->port*4, 0);
3873         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
3874                   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
3875                 vars->link_up = 1;
3876                 vars->line_speed = SPEED_10000;
3877                 vars->duplex = DUPLEX_FULL;
3878                 vars->flow_ctrl = FLOW_CTRL_NONE;
3879
3880                 vars->phy_flags = PHY_XGXS_FLAG;
3881
3882                 val = REG_RD(bp,
3883                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
3884                                  params->port*0x18);
3885                 params->phy_addr = (u8)val;
3886
3887                 bnx2x_phy_deassert(params, vars->phy_flags);
3888                 bnx2x_link_initialize(params, vars);
3889
3890                 vars->mac_type = MAC_TYPE_BMAC;
3891
3892                 bnx2x_bmac_enable(params, vars, 0);
3893
3894                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
3895                         /* set 10G XGXS loopback */
3896                         bnx2x_set_xgxs_loopback(params, vars, 1);
3897                 } else {
3898                         /* set external phy loopback */
3899                         bnx2x_ext_phy_loopback(params);
3900                 }
3901                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3902                             params->port*4, 0);
3903         } else
3904         /* No loopback */
3905         {
3906
3907                 bnx2x_phy_deassert(params, vars->phy_flags);
3908                 switch (params->switch_cfg) {
3909                 case SWITCH_CFG_1G:
3910                         vars->phy_flags |= PHY_SERDES_FLAG;
3911                         if ((params->ext_phy_config &
3912                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
3913                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
3914                                 vars->phy_flags |=
3915                                         PHY_SGMII_FLAG;
3916                         }
3917
3918                         val = REG_RD(bp,
3919                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
3920                                          params->port*0x10);
3921
3922                         params->phy_addr = (u8)val;
3923
3924                         break;
3925                 case SWITCH_CFG_10G:
3926                         vars->phy_flags |= PHY_XGXS_FLAG;
3927                         val = REG_RD(bp,
3928                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
3929                                  params->port*0x18);
3930                         params->phy_addr = (u8)val;
3931
3932                         break;
3933                 default:
3934                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
3935                         return -EINVAL;
3936                         break;
3937                 }
3938
3939                 bnx2x_link_initialize(params, vars);
3940                 msleep(30);
3941                 bnx2x_link_int_enable(params);
3942         }
3943         return 0;
3944 }
3945
3946 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
3947 {
3948
3949         struct bnx2x *bp = params->bp;
3950         u32 ext_phy_config = params->ext_phy_config;
3951         u16 hw_led_mode = params->hw_led_mode;
3952         u32 chip_id = params->chip_id;
3953         u8 port = params->port;
3954         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
3955         /* disable attentions */
3956
3957         vars->link_status = 0;
3958         bnx2x_update_mng(params, vars->link_status);
3959         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3960                      (NIG_MASK_XGXS0_LINK_STATUS |
3961                       NIG_MASK_XGXS0_LINK10G |
3962                       NIG_MASK_SERDES0_LINK_STATUS |
3963                       NIG_MASK_MI_INT));
3964
3965         /* activate nig drain */
3966         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
3967
3968         /* disable nig egress interface */
3969         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
3970         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
3971
3972         /* Stop BigMac rx */
3973         bnx2x_bmac_rx_disable(bp, port);
3974
3975         /* disable emac */
3976         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
3977
3978         msleep(10);
3979         /* The PHY reset is controled by GPIO 1
3980          * Hold it as vars low
3981          */
3982          /* clear link led */
3983         bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
3984         if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
3985                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3986                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3987                         /* HW reset */
3988
3989                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3990                                        MISC_REGISTERS_GPIO_OUTPUT_LOW);
3991
3992                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3993                                        MISC_REGISTERS_GPIO_OUTPUT_LOW);
3994
3995                         DP(NETIF_MSG_LINK, "reset external PHY\n");
3996                 } else if (ext_phy_type ==
3997                            PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3998                                 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
3999                                          "low power mode\n",
4000                                          port);
4001                                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4002                                         MISC_REGISTERS_GPIO_OUTPUT_LOW);
4003                 }
4004         }
4005         /* reset the SerDes/XGXS */
4006         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4007                (0x1ff << (port*16)));
4008
4009         /* reset BigMac */
4010         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4011                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4012
4013         /* disable nig ingress interface */
4014         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4015         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4016         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4017         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4018         vars->link_up = 0;
4019         return 0;
4020 }
4021
4022 static u8 bnx2x_update_link_down(struct link_params *params,
4023                                struct link_vars *vars)
4024 {
4025         struct bnx2x *bp = params->bp;
4026         u8 port = params->port;
4027         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4028         bnx2x_set_led(bp, port, LED_MODE_OFF,
4029                     0, params->hw_led_mode,
4030                     params->chip_id);
4031
4032         /* indicate no mac active */
4033         vars->mac_type = MAC_TYPE_NONE;
4034
4035         /* update shared memory */
4036         vars->link_status = 0;
4037         vars->line_speed = 0;
4038         bnx2x_update_mng(params, vars->link_status);
4039
4040         /* activate nig drain */
4041         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4042
4043         /* reset BigMac */
4044         bnx2x_bmac_rx_disable(bp, params->port);
4045         REG_WR(bp, GRCBASE_MISC +
4046                    MISC_REGISTERS_RESET_REG_2_CLEAR,
4047                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4048         return 0;
4049 }
4050
4051 static u8 bnx2x_update_link_up(struct link_params *params,
4052                              struct link_vars *vars,
4053                              u8 link_10g, u32 gp_status)
4054 {
4055         struct bnx2x *bp = params->bp;
4056         u8 port = params->port;
4057         u8 rc = 0;
4058         vars->link_status |= LINK_STATUS_LINK_UP;
4059         if (link_10g) {
4060                 bnx2x_bmac_enable(params, vars, 0);
4061                 bnx2x_set_led(bp, port, LED_MODE_OPER,
4062                             SPEED_10000, params->hw_led_mode,
4063                             params->chip_id);
4064
4065         } else {
4066                 bnx2x_emac_enable(params, vars, 0);
4067                 rc = bnx2x_emac_program(params, vars->line_speed,
4068                                       vars->duplex);
4069
4070                 /* AN complete? */
4071                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4072                         if (!(vars->phy_flags &
4073                               PHY_SGMII_FLAG))
4074                                 bnx2x_set_sgmii_tx_driver(params);
4075                 }
4076         }
4077
4078         /* PBF - link up */
4079         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4080                               vars->line_speed);
4081
4082         /* disable drain */
4083         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4084
4085         /* update shared memory */
4086         bnx2x_update_mng(params, vars->link_status);
4087         return rc;
4088 }
4089 /* This function should called upon link interrupt */
4090 /* In case vars->link_up, driver needs to
4091         1. Update the pbf
4092         2. Disable drain
4093         3. Update the shared memory
4094         4. Indicate link up
4095         5. Set LEDs
4096    Otherwise,
4097         1. Update shared memory
4098         2. Reset BigMac
4099         3. Report link down
4100         4. Unset LEDs
4101 */
4102 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4103 {
4104         struct bnx2x *bp = params->bp;
4105         u8 port = params->port;
4106         u16 gp_status;
4107         u8 link_10g;
4108         u8 ext_phy_link_up, rc = 0;
4109         u32 ext_phy_type;
4110
4111         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4112          port,
4113         (vars->phy_flags & PHY_XGXS_FLAG),
4114          REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4115
4116         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4117         REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4118         REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4119         REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4120
4121         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4122           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4123           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4124
4125         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4126
4127         /* Check external link change only for non-direct */
4128         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4129
4130         /* Read gp_status */
4131         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4132                               MDIO_REG_BANK_GP_STATUS,
4133                               MDIO_GP_STATUS_TOP_AN_STATUS1,
4134                               &gp_status);
4135
4136         rc = bnx2x_link_settings_status(params, vars, gp_status);
4137         if (rc != 0)
4138                 return rc;
4139
4140         /* anything 10 and over uses the bmac */
4141         link_10g = ((vars->line_speed == SPEED_10000) ||
4142                     (vars->line_speed == SPEED_12000) ||
4143                     (vars->line_speed == SPEED_12500) ||
4144                     (vars->line_speed == SPEED_13000) ||
4145                     (vars->line_speed == SPEED_15000) ||
4146                     (vars->line_speed == SPEED_16000));
4147
4148         bnx2x_link_int_ack(params, vars, link_10g);
4149
4150         /* In case external phy link is up, and internal link is down
4151         ( not initialized yet probably after link initialization, it needs
4152         to be initialized.
4153         Note that after link down-up as result of cable plug,
4154         the xgxs link would probably become up again without the need to
4155         initialize it*/
4156
4157         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4158             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4159             (ext_phy_link_up && !vars->phy_link_up))
4160                 bnx2x_init_internal_phy(params, vars);
4161
4162         /* link is up only if both local phy and external phy are up */
4163         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4164
4165         if (vars->link_up)
4166                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4167         else
4168                 rc = bnx2x_update_link_down(params, vars);
4169
4170         return rc;
4171 }
4172
4173 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4174 {
4175         u16 val, cnt;
4176
4177         bnx2x_cl45_read(bp, port,
4178                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4179                       phy_addr,
4180                       MDIO_PMA_DEVAD,
4181                       MDIO_PMA_REG_7101_RESET, &val);
4182
4183         for (cnt = 0; cnt < 10; cnt++) {
4184                 msleep(50);
4185                 /* Writes a self-clearing reset */
4186                 bnx2x_cl45_write(bp, port,
4187                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4188                                phy_addr,
4189                                MDIO_PMA_DEVAD,
4190                                MDIO_PMA_REG_7101_RESET,
4191                                (val | (1<<15)));
4192                 /* Wait for clear */
4193                 bnx2x_cl45_read(bp, port,
4194                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4195                               phy_addr,
4196                               MDIO_PMA_DEVAD,
4197                               MDIO_PMA_REG_7101_RESET, &val);
4198
4199                 if ((val & (1<<15)) == 0)
4200                         break;
4201         }
4202 }
4203 #define RESERVED_SIZE 256
4204 /* max application is 160K bytes - data at end of RAM */
4205 #define MAX_APP_SIZE 160*1024 - RESERVED_SIZE
4206
4207 /* Header is 14 bytes */
4208 #define HEADER_SIZE 14
4209 #define DATA_OFFSET HEADER_SIZE
4210
4211 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4212         bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4213                         ext_phy_addr, \
4214                         MDIO_PCS_DEVAD, \
4215                         MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4216
4217 /* Programs an image to DSP's flash via the SPI port*/
4218 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4219                                      u8 ext_phy_addr,
4220                                      char data[], u32 size)
4221 {
4222         const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
4223         /* Doesn't include last trans!*/
4224         const u16 last_trans_size = size%4; /* Num bytes on last trans */
4225         u16 trans_cnt, byte_cnt;
4226         u32 data_index;
4227         u16 tmp;
4228         u16 code_started = 0;
4229         u16 image_revision1, image_revision2;
4230         u16 cnt;
4231
4232         DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
4233         /* Going to flash*/
4234         if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
4235                 /* This very often will be the case, because the image is built
4236                 with 160Kbytes size whereas the total image size must actually
4237                 be 160Kbytes-RESERVED_SIZE */
4238                 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
4239                          "truncated to %d bytes\n", size, MAX_APP_SIZE);
4240                 size = MAX_APP_SIZE+HEADER_SIZE;
4241         }
4242         DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4243         DP(NETIF_MSG_LINK, "                %c%c\n", data[0x150], data[0x151]);
4244         /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4245            and issuing a reset.*/
4246
4247         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4248                           MISC_REGISTERS_GPIO_HIGH);
4249
4250         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4251
4252         /* wait 0.5 sec */
4253         for (cnt = 0; cnt < 100; cnt++)
4254                 msleep(5);
4255
4256         /* Make sure we can access the DSP
4257            And it's in the correct mode (waiting for download) */
4258
4259         bnx2x_cl45_read(bp, port,
4260                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4261                       ext_phy_addr,
4262                       MDIO_PCS_DEVAD,
4263                       MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
4264
4265         if (tmp != 0x000A) {
4266                 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
4267                          "Expected 0x000A, read 0x%04X\n", tmp);
4268                 DP(NETIF_MSG_LINK, "Download failed\n");
4269                 return -EINVAL;
4270         }
4271
4272         /* Mux the SPI interface away from the internal processor */
4273         bnx2x_cl45_write(bp, port,
4274                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4275                        ext_phy_addr,
4276                        MDIO_PCS_DEVAD,
4277                        MDIO_PCS_REG_7101_SPI_MUX, 1);
4278
4279         /* Reset the SPI port */
4280         bnx2x_cl45_write(bp, port,
4281                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4282                        ext_phy_addr,
4283                        MDIO_PCS_DEVAD,
4284                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4285         bnx2x_cl45_write(bp, port,
4286                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4287                        ext_phy_addr,
4288                        MDIO_PCS_DEVAD,
4289                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
4290                        (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
4291         bnx2x_cl45_write(bp, port,
4292                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4293                        ext_phy_addr,
4294                        MDIO_PCS_DEVAD,
4295                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4296
4297         /* Erase the flash */
4298         bnx2x_cl45_write(bp, port,
4299                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4300                        ext_phy_addr,
4301                        MDIO_PCS_DEVAD,
4302                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4303                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4304
4305         bnx2x_cl45_write(bp, port,
4306                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4307                        ext_phy_addr,
4308                        MDIO_PCS_DEVAD,
4309                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4310                        1);
4311
4312         SPI_START_TRANSFER(bp, port, ext_phy_addr);
4313         bnx2x_cl45_write(bp, port,
4314                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4315                        ext_phy_addr,
4316                        MDIO_PCS_DEVAD,
4317                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4318                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
4319
4320         bnx2x_cl45_write(bp, port,
4321                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4322                        ext_phy_addr,
4323                        MDIO_PCS_DEVAD,
4324                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4325                        1);
4326         SPI_START_TRANSFER(bp, port, ext_phy_addr);
4327
4328         /* Wait 10 seconds, the maximum time for the erase to complete */
4329         DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
4330         for (cnt = 0; cnt < 1000; cnt++)
4331                 msleep(10);
4332
4333         DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
4334         data_index = 0;
4335         for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
4336                 bnx2x_cl45_write(bp, port,
4337                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4338                              ext_phy_addr,
4339                              MDIO_PCS_DEVAD,
4340                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4341                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4342
4343                 bnx2x_cl45_write(bp, port,
4344                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4345                                ext_phy_addr,
4346                                MDIO_PCS_DEVAD,
4347                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4348                                1);
4349                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4350
4351                 bnx2x_cl45_write(bp, port,
4352                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4353                                ext_phy_addr,
4354                                MDIO_PCS_DEVAD,
4355                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4356                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4357
4358                 /* Bits 23-16 of address */
4359                 bnx2x_cl45_write(bp, port,
4360                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4361                                ext_phy_addr,
4362                                MDIO_PCS_DEVAD,
4363                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4364                                (data_index>>16));
4365                 /* Bits 15-8 of address */
4366                 bnx2x_cl45_write(bp, port,
4367                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4368                                ext_phy_addr,
4369                                MDIO_PCS_DEVAD,
4370                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4371                                (data_index>>8));
4372
4373                 /* Bits 7-0 of address */
4374                 bnx2x_cl45_write(bp, port,
4375                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4376                                ext_phy_addr,
4377                                MDIO_PCS_DEVAD,
4378                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4379                                ((u16)data_index));
4380
4381                 byte_cnt = 0;
4382                 while (byte_cnt < 4 && data_index < size) {
4383                         bnx2x_cl45_write(bp, port,
4384                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4385                                        ext_phy_addr,
4386                                MDIO_PCS_DEVAD,
4387                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4388                                data[data_index++]);
4389                         byte_cnt++;
4390                 }
4391
4392                 bnx2x_cl45_write(bp, port,
4393                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4394                                ext_phy_addr,
4395                                MDIO_PCS_DEVAD,
4396                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4397                                byte_cnt+4);
4398
4399                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4400                 msleep(5); /* Wait 5 ms minimum between transs */
4401
4402                 /* Let the user know something's going on.*/
4403                 /* a pacifier ever 4K */
4404                 if ((data_index % 1023) == 0)
4405                         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4406         }
4407
4408         DP(NETIF_MSG_LINK, "\n");
4409         /* Transfer the last block if there is data remaining */
4410         if (last_trans_size) {
4411                 bnx2x_cl45_write(bp, port,
4412                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4413                         ext_phy_addr,
4414                         MDIO_PCS_DEVAD,
4415                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4416                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4417
4418                 bnx2x_cl45_write(bp, port,
4419                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4420                                ext_phy_addr,
4421                                MDIO_PCS_DEVAD,
4422                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4423                                1);
4424
4425                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4426
4427                 bnx2x_cl45_write(bp, port,
4428                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4429                              ext_phy_addr,
4430                              MDIO_PCS_DEVAD,
4431                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4432                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4433
4434                 /* Bits 23-16 of address */
4435                 bnx2x_cl45_write(bp, port,
4436                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4437                                ext_phy_addr,
4438                                MDIO_PCS_DEVAD,
4439                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4440                                (data_index>>16));
4441                 /* Bits 15-8 of address */
4442                 bnx2x_cl45_write(bp, port,
4443                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4444                                ext_phy_addr,
4445                                MDIO_PCS_DEVAD,
4446                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4447                                (data_index>>8));
4448
4449                 /* Bits 7-0 of address */
4450                 bnx2x_cl45_write(bp, port,
4451                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4452                                ext_phy_addr,
4453                                MDIO_PCS_DEVAD,
4454                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4455                                ((u16)data_index));
4456
4457                 byte_cnt = 0;
4458                 while (byte_cnt < last_trans_size && data_index < size) {
4459                         /* Bits 7-0 of address */
4460                         bnx2x_cl45_write(bp, port,
4461                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4462                                 ext_phy_addr,
4463                                 MDIO_PCS_DEVAD,
4464                                 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4465                                 data[data_index++]);
4466                         byte_cnt++;
4467                 }
4468
4469                 bnx2x_cl45_write(bp, port,
4470                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4471                                ext_phy_addr,
4472                                MDIO_PCS_DEVAD,
4473                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4474                                byte_cnt+4);
4475
4476                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4477         }
4478
4479         /* DSP Remove Download Mode */
4480         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, MISC_REGISTERS_GPIO_LOW);
4481
4482         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4483
4484         /* wait 0.5 sec to allow it to run */
4485         for (cnt = 0; cnt < 100; cnt++)
4486                 msleep(5);
4487
4488         bnx2x_hw_reset(bp);
4489
4490         for (cnt = 0; cnt < 100; cnt++)
4491                 msleep(5);
4492
4493         /* Check that the code is started. In case the download
4494         checksum failed, the code won't be started. */
4495         bnx2x_cl45_read(bp, port,
4496                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4497                       ext_phy_addr,
4498                       MDIO_PCS_DEVAD,
4499                       MDIO_PCS_REG_7101_DSP_ACCESS,
4500                       &tmp);
4501
4502         code_started = (tmp & (1<<4));
4503         if (!code_started) {
4504                 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
4505                 return -EINVAL;
4506         }
4507
4508         /* Verify that the file revision is now equal to the image
4509         revision within the DSP */
4510         bnx2x_cl45_read(bp, port,
4511                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4512                       ext_phy_addr,
4513                       MDIO_PMA_DEVAD,
4514                       MDIO_PMA_REG_7101_VER1,
4515                       &image_revision1);
4516
4517         bnx2x_cl45_read(bp, port,
4518                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4519                       ext_phy_addr,
4520                       MDIO_PMA_DEVAD,
4521                       MDIO_PMA_REG_7101_VER2,
4522                       &image_revision2);
4523
4524         if (data[0x14e] != (image_revision2&0xFF) ||
4525             data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4526             data[0x150] != (image_revision1&0xFF) ||
4527             data[0x151] != ((image_revision1&0xFF00)>>8)) {
4528                 DP(NETIF_MSG_LINK, "Download failed.\n");
4529                 return -EINVAL;
4530         }
4531         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4532         return 0;
4533 }
4534
4535 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4536                       u8 driver_loaded, char data[], u32 size)
4537 {
4538         u8 rc = 0;
4539         u32 ext_phy_type;
4540         u8 ext_phy_addr;
4541         ext_phy_addr = ((ext_phy_config &
4542                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4543                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4544
4545         ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4546
4547         switch (ext_phy_type) {
4548         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4549         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4550         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4551         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4552                 DP(NETIF_MSG_LINK,
4553                         "Flash download not supported for this ext phy\n");
4554                 rc = -EINVAL;
4555                 break;
4556         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4557                 /* Take ext phy out of reset */
4558                 if (!driver_loaded)
4559                         bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4560                 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4561                                                 data, size);
4562                 if (!driver_loaded)
4563                         bnx2x_turn_off_sf(bp);
4564                 break;
4565         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4566         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4567         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4568         default:
4569                 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
4570                 rc = -EINVAL;
4571                 break;
4572         }
4573         return rc;
4574 }
4575