bnx2x: Minor code improvements
[linux-2.6.git] / drivers / net / bnx2x_link.c
1 /* Copyright 2008 Broadcom Corporation
2  *
3  * Unless you and Broadcom execute a separate written software license
4  * agreement governing use of this software, this software is licensed to you
5  * under the terms of the GNU General Public License version 2, available
6  * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7  *
8  * Notwithstanding the above, under no circumstances may you combine this
9  * software in any way with any other Broadcom software provided under a
10  * license other than the GPL, without Broadcom's express prior written
11  * consent.
12  *
13  * Written by Yaniv Rosner
14  *
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24 #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(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
205
206         timeout = 200;
207         do {
208                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
209                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
210                 if (!timeout) {
211                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
212                         return;
213                 }
214                 timeout--;
215         } while (val & EMAC_MODE_RESET);
216
217         /* Set mac address */
218         val = ((params->mac_addr[0] << 8) |
219                 params->mac_addr[1]);
220         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
221
222         val = ((params->mac_addr[2] << 24) |
223                (params->mac_addr[3] << 16) |
224                (params->mac_addr[4] << 8) |
225                 params->mac_addr[5]);
226         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
227 }
228
229 static u8 bnx2x_emac_enable(struct link_params *params,
230                           struct link_vars *vars, u8 lb)
231 {
232         struct bnx2x *bp = params->bp;
233         u8 port = params->port;
234         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
235         u32 val;
236
237         DP(NETIF_MSG_LINK, "enabling EMAC\n");
238
239         /* enable emac and not bmac */
240         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
241
242         /* for paladium */
243         if (CHIP_REV_IS_EMUL(bp)) {
244                 /* Use lane 1 (of lanes 0-3) */
245                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
246                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
247                             port*4, 1);
248         }
249         /* for fpga */
250         else
251
252         if (CHIP_REV_IS_FPGA(bp)) {
253                 /* Use lane 1 (of lanes 0-3) */
254                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
255
256                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
257                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
258                             0);
259         } else
260         /* ASIC */
261         if (vars->phy_flags & PHY_XGXS_FLAG) {
262                 u32 ser_lane = ((params->lane_config &
263                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
264                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
265
266                 DP(NETIF_MSG_LINK, "XGXS\n");
267                 /* select the master lanes (out of 0-3) */
268                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
269                            port*4, ser_lane);
270                 /* select XGXS */
271                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
272                            port*4, 1);
273
274         } else { /* SerDes */
275                 DP(NETIF_MSG_LINK, "SerDes\n");
276                 /* select SerDes */
277                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
278                            port*4, 0);
279         }
280
281         /* enable emac */
282         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
283
284         if (CHIP_REV_IS_SLOW(bp)) {
285                 /* config GMII mode */
286                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
287                 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
288                             (val | EMAC_MODE_PORT_GMII));
289         } else { /* ASIC */
290                 /* pause enable/disable */
291                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
292                                EMAC_RX_MODE_FLOW_EN);
293                 if (vars->flow_ctrl & FLOW_CTRL_RX)
294                         bnx2x_bits_en(bp, emac_base +
295                                     EMAC_REG_EMAC_RX_MODE,
296                                     EMAC_RX_MODE_FLOW_EN);
297
298                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
299                              (EMAC_TX_MODE_EXT_PAUSE_EN |
300                               EMAC_TX_MODE_FLOW_EN));
301                 if (vars->flow_ctrl & FLOW_CTRL_TX)
302                         bnx2x_bits_en(bp, emac_base +
303                                     EMAC_REG_EMAC_TX_MODE,
304                                    (EMAC_TX_MODE_EXT_PAUSE_EN |
305                                     EMAC_TX_MODE_FLOW_EN));
306         }
307
308         /* KEEP_VLAN_TAG, promiscuous */
309         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
310         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
311         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
312
313         /* Set Loopback */
314         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
315         if (lb)
316                 val |= 0x810;
317         else
318                 val &= ~0x810;
319         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
320
321         /* enable emac for jumbo packets */
322         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
323                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
324                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
325
326         /* strip CRC */
327         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
328
329         /* disable the NIG in/out to the bmac */
330         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
331         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
332         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
333
334         /* enable the NIG in/out to the emac */
335         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
336         val = 0;
337         if (vars->flow_ctrl & FLOW_CTRL_TX)
338                 val = 1;
339
340         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
341         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
342
343         if (CHIP_REV_IS_EMUL(bp)) {
344                 /* take the BigMac out of reset */
345                 REG_WR(bp,
346                            GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
347                            (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
348
349                 /* enable access for bmac registers */
350                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
351         }
352
353         vars->mac_type = MAC_TYPE_EMAC;
354         return 0;
355 }
356
357
358
359 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
360                           u8 is_lb)
361 {
362         struct bnx2x *bp = params->bp;
363         u8 port = params->port;
364         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
365                                NIG_REG_INGRESS_BMAC0_MEM;
366         u32 wb_data[2];
367         u32 val;
368
369         DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
370         /* reset and unreset the BigMac */
371         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
372                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
373         msleep(1);
374
375         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
376                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
377
378         /* enable access for bmac registers */
379         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
380
381         /* XGXS control */
382         wb_data[0] = 0x3c;
383         wb_data[1] = 0;
384         REG_WR_DMAE(bp, bmac_addr +
385                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
386                       wb_data, 2);
387
388         /* tx MAC SA */
389         wb_data[0] = ((params->mac_addr[2] << 24) |
390                        (params->mac_addr[3] << 16) |
391                        (params->mac_addr[4] << 8) |
392                         params->mac_addr[5]);
393         wb_data[1] = ((params->mac_addr[0] << 8) |
394                         params->mac_addr[1]);
395         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
396                     wb_data, 2);
397
398         /* tx control */
399         val = 0xc0;
400         if (vars->flow_ctrl & FLOW_CTRL_TX)
401                 val |= 0x800000;
402         wb_data[0] = val;
403         wb_data[1] = 0;
404         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
405                         wb_data, 2);
406
407         /* mac control */
408         val = 0x3;
409         if (is_lb) {
410                 val |= 0x4;
411                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
412         }
413         wb_data[0] = val;
414         wb_data[1] = 0;
415         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
416                     wb_data, 2);
417
418
419         /* set rx mtu */
420         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
421         wb_data[1] = 0;
422         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
423                         wb_data, 2);
424
425         /* rx control set to don't strip crc */
426         val = 0x14;
427         if (vars->flow_ctrl & FLOW_CTRL_RX)
428                 val |= 0x20;
429         wb_data[0] = val;
430         wb_data[1] = 0;
431         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
432                         wb_data, 2);
433
434         /* set tx mtu */
435         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
436         wb_data[1] = 0;
437         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
438                         wb_data, 2);
439
440         /* set cnt max size */
441         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
442         wb_data[1] = 0;
443         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
444                     wb_data, 2);
445
446         /* configure safc */
447         wb_data[0] = 0x1000200;
448         wb_data[1] = 0;
449         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
450                     wb_data, 2);
451         /* fix for emulation */
452         if (CHIP_REV_IS_EMUL(bp)) {
453                 wb_data[0] = 0xf000;
454                 wb_data[1] = 0;
455                 REG_WR_DMAE(bp,
456                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
457                             wb_data, 2);
458         }
459
460         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
461         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
462         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
463         val = 0;
464         if (vars->flow_ctrl & FLOW_CTRL_TX)
465                 val = 1;
466         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
467         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
468         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
469         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
470         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
471         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
472
473         vars->mac_type = MAC_TYPE_BMAC;
474         return 0;
475 }
476
477 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
478 {
479         struct bnx2x *bp = params->bp;
480         u32 val;
481
482         if (phy_flags & PHY_XGXS_FLAG) {
483                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
484                 val = XGXS_RESET_BITS;
485
486         } else { /* SerDes */
487                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
488                 val = SERDES_RESET_BITS;
489         }
490
491         val = val << (params->port*16);
492
493         /* reset and unreset the SerDes/XGXS */
494         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
495                     val);
496         udelay(500);
497         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
498                     val);
499         bnx2x_set_phy_mdio(params);
500 }
501
502 void bnx2x_link_status_update(struct link_params *params,
503                             struct link_vars   *vars)
504 {
505         struct bnx2x *bp = params->bp;
506         u8 link_10g;
507         u8 port = params->port;
508
509         if (params->switch_cfg ==  SWITCH_CFG_1G)
510                 vars->phy_flags = PHY_SERDES_FLAG;
511         else
512                 vars->phy_flags = PHY_XGXS_FLAG;
513         vars->link_status = REG_RD(bp, params->shmem_base +
514                                           offsetof(struct shmem_region,
515                                            port_mb[port].link_status));
516
517         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
518
519         if (vars->link_up) {
520                 DP(NETIF_MSG_LINK, "phy link up\n");
521
522                 vars->phy_link_up = 1;
523                 vars->duplex = DUPLEX_FULL;
524                 switch (vars->link_status &
525                                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
526                         case LINK_10THD:
527                                 vars->duplex = DUPLEX_HALF;
528                                 /* fall thru */
529                         case LINK_10TFD:
530                                 vars->line_speed = SPEED_10;
531                                 break;
532
533                         case LINK_100TXHD:
534                                 vars->duplex = DUPLEX_HALF;
535                                 /* fall thru */
536                         case LINK_100T4:
537                         case LINK_100TXFD:
538                                 vars->line_speed = SPEED_100;
539                                 break;
540
541                         case LINK_1000THD:
542                                 vars->duplex = DUPLEX_HALF;
543                                 /* fall thru */
544                         case LINK_1000TFD:
545                                 vars->line_speed = SPEED_1000;
546                                 break;
547
548                         case LINK_2500THD:
549                                 vars->duplex = DUPLEX_HALF;
550                                 /* fall thru */
551                         case LINK_2500TFD:
552                                 vars->line_speed = SPEED_2500;
553                                 break;
554
555                         case LINK_10GTFD:
556                                 vars->line_speed = SPEED_10000;
557                                 break;
558
559                         case LINK_12GTFD:
560                                 vars->line_speed = SPEED_12000;
561                                 break;
562
563                         case LINK_12_5GTFD:
564                                 vars->line_speed = SPEED_12500;
565                                 break;
566
567                         case LINK_13GTFD:
568                                 vars->line_speed = SPEED_13000;
569                                 break;
570
571                         case LINK_15GTFD:
572                                 vars->line_speed = SPEED_15000;
573                                 break;
574
575                         case LINK_16GTFD:
576                                 vars->line_speed = SPEED_16000;
577                                 break;
578
579                         default:
580                                 break;
581                 }
582
583                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
584                         vars->flow_ctrl |= FLOW_CTRL_TX;
585                 else
586                         vars->flow_ctrl &= ~FLOW_CTRL_TX;
587
588                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
589                         vars->flow_ctrl |= FLOW_CTRL_RX;
590                 else
591                         vars->flow_ctrl &= ~FLOW_CTRL_RX;
592
593                 if (vars->phy_flags & PHY_XGXS_FLAG) {
594                         if (vars->line_speed &&
595                             ((vars->line_speed == SPEED_10) ||
596                              (vars->line_speed == SPEED_100))) {
597                                 vars->phy_flags |= PHY_SGMII_FLAG;
598                         } else {
599                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
600                         }
601                 }
602
603                 /* anything 10 and over uses the bmac */
604                 link_10g = ((vars->line_speed == SPEED_10000) ||
605                             (vars->line_speed == SPEED_12000) ||
606                             (vars->line_speed == SPEED_12500) ||
607                             (vars->line_speed == SPEED_13000) ||
608                             (vars->line_speed == SPEED_15000) ||
609                             (vars->line_speed == SPEED_16000));
610                 if (link_10g)
611                         vars->mac_type = MAC_TYPE_BMAC;
612                 else
613                         vars->mac_type = MAC_TYPE_EMAC;
614
615         } else { /* link down */
616                 DP(NETIF_MSG_LINK, "phy link down\n");
617
618                 vars->phy_link_up = 0;
619
620                 vars->line_speed = 0;
621                 vars->duplex = DUPLEX_FULL;
622                 vars->flow_ctrl = FLOW_CTRL_NONE;
623
624                 /* indicate no mac active */
625                 vars->mac_type = MAC_TYPE_NONE;
626         }
627
628         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
629                  vars->link_status, vars->phy_link_up);
630         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
631                  vars->line_speed, vars->duplex, vars->flow_ctrl);
632 }
633
634 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
635 {
636         struct bnx2x *bp = params->bp;
637         REG_WR(bp, params->shmem_base +
638                    offsetof(struct shmem_region,
639                             port_mb[params->port].link_status),
640                         link_status);
641 }
642
643 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
644 {
645         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
646                 NIG_REG_INGRESS_BMAC0_MEM;
647         u32 wb_data[2];
648         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
649
650         /* Only if the bmac is out of reset */
651         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
652                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
653             nig_bmac_enable) {
654
655                 /* Clear Rx Enable bit in BMAC_CONTROL register */
656                 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
657                             wb_data, 2);
658                 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
659                 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
660                             wb_data, 2);
661
662                 msleep(1);
663         }
664 }
665
666 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
667                          u32 line_speed)
668 {
669         struct bnx2x *bp = params->bp;
670         u8 port = params->port;
671         u32 init_crd, crd;
672         u32 count = 1000;
673
674         /* disable port */
675         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
676
677         /* wait for init credit */
678         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
679         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
680         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
681
682         while ((init_crd != crd) && count) {
683                 msleep(5);
684
685                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
686                 count--;
687         }
688         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
689         if (init_crd != crd) {
690                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
691                           init_crd, crd);
692                 return -EINVAL;
693         }
694
695         if (flow_ctrl & FLOW_CTRL_RX ||
696             line_speed == SPEED_10 ||
697             line_speed == SPEED_100 ||
698             line_speed == SPEED_1000 ||
699             line_speed == SPEED_2500) {
700                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
701                 /* update threshold */
702                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
703                 /* update init credit */
704                 init_crd = 778;         /* (800-18-4) */
705
706         } else {
707                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
708                               ETH_OVREHEAD)/16;
709                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
710                 /* update threshold */
711                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
712                 /* update init credit */
713                 switch (line_speed) {
714                 case SPEED_10000:
715                         init_crd = thresh + 553 - 22;
716                         break;
717
718                 case SPEED_12000:
719                         init_crd = thresh + 664 - 22;
720                         break;
721
722                 case SPEED_13000:
723                         init_crd = thresh + 742 - 22;
724                         break;
725
726                 case SPEED_16000:
727                         init_crd = thresh + 778 - 22;
728                         break;
729                 default:
730                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
731                                   line_speed);
732                         return -EINVAL;
733                         break;
734                 }
735         }
736         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
737         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
738                  line_speed, init_crd);
739
740         /* probe the credit changes */
741         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
742         msleep(5);
743         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
744
745         /* enable port */
746         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
747         return 0;
748 }
749
750 static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
751 {
752         u32 emac_base;
753         switch (ext_phy_type) {
754         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
755                 emac_base = GRCBASE_EMAC0;
756                 break;
757         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
758                 emac_base = (port) ? GRCBASE_EMAC0: GRCBASE_EMAC1;
759                 break;
760         default:
761                 emac_base = (port) ? GRCBASE_EMAC1: GRCBASE_EMAC0;
762                 break;
763         }
764         return emac_base;
765
766 }
767
768 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
769                   u8 phy_addr, u8 devad, u16 reg, u16 val)
770 {
771         u32 tmp, saved_mode;
772         u8 i, rc = 0;
773         u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
774
775         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
776          * (a value of 49==0x31) and make sure that the AUTO poll is off
777          */
778         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
779         tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
780                              EMAC_MDIO_MODE_CLOCK_CNT);
781         tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
782                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
783         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
784         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
785         udelay(40);
786
787         /* address */
788
789         tmp = ((phy_addr << 21) | (devad << 16) | reg |
790                EMAC_MDIO_COMM_COMMAND_ADDRESS |
791                EMAC_MDIO_COMM_START_BUSY);
792         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
793
794         for (i = 0; i < 50; i++) {
795                 udelay(10);
796
797                 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
798                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
799                         udelay(5);
800                         break;
801                 }
802         }
803         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
804                 DP(NETIF_MSG_LINK, "write phy register failed\n");
805                 rc = -EFAULT;
806         } else {
807                 /* data */
808                 tmp = ((phy_addr << 21) | (devad << 16) | val |
809                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
810                        EMAC_MDIO_COMM_START_BUSY);
811                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
812
813                 for (i = 0; i < 50; i++) {
814                         udelay(10);
815
816                         tmp = REG_RD(bp, mdio_ctrl +
817                                          EMAC_REG_EMAC_MDIO_COMM);
818                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
819                                 udelay(5);
820                                 break;
821                         }
822                 }
823                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
824                         DP(NETIF_MSG_LINK, "write phy register failed\n");
825                         rc = -EFAULT;
826                 }
827         }
828
829         /* Restore the saved mode */
830         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
831
832         return rc;
833 }
834
835 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
836                  u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
837 {
838         u32 val, saved_mode;
839         u16 i;
840         u8 rc = 0;
841
842         u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
843         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
844          * (a value of 49==0x31) and make sure that the AUTO poll is off
845          */
846         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
847         val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
848                              EMAC_MDIO_MODE_CLOCK_CNT));
849         val |= (EMAC_MDIO_MODE_CLAUSE_45 |
850                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
851         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
852         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
853         udelay(40);
854
855         /* address */
856         val = ((phy_addr << 21) | (devad << 16) | reg |
857                EMAC_MDIO_COMM_COMMAND_ADDRESS |
858                EMAC_MDIO_COMM_START_BUSY);
859         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
860
861         for (i = 0; i < 50; i++) {
862                 udelay(10);
863
864                 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
865                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
866                         udelay(5);
867                         break;
868                 }
869         }
870         if (val & EMAC_MDIO_COMM_START_BUSY) {
871                 DP(NETIF_MSG_LINK, "read phy register failed\n");
872
873                 *ret_val = 0;
874                 rc = -EFAULT;
875
876         } else {
877                 /* data */
878                 val = ((phy_addr << 21) | (devad << 16) |
879                        EMAC_MDIO_COMM_COMMAND_READ_45 |
880                        EMAC_MDIO_COMM_START_BUSY);
881                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
882
883                 for (i = 0; i < 50; i++) {
884                         udelay(10);
885
886                         val = REG_RD(bp, mdio_ctrl +
887                                           EMAC_REG_EMAC_MDIO_COMM);
888                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
889                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
890                                 break;
891                         }
892                 }
893                 if (val & EMAC_MDIO_COMM_START_BUSY) {
894                         DP(NETIF_MSG_LINK, "read phy register failed\n");
895
896                         *ret_val = 0;
897                         rc = -EFAULT;
898                 }
899         }
900
901         /* Restore the saved mode */
902         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
903
904         return rc;
905 }
906
907 static void bnx2x_set_aer_mmd(struct link_params *params,
908                             struct link_vars   *vars)
909 {
910         struct bnx2x *bp = params->bp;
911         u32 ser_lane;
912         u16 offset;
913
914         ser_lane = ((params->lane_config &
915                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
916                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
917
918         offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
919                 (params->phy_addr + ser_lane) : 0;
920
921         CL45_WR_OVER_CL22(bp, params->port,
922                               params->phy_addr,
923                               MDIO_REG_BANK_AER_BLOCK,
924                               MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
925 }
926
927 static void bnx2x_set_master_ln(struct link_params *params)
928 {
929         struct bnx2x *bp = params->bp;
930         u16 new_master_ln, ser_lane;
931         ser_lane =  ((params->lane_config &
932                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
933                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
934
935         /* set the master_ln for AN */
936         CL45_RD_OVER_CL22(bp, params->port,
937                               params->phy_addr,
938                               MDIO_REG_BANK_XGXS_BLOCK2,
939                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
940                               &new_master_ln);
941
942         CL45_WR_OVER_CL22(bp, params->port,
943                               params->phy_addr,
944                               MDIO_REG_BANK_XGXS_BLOCK2 ,
945                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
946                               (new_master_ln | ser_lane));
947 }
948
949 static u8 bnx2x_reset_unicore(struct link_params *params)
950 {
951         struct bnx2x *bp = params->bp;
952         u16 mii_control;
953         u16 i;
954
955         CL45_RD_OVER_CL22(bp, params->port,
956                               params->phy_addr,
957                               MDIO_REG_BANK_COMBO_IEEE0,
958                               MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
959
960         /* reset the unicore */
961         CL45_WR_OVER_CL22(bp, params->port,
962                               params->phy_addr,
963                               MDIO_REG_BANK_COMBO_IEEE0,
964                               MDIO_COMBO_IEEE0_MII_CONTROL,
965                               (mii_control |
966                                MDIO_COMBO_IEEO_MII_CONTROL_RESET));
967
968         /* wait for the reset to self clear */
969         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
970                 udelay(5);
971
972                 /* the reset erased the previous bank value */
973                 CL45_RD_OVER_CL22(bp, params->port,
974                                       params->phy_addr,
975                               MDIO_REG_BANK_COMBO_IEEE0,
976                               MDIO_COMBO_IEEE0_MII_CONTROL,
977                               &mii_control);
978
979                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
980                         udelay(5);
981                         return 0;
982                 }
983         }
984
985         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
986         return -EINVAL;
987
988 }
989
990 static void bnx2x_set_swap_lanes(struct link_params *params)
991 {
992         struct bnx2x *bp = params->bp;
993         /* Each two bits represents a lane number:
994            No swap is 0123 => 0x1b no need to enable the swap */
995         u16 ser_lane, rx_lane_swap, tx_lane_swap;
996
997         ser_lane = ((params->lane_config &
998                          PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
999                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1000         rx_lane_swap = ((params->lane_config &
1001                              PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1002                             PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1003         tx_lane_swap = ((params->lane_config &
1004                              PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1005                             PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1006
1007         if (rx_lane_swap != 0x1b) {
1008                 CL45_WR_OVER_CL22(bp, params->port,
1009                                       params->phy_addr,
1010                                     MDIO_REG_BANK_XGXS_BLOCK2,
1011                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1012                                     (rx_lane_swap |
1013                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1014                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1015         } else {
1016                 CL45_WR_OVER_CL22(bp, params->port,
1017                                       params->phy_addr,
1018                                       MDIO_REG_BANK_XGXS_BLOCK2,
1019                                       MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1020         }
1021
1022         if (tx_lane_swap != 0x1b) {
1023                 CL45_WR_OVER_CL22(bp, params->port,
1024                                       params->phy_addr,
1025                                       MDIO_REG_BANK_XGXS_BLOCK2,
1026                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1027                                       (tx_lane_swap |
1028                                        MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1029         } else {
1030                 CL45_WR_OVER_CL22(bp, params->port,
1031                                       params->phy_addr,
1032                                       MDIO_REG_BANK_XGXS_BLOCK2,
1033                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1034         }
1035 }
1036
1037 static void bnx2x_set_parallel_detection(struct link_params *params,
1038                                        u8                phy_flags)
1039 {
1040         struct bnx2x *bp = params->bp;
1041         u16 control2;
1042
1043         CL45_RD_OVER_CL22(bp, params->port,
1044                               params->phy_addr,
1045                               MDIO_REG_BANK_SERDES_DIGITAL,
1046                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1047                               &control2);
1048
1049
1050         control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1051
1052
1053         CL45_WR_OVER_CL22(bp, params->port,
1054                               params->phy_addr,
1055                               MDIO_REG_BANK_SERDES_DIGITAL,
1056                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1057                               control2);
1058
1059         if (phy_flags & PHY_XGXS_FLAG) {
1060                 DP(NETIF_MSG_LINK, "XGXS\n");
1061
1062                 CL45_WR_OVER_CL22(bp, params->port,
1063                                       params->phy_addr,
1064                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1065                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1066                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1067
1068                 CL45_RD_OVER_CL22(bp, params->port,
1069                                       params->phy_addr,
1070                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1071                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1072                                 &control2);
1073
1074
1075                 control2 |=
1076                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1077
1078                 CL45_WR_OVER_CL22(bp, params->port,
1079                                       params->phy_addr,
1080                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1081                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1082                                 control2);
1083
1084                 /* Disable parallel detection of HiG */
1085                 CL45_WR_OVER_CL22(bp, params->port,
1086                                       params->phy_addr,
1087                                 MDIO_REG_BANK_XGXS_BLOCK2,
1088                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1089                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1090                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1091         }
1092 }
1093
1094 static void bnx2x_set_autoneg(struct link_params *params,
1095                             struct link_vars   *vars)
1096 {
1097         struct bnx2x *bp = params->bp;
1098         u16 reg_val;
1099
1100         /* CL37 Autoneg */
1101
1102         CL45_RD_OVER_CL22(bp, params->port,
1103                               params->phy_addr,
1104                               MDIO_REG_BANK_COMBO_IEEE0,
1105                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1106
1107         /* CL37 Autoneg Enabled */
1108         if (vars->line_speed == SPEED_AUTO_NEG)
1109                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1110         else /* CL37 Autoneg Disabled */
1111                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1112                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1113
1114         CL45_WR_OVER_CL22(bp, params->port,
1115                               params->phy_addr,
1116                               MDIO_REG_BANK_COMBO_IEEE0,
1117                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1118
1119         /* Enable/Disable Autodetection */
1120
1121         CL45_RD_OVER_CL22(bp, params->port,
1122                               params->phy_addr,
1123                               MDIO_REG_BANK_SERDES_DIGITAL,
1124                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1125         reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1126         if (vars->line_speed == SPEED_AUTO_NEG)
1127                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1128         else
1129                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1130
1131         CL45_WR_OVER_CL22(bp, params->port,
1132                               params->phy_addr,
1133                               MDIO_REG_BANK_SERDES_DIGITAL,
1134                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1135
1136         /* Enable TetonII and BAM autoneg */
1137         CL45_RD_OVER_CL22(bp, params->port,
1138                               params->phy_addr,
1139                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1140                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1141                           &reg_val);
1142         if (vars->line_speed == SPEED_AUTO_NEG) {
1143                 /* Enable BAM aneg Mode and TetonII aneg Mode */
1144                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1145                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1146         } else {
1147                 /* TetonII and BAM Autoneg Disabled */
1148                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1149                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1150         }
1151         CL45_WR_OVER_CL22(bp, params->port,
1152                               params->phy_addr,
1153                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1154                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1155                               reg_val);
1156
1157         /* Enable Clause 73 Aneg */
1158         if ((vars->line_speed == SPEED_AUTO_NEG) &&
1159             (SUPPORT_CL73)) {
1160                 /* Enable BAM Station Manager */
1161
1162                 CL45_WR_OVER_CL22(bp, params->port,
1163                                       params->phy_addr,
1164                                       MDIO_REG_BANK_CL73_USERB0,
1165                                       MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1166                                    (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1167                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1168                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1169
1170                 /* Merge CL73 and CL37 aneg resolution */
1171                 CL45_RD_OVER_CL22(bp, params->port,
1172                                       params->phy_addr,
1173                                       MDIO_REG_BANK_CL73_USERB0,
1174                                       MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1175                                       &reg_val);
1176
1177                 CL45_WR_OVER_CL22(bp, params->port,
1178                                       params->phy_addr,
1179                         MDIO_REG_BANK_CL73_USERB0,
1180                         MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1181                         (reg_val |
1182                         MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1183
1184                 /* Set the CL73 AN speed */
1185
1186                 CL45_RD_OVER_CL22(bp, params->port,
1187                                       params->phy_addr,
1188                                       MDIO_REG_BANK_CL73_IEEEB1,
1189                                       MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
1190                 /* In the SerDes we support only the 1G.
1191                    In the XGXS we support the 10G KX4
1192                    but we currently do not support the KR */
1193                 if (vars->phy_flags & PHY_XGXS_FLAG) {
1194                         DP(NETIF_MSG_LINK, "XGXS\n");
1195                         /* 10G KX4 */
1196                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1197                 } else {
1198                         DP(NETIF_MSG_LINK, "SerDes\n");
1199                         /* 1000M KX */
1200                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1201                 }
1202                 CL45_WR_OVER_CL22(bp, params->port,
1203                                       params->phy_addr,
1204                                       MDIO_REG_BANK_CL73_IEEEB1,
1205                                       MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1206
1207                 /* CL73 Autoneg Enabled */
1208                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1209         } else {
1210                 /* CL73 Autoneg Disabled */
1211                 reg_val = 0;
1212         }
1213         CL45_WR_OVER_CL22(bp, params->port,
1214                               params->phy_addr,
1215                               MDIO_REG_BANK_CL73_IEEEB0,
1216                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1217 }
1218
1219 /* program SerDes, forced speed */
1220 static void bnx2x_program_serdes(struct link_params *params,
1221                                struct link_vars *vars)
1222 {
1223         struct bnx2x *bp = params->bp;
1224         u16 reg_val;
1225
1226         /* program duplex, disable autoneg */
1227
1228         CL45_RD_OVER_CL22(bp, params->port,
1229                               params->phy_addr,
1230                               MDIO_REG_BANK_COMBO_IEEE0,
1231                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1232         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1233                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1234         if (params->req_duplex == DUPLEX_FULL)
1235                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1236         CL45_WR_OVER_CL22(bp, params->port,
1237                               params->phy_addr,
1238                               MDIO_REG_BANK_COMBO_IEEE0,
1239                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1240
1241         /* program speed
1242            - needed only if the speed is greater than 1G (2.5G or 10G) */
1243         CL45_RD_OVER_CL22(bp, params->port,
1244                                       params->phy_addr,
1245                                       MDIO_REG_BANK_SERDES_DIGITAL,
1246                                       MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1247         /* clearing the speed value before setting the right speed */
1248         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1249
1250         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1251                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1252
1253         if (!((vars->line_speed == SPEED_1000) ||
1254               (vars->line_speed == SPEED_100) ||
1255               (vars->line_speed == SPEED_10))) {
1256
1257                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1258                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1259                 if (vars->line_speed == SPEED_10000)
1260                         reg_val |=
1261                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1262                 if (vars->line_speed == SPEED_13000)
1263                         reg_val |=
1264                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1265         }
1266
1267         CL45_WR_OVER_CL22(bp, params->port,
1268                                       params->phy_addr,
1269                                       MDIO_REG_BANK_SERDES_DIGITAL,
1270                                       MDIO_SERDES_DIGITAL_MISC1, reg_val);
1271
1272 }
1273
1274 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1275 {
1276         struct bnx2x *bp = params->bp;
1277         u16 val = 0;
1278
1279         /* configure the 48 bits for BAM AN */
1280
1281         /* set extended capabilities */
1282         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1283                 val |= MDIO_OVER_1G_UP1_2_5G;
1284         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1285                 val |= MDIO_OVER_1G_UP1_10G;
1286         CL45_WR_OVER_CL22(bp, params->port,
1287                               params->phy_addr,
1288                               MDIO_REG_BANK_OVER_1G,
1289                               MDIO_OVER_1G_UP1, val);
1290
1291         CL45_WR_OVER_CL22(bp, params->port,
1292                               params->phy_addr,
1293                               MDIO_REG_BANK_OVER_1G,
1294                               MDIO_OVER_1G_UP3, 0);
1295 }
1296
1297 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1298 {
1299         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1300         /* resolve pause mode and advertisement
1301          * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1302
1303         switch (params->req_flow_ctrl) {
1304         case FLOW_CTRL_AUTO:
1305                 if (params->req_fc_auto_adv == FLOW_CTRL_BOTH) {
1306                         *ieee_fc |=
1307                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1308                 } else {
1309                         *ieee_fc |=
1310                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1311                 }
1312                 break;
1313         case FLOW_CTRL_TX:
1314                 *ieee_fc |=
1315                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1316                 break;
1317
1318         case FLOW_CTRL_RX:
1319         case FLOW_CTRL_BOTH:
1320                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1321                 break;
1322
1323         case FLOW_CTRL_NONE:
1324         default:
1325                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1326                 break;
1327         }
1328 }
1329
1330 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1331                                            u32 ieee_fc)
1332 {
1333         struct bnx2x *bp = params->bp;
1334         /* for AN, we are always publishing full duplex */
1335
1336         CL45_WR_OVER_CL22(bp, params->port,
1337                               params->phy_addr,
1338                               MDIO_REG_BANK_COMBO_IEEE0,
1339                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1340 }
1341
1342 static void bnx2x_restart_autoneg(struct link_params *params)
1343 {
1344         struct bnx2x *bp = params->bp;
1345         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1346         if (SUPPORT_CL73) {
1347                 /* enable and restart clause 73 aneg */
1348                 u16 an_ctrl;
1349
1350                 CL45_RD_OVER_CL22(bp, params->port,
1351                                       params->phy_addr,
1352                                       MDIO_REG_BANK_CL73_IEEEB0,
1353                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1354                                   &an_ctrl);
1355                 CL45_WR_OVER_CL22(bp, params->port,
1356                                       params->phy_addr,
1357                                 MDIO_REG_BANK_CL73_IEEEB0,
1358                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1359                                 (an_ctrl |
1360                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1361                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1362
1363         } else {
1364                 /* Enable and restart BAM/CL37 aneg */
1365                 u16 mii_control;
1366
1367                 CL45_RD_OVER_CL22(bp, params->port,
1368                                       params->phy_addr,
1369                                       MDIO_REG_BANK_COMBO_IEEE0,
1370                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1371                                       &mii_control);
1372                 DP(NETIF_MSG_LINK,
1373                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1374                          mii_control);
1375                 CL45_WR_OVER_CL22(bp, params->port,
1376                                       params->phy_addr,
1377                                       MDIO_REG_BANK_COMBO_IEEE0,
1378                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1379                                       (mii_control |
1380                                 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1381                                 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1382         }
1383 }
1384
1385 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1386                                          struct link_vars *vars)
1387 {
1388         struct bnx2x *bp = params->bp;
1389         u16 control1;
1390
1391         /* in SGMII mode, the unicore is always slave */
1392
1393         CL45_RD_OVER_CL22(bp, params->port,
1394                               params->phy_addr,
1395                               MDIO_REG_BANK_SERDES_DIGITAL,
1396                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1397                       &control1);
1398         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1399         /* set sgmii mode (and not fiber) */
1400         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1401                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1402                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1403         CL45_WR_OVER_CL22(bp, params->port,
1404                               params->phy_addr,
1405                               MDIO_REG_BANK_SERDES_DIGITAL,
1406                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1407                               control1);
1408
1409         /* if forced speed */
1410         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1411                 /* set speed, disable autoneg */
1412                 u16 mii_control;
1413
1414                 CL45_RD_OVER_CL22(bp, params->port,
1415                                       params->phy_addr,
1416                                       MDIO_REG_BANK_COMBO_IEEE0,
1417                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1418                                       &mii_control);
1419                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1420                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1421                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1422
1423                 switch (vars->line_speed) {
1424                 case SPEED_100:
1425                         mii_control |=
1426                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1427                         break;
1428                 case SPEED_1000:
1429                         mii_control |=
1430                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1431                         break;
1432                 case SPEED_10:
1433                         /* there is nothing to set for 10M */
1434                         break;
1435                 default:
1436                         /* invalid speed for SGMII */
1437                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1438                                   vars->line_speed);
1439                         break;
1440                 }
1441
1442                 /* setting the full duplex */
1443                 if (params->req_duplex == DUPLEX_FULL)
1444                         mii_control |=
1445                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1446                 CL45_WR_OVER_CL22(bp, params->port,
1447                                       params->phy_addr,
1448                                       MDIO_REG_BANK_COMBO_IEEE0,
1449                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1450                                       mii_control);
1451
1452         } else { /* AN mode */
1453                 /* enable and restart AN */
1454                 bnx2x_restart_autoneg(params);
1455         }
1456 }
1457
1458
1459 /*
1460  * link management
1461  */
1462
1463 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1464 {                                               /*  LD      LP   */
1465         switch (pause_result) {                 /* ASYM P ASYM P */
1466         case 0xb:                               /*   1  0   1  1 */
1467                 vars->flow_ctrl = FLOW_CTRL_TX;
1468                 break;
1469
1470         case 0xe:                               /*   1  1   1  0 */
1471                 vars->flow_ctrl = FLOW_CTRL_RX;
1472                 break;
1473
1474         case 0x5:                               /*   0  1   0  1 */
1475         case 0x7:                               /*   0  1   1  1 */
1476         case 0xd:                               /*   1  1   0  1 */
1477         case 0xf:                               /*   1  1   1  1 */
1478                 vars->flow_ctrl = FLOW_CTRL_BOTH;
1479                 break;
1480
1481         default:
1482                 break;
1483         }
1484 }
1485
1486 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1487                                   struct link_vars *vars)
1488 {
1489         struct bnx2x *bp = params->bp;
1490         u8 ext_phy_addr;
1491         u16 ld_pause;   /* local */
1492         u16 lp_pause;   /* link partner */
1493         u16 an_complete; /* AN complete */
1494         u16 pause_result;
1495         u8 ret = 0;
1496         u32 ext_phy_type;
1497         u8 port = params->port;
1498         ext_phy_addr = ((params->ext_phy_config &
1499                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1500                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1501
1502         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1503         /* read twice */
1504
1505         bnx2x_cl45_read(bp, port,
1506                       ext_phy_type,
1507                       ext_phy_addr,
1508                       MDIO_AN_DEVAD,
1509                       MDIO_AN_REG_STATUS, &an_complete);
1510         bnx2x_cl45_read(bp, port,
1511                       ext_phy_type,
1512                       ext_phy_addr,
1513                       MDIO_AN_DEVAD,
1514                       MDIO_AN_REG_STATUS, &an_complete);
1515
1516         if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1517                 ret = 1;
1518                 bnx2x_cl45_read(bp, port,
1519                               ext_phy_type,
1520                               ext_phy_addr,
1521                               MDIO_AN_DEVAD,
1522                               MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1523                 bnx2x_cl45_read(bp, port,
1524                               ext_phy_type,
1525                               ext_phy_addr,
1526                               MDIO_AN_DEVAD,
1527                               MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1528                 pause_result = (ld_pause &
1529                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1530                 pause_result |= (lp_pause &
1531                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1532                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1533                    pause_result);
1534                 bnx2x_pause_resolve(vars, pause_result);
1535                 if (vars->flow_ctrl == FLOW_CTRL_NONE &&
1536                      ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1537                         bnx2x_cl45_read(bp, port,
1538                                       ext_phy_type,
1539                                       ext_phy_addr,
1540                                       MDIO_AN_DEVAD,
1541                                       MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1542
1543                         bnx2x_cl45_read(bp, port,
1544                                       ext_phy_type,
1545                                       ext_phy_addr,
1546                                       MDIO_AN_DEVAD,
1547                                       MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1548                         pause_result = (ld_pause &
1549                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1550                         pause_result |= (lp_pause &
1551                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1552
1553                         bnx2x_pause_resolve(vars, pause_result);
1554                         DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1555                                  pause_result);
1556                 }
1557         }
1558         return ret;
1559 }
1560
1561
1562 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1563                                   struct link_vars *vars,
1564                                   u32 gp_status)
1565 {
1566         struct bnx2x *bp = params->bp;
1567         u16 ld_pause;   /* local driver */
1568         u16 lp_pause;   /* link partner */
1569         u16 pause_result;
1570
1571         vars->flow_ctrl = FLOW_CTRL_NONE;
1572
1573         /* resolve from gp_status in case of AN complete and not sgmii */
1574         if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1575             (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1576             (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1577             (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1578              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1579                 CL45_RD_OVER_CL22(bp, params->port,
1580                                       params->phy_addr,
1581                                       MDIO_REG_BANK_COMBO_IEEE0,
1582                                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1583                                       &ld_pause);
1584                 CL45_RD_OVER_CL22(bp, params->port,
1585                                       params->phy_addr,
1586                         MDIO_REG_BANK_COMBO_IEEE0,
1587                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1588                         &lp_pause);
1589                 pause_result = (ld_pause &
1590                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1591                 pause_result |= (lp_pause &
1592                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1593                 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1594                 bnx2x_pause_resolve(vars, pause_result);
1595         } else if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1596                    (bnx2x_ext_phy_resove_fc(params, vars))) {
1597                 return;
1598         } else {
1599                 if (params->req_flow_ctrl == FLOW_CTRL_AUTO)
1600                         vars->flow_ctrl = params->req_fc_auto_adv;
1601                 else
1602                         vars->flow_ctrl = params->req_flow_ctrl;
1603         }
1604         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1605 }
1606
1607
1608 static u8 bnx2x_link_settings_status(struct link_params *params,
1609                                       struct link_vars *vars,
1610                                       u32 gp_status)
1611 {
1612         struct bnx2x *bp = params->bp;
1613
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, u8 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(bp, 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(bp, 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
3937         /* disable attentions */
3938         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3939                        (NIG_MASK_XGXS0_LINK_STATUS |
3940                         NIG_MASK_XGXS0_LINK10G |
3941                         NIG_MASK_SERDES0_LINK_STATUS |
3942                         NIG_MASK_MI_INT));
3943
3944         bnx2x_emac_init(params, vars);
3945
3946         if (CHIP_REV_IS_FPGA(bp)) {
3947                 vars->link_up = 1;
3948                 vars->line_speed = SPEED_10000;
3949                 vars->duplex = DUPLEX_FULL;
3950                 vars->flow_ctrl = FLOW_CTRL_NONE;
3951                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3952                 /* enable on E1.5 FPGA */
3953                 if (CHIP_IS_E1H(bp)) {
3954                         vars->flow_ctrl |=
3955                                 (FLOW_CTRL_TX | FLOW_CTRL_RX);
3956                         vars->link_status |=
3957                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
3958                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
3959                 }
3960
3961                 bnx2x_emac_enable(params, vars, 0);
3962                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3963                 /* disable drain */
3964                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3965                                     + params->port*4, 0);
3966
3967                 /* update shared memory */
3968                 bnx2x_update_mng(params, vars->link_status);
3969
3970                 return 0;
3971
3972         } else
3973         if (CHIP_REV_IS_EMUL(bp)) {
3974
3975                 vars->link_up = 1;
3976                 vars->line_speed = SPEED_10000;
3977                 vars->duplex = DUPLEX_FULL;
3978                 vars->flow_ctrl = FLOW_CTRL_NONE;
3979                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3980
3981                 bnx2x_bmac_enable(params, vars, 0);
3982
3983                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3984                 /* Disable drain */
3985                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3986                                     + params->port*4, 0);
3987
3988                 /* update shared memory */
3989                 bnx2x_update_mng(params, vars->link_status);
3990
3991                 return 0;
3992
3993         } else
3994         if (params->loopback_mode == LOOPBACK_BMAC) {
3995                 vars->link_up = 1;
3996                 vars->line_speed = SPEED_10000;
3997                 vars->duplex = DUPLEX_FULL;
3998                 vars->flow_ctrl = FLOW_CTRL_NONE;
3999                 vars->mac_type = MAC_TYPE_BMAC;
4000
4001                 vars->phy_flags = PHY_XGXS_FLAG;
4002
4003                 bnx2x_phy_deassert(params, vars->phy_flags);
4004                 /* set bmac loopback */
4005                 bnx2x_bmac_enable(params, vars, 1);
4006
4007                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4008                     params->port*4, 0);
4009         } else if (params->loopback_mode == LOOPBACK_EMAC) {
4010                 vars->link_up = 1;
4011                 vars->line_speed = SPEED_1000;
4012                 vars->duplex = DUPLEX_FULL;
4013                 vars->flow_ctrl = FLOW_CTRL_NONE;
4014                 vars->mac_type = MAC_TYPE_EMAC;
4015
4016                 vars->phy_flags = PHY_XGXS_FLAG;
4017
4018                 bnx2x_phy_deassert(params, vars->phy_flags);
4019                 /* set bmac loopback */
4020                 bnx2x_emac_enable(params, vars, 1);
4021                 bnx2x_emac_program(params, vars->line_speed,
4022                                               vars->duplex);
4023                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4024                     params->port*4, 0);
4025         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4026                   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4027                 vars->link_up = 1;
4028                 vars->line_speed = SPEED_10000;
4029                 vars->duplex = DUPLEX_FULL;
4030                 vars->flow_ctrl = FLOW_CTRL_NONE;
4031
4032                 vars->phy_flags = PHY_XGXS_FLAG;
4033
4034                 val = REG_RD(bp,
4035                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
4036                                  params->port*0x18);
4037                 params->phy_addr = (u8)val;
4038
4039                 bnx2x_phy_deassert(params, vars->phy_flags);
4040                 bnx2x_link_initialize(params, vars);
4041
4042                 vars->mac_type = MAC_TYPE_BMAC;
4043
4044                 bnx2x_bmac_enable(params, vars, 0);
4045
4046                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4047                         /* set 10G XGXS loopback */
4048                         bnx2x_set_xgxs_loopback(params, vars, 1);
4049                 } else {
4050                         /* set external phy loopback */
4051                         bnx2x_ext_phy_loopback(params);
4052                 }
4053                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4054                             params->port*4, 0);
4055         } else
4056         /* No loopback */
4057         {
4058
4059                 bnx2x_phy_deassert(params, vars->phy_flags);
4060                 switch (params->switch_cfg) {
4061                 case SWITCH_CFG_1G:
4062                         vars->phy_flags |= PHY_SERDES_FLAG;
4063                         if ((params->ext_phy_config &
4064                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4065                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4066                                 vars->phy_flags |=
4067                                         PHY_SGMII_FLAG;
4068                         }
4069
4070                         val = REG_RD(bp,
4071                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
4072                                          params->port*0x10);
4073
4074                         params->phy_addr = (u8)val;
4075
4076                         break;
4077                 case SWITCH_CFG_10G:
4078                         vars->phy_flags |= PHY_XGXS_FLAG;
4079                         val = REG_RD(bp,
4080                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
4081                                  params->port*0x18);
4082                         params->phy_addr = (u8)val;
4083
4084                         break;
4085                 default:
4086                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4087                         return -EINVAL;
4088                         break;
4089                 }
4090
4091                 bnx2x_link_initialize(params, vars);
4092                 msleep(30);
4093                 bnx2x_link_int_enable(params);
4094         }
4095         return 0;
4096 }
4097
4098 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
4099 {
4100
4101         struct bnx2x *bp = params->bp;
4102         u32 ext_phy_config = params->ext_phy_config;
4103         u16 hw_led_mode = params->hw_led_mode;
4104         u32 chip_id = params->chip_id;
4105         u8 port = params->port;
4106         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4107         /* disable attentions */
4108
4109         vars->link_status = 0;
4110         bnx2x_update_mng(params, vars->link_status);
4111         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4112                      (NIG_MASK_XGXS0_LINK_STATUS |
4113                       NIG_MASK_XGXS0_LINK10G |
4114                       NIG_MASK_SERDES0_LINK_STATUS |
4115                       NIG_MASK_MI_INT));
4116
4117         /* activate nig drain */
4118         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4119
4120         /* disable nig egress interface */
4121         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4122         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4123
4124         /* Stop BigMac rx */
4125         bnx2x_bmac_rx_disable(bp, port);
4126
4127         /* disable emac */
4128         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4129
4130         msleep(10);
4131         /* The PHY reset is controled by GPIO 1
4132          * Hold it as vars low
4133          */
4134          /* clear link led */
4135         bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4136         if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
4137                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
4138                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
4139                         /* HW reset */
4140
4141                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4142                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4143                                           port);
4144
4145                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4146                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4147                                           port);
4148
4149                         DP(NETIF_MSG_LINK, "reset external PHY\n");
4150                 } else if (ext_phy_type ==
4151                            PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4152                                 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4153                                          "low power mode\n",
4154                                          port);
4155                                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4156                                         MISC_REGISTERS_GPIO_OUTPUT_LOW,
4157                                                   port);
4158                 }
4159         }
4160         /* reset the SerDes/XGXS */
4161         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4162                (0x1ff << (port*16)));
4163
4164         /* reset BigMac */
4165         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4166                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4167
4168         /* disable nig ingress interface */
4169         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4170         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4171         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4172         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4173         vars->link_up = 0;
4174         return 0;
4175 }
4176
4177 static u8 bnx2x_update_link_down(struct link_params *params,
4178                                struct link_vars *vars)
4179 {
4180         struct bnx2x *bp = params->bp;
4181         u8 port = params->port;
4182         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4183         bnx2x_set_led(bp, port, LED_MODE_OFF,
4184                     0, params->hw_led_mode,
4185                     params->chip_id);
4186
4187         /* indicate no mac active */
4188         vars->mac_type = MAC_TYPE_NONE;
4189
4190         /* update shared memory */
4191         vars->link_status = 0;
4192         vars->line_speed = 0;
4193         bnx2x_update_mng(params, vars->link_status);
4194
4195         /* activate nig drain */
4196         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4197
4198         /* reset BigMac */
4199         bnx2x_bmac_rx_disable(bp, params->port);
4200         REG_WR(bp, GRCBASE_MISC +
4201                    MISC_REGISTERS_RESET_REG_2_CLEAR,
4202                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4203         return 0;
4204 }
4205
4206 static u8 bnx2x_update_link_up(struct link_params *params,
4207                              struct link_vars *vars,
4208                              u8 link_10g, u32 gp_status)
4209 {
4210         struct bnx2x *bp = params->bp;
4211         u8 port = params->port;
4212         u8 rc = 0;
4213         vars->link_status |= LINK_STATUS_LINK_UP;
4214         if (link_10g) {
4215                 bnx2x_bmac_enable(params, vars, 0);
4216                 bnx2x_set_led(bp, port, LED_MODE_OPER,
4217                             SPEED_10000, params->hw_led_mode,
4218                             params->chip_id);
4219
4220         } else {
4221                 bnx2x_emac_enable(params, vars, 0);
4222                 rc = bnx2x_emac_program(params, vars->line_speed,
4223                                       vars->duplex);
4224
4225                 /* AN complete? */
4226                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4227                         if (!(vars->phy_flags &
4228                               PHY_SGMII_FLAG))
4229                                 bnx2x_set_sgmii_tx_driver(params);
4230                 }
4231         }
4232
4233         /* PBF - link up */
4234         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4235                               vars->line_speed);
4236
4237         /* disable drain */
4238         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4239
4240         /* update shared memory */
4241         bnx2x_update_mng(params, vars->link_status);
4242         return rc;
4243 }
4244 /* This function should called upon link interrupt */
4245 /* In case vars->link_up, driver needs to
4246         1. Update the pbf
4247         2. Disable drain
4248         3. Update the shared memory
4249         4. Indicate link up
4250         5. Set LEDs
4251    Otherwise,
4252         1. Update shared memory
4253         2. Reset BigMac
4254         3. Report link down
4255         4. Unset LEDs
4256 */
4257 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4258 {
4259         struct bnx2x *bp = params->bp;
4260         u8 port = params->port;
4261         u16 gp_status;
4262         u8 link_10g;
4263         u8 ext_phy_link_up, rc = 0;
4264         u32 ext_phy_type;
4265
4266         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4267          port,
4268         (vars->phy_flags & PHY_XGXS_FLAG),
4269          REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4270
4271         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4272         REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4273         REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4274         REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4275
4276         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4277           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4278           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4279
4280         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4281
4282         /* Check external link change only for non-direct */
4283         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4284
4285         /* Read gp_status */
4286         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4287                               MDIO_REG_BANK_GP_STATUS,
4288                               MDIO_GP_STATUS_TOP_AN_STATUS1,
4289                               &gp_status);
4290
4291         rc = bnx2x_link_settings_status(params, vars, gp_status);
4292         if (rc != 0)
4293                 return rc;
4294
4295         /* anything 10 and over uses the bmac */
4296         link_10g = ((vars->line_speed == SPEED_10000) ||
4297                     (vars->line_speed == SPEED_12000) ||
4298                     (vars->line_speed == SPEED_12500) ||
4299                     (vars->line_speed == SPEED_13000) ||
4300                     (vars->line_speed == SPEED_15000) ||
4301                     (vars->line_speed == SPEED_16000));
4302
4303         bnx2x_link_int_ack(params, vars, link_10g);
4304
4305         /* In case external phy link is up, and internal link is down
4306         ( not initialized yet probably after link initialization, it needs
4307         to be initialized.
4308         Note that after link down-up as result of cable plug,
4309         the xgxs link would probably become up again without the need to
4310         initialize it*/
4311
4312         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4313             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4314             (ext_phy_link_up && !vars->phy_link_up))
4315                 bnx2x_init_internal_phy(params, vars);
4316
4317         /* link is up only if both local phy and external phy are up */
4318         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4319
4320         if (vars->link_up)
4321                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4322         else
4323                 rc = bnx2x_update_link_down(params, vars);
4324
4325         return rc;
4326 }
4327
4328 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4329 {
4330         u8 ext_phy_addr[PORT_MAX];
4331         u16 val;
4332         s8 port;
4333
4334         /* PART1 - Reset both phys */
4335         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4336                 /* Extract the ext phy address for the port */
4337                 u32 ext_phy_config = REG_RD(bp, shmem_base +
4338                                         offsetof(struct shmem_region,
4339                    dev_info.port_hw_config[port].external_phy_config));
4340
4341                 /* disable attentions */
4342                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4343                              (NIG_MASK_XGXS0_LINK_STATUS |
4344                               NIG_MASK_XGXS0_LINK10G |
4345                               NIG_MASK_SERDES0_LINK_STATUS |
4346                               NIG_MASK_MI_INT));
4347
4348                 ext_phy_addr[port] =
4349                         ((ext_phy_config &
4350                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4351                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4352
4353                 /* Need to take the phy out of low power mode in order
4354                         to write to access its registers */
4355                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4356                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
4357
4358                 /* Reset the phy */
4359                 bnx2x_cl45_write(bp, port,
4360                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4361                                ext_phy_addr[port],
4362                                MDIO_PMA_DEVAD,
4363                                MDIO_PMA_REG_CTRL,
4364                                1<<15);
4365         }
4366
4367         /* Add delay of 150ms after reset */
4368         msleep(150);
4369
4370         /* PART2 - Download firmware to both phys */
4371         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4372                 u16 fw_ver1;
4373
4374                 bnx2x_bcm8073_external_rom_boot(bp, port,
4375                                                       ext_phy_addr[port]);
4376
4377                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4378                               ext_phy_addr[port],
4379                               MDIO_PMA_DEVAD,
4380                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
4381                 if (fw_ver1 == 0) {
4382                         DP(NETIF_MSG_LINK,
4383                                  "bnx2x_8073_common_init_phy port %x "
4384                                  "fw Download failed\n", port);
4385                         return -EINVAL;
4386                 }
4387
4388                 /* Only set bit 10 = 1 (Tx power down) */
4389                 bnx2x_cl45_read(bp, port,
4390                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4391                               ext_phy_addr[port],
4392                               MDIO_PMA_DEVAD,
4393                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
4394
4395                 /* Phase1 of TX_POWER_DOWN reset */
4396                 bnx2x_cl45_write(bp, port,
4397                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4398                                ext_phy_addr[port],
4399                                MDIO_PMA_DEVAD,
4400                                MDIO_PMA_REG_TX_POWER_DOWN,
4401                                (val | 1<<10));
4402         }
4403
4404         /* Toggle Transmitter: Power down and then up with 600ms
4405            delay between */
4406         msleep(600);
4407
4408         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
4409         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4410                 /* Phase2 of POWER_DOWN_RESET*/
4411                 /* Release bit 10 (Release Tx power down) */
4412                 bnx2x_cl45_read(bp, port,
4413                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4414                               ext_phy_addr[port],
4415                               MDIO_PMA_DEVAD,
4416                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
4417
4418                 bnx2x_cl45_write(bp, port,
4419                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4420                                ext_phy_addr[port],
4421                                MDIO_PMA_DEVAD,
4422                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
4423                 msleep(15);
4424
4425                 /* Read modify write the SPI-ROM version select register */
4426                 bnx2x_cl45_read(bp, port,
4427                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4428                               ext_phy_addr[port],
4429                               MDIO_PMA_DEVAD,
4430                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
4431                 bnx2x_cl45_write(bp, port,
4432                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4433                               ext_phy_addr[port],
4434                               MDIO_PMA_DEVAD,
4435                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
4436
4437                 /* set GPIO2 back to LOW */
4438                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4439                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
4440         }
4441         return 0;
4442
4443 }
4444
4445 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4446 {
4447         u8 rc = 0;
4448         u32 ext_phy_type;
4449
4450         DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
4451
4452         /* Read the ext_phy_type for arbitrary port(0) */
4453         ext_phy_type = XGXS_EXT_PHY_TYPE(
4454                         REG_RD(bp, shmem_base +
4455                            offsetof(struct shmem_region,
4456                              dev_info.port_hw_config[0].external_phy_config)));
4457
4458         switch (ext_phy_type) {
4459         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4460         {
4461                 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
4462                 break;
4463         }
4464         default:
4465                 DP(NETIF_MSG_LINK,
4466                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
4467                          ext_phy_type);
4468                 break;
4469         }
4470
4471         return rc;
4472 }
4473
4474
4475
4476 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4477 {
4478         u16 val, cnt;
4479
4480         bnx2x_cl45_read(bp, port,
4481                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4482                       phy_addr,
4483                       MDIO_PMA_DEVAD,
4484                       MDIO_PMA_REG_7101_RESET, &val);
4485
4486         for (cnt = 0; cnt < 10; cnt++) {
4487                 msleep(50);
4488                 /* Writes a self-clearing reset */
4489                 bnx2x_cl45_write(bp, port,
4490                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4491                                phy_addr,
4492                                MDIO_PMA_DEVAD,
4493                                MDIO_PMA_REG_7101_RESET,
4494                                (val | (1<<15)));
4495                 /* Wait for clear */
4496                 bnx2x_cl45_read(bp, port,
4497                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4498                               phy_addr,
4499                               MDIO_PMA_DEVAD,
4500                               MDIO_PMA_REG_7101_RESET, &val);
4501
4502                 if ((val & (1<<15)) == 0)
4503                         break;
4504         }
4505 }
4506 #define RESERVED_SIZE 256
4507 /* max application is 160K bytes - data at end of RAM */
4508 #define MAX_APP_SIZE 160*1024 - RESERVED_SIZE
4509
4510 /* Header is 14 bytes */
4511 #define HEADER_SIZE 14
4512 #define DATA_OFFSET HEADER_SIZE
4513
4514 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4515         bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4516                         ext_phy_addr, \
4517                         MDIO_PCS_DEVAD, \
4518                         MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4519
4520 /* Programs an image to DSP's flash via the SPI port*/
4521 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4522                                      u8 ext_phy_addr,
4523                                      char data[], u32 size)
4524 {
4525         const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
4526         /* Doesn't include last trans!*/
4527         const u16 last_trans_size = size%4; /* Num bytes on last trans */
4528         u16 trans_cnt, byte_cnt;
4529         u32 data_index;
4530         u16 tmp;
4531         u16 code_started = 0;
4532         u16 image_revision1, image_revision2;
4533         u16 cnt;
4534
4535         DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
4536         /* Going to flash*/
4537         if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
4538                 /* This very often will be the case, because the image is built
4539                 with 160Kbytes size whereas the total image size must actually
4540                 be 160Kbytes-RESERVED_SIZE */
4541                 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
4542                          "truncated to %d bytes\n", size, MAX_APP_SIZE);
4543                 size = MAX_APP_SIZE+HEADER_SIZE;
4544         }
4545         DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4546         DP(NETIF_MSG_LINK, "          %c%c\n", data[0x150], data[0x151]);
4547         /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4548            and issuing a reset.*/
4549
4550         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4551                           MISC_REGISTERS_GPIO_HIGH, port);
4552
4553         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4554
4555         /* wait 0.5 sec */
4556         for (cnt = 0; cnt < 100; cnt++)
4557                 msleep(5);
4558
4559         /* Make sure we can access the DSP
4560            And it's in the correct mode (waiting for download) */
4561
4562         bnx2x_cl45_read(bp, port,
4563                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4564                       ext_phy_addr,
4565                       MDIO_PCS_DEVAD,
4566                       MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
4567
4568         if (tmp != 0x000A) {
4569                 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
4570                          "Expected 0x000A, read 0x%04X\n", tmp);
4571                 DP(NETIF_MSG_LINK, "Download failed\n");
4572                 return -EINVAL;
4573         }
4574
4575         /* Mux the SPI interface away from the internal processor */
4576         bnx2x_cl45_write(bp, port,
4577                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4578                        ext_phy_addr,
4579                        MDIO_PCS_DEVAD,
4580                        MDIO_PCS_REG_7101_SPI_MUX, 1);
4581
4582         /* Reset the SPI port */
4583         bnx2x_cl45_write(bp, port,
4584                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4585                        ext_phy_addr,
4586                        MDIO_PCS_DEVAD,
4587                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4588         bnx2x_cl45_write(bp, port,
4589                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4590                        ext_phy_addr,
4591                        MDIO_PCS_DEVAD,
4592                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
4593                        (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
4594         bnx2x_cl45_write(bp, port,
4595                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4596                        ext_phy_addr,
4597                        MDIO_PCS_DEVAD,
4598                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4599
4600         /* Erase the flash */
4601         bnx2x_cl45_write(bp, port,
4602                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4603                        ext_phy_addr,
4604                        MDIO_PCS_DEVAD,
4605                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4606                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4607
4608         bnx2x_cl45_write(bp, port,
4609                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4610                        ext_phy_addr,
4611                        MDIO_PCS_DEVAD,
4612                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4613                        1);
4614
4615         SPI_START_TRANSFER(bp, port, ext_phy_addr);
4616         bnx2x_cl45_write(bp, port,
4617                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4618                        ext_phy_addr,
4619                        MDIO_PCS_DEVAD,
4620                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4621                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
4622
4623         bnx2x_cl45_write(bp, port,
4624                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4625                        ext_phy_addr,
4626                        MDIO_PCS_DEVAD,
4627                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4628                        1);
4629         SPI_START_TRANSFER(bp, port, ext_phy_addr);
4630
4631         /* Wait 10 seconds, the maximum time for the erase to complete */
4632         DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
4633         for (cnt = 0; cnt < 1000; cnt++)
4634                 msleep(10);
4635
4636         DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
4637         data_index = 0;
4638         for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
4639                 bnx2x_cl45_write(bp, port,
4640                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4641                              ext_phy_addr,
4642                              MDIO_PCS_DEVAD,
4643                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4644                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4645
4646                 bnx2x_cl45_write(bp, port,
4647                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4648                                ext_phy_addr,
4649                                MDIO_PCS_DEVAD,
4650                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4651                                1);
4652                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4653
4654                 bnx2x_cl45_write(bp, port,
4655                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4656                                ext_phy_addr,
4657                                MDIO_PCS_DEVAD,
4658                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4659                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4660
4661                 /* Bits 23-16 of address */
4662                 bnx2x_cl45_write(bp, port,
4663                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4664                                ext_phy_addr,
4665                                MDIO_PCS_DEVAD,
4666                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4667                                (data_index>>16));
4668                 /* Bits 15-8 of address */
4669                 bnx2x_cl45_write(bp, port,
4670                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4671                                ext_phy_addr,
4672                                MDIO_PCS_DEVAD,
4673                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4674                                (data_index>>8));
4675
4676                 /* Bits 7-0 of address */
4677                 bnx2x_cl45_write(bp, port,
4678                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4679                                ext_phy_addr,
4680                                MDIO_PCS_DEVAD,
4681                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4682                                ((u16)data_index));
4683
4684                 byte_cnt = 0;
4685                 while (byte_cnt < 4 && data_index < size) {
4686                         bnx2x_cl45_write(bp, port,
4687                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4688                                        ext_phy_addr,
4689                                MDIO_PCS_DEVAD,
4690                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4691                                data[data_index++]);
4692                         byte_cnt++;
4693                 }
4694
4695                 bnx2x_cl45_write(bp, port,
4696                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4697                                ext_phy_addr,
4698                                MDIO_PCS_DEVAD,
4699                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4700                                byte_cnt+4);
4701
4702                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4703                 msleep(5); /* Wait 5 ms minimum between transs */
4704
4705                 /* Let the user know something's going on.*/
4706                 /* a pacifier ever 4K */
4707                 if ((data_index % 1023) == 0)
4708                         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4709         }
4710
4711         DP(NETIF_MSG_LINK, "\n");
4712         /* Transfer the last block if there is data remaining */
4713         if (last_trans_size) {
4714                 bnx2x_cl45_write(bp, port,
4715                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4716                         ext_phy_addr,
4717                         MDIO_PCS_DEVAD,
4718                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4719                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4720
4721                 bnx2x_cl45_write(bp, port,
4722                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4723                                ext_phy_addr,
4724                                MDIO_PCS_DEVAD,
4725                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4726                                1);
4727
4728                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4729
4730                 bnx2x_cl45_write(bp, port,
4731                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4732                              ext_phy_addr,
4733                              MDIO_PCS_DEVAD,
4734                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4735                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4736
4737                 /* Bits 23-16 of address */
4738                 bnx2x_cl45_write(bp, port,
4739                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4740                                ext_phy_addr,
4741                                MDIO_PCS_DEVAD,
4742                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4743                                (data_index>>16));
4744                 /* Bits 15-8 of address */
4745                 bnx2x_cl45_write(bp, port,
4746                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4747                                ext_phy_addr,
4748                                MDIO_PCS_DEVAD,
4749                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4750                                (data_index>>8));
4751
4752                 /* Bits 7-0 of address */
4753                 bnx2x_cl45_write(bp, port,
4754                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4755                                ext_phy_addr,
4756                                MDIO_PCS_DEVAD,
4757                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4758                                ((u16)data_index));
4759
4760                 byte_cnt = 0;
4761                 while (byte_cnt < last_trans_size && data_index < size) {
4762                         /* Bits 7-0 of address */
4763                         bnx2x_cl45_write(bp, port,
4764                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4765                                 ext_phy_addr,
4766                                 MDIO_PCS_DEVAD,
4767                                 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4768                                 data[data_index++]);
4769                         byte_cnt++;
4770                 }
4771
4772                 bnx2x_cl45_write(bp, port,
4773                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4774                                ext_phy_addr,
4775                                MDIO_PCS_DEVAD,
4776                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4777                                byte_cnt+4);
4778
4779                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4780         }
4781
4782         /* DSP Remove Download Mode */
4783         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4784                           MISC_REGISTERS_GPIO_LOW, port);
4785
4786         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4787
4788         /* wait 0.5 sec to allow it to run */
4789         for (cnt = 0; cnt < 100; cnt++)
4790                 msleep(5);
4791
4792         bnx2x_hw_reset(bp, port);
4793
4794         for (cnt = 0; cnt < 100; cnt++)
4795                 msleep(5);
4796
4797         /* Check that the code is started. In case the download
4798         checksum failed, the code won't be started. */
4799         bnx2x_cl45_read(bp, port,
4800                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4801                       ext_phy_addr,
4802                       MDIO_PCS_DEVAD,
4803                       MDIO_PCS_REG_7101_DSP_ACCESS,
4804                       &tmp);
4805
4806         code_started = (tmp & (1<<4));
4807         if (!code_started) {
4808                 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
4809                 return -EINVAL;
4810         }
4811
4812         /* Verify that the file revision is now equal to the image
4813         revision within the DSP */
4814         bnx2x_cl45_read(bp, port,
4815                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4816                       ext_phy_addr,
4817                       MDIO_PMA_DEVAD,
4818                       MDIO_PMA_REG_7101_VER1,
4819                       &image_revision1);
4820
4821         bnx2x_cl45_read(bp, port,
4822                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4823                       ext_phy_addr,
4824                       MDIO_PMA_DEVAD,
4825                       MDIO_PMA_REG_7101_VER2,
4826                       &image_revision2);
4827
4828         if (data[0x14e] != (image_revision2&0xFF) ||
4829             data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4830             data[0x150] != (image_revision1&0xFF) ||
4831             data[0x151] != ((image_revision1&0xFF00)>>8)) {
4832                 DP(NETIF_MSG_LINK, "Download failed.\n");
4833                 return -EINVAL;
4834         }
4835         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4836         return 0;
4837 }
4838
4839 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4840                       u8 driver_loaded, char data[], u32 size)
4841 {
4842         u8 rc = 0;
4843         u32 ext_phy_type;
4844         u8 ext_phy_addr;
4845         ext_phy_addr = ((ext_phy_config &
4846                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4847                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4848
4849         ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4850
4851         switch (ext_phy_type) {
4852         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4853         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4854         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4855         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4856                 DP(NETIF_MSG_LINK,
4857                         "Flash download not supported for this ext phy\n");
4858                 rc = -EINVAL;
4859                 break;
4860         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4861                 /* Take ext phy out of reset */
4862                 if (!driver_loaded)
4863                         bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4864                 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4865                                                 data, size);
4866                 if (!driver_loaded)
4867                         bnx2x_turn_off_sf(bp, port);
4868                 break;
4869         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4870         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4871         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4872         default:
4873                 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
4874                 rc = -EINVAL;
4875                 break;
4876         }
4877         return rc;
4878 }
4879