Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6.git] / drivers / net / bnx2x_link.c
1 /* Copyright 2008-2009 Broadcom Corporation
2  *
3  * Unless you and Broadcom execute a separate written software license
4  * agreement governing use of this software, this software is licensed to you
5  * under the terms of the GNU General Public License version 2, available
6  * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7  *
8  * Notwithstanding the above, under no circumstances may you combine this
9  * software in any way with any other Broadcom software provided under a
10  * license other than the GPL, without Broadcom's express prior written
11  * consent.
12  *
13  * Written by Yaniv Rosner
14  *
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24
25 #include "bnx2x_reg.h"
26 #include "bnx2x_fw_defs.h"
27 #include "bnx2x_hsi.h"
28 #include "bnx2x_link.h"
29 #include "bnx2x.h"
30
31 /********************************************************/
32 #define SUPPORT_CL73 0 /* Currently no */
33 #define ETH_HLEN                        14
34 #define ETH_OVREHEAD            (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
35 #define ETH_MIN_PACKET_SIZE             60
36 #define ETH_MAX_PACKET_SIZE             1500
37 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
38 #define MDIO_ACCESS_TIMEOUT             1000
39 #define BMAC_CONTROL_RX_ENABLE  2
40
41 /***********************************************************/
42 /*                      Shortcut definitions               */
43 /***********************************************************/
44
45 #define NIG_STATUS_XGXS0_LINK10G \
46                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
47 #define NIG_STATUS_XGXS0_LINK_STATUS \
48                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
49 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
50                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
51 #define NIG_STATUS_SERDES0_LINK_STATUS \
52                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
53 #define NIG_MASK_MI_INT \
54                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
55 #define NIG_MASK_XGXS0_LINK10G \
56                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
57 #define NIG_MASK_XGXS0_LINK_STATUS \
58                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
59 #define NIG_MASK_SERDES0_LINK_STATUS \
60                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
61
62 #define MDIO_AN_CL73_OR_37_COMPLETE \
63                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
64                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
65
66 #define XGXS_RESET_BITS \
67         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
68          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
69          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
70          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
71          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
72
73 #define SERDES_RESET_BITS \
74         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
75          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
76          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
77          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
78
79 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
80 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
81 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
82 #define AUTONEG_PARALLEL \
83                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
84 #define AUTONEG_SGMII_FIBER_AUTODET \
85                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
86 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
87
88 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
89                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
90 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
91                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
92 #define GP_STATUS_SPEED_MASK \
93                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
94 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
95 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
96 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
97 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
98 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
99 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
100 #define GP_STATUS_10G_HIG \
101                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
102 #define GP_STATUS_10G_CX4 \
103                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
104 #define GP_STATUS_12G_HIG \
105                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
106 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
107 #define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
108 #define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
109 #define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
110 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
111 #define GP_STATUS_10G_KX4 \
112                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
113
114 #define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
115 #define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
116 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
117 #define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
118 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
119 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
120 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
121 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
122 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
123 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
124 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
125 #define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
126 #define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
127 #define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
128 #define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
129 #define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
130 #define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
131 #define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
132 #define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
133 #define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
134 #define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
135 #define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
136 #define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
137
138 #define PHY_XGXS_FLAG                   0x1
139 #define PHY_SGMII_FLAG                  0x2
140 #define PHY_SERDES_FLAG                 0x4
141
142 /**********************************************************/
143 /*                     INTERFACE                          */
144 /**********************************************************/
145 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
146         bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
147                 DEFAULT_PHY_DEV_ADDR, \
148                 (_bank + (_addr & 0xf)), \
149                 _val)
150
151 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
152         bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
153                 DEFAULT_PHY_DEV_ADDR, \
154                 (_bank + (_addr & 0xf)), \
155                 _val)
156
157 static void bnx2x_set_phy_mdio(struct link_params *params)
158 {
159         struct bnx2x *bp = params->bp;
160         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
161                    params->port*0x18, 0);
162         REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
163                    DEFAULT_PHY_DEV_ADDR);
164 }
165
166 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
167 {
168         u32 val = REG_RD(bp, reg);
169
170         val |= bits;
171         REG_WR(bp, reg, val);
172         return val;
173 }
174
175 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
176 {
177         u32 val = REG_RD(bp, reg);
178
179         val &= ~bits;
180         REG_WR(bp, reg, val);
181         return val;
182 }
183
184 static void bnx2x_emac_init(struct link_params *params,
185                            struct link_vars *vars)
186 {
187         /* reset and unreset the emac core */
188         struct bnx2x *bp = params->bp;
189         u8 port = params->port;
190         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
191         u32 val;
192         u16 timeout;
193
194         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
195                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
196         udelay(5);
197         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
198                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
199
200         /* init emac - use read-modify-write */
201         /* self clear reset */
202         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
203         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
204
205         timeout = 200;
206         do {
207                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
208                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
209                 if (!timeout) {
210                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
211                         return;
212                 }
213                 timeout--;
214         } while (val & EMAC_MODE_RESET);
215
216         /* Set mac address */
217         val = ((params->mac_addr[0] << 8) |
218                 params->mac_addr[1]);
219         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
220
221         val = ((params->mac_addr[2] << 24) |
222                (params->mac_addr[3] << 16) |
223                (params->mac_addr[4] << 8) |
224                 params->mac_addr[5]);
225         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
226 }
227
228 static u8 bnx2x_emac_enable(struct link_params *params,
229                           struct link_vars *vars, u8 lb)
230 {
231         struct bnx2x *bp = params->bp;
232         u8 port = params->port;
233         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
234         u32 val;
235
236         DP(NETIF_MSG_LINK, "enabling EMAC\n");
237
238         /* enable emac and not bmac */
239         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
240
241         /* for paladium */
242         if (CHIP_REV_IS_EMUL(bp)) {
243                 /* Use lane 1 (of lanes 0-3) */
244                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
245                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
246                             port*4, 1);
247         }
248         /* for fpga */
249         else
250
251         if (CHIP_REV_IS_FPGA(bp)) {
252                 /* Use lane 1 (of lanes 0-3) */
253                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
254
255                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
256                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
257                             0);
258         } else
259         /* ASIC */
260         if (vars->phy_flags & PHY_XGXS_FLAG) {
261                 u32 ser_lane = ((params->lane_config &
262                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
263                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
264
265                 DP(NETIF_MSG_LINK, "XGXS\n");
266                 /* select the master lanes (out of 0-3) */
267                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
268                            port*4, ser_lane);
269                 /* select XGXS */
270                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
271                            port*4, 1);
272
273         } else { /* SerDes */
274                 DP(NETIF_MSG_LINK, "SerDes\n");
275                 /* select SerDes */
276                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
277                            port*4, 0);
278         }
279
280         /* enable emac */
281         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
282
283         if (CHIP_REV_IS_SLOW(bp)) {
284                 /* config GMII mode */
285                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
286                 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
287                             (val | EMAC_MODE_PORT_GMII));
288         } else { /* ASIC */
289                 /* pause enable/disable */
290                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
291                                EMAC_RX_MODE_FLOW_EN);
292                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
293                         bnx2x_bits_en(bp, emac_base +
294                                     EMAC_REG_EMAC_RX_MODE,
295                                     EMAC_RX_MODE_FLOW_EN);
296
297                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
298                              (EMAC_TX_MODE_EXT_PAUSE_EN |
299                               EMAC_TX_MODE_FLOW_EN));
300                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
301                         bnx2x_bits_en(bp, emac_base +
302                                     EMAC_REG_EMAC_TX_MODE,
303                                    (EMAC_TX_MODE_EXT_PAUSE_EN |
304                                     EMAC_TX_MODE_FLOW_EN));
305         }
306
307         /* KEEP_VLAN_TAG, promiscuous */
308         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
309         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
310         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
311
312         /* Set Loopback */
313         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
314         if (lb)
315                 val |= 0x810;
316         else
317                 val &= ~0x810;
318         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
319
320         /* enable emac */
321         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
322
323         /* enable emac for jumbo packets */
324         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
325                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
326                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
327
328         /* strip CRC */
329         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
330
331         /* disable the NIG in/out to the bmac */
332         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
333         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
334         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
335
336         /* enable the NIG in/out to the emac */
337         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
338         val = 0;
339         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
340                 val = 1;
341
342         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
343         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
344
345         if (CHIP_REV_IS_EMUL(bp)) {
346                 /* take the BigMac out of reset */
347                 REG_WR(bp,
348                            GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
349                            (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
350
351                 /* enable access for bmac registers */
352                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
353         }
354
355         vars->mac_type = MAC_TYPE_EMAC;
356         return 0;
357 }
358
359
360
361 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
362                           u8 is_lb)
363 {
364         struct bnx2x *bp = params->bp;
365         u8 port = params->port;
366         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
367                                NIG_REG_INGRESS_BMAC0_MEM;
368         u32 wb_data[2];
369         u32 val;
370
371         DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
372         /* reset and unreset the BigMac */
373         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
374                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
375         msleep(1);
376
377         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
378                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
379
380         /* enable access for bmac registers */
381         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
382
383         /* XGXS control */
384         wb_data[0] = 0x3c;
385         wb_data[1] = 0;
386         REG_WR_DMAE(bp, bmac_addr +
387                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
388                       wb_data, 2);
389
390         /* tx MAC SA */
391         wb_data[0] = ((params->mac_addr[2] << 24) |
392                        (params->mac_addr[3] << 16) |
393                        (params->mac_addr[4] << 8) |
394                         params->mac_addr[5]);
395         wb_data[1] = ((params->mac_addr[0] << 8) |
396                         params->mac_addr[1]);
397         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
398                     wb_data, 2);
399
400         /* tx control */
401         val = 0xc0;
402         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
403                 val |= 0x800000;
404         wb_data[0] = val;
405         wb_data[1] = 0;
406         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
407                         wb_data, 2);
408
409         /* mac control */
410         val = 0x3;
411         if (is_lb) {
412                 val |= 0x4;
413                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
414         }
415         wb_data[0] = val;
416         wb_data[1] = 0;
417         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
418                     wb_data, 2);
419
420
421         /* set rx mtu */
422         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
423         wb_data[1] = 0;
424         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
425                         wb_data, 2);
426
427         /* rx control set to don't strip crc */
428         val = 0x14;
429         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
430                 val |= 0x20;
431         wb_data[0] = val;
432         wb_data[1] = 0;
433         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
434                         wb_data, 2);
435
436         /* set tx mtu */
437         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
438         wb_data[1] = 0;
439         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
440                         wb_data, 2);
441
442         /* set cnt max size */
443         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
444         wb_data[1] = 0;
445         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
446                     wb_data, 2);
447
448         /* configure safc */
449         wb_data[0] = 0x1000200;
450         wb_data[1] = 0;
451         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
452                     wb_data, 2);
453         /* fix for emulation */
454         if (CHIP_REV_IS_EMUL(bp)) {
455                 wb_data[0] = 0xf000;
456                 wb_data[1] = 0;
457                 REG_WR_DMAE(bp,
458                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
459                             wb_data, 2);
460         }
461
462         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
463         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
464         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
465         val = 0;
466         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
467                 val = 1;
468         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
469         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
470         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
471         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
472         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
473         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
474
475         vars->mac_type = MAC_TYPE_BMAC;
476         return 0;
477 }
478
479 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
480 {
481         struct bnx2x *bp = params->bp;
482         u32 val;
483
484         if (phy_flags & PHY_XGXS_FLAG) {
485                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
486                 val = XGXS_RESET_BITS;
487
488         } else { /* SerDes */
489                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
490                 val = SERDES_RESET_BITS;
491         }
492
493         val = val << (params->port*16);
494
495         /* reset and unreset the SerDes/XGXS */
496         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
497                     val);
498         udelay(500);
499         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
500                     val);
501         bnx2x_set_phy_mdio(params);
502 }
503
504 void bnx2x_link_status_update(struct link_params *params,
505                             struct link_vars   *vars)
506 {
507         struct bnx2x *bp = params->bp;
508         u8 link_10g;
509         u8 port = params->port;
510
511         if (params->switch_cfg ==  SWITCH_CFG_1G)
512                 vars->phy_flags = PHY_SERDES_FLAG;
513         else
514                 vars->phy_flags = PHY_XGXS_FLAG;
515         vars->link_status = REG_RD(bp, params->shmem_base +
516                                           offsetof(struct shmem_region,
517                                            port_mb[port].link_status));
518
519         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
520
521         if (vars->link_up) {
522                 DP(NETIF_MSG_LINK, "phy link up\n");
523
524                 vars->phy_link_up = 1;
525                 vars->duplex = DUPLEX_FULL;
526                 switch (vars->link_status &
527                                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
528                         case LINK_10THD:
529                                 vars->duplex = DUPLEX_HALF;
530                                 /* fall thru */
531                         case LINK_10TFD:
532                                 vars->line_speed = SPEED_10;
533                                 break;
534
535                         case LINK_100TXHD:
536                                 vars->duplex = DUPLEX_HALF;
537                                 /* fall thru */
538                         case LINK_100T4:
539                         case LINK_100TXFD:
540                                 vars->line_speed = SPEED_100;
541                                 break;
542
543                         case LINK_1000THD:
544                                 vars->duplex = DUPLEX_HALF;
545                                 /* fall thru */
546                         case LINK_1000TFD:
547                                 vars->line_speed = SPEED_1000;
548                                 break;
549
550                         case LINK_2500THD:
551                                 vars->duplex = DUPLEX_HALF;
552                                 /* fall thru */
553                         case LINK_2500TFD:
554                                 vars->line_speed = SPEED_2500;
555                                 break;
556
557                         case LINK_10GTFD:
558                                 vars->line_speed = SPEED_10000;
559                                 break;
560
561                         case LINK_12GTFD:
562                                 vars->line_speed = SPEED_12000;
563                                 break;
564
565                         case LINK_12_5GTFD:
566                                 vars->line_speed = SPEED_12500;
567                                 break;
568
569                         case LINK_13GTFD:
570                                 vars->line_speed = SPEED_13000;
571                                 break;
572
573                         case LINK_15GTFD:
574                                 vars->line_speed = SPEED_15000;
575                                 break;
576
577                         case LINK_16GTFD:
578                                 vars->line_speed = SPEED_16000;
579                                 break;
580
581                         default:
582                                 break;
583                 }
584
585                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
586                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
587                 else
588                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
589
590                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
591                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
592                 else
593                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
594
595                 if (vars->phy_flags & PHY_XGXS_FLAG) {
596                         if (vars->line_speed &&
597                             ((vars->line_speed == SPEED_10) ||
598                              (vars->line_speed == SPEED_100))) {
599                                 vars->phy_flags |= PHY_SGMII_FLAG;
600                         } else {
601                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
602                         }
603                 }
604
605                 /* anything 10 and over uses the bmac */
606                 link_10g = ((vars->line_speed == SPEED_10000) ||
607                             (vars->line_speed == SPEED_12000) ||
608                             (vars->line_speed == SPEED_12500) ||
609                             (vars->line_speed == SPEED_13000) ||
610                             (vars->line_speed == SPEED_15000) ||
611                             (vars->line_speed == SPEED_16000));
612                 if (link_10g)
613                         vars->mac_type = MAC_TYPE_BMAC;
614                 else
615                         vars->mac_type = MAC_TYPE_EMAC;
616
617         } else { /* link down */
618                 DP(NETIF_MSG_LINK, "phy link down\n");
619
620                 vars->phy_link_up = 0;
621
622                 vars->line_speed = 0;
623                 vars->duplex = DUPLEX_FULL;
624                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
625
626                 /* indicate no mac active */
627                 vars->mac_type = MAC_TYPE_NONE;
628         }
629
630         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
631                  vars->link_status, vars->phy_link_up);
632         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
633                  vars->line_speed, vars->duplex, vars->flow_ctrl);
634 }
635
636 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
637 {
638         struct bnx2x *bp = params->bp;
639         REG_WR(bp, params->shmem_base +
640                    offsetof(struct shmem_region,
641                             port_mb[params->port].link_status),
642                         link_status);
643 }
644
645 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
646 {
647         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
648                 NIG_REG_INGRESS_BMAC0_MEM;
649         u32 wb_data[2];
650         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
651
652         /* Only if the bmac is out of reset */
653         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
654                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
655             nig_bmac_enable) {
656
657                 /* Clear Rx Enable bit in BMAC_CONTROL register */
658                 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
659                             wb_data, 2);
660                 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
661                 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
662                             wb_data, 2);
663
664                 msleep(1);
665         }
666 }
667
668 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
669                          u32 line_speed)
670 {
671         struct bnx2x *bp = params->bp;
672         u8 port = params->port;
673         u32 init_crd, crd;
674         u32 count = 1000;
675
676         /* disable port */
677         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
678
679         /* wait for init credit */
680         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
681         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
682         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
683
684         while ((init_crd != crd) && count) {
685                 msleep(5);
686
687                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
688                 count--;
689         }
690         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
691         if (init_crd != crd) {
692                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
693                           init_crd, crd);
694                 return -EINVAL;
695         }
696
697         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
698             line_speed == SPEED_10 ||
699             line_speed == SPEED_100 ||
700             line_speed == SPEED_1000 ||
701             line_speed == SPEED_2500) {
702                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
703                 /* update threshold */
704                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
705                 /* update init credit */
706                 init_crd = 778;         /* (800-18-4) */
707
708         } else {
709                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
710                               ETH_OVREHEAD)/16;
711                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
712                 /* update threshold */
713                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
714                 /* update init credit */
715                 switch (line_speed) {
716                 case SPEED_10000:
717                         init_crd = thresh + 553 - 22;
718                         break;
719
720                 case SPEED_12000:
721                         init_crd = thresh + 664 - 22;
722                         break;
723
724                 case SPEED_13000:
725                         init_crd = thresh + 742 - 22;
726                         break;
727
728                 case SPEED_16000:
729                         init_crd = thresh + 778 - 22;
730                         break;
731                 default:
732                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
733                                   line_speed);
734                         return -EINVAL;
735                         break;
736                 }
737         }
738         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
739         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
740                  line_speed, init_crd);
741
742         /* probe the credit changes */
743         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
744         msleep(5);
745         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
746
747         /* enable port */
748         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
749         return 0;
750 }
751
752 static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
753 {
754         u32 emac_base;
755         switch (ext_phy_type) {
756         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
757                 emac_base = GRCBASE_EMAC0;
758                 break;
759         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
760                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
761                 break;
762         default:
763                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
764                 break;
765         }
766         return emac_base;
767
768 }
769
770 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
771                   u8 phy_addr, u8 devad, u16 reg, u16 val)
772 {
773         u32 tmp, saved_mode;
774         u8 i, rc = 0;
775         u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
776
777         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
778          * (a value of 49==0x31) and make sure that the AUTO poll is off
779          */
780         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
781         tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
782                              EMAC_MDIO_MODE_CLOCK_CNT);
783         tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
784                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
785         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
786         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
787         udelay(40);
788
789         /* address */
790
791         tmp = ((phy_addr << 21) | (devad << 16) | reg |
792                EMAC_MDIO_COMM_COMMAND_ADDRESS |
793                EMAC_MDIO_COMM_START_BUSY);
794         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
795
796         for (i = 0; i < 50; i++) {
797                 udelay(10);
798
799                 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
800                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
801                         udelay(5);
802                         break;
803                 }
804         }
805         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
806                 DP(NETIF_MSG_LINK, "write phy register failed\n");
807                 rc = -EFAULT;
808         } else {
809                 /* data */
810                 tmp = ((phy_addr << 21) | (devad << 16) | val |
811                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
812                        EMAC_MDIO_COMM_START_BUSY);
813                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
814
815                 for (i = 0; i < 50; i++) {
816                         udelay(10);
817
818                         tmp = REG_RD(bp, mdio_ctrl +
819                                          EMAC_REG_EMAC_MDIO_COMM);
820                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
821                                 udelay(5);
822                                 break;
823                         }
824                 }
825                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
826                         DP(NETIF_MSG_LINK, "write phy register failed\n");
827                         rc = -EFAULT;
828                 }
829         }
830
831         /* Restore the saved mode */
832         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
833
834         return rc;
835 }
836
837 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
838                  u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
839 {
840         u32 val, saved_mode;
841         u16 i;
842         u8 rc = 0;
843
844         u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
845         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
846          * (a value of 49==0x31) and make sure that the AUTO poll is off
847          */
848         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
849         val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
850                              EMAC_MDIO_MODE_CLOCK_CNT));
851         val |= (EMAC_MDIO_MODE_CLAUSE_45 |
852                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
853         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
854         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
855         udelay(40);
856
857         /* address */
858         val = ((phy_addr << 21) | (devad << 16) | reg |
859                EMAC_MDIO_COMM_COMMAND_ADDRESS |
860                EMAC_MDIO_COMM_START_BUSY);
861         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
862
863         for (i = 0; i < 50; i++) {
864                 udelay(10);
865
866                 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
867                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
868                         udelay(5);
869                         break;
870                 }
871         }
872         if (val & EMAC_MDIO_COMM_START_BUSY) {
873                 DP(NETIF_MSG_LINK, "read phy register failed\n");
874
875                 *ret_val = 0;
876                 rc = -EFAULT;
877
878         } else {
879                 /* data */
880                 val = ((phy_addr << 21) | (devad << 16) |
881                        EMAC_MDIO_COMM_COMMAND_READ_45 |
882                        EMAC_MDIO_COMM_START_BUSY);
883                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
884
885                 for (i = 0; i < 50; i++) {
886                         udelay(10);
887
888                         val = REG_RD(bp, mdio_ctrl +
889                                           EMAC_REG_EMAC_MDIO_COMM);
890                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
891                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
892                                 break;
893                         }
894                 }
895                 if (val & EMAC_MDIO_COMM_START_BUSY) {
896                         DP(NETIF_MSG_LINK, "read phy register failed\n");
897
898                         *ret_val = 0;
899                         rc = -EFAULT;
900                 }
901         }
902
903         /* Restore the saved mode */
904         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
905
906         return rc;
907 }
908
909 static void bnx2x_set_aer_mmd(struct link_params *params,
910                             struct link_vars   *vars)
911 {
912         struct bnx2x *bp = params->bp;
913         u32 ser_lane;
914         u16 offset;
915
916         ser_lane = ((params->lane_config &
917                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
918                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
919
920         offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
921                 (params->phy_addr + ser_lane) : 0;
922
923         CL45_WR_OVER_CL22(bp, params->port,
924                               params->phy_addr,
925                               MDIO_REG_BANK_AER_BLOCK,
926                               MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
927 }
928
929 static void bnx2x_set_master_ln(struct link_params *params)
930 {
931         struct bnx2x *bp = params->bp;
932         u16 new_master_ln, ser_lane;
933         ser_lane =  ((params->lane_config &
934                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
935                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
936
937         /* set the master_ln for AN */
938         CL45_RD_OVER_CL22(bp, params->port,
939                               params->phy_addr,
940                               MDIO_REG_BANK_XGXS_BLOCK2,
941                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
942                               &new_master_ln);
943
944         CL45_WR_OVER_CL22(bp, params->port,
945                               params->phy_addr,
946                               MDIO_REG_BANK_XGXS_BLOCK2 ,
947                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
948                               (new_master_ln | ser_lane));
949 }
950
951 static u8 bnx2x_reset_unicore(struct link_params *params)
952 {
953         struct bnx2x *bp = params->bp;
954         u16 mii_control;
955         u16 i;
956
957         CL45_RD_OVER_CL22(bp, params->port,
958                               params->phy_addr,
959                               MDIO_REG_BANK_COMBO_IEEE0,
960                               MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
961
962         /* reset the unicore */
963         CL45_WR_OVER_CL22(bp, params->port,
964                               params->phy_addr,
965                               MDIO_REG_BANK_COMBO_IEEE0,
966                               MDIO_COMBO_IEEE0_MII_CONTROL,
967                               (mii_control |
968                                MDIO_COMBO_IEEO_MII_CONTROL_RESET));
969
970         /* wait for the reset to self clear */
971         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
972                 udelay(5);
973
974                 /* the reset erased the previous bank value */
975                 CL45_RD_OVER_CL22(bp, params->port,
976                                       params->phy_addr,
977                               MDIO_REG_BANK_COMBO_IEEE0,
978                               MDIO_COMBO_IEEE0_MII_CONTROL,
979                               &mii_control);
980
981                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
982                         udelay(5);
983                         return 0;
984                 }
985         }
986
987         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
988         return -EINVAL;
989
990 }
991
992 static void bnx2x_set_swap_lanes(struct link_params *params)
993 {
994         struct bnx2x *bp = params->bp;
995         /* Each two bits represents a lane number:
996            No swap is 0123 => 0x1b no need to enable the swap */
997         u16 ser_lane, rx_lane_swap, tx_lane_swap;
998
999         ser_lane = ((params->lane_config &
1000                          PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1001                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1002         rx_lane_swap = ((params->lane_config &
1003                              PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1004                             PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1005         tx_lane_swap = ((params->lane_config &
1006                              PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1007                             PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1008
1009         if (rx_lane_swap != 0x1b) {
1010                 CL45_WR_OVER_CL22(bp, params->port,
1011                                       params->phy_addr,
1012                                     MDIO_REG_BANK_XGXS_BLOCK2,
1013                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1014                                     (rx_lane_swap |
1015                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1016                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1017         } else {
1018                 CL45_WR_OVER_CL22(bp, params->port,
1019                                       params->phy_addr,
1020                                       MDIO_REG_BANK_XGXS_BLOCK2,
1021                                       MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1022         }
1023
1024         if (tx_lane_swap != 0x1b) {
1025                 CL45_WR_OVER_CL22(bp, params->port,
1026                                       params->phy_addr,
1027                                       MDIO_REG_BANK_XGXS_BLOCK2,
1028                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1029                                       (tx_lane_swap |
1030                                        MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1031         } else {
1032                 CL45_WR_OVER_CL22(bp, params->port,
1033                                       params->phy_addr,
1034                                       MDIO_REG_BANK_XGXS_BLOCK2,
1035                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1036         }
1037 }
1038
1039 static void bnx2x_set_parallel_detection(struct link_params *params,
1040                                        u8                phy_flags)
1041 {
1042         struct bnx2x *bp = params->bp;
1043         u16 control2;
1044
1045         CL45_RD_OVER_CL22(bp, params->port,
1046                               params->phy_addr,
1047                               MDIO_REG_BANK_SERDES_DIGITAL,
1048                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1049                               &control2);
1050
1051
1052         control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1053
1054
1055         CL45_WR_OVER_CL22(bp, params->port,
1056                               params->phy_addr,
1057                               MDIO_REG_BANK_SERDES_DIGITAL,
1058                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1059                               control2);
1060
1061         if (phy_flags & PHY_XGXS_FLAG) {
1062                 DP(NETIF_MSG_LINK, "XGXS\n");
1063
1064                 CL45_WR_OVER_CL22(bp, params->port,
1065                                       params->phy_addr,
1066                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1067                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1068                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1069
1070                 CL45_RD_OVER_CL22(bp, params->port,
1071                                       params->phy_addr,
1072                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1073                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1074                                 &control2);
1075
1076
1077                 control2 |=
1078                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1079
1080                 CL45_WR_OVER_CL22(bp, params->port,
1081                                       params->phy_addr,
1082                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1083                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1084                                 control2);
1085
1086                 /* Disable parallel detection of HiG */
1087                 CL45_WR_OVER_CL22(bp, params->port,
1088                                       params->phy_addr,
1089                                 MDIO_REG_BANK_XGXS_BLOCK2,
1090                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1091                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1092                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1093         }
1094 }
1095
1096 static void bnx2x_set_autoneg(struct link_params *params,
1097                             struct link_vars   *vars)
1098 {
1099         struct bnx2x *bp = params->bp;
1100         u16 reg_val;
1101
1102         /* CL37 Autoneg */
1103
1104         CL45_RD_OVER_CL22(bp, params->port,
1105                               params->phy_addr,
1106                               MDIO_REG_BANK_COMBO_IEEE0,
1107                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1108
1109         /* CL37 Autoneg Enabled */
1110         if (vars->line_speed == SPEED_AUTO_NEG)
1111                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1112         else /* CL37 Autoneg Disabled */
1113                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1114                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1115
1116         CL45_WR_OVER_CL22(bp, params->port,
1117                               params->phy_addr,
1118                               MDIO_REG_BANK_COMBO_IEEE0,
1119                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1120
1121         /* Enable/Disable Autodetection */
1122
1123         CL45_RD_OVER_CL22(bp, params->port,
1124                               params->phy_addr,
1125                               MDIO_REG_BANK_SERDES_DIGITAL,
1126                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1127         reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1128         if (vars->line_speed == SPEED_AUTO_NEG)
1129                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1130         else
1131                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1132
1133         CL45_WR_OVER_CL22(bp, params->port,
1134                               params->phy_addr,
1135                               MDIO_REG_BANK_SERDES_DIGITAL,
1136                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1137
1138         /* Enable TetonII and BAM autoneg */
1139         CL45_RD_OVER_CL22(bp, params->port,
1140                               params->phy_addr,
1141                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1142                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1143                           &reg_val);
1144         if (vars->line_speed == SPEED_AUTO_NEG) {
1145                 /* Enable BAM aneg Mode and TetonII aneg Mode */
1146                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1147                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1148         } else {
1149                 /* TetonII and BAM Autoneg Disabled */
1150                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1151                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1152         }
1153         CL45_WR_OVER_CL22(bp, params->port,
1154                               params->phy_addr,
1155                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1156                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1157                               reg_val);
1158
1159         /* Enable Clause 73 Aneg */
1160         if ((vars->line_speed == SPEED_AUTO_NEG) &&
1161             (SUPPORT_CL73)) {
1162                 /* Enable BAM Station Manager */
1163
1164                 CL45_WR_OVER_CL22(bp, params->port,
1165                                       params->phy_addr,
1166                                       MDIO_REG_BANK_CL73_USERB0,
1167                                       MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1168                                    (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1169                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1170                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1171
1172                 /* Merge CL73 and CL37 aneg resolution */
1173                 CL45_RD_OVER_CL22(bp, params->port,
1174                                       params->phy_addr,
1175                                       MDIO_REG_BANK_CL73_USERB0,
1176                                       MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1177                                       &reg_val);
1178
1179                 CL45_WR_OVER_CL22(bp, params->port,
1180                                       params->phy_addr,
1181                         MDIO_REG_BANK_CL73_USERB0,
1182                         MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1183                         (reg_val |
1184                         MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1185
1186                 /* Set the CL73 AN speed */
1187
1188                 CL45_RD_OVER_CL22(bp, params->port,
1189                                       params->phy_addr,
1190                                       MDIO_REG_BANK_CL73_IEEEB1,
1191                                       MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
1192                 /* In the SerDes we support only the 1G.
1193                    In the XGXS we support the 10G KX4
1194                    but we currently do not support the KR */
1195                 if (vars->phy_flags & PHY_XGXS_FLAG) {
1196                         DP(NETIF_MSG_LINK, "XGXS\n");
1197                         /* 10G KX4 */
1198                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1199                 } else {
1200                         DP(NETIF_MSG_LINK, "SerDes\n");
1201                         /* 1000M KX */
1202                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1203                 }
1204                 CL45_WR_OVER_CL22(bp, params->port,
1205                                       params->phy_addr,
1206                                       MDIO_REG_BANK_CL73_IEEEB1,
1207                                       MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1208
1209                 /* CL73 Autoneg Enabled */
1210                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1211         } else {
1212                 /* CL73 Autoneg Disabled */
1213                 reg_val = 0;
1214         }
1215         CL45_WR_OVER_CL22(bp, params->port,
1216                               params->phy_addr,
1217                               MDIO_REG_BANK_CL73_IEEEB0,
1218                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1219 }
1220
1221 /* program SerDes, forced speed */
1222 static void bnx2x_program_serdes(struct link_params *params,
1223                                struct link_vars *vars)
1224 {
1225         struct bnx2x *bp = params->bp;
1226         u16 reg_val;
1227
1228         /* program duplex, disable autoneg */
1229
1230         CL45_RD_OVER_CL22(bp, params->port,
1231                               params->phy_addr,
1232                               MDIO_REG_BANK_COMBO_IEEE0,
1233                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1234         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1235                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1236         if (params->req_duplex == DUPLEX_FULL)
1237                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1238         CL45_WR_OVER_CL22(bp, params->port,
1239                               params->phy_addr,
1240                               MDIO_REG_BANK_COMBO_IEEE0,
1241                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1242
1243         /* program speed
1244            - needed only if the speed is greater than 1G (2.5G or 10G) */
1245         CL45_RD_OVER_CL22(bp, params->port,
1246                                       params->phy_addr,
1247                                       MDIO_REG_BANK_SERDES_DIGITAL,
1248                                       MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1249         /* clearing the speed value before setting the right speed */
1250         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1251
1252         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1253                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1254
1255         if (!((vars->line_speed == SPEED_1000) ||
1256               (vars->line_speed == SPEED_100) ||
1257               (vars->line_speed == SPEED_10))) {
1258
1259                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1260                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1261                 if (vars->line_speed == SPEED_10000)
1262                         reg_val |=
1263                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1264                 if (vars->line_speed == SPEED_13000)
1265                         reg_val |=
1266                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1267         }
1268
1269         CL45_WR_OVER_CL22(bp, params->port,
1270                                       params->phy_addr,
1271                                       MDIO_REG_BANK_SERDES_DIGITAL,
1272                                       MDIO_SERDES_DIGITAL_MISC1, reg_val);
1273
1274 }
1275
1276 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1277 {
1278         struct bnx2x *bp = params->bp;
1279         u16 val = 0;
1280
1281         /* configure the 48 bits for BAM AN */
1282
1283         /* set extended capabilities */
1284         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1285                 val |= MDIO_OVER_1G_UP1_2_5G;
1286         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1287                 val |= MDIO_OVER_1G_UP1_10G;
1288         CL45_WR_OVER_CL22(bp, params->port,
1289                               params->phy_addr,
1290                               MDIO_REG_BANK_OVER_1G,
1291                               MDIO_OVER_1G_UP1, val);
1292
1293         CL45_WR_OVER_CL22(bp, params->port,
1294                               params->phy_addr,
1295                               MDIO_REG_BANK_OVER_1G,
1296                               MDIO_OVER_1G_UP3, 0);
1297 }
1298
1299 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1300 {
1301         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1302         /* resolve pause mode and advertisement
1303          * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1304
1305         switch (params->req_flow_ctrl) {
1306         case BNX2X_FLOW_CTRL_AUTO:
1307                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1308                         *ieee_fc |=
1309                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1310                 } else {
1311                         *ieee_fc |=
1312                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1313                 }
1314                 break;
1315         case BNX2X_FLOW_CTRL_TX:
1316                 *ieee_fc |=
1317                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1318                 break;
1319
1320         case BNX2X_FLOW_CTRL_RX:
1321         case BNX2X_FLOW_CTRL_BOTH:
1322                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1323                 break;
1324
1325         case BNX2X_FLOW_CTRL_NONE:
1326         default:
1327                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1328                 break;
1329         }
1330 }
1331
1332 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1333                                            u32 ieee_fc)
1334 {
1335         struct bnx2x *bp = params->bp;
1336         /* for AN, we are always publishing full duplex */
1337
1338         CL45_WR_OVER_CL22(bp, params->port,
1339                               params->phy_addr,
1340                               MDIO_REG_BANK_COMBO_IEEE0,
1341                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1342 }
1343
1344 static void bnx2x_restart_autoneg(struct link_params *params)
1345 {
1346         struct bnx2x *bp = params->bp;
1347         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1348         if (SUPPORT_CL73) {
1349                 /* enable and restart clause 73 aneg */
1350                 u16 an_ctrl;
1351
1352                 CL45_RD_OVER_CL22(bp, params->port,
1353                                       params->phy_addr,
1354                                       MDIO_REG_BANK_CL73_IEEEB0,
1355                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1356                                   &an_ctrl);
1357                 CL45_WR_OVER_CL22(bp, params->port,
1358                                       params->phy_addr,
1359                                 MDIO_REG_BANK_CL73_IEEEB0,
1360                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1361                                 (an_ctrl |
1362                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1363                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1364
1365         } else {
1366                 /* Enable and restart BAM/CL37 aneg */
1367                 u16 mii_control;
1368
1369                 CL45_RD_OVER_CL22(bp, params->port,
1370                                       params->phy_addr,
1371                                       MDIO_REG_BANK_COMBO_IEEE0,
1372                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1373                                       &mii_control);
1374                 DP(NETIF_MSG_LINK,
1375                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1376                          mii_control);
1377                 CL45_WR_OVER_CL22(bp, params->port,
1378                                       params->phy_addr,
1379                                       MDIO_REG_BANK_COMBO_IEEE0,
1380                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1381                                       (mii_control |
1382                                 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1383                                 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1384         }
1385 }
1386
1387 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1388                                          struct link_vars *vars)
1389 {
1390         struct bnx2x *bp = params->bp;
1391         u16 control1;
1392
1393         /* in SGMII mode, the unicore is always slave */
1394
1395         CL45_RD_OVER_CL22(bp, params->port,
1396                               params->phy_addr,
1397                               MDIO_REG_BANK_SERDES_DIGITAL,
1398                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1399                       &control1);
1400         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1401         /* set sgmii mode (and not fiber) */
1402         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1403                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1404                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1405         CL45_WR_OVER_CL22(bp, params->port,
1406                               params->phy_addr,
1407                               MDIO_REG_BANK_SERDES_DIGITAL,
1408                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1409                               control1);
1410
1411         /* if forced speed */
1412         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1413                 /* set speed, disable autoneg */
1414                 u16 mii_control;
1415
1416                 CL45_RD_OVER_CL22(bp, params->port,
1417                                       params->phy_addr,
1418                                       MDIO_REG_BANK_COMBO_IEEE0,
1419                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1420                                       &mii_control);
1421                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1422                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1423                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1424
1425                 switch (vars->line_speed) {
1426                 case SPEED_100:
1427                         mii_control |=
1428                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1429                         break;
1430                 case SPEED_1000:
1431                         mii_control |=
1432                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1433                         break;
1434                 case SPEED_10:
1435                         /* there is nothing to set for 10M */
1436                         break;
1437                 default:
1438                         /* invalid speed for SGMII */
1439                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1440                                   vars->line_speed);
1441                         break;
1442                 }
1443
1444                 /* setting the full duplex */
1445                 if (params->req_duplex == DUPLEX_FULL)
1446                         mii_control |=
1447                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1448                 CL45_WR_OVER_CL22(bp, params->port,
1449                                       params->phy_addr,
1450                                       MDIO_REG_BANK_COMBO_IEEE0,
1451                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1452                                       mii_control);
1453
1454         } else { /* AN mode */
1455                 /* enable and restart AN */
1456                 bnx2x_restart_autoneg(params);
1457         }
1458 }
1459
1460
1461 /*
1462  * link management
1463  */
1464
1465 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1466 {                                               /*  LD      LP   */
1467         switch (pause_result) {                 /* ASYM P ASYM P */
1468         case 0xb:                               /*   1  0   1  1 */
1469                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1470                 break;
1471
1472         case 0xe:                               /*   1  1   1  0 */
1473                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1474                 break;
1475
1476         case 0x5:                               /*   0  1   0  1 */
1477         case 0x7:                               /*   0  1   1  1 */
1478         case 0xd:                               /*   1  1   0  1 */
1479         case 0xf:                               /*   1  1   1  1 */
1480                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1481                 break;
1482
1483         default:
1484                 break;
1485         }
1486 }
1487
1488 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1489                                   struct link_vars *vars)
1490 {
1491         struct bnx2x *bp = params->bp;
1492         u8 ext_phy_addr;
1493         u16 ld_pause;   /* local */
1494         u16 lp_pause;   /* link partner */
1495         u16 an_complete; /* AN complete */
1496         u16 pause_result;
1497         u8 ret = 0;
1498         u32 ext_phy_type;
1499         u8 port = params->port;
1500         ext_phy_addr = ((params->ext_phy_config &
1501                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1502                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1503
1504         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1505         /* read twice */
1506
1507         bnx2x_cl45_read(bp, port,
1508                       ext_phy_type,
1509                       ext_phy_addr,
1510                       MDIO_AN_DEVAD,
1511                       MDIO_AN_REG_STATUS, &an_complete);
1512         bnx2x_cl45_read(bp, port,
1513                       ext_phy_type,
1514                       ext_phy_addr,
1515                       MDIO_AN_DEVAD,
1516                       MDIO_AN_REG_STATUS, &an_complete);
1517
1518         if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1519                 ret = 1;
1520                 bnx2x_cl45_read(bp, port,
1521                               ext_phy_type,
1522                               ext_phy_addr,
1523                               MDIO_AN_DEVAD,
1524                               MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1525                 bnx2x_cl45_read(bp, port,
1526                               ext_phy_type,
1527                               ext_phy_addr,
1528                               MDIO_AN_DEVAD,
1529                               MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1530                 pause_result = (ld_pause &
1531                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1532                 pause_result |= (lp_pause &
1533                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1534                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1535                    pause_result);
1536                 bnx2x_pause_resolve(vars, pause_result);
1537                 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1538                      ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1539                         bnx2x_cl45_read(bp, port,
1540                                       ext_phy_type,
1541                                       ext_phy_addr,
1542                                       MDIO_AN_DEVAD,
1543                                       MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1544
1545                         bnx2x_cl45_read(bp, port,
1546                                       ext_phy_type,
1547                                       ext_phy_addr,
1548                                       MDIO_AN_DEVAD,
1549                                       MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1550                         pause_result = (ld_pause &
1551                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1552                         pause_result |= (lp_pause &
1553                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1554
1555                         bnx2x_pause_resolve(vars, pause_result);
1556                         DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1557                                  pause_result);
1558                 }
1559         }
1560         return ret;
1561 }
1562
1563
1564 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1565                                   struct link_vars *vars,
1566                                   u32 gp_status)
1567 {
1568         struct bnx2x *bp = params->bp;
1569         u16 ld_pause;   /* local driver */
1570         u16 lp_pause;   /* link partner */
1571         u16 pause_result;
1572
1573         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1574
1575         /* resolve from gp_status in case of AN complete and not sgmii */
1576         if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1577             (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1578             (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1579             (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1580              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1581                 CL45_RD_OVER_CL22(bp, params->port,
1582                                       params->phy_addr,
1583                                       MDIO_REG_BANK_COMBO_IEEE0,
1584                                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1585                                       &ld_pause);
1586                 CL45_RD_OVER_CL22(bp, params->port,
1587                                       params->phy_addr,
1588                         MDIO_REG_BANK_COMBO_IEEE0,
1589                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1590                         &lp_pause);
1591                 pause_result = (ld_pause &
1592                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1593                 pause_result |= (lp_pause &
1594                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1595                 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1596                 bnx2x_pause_resolve(vars, pause_result);
1597         } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1598                    (bnx2x_ext_phy_resove_fc(params, vars))) {
1599                 return;
1600         } else {
1601                 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1602                         vars->flow_ctrl = params->req_fc_auto_adv;
1603                 else
1604                         vars->flow_ctrl = params->req_flow_ctrl;
1605         }
1606         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1607 }
1608
1609
1610 static u8 bnx2x_link_settings_status(struct link_params *params,
1611                                       struct link_vars *vars,
1612                                       u32 gp_status)
1613 {
1614         struct bnx2x *bp = params->bp;
1615         u16 new_line_speed;
1616         u8 rc = 0;
1617         vars->link_status = 0;
1618
1619         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1620                 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1621                          gp_status);
1622
1623                 vars->phy_link_up = 1;
1624                 vars->link_status |= LINK_STATUS_LINK_UP;
1625
1626                 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1627                         vars->duplex = DUPLEX_FULL;
1628                 else
1629                         vars->duplex = DUPLEX_HALF;
1630
1631                 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1632
1633                 switch (gp_status & GP_STATUS_SPEED_MASK) {
1634                 case GP_STATUS_10M:
1635                         new_line_speed = SPEED_10;
1636                         if (vars->duplex == DUPLEX_FULL)
1637                                 vars->link_status |= LINK_10TFD;
1638                         else
1639                                 vars->link_status |= LINK_10THD;
1640                         break;
1641
1642                 case GP_STATUS_100M:
1643                         new_line_speed = SPEED_100;
1644                         if (vars->duplex == DUPLEX_FULL)
1645                                 vars->link_status |= LINK_100TXFD;
1646                         else
1647                                 vars->link_status |= LINK_100TXHD;
1648                         break;
1649
1650                 case GP_STATUS_1G:
1651                 case GP_STATUS_1G_KX:
1652                         new_line_speed = SPEED_1000;
1653                         if (vars->duplex == DUPLEX_FULL)
1654                                 vars->link_status |= LINK_1000TFD;
1655                         else
1656                                 vars->link_status |= LINK_1000THD;
1657                         break;
1658
1659                 case GP_STATUS_2_5G:
1660                         new_line_speed = SPEED_2500;
1661                         if (vars->duplex == DUPLEX_FULL)
1662                                 vars->link_status |= LINK_2500TFD;
1663                         else
1664                                 vars->link_status |= LINK_2500THD;
1665                         break;
1666
1667                 case GP_STATUS_5G:
1668                 case GP_STATUS_6G:
1669                         DP(NETIF_MSG_LINK,
1670                                  "link speed unsupported  gp_status 0x%x\n",
1671                                   gp_status);
1672                         return -EINVAL;
1673                         break;
1674                 case GP_STATUS_10G_KX4:
1675                 case GP_STATUS_10G_HIG:
1676                 case GP_STATUS_10G_CX4:
1677                         new_line_speed = SPEED_10000;
1678                         vars->link_status |= LINK_10GTFD;
1679                         break;
1680
1681                 case GP_STATUS_12G_HIG:
1682                         new_line_speed = SPEED_12000;
1683                         vars->link_status |= LINK_12GTFD;
1684                         break;
1685
1686                 case GP_STATUS_12_5G:
1687                         new_line_speed = SPEED_12500;
1688                         vars->link_status |= LINK_12_5GTFD;
1689                         break;
1690
1691                 case GP_STATUS_13G:
1692                         new_line_speed = SPEED_13000;
1693                         vars->link_status |= LINK_13GTFD;
1694                         break;
1695
1696                 case GP_STATUS_15G:
1697                         new_line_speed = SPEED_15000;
1698                         vars->link_status |= LINK_15GTFD;
1699                         break;
1700
1701                 case GP_STATUS_16G:
1702                         new_line_speed = SPEED_16000;
1703                         vars->link_status |= LINK_16GTFD;
1704                         break;
1705
1706                 default:
1707                         DP(NETIF_MSG_LINK,
1708                                   "link speed unsupported gp_status 0x%x\n",
1709                                   gp_status);
1710                 return -EINVAL;
1711                         break;
1712                 }
1713
1714                 /* Upon link speed change set the NIG into drain mode.
1715                 Comes to deals with possible FIFO glitch due to clk change
1716                 when speed is decreased without link down indicator */
1717                 if (new_line_speed != vars->line_speed) {
1718                         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1719                                     + params->port*4, 0);
1720                         msleep(1);
1721                 }
1722                 vars->line_speed = new_line_speed;
1723                 vars->link_status |= LINK_STATUS_SERDES_LINK;
1724
1725                 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1726                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1727                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1728                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1729                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
1730                         vars->autoneg = AUTO_NEG_ENABLED;
1731
1732                         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1733                                 vars->autoneg |= AUTO_NEG_COMPLETE;
1734                                 vars->link_status |=
1735                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1736                         }
1737
1738                         vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1739                         vars->link_status |=
1740                                 LINK_STATUS_PARALLEL_DETECTION_USED;
1741
1742                 }
1743                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1744                         vars->link_status |=
1745                                 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1746
1747                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1748                         vars->link_status |=
1749                                 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1750
1751         } else { /* link_down */
1752                 DP(NETIF_MSG_LINK, "phy link down\n");
1753
1754                 vars->phy_link_up = 0;
1755
1756                 vars->duplex = DUPLEX_FULL;
1757                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1758                 vars->autoneg = AUTO_NEG_DISABLED;
1759                 vars->mac_type = MAC_TYPE_NONE;
1760         }
1761
1762         DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
1763                  gp_status, vars->phy_link_up, vars->line_speed);
1764         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
1765                  " autoneg 0x%x\n",
1766                  vars->duplex,
1767                  vars->flow_ctrl, vars->autoneg);
1768         DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1769
1770         return rc;
1771 }
1772
1773 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1774 {
1775         struct bnx2x *bp = params->bp;
1776         u16 lp_up2;
1777         u16 tx_driver;
1778
1779         /* read precomp */
1780
1781         CL45_RD_OVER_CL22(bp, params->port,
1782                               params->phy_addr,
1783                               MDIO_REG_BANK_OVER_1G,
1784                               MDIO_OVER_1G_LP_UP2, &lp_up2);
1785
1786         CL45_RD_OVER_CL22(bp, params->port,
1787                               params->phy_addr,
1788                               MDIO_REG_BANK_TX0,
1789                               MDIO_TX0_TX_DRIVER, &tx_driver);
1790
1791         /* bits [10:7] at lp_up2, positioned at [15:12] */
1792         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1793                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1794                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1795
1796         if ((lp_up2 != 0) &&
1797             (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1798                 /* replace tx_driver bits [15:12] */
1799                 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1800                 tx_driver |= lp_up2;
1801                 CL45_WR_OVER_CL22(bp, params->port,
1802                                       params->phy_addr,
1803                                       MDIO_REG_BANK_TX0,
1804                                       MDIO_TX0_TX_DRIVER, tx_driver);
1805         }
1806 }
1807
1808 static u8 bnx2x_emac_program(struct link_params *params,
1809                            u32 line_speed, u32 duplex)
1810 {
1811         struct bnx2x *bp = params->bp;
1812         u8 port = params->port;
1813         u16 mode = 0;
1814
1815         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1816         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1817                      EMAC_REG_EMAC_MODE,
1818                      (EMAC_MODE_25G_MODE |
1819                      EMAC_MODE_PORT_MII_10M |
1820                      EMAC_MODE_HALF_DUPLEX));
1821         switch (line_speed) {
1822         case SPEED_10:
1823                 mode |= EMAC_MODE_PORT_MII_10M;
1824                 break;
1825
1826         case SPEED_100:
1827                 mode |= EMAC_MODE_PORT_MII;
1828                 break;
1829
1830         case SPEED_1000:
1831                 mode |= EMAC_MODE_PORT_GMII;
1832                 break;
1833
1834         case SPEED_2500:
1835                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1836                 break;
1837
1838         default:
1839                 /* 10G not valid for EMAC */
1840                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1841                 return -EINVAL;
1842         }
1843
1844         if (duplex == DUPLEX_HALF)
1845                 mode |= EMAC_MODE_HALF_DUPLEX;
1846         bnx2x_bits_en(bp,
1847                     GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1848                     mode);
1849
1850         bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1851                     line_speed, params->hw_led_mode, params->chip_id);
1852         return 0;
1853 }
1854
1855 /*****************************************************************************/
1856 /*                           External Phy section                            */
1857 /*****************************************************************************/
1858 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1859 {
1860         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1861                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1862         msleep(1);
1863         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1864                       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1865 }
1866
1867 static void bnx2x_ext_phy_reset(struct link_params *params,
1868                               struct link_vars   *vars)
1869 {
1870         struct bnx2x *bp = params->bp;
1871         u32 ext_phy_type;
1872         u8 ext_phy_addr = ((params->ext_phy_config &
1873                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1874                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1875         DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1876         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1877         /* The PHY reset is controled by GPIO 1
1878          * Give it 1ms of reset pulse
1879          */
1880         if (vars->phy_flags & PHY_XGXS_FLAG) {
1881
1882                 switch (ext_phy_type) {
1883                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1884                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
1885                         break;
1886
1887                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1888                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1889                         DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1890
1891                         /* Restore normal power mode*/
1892                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1893                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1894                                           params->port);
1895
1896                         /* HW reset */
1897                         bnx2x_hw_reset(bp, params->port);
1898
1899                         bnx2x_cl45_write(bp, params->port,
1900                                        ext_phy_type,
1901                                        ext_phy_addr,
1902                                        MDIO_PMA_DEVAD,
1903                                        MDIO_PMA_REG_CTRL, 0xa040);
1904                         break;
1905                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1906                         /* Unset Low Power Mode and SW reset */
1907                         /* Restore normal power mode*/
1908                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1909                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1910                                           params->port);
1911
1912                         DP(NETIF_MSG_LINK, "XGXS 8072\n");
1913                         bnx2x_cl45_write(bp, params->port,
1914                                        ext_phy_type,
1915                                        ext_phy_addr,
1916                                        MDIO_PMA_DEVAD,
1917                                        MDIO_PMA_REG_CTRL,
1918                                        1<<15);
1919                         break;
1920                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1921                         {
1922                         u16 emac_base;
1923                         emac_base = (params->port) ? GRCBASE_EMAC0 :
1924                                         GRCBASE_EMAC1;
1925
1926                         /* Restore normal power mode*/
1927                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1928                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1929                                           params->port);
1930
1931                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1932                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1933                                           params->port);
1934
1935                         DP(NETIF_MSG_LINK, "XGXS 8073\n");
1936                         }
1937                         break;
1938
1939                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1940                         DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1941
1942                         /* Restore normal power mode*/
1943                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1944                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1945                                           params->port);
1946
1947                         /* HW reset */
1948                         bnx2x_hw_reset(bp, params->port);
1949
1950                         break;
1951
1952                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1953                         DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1954                         break;
1955
1956                 default:
1957                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1958                            params->ext_phy_config);
1959                         break;
1960                 }
1961
1962         } else { /* SerDes */
1963                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1964                 switch (ext_phy_type) {
1965                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1966                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
1967                         break;
1968
1969                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1970                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
1971                         bnx2x_hw_reset(bp, params->port);
1972                         break;
1973
1974                 default:
1975                         DP(NETIF_MSG_LINK,
1976                                  "BAD SerDes ext_phy_config 0x%x\n",
1977                                  params->ext_phy_config);
1978                         break;
1979                 }
1980         }
1981 }
1982
1983 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
1984 {
1985         struct bnx2x *bp = params->bp;
1986         u8 port = params->port;
1987         u8 ext_phy_addr = ((params->ext_phy_config &
1988                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1989                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1990         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1991         u16 fw_ver1, fw_ver2;
1992
1993         /* Need to wait 200ms after reset */
1994         msleep(200);
1995         /* Boot port from external ROM
1996          * Set ser_boot_ctl bit in the MISC_CTRL1 register
1997          */
1998         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1999                             MDIO_PMA_DEVAD,
2000                             MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2001
2002         /* Reset internal microprocessor */
2003         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2004                           MDIO_PMA_DEVAD,
2005                           MDIO_PMA_REG_GEN_CTRL,
2006                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2007         /* set micro reset = 0 */
2008         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2009                             MDIO_PMA_DEVAD,
2010                             MDIO_PMA_REG_GEN_CTRL,
2011                             MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2012         /* Reset internal microprocessor */
2013         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2014                           MDIO_PMA_DEVAD,
2015                           MDIO_PMA_REG_GEN_CTRL,
2016                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2017         /* wait for 100ms for code download via SPI port */
2018         msleep(100);
2019
2020         /* Clear ser_boot_ctl bit */
2021         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2022                             MDIO_PMA_DEVAD,
2023                             MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2024         /* Wait 100ms */
2025         msleep(100);
2026
2027         /* Print the PHY FW version */
2028         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2029                             MDIO_PMA_DEVAD,
2030                             MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2031         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2032                             MDIO_PMA_DEVAD,
2033                             MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2034         DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2035 }
2036
2037 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2038 {
2039         /* This is only required for 8073A1, version 102 only */
2040
2041         struct bnx2x *bp = params->bp;
2042         u8 ext_phy_addr = ((params->ext_phy_config &
2043                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2044                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2045         u16 val;
2046
2047         /* Read 8073 HW revision*/
2048         bnx2x_cl45_read(bp, params->port,
2049                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2050                       ext_phy_addr,
2051                       MDIO_PMA_DEVAD,
2052                       0xc801, &val);
2053
2054         if (val != 1) {
2055                 /* No need to workaround in 8073 A1 */
2056                 return 0;
2057         }
2058
2059         bnx2x_cl45_read(bp, params->port,
2060                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2061                       ext_phy_addr,
2062                       MDIO_PMA_DEVAD,
2063                       MDIO_PMA_REG_ROM_VER2, &val);
2064
2065         /* SNR should be applied only for version 0x102 */
2066         if (val != 0x102)
2067                 return 0;
2068
2069         return 1;
2070 }
2071
2072 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2073 {
2074         struct bnx2x *bp = params->bp;
2075         u8 ext_phy_addr = ((params->ext_phy_config &
2076                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2077                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2078         u16 val, cnt, cnt1 ;
2079
2080         bnx2x_cl45_read(bp, params->port,
2081                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2082                       ext_phy_addr,
2083                       MDIO_PMA_DEVAD,
2084                       0xc801, &val);
2085
2086         if (val > 0) {
2087                 /* No need to workaround in 8073 A1 */
2088                 return 0;
2089         }
2090         /* XAUI workaround in 8073 A0: */
2091
2092         /* After loading the boot ROM and restarting Autoneg,
2093         poll Dev1, Reg $C820: */
2094
2095         for (cnt = 0; cnt < 1000; cnt++) {
2096                 bnx2x_cl45_read(bp, params->port,
2097                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2098                               ext_phy_addr,
2099                               MDIO_PMA_DEVAD,
2100                               0xc820, &val);
2101                   /* If bit [14] = 0 or bit [13] = 0, continue on with
2102                    system initialization (XAUI work-around not required,
2103                     as these bits indicate 2.5G or 1G link up). */
2104                 if (!(val & (1<<14)) || !(val & (1<<13))) {
2105                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2106                         return 0;
2107                 } else if (!(val & (1<<15))) {
2108                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2109                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2110                           it's MSB (bit 15) goes to 1 (indicating that the
2111                           XAUI workaround has completed),
2112                           then continue on with system initialization.*/
2113                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2114                                 bnx2x_cl45_read(bp, params->port,
2115                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2116                                         ext_phy_addr,
2117                                         MDIO_PMA_DEVAD,
2118                                         0xc841, &val);
2119                                 if (val & (1<<15)) {
2120                                         DP(NETIF_MSG_LINK,
2121                                           "XAUI workaround has completed\n");
2122                                         return 0;
2123                                  }
2124                                  msleep(3);
2125                         }
2126                         break;
2127                 }
2128                 msleep(3);
2129         }
2130         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2131         return -EINVAL;
2132
2133 }
2134
2135 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2136                                           u8 ext_phy_addr)
2137 {
2138         u16 fw_ver1, fw_ver2;
2139         /* Boot port from external ROM  */
2140         /* EDC grst */
2141         bnx2x_cl45_write(bp, port,
2142                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2143                        ext_phy_addr,
2144                        MDIO_PMA_DEVAD,
2145                        MDIO_PMA_REG_GEN_CTRL,
2146                        0x0001);
2147
2148         /* ucode reboot and rst */
2149         bnx2x_cl45_write(bp, port,
2150                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2151                        ext_phy_addr,
2152                        MDIO_PMA_DEVAD,
2153                        MDIO_PMA_REG_GEN_CTRL,
2154                        0x008c);
2155
2156         bnx2x_cl45_write(bp, port,
2157                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2158                        ext_phy_addr,
2159                        MDIO_PMA_DEVAD,
2160                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2161
2162         /* Reset internal microprocessor */
2163         bnx2x_cl45_write(bp, port,
2164                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2165                        ext_phy_addr,
2166                        MDIO_PMA_DEVAD,
2167                        MDIO_PMA_REG_GEN_CTRL,
2168                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2169
2170         /* Release srst bit */
2171         bnx2x_cl45_write(bp, port,
2172                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2173                        ext_phy_addr,
2174                        MDIO_PMA_DEVAD,
2175                        MDIO_PMA_REG_GEN_CTRL,
2176                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2177
2178         /* wait for 100ms for code download via SPI port */
2179         msleep(100);
2180
2181         /* Clear ser_boot_ctl bit */
2182         bnx2x_cl45_write(bp, port,
2183                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2184                        ext_phy_addr,
2185                        MDIO_PMA_DEVAD,
2186                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2187
2188         bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2189                       ext_phy_addr,
2190                       MDIO_PMA_DEVAD,
2191                       MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2192         bnx2x_cl45_read(bp, port,
2193                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2194                       ext_phy_addr,
2195                       MDIO_PMA_DEVAD,
2196                       MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2197         DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2198
2199 }
2200
2201 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2202 {
2203         struct bnx2x *bp = params->bp;
2204         u8 port = params->port;
2205         u8 ext_phy_addr = ((params->ext_phy_config &
2206                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2207                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2208         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2209
2210         /* Force KR or KX */
2211         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2212                        MDIO_PMA_DEVAD,
2213                        MDIO_PMA_REG_CTRL,
2214                        0x2040);
2215         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2216                        MDIO_PMA_DEVAD,
2217                        MDIO_PMA_REG_10G_CTRL2,
2218                        0x000b);
2219         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2220                        MDIO_PMA_DEVAD,
2221                        MDIO_PMA_REG_BCM_CTRL,
2222                        0x0000);
2223         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2224                        MDIO_AN_DEVAD,
2225                        MDIO_AN_REG_CTRL,
2226                        0x0000);
2227 }
2228 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2229 {
2230         struct bnx2x *bp = params->bp;
2231         u8 port = params->port;
2232         u16 val;
2233         u8 ext_phy_addr = ((params->ext_phy_config &
2234                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2235                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2236         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2237
2238         bnx2x_cl45_read(bp, params->port,
2239                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2240                       ext_phy_addr,
2241                       MDIO_PMA_DEVAD,
2242                       0xc801, &val);
2243
2244         if (val == 0) {
2245                 /* Mustn't set low power mode in 8073 A0 */
2246                 return;
2247         }
2248
2249         /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2250         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2251                        MDIO_XS_DEVAD,
2252                        MDIO_XS_PLL_SEQUENCER, &val);
2253         val &= ~(1<<13);
2254         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2255                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2256
2257         /* PLL controls */
2258         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2259                        MDIO_XS_DEVAD, 0x805E, 0x1077);
2260         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2261                        MDIO_XS_DEVAD, 0x805D, 0x0000);
2262         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2263                        MDIO_XS_DEVAD, 0x805C, 0x030B);
2264         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2265                        MDIO_XS_DEVAD, 0x805B, 0x1240);
2266         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2267                        MDIO_XS_DEVAD, 0x805A, 0x2490);
2268
2269         /* Tx Controls */
2270         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2271                        MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2272         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2273                        MDIO_XS_DEVAD, 0x80A6, 0x9041);
2274         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2275                        MDIO_XS_DEVAD, 0x80A5, 0x4640);
2276
2277         /* Rx Controls */
2278         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2279                        MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2280         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2281                        MDIO_XS_DEVAD, 0x80FD, 0x9249);
2282         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2283                        MDIO_XS_DEVAD, 0x80FC, 0x2015);
2284
2285         /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
2286         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2287                        MDIO_XS_DEVAD,
2288                        MDIO_XS_PLL_SEQUENCER, &val);
2289         val |= (1<<13);
2290         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2291                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2292 }
2293
2294 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2295                                   struct link_vars *vars)
2296 {
2297
2298         struct bnx2x *bp = params->bp;
2299         u16 cl37_val;
2300         u8 ext_phy_addr = ((params->ext_phy_config &
2301                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2302                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2303         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2304
2305         bnx2x_cl45_read(bp, params->port,
2306                       ext_phy_type,
2307                       ext_phy_addr,
2308                       MDIO_AN_DEVAD,
2309                       MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2310
2311         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2312         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2313
2314         if ((vars->ieee_fc &
2315             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2316             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2317                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2318         }
2319         if ((vars->ieee_fc &
2320             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2321             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2322                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2323         }
2324         if ((vars->ieee_fc &
2325             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2326             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2327                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2328         }
2329         DP(NETIF_MSG_LINK,
2330                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2331
2332         bnx2x_cl45_write(bp, params->port,
2333                        ext_phy_type,
2334                        ext_phy_addr,
2335                        MDIO_AN_DEVAD,
2336                        MDIO_AN_REG_CL37_FC_LD, cl37_val);
2337         msleep(500);
2338 }
2339
2340 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2341                                   struct link_vars *vars)
2342 {
2343         struct bnx2x *bp = params->bp;
2344         u16 val;
2345         u8 ext_phy_addr = ((params->ext_phy_config &
2346                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2347                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2348         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2349
2350         /* read modify write pause advertizing */
2351         bnx2x_cl45_read(bp, params->port,
2352                       ext_phy_type,
2353                       ext_phy_addr,
2354                       MDIO_AN_DEVAD,
2355                       MDIO_AN_REG_ADV_PAUSE, &val);
2356
2357         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2358
2359         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2360
2361         if ((vars->ieee_fc &
2362             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2363             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2364                 val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2365         }
2366         if ((vars->ieee_fc &
2367             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2368             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2369                 val |=
2370                  MDIO_AN_REG_ADV_PAUSE_PAUSE;
2371         }
2372         DP(NETIF_MSG_LINK,
2373                  "Ext phy AN advertize 0x%x\n", val);
2374         bnx2x_cl45_write(bp, params->port,
2375                        ext_phy_type,
2376                        ext_phy_addr,
2377                        MDIO_AN_DEVAD,
2378                        MDIO_AN_REG_ADV_PAUSE, val);
2379 }
2380
2381
2382 static void bnx2x_init_internal_phy(struct link_params *params,
2383                                 struct link_vars *vars)
2384 {
2385         struct bnx2x *bp = params->bp;
2386         u8 port = params->port;
2387         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2388                 u16 bank, rx_eq;
2389
2390                 rx_eq = ((params->serdes_config &
2391                           PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2392                          PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2393
2394                 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2395                 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2396                       bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2397                         CL45_WR_OVER_CL22(bp, port,
2398                                               params->phy_addr,
2399                                               bank ,
2400                                               MDIO_RX0_RX_EQ_BOOST,
2401                                               ((rx_eq &
2402                                 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2403                                 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2404                 }
2405
2406                 /* forced speed requested? */
2407                 if (vars->line_speed != SPEED_AUTO_NEG) {
2408                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2409
2410                         /* disable autoneg */
2411                         bnx2x_set_autoneg(params, vars);
2412
2413                         /* program speed and duplex */
2414                         bnx2x_program_serdes(params, vars);
2415
2416                 } else { /* AN_mode */
2417                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2418
2419                         /* AN enabled */
2420                         bnx2x_set_brcm_cl37_advertisment(params);
2421
2422                         /* program duplex & pause advertisement (for aneg) */
2423                         bnx2x_set_ieee_aneg_advertisment(params,
2424                                                        vars->ieee_fc);
2425
2426                         /* enable autoneg */
2427                         bnx2x_set_autoneg(params, vars);
2428
2429                         /* enable and restart AN */
2430                         bnx2x_restart_autoneg(params);
2431                 }
2432
2433         } else { /* SGMII mode */
2434                 DP(NETIF_MSG_LINK, "SGMII\n");
2435
2436                 bnx2x_initialize_sgmii_process(params, vars);
2437         }
2438 }
2439
2440 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2441 {
2442         struct bnx2x *bp = params->bp;
2443         u32 ext_phy_type;
2444         u8 ext_phy_addr;
2445         u16 cnt;
2446         u16 ctrl = 0;
2447         u16 val = 0;
2448         u8 rc = 0;
2449         if (vars->phy_flags & PHY_XGXS_FLAG) {
2450                 ext_phy_addr = ((params->ext_phy_config &
2451                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2452                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2453
2454                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2455                 /* Make sure that the soft reset is off (expect for the 8072:
2456                  * due to the lock, it will be done inside the specific
2457                  * handling)
2458                  */
2459                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2460                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2461                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2462                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2463                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2464                         /* Wait for soft reset to get cleared upto 1 sec */
2465                         for (cnt = 0; cnt < 1000; cnt++) {
2466                                 bnx2x_cl45_read(bp, params->port,
2467                                               ext_phy_type,
2468                                               ext_phy_addr,
2469                                               MDIO_PMA_DEVAD,
2470                                               MDIO_PMA_REG_CTRL, &ctrl);
2471                                 if (!(ctrl & (1<<15)))
2472                                         break;
2473                                 msleep(1);
2474                         }
2475                         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2476                                  ctrl, cnt);
2477                 }
2478
2479                 switch (ext_phy_type) {
2480                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2481                         break;
2482
2483                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2484                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
2485
2486                         bnx2x_cl45_write(bp, params->port,
2487                                        ext_phy_type,
2488                                        ext_phy_addr,
2489                                        MDIO_PMA_DEVAD,
2490                                        MDIO_PMA_REG_MISC_CTRL,
2491                                        0x8288);
2492                         bnx2x_cl45_write(bp, params->port,
2493                                        ext_phy_type,
2494                                        ext_phy_addr,
2495                                        MDIO_PMA_DEVAD,
2496                                        MDIO_PMA_REG_PHY_IDENTIFIER,
2497                                        0x7fbf);
2498                         bnx2x_cl45_write(bp, params->port,
2499                                        ext_phy_type,
2500                                        ext_phy_addr,
2501                                        MDIO_PMA_DEVAD,
2502                                        MDIO_PMA_REG_CMU_PLL_BYPASS,
2503                                        0x0100);
2504                         bnx2x_cl45_write(bp, params->port,
2505                                        ext_phy_type,
2506                                        ext_phy_addr,
2507                                        MDIO_WIS_DEVAD,
2508                                        MDIO_WIS_REG_LASI_CNTL, 0x1);
2509                         break;
2510
2511                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2512                         DP(NETIF_MSG_LINK, "XGXS 8706\n");
2513
2514                         msleep(10);
2515                         /* Force speed */
2516                         /* First enable LASI */
2517                         bnx2x_cl45_write(bp, params->port,
2518                                        ext_phy_type,
2519                                        ext_phy_addr,
2520                                        MDIO_PMA_DEVAD,
2521                                        MDIO_PMA_REG_RX_ALARM_CTRL,
2522                                        0x0400);
2523                         bnx2x_cl45_write(bp, params->port,
2524                                        ext_phy_type,
2525                                        ext_phy_addr,
2526                                        MDIO_PMA_DEVAD,
2527                                        MDIO_PMA_REG_LASI_CTRL, 0x0004);
2528
2529                         if (params->req_line_speed == SPEED_10000) {
2530                                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
2531
2532                                 bnx2x_cl45_write(bp, params->port,
2533                                                ext_phy_type,
2534                                                ext_phy_addr,
2535                                                MDIO_PMA_DEVAD,
2536                                                MDIO_PMA_REG_DIGITAL_CTRL,
2537                                                0x400);
2538                         } else {
2539                                 /* Force 1Gbps using autoneg with 1G
2540                                 advertisment */
2541
2542                                 /* Allow CL37 through CL73 */
2543                                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
2544                                 bnx2x_cl45_write(bp, params->port,
2545                                                ext_phy_type,
2546                                                ext_phy_addr,
2547                                                MDIO_AN_DEVAD,
2548                                                MDIO_AN_REG_CL37_CL73,
2549                                                0x040c);
2550
2551                                 /* Enable Full-Duplex advertisment on CL37 */
2552                                 bnx2x_cl45_write(bp, params->port,
2553                                                ext_phy_type,
2554                                                ext_phy_addr,
2555                                                MDIO_AN_DEVAD,
2556                                                MDIO_AN_REG_CL37_FC_LP,
2557                                                0x0020);
2558                                 /* Enable CL37 AN */
2559                                 bnx2x_cl45_write(bp, params->port,
2560                                                ext_phy_type,
2561                                                ext_phy_addr,
2562                                                MDIO_AN_DEVAD,
2563                                                MDIO_AN_REG_CL37_AN,
2564                                                0x1000);
2565                                 /* 1G support */
2566                                 bnx2x_cl45_write(bp, params->port,
2567                                                ext_phy_type,
2568                                                ext_phy_addr,
2569                                                MDIO_AN_DEVAD,
2570                                                MDIO_AN_REG_ADV, (1<<5));
2571
2572                                 /* Enable clause 73 AN */
2573                                 bnx2x_cl45_write(bp, params->port,
2574                                                ext_phy_type,
2575                                                ext_phy_addr,
2576                                                MDIO_AN_DEVAD,
2577                                                MDIO_AN_REG_CTRL,
2578                                                0x1200);
2579
2580                         }
2581
2582                         break;
2583
2584                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2585                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2586                 {
2587                         u16 tmp1;
2588                         u16 rx_alarm_ctrl_val;
2589                         u16 lasi_ctrl_val;
2590                         if (ext_phy_type ==
2591                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2592                                 rx_alarm_ctrl_val = 0x400;
2593                                 lasi_ctrl_val = 0x0004;
2594                         } else {
2595                                 rx_alarm_ctrl_val = (1<<2);
2596                                 lasi_ctrl_val = 0x0004;
2597                         }
2598
2599                         /* enable LASI */
2600                         bnx2x_cl45_write(bp, params->port,
2601                                    ext_phy_type,
2602                                    ext_phy_addr,
2603                                    MDIO_PMA_DEVAD,
2604                                    MDIO_PMA_REG_RX_ALARM_CTRL,
2605                                    rx_alarm_ctrl_val);
2606
2607                         bnx2x_cl45_write(bp, params->port,
2608                                        ext_phy_type,
2609                                        ext_phy_addr,
2610                                        MDIO_PMA_DEVAD,
2611                                        MDIO_PMA_REG_LASI_CTRL,
2612                                        lasi_ctrl_val);
2613
2614                         bnx2x_8073_set_pause_cl37(params, vars);
2615
2616                         if (ext_phy_type ==
2617                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
2618                                 bnx2x_bcm8072_external_rom_boot(params);
2619                         } else {
2620
2621                                 /* In case of 8073 with long xaui lines,
2622                                 don't set the 8073 xaui low power*/
2623                                 bnx2x_bcm8073_set_xaui_low_power_mode(params);
2624                         }
2625
2626                         bnx2x_cl45_read(bp, params->port,
2627                                       ext_phy_type,
2628                                       ext_phy_addr,
2629                                       MDIO_PMA_DEVAD,
2630                                       0xca13,
2631                                       &tmp1);
2632
2633                         bnx2x_cl45_read(bp, params->port,
2634                                       ext_phy_type,
2635                                       ext_phy_addr,
2636                                       MDIO_PMA_DEVAD,
2637                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
2638
2639                         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
2640                                              "0x%x\n", tmp1);
2641
2642                         /* If this is forced speed, set to KR or KX
2643                          * (all other are not supported)
2644                          */
2645                         if (params->loopback_mode == LOOPBACK_EXT) {
2646                                 bnx2x_bcm807x_force_10G(params);
2647                                 DP(NETIF_MSG_LINK,
2648                                         "Forced speed 10G on 807X\n");
2649                                 break;
2650                         } else {
2651                                 bnx2x_cl45_write(bp, params->port,
2652                                                ext_phy_type, ext_phy_addr,
2653                                                MDIO_PMA_DEVAD,
2654                                                MDIO_PMA_REG_BCM_CTRL,
2655                                                0x0002);
2656                         }
2657                         if (params->req_line_speed != SPEED_AUTO_NEG) {
2658                                 if (params->req_line_speed == SPEED_10000) {
2659                                         val = (1<<7);
2660                                 } else if (params->req_line_speed ==
2661                                            SPEED_2500) {
2662                                         val = (1<<5);
2663                                         /* Note that 2.5G works only
2664                                         when used with 1G advertisment */
2665                                 } else
2666                                         val = (1<<5);
2667                         } else {
2668
2669                                 val = 0;
2670                                 if (params->speed_cap_mask &
2671                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2672                                         val |= (1<<7);
2673
2674                                 /* Note that 2.5G works only when
2675                                 used with 1G advertisment */
2676                                 if (params->speed_cap_mask &
2677                                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
2678                                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
2679                                         val |= (1<<5);
2680                                 DP(NETIF_MSG_LINK,
2681                                          "807x autoneg val = 0x%x\n", val);
2682                         }
2683
2684                         bnx2x_cl45_write(bp, params->port,
2685                                        ext_phy_type,
2686                                        ext_phy_addr,
2687                                        MDIO_AN_DEVAD,
2688                                        MDIO_AN_REG_ADV, val);
2689
2690                         if (ext_phy_type ==
2691                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2692
2693                                 bnx2x_cl45_read(bp, params->port,
2694                                               ext_phy_type,
2695                                               ext_phy_addr,
2696                                               MDIO_AN_DEVAD,
2697                                               0x8329, &tmp1);
2698
2699                                 if (((params->speed_cap_mask &
2700                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
2701                                      (params->req_line_speed ==
2702                                       SPEED_AUTO_NEG)) ||
2703                                     (params->req_line_speed ==
2704                                      SPEED_2500)) {
2705                                         u16 phy_ver;
2706                                         /* Allow 2.5G for A1 and above */
2707                                         bnx2x_cl45_read(bp, params->port,
2708                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2709                                          ext_phy_addr,
2710                                          MDIO_PMA_DEVAD,
2711                                          0xc801, &phy_ver);
2712                                         DP(NETIF_MSG_LINK, "Add 2.5G\n");
2713                                         if (phy_ver > 0)
2714                                                 tmp1 |= 1;
2715                                         else
2716                                                 tmp1 &= 0xfffe;
2717                                 } else {
2718                                         DP(NETIF_MSG_LINK, "Disable 2.5G\n");
2719                                         tmp1 &= 0xfffe;
2720                                 }
2721
2722                                 bnx2x_cl45_write(bp, params->port,
2723                                                ext_phy_type,
2724                                                ext_phy_addr,
2725                                                MDIO_AN_DEVAD,
2726                                                0x8329, tmp1);
2727                         }
2728
2729                         /* Add support for CL37 (passive mode) II */
2730
2731                         bnx2x_cl45_read(bp, params->port,
2732                                        ext_phy_type,
2733                                        ext_phy_addr,
2734                                        MDIO_AN_DEVAD,
2735                                        MDIO_AN_REG_CL37_FC_LD,
2736                                        &tmp1);
2737
2738                         bnx2x_cl45_write(bp, params->port,
2739                                        ext_phy_type,
2740                                        ext_phy_addr,
2741                                        MDIO_AN_DEVAD,
2742                                        MDIO_AN_REG_CL37_FC_LD, (tmp1 |
2743                                        ((params->req_duplex == DUPLEX_FULL) ?
2744                                        0x20 : 0x40)));
2745
2746                         /* Add support for CL37 (passive mode) III */
2747                         bnx2x_cl45_write(bp, params->port,
2748                                        ext_phy_type,
2749                                        ext_phy_addr,
2750                                        MDIO_AN_DEVAD,
2751                                        MDIO_AN_REG_CL37_AN, 0x1000);
2752
2753                         if (ext_phy_type ==
2754                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2755                                 /* The SNR will improve about 2db by changing
2756                                 BW and FEE main tap. Rest commands are executed
2757                                 after link is up*/
2758                                 /*Change FFE main cursor to 5 in EDC register*/
2759                                 if (bnx2x_8073_is_snr_needed(params))
2760                                         bnx2x_cl45_write(bp, params->port,
2761                                                     ext_phy_type,
2762                                                     ext_phy_addr,
2763                                                     MDIO_PMA_DEVAD,
2764                                                     MDIO_PMA_REG_EDC_FFE_MAIN,
2765                                                     0xFB0C);
2766
2767                                 /* Enable FEC (Forware Error Correction)
2768                                 Request in the AN */
2769                                 bnx2x_cl45_read(bp, params->port,
2770                                               ext_phy_type,
2771                                               ext_phy_addr,
2772                                               MDIO_AN_DEVAD,
2773                                               MDIO_AN_REG_ADV2, &tmp1);
2774
2775                                 tmp1 |= (1<<15);
2776
2777                                 bnx2x_cl45_write(bp, params->port,
2778                                                ext_phy_type,
2779                                                ext_phy_addr,
2780                                                MDIO_AN_DEVAD,
2781                                                MDIO_AN_REG_ADV2, tmp1);
2782
2783                         }
2784
2785                         bnx2x_ext_phy_set_pause(params, vars);
2786
2787                         /* Restart autoneg */
2788                         msleep(500);
2789                         bnx2x_cl45_write(bp, params->port,
2790                                        ext_phy_type,
2791                                        ext_phy_addr,
2792                                        MDIO_AN_DEVAD,
2793                                        MDIO_AN_REG_CTRL, 0x1200);
2794                         DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
2795                            "Advertise 1G=%x, 10G=%x\n",
2796                            ((val & (1<<5)) > 0),
2797                            ((val & (1<<7)) > 0));
2798                         break;
2799                 }
2800                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2801                         DP(NETIF_MSG_LINK,
2802                                 "Setting the SFX7101 LASI indication\n");
2803
2804                         bnx2x_cl45_write(bp, params->port,
2805                                        ext_phy_type,
2806                                        ext_phy_addr,
2807                                        MDIO_PMA_DEVAD,
2808                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
2809                         DP(NETIF_MSG_LINK,
2810                           "Setting the SFX7101 LED to blink on traffic\n");
2811                         bnx2x_cl45_write(bp, params->port,
2812                                        ext_phy_type,
2813                                        ext_phy_addr,
2814                                        MDIO_PMA_DEVAD,
2815                                        MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
2816
2817                         bnx2x_ext_phy_set_pause(params, vars);
2818                         /* Restart autoneg */
2819                         bnx2x_cl45_read(bp, params->port,
2820                                       ext_phy_type,
2821                                       ext_phy_addr,
2822                                       MDIO_AN_DEVAD,
2823                                       MDIO_AN_REG_CTRL, &val);
2824                         val |= 0x200;
2825                         bnx2x_cl45_write(bp, params->port,
2826                                        ext_phy_type,
2827                                        ext_phy_addr,
2828                                        MDIO_AN_DEVAD,
2829                                        MDIO_AN_REG_CTRL, val);
2830                         break;
2831                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2832                         DP(NETIF_MSG_LINK,
2833                                  "XGXS PHY Failure detected 0x%x\n",
2834                                  params->ext_phy_config);
2835                         rc = -EINVAL;
2836                         break;
2837                 default:
2838                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2839                                   params->ext_phy_config);
2840                         rc = -EINVAL;
2841                         break;
2842                 }
2843
2844         } else { /* SerDes */
2845
2846                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2847                 switch (ext_phy_type) {
2848                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2849                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
2850                         break;
2851
2852                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2853                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
2854                         break;
2855
2856                 default:
2857                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2858                            params->ext_phy_config);
2859                         break;
2860                 }
2861         }
2862         return rc;
2863 }
2864
2865
2866 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2867                                  struct link_vars *vars)
2868 {
2869         struct bnx2x *bp = params->bp;
2870         u32 ext_phy_type;
2871         u8 ext_phy_addr;
2872         u16 val1 = 0, val2;
2873         u16 rx_sd, pcs_status;
2874         u8 ext_phy_link_up = 0;
2875         u8 port = params->port;
2876         if (vars->phy_flags & PHY_XGXS_FLAG) {
2877                 ext_phy_addr = ((params->ext_phy_config &
2878                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2879                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2880
2881                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2882                 switch (ext_phy_type) {
2883                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2884                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
2885                         ext_phy_link_up = 1;
2886                         break;
2887
2888                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2889                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
2890                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2891                                       ext_phy_addr,
2892                                       MDIO_WIS_DEVAD,
2893                                       MDIO_WIS_REG_LASI_STATUS, &val1);
2894                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2895
2896                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2897                                       ext_phy_addr,
2898                                       MDIO_WIS_DEVAD,
2899                                       MDIO_WIS_REG_LASI_STATUS, &val1);
2900                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2901
2902                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2903                                       ext_phy_addr,
2904                                       MDIO_PMA_DEVAD,
2905                                       MDIO_PMA_REG_RX_SD, &rx_sd);
2906                         DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
2907                         ext_phy_link_up = (rx_sd & 0x1);
2908                         if (ext_phy_link_up)
2909                                 vars->line_speed = SPEED_10000;
2910                         break;
2911
2912                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2913                         DP(NETIF_MSG_LINK, "XGXS 8706\n");
2914                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2915                                       ext_phy_addr,
2916                                       MDIO_PMA_DEVAD,
2917                                       MDIO_PMA_REG_LASI_STATUS, &val1);
2918                         DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2919
2920                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2921                                       ext_phy_addr,
2922                                       MDIO_PMA_DEVAD,
2923                                       MDIO_PMA_REG_LASI_STATUS, &val1);
2924                         DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2925
2926                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2927                                       ext_phy_addr,
2928                                       MDIO_PMA_DEVAD,
2929                                       MDIO_PMA_REG_RX_SD, &rx_sd);
2930                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2931                                       ext_phy_addr,
2932                                       MDIO_PCS_DEVAD,
2933                                       MDIO_PCS_REG_STATUS, &pcs_status);
2934
2935                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
2936                                       ext_phy_addr,
2937                                       MDIO_AN_DEVAD,
2938                                       MDIO_AN_REG_LINK_STATUS, &val2);
2939                         bnx2x_cl45_read(bp, params->port, ext_phy_type,