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