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