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