]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/bnx2x_link.c
bnx2x: GMII not SGMII
[karo-tx-linux.git] / drivers / net / bnx2x_link.c
1 /* Copyright 2008-2009 Broadcom Corporation
2  *
3  * Unless you and Broadcom execute a separate written software license
4  * agreement governing use of this software, this software is licensed to you
5  * under the terms of the GNU General Public License version 2, available
6  * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7  *
8  * Notwithstanding the above, under no circumstances may you combine this
9  * software in any way with any other Broadcom software provided under a
10  * license other than the GPL, without Broadcom's express prior written
11  * consent.
12  *
13  * Written by Yaniv Rosner
14  *
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24
25 #include "bnx2x_reg.h"
26 #include "bnx2x_fw_defs.h"
27 #include "bnx2x_hsi.h"
28 #include "bnx2x_link.h"
29 #include "bnx2x.h"
30
31 /********************************************************/
32 #define ETH_HLEN                        14
33 #define ETH_OVREHEAD            (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
34 #define ETH_MIN_PACKET_SIZE             60
35 #define ETH_MAX_PACKET_SIZE             1500
36 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
37 #define MDIO_ACCESS_TIMEOUT             1000
38 #define BMAC_CONTROL_RX_ENABLE  2
39
40 /***********************************************************/
41 /*                      Shortcut definitions               */
42 /***********************************************************/
43
44 #define NIG_STATUS_XGXS0_LINK10G \
45                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
46 #define NIG_STATUS_XGXS0_LINK_STATUS \
47                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
48 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
49                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
50 #define NIG_STATUS_SERDES0_LINK_STATUS \
51                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
52 #define NIG_MASK_MI_INT \
53                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
54 #define NIG_MASK_XGXS0_LINK10G \
55                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
56 #define NIG_MASK_XGXS0_LINK_STATUS \
57                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
58 #define NIG_MASK_SERDES0_LINK_STATUS \
59                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
60
61 #define MDIO_AN_CL73_OR_37_COMPLETE \
62                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
63                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
64
65 #define XGXS_RESET_BITS \
66         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
67          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
68          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
69          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
70          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
71
72 #define SERDES_RESET_BITS \
73         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
74          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
75          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
76          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
77
78 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
79 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
80 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
81 #define AUTONEG_PARALLEL \
82                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
83 #define AUTONEG_SGMII_FIBER_AUTODET \
84                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
85 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
86
87 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
88                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
89 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
90                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
91 #define GP_STATUS_SPEED_MASK \
92                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
93 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
94 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
95 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
96 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
97 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
98 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
99 #define GP_STATUS_10G_HIG \
100                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
101 #define GP_STATUS_10G_CX4 \
102                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
103 #define GP_STATUS_12G_HIG \
104                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
105 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
106 #define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
107 #define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
108 #define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
109 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
110 #define GP_STATUS_10G_KX4 \
111                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
112
113 #define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
114 #define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
115 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
116 #define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
117 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
118 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
119 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
120 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
121 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
122 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
123 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
124 #define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
125 #define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
126 #define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
127 #define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
128 #define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
129 #define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
130 #define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
131 #define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
132 #define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
133 #define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
134 #define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
135 #define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
136
137 #define PHY_XGXS_FLAG                   0x1
138 #define PHY_SGMII_FLAG                  0x2
139 #define PHY_SERDES_FLAG                 0x4
140
141 /* */
142 #define SFP_EEPROM_CON_TYPE_ADDR                0x2
143         #define SFP_EEPROM_CON_TYPE_VAL_LC              0x7
144         #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
145
146 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
147         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
148         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE      0x8
149 #define SFP_EEPROM_VENDOR_NAME_ADDR             0x14
150 #define SFP_EEPROM_VENDOR_NAME_SIZE     16
151 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
152         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
153 #define SFP_EEPROM_OPTIONS_SIZE                 2
154
155 #define SFP_MODULE_TYPE_UNKNOWN                         0x0
156 #define SFP_MODULE_TYPE_LC                      0x1
157 #define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE             0x2
158 #define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE    0x3
159
160 #define SFP_LIMITING_MODE_VALUE                         0x0044
161 /**********************************************************/
162 /*                     INTERFACE                          */
163 /**********************************************************/
164 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
165         bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
166                 DEFAULT_PHY_DEV_ADDR, \
167                 (_bank + (_addr & 0xf)), \
168                 _val)
169
170 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
171         bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
172                 DEFAULT_PHY_DEV_ADDR, \
173                 (_bank + (_addr & 0xf)), \
174                 _val)
175
176 static void bnx2x_set_serdes_access(struct link_params *params)
177 {
178         struct bnx2x *bp = params->bp;
179         u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
180         /* Set Clause 22 */
181         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
182         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
183         udelay(500);
184         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
185         udelay(500);
186          /* Set Clause 45 */
187         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
188 }
189 static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
190 {
191         struct bnx2x *bp = params->bp;
192         if (phy_flags & PHY_XGXS_FLAG) {
193                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
194                            params->port*0x18, 0);
195                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
196                            DEFAULT_PHY_DEV_ADDR);
197         } else {
198                 bnx2x_set_serdes_access(params);
199
200                 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
201                            params->port*0x10,
202                            DEFAULT_PHY_DEV_ADDR);
203         }
204 }
205
206 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
207 {
208         u32 val = REG_RD(bp, reg);
209
210         val |= bits;
211         REG_WR(bp, reg, val);
212         return val;
213 }
214
215 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
216 {
217         u32 val = REG_RD(bp, reg);
218
219         val &= ~bits;
220         REG_WR(bp, reg, val);
221         return val;
222 }
223
224 static void bnx2x_emac_init(struct link_params *params,
225                            struct link_vars *vars)
226 {
227         /* reset and unreset the emac core */
228         struct bnx2x *bp = params->bp;
229         u8 port = params->port;
230         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
231         u32 val;
232         u16 timeout;
233
234         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
235                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
236         udelay(5);
237         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
238                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
239
240         /* init emac - use read-modify-write */
241         /* self clear reset */
242         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
243         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
244
245         timeout = 200;
246         do {
247                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
248                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
249                 if (!timeout) {
250                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
251                         return;
252                 }
253                 timeout--;
254         } while (val & EMAC_MODE_RESET);
255
256         /* Set mac address */
257         val = ((params->mac_addr[0] << 8) |
258                 params->mac_addr[1]);
259         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
260
261         val = ((params->mac_addr[2] << 24) |
262                (params->mac_addr[3] << 16) |
263                (params->mac_addr[4] << 8) |
264                 params->mac_addr[5]);
265         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
266 }
267
268 static u8 bnx2x_emac_enable(struct link_params *params,
269                           struct link_vars *vars, u8 lb)
270 {
271         struct bnx2x *bp = params->bp;
272         u8 port = params->port;
273         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
274         u32 val;
275
276         DP(NETIF_MSG_LINK, "enabling EMAC\n");
277
278         /* enable emac and not bmac */
279         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
280
281         /* for paladium */
282         if (CHIP_REV_IS_EMUL(bp)) {
283                 /* Use lane 1 (of lanes 0-3) */
284                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
285                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
286                             port*4, 1);
287         }
288         /* for fpga */
289         else
290
291         if (CHIP_REV_IS_FPGA(bp)) {
292                 /* Use lane 1 (of lanes 0-3) */
293                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
294
295                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
296                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
297                             0);
298         } else
299         /* ASIC */
300         if (vars->phy_flags & PHY_XGXS_FLAG) {
301                 u32 ser_lane = ((params->lane_config &
302                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
303                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
304
305                 DP(NETIF_MSG_LINK, "XGXS\n");
306                 /* select the master lanes (out of 0-3) */
307                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
308                            port*4, ser_lane);
309                 /* select XGXS */
310                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
311                            port*4, 1);
312
313         } else { /* SerDes */
314                 DP(NETIF_MSG_LINK, "SerDes\n");
315                 /* select SerDes */
316                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
317                            port*4, 0);
318         }
319
320         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
321                     EMAC_RX_MODE_RESET);
322         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
323                     EMAC_TX_MODE_RESET);
324
325         if (CHIP_REV_IS_SLOW(bp)) {
326                 /* config GMII mode */
327                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
328                 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
329                             (val | EMAC_MODE_PORT_GMII));
330         } else { /* ASIC */
331                 /* pause enable/disable */
332                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
333                                EMAC_RX_MODE_FLOW_EN);
334                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
335                         bnx2x_bits_en(bp, emac_base +
336                                     EMAC_REG_EMAC_RX_MODE,
337                                     EMAC_RX_MODE_FLOW_EN);
338
339                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
340                              (EMAC_TX_MODE_EXT_PAUSE_EN |
341                               EMAC_TX_MODE_FLOW_EN));
342                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
343                         bnx2x_bits_en(bp, emac_base +
344                                     EMAC_REG_EMAC_TX_MODE,
345                                    (EMAC_TX_MODE_EXT_PAUSE_EN |
346                                     EMAC_TX_MODE_FLOW_EN));
347         }
348
349         /* KEEP_VLAN_TAG, promiscuous */
350         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
351         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
352         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
353
354         /* Set Loopback */
355         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
356         if (lb)
357                 val |= 0x810;
358         else
359                 val &= ~0x810;
360         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
361
362         /* enable emac */
363         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
364
365         /* enable emac for jumbo packets */
366         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
367                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
368                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
369
370         /* strip CRC */
371         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
372
373         /* disable the NIG in/out to the bmac */
374         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
375         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
376         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
377
378         /* enable the NIG in/out to the emac */
379         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
380         val = 0;
381         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
382                 val = 1;
383
384         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
385         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
386
387         if (CHIP_REV_IS_EMUL(bp)) {
388                 /* take the BigMac out of reset */
389                 REG_WR(bp,
390                            GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
391                            (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
392
393                 /* enable access for bmac registers */
394                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
395         }
396
397         vars->mac_type = MAC_TYPE_EMAC;
398         return 0;
399 }
400
401
402
403 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
404                           u8 is_lb)
405 {
406         struct bnx2x *bp = params->bp;
407         u8 port = params->port;
408         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
409                                NIG_REG_INGRESS_BMAC0_MEM;
410         u32 wb_data[2];
411         u32 val;
412
413         DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
414         /* reset and unreset the BigMac */
415         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
416                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
417         msleep(1);
418
419         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
420                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
421
422         /* enable access for bmac registers */
423         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
424
425         /* XGXS control */
426         wb_data[0] = 0x3c;
427         wb_data[1] = 0;
428         REG_WR_DMAE(bp, bmac_addr +
429                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
430                       wb_data, 2);
431
432         /* tx MAC SA */
433         wb_data[0] = ((params->mac_addr[2] << 24) |
434                        (params->mac_addr[3] << 16) |
435                        (params->mac_addr[4] << 8) |
436                         params->mac_addr[5]);
437         wb_data[1] = ((params->mac_addr[0] << 8) |
438                         params->mac_addr[1]);
439         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
440                     wb_data, 2);
441
442         /* tx control */
443         val = 0xc0;
444         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
445                 val |= 0x800000;
446         wb_data[0] = val;
447         wb_data[1] = 0;
448         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
449                         wb_data, 2);
450
451         /* mac control */
452         val = 0x3;
453         if (is_lb) {
454                 val |= 0x4;
455                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
456         }
457         wb_data[0] = val;
458         wb_data[1] = 0;
459         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
460                     wb_data, 2);
461
462
463         /* set rx mtu */
464         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
465         wb_data[1] = 0;
466         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
467                         wb_data, 2);
468
469         /* rx control set to don't strip crc */
470         val = 0x14;
471         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
472                 val |= 0x20;
473         wb_data[0] = val;
474         wb_data[1] = 0;
475         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
476                         wb_data, 2);
477
478         /* set tx mtu */
479         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
480         wb_data[1] = 0;
481         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
482                         wb_data, 2);
483
484         /* set cnt max size */
485         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
486         wb_data[1] = 0;
487         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
488                     wb_data, 2);
489
490         /* configure safc */
491         wb_data[0] = 0x1000200;
492         wb_data[1] = 0;
493         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
494                     wb_data, 2);
495         /* fix for emulation */
496         if (CHIP_REV_IS_EMUL(bp)) {
497                 wb_data[0] = 0xf000;
498                 wb_data[1] = 0;
499                 REG_WR_DMAE(bp,
500                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
501                             wb_data, 2);
502         }
503
504         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
505         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
506         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
507         val = 0;
508         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
509                 val = 1;
510         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
511         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
512         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
513         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
514         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
515         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
516
517         vars->mac_type = MAC_TYPE_BMAC;
518         return 0;
519 }
520
521 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
522 {
523         struct bnx2x *bp = params->bp;
524         u32 val;
525
526         if (phy_flags & PHY_XGXS_FLAG) {
527                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
528                 val = XGXS_RESET_BITS;
529
530         } else { /* SerDes */
531                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
532                 val = SERDES_RESET_BITS;
533         }
534
535         val = val << (params->port*16);
536
537         /* reset and unreset the SerDes/XGXS */
538         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
539                     val);
540         udelay(500);
541         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
542                     val);
543         bnx2x_set_phy_mdio(params, phy_flags);
544 }
545
546 void bnx2x_link_status_update(struct link_params *params,
547                             struct link_vars   *vars)
548 {
549         struct bnx2x *bp = params->bp;
550         u8 link_10g;
551         u8 port = params->port;
552
553         if (params->switch_cfg ==  SWITCH_CFG_1G)
554                 vars->phy_flags = PHY_SERDES_FLAG;
555         else
556                 vars->phy_flags = PHY_XGXS_FLAG;
557         vars->link_status = REG_RD(bp, params->shmem_base +
558                                           offsetof(struct shmem_region,
559                                            port_mb[port].link_status));
560
561         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
562
563         if (vars->link_up) {
564                 DP(NETIF_MSG_LINK, "phy link up\n");
565
566                 vars->phy_link_up = 1;
567                 vars->duplex = DUPLEX_FULL;
568                 switch (vars->link_status &
569                                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
570                         case LINK_10THD:
571                                 vars->duplex = DUPLEX_HALF;
572                                 /* fall thru */
573                         case LINK_10TFD:
574                                 vars->line_speed = SPEED_10;
575                                 break;
576
577                         case LINK_100TXHD:
578                                 vars->duplex = DUPLEX_HALF;
579                                 /* fall thru */
580                         case LINK_100T4:
581                         case LINK_100TXFD:
582                                 vars->line_speed = SPEED_100;
583                                 break;
584
585                         case LINK_1000THD:
586                                 vars->duplex = DUPLEX_HALF;
587                                 /* fall thru */
588                         case LINK_1000TFD:
589                                 vars->line_speed = SPEED_1000;
590                                 break;
591
592                         case LINK_2500THD:
593                                 vars->duplex = DUPLEX_HALF;
594                                 /* fall thru */
595                         case LINK_2500TFD:
596                                 vars->line_speed = SPEED_2500;
597                                 break;
598
599                         case LINK_10GTFD:
600                                 vars->line_speed = SPEED_10000;
601                                 break;
602
603                         case LINK_12GTFD:
604                                 vars->line_speed = SPEED_12000;
605                                 break;
606
607                         case LINK_12_5GTFD:
608                                 vars->line_speed = SPEED_12500;
609                                 break;
610
611                         case LINK_13GTFD:
612                                 vars->line_speed = SPEED_13000;
613                                 break;
614
615                         case LINK_15GTFD:
616                                 vars->line_speed = SPEED_15000;
617                                 break;
618
619                         case LINK_16GTFD:
620                                 vars->line_speed = SPEED_16000;
621                                 break;
622
623                         default:
624                                 break;
625                 }
626
627                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
628                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
629                 else
630                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
631
632                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
633                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
634                 else
635                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
636
637                 if (vars->phy_flags & PHY_XGXS_FLAG) {
638                         if (vars->line_speed &&
639                             ((vars->line_speed == SPEED_10) ||
640                              (vars->line_speed == SPEED_100))) {
641                                 vars->phy_flags |= PHY_SGMII_FLAG;
642                         } else {
643                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
644                         }
645                 }
646
647                 /* anything 10 and over uses the bmac */
648                 link_10g = ((vars->line_speed == SPEED_10000) ||
649                             (vars->line_speed == SPEED_12000) ||
650                             (vars->line_speed == SPEED_12500) ||
651                             (vars->line_speed == SPEED_13000) ||
652                             (vars->line_speed == SPEED_15000) ||
653                             (vars->line_speed == SPEED_16000));
654                 if (link_10g)
655                         vars->mac_type = MAC_TYPE_BMAC;
656                 else
657                         vars->mac_type = MAC_TYPE_EMAC;
658
659         } else { /* link down */
660                 DP(NETIF_MSG_LINK, "phy link down\n");
661
662                 vars->phy_link_up = 0;
663
664                 vars->line_speed = 0;
665                 vars->duplex = DUPLEX_FULL;
666                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
667
668                 /* indicate no mac active */
669                 vars->mac_type = MAC_TYPE_NONE;
670         }
671
672         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
673                  vars->link_status, vars->phy_link_up);
674         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
675                  vars->line_speed, vars->duplex, vars->flow_ctrl);
676 }
677
678 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
679 {
680         struct bnx2x *bp = params->bp;
681         REG_WR(bp, params->shmem_base +
682                    offsetof(struct shmem_region,
683                             port_mb[params->port].link_status),
684                         link_status);
685 }
686
687 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
688 {
689         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
690                 NIG_REG_INGRESS_BMAC0_MEM;
691         u32 wb_data[2];
692         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
693
694         /* Only if the bmac is out of reset */
695         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
696                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
697             nig_bmac_enable) {
698
699                 /* Clear Rx Enable bit in BMAC_CONTROL register */
700                 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
701                             wb_data, 2);
702                 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
703                 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
704                             wb_data, 2);
705
706                 msleep(1);
707         }
708 }
709
710 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
711                          u32 line_speed)
712 {
713         struct bnx2x *bp = params->bp;
714         u8 port = params->port;
715         u32 init_crd, crd;
716         u32 count = 1000;
717
718         /* disable port */
719         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
720
721         /* wait for init credit */
722         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
723         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
724         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
725
726         while ((init_crd != crd) && count) {
727                 msleep(5);
728
729                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
730                 count--;
731         }
732         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
733         if (init_crd != crd) {
734                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
735                           init_crd, crd);
736                 return -EINVAL;
737         }
738
739         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
740             line_speed == SPEED_10 ||
741             line_speed == SPEED_100 ||
742             line_speed == SPEED_1000 ||
743             line_speed == SPEED_2500) {
744                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
745                 /* update threshold */
746                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
747                 /* update init credit */
748                 init_crd = 778;         /* (800-18-4) */
749
750         } else {
751                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
752                               ETH_OVREHEAD)/16;
753                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
754                 /* update threshold */
755                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
756                 /* update init credit */
757                 switch (line_speed) {
758                 case SPEED_10000:
759                         init_crd = thresh + 553 - 22;
760                         break;
761
762                 case SPEED_12000:
763                         init_crd = thresh + 664 - 22;
764                         break;
765
766                 case SPEED_13000:
767                         init_crd = thresh + 742 - 22;
768                         break;
769
770                 case SPEED_16000:
771                         init_crd = thresh + 778 - 22;
772                         break;
773                 default:
774                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
775                                   line_speed);
776                         return -EINVAL;
777                         break;
778                 }
779         }
780         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
781         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
782                  line_speed, init_crd);
783
784         /* probe the credit changes */
785         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
786         msleep(5);
787         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
788
789         /* enable port */
790         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
791         return 0;
792 }
793
794 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
795 {
796         u32 emac_base;
797         switch (ext_phy_type) {
798         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
799         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
800                 /* All MDC/MDIO is directed through single EMAC */
801                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
802                         emac_base = GRCBASE_EMAC0;
803                 else
804                         emac_base = GRCBASE_EMAC1;
805                 break;
806         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
807                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
808                 break;
809         default:
810                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
811                 break;
812         }
813         return emac_base;
814
815 }
816
817 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
818                   u8 phy_addr, u8 devad, u16 reg, u16 val)
819 {
820         u32 tmp, saved_mode;
821         u8 i, rc = 0;
822         u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
823
824         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
825          * (a value of 49==0x31) and make sure that the AUTO poll is off
826          */
827
828         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
829         tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
830                              EMAC_MDIO_MODE_CLOCK_CNT);
831         tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
832                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
833         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
834         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
835         udelay(40);
836
837         /* address */
838
839         tmp = ((phy_addr << 21) | (devad << 16) | reg |
840                EMAC_MDIO_COMM_COMMAND_ADDRESS |
841                EMAC_MDIO_COMM_START_BUSY);
842         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
843
844         for (i = 0; i < 50; i++) {
845                 udelay(10);
846
847                 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
848                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
849                         udelay(5);
850                         break;
851                 }
852         }
853         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
854                 DP(NETIF_MSG_LINK, "write phy register failed\n");
855                 rc = -EFAULT;
856         } else {
857                 /* data */
858                 tmp = ((phy_addr << 21) | (devad << 16) | val |
859                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
860                        EMAC_MDIO_COMM_START_BUSY);
861                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
862
863                 for (i = 0; i < 50; i++) {
864                         udelay(10);
865
866                         tmp = REG_RD(bp, mdio_ctrl +
867                                          EMAC_REG_EMAC_MDIO_COMM);
868                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
869                                 udelay(5);
870                                 break;
871                         }
872                 }
873                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
874                         DP(NETIF_MSG_LINK, "write phy register failed\n");
875                         rc = -EFAULT;
876                 }
877         }
878
879         /* Restore the saved mode */
880         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
881
882         return rc;
883 }
884
885 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
886                  u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
887 {
888         u32 val, saved_mode;
889         u16 i;
890         u8 rc = 0;
891
892         u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
893         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
894          * (a value of 49==0x31) and make sure that the AUTO poll is off
895          */
896
897         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
898         val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
899                              EMAC_MDIO_MODE_CLOCK_CNT));
900         val |= (EMAC_MDIO_MODE_CLAUSE_45 |
901                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
902         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
903         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
904         udelay(40);
905
906         /* address */
907         val = ((phy_addr << 21) | (devad << 16) | reg |
908                EMAC_MDIO_COMM_COMMAND_ADDRESS |
909                EMAC_MDIO_COMM_START_BUSY);
910         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
911
912         for (i = 0; i < 50; i++) {
913                 udelay(10);
914
915                 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
916                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
917                         udelay(5);
918                         break;
919                 }
920         }
921         if (val & EMAC_MDIO_COMM_START_BUSY) {
922                 DP(NETIF_MSG_LINK, "read phy register failed\n");
923
924                 *ret_val = 0;
925                 rc = -EFAULT;
926
927         } else {
928                 /* data */
929                 val = ((phy_addr << 21) | (devad << 16) |
930                        EMAC_MDIO_COMM_COMMAND_READ_45 |
931                        EMAC_MDIO_COMM_START_BUSY);
932                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
933
934                 for (i = 0; i < 50; i++) {
935                         udelay(10);
936
937                         val = REG_RD(bp, mdio_ctrl +
938                                           EMAC_REG_EMAC_MDIO_COMM);
939                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
940                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
941                                 break;
942                         }
943                 }
944                 if (val & EMAC_MDIO_COMM_START_BUSY) {
945                         DP(NETIF_MSG_LINK, "read phy register failed\n");
946
947                         *ret_val = 0;
948                         rc = -EFAULT;
949                 }
950         }
951
952         /* Restore the saved mode */
953         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
954
955         return rc;
956 }
957
958 static void bnx2x_set_aer_mmd(struct link_params *params,
959                             struct link_vars   *vars)
960 {
961         struct bnx2x *bp = params->bp;
962         u32 ser_lane;
963         u16 offset;
964
965         ser_lane = ((params->lane_config &
966                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
967                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
968
969         offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
970                 (params->phy_addr + ser_lane) : 0;
971
972         CL45_WR_OVER_CL22(bp, params->port,
973                               params->phy_addr,
974                               MDIO_REG_BANK_AER_BLOCK,
975                               MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
976 }
977
978 static void bnx2x_set_master_ln(struct link_params *params)
979 {
980         struct bnx2x *bp = params->bp;
981         u16 new_master_ln, ser_lane;
982         ser_lane =  ((params->lane_config &
983                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
984                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
985
986         /* set the master_ln for AN */
987         CL45_RD_OVER_CL22(bp, params->port,
988                               params->phy_addr,
989                               MDIO_REG_BANK_XGXS_BLOCK2,
990                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
991                               &new_master_ln);
992
993         CL45_WR_OVER_CL22(bp, params->port,
994                               params->phy_addr,
995                               MDIO_REG_BANK_XGXS_BLOCK2 ,
996                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
997                               (new_master_ln | ser_lane));
998 }
999
1000 static u8 bnx2x_reset_unicore(struct link_params *params)
1001 {
1002         struct bnx2x *bp = params->bp;
1003         u16 mii_control;
1004         u16 i;
1005
1006         CL45_RD_OVER_CL22(bp, params->port,
1007                               params->phy_addr,
1008                               MDIO_REG_BANK_COMBO_IEEE0,
1009                               MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1010
1011         /* reset the unicore */
1012         CL45_WR_OVER_CL22(bp, params->port,
1013                               params->phy_addr,
1014                               MDIO_REG_BANK_COMBO_IEEE0,
1015                               MDIO_COMBO_IEEE0_MII_CONTROL,
1016                               (mii_control |
1017                                MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1018
1019         bnx2x_set_serdes_access(params);
1020
1021         /* wait for the reset to self clear */
1022         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1023                 udelay(5);
1024
1025                 /* the reset erased the previous bank value */
1026                 CL45_RD_OVER_CL22(bp, params->port,
1027                                       params->phy_addr,
1028                               MDIO_REG_BANK_COMBO_IEEE0,
1029                               MDIO_COMBO_IEEE0_MII_CONTROL,
1030                               &mii_control);
1031
1032                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1033                         udelay(5);
1034                         return 0;
1035                 }
1036         }
1037
1038         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1039         return -EINVAL;
1040
1041 }
1042
1043 static void bnx2x_set_swap_lanes(struct link_params *params)
1044 {
1045         struct bnx2x *bp = params->bp;
1046         /* Each two bits represents a lane number:
1047            No swap is 0123 => 0x1b no need to enable the swap */
1048         u16 ser_lane, rx_lane_swap, tx_lane_swap;
1049
1050         ser_lane = ((params->lane_config &
1051                          PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1052                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1053         rx_lane_swap = ((params->lane_config &
1054                              PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1055                             PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1056         tx_lane_swap = ((params->lane_config &
1057                              PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1058                             PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1059
1060         if (rx_lane_swap != 0x1b) {
1061                 CL45_WR_OVER_CL22(bp, params->port,
1062                                       params->phy_addr,
1063                                     MDIO_REG_BANK_XGXS_BLOCK2,
1064                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1065                                     (rx_lane_swap |
1066                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1067                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1068         } else {
1069                 CL45_WR_OVER_CL22(bp, params->port,
1070                                       params->phy_addr,
1071                                       MDIO_REG_BANK_XGXS_BLOCK2,
1072                                       MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1073         }
1074
1075         if (tx_lane_swap != 0x1b) {
1076                 CL45_WR_OVER_CL22(bp, params->port,
1077                                       params->phy_addr,
1078                                       MDIO_REG_BANK_XGXS_BLOCK2,
1079                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1080                                       (tx_lane_swap |
1081                                        MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1082         } else {
1083                 CL45_WR_OVER_CL22(bp, params->port,
1084                                       params->phy_addr,
1085                                       MDIO_REG_BANK_XGXS_BLOCK2,
1086                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1087         }
1088 }
1089
1090 static void bnx2x_set_parallel_detection(struct link_params *params,
1091                                        u8                phy_flags)
1092 {
1093         struct bnx2x *bp = params->bp;
1094         u16 control2;
1095
1096         CL45_RD_OVER_CL22(bp, params->port,
1097                               params->phy_addr,
1098                               MDIO_REG_BANK_SERDES_DIGITAL,
1099                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1100                               &control2);
1101
1102
1103         control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1104
1105
1106         CL45_WR_OVER_CL22(bp, params->port,
1107                               params->phy_addr,
1108                               MDIO_REG_BANK_SERDES_DIGITAL,
1109                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1110                               control2);
1111
1112         if (phy_flags & PHY_XGXS_FLAG) {
1113                 DP(NETIF_MSG_LINK, "XGXS\n");
1114
1115                 CL45_WR_OVER_CL22(bp, params->port,
1116                                       params->phy_addr,
1117                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1118                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1119                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1120
1121                 CL45_RD_OVER_CL22(bp, params->port,
1122                                       params->phy_addr,
1123                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1124                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1125                                 &control2);
1126
1127
1128                 control2 |=
1129                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1130
1131                 CL45_WR_OVER_CL22(bp, params->port,
1132                                       params->phy_addr,
1133                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1134                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1135                                 control2);
1136
1137                 /* Disable parallel detection of HiG */
1138                 CL45_WR_OVER_CL22(bp, params->port,
1139                                       params->phy_addr,
1140                                 MDIO_REG_BANK_XGXS_BLOCK2,
1141                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1142                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1143                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1144         }
1145 }
1146
1147 static void bnx2x_set_autoneg(struct link_params *params,
1148                             struct link_vars   *vars)
1149 {
1150         struct bnx2x *bp = params->bp;
1151         u16 reg_val;
1152
1153         /* CL37 Autoneg */
1154
1155         CL45_RD_OVER_CL22(bp, params->port,
1156                               params->phy_addr,
1157                               MDIO_REG_BANK_COMBO_IEEE0,
1158                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1159
1160         /* CL37 Autoneg Enabled */
1161         if (vars->line_speed == SPEED_AUTO_NEG)
1162                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1163         else /* CL37 Autoneg Disabled */
1164                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1165                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1166
1167         CL45_WR_OVER_CL22(bp, params->port,
1168                               params->phy_addr,
1169                               MDIO_REG_BANK_COMBO_IEEE0,
1170                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1171
1172         /* Enable/Disable Autodetection */
1173
1174         CL45_RD_OVER_CL22(bp, params->port,
1175                               params->phy_addr,
1176                               MDIO_REG_BANK_SERDES_DIGITAL,
1177                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1178         reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1179         if (vars->line_speed == SPEED_AUTO_NEG)
1180                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1181         else
1182                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1183
1184         CL45_WR_OVER_CL22(bp, params->port,
1185                               params->phy_addr,
1186                               MDIO_REG_BANK_SERDES_DIGITAL,
1187                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1188
1189         /* Enable TetonII and BAM autoneg */
1190         CL45_RD_OVER_CL22(bp, params->port,
1191                               params->phy_addr,
1192                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1193                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1194                           &reg_val);
1195         if (vars->line_speed == SPEED_AUTO_NEG) {
1196                 /* Enable BAM aneg Mode and TetonII aneg Mode */
1197                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1198                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1199         } else {
1200                 /* TetonII and BAM Autoneg Disabled */
1201                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1202                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1203         }
1204         CL45_WR_OVER_CL22(bp, params->port,
1205                               params->phy_addr,
1206                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1207                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1208                               reg_val);
1209
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 BNX2X_FLOW_CTRL_AUTO:
1305                 if (params->req_fc_auto_adv == BNX2X_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 BNX2X_FLOW_CTRL_TX:
1314                 *ieee_fc |=
1315                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1316                 break;
1317
1318         case BNX2X_FLOW_CTRL_RX:
1319         case BNX2X_FLOW_CTRL_BOTH:
1320                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1321                 break;
1322
1323         case BNX2X_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         u16 mii_control;
1346         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1347         /* Enable and restart BAM/CL37 aneg */
1348
1349         CL45_RD_OVER_CL22(bp, params->port,
1350                               params->phy_addr,
1351                               MDIO_REG_BANK_COMBO_IEEE0,
1352                               MDIO_COMBO_IEEE0_MII_CONTROL,
1353                               &mii_control);
1354         DP(NETIF_MSG_LINK,
1355                  "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1356                  mii_control);
1357         CL45_WR_OVER_CL22(bp, params->port,
1358                               params->phy_addr,
1359                               MDIO_REG_BANK_COMBO_IEEE0,
1360                               MDIO_COMBO_IEEE0_MII_CONTROL,
1361                               (mii_control |
1362                                MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1363                                MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1364 }
1365
1366 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1367                                          struct link_vars *vars)
1368 {
1369         struct bnx2x *bp = params->bp;
1370         u16 control1;
1371
1372         /* in SGMII mode, the unicore is always slave */
1373
1374         CL45_RD_OVER_CL22(bp, params->port,
1375                               params->phy_addr,
1376                               MDIO_REG_BANK_SERDES_DIGITAL,
1377                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1378                       &control1);
1379         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1380         /* set sgmii mode (and not fiber) */
1381         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1382                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1383                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1384         CL45_WR_OVER_CL22(bp, params->port,
1385                               params->phy_addr,
1386                               MDIO_REG_BANK_SERDES_DIGITAL,
1387                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1388                               control1);
1389
1390         /* if forced speed */
1391         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1392                 /* set speed, disable autoneg */
1393                 u16 mii_control;
1394
1395                 CL45_RD_OVER_CL22(bp, params->port,
1396                                       params->phy_addr,
1397                                       MDIO_REG_BANK_COMBO_IEEE0,
1398                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1399                                       &mii_control);
1400                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1401                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1402                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1403
1404                 switch (vars->line_speed) {
1405                 case SPEED_100:
1406                         mii_control |=
1407                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1408                         break;
1409                 case SPEED_1000:
1410                         mii_control |=
1411                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1412                         break;
1413                 case SPEED_10:
1414                         /* there is nothing to set for 10M */
1415                         break;
1416                 default:
1417                         /* invalid speed for SGMII */
1418                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1419                                   vars->line_speed);
1420                         break;
1421                 }
1422
1423                 /* setting the full duplex */
1424                 if (params->req_duplex == DUPLEX_FULL)
1425                         mii_control |=
1426                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1427                 CL45_WR_OVER_CL22(bp, params->port,
1428                                       params->phy_addr,
1429                                       MDIO_REG_BANK_COMBO_IEEE0,
1430                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1431                                       mii_control);
1432
1433         } else { /* AN mode */
1434                 /* enable and restart AN */
1435                 bnx2x_restart_autoneg(params);
1436         }
1437 }
1438
1439
1440 /*
1441  * link management
1442  */
1443
1444 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1445 {                                               /*  LD      LP   */
1446         switch (pause_result) {                 /* ASYM P ASYM P */
1447         case 0xb:                               /*   1  0   1  1 */
1448                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1449                 break;
1450
1451         case 0xe:                               /*   1  1   1  0 */
1452                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1453                 break;
1454
1455         case 0x5:                               /*   0  1   0  1 */
1456         case 0x7:                               /*   0  1   1  1 */
1457         case 0xd:                               /*   1  1   0  1 */
1458         case 0xf:                               /*   1  1   1  1 */
1459                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1460                 break;
1461
1462         default:
1463                 break;
1464         }
1465 }
1466
1467 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1468                                   struct link_vars *vars)
1469 {
1470         struct bnx2x *bp = params->bp;
1471         u8 ext_phy_addr;
1472         u16 ld_pause;   /* local */
1473         u16 lp_pause;   /* link partner */
1474         u16 an_complete; /* AN complete */
1475         u16 pause_result;
1476         u8 ret = 0;
1477         u32 ext_phy_type;
1478         u8 port = params->port;
1479         ext_phy_addr = ((params->ext_phy_config &
1480                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1481                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1482
1483         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1484         /* read twice */
1485
1486         bnx2x_cl45_read(bp, port,
1487                       ext_phy_type,
1488                       ext_phy_addr,
1489                       MDIO_AN_DEVAD,
1490                       MDIO_AN_REG_STATUS, &an_complete);
1491         bnx2x_cl45_read(bp, port,
1492                       ext_phy_type,
1493                       ext_phy_addr,
1494                       MDIO_AN_DEVAD,
1495                       MDIO_AN_REG_STATUS, &an_complete);
1496
1497         if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1498                 ret = 1;
1499                 bnx2x_cl45_read(bp, port,
1500                               ext_phy_type,
1501                               ext_phy_addr,
1502                               MDIO_AN_DEVAD,
1503                               MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1504                 bnx2x_cl45_read(bp, port,
1505                               ext_phy_type,
1506                               ext_phy_addr,
1507                               MDIO_AN_DEVAD,
1508                               MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1509                 pause_result = (ld_pause &
1510                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1511                 pause_result |= (lp_pause &
1512                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1513                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1514                    pause_result);
1515                 bnx2x_pause_resolve(vars, pause_result);
1516                 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1517                      ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1518                         bnx2x_cl45_read(bp, port,
1519                                       ext_phy_type,
1520                                       ext_phy_addr,
1521                                       MDIO_AN_DEVAD,
1522                                       MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1523
1524                         bnx2x_cl45_read(bp, port,
1525                                       ext_phy_type,
1526                                       ext_phy_addr,
1527                                       MDIO_AN_DEVAD,
1528                                       MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1529                         pause_result = (ld_pause &
1530                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1531                         pause_result |= (lp_pause &
1532                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1533
1534                         bnx2x_pause_resolve(vars, pause_result);
1535                         DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1536                                  pause_result);
1537                 }
1538         }
1539         return ret;
1540 }
1541
1542
1543 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1544                                   struct link_vars *vars,
1545                                   u32 gp_status)
1546 {
1547         struct bnx2x *bp = params->bp;
1548         u16 ld_pause;   /* local driver */
1549         u16 lp_pause;   /* link partner */
1550         u16 pause_result;
1551
1552         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1553
1554         /* resolve from gp_status in case of AN complete and not sgmii */
1555         if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1556             (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1557             (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1558             (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1559              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1560                 CL45_RD_OVER_CL22(bp, params->port,
1561                                       params->phy_addr,
1562                                       MDIO_REG_BANK_COMBO_IEEE0,
1563                                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1564                                       &ld_pause);
1565                 CL45_RD_OVER_CL22(bp, params->port,
1566                                       params->phy_addr,
1567                         MDIO_REG_BANK_COMBO_IEEE0,
1568                         MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1569                         &lp_pause);
1570                 pause_result = (ld_pause &
1571                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1572                 pause_result |= (lp_pause &
1573                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1574                 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1575                 bnx2x_pause_resolve(vars, pause_result);
1576         } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1577                    (bnx2x_ext_phy_resove_fc(params, vars))) {
1578                 return;
1579         } else {
1580                 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1581                         vars->flow_ctrl = params->req_fc_auto_adv;
1582                 else
1583                         vars->flow_ctrl = params->req_flow_ctrl;
1584         }
1585         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1586 }
1587
1588
1589 static u8 bnx2x_link_settings_status(struct link_params *params,
1590                                       struct link_vars *vars,
1591                                       u32 gp_status)
1592 {
1593         struct bnx2x *bp = params->bp;
1594         u16 new_line_speed;
1595         u8 rc = 0;
1596         vars->link_status = 0;
1597
1598         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1599                 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1600                          gp_status);
1601
1602                 vars->phy_link_up = 1;
1603                 vars->link_status |= LINK_STATUS_LINK_UP;
1604
1605                 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1606                         vars->duplex = DUPLEX_FULL;
1607                 else
1608                         vars->duplex = DUPLEX_HALF;
1609
1610                 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1611
1612                 switch (gp_status & GP_STATUS_SPEED_MASK) {
1613                 case GP_STATUS_10M:
1614                         new_line_speed = SPEED_10;
1615                         if (vars->duplex == DUPLEX_FULL)
1616                                 vars->link_status |= LINK_10TFD;
1617                         else
1618                                 vars->link_status |= LINK_10THD;
1619                         break;
1620
1621                 case GP_STATUS_100M:
1622                         new_line_speed = SPEED_100;
1623                         if (vars->duplex == DUPLEX_FULL)
1624                                 vars->link_status |= LINK_100TXFD;
1625                         else
1626                                 vars->link_status |= LINK_100TXHD;
1627                         break;
1628
1629                 case GP_STATUS_1G:
1630                 case GP_STATUS_1G_KX:
1631                         new_line_speed = SPEED_1000;
1632                         if (vars->duplex == DUPLEX_FULL)
1633                                 vars->link_status |= LINK_1000TFD;
1634                         else
1635                                 vars->link_status |= LINK_1000THD;
1636                         break;
1637
1638                 case GP_STATUS_2_5G:
1639                         new_line_speed = SPEED_2500;
1640                         if (vars->duplex == DUPLEX_FULL)
1641                                 vars->link_status |= LINK_2500TFD;
1642                         else
1643                                 vars->link_status |= LINK_2500THD;
1644                         break;
1645
1646                 case GP_STATUS_5G:
1647                 case GP_STATUS_6G:
1648                         DP(NETIF_MSG_LINK,
1649                                  "link speed unsupported  gp_status 0x%x\n",
1650                                   gp_status);
1651                         return -EINVAL;
1652                         break;
1653                 case GP_STATUS_10G_KX4:
1654                 case GP_STATUS_10G_HIG:
1655                 case GP_STATUS_10G_CX4:
1656                         new_line_speed = SPEED_10000;
1657                         vars->link_status |= LINK_10GTFD;
1658                         break;
1659
1660                 case GP_STATUS_12G_HIG:
1661                         new_line_speed = SPEED_12000;
1662                         vars->link_status |= LINK_12GTFD;
1663                         break;
1664
1665                 case GP_STATUS_12_5G:
1666                         new_line_speed = SPEED_12500;
1667                         vars->link_status |= LINK_12_5GTFD;
1668                         break;
1669
1670                 case GP_STATUS_13G:
1671                         new_line_speed = SPEED_13000;
1672                         vars->link_status |= LINK_13GTFD;
1673                         break;
1674
1675                 case GP_STATUS_15G:
1676                         new_line_speed = SPEED_15000;
1677                         vars->link_status |= LINK_15GTFD;
1678                         break;
1679
1680                 case GP_STATUS_16G:
1681                         new_line_speed = SPEED_16000;
1682                         vars->link_status |= LINK_16GTFD;
1683                         break;
1684
1685                 default:
1686                         DP(NETIF_MSG_LINK,
1687                                   "link speed unsupported gp_status 0x%x\n",
1688                                   gp_status);
1689                 return -EINVAL;
1690                         break;
1691                 }
1692
1693                 /* Upon link speed change set the NIG into drain mode.
1694                 Comes to deals with possible FIFO glitch due to clk change
1695                 when speed is decreased without link down indicator */
1696                 if (new_line_speed != vars->line_speed) {
1697                         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1698                                     + params->port*4, 0);
1699                         msleep(1);
1700                 }
1701                 vars->line_speed = new_line_speed;
1702                 vars->link_status |= LINK_STATUS_SERDES_LINK;
1703
1704                 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1705                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1706                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1707                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1708                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1709                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1710                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
1711                      (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1712                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481))) {
1713                         vars->autoneg = AUTO_NEG_ENABLED;
1714
1715                         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1716                                 vars->autoneg |= AUTO_NEG_COMPLETE;
1717                                 vars->link_status |=
1718                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1719                         }
1720
1721                         vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1722                         vars->link_status |=
1723                                 LINK_STATUS_PARALLEL_DETECTION_USED;
1724
1725                 }
1726                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1727                         vars->link_status |=
1728                                 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1729
1730                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1731                         vars->link_status |=
1732                                 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1733
1734         } else { /* link_down */
1735                 DP(NETIF_MSG_LINK, "phy link down\n");
1736
1737                 vars->phy_link_up = 0;
1738
1739                 vars->duplex = DUPLEX_FULL;
1740                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1741                 vars->autoneg = AUTO_NEG_DISABLED;
1742                 vars->mac_type = MAC_TYPE_NONE;
1743         }
1744
1745         DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
1746                  gp_status, vars->phy_link_up, vars->line_speed);
1747         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
1748                  " autoneg 0x%x\n",
1749                  vars->duplex,
1750                  vars->flow_ctrl, vars->autoneg);
1751         DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1752
1753         return rc;
1754 }
1755
1756 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
1757 {
1758         struct bnx2x *bp = params->bp;
1759         u16 lp_up2;
1760         u16 tx_driver;
1761
1762         /* read precomp */
1763
1764         CL45_RD_OVER_CL22(bp, params->port,
1765                               params->phy_addr,
1766                               MDIO_REG_BANK_OVER_1G,
1767                               MDIO_OVER_1G_LP_UP2, &lp_up2);
1768
1769         CL45_RD_OVER_CL22(bp, params->port,
1770                               params->phy_addr,
1771                               MDIO_REG_BANK_TX0,
1772                               MDIO_TX0_TX_DRIVER, &tx_driver);
1773
1774         /* bits [10:7] at lp_up2, positioned at [15:12] */
1775         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1776                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1777                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1778
1779         if ((lp_up2 != 0) &&
1780             (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1781                 /* replace tx_driver bits [15:12] */
1782                 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1783                 tx_driver |= lp_up2;
1784                 CL45_WR_OVER_CL22(bp, params->port,
1785                                       params->phy_addr,
1786                                       MDIO_REG_BANK_TX0,
1787                                       MDIO_TX0_TX_DRIVER, tx_driver);
1788         }
1789 }
1790
1791 static u8 bnx2x_emac_program(struct link_params *params,
1792                            u32 line_speed, u32 duplex)
1793 {
1794         struct bnx2x *bp = params->bp;
1795         u8 port = params->port;
1796         u16 mode = 0;
1797
1798         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1799         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1800                      EMAC_REG_EMAC_MODE,
1801                      (EMAC_MODE_25G_MODE |
1802                      EMAC_MODE_PORT_MII_10M |
1803                      EMAC_MODE_HALF_DUPLEX));
1804         switch (line_speed) {
1805         case SPEED_10:
1806                 mode |= EMAC_MODE_PORT_MII_10M;
1807                 break;
1808
1809         case SPEED_100:
1810                 mode |= EMAC_MODE_PORT_MII;
1811                 break;
1812
1813         case SPEED_1000:
1814                 mode |= EMAC_MODE_PORT_GMII;
1815                 break;
1816
1817         case SPEED_2500:
1818                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1819                 break;
1820
1821         default:
1822                 /* 10G not valid for EMAC */
1823                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1824                 return -EINVAL;
1825         }
1826
1827         if (duplex == DUPLEX_HALF)
1828                 mode |= EMAC_MODE_HALF_DUPLEX;
1829         bnx2x_bits_en(bp,
1830                     GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1831                     mode);
1832
1833         bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1834                     line_speed, params->hw_led_mode, params->chip_id);
1835         return 0;
1836 }
1837
1838 /*****************************************************************************/
1839 /*                           External Phy section                            */
1840 /*****************************************************************************/
1841 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1842 {
1843         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1844                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1845         msleep(1);
1846         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1847                       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1848 }
1849
1850 static void bnx2x_ext_phy_reset(struct link_params *params,
1851                               struct link_vars   *vars)
1852 {
1853         struct bnx2x *bp = params->bp;
1854         u32 ext_phy_type;
1855         u8 ext_phy_addr = ((params->ext_phy_config &
1856                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1857                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1858         DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1859         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1860         /* The PHY reset is controled by GPIO 1
1861          * Give it 1ms of reset pulse
1862          */
1863         if (vars->phy_flags & PHY_XGXS_FLAG) {
1864
1865                 switch (ext_phy_type) {
1866                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1867                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
1868                         break;
1869
1870                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1871                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1872                         DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1873
1874                         /* Restore normal power mode*/
1875                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1876                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1877                                           params->port);
1878
1879                         /* HW reset */
1880                         bnx2x_hw_reset(bp, params->port);
1881
1882                         bnx2x_cl45_write(bp, params->port,
1883                                        ext_phy_type,
1884                                        ext_phy_addr,
1885                                        MDIO_PMA_DEVAD,
1886                                        MDIO_PMA_REG_CTRL, 0xa040);
1887                         break;
1888                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
1889
1890                         /* Restore normal power mode*/
1891                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1892                                           MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1893                                           params->port);
1894
1895                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1896                                           MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1897                                           params->port);
1898
1899                         bnx2x_cl45_write(bp, params->port,
1900                                        ext_phy_type,
1901                                        ext_phy_addr,
1902                                        MDIO_PMA_DEVAD,
1903                                        MDIO_PMA_REG_CTRL,
1904                                        1<<15);
1905
1906                         break;
1907                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1908                         /* Unset Low Power Mode and SW reset */
1909                         /* Restore normal power mode*/
1910                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1911                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1912                                           params->port);
1913
1914                         DP(NETIF_MSG_LINK, "XGXS 8072\n");
1915                         bnx2x_cl45_write(bp, params->port,
1916                                        ext_phy_type,
1917                                        ext_phy_addr,
1918                                        MDIO_PMA_DEVAD,
1919                                        MDIO_PMA_REG_CTRL,
1920                                        1<<15);
1921                         break;
1922                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1923                         {
1924                         u16 emac_base;
1925                         emac_base = (params->port) ? GRCBASE_EMAC0 :
1926                                         GRCBASE_EMAC1;
1927
1928                         /* Restore normal power mode*/
1929                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1930                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1931                                           params->port);
1932
1933                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1934                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1935                                           params->port);
1936
1937                         DP(NETIF_MSG_LINK, "XGXS 8073\n");
1938                         }
1939                         break;
1940
1941                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1942                         DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1943
1944                         /* Restore normal power mode*/
1945                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1946                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1947                                           params->port);
1948
1949                         /* HW reset */
1950                         bnx2x_hw_reset(bp, params->port);
1951
1952                         break;
1953
1954                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
1955
1956                         /* Restore normal power mode*/
1957                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1958                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1959                                           params->port);
1960
1961                         /* HW reset */
1962                         bnx2x_hw_reset(bp, params->port);
1963
1964                         bnx2x_cl45_write(bp, params->port,
1965                                        ext_phy_type,
1966                                        ext_phy_addr,
1967                                        MDIO_PMA_DEVAD,
1968                                        MDIO_PMA_REG_CTRL,
1969                                        1<<15);
1970                         break;
1971                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1972                         DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1973                         break;
1974
1975                 default:
1976                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1977                            params->ext_phy_config);
1978                         break;
1979                 }
1980
1981         } else { /* SerDes */
1982                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1983                 switch (ext_phy_type) {
1984                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1985                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
1986                         break;
1987
1988                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1989                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
1990                         bnx2x_hw_reset(bp, params->port);
1991                         break;
1992
1993                 default:
1994                         DP(NETIF_MSG_LINK,
1995                                  "BAD SerDes ext_phy_config 0x%x\n",
1996                                  params->ext_phy_config);
1997                         break;
1998                 }
1999         }
2000 }
2001
2002
2003 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2004                                     u32 shmem_base, u32 spirom_ver)
2005 {
2006         DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x\n",
2007                  (u16)(spirom_ver>>16), (u16)spirom_ver);
2008         REG_WR(bp, shmem_base +
2009                    offsetof(struct shmem_region,
2010                             port_mb[port].ext_phy_fw_version),
2011                         spirom_ver);
2012 }
2013
2014 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
2015                                     u32 ext_phy_type, u8 ext_phy_addr,
2016                                     u32 shmem_base)
2017 {
2018         u16 fw_ver1, fw_ver2;
2019         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2020                       MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2021         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2022                       MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2023         bnx2x_save_spirom_version(bp, port, shmem_base,
2024                                 (u32)(fw_ver1<<16 | fw_ver2));
2025 }
2026
2027 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2028 {
2029         struct bnx2x *bp = params->bp;
2030         u8 port = params->port;
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         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2035
2036         /* Need to wait 200ms after reset */
2037         msleep(200);
2038         /* Boot port from external ROM
2039          * Set ser_boot_ctl bit in the MISC_CTRL1 register
2040          */
2041         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2042                             MDIO_PMA_DEVAD,
2043                             MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2044
2045         /* Reset internal microprocessor */
2046         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2047                           MDIO_PMA_DEVAD,
2048                           MDIO_PMA_REG_GEN_CTRL,
2049                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2050         /* set micro reset = 0 */
2051         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2052                             MDIO_PMA_DEVAD,
2053                             MDIO_PMA_REG_GEN_CTRL,
2054                             MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2055         /* Reset internal microprocessor */
2056         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2057                           MDIO_PMA_DEVAD,
2058                           MDIO_PMA_REG_GEN_CTRL,
2059                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2060         /* wait for 100ms for code download via SPI port */
2061         msleep(100);
2062
2063         /* Clear ser_boot_ctl bit */
2064         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2065                             MDIO_PMA_DEVAD,
2066                             MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2067         /* Wait 100ms */
2068         msleep(100);
2069
2070         bnx2x_save_bcm_spirom_ver(bp, port,
2071                                 ext_phy_type,
2072                                 ext_phy_addr,
2073                                 params->shmem_base);
2074 }
2075
2076 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2077 {
2078         /* This is only required for 8073A1, version 102 only */
2079
2080         struct bnx2x *bp = params->bp;
2081         u8 ext_phy_addr = ((params->ext_phy_config &
2082                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2083                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2084         u16 val;
2085
2086         /* Read 8073 HW revision*/
2087         bnx2x_cl45_read(bp, params->port,
2088                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2089                       ext_phy_addr,
2090                       MDIO_PMA_DEVAD,
2091                       0xc801, &val);
2092
2093         if (val != 1) {
2094                 /* No need to workaround in 8073 A1 */
2095                 return 0;
2096         }
2097
2098         bnx2x_cl45_read(bp, params->port,
2099                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2100                       ext_phy_addr,
2101                       MDIO_PMA_DEVAD,
2102                       MDIO_PMA_REG_ROM_VER2, &val);
2103
2104         /* SNR should be applied only for version 0x102 */
2105         if (val != 0x102)
2106                 return 0;
2107
2108         return 1;
2109 }
2110
2111 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2112 {
2113         struct bnx2x *bp = params->bp;
2114         u8 ext_phy_addr = ((params->ext_phy_config &
2115                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2116                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2117         u16 val, cnt, cnt1 ;
2118
2119         bnx2x_cl45_read(bp, params->port,
2120                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2121                       ext_phy_addr,
2122                       MDIO_PMA_DEVAD,
2123                       0xc801, &val);
2124
2125         if (val > 0) {
2126                 /* No need to workaround in 8073 A1 */
2127                 return 0;
2128         }
2129         /* XAUI workaround in 8073 A0: */
2130
2131         /* After loading the boot ROM and restarting Autoneg,
2132         poll Dev1, Reg $C820: */
2133
2134         for (cnt = 0; cnt < 1000; cnt++) {
2135                 bnx2x_cl45_read(bp, params->port,
2136                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2137                               ext_phy_addr,
2138                               MDIO_PMA_DEVAD,
2139                               0xc820, &val);
2140                   /* If bit [14] = 0 or bit [13] = 0, continue on with
2141                    system initialization (XAUI work-around not required,
2142                     as these bits indicate 2.5G or 1G link up). */
2143                 if (!(val & (1<<14)) || !(val & (1<<13))) {
2144                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2145                         return 0;
2146                 } else if (!(val & (1<<15))) {
2147                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2148                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2149                           it's MSB (bit 15) goes to 1 (indicating that the
2150                           XAUI workaround has completed),
2151                           then continue on with system initialization.*/
2152                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2153                                 bnx2x_cl45_read(bp, params->port,
2154                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2155                                         ext_phy_addr,
2156                                         MDIO_PMA_DEVAD,
2157                                         0xc841, &val);
2158                                 if (val & (1<<15)) {
2159                                         DP(NETIF_MSG_LINK,
2160                                           "XAUI workaround has completed\n");
2161                                         return 0;
2162                                  }
2163                                  msleep(3);
2164                         }
2165                         break;
2166                 }
2167                 msleep(3);
2168         }
2169         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2170         return -EINVAL;
2171
2172 }
2173
2174 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2175                                           u8 ext_phy_addr, u32 shmem_base)
2176 {
2177         /* Boot port from external ROM  */
2178         /* EDC grst */
2179         bnx2x_cl45_write(bp, port,
2180                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2181                        ext_phy_addr,
2182                        MDIO_PMA_DEVAD,
2183                        MDIO_PMA_REG_GEN_CTRL,
2184                        0x0001);
2185
2186         /* ucode reboot and rst */
2187         bnx2x_cl45_write(bp, port,
2188                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2189                        ext_phy_addr,
2190                        MDIO_PMA_DEVAD,
2191                        MDIO_PMA_REG_GEN_CTRL,
2192                        0x008c);
2193
2194         bnx2x_cl45_write(bp, port,
2195                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2196                        ext_phy_addr,
2197                        MDIO_PMA_DEVAD,
2198                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2199
2200         /* Reset internal microprocessor */
2201         bnx2x_cl45_write(bp, port,
2202                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2203                        ext_phy_addr,
2204                        MDIO_PMA_DEVAD,
2205                        MDIO_PMA_REG_GEN_CTRL,
2206                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2207
2208         /* Release srst bit */
2209         bnx2x_cl45_write(bp, port,
2210                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2211                        ext_phy_addr,
2212                        MDIO_PMA_DEVAD,
2213                        MDIO_PMA_REG_GEN_CTRL,
2214                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2215
2216         /* wait for 100ms for code download via SPI port */
2217         msleep(100);
2218
2219         /* Clear ser_boot_ctl bit */
2220         bnx2x_cl45_write(bp, port,
2221                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2222                        ext_phy_addr,
2223                        MDIO_PMA_DEVAD,
2224                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2225
2226         bnx2x_save_bcm_spirom_ver(bp, port,
2227                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2228                                 ext_phy_addr,
2229                                 shmem_base);
2230 }
2231
2232 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2233 {
2234         struct bnx2x *bp = params->bp;
2235         u8 port = params->port;
2236         u8 ext_phy_addr = ((params->ext_phy_config &
2237                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2238                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2239         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2240
2241         /* Need to wait 100ms after reset */
2242         msleep(100);
2243
2244         /* Set serial boot control for external load */
2245         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2246                        MDIO_PMA_DEVAD,
2247                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2248
2249         /* Micro controller re-boot */
2250         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2251                        MDIO_PMA_DEVAD,
2252                        MDIO_PMA_REG_GEN_CTRL,
2253                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2254
2255         /* Set soft reset */
2256         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2257                        MDIO_PMA_DEVAD,
2258                        MDIO_PMA_REG_GEN_CTRL,
2259                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2260
2261         /* Clear soft reset.
2262         Will automatically reset micro-controller re-boot */
2263         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2264                        MDIO_PMA_DEVAD,
2265                        MDIO_PMA_REG_GEN_CTRL,
2266                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2267
2268         /* wait for 100ms for microcode load */
2269         msleep(100);
2270
2271         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2272         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2273                        MDIO_PMA_DEVAD,
2274                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2275
2276         msleep(200);
2277         bnx2x_save_bcm_spirom_ver(bp, port,
2278                                 ext_phy_type,
2279                                 ext_phy_addr,
2280                                 params->shmem_base);
2281 }
2282
2283 static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
2284                                         u8 ext_phy_addr, u8 tx_en)
2285 {
2286         u16 val;
2287         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2288                  tx_en, port);
2289         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2290         bnx2x_cl45_read(bp, port,
2291                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2292                       ext_phy_addr,
2293                       MDIO_PMA_DEVAD,
2294                       MDIO_PMA_REG_PHY_IDENTIFIER,
2295                       &val);
2296
2297         if (tx_en)
2298                 val &= ~(1<<15);
2299         else
2300                 val |= (1<<15);
2301
2302         bnx2x_cl45_write(bp, port,
2303                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2304                        ext_phy_addr,
2305                        MDIO_PMA_DEVAD,
2306                        MDIO_PMA_REG_PHY_IDENTIFIER,
2307                        val);
2308 }
2309
2310
2311 static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2312                                      u8 byte_cnt, u8 *o_buf) {
2313         struct bnx2x *bp = params->bp;
2314         u16 val, i;
2315         u8 port = params->port;
2316         u8 ext_phy_addr = ((params->ext_phy_config &
2317                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2318                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2319         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2320         if (byte_cnt > 16) {
2321                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2322                             " is limited to 0xf\n");
2323                 return -EINVAL;
2324         }
2325         /* Set the read command byte count */
2326         bnx2x_cl45_write(bp, port,
2327                        ext_phy_type,
2328                        ext_phy_addr,
2329                        MDIO_PMA_DEVAD,
2330                        MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
2331                        (byte_cnt | 0xa000));
2332
2333         /* Set the read command address */
2334         bnx2x_cl45_write(bp, port,
2335                        ext_phy_type,
2336                        ext_phy_addr,
2337                        MDIO_PMA_DEVAD,
2338                        MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
2339                        addr);
2340
2341         /* Activate read command */
2342         bnx2x_cl45_write(bp, port,
2343                        ext_phy_type,
2344                        ext_phy_addr,
2345                        MDIO_PMA_DEVAD,
2346                        MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
2347                        0x2c0f);
2348
2349         /* Wait up to 500us for command complete status */
2350         for (i = 0; i < 100; i++) {
2351                 bnx2x_cl45_read(bp, port,
2352                               ext_phy_type,
2353                               ext_phy_addr,
2354                               MDIO_PMA_DEVAD,
2355                               MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2356                 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2357                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
2358                         break;
2359                 udelay(5);
2360         }
2361
2362         if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
2363                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
2364                 DP(NETIF_MSG_LINK,
2365                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2366                          (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
2367                 return -EINVAL;
2368         }
2369
2370         /* Read the buffer */
2371         for (i = 0; i < byte_cnt; i++) {
2372                 bnx2x_cl45_read(bp, port,
2373                               ext_phy_type,
2374                               ext_phy_addr,
2375                               MDIO_PMA_DEVAD,
2376                               MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2377                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2378         }
2379
2380         for (i = 0; i < 100; i++) {
2381                 bnx2x_cl45_read(bp, port,
2382                               ext_phy_type,
2383                               ext_phy_addr,
2384                               MDIO_PMA_DEVAD,
2385                               MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2386                 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2387                     MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
2388                         return 0;;
2389                 msleep(1);
2390         }
2391         return -EINVAL;
2392 }
2393
2394
2395 static u8 bnx2x_get_sfp_module_type(struct link_params *params,
2396                                   u8 *module_type)
2397 {
2398         struct bnx2x *bp = params->bp;
2399         u8 val;
2400         *module_type = SFP_MODULE_TYPE_UNKNOWN;
2401
2402         /* First check for copper cable */
2403         if (bnx2x_read_sfp_module_eeprom(params,
2404                                        SFP_EEPROM_CON_TYPE_ADDR,
2405                                        1,
2406                                        &val) != 0) {
2407                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
2408                 return -EINVAL;
2409         }
2410
2411         switch (val) {
2412         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2413         {
2414                 u8 copper_module_type;
2415                 /* Check if its active cable( includes SFP+ module)
2416                 of passive cable*/
2417                 if (bnx2x_read_sfp_module_eeprom(params,
2418                                                SFP_EEPROM_FC_TX_TECH_ADDR,
2419                                                1,
2420                                                &copper_module_type) !=
2421                     0) {
2422                         DP(NETIF_MSG_LINK,
2423                                 "Failed to read copper-cable-type"
2424                                 " from SFP+ EEPROM\n");
2425                         return -EINVAL;
2426                 }
2427
2428                 if (copper_module_type &
2429                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2430                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2431                         *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
2432                 } else if (copper_module_type &
2433                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2434                                 DP(NETIF_MSG_LINK, "Passive Copper"
2435                                             " cable detected\n");
2436                                 *module_type =
2437                                       SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
2438                 } else {
2439                         DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2440                                      "type 0x%x !!!\n", copper_module_type);
2441                         return -EINVAL;
2442                 }
2443                 break;
2444         }
2445         case SFP_EEPROM_CON_TYPE_VAL_LC:
2446                 DP(NETIF_MSG_LINK, "Optic module detected\n");
2447                 *module_type = SFP_MODULE_TYPE_LC;
2448                 break;
2449
2450         default:
2451                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2452                          val);
2453                 return -EINVAL;
2454         }
2455         return 0;
2456 }
2457
2458
2459 /* This function read the relevant field from the module ( SFP+ ),
2460         and verify it is compliant with this board */
2461 static u8 bnx2x_verify_sfp_module(struct link_params *params,
2462                                 u8 module_type)
2463 {
2464         struct bnx2x *bp = params->bp;
2465         u8 *str_p, *tmp_buf;
2466         u16 i;
2467
2468 #define COMPLIANCE_STR_CNT 6
2469         u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
2470                 "FINISAR CORP.   ", "Amphenol"};
2471         u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
2472         /* Passive Copper cables are allowed to participate,
2473         since the module is hardwired to the copper cable */
2474
2475         if (!(params->feature_config_flags &
2476              FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2477                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2478                 return 0;
2479         }
2480
2481         if (module_type != SFP_MODULE_TYPE_LC) {
2482                 DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
2483                 return 0;
2484         }
2485
2486         /* In case of non copper cable or Active copper cable,
2487                 verify that the SFP+ module is compliant with this board*/
2488         if (bnx2x_read_sfp_module_eeprom(params,
2489                                        SFP_EEPROM_VENDOR_NAME_ADDR,
2490                                        SFP_EEPROM_VENDOR_NAME_SIZE,
2491                                        buf) != 0) {
2492                 DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
2493                             " module EEPROM\n");
2494                 return -EINVAL;
2495         }
2496         for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
2497                 str_p = compliance_str[i];
2498                 tmp_buf = buf;
2499                 while (*str_p) {
2500                         if ((u8)(*tmp_buf) != (u8)(*str_p))
2501                                 break;
2502                         str_p++;
2503                         tmp_buf++;
2504                 }
2505
2506                 if (!(*str_p)) {
2507                         DP(NETIF_MSG_LINK, "SFP+ Module verified, "
2508                                      "index=%x\n", i);
2509                         return 0;
2510                 }
2511         }
2512         DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
2513         return -EINVAL;
2514 }
2515
2516
2517 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2518                                         u8 module_type)
2519 {
2520         struct bnx2x *bp = params->bp;
2521         u8 port = params->port;
2522         u8 options[SFP_EEPROM_OPTIONS_SIZE];
2523         u8 limiting_mode;
2524         u8 ext_phy_addr = ((params->ext_phy_config &
2525                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2526                            PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2527
2528         if (bnx2x_read_sfp_module_eeprom(params,
2529                                        SFP_EEPROM_OPTIONS_ADDR,
2530                                        SFP_EEPROM_OPTIONS_SIZE,
2531                                        options) != 0) {
2532                 DP(NETIF_MSG_LINK, "Failed to read Option field from"
2533                             " module EEPROM\n");
2534                 return -EINVAL;
2535         }
2536         limiting_mode = !(options[0] &
2537                           SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
2538         if (limiting_mode &&
2539             (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
2540                 DP(NETIF_MSG_LINK,
2541                          "Module options = 0x%x.Setting LIMITING MODE\n",
2542                          options[0]);
2543                 bnx2x_cl45_write(bp, port,
2544                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2545                                ext_phy_addr,
2546                                MDIO_PMA_DEVAD,
2547                                MDIO_PMA_REG_ROM_VER2,
2548                                SFP_LIMITING_MODE_VALUE);
2549         } else { /* LRM mode ( default )*/
2550                 u16 cur_limiting_mode;
2551                 DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
2552                          options[0]);
2553
2554                 bnx2x_cl45_read(bp, port,
2555                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2556                                ext_phy_addr,
2557                                MDIO_PMA_DEVAD,
2558                                MDIO_PMA_REG_ROM_VER2,
2559                                &cur_limiting_mode);
2560
2561                 /* Changing to LRM mode takes quite few seconds.
2562                 So do it only if current mode is limiting
2563                 ( default is LRM )*/
2564                 if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
2565                         return 0;
2566
2567                 bnx2x_cl45_write(bp, port,
2568                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2569                                ext_phy_addr,
2570                                MDIO_PMA_DEVAD,
2571                                MDIO_PMA_REG_LRM_MODE,
2572                                0);
2573                 bnx2x_cl45_write(bp, port,
2574                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2575                                ext_phy_addr,
2576                                MDIO_PMA_DEVAD,
2577                                MDIO_PMA_REG_ROM_VER2,
2578                                0x128);
2579                 bnx2x_cl45_write(bp, port,
2580                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2581                                ext_phy_addr,
2582                                MDIO_PMA_DEVAD,
2583                                MDIO_PMA_REG_MISC_CTRL0,
2584                                0x4008);
2585                 bnx2x_cl45_write(bp, port,
2586                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2587                                ext_phy_addr,
2588                                MDIO_PMA_DEVAD,
2589                                MDIO_PMA_REG_LRM_MODE,
2590                                0xaaaa);
2591         }
2592         return 0;
2593 }
2594
2595 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2596 {
2597         u8 val;
2598         struct bnx2x *bp = params->bp;
2599         u16 timeout;
2600         /* Initialization time after hot-plug may take up to 300ms for some
2601         phys type ( e.g. JDSU ) */
2602         for (timeout = 0; timeout < 60; timeout++) {
2603                 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2604                     == 0) {
2605                         DP(NETIF_MSG_LINK, "SFP+ module initialization "
2606                                      "took %d ms\n", timeout * 5);
2607                         return 0;
2608                 }
2609                 msleep(5);
2610         }
2611         return -EINVAL;
2612 }
2613
2614 static u8 bnx2x_sfp_module_detection(struct link_params *params)
2615 {
2616         struct bnx2x *bp = params->bp;
2617         u8 module_type;
2618         u8 ext_phy_addr = ((params->ext_phy_config &
2619                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2620                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2621         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2622
2623         if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
2624                 DP(NETIF_MSG_LINK, "Module detection is not required "
2625                             "for this phy\n");
2626                 return 0;
2627         }
2628
2629         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2630                  params->port);
2631
2632         if (bnx2x_get_sfp_module_type(params,
2633                                     &module_type) != 0) {
2634                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2635                 if (!(params->feature_config_flags &
2636                       FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2637                         /* In case module detection is disabled, it trys to
2638                         link up. The issue that can happen here is LRM /
2639                         LIMITING mode which set according to the module-type*/
2640                         DP(NETIF_MSG_LINK, "Unable to read module-type."
2641                                     "Probably due to Bit Stretching."
2642                                     " Proceeding...\n");
2643                 } else {
2644                         return -EINVAL;
2645                 }
2646         } else if (bnx2x_verify_sfp_module(params, module_type) !=
2647                    0) {
2648                 /* check SFP+ module compatibility */
2649                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2650                 /* Turn on fault module-detected led */
2651                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2652                                   MISC_REGISTERS_GPIO_HIGH,
2653                                   params->port);
2654                 return -EINVAL;
2655         }
2656
2657         /* Turn off fault module-detected led */
2658         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2659                           MISC_REGISTERS_GPIO_LOW,
2660                           params->port);
2661
2662         /* Check and set limiting mode / LRM mode */
2663         if (bnx2x_bcm8726_set_limiting_mode(params, module_type)
2664              != 0) {
2665                 DP(NETIF_MSG_LINK, "Setting limiting mode failed!!\n");
2666                 return -EINVAL;
2667         }
2668
2669         /* Enable transmit for this module */
2670         bnx2x_bcm8726_set_transmitter(bp, params->port,
2671                                     ext_phy_addr, 1);
2672         return 0;
2673 }
2674
2675 void bnx2x_handle_module_detect_int(struct link_params *params)
2676 {
2677         struct bnx2x *bp = params->bp;
2678         u32 gpio_val;
2679         u8 port = params->port;
2680         /* Set valid module led off */
2681         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2682                           MISC_REGISTERS_GPIO_HIGH,
2683                           params->port);
2684
2685         /* Get current gpio val refelecting module plugged in / out*/
2686         gpio_val = bnx2x_get_gpio(bp,  MISC_REGISTERS_GPIO_3, port);
2687
2688         /* Call the handling function in case module is detected */
2689         if (gpio_val == 0) {
2690
2691                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2692                                       MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2693                                       port);
2694
2695                 if (bnx2x_wait_for_sfp_module_initialized(params)
2696                     == 0)
2697                         bnx2x_sfp_module_detection(params);
2698                 else
2699                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2700         } else {
2701                 u8 ext_phy_addr = ((params->ext_phy_config &
2702                                     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2703                                    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2704                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2705                                       MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2706                                       port);
2707                 /* Module was plugged out. */
2708                 /* Disable transmit for this module */
2709                 bnx2x_bcm8726_set_transmitter(bp, params->port,
2710                                             ext_phy_addr, 0);
2711         }
2712 }
2713
2714 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2715 {
2716         struct bnx2x *bp = params->bp;
2717         u8 port = params->port;
2718         u8 ext_phy_addr = ((params->ext_phy_config &
2719                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2720                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2721         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2722
2723         /* Force KR or KX */
2724         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2725                        MDIO_PMA_DEVAD,
2726                        MDIO_PMA_REG_CTRL,
2727                        0x2040);
2728         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2729                        MDIO_PMA_DEVAD,
2730                        MDIO_PMA_REG_10G_CTRL2,
2731                        0x000b);
2732         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2733                        MDIO_PMA_DEVAD,
2734                        MDIO_PMA_REG_BCM_CTRL,
2735                        0x0000);
2736         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2737                        MDIO_AN_DEVAD,
2738                        MDIO_AN_REG_CTRL,
2739                        0x0000);
2740 }
2741 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2742 {
2743         struct bnx2x *bp = params->bp;
2744         u8 port = params->port;
2745         u16 val;
2746         u8 ext_phy_addr = ((params->ext_phy_config &
2747                              PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2748                             PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2749         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2750
2751         bnx2x_cl45_read(bp, params->port,
2752                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2753                       ext_phy_addr,
2754                       MDIO_PMA_DEVAD,
2755                       0xc801, &val);
2756
2757         if (val == 0) {
2758                 /* Mustn't set low power mode in 8073 A0 */
2759                 return;
2760         }
2761
2762         /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2763         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2764                        MDIO_XS_DEVAD,
2765                        MDIO_XS_PLL_SEQUENCER, &val);
2766         val &= ~(1<<13);
2767         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2768                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2769
2770         /* PLL controls */
2771         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2772                        MDIO_XS_DEVAD, 0x805E, 0x1077);
2773         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2774                        MDIO_XS_DEVAD, 0x805D, 0x0000);
2775         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2776                        MDIO_XS_DEVAD, 0x805C, 0x030B);
2777         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2778                        MDIO_XS_DEVAD, 0x805B, 0x1240);
2779         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2780                        MDIO_XS_DEVAD, 0x805A, 0x2490);
2781
2782         /* Tx Controls */
2783         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2784                        MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2785         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2786                        MDIO_XS_DEVAD, 0x80A6, 0x9041);
2787         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2788                        MDIO_XS_DEVAD, 0x80A5, 0x4640);
2789
2790         /* Rx Controls */
2791         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2792                        MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2793         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2794                        MDIO_XS_DEVAD, 0x80FD, 0x9249);
2795         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2796                        MDIO_XS_DEVAD, 0x80FC, 0x2015);
2797
2798         /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
2799         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2800                        MDIO_XS_DEVAD,
2801                        MDIO_XS_PLL_SEQUENCER, &val);
2802         val |= (1<<13);
2803         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2804                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2805 }
2806
2807 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2808                                   struct link_vars *vars)
2809 {
2810
2811         struct bnx2x *bp = params->bp;
2812         u16 cl37_val;
2813         u8 ext_phy_addr = ((params->ext_phy_config &
2814                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2815                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2816         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2817
2818         bnx2x_cl45_read(bp, params->port,
2819                       ext_phy_type,
2820                       ext_phy_addr,
2821                       MDIO_AN_DEVAD,
2822                       MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2823
2824         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2825         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2826
2827         if ((vars->ieee_fc &
2828             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2829             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2830                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2831         }
2832         if ((vars->ieee_fc &
2833             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2834             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2835                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2836         }
2837         if ((vars->ieee_fc &
2838             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2839             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2840                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2841         }
2842         DP(NETIF_MSG_LINK,
2843                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2844
2845         bnx2x_cl45_write(bp, params->port,
2846                        ext_phy_type,
2847                        ext_phy_addr,
2848                        MDIO_AN_DEVAD,
2849                        MDIO_AN_REG_CL37_FC_LD, cl37_val);
2850         msleep(500);
2851 }
2852
2853 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2854                                   struct link_vars *vars)
2855 {
2856         struct bnx2x *bp = params->bp;
2857         u16 val;
2858         u8 ext_phy_addr = ((params->ext_phy_config &
2859                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2860                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2861         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2862
2863         /* read modify write pause advertizing */
2864         bnx2x_cl45_read(bp, params->port,
2865                       ext_phy_type,
2866                       ext_phy_addr,
2867                       MDIO_AN_DEVAD,
2868                       MDIO_AN_REG_ADV_PAUSE, &val);
2869
2870         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2871
2872         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2873
2874         if ((vars->ieee_fc &
2875             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2876             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2877                 val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2878         }
2879         if ((vars->ieee_fc &
2880             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2881             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2882                 val |=
2883                  MDIO_AN_REG_ADV_PAUSE_PAUSE;
2884         }
2885         DP(NETIF_MSG_LINK,
2886                  "Ext phy AN advertize 0x%x\n", val);
2887         bnx2x_cl45_write(bp, params->port,
2888                        ext_phy_type,
2889                        ext_phy_addr,
2890                        MDIO_AN_DEVAD,
2891                        MDIO_AN_REG_ADV_PAUSE, val);
2892 }
2893
2894
2895 static void bnx2x_init_internal_phy(struct link_params *params,
2896                                 struct link_vars *vars)
2897 {
2898         struct bnx2x *bp = params->bp;
2899         u8 port = params->port;
2900         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2901                 u16 bank, rx_eq;
2902
2903                 rx_eq = ((params->serdes_config &
2904                           PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2905                          PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2906
2907                 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2908                 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2909                       bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2910                         CL45_WR_OVER_CL22(bp, port,
2911                                               params->phy_addr,
2912                                               bank ,
2913                                               MDIO_RX0_RX_EQ_BOOST,
2914                                               ((rx_eq &
2915                                 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2916                                 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2917                 }
2918
2919                 /* forced speed requested? */
2920                 if (vars->line_speed != SPEED_AUTO_NEG) {
2921                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2922
2923                         /* disable autoneg */
2924                         bnx2x_set_autoneg(params, vars);
2925
2926                         /* program speed and duplex */
2927                         bnx2x_program_serdes(params, vars);
2928
2929                 } else { /* AN_mode */
2930                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2931
2932                         /* AN enabled */
2933                         bnx2x_set_brcm_cl37_advertisment(params);
2934
2935                         /* program duplex & pause advertisement (for aneg) */
2936                         bnx2x_set_ieee_aneg_advertisment(params,
2937                                                        vars->ieee_fc);
2938
2939                         /* enable autoneg */
2940                         bnx2x_set_autoneg(params, vars);
2941
2942                         /* enable and restart AN */
2943                         bnx2x_restart_autoneg(params);
2944                 }
2945
2946         } else { /* SGMII mode */
2947                 DP(NETIF_MSG_LINK, "SGMII\n");
2948
2949                 bnx2x_initialize_sgmii_process(params, vars);
2950         }
2951 }
2952
2953 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2954 {
2955         struct bnx2x *bp = params->bp;
2956         u32 ext_phy_type;
2957         u8 ext_phy_addr;
2958         u16 cnt;
2959         u16 ctrl = 0;
2960         u16 val = 0;
2961         u8 rc = 0;
2962         if (vars->phy_flags & PHY_XGXS_FLAG) {
2963                 ext_phy_addr = ((params->ext_phy_config &
2964                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2965                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2966
2967                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2968                 /* Make sure that the soft reset is off (expect for the 8072:
2969                  * due to the lock, it will be done inside the specific
2970                  * handling)
2971                  */
2972                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2973                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2974                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2975                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2976                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2977                         /* Wait for soft reset to get cleared upto 1 sec */
2978                         for (cnt = 0; cnt < 1000; cnt++) {
2979                                 bnx2x_cl45_read(bp, params->port,
2980                                               ext_phy_type,
2981                                               ext_phy_addr,
2982                                               MDIO_PMA_DEVAD,
2983                                               MDIO_PMA_REG_CTRL, &ctrl);
2984                                 if (!(ctrl & (1<<15)))
2985                                         break;
2986                                 msleep(1);
2987                         }
2988                         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2989                                  ctrl, cnt);
2990                 }
2991
2992                 switch (ext_phy_type) {
2993                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2994                         break;
2995
2996                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2997                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
2998
2999                         bnx2x_cl45_write(bp, params->port,
3000                                        ext_phy_type,
3001                                        ext_phy_addr,
3002                                        MDIO_PMA_DEVAD,
3003                                        MDIO_PMA_REG_MISC_CTRL,
3004                                        0x8288);
3005                         bnx2x_cl45_write(bp, params->port,
3006                                        ext_phy_type,
3007                                        ext_phy_addr,
3008                                        MDIO_PMA_DEVAD,
3009                                        MDIO_PMA_REG_PHY_IDENTIFIER,
3010                                        0x7fbf);
3011                         bnx2x_cl45_write(bp, params->port,
3012                                        ext_phy_type,
3013                                        ext_phy_addr,
3014                                        MDIO_PMA_DEVAD,
3015                                        MDIO_PMA_REG_CMU_PLL_BYPASS,
3016                                        0x0100);
3017                         bnx2x_cl45_write(bp, params->port,
3018                                        ext_phy_type,
3019                                        ext_phy_addr,
3020                                        MDIO_WIS_DEVAD,
3021                                        MDIO_WIS_REG_LASI_CNTL, 0x1);
3022
3023                         bnx2x_save_bcm_spirom_ver(bp, params->port,
3024                                                 ext_phy_type,
3025                                                 ext_phy_addr,
3026                                                 params->shmem_base);
3027                         break;
3028
3029                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3030                         /* Wait until fw is loaded */
3031                         for (cnt = 0; cnt < 100; cnt++) {
3032                                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3033                                               ext_phy_addr, MDIO_PMA_DEVAD,
3034                                               MDIO_PMA_REG_ROM_VER1, &val);
3035                                 if (val)
3036                                         break;
3037                                 msleep(10);
3038                         }
3039                         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3040                                 "after %d ms\n", cnt);
3041                         /* Force speed */
3042                         /* First enable LASI */
3043                         bnx2x_cl45_write(bp, params->port,
3044                                        ext_phy_type,
3045                                        ext_phy_addr,
3046                                        MDIO_PMA_DEVAD,
3047                                        MDIO_PMA_REG_RX_ALARM_CTRL,
3048                                        0x0400);
3049                         bnx2x_cl45_write(bp, params->port,
3050                                        ext_phy_type,
3051                                        ext_phy_addr,
3052                                        MDIO_PMA_DEVAD,
3053                                        MDIO_PMA_REG_LASI_CTRL, 0x0004);
3054
3055                         if (params->req_line_speed == SPEED_10000) {
3056                                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3057
3058                                 bnx2x_cl45_write(bp, params->port,
3059                                                ext_phy_type,
3060                                                ext_phy_addr,
3061                                                MDIO_PMA_DEVAD,
3062                                                MDIO_PMA_REG_DIGITAL_CTRL,
3063                                                0x400);
3064                         } else {
3065                                 /* Force 1Gbps using autoneg with 1G
3066                                 advertisment */
3067
3068                                 /* Allow CL37 through CL73 */
3069                                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3070                                 bnx2x_cl45_write(bp, params->port,
3071                                                ext_phy_type,
3072                                                ext_phy_addr,
3073                                                MDIO_AN_DEVAD,
3074                                                MDIO_AN_REG_CL37_CL73,
3075                                                0x040c);
3076
3077                                 /* Enable Full-Duplex advertisment on CL37 */
3078                                 bnx2x_cl45_write(bp, params->port,
3079                                                ext_phy_type,
3080                                                ext_phy_addr,
3081                                                MDIO_AN_DEVAD,
3082                                                MDIO_AN_REG_CL37_FC_LP,
3083                                                0x0020);
3084                                 /* Enable CL37 AN */
3085                                 bnx2x_cl45_write(bp, params->port,
3086                                                ext_phy_type,
3087                                                ext_phy_addr,
3088                                                MDIO_AN_DEVAD,
3089                                                MDIO_AN_REG_CL37_AN,
3090                                                0x1000);
3091                                 /* 1G support */
3092                                 bnx2x_cl45_write(bp, params->port,
3093                                                ext_phy_type,
3094                                                ext_phy_addr,
3095                                                MDIO_AN_DEVAD,
3096                                                MDIO_AN_REG_ADV, (1<<5));
3097
3098                                 /* Enable clause 73 AN */
3099                                 bnx2x_cl45_write(bp, params->port,
3100                                                ext_phy_type,
3101                                                ext_phy_addr,
3102                                                MDIO_AN_DEVAD,
3103                                                MDIO_AN_REG_CTRL,
3104                                                0x1200);
3105
3106                         }
3107                         bnx2x_save_bcm_spirom_ver(bp, params->port,
3108                                                 ext_phy_type,
3109                                                 ext_phy_addr,
3110                                                 params->shmem_base);
3111                         break;
3112                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3113                         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3114                         bnx2x_bcm8726_external_rom_boot(params);
3115
3116                         /* Need to call module detected on initialization since
3117                         the module detection triggered by actual module
3118                         insertion might occur before driver is loaded, and when
3119                         driver is loaded, it reset all registers, including the
3120                         transmitter */
3121                         bnx2x_sfp_module_detection(params);
3122                         if (params->req_line_speed == SPEED_1000) {
3123                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3124                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3125                                                ext_phy_addr, MDIO_PMA_DEVAD,
3126                                                MDIO_PMA_REG_CTRL, 0x40);
3127                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3128                                                ext_phy_addr, MDIO_PMA_DEVAD,
3129                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
3130                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3131                                                ext_phy_addr, MDIO_PMA_DEVAD,
3132                                                MDIO_PMA_REG_LASI_CTRL, 0x5);
3133                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3134                                                ext_phy_addr, MDIO_PMA_DEVAD,
3135                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3136                                                0x400);
3137                         } else if ((params->req_line_speed ==
3138                                     SPEED_AUTO_NEG) &&
3139                                    ((params->speed_cap_mask &
3140                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3141                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3142                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3143                                                ext_phy_addr, MDIO_AN_DEVAD,
3144                                                MDIO_AN_REG_ADV, 0x20);
3145                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3146                                                ext_phy_addr, MDIO_AN_DEVAD,
3147                                                MDIO_AN_REG_CL37_CL73, 0x040c);
3148                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3149                                                ext_phy_addr, MDIO_AN_DEVAD,
3150                                                MDIO_AN_REG_CL37_FC_LD, 0x0020);
3151                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3152                                                ext_phy_addr, MDIO_AN_DEVAD,
3153                                                MDIO_AN_REG_CL37_AN, 0x1000);
3154                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3155                                                ext_phy_addr, MDIO_AN_DEVAD,
3156                                                MDIO_AN_REG_CTRL, 0x1200);
3157
3158                                 /* Enable RX-ALARM control to receive
3159                                 interrupt for 1G speed change */
3160                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3161                                                ext_phy_addr, MDIO_PMA_DEVAD,
3162                                                MDIO_PMA_REG_LASI_CTRL, 0x4);
3163                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3164                                                ext_phy_addr, MDIO_PMA_DEVAD,
3165                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3166                                                0x400);
3167
3168                         } else { /* Default 10G. Set only LASI control */
3169                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3170                                                ext_phy_addr, MDIO_PMA_DEVAD,
3171                                                MDIO_PMA_REG_LASI_CTRL, 1);
3172                         }
3173                         break;
3174                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3175                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3176                 {
3177                         u16 tmp1;
3178                         u16 rx_alarm_ctrl_val;
3179                         u16 lasi_ctrl_val;
3180                         if (ext_phy_type ==
3181                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3182                                 rx_alarm_ctrl_val = 0x400;
3183                                 lasi_ctrl_val = 0x0004;
3184                         } else {
3185                                 rx_alarm_ctrl_val = (1<<2);
3186                                 lasi_ctrl_val = 0x0004;
3187                         }
3188
3189                         /* enable LASI */
3190                         bnx2x_cl45_write(bp, params->port,
3191                                    ext_phy_type,
3192                                    ext_phy_addr,
3193                                    MDIO_PMA_DEVAD,
3194                                    MDIO_PMA_REG_RX_ALARM_CTRL,
3195                                    rx_alarm_ctrl_val);
3196
3197                         bnx2x_cl45_write(bp, params->port,
3198                                        ext_phy_type,
3199                                        ext_phy_addr,
3200                                        MDIO_PMA_DEVAD,
3201                                        MDIO_PMA_REG_LASI_CTRL,
3202                                        lasi_ctrl_val);
3203
3204                         bnx2x_8073_set_pause_cl37(params, vars);
3205
3206                         if (ext_phy_type ==
3207                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
3208                                 bnx2x_bcm8072_external_rom_boot(params);
3209                         } else {
3210
3211                                 /* In case of 8073 with long xaui lines,
3212                                 don't set the 8073 xaui low power*/
3213                                 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3214                         }
3215
3216                         bnx2x_cl45_read(bp, params->port,
3217                                       ext_phy_type,
3218                                       ext_phy_addr,
3219                                       MDIO_PMA_DEVAD,
3220                                       0xca13,
3221                                       &tmp1);
3222
3223                         bnx2x_cl45_read(bp, params->port,
3224                                       ext_phy_type,
3225                                       ext_phy_addr,
3226                                       MDIO_PMA_DEVAD,
3227                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
3228
3229                         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3230                                              "0x%x\n", tmp1);
3231
3232                         /* If this is forced speed, set to KR or KX
3233                          * (all other are not supported)
3234                          */
3235                         if (params->loopback_mode == LOOPBACK_EXT) {
3236                                 bnx2x_bcm807x_force_10G(params);
3237                                 DP(NETIF_MSG_LINK,
3238                                         "Forced speed 10G on 807X\n");
3239                                 break;
3240                         } else {
3241                                 bnx2x_cl45_write(bp, params->port,
3242                                                ext_phy_type, ext_phy_addr,
3243                                                MDIO_PMA_DEVAD,
3244                                                MDIO_PMA_REG_BCM_CTRL,
3245                                                0x0002);
3246                         }
3247                         if (params->req_line_speed != SPEED_AUTO_NEG) {
3248                                 if (params->req_line_speed == SPEED_10000) {
3249                                         val = (1<<7);
3250                                 } else if (params->req_line_speed ==
3251                                            SPEED_2500) {
3252                                         val = (1<<5);
3253                                         /* Note that 2.5G works only
3254                                         when used with 1G advertisment */
3255                                 } else
3256                                         val = (1<<5);
3257                         } else {
3258
3259                                 val = 0;
3260                                 if (params->speed_cap_mask &
3261                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3262                                         val |= (1<<7);
3263
3264                                 /* Note that 2.5G works only when
3265                                 used with 1G advertisment */
3266                                 if (params->speed_cap_mask &
3267                                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3268                                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3269                                         val |= (1<<5);
3270                                 DP(NETIF_MSG_LINK,
3271                                          "807x autoneg val = 0x%x\n", val);
3272                         }
3273
3274                         bnx2x_cl45_write(bp, params->port,
3275                                        ext_phy_type,
3276                                        ext_phy_addr,
3277                                        MDIO_AN_DEVAD,
3278                                        MDIO_AN_REG_ADV, val);
3279
3280                         if (ext_phy_type ==
3281                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3282
3283                                 bnx2x_cl45_read(bp, params->port,
3284                                               ext_phy_type,
3285                                               ext_phy_addr,
3286                                               MDIO_AN_DEVAD,
3287                                               0x8329, &tmp1);
3288
3289                                 if (((params->speed_cap_mask &
3290                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3291                                      (params->req_line_speed ==
3292                                       SPEED_AUTO_NEG)) ||
3293                                     (params->req_line_speed ==
3294                                      SPEED_2500)) {
3295                                         u16 phy_ver;
3296                                         /* Allow 2.5G for A1 and above */
3297                                         bnx2x_cl45_read(bp, params->port,
3298                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3299                                          ext_phy_addr,
3300                                          MDIO_PMA_DEVAD,
3301                                          0xc801, &phy_ver);
3302                                         DP(NETIF_MSG_LINK, "Add 2.5G\n");
3303                                         if (phy_ver > 0)
3304                                                 tmp1 |= 1;
3305                                         else
3306                                                 tmp1 &= 0xfffe;
3307                                 } else {
3308                                         DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3309                                         tmp1 &= 0xfffe;
3310                                 }
3311
3312                                 bnx2x_cl45_write(bp, params->port,
3313                                                ext_phy_type,
3314                                                ext_phy_addr,
3315                                                MDIO_AN_DEVAD,
3316                                                0x8329, tmp1);
3317                         }
3318
3319                         /* Add support for CL37 (passive mode) II */
3320
3321                         bnx2x_cl45_read(bp, params->port,
3322                                        ext_phy_type,
3323                                        ext_phy_addr,
3324                                        MDIO_AN_DEVAD,
3325                                        MDIO_AN_REG_CL37_FC_LD,
3326                                        &tmp1);
3327
3328                         bnx2x_cl45_write(bp, params->port,
3329                                        ext_phy_type,
3330                                        ext_phy_addr,
3331                                        MDIO_AN_DEVAD,
3332                                        MDIO_AN_REG_CL37_FC_LD, (tmp1 |
3333                                        ((params->req_duplex == DUPLEX_FULL) ?
3334                                        0x20 : 0x40)));
3335
3336                         /* Add support for CL37 (passive mode) III */
3337                         bnx2x_cl45_write(bp, params->port,
3338                                        ext_phy_type,
3339                                        ext_phy_addr,
3340                                        MDIO_AN_DEVAD,
3341                                        MDIO_AN_REG_CL37_AN, 0x1000);
3342
3343                         if (ext_phy_type ==
3344                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3345                                 /* The SNR will improve about 2db by changing
3346                                 BW and FEE main tap. Rest commands are executed
3347                                 after link is up*/
3348                                 /*Change FFE main cursor to 5 in EDC register*/
3349                                 if (bnx2x_8073_is_snr_needed(params))
3350                                         bnx2x_cl45_write(bp, params->port,
3351                                                     ext_phy_type,
3352                                                     ext_phy_addr,
3353                                                     MDIO_PMA_DEVAD,
3354                                                     MDIO_PMA_REG_EDC_FFE_MAIN,
3355                                                     0xFB0C);
3356
3357                                 /* Enable FEC (Forware Error Correction)
3358                                 Request in the AN */
3359                                 bnx2x_cl45_read(bp, params->port,
3360                                               ext_phy_type,
3361                                               ext_phy_addr,
3362                                               MDIO_AN_DEVAD,
3363                                               MDIO_AN_REG_ADV2, &tmp1);
3364
3365                                 tmp1 |= (1<<15);
3366
3367                                 bnx2x_cl45_write(bp, params->port,
3368                                                ext_phy_type,
3369                                                ext_phy_addr,
3370                                                MDIO_AN_DEVAD,
3371                                                MDIO_AN_REG_ADV2, tmp1);
3372
3373                         }
3374
3375                         bnx2x_ext_phy_set_pause(params, vars);
3376
3377                         /* Restart autoneg */
3378                         msleep(500);
3379                         bnx2x_cl45_write(bp, params->port,
3380                                        ext_phy_type,
3381                                        ext_phy_addr,
3382                                        MDIO_AN_DEVAD,
3383                                        MDIO_AN_REG_CTRL, 0x1200);
3384                         DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
3385                            "Advertise 1G=%x, 10G=%x\n",
3386                            ((val & (1<<5)) > 0),
3387                            ((val & (1<<7)) > 0));
3388                         break;
3389                 }
3390                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3391                 {
3392                         u16 fw_ver1, fw_ver2;
3393                         DP(NETIF_MSG_LINK,
3394                                 "Setting the SFX7101 LASI indication\n");
3395
3396                         bnx2x_cl45_write(bp, params->port,
3397                                        ext_phy_type,
3398                                        ext_phy_addr,
3399                                        MDIO_PMA_DEVAD,
3400                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
3401                         DP(NETIF_MSG_LINK,
3402                           "Setting the SFX7101 LED to blink on traffic\n");
3403                         bnx2x_cl45_write(bp, params->port,
3404                                        ext_phy_type,
3405                                        ext_phy_addr,
3406                                        MDIO_PMA_DEVAD,
3407                                        MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
3408
3409                         bnx2x_ext_phy_set_pause(params, vars);
3410                         /* Restart autoneg */
3411                         bnx2x_cl45_read(bp, params->port,
3412                                       ext_phy_type,
3413                                       ext_phy_addr,
3414                                       MDIO_AN_DEVAD,
3415                                       MDIO_AN_REG_CTRL, &val);
3416                         val |= 0x200;
3417                         bnx2x_cl45_write(bp, params->port,
3418                                        ext_phy_type,
3419                                        ext_phy_addr,
3420                                        MDIO_AN_DEVAD,
3421                                        MDIO_AN_REG_CTRL, val);
3422
3423                         /* Save spirom version */
3424                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3425                                       ext_phy_addr, MDIO_PMA_DEVAD,
3426                                       MDIO_PMA_REG_7101_VER1, &fw_ver1);
3427
3428                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3429                                       ext_phy_addr, MDIO_PMA_DEVAD,
3430                                       MDIO_PMA_REG_7101_VER2, &fw_ver2);
3431
3432                         bnx2x_save_spirom_version(params->bp, params->port,
3433                                                 params->shmem_base,
3434                                                 (u32)(fw_ver1<<16 | fw_ver2));
3435
3436                         break;
3437                 }
3438                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3439                         DP(NETIF_MSG_LINK,
3440                                 "Setting the BCM8481 LASI control\n");
3441
3442                         bnx2x_cl45_write(bp, params->port,
3443                                        ext_phy_type,
3444                                        ext_phy_addr,
3445                                        MDIO_PMA_DEVAD,
3446                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
3447
3448                         /* Restart autoneg */
3449                         bnx2x_cl45_read(bp, params->port,
3450                                       ext_phy_type,
3451                                       ext_phy_addr,
3452                                       MDIO_AN_DEVAD,
3453                                       MDIO_AN_REG_CTRL, &val);
3454                         val |= 0x200;
3455                         bnx2x_cl45_write(bp, params->port,
3456                                        ext_phy_type,
3457                                        ext_phy_addr,
3458                                        MDIO_AN_DEVAD,
3459                                        MDIO_AN_REG_CTRL, val);
3460
3461                         bnx2x_save_bcm_spirom_ver(bp, params->port,
3462                                                 ext_phy_type,
3463                                                 ext_phy_addr,
3464                                                 params->shmem_base);
3465
3466                         break;
3467                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3468                         DP(NETIF_MSG_LINK,
3469                                  "XGXS PHY Failure detected 0x%x\n",
3470                                  params->ext_phy_config);
3471                         rc = -EINVAL;
3472                         break;
3473                 default:
3474                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3475                                   params->ext_phy_config);
3476                         rc = -EINVAL;
3477                         break;
3478                 }
3479
3480         } else { /* SerDes */
3481
3482                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3483                 switch (ext_phy_type) {
3484                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3485                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
3486                         break;
3487
3488                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3489                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
3490                         break;
3491
3492                 default:
3493                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
3494                            params->ext_phy_config);
3495                         break;
3496                 }
3497         }
3498         return rc;
3499 }
3500
3501
3502 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
3503                                  struct link_vars *vars)
3504 {
3505         struct bnx2x *bp = params->bp;
3506         u32 ext_phy_type;
3507         u8 ext_phy_addr;
3508         u16 val1 = 0, val2;
3509         u16 rx_sd, pcs_status;
3510         u8 ext_phy_link_up = 0;
3511         u8 port = params->port;
3512         if (vars->phy_flags & PHY_XGXS_FLAG) {
3513                 ext_phy_addr = ((params->ext_phy_config &
3514                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3515                                 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3516
3517                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3518                 switch (ext_phy_type) {
3519                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3520                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
3521                         ext_phy_link_up = 1;
3522                         break;
3523
3524                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3525                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
3526                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3527                                       ext_phy_addr,
3528                                       MDIO_WIS_DEVAD,
3529                                       MDIO_WIS_REG_LASI_STATUS, &val1);
3530                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3531
3532                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3533                                       ext_phy_addr,
3534                                       MDIO_WIS_DEVAD,
3535                                       MDIO_WIS_REG_LASI_STATUS, &val1);
3536                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3537
3538                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3539                                       ext_phy_addr,
3540                                       MDIO_PMA_DEVAD,
3541                                       MDIO_PMA_REG_RX_SD, &rx_sd);
3542                         DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
3543                         ext_phy_link_up = (rx_sd & 0x1);
3544                         if (ext_phy_link_up)
3545                                 vars->line_speed = SPEED_10000;
3546                         break;
3547
3548                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3549                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3550                         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3551                         /* Clear RX Alarm*/
3552                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3553                                       ext_phy_addr,
3554                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
3555                                       &val2);
3556                         /* clear LASI indication*/
3557                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3558                                       ext_phy_addr,
3559                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3560                                       &val1);
3561                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3562                                       ext_phy_addr,
3563                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3564                                       &val2);
3565                         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
3566                                      "0x%x\n", val1, val2);
3567
3568                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3569                                       ext_phy_addr,
3570                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3571                                       &rx_sd);
3572                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3573                                       ext_phy_addr,
3574                                       MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3575                                       &pcs_status);
3576                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3577                                       ext_phy_addr,
3578                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3579                                       &val2);
3580                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3581                                       ext_phy_addr,
3582                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
3583                                       &val2);
3584
3585                         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
3586                            "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
3587                            rx_sd, pcs_status, val2);
3588                         /* link is up if both bit 0 of pmd_rx_sd and
3589                          * bit 0 of pcs_status are set, or if the autoneg bit
3590                            1 is set
3591                          */
3592                         ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
3593                                            (val2 & (1<<1)));
3594                         if (ext_phy_link_up) {
3595                                 if (ext_phy_type ==
3596                                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
3597                                         /* If transmitter is disabled,
3598                                         ignore false link up indication */
3599                                         bnx2x_cl45_read(bp, params->port,
3600                                                    ext_phy_type,
3601                                                    ext_phy_addr,
3602                                                    MDIO_PMA_DEVAD,
3603                                                    MDIO_PMA_REG_PHY_IDENTIFIER,
3604                                                    &val1);
3605                                         if (val1 & (1<<15)) {
3606                                                 DP(NETIF_MSG_LINK, "Tx is "
3607                                                             "disabled\n");
3608                                                 ext_phy_link_up = 0;
3609                                                 break;
3610                                         }
3611                                 }
3612
3613                                 if (val2 & (1<<1))
3614                                         vars->line_speed = SPEED_1000;
3615                                 else
3616                                         vars->line_speed = SPEED_10000;
3617                         }
3618
3619                         break;
3620                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3621                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3622                 {
3623                         u16 link_status = 0;
3624                         u16 an1000_status = 0;
3625                         if (ext_phy_type ==
3626                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3627                                 bnx2x_cl45_read(bp, params->port,
3628                                       ext_phy_type,
3629                                       ext_phy_addr,
3630                                       MDIO_PCS_DEVAD,
3631                                       MDIO_PCS_REG_LASI_STATUS, &val1);
3632                         bnx2x_cl45_read(bp, params->port,
3633                                       ext_phy_type,
3634                                       ext_phy_addr,
3635                                       MDIO_PCS_DEVAD,
3636                                       MDIO_PCS_REG_LASI_STATUS, &val2);
3637                         DP(NETIF_MSG_LINK,
3638                                  "870x LASI status 0x%x->0x%x\n",
3639                                   val1, val2);
3640
3641                         } else {
3642                                 /* In 8073, port1 is directed through emac0 and
3643                                  * port0 is directed through emac1
3644                                  */
3645                                 bnx2x_cl45_read(bp, params->port,
3646                                               ext_phy_type,
3647                                               ext_phy_addr,
3648                                               MDIO_PMA_DEVAD,
3649                                               MDIO_PMA_REG_LASI_STATUS, &val1);
3650
3651                                 DP(NETIF_MSG_LINK,
3652                                          "8703 LASI status 0x%x\n",
3653                                           val1);
3654                         }
3655
3656                         /* clear the interrupt LASI status register */
3657                         bnx2x_cl45_read(bp, params->port,
3658                                       ext_phy_type,
3659                                       ext_phy_addr,
3660                                       MDIO_PCS_DEVAD,
3661                                       MDIO_PCS_REG_STATUS, &val2);
3662                         bnx2x_cl45_read(bp, params->port,
3663                                       ext_phy_type,
3664                                       ext_phy_addr,
3665                                       MDIO_PCS_DEVAD,
3666                                       MDIO_PCS_REG_STATUS, &val1);
3667                         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
3668                            val2, val1);
3669                         /* Clear MSG-OUT */
3670                         bnx2x_cl45_read(bp, params->port,
3671                                       ext_phy_type,
3672                                       ext_phy_addr,
3673                                       MDIO_PMA_DEVAD,
3674                                       0xca13,
3675                                       &val1);
3676
3677                         /* Check the LASI */
3678                         bnx2x_cl45_read(bp, params->port,
3679                                       ext_phy_type,
3680                                       ext_phy_addr,
3681                                       MDIO_PMA_DEVAD,
3682                                       MDIO_PMA_REG_RX_ALARM, &val2);
3683
3684                         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3685
3686                         /* Check the link status */
3687                         bnx2x_cl45_read(bp, params->port,
3688                                       ext_phy_type,
3689                                       ext_phy_addr,
3690                                       MDIO_PCS_DEVAD,
3691                                       MDIO_PCS_REG_STATUS, &val2);
3692                         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3693
3694                         bnx2x_cl45_read(bp, params->port,
3695                                       ext_phy_type,
3696                                       ext_phy_addr,
3697                                       MDIO_PMA_DEVAD,
3698                                       MDIO_PMA_REG_STATUS, &val2);
3699                         bnx2x_cl45_read(bp, params->port,
3700                                       ext_phy_type,
3701                                       ext_phy_addr,
3702                                       MDIO_PMA_DEVAD,
3703                                       MDIO_PMA_REG_STATUS, &val1);
3704                         ext_phy_link_up = ((val1 & 4) == 4);
3705                         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3706                         if (ext_phy_type ==
3707                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3708
3709                                 if (ext_phy_link_up &&
3710                                     ((params->req_line_speed !=
3711                                         SPEED_10000))) {
3712                                         if (bnx2x_bcm8073_xaui_wa(params)
3713                                              != 0) {
3714                                                 ext_phy_link_up = 0;
3715                                                 break;
3716                                         }
3717                                 }
3718                                 bnx2x_cl45_read(bp, params->port,
3719                                                       ext_phy_type,
3720                                                       ext_phy_addr,
3721                                                       MDIO_AN_DEVAD,
3722                                                       0x8304,
3723                                                       &an1000_status);
3724                                 bnx2x_cl45_read(bp, params->port,
3725                                                       ext_phy_type,
3726                                                       ext_phy_addr,
3727                                                       MDIO_AN_DEVAD,
3728                                                       0x8304,
3729                                                       &an1000_status);
3730
3731                                 /* Check the link status on 1.1.2 */
3732                                 bnx2x_cl45_read(bp, params->port,
3733                                               ext_phy_type,
3734                                               ext_phy_addr,
3735                                               MDIO_PMA_DEVAD,
3736                                               MDIO_PMA_REG_STATUS, &val2);
3737                                 bnx2x_cl45_read(bp, params->port,
3738                                               ext_phy_type,
3739                                               ext_phy_addr,
3740                                               MDIO_PMA_DEVAD,
3741                                               MDIO_PMA_REG_STATUS, &val1);
3742                                 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3743                                              "an_link_status=0x%x\n",
3744                                           val2, val1, an1000_status);
3745
3746                                         ext_phy_link_up = (((val1 & 4) == 4) ||
3747                                                 (an1000_status & (1<<1)));
3748                                 if (ext_phy_link_up &&
3749                                     bnx2x_8073_is_snr_needed(params)) {
3750                                         /* The SNR will improve about 2dbby
3751                                         changing the BW and FEE main tap.*/
3752
3753                                         /* The 1st write to change FFE main
3754                                         tap is set before restart AN */
3755                                         /* Change PLL Bandwidth in EDC
3756                                         register */
3757                                         bnx2x_cl45_write(bp, port, ext_phy_type,
3758                                                     ext_phy_addr,
3759                                                     MDIO_PMA_DEVAD,
3760                                                     MDIO_PMA_REG_PLL_BANDWIDTH,
3761                                                     0x26BC);
3762
3763                                         /* Change CDR Bandwidth in EDC
3764                                         register */
3765                                         bnx2x_cl45_write(bp, port, ext_phy_type,
3766                                                     ext_phy_addr,
3767                                                     MDIO_PMA_DEVAD,
3768                                                     MDIO_PMA_REG_CDR_BANDWIDTH,
3769                                                     0x0333);
3770
3771
3772                                 }
3773                                 bnx2x_cl45_read(bp, params->port,
3774                                                       ext_phy_type,
3775                                                       ext_phy_addr,
3776                                                       MDIO_PMA_DEVAD,
3777                                                       0xc820,
3778                                                       &link_status);
3779
3780                                 /* Bits 0..2 --> speed detected,
3781                                    bits 13..15--> link is down */
3782                                 if ((link_status & (1<<2)) &&
3783                                     (!(link_status & (1<<15)))) {
3784                                         ext_phy_link_up = 1;
3785                                         vars->line_speed = SPEED_10000;
3786                                         DP(NETIF_MSG_LINK,
3787                                                  "port %x: External link"
3788                                                  " up in 10G\n", params->port);
3789                                 } else if ((link_status & (1<<1)) &&
3790                                            (!(link_status & (1<<14)))) {
3791                                         ext_phy_link_up = 1;
3792                                         vars->line_speed = SPEED_2500;
3793                                         DP(NETIF_MSG_LINK,
3794                                                  "port %x: External link"
3795                                                  " up in 2.5G\n", params->port);
3796                                 } else if ((link_status & (1<<0)) &&
3797                                            (!(link_status & (1<<13)))) {
3798                                         ext_phy_link_up = 1;
3799                                         vars->line_speed = SPEED_1000;
3800                                         DP(NETIF_MSG_LINK,
3801                                                  "port %x: External link"
3802                                                  " up in 1G\n", params->port);
3803                                 } else {
3804                                         ext_phy_link_up = 0;
3805                                         DP(NETIF_MSG_LINK,
3806                                                  "port %x: External link"
3807                                                  " is down\n", params->port);
3808                                 }
3809                         } else {
3810                                 /* See if 1G link is up for the 8072 */
3811                                 bnx2x_cl45_read(bp, params->port,
3812                                                       ext_phy_type,
3813                                                       ext_phy_addr,
3814                                                       MDIO_AN_DEVAD,
3815                                                       0x8304,
3816                                                       &an1000_status);
3817                                 bnx2x_cl45_read(bp, params->port,
3818                                                       ext_phy_type,
3819                                                       ext_phy_addr,
3820                                                       MDIO_AN_DEVAD,
3821                                                       0x8304,
3822                                                       &an1000_status);
3823                                 if (an1000_status & (1<<1)) {
3824                                         ext_phy_link_up = 1;
3825                                         vars->line_speed = SPEED_1000;
3826                                         DP(NETIF_MSG_LINK,
3827                                                  "port %x: External link"
3828                                                  " up in 1G\n", params->port);
3829                                 } else if (ext_phy_link_up) {
3830                                         ext_phy_link_up = 1;
3831                                         vars->line_speed = SPEED_10000;
3832                                         DP(NETIF_MSG_LINK,
3833                                                  "port %x: External link"
3834                                                  " up in 10G\n", params->port);
3835                                 }
3836                         }
3837
3838
3839                         break;
3840                 }
3841                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3842                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3843                                       ext_phy_addr,
3844                                       MDIO_PMA_DEVAD,
3845                                       MDIO_PMA_REG_LASI_STATUS, &val2);
3846                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3847                                       ext_phy_addr,
3848                                       MDIO_PMA_DEVAD,
3849                                       MDIO_PMA_REG_LASI_STATUS, &val1);
3850                         DP(NETIF_MSG_LINK,
3851                                  "10G-base-T LASI status 0x%x->0x%x\n",
3852                                   val2, val1);
3853                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3854                                       ext_phy_addr,
3855                                       MDIO_PMA_DEVAD,
3856                                       MDIO_PMA_REG_STATUS, &val2);
3857                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3858                                       ext_phy_addr,
3859                                       MDIO_PMA_DEVAD,
3860                                       MDIO_PMA_REG_STATUS, &val1);
3861                         DP(NETIF_MSG_LINK,
3862                                  "10G-base-T PMA status 0x%x->0x%x\n",
3863                                  val2, val1);
3864                         ext_phy_link_up = ((val1 & 4) == 4);
3865                         /* if link is up
3866                          * print the AN outcome of the SFX7101 PHY
3867                          */
3868                         if (ext_phy_link_up) {
3869                                 bnx2x_cl45_read(bp, params->port,
3870                                               ext_phy_type,
3871                                               ext_phy_addr,
3872                                               MDIO_AN_DEVAD,
3873                                               MDIO_AN_REG_MASTER_STATUS,
3874                                               &val2);
3875                                 vars->line_speed = SPEED_10000;
3876                                 DP(NETIF_MSG_LINK,
3877                                          "SFX7101 AN status 0x%x->Master=%x\n",
3878                                           val2,
3879                                          (val2 & (1<<14)));
3880                         }
3881                         break;
3882                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
3883                         /* Clear LASI interrupt */
3884                         bnx2x_cl45_read(bp, params->port,
3885                                       ext_phy_type,
3886                                       ext_phy_addr,
3887                                       MDIO_PMA_DEVAD,
3888                                       MDIO_PMA_REG_LASI_STATUS, &val1);
3889                         DP(NETIF_MSG_LINK, "8481 LASI status reg = 0x%x\n",
3890                                  val1);
3891
3892                         /* Check 10G-BaseT link status */
3893                         /* Check Global PMD signal ok */
3894                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3895                                       ext_phy_addr,
3896                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
3897                                       &rx_sd);
3898                         /* Check PCS block lock */
3899                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
3900                                       ext_phy_addr,
3901                                       MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
3902                                       &pcs_status);
3903                         DP(NETIF_MSG_LINK, "8481 1.a = 0x%x, 1.20 = 0x%x\n",
3904                                  rx_sd, pcs_status);
3905                         if (rx_sd & pcs_status & 0x1) {
3906                                 vars->line_speed = SPEED_10000;
3907                                 ext_phy_link_up = 1;
3908                         } else {
3909
3910                                 /* Check 1000-BaseT link status */
3911                                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3912                                               ext_phy_addr,
3913                                               MDIO_AN_DEVAD, 0xFFE1,
3914                                               &val1);
3915
3916                                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3917                                               ext_phy_addr,
3918                                               MDIO_AN_DEVAD, 0xFFE1,
3919                                               &val2);
3920                                 DP(NETIF_MSG_LINK, "8481 7.FFE1 ="
3921                                              "0x%x-->0x%x\n", val1, val2);
3922                                 if (val2 & (1<<2)) {
3923                                         vars->line_speed = SPEED_1000;
3924                                         ext_phy_link_up = 1;
3925                                 }
3926                         }
3927
3928                         break;
3929                 default:
3930                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3931                            params->ext_phy_config);
3932                         ext_phy_link_up = 0;
3933                         break;
3934                 }
3935
3936         } else { /* SerDes */
3937                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3938                 switch (ext_phy_type) {
3939                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3940                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
3941                         ext_phy_link_up = 1;
3942                         break;
3943
3944                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3945                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
3946                         ext_phy_link_up = 1;
3947                         break;
3948
3949                 default:
3950                         DP(NETIF_MSG_LINK,
3951                                  "BAD SerDes ext_phy_config 0x%x\n",
3952                                  params->ext_phy_config);
3953                         ext_phy_link_up = 0;
3954                         break;
3955                 }
3956         }
3957
3958         return ext_phy_link_up;
3959 }
3960
3961 static void bnx2x_link_int_enable(struct link_params *params)
3962 {
3963         u8 port = params->port;
3964         u32 ext_phy_type;
3965         u32 mask;
3966         struct bnx2x *bp = params->bp;
3967         /* setting the status to report on link up
3968            for either XGXS or SerDes */
3969
3970         if (params->switch_cfg == SWITCH_CFG_10G) {
3971                 mask = (NIG_MASK_XGXS0_LINK10G |
3972                         NIG_MASK_XGXS0_LINK_STATUS);
3973                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3974                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3975                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3976                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3977                     (ext_phy_type !=
3978                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3979                         mask |= NIG_MASK_MI_INT;
3980                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
3981                 }
3982
3983         } else { /* SerDes */
3984                 mask = NIG_MASK_SERDES0_LINK_STATUS;
3985                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3986                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3987                 if ((ext_phy_type !=
3988                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3989                     (ext_phy_type !=
3990                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3991                         mask |= NIG_MASK_MI_INT;
3992                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
3993                 }
3994         }
3995         bnx2x_bits_en(bp,
3996                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3997                       mask);
3998         DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3999                  (params->switch_cfg == SWITCH_CFG_10G),
4000                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4001
4002         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
4003                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4004                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4005                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
4006         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4007            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4008            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4009 }
4010
4011
4012 /*
4013  * link management
4014  */
4015 static void bnx2x_link_int_ack(struct link_params *params,
4016                              struct link_vars *vars, u8 is_10g)
4017 {
4018         struct bnx2x *bp = params->bp;
4019         u8 port = params->port;
4020
4021         /* first reset all status
4022          * we assume only one line will be change at a time */
4023         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4024                      (NIG_STATUS_XGXS0_LINK10G |
4025                       NIG_STATUS_XGXS0_LINK_STATUS |
4026                       NIG_STATUS_SERDES0_LINK_STATUS));
4027         if (vars->phy_link_up) {
4028                 if (is_10g) {
4029                         /* Disable the 10G link interrupt
4030                          * by writing 1 to the status register
4031                          */
4032                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
4033                         bnx2x_bits_en(bp,
4034                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4035                                       NIG_STATUS_XGXS0_LINK10G);
4036
4037                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
4038                         /* Disable the link interrupt
4039                          * by writing 1 to the relevant lane
4040                          * in the status register
4041                          */
4042                         u32 ser_lane = ((params->lane_config &
4043                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4044                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4045
4046                         DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
4047                         bnx2x_bits_en(bp,
4048                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4049                                       ((1 << ser_lane) <<
4050                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
4051
4052                 } else { /* SerDes */
4053                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
4054                         /* Disable the link interrupt
4055                          * by writing 1 to the status register
4056                          */
4057                         bnx2x_bits_en(bp,
4058                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4059                                       NIG_STATUS_SERDES0_LINK_STATUS);
4060                 }
4061
4062         } else { /* link_down */
4063         }
4064 }
4065
4066 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
4067 {
4068         u8 *str_ptr = str;
4069         u32 mask = 0xf0000000;
4070         u8 shift = 8*4;
4071         u8 digit;
4072         if (len < 10) {
4073                 /* Need more than 10chars for this format */
4074                 *str_ptr = '\0';
4075                 return -EINVAL;
4076         }
4077         while (shift > 0) {
4078
4079                 shift -= 4;
4080                 digit = ((num & mask) >> shift);
4081                 if (digit < 0xa)
4082                         *str_ptr = digit + '0';
4083                 else
4084                         *str_ptr = digit - 0xa + 'a';
4085                 str_ptr++;
4086                 mask = mask >> 4;
4087                 if (shift == 4*4) {
4088                         *str_ptr = ':';
4089                         str_ptr++;
4090                 }
4091         }
4092         *str_ptr = '\0';
4093         return 0;
4094 }
4095
4096
4097 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
4098                            u32 ext_phy_type)
4099 {
4100         u32 cnt = 0;
4101         u16 ctrl = 0;
4102         /* Enable EMAC0 in to enable MDIO */
4103         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
4104                (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
4105         msleep(5);
4106
4107         /* take ext phy out of reset */
4108         bnx2x_set_gpio(bp,
4109                           MISC_REGISTERS_GPIO_2,
4110                           MISC_REGISTERS_GPIO_HIGH,
4111                           port);
4112
4113         bnx2x_set_gpio(bp,
4114                           MISC_REGISTERS_GPIO_1,
4115                           MISC_REGISTERS_GPIO_HIGH,
4116                           port);
4117
4118         /* wait for 5ms */
4119         msleep(5);
4120
4121         for (cnt = 0; cnt < 1000; cnt++) {
4122                 msleep(1);
4123                 bnx2x_cl45_read(bp, port,
4124                               ext_phy_type,
4125                               ext_phy_addr,
4126                               MDIO_PMA_DEVAD,
4127                               MDIO_PMA_REG_CTRL,
4128                                &ctrl);
4129                 if (!(ctrl & (1<<15))) {
4130                         DP(NETIF_MSG_LINK, "Reset completed\n\n");
4131                                 break;
4132                 }
4133         }
4134 }
4135
4136 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
4137 {
4138         /* put sf to reset */
4139         bnx2x_set_gpio(bp,
4140                           MISC_REGISTERS_GPIO_1,
4141                           MISC_REGISTERS_GPIO_LOW,
4142                           port);
4143         bnx2x_set_gpio(bp,
4144                           MISC_REGISTERS_GPIO_2,
4145                           MISC_REGISTERS_GPIO_LOW,
4146                           port);
4147 }
4148
4149 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4150                               u8 *version, u16 len)
4151 {
4152         struct bnx2x *bp = params->bp;
4153         u32 ext_phy_type = 0;
4154         u32 spirom_ver = 0;
4155         u8 status = 0 ;
4156
4157         if (version == NULL || params == NULL)
4158                 return -EINVAL;
4159
4160         spirom_ver = REG_RD(bp, params->shmem_base +
4161                    offsetof(struct shmem_region,
4162                             port_mb[params->port].ext_phy_fw_version));
4163
4164         /* reset the returned value to zero */
4165         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4166         switch (ext_phy_type) {
4167         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4168
4169                 if (len < 5)
4170                         return -EINVAL;
4171
4172                 version[0] = (spirom_ver & 0xFF);
4173                 version[1] = (spirom_ver & 0xFF00) >> 8;
4174                 version[2] = (spirom_ver & 0xFF0000) >> 16;
4175                 version[3] = (spirom_ver & 0xFF000000) >> 24;
4176                 version[4] = '\0';
4177
4178                 break;
4179         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4180         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4181         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4182         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4183         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4184                 status = bnx2x_format_ver(spirom_ver, version, len);
4185                 break;
4186         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4187                 break;
4188
4189         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4190                 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
4191                                     " type is FAILURE!\n");
4192                 status = -EINVAL;
4193                 break;
4194
4195         default:
4196                 break;
4197         }
4198         return status;
4199 }
4200
4201 static void bnx2x_set_xgxs_loopback(struct link_params *params,
4202                                   struct link_vars *vars,
4203                                   u8 is_10g)
4204 {
4205         u8 port = params->port;
4206         struct bnx2x *bp = params->bp;
4207
4208         if (is_10g) {
4209                 u32 md_devad;
4210
4211                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4212
4213                 /* change the uni_phy_addr in the nig */
4214                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4215                                           port*0x18));
4216
4217                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4218
4219                 bnx2x_cl45_write(bp, port, 0,
4220                                params->phy_addr,
4221                                5,
4222                                (MDIO_REG_BANK_AER_BLOCK +
4223                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4224                                0x2800);
4225
4226                 bnx2x_cl45_write(bp, port, 0,
4227                                params->phy_addr,
4228                                5,
4229                                (MDIO_REG_BANK_CL73_IEEEB0 +
4230                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4231                                0x6041);
4232                 msleep(200);
4233                 /* set aer mmd back */
4234                 bnx2x_set_aer_mmd(params, vars);
4235
4236                 /* and md_devad */
4237                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4238                             md_devad);
4239
4240         } else {
4241                 u16 mii_control;
4242
4243                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
4244
4245                 CL45_RD_OVER_CL22(bp, port,
4246                                       params->phy_addr,
4247                                       MDIO_REG_BANK_COMBO_IEEE0,
4248                                       MDIO_COMBO_IEEE0_MII_CONTROL,
4249                                       &mii_control);
4250
4251                 CL45_WR_OVER_CL22(bp, port,
4252                                       params->phy_addr,
4253                                       MDIO_REG_BANK_COMBO_IEEE0,
4254                                       MDIO_COMBO_IEEE0_MII_CONTROL,
4255                                       (mii_control |
4256                                        MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
4257         }
4258 }
4259
4260
4261 static void bnx2x_ext_phy_loopback(struct link_params *params)
4262 {
4263         struct bnx2x *bp = params->bp;
4264         u8 ext_phy_addr;
4265         u32 ext_phy_type;
4266
4267         if (params->switch_cfg == SWITCH_CFG_10G) {
4268                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4269                 /* CL37 Autoneg Enabled */
4270                 ext_phy_addr = ((params->ext_phy_config &
4271                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4272                                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4273                 switch (ext_phy_type) {
4274                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4275                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4276                         DP(NETIF_MSG_LINK,
4277                                 "ext_phy_loopback: We should not get here\n");
4278                         break;
4279                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4280                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
4281                         break;
4282                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4283                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
4284                         break;
4285                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4286                         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4287                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
4288                                        ext_phy_addr,
4289                                        MDIO_PMA_DEVAD,
4290                                        MDIO_PMA_REG_CTRL,
4291                                        0x0001);
4292                         break;
4293                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4294                         /* SFX7101_XGXS_TEST1 */
4295                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
4296                                        ext_phy_addr,
4297                                        MDIO_XS_DEVAD,
4298                                        MDIO_XS_SFX7101_XGXS_TEST1,
4299                                        0x100);
4300                         DP(NETIF_MSG_LINK,
4301                                 "ext_phy_loopback: set ext phy loopback\n");
4302                         break;
4303                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4304
4305                         break;
4306                 } /* switch external PHY type */
4307         } else {
4308                 /* serdes */
4309                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4310                 ext_phy_addr = (params->ext_phy_config  &
4311                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
4312                 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
4313         }
4314 }
4315
4316
4317 /*
4318  *------------------------------------------------------------------------
4319  * bnx2x_override_led_value -
4320  *
4321  * Override the led value of the requsted led
4322  *
4323  *------------------------------------------------------------------------
4324  */
4325 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
4326                           u32 led_idx, u32 value)
4327 {
4328         u32 reg_val;
4329
4330         /* If port 0 then use EMAC0, else use EMAC1*/
4331         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4332
4333         DP(NETIF_MSG_LINK,
4334                  "bnx2x_override_led_value() port %x led_idx %d value %d\n",
4335                  port, led_idx, value);
4336
4337         switch (led_idx) {
4338         case 0: /* 10MB led */
4339                 /* Read the current value of the LED register in
4340                 the EMAC block */
4341                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4342                 /* Set the OVERRIDE bit to 1 */
4343                 reg_val |= EMAC_LED_OVERRIDE;
4344                 /* If value is 1, set the 10M_OVERRIDE bit,
4345                 otherwise reset it.*/
4346                 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
4347                         (reg_val & ~EMAC_LED_10MB_OVERRIDE);
4348                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4349                 break;
4350         case 1: /*100MB led    */
4351                 /*Read the current value of the LED register in
4352                 the EMAC block */
4353                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4354                 /*  Set the OVERRIDE bit to 1 */
4355                 reg_val |= EMAC_LED_OVERRIDE;
4356                 /*  If value is 1, set the 100M_OVERRIDE bit,
4357                 otherwise reset it.*/
4358                 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
4359                         (reg_val & ~EMAC_LED_100MB_OVERRIDE);
4360                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4361                 break;
4362         case 2: /* 1000MB led */
4363                 /* Read the current value of the LED register in the
4364                 EMAC block */
4365                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4366                 /* Set the OVERRIDE bit to 1 */
4367                 reg_val |= EMAC_LED_OVERRIDE;
4368                 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
4369                 reset it. */
4370                 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
4371                         (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
4372                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4373                 break;
4374         case 3: /* 2500MB led */
4375                 /*  Read the current value of the LED register in the
4376                 EMAC block*/
4377                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4378                 /* Set the OVERRIDE bit to 1 */
4379                 reg_val |= EMAC_LED_OVERRIDE;
4380                 /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
4381                 reset it.*/
4382                 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
4383                         (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
4384                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4385                 break;
4386         case 4: /*10G led */
4387                 if (port == 0) {
4388                         REG_WR(bp, NIG_REG_LED_10G_P0,
4389                                     value);
4390                 } else {
4391                         REG_WR(bp, NIG_REG_LED_10G_P1,
4392                                     value);
4393                 }
4394                 break;
4395         case 5: /* TRAFFIC led */
4396                 /* Find if the traffic control is via BMAC or EMAC */
4397                 if (port == 0)
4398                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
4399                 else
4400                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
4401
4402                 /*  Override the traffic led in the EMAC:*/
4403                 if (reg_val == 1) {
4404                         /* Read the current value of the LED register in
4405                         the EMAC block */
4406                         reg_val = REG_RD(bp, emac_base +
4407                                              EMAC_REG_EMAC_LED);
4408                         /* Set the TRAFFIC_OVERRIDE bit to 1 */
4409                         reg_val |= EMAC_LED_OVERRIDE;
4410                         /* If value is 1, set the TRAFFIC bit, otherwise
4411                         reset it.*/
4412                         reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
4413                                 (reg_val & ~EMAC_LED_TRAFFIC);
4414                         REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4415                 } else { /* Override the traffic led in the BMAC: */
4416                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4417                                    + port*4, 1);
4418                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
4419                                     value);
4420                 }
4421                 break;
4422         default:
4423                 DP(NETIF_MSG_LINK,
4424                          "bnx2x_override_led_value() unknown led index %d "
4425                          "(should be 0-5)\n", led_idx);
4426                 return -EINVAL;
4427         }
4428
4429         return 0;
4430 }
4431
4432
4433 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
4434                u16 hw_led_mode, u32 chip_id)
4435 {
4436         u8 rc = 0;
4437         u32 tmp;
4438         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4439         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4440         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4441                  speed, hw_led_mode);
4442         switch (mode) {
4443         case LED_MODE_OFF:
4444                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4445                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4446                            SHARED_HW_CFG_LED_MAC1);
4447
4448                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4449                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
4450                 break;
4451
4452         case LED_MODE_OPER:
4453                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
4454                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
4455                            port*4, 0);
4456                 /* Set blinking rate to ~15.9Hz */
4457                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
4458                            LED_BLINK_RATE_VAL);
4459                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
4460                            port*4, 1);
4461                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
4462                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
4463                             (tmp & (~EMAC_LED_OVERRIDE)));
4464
4465                 if (!CHIP_IS_E1H(bp) &&
4466                     ((speed == SPEED_2500) ||
4467                      (speed == SPEED_1000) ||
4468                      (speed == SPEED_100) ||
4469                      (speed == SPEED_10))) {
4470                         /* On Everest 1 Ax chip versions for speeds less than
4471                         10G LED scheme is different */
4472                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4473                                    + port*4, 1);
4474                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
4475                                    port*4, 0);
4476                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
4477                                    port*4, 1);
4478                 }
4479                 break;
4480
4481         default:
4482                 rc = -EINVAL;
4483                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
4484                          mode);
4485                 break;
4486         }
4487         return rc;
4488
4489 }
4490
4491 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
4492 {
4493         struct bnx2x *bp = params->bp;
4494         u16 gp_status = 0;
4495
4496         CL45_RD_OVER_CL22(bp, params->port,
4497                               params->phy_addr,
4498                               MDIO_REG_BANK_GP_STATUS,
4499                               MDIO_GP_STATUS_TOP_AN_STATUS1,
4500                               &gp_status);
4501         /* link is up only if both local phy and external phy are up */
4502         if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
4503             bnx2x_ext_phy_is_link_up(params, vars))
4504                 return 0;
4505
4506         return -ESRCH;
4507 }
4508
4509 static u8 bnx2x_link_initialize(struct link_params *params,
4510                               struct link_vars *vars)
4511 {
4512         struct bnx2x *bp = params->bp;
4513         u8 port = params->port;
4514         u8 rc = 0;
4515         u8 non_ext_phy;
4516         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4517         /* Activate the external PHY */
4518         bnx2x_ext_phy_reset(params, vars);
4519
4520         bnx2x_set_aer_mmd(params, vars);
4521
4522         if (vars->phy_flags & PHY_XGXS_FLAG)
4523                 bnx2x_set_master_ln(params);
4524
4525         rc = bnx2x_reset_unicore(params);
4526         /* reset the SerDes and wait for reset bit return low */
4527         if (rc != 0)
4528                 return rc;
4529
4530         bnx2x_set_aer_mmd(params, vars);
4531
4532         /* setting the masterLn_def again after the reset */
4533         if (vars->phy_flags & PHY_XGXS_FLAG) {
4534                 bnx2x_set_master_ln(params);
4535                 bnx2x_set_swap_lanes(params);
4536         }
4537
4538         if (vars->phy_flags & PHY_XGXS_FLAG) {
4539                 if ((params->req_line_speed &&
4540                     ((params->req_line_speed == SPEED_100) ||
4541                      (params->req_line_speed == SPEED_10))) ||
4542                     (!params->req_line_speed &&
4543                      (params->speed_cap_mask >=
4544                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
4545                      (params->speed_cap_mask <
4546                        PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4547                      ))  {
4548                         vars->phy_flags |= PHY_SGMII_FLAG;
4549                 } else {
4550                         vars->phy_flags &= ~PHY_SGMII_FLAG;
4551                 }
4552         }
4553         /* In case of external phy existance, the line speed would be the
4554          line speed linked up by the external phy. In case it is direct only,
4555           then the line_speed during initialization will be equal to the
4556            req_line_speed*/
4557         vars->line_speed = params->req_line_speed;
4558
4559         bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
4560
4561         /* init ext phy and enable link state int */
4562         non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
4563                        (params->loopback_mode == LOOPBACK_XGXS_10) ||
4564                        (params->loopback_mode == LOOPBACK_EXT_PHY));
4565
4566         if (non_ext_phy ||
4567             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
4568             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
4569             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481)) {
4570                 if (params->req_line_speed == SPEED_AUTO_NEG)
4571                         bnx2x_set_parallel_detection(params, vars->phy_flags);
4572                 bnx2x_init_internal_phy(params, vars);
4573         }
4574
4575         if (!non_ext_phy)
4576                 rc |= bnx2x_ext_phy_init(params, vars);
4577
4578         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4579                      (NIG_STATUS_XGXS0_LINK10G |
4580                       NIG_STATUS_XGXS0_LINK_STATUS |
4581                       NIG_STATUS_SERDES0_LINK_STATUS));
4582
4583         return rc;
4584
4585 }
4586
4587
4588 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4589 {
4590         struct bnx2x *bp = params->bp;
4591
4592         u32 val;
4593         DP(NETIF_MSG_LINK, "Phy Initialization started \n");
4594         DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
4595                   params->req_line_speed, params->req_flow_ctrl);
4596         vars->link_status = 0;
4597         vars->phy_link_up = 0;
4598         vars->link_up = 0;
4599         vars->line_speed = 0;
4600         vars->duplex = DUPLEX_FULL;
4601         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4602         vars->mac_type = MAC_TYPE_NONE;
4603
4604         if (params->switch_cfg ==  SWITCH_CFG_1G)
4605                 vars->phy_flags = PHY_SERDES_FLAG;
4606         else
4607                 vars->phy_flags = PHY_XGXS_FLAG;
4608
4609
4610         /* disable attentions */
4611         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
4612                        (NIG_MASK_XGXS0_LINK_STATUS |
4613                         NIG_MASK_XGXS0_LINK10G |
4614                         NIG_MASK_SERDES0_LINK_STATUS |
4615                         NIG_MASK_MI_INT));
4616
4617         bnx2x_emac_init(params, vars);
4618
4619         if (CHIP_REV_IS_FPGA(bp)) {
4620                 vars->link_up = 1;
4621                 vars->line_speed = SPEED_10000;
4622                 vars->duplex = DUPLEX_FULL;
4623                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4624                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4625                 /* enable on E1.5 FPGA */
4626                 if (CHIP_IS_E1H(bp)) {
4627                         vars->flow_ctrl |=
4628                                 (BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
4629                         vars->link_status |=
4630                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
4631                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
4632                 }
4633
4634                 bnx2x_emac_enable(params, vars, 0);
4635                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4636                 /* disable drain */
4637                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4638                                     + params->port*4, 0);
4639
4640                 /* update shared memory */
4641                 bnx2x_update_mng(params, vars->link_status);
4642
4643                 return 0;
4644
4645         } else
4646         if (CHIP_REV_IS_EMUL(bp)) {
4647
4648                 vars->link_up = 1;
4649                 vars->line_speed = SPEED_10000;
4650                 vars->duplex = DUPLEX_FULL;
4651                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4652                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
4653
4654                 bnx2x_bmac_enable(params, vars, 0);
4655
4656                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4657                 /* Disable drain */
4658                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4659                                     + params->port*4, 0);
4660
4661                 /* update shared memory */
4662                 bnx2x_update_mng(params, vars->link_status);
4663
4664                 return 0;
4665
4666         } else
4667         if (params->loopback_mode == LOOPBACK_BMAC) {
4668                 vars->link_up = 1;
4669                 vars->line_speed = SPEED_10000;
4670                 vars->duplex = DUPLEX_FULL;
4671                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4672                 vars->mac_type = MAC_TYPE_BMAC;
4673
4674                 vars->phy_flags = PHY_XGXS_FLAG;
4675
4676                 bnx2x_phy_deassert(params, vars->phy_flags);
4677                 /* set bmac loopback */
4678                 bnx2x_bmac_enable(params, vars, 1);
4679
4680                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4681                     params->port*4, 0);
4682         } else if (params->loopback_mode == LOOPBACK_EMAC) {
4683                 vars->link_up = 1;
4684                 vars->line_speed = SPEED_1000;
4685                 vars->duplex = DUPLEX_FULL;
4686                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4687                 vars->mac_type = MAC_TYPE_EMAC;
4688
4689                 vars->phy_flags = PHY_XGXS_FLAG;
4690
4691                 bnx2x_phy_deassert(params, vars->phy_flags);
4692                 /* set bmac loopback */
4693                 bnx2x_emac_enable(params, vars, 1);
4694                 bnx2x_emac_program(params, vars->line_speed,
4695                                               vars->duplex);
4696                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4697                     params->port*4, 0);
4698         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4699                   (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4700                 vars->link_up = 1;
4701                 vars->line_speed = SPEED_10000;
4702                 vars->duplex = DUPLEX_FULL;
4703                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4704
4705                 vars->phy_flags = PHY_XGXS_FLAG;
4706
4707                 val = REG_RD(bp,
4708                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
4709                                  params->port*0x18);
4710                 params->phy_addr = (u8)val;
4711
4712                 bnx2x_phy_deassert(params, vars->phy_flags);
4713                 bnx2x_link_initialize(params, vars);
4714
4715                 vars->mac_type = MAC_TYPE_BMAC;
4716
4717                 bnx2x_bmac_enable(params, vars, 0);
4718
4719                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
4720                         /* set 10G XGXS loopback */
4721                         bnx2x_set_xgxs_loopback(params, vars, 1);
4722                 } else {
4723                         /* set external phy loopback */
4724                         bnx2x_ext_phy_loopback(params);
4725                 }
4726                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4727                             params->port*4, 0);
4728         } else
4729         /* No loopback */
4730         {
4731
4732                 bnx2x_phy_deassert(params, vars->phy_flags);
4733                 switch (params->switch_cfg) {
4734                 case SWITCH_CFG_1G:
4735                         vars->phy_flags |= PHY_SERDES_FLAG;
4736                         if ((params->ext_phy_config &
4737                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4738                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4739                                 vars->phy_flags |=
4740                                         PHY_SGMII_FLAG;
4741                         }
4742
4743                         val = REG_RD(bp,
4744                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
4745                                          params->port*0x10);
4746
4747                         params->phy_addr = (u8)val;
4748
4749                         break;
4750                 case SWITCH_CFG_10G:
4751                         vars->phy_flags |= PHY_XGXS_FLAG;
4752                         val = REG_RD(bp,
4753                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
4754                                  params->port*0x18);
4755                         params->phy_addr = (u8)val;
4756
4757                         break;
4758                 default:
4759                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4760                         return -EINVAL;
4761                         break;
4762                 }
4763
4764                 bnx2x_link_initialize(params, vars);
4765                 msleep(30);
4766                 bnx2x_link_int_enable(params);
4767         }
4768         return 0;
4769 }
4770
4771 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
4772 {
4773         DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
4774
4775         /* Set serial boot control for external load */
4776         bnx2x_cl45_write(bp, port,
4777                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
4778                        MDIO_PMA_DEVAD,
4779                        MDIO_PMA_REG_GEN_CTRL, 0x0001);
4780
4781         /* Disable Transmitter */
4782         bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
4783
4784 }
4785
4786 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
4787                   u8 reset_ext_phy)
4788 {
4789
4790         struct bnx2x *bp = params->bp;
4791         u32 ext_phy_config = params->ext_phy_config;
4792         u16 hw_led_mode = params->hw_led_mode;
4793         u32 chip_id = params->chip_id;
4794         u8 port = params->port;
4795         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4796         /* disable attentions */
4797
4798         vars->link_status = 0;
4799         bnx2x_update_mng(params, vars->link_status);
4800         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4801                      (NIG_MASK_XGXS0_LINK_STATUS |
4802                       NIG_MASK_XGXS0_LINK10G |
4803                       NIG_MASK_SERDES0_LINK_STATUS |
4804                       NIG_MASK_MI_INT));
4805
4806         /* activate nig drain */
4807         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4808
4809         /* disable nig egress interface */
4810         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4811         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4812
4813         /* Stop BigMac rx */
4814         bnx2x_bmac_rx_disable(bp, port);
4815
4816         /* disable emac */
4817         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4818
4819         msleep(10);
4820         /* The PHY reset is controled by GPIO 1
4821          * Hold it as vars low
4822          */
4823          /* clear link led */
4824         bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4825         if (reset_ext_phy) {
4826                 switch (ext_phy_type) {
4827                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4828                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4829                         break;
4830                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4831                         DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4832                                  "low power mode\n",
4833                                  port);
4834                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4835                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4836                                           port);
4837                         break;
4838                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4839                 {
4840                         u8 ext_phy_addr = ((params->ext_phy_config &
4841                                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4842                                          PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4843                         /* Set soft reset */
4844                         bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
4845                         break;
4846                 }
4847                 default:
4848                         /* HW reset */
4849                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4850                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4851                                           port);
4852                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4853                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
4854                                           port);
4855                         DP(NETIF_MSG_LINK, "reset external PHY\n");
4856                 }
4857         }
4858         /* reset the SerDes/XGXS */
4859         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4860                (0x1ff << (port*16)));
4861
4862         /* reset BigMac */
4863         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4864                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4865
4866         /* disable nig ingress interface */
4867         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4868         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4869         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4870         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4871         vars->link_up = 0;
4872         return 0;
4873 }
4874
4875 static u8 bnx2x_update_link_down(struct link_params *params,
4876                                struct link_vars *vars)
4877 {
4878         struct bnx2x *bp = params->bp;
4879         u8 port = params->port;
4880         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4881         bnx2x_set_led(bp, port, LED_MODE_OFF,
4882                     0, params->hw_led_mode,
4883                     params->chip_id);
4884
4885         /* indicate no mac active */
4886         vars->mac_type = MAC_TYPE_NONE;
4887
4888         /* update shared memory */
4889         vars->link_status = 0;
4890         vars->line_speed = 0;
4891         bnx2x_update_mng(params, vars->link_status);
4892
4893         /* activate nig drain */
4894         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4895
4896         /* disable emac */
4897         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4898
4899         msleep(10);
4900
4901         /* reset BigMac */
4902         bnx2x_bmac_rx_disable(bp, params->port);
4903         REG_WR(bp, GRCBASE_MISC +
4904                    MISC_REGISTERS_RESET_REG_2_CLEAR,
4905                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4906         return 0;
4907 }
4908
4909 static u8 bnx2x_update_link_up(struct link_params *params,
4910                              struct link_vars *vars,
4911                              u8 link_10g, u32 gp_status)
4912 {
4913         struct bnx2x *bp = params->bp;
4914         u8 port = params->port;
4915         u8 rc = 0;
4916         vars->link_status |= LINK_STATUS_LINK_UP;
4917         if (link_10g) {
4918                 bnx2x_bmac_enable(params, vars, 0);
4919                 bnx2x_set_led(bp, port, LED_MODE_OPER,
4920                             SPEED_10000, params->hw_led_mode,
4921                             params->chip_id);
4922
4923         } else {
4924                 bnx2x_emac_enable(params, vars, 0);
4925                 rc = bnx2x_emac_program(params, vars->line_speed,
4926                                       vars->duplex);
4927
4928                 /* AN complete? */
4929                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4930                         if (!(vars->phy_flags &
4931                               PHY_SGMII_FLAG))
4932                                 bnx2x_set_gmii_tx_driver(params);
4933                 }
4934         }
4935
4936         /* PBF - link up */
4937         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4938                               vars->line_speed);
4939
4940         /* disable drain */
4941         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4942
4943         /* update shared memory */
4944         bnx2x_update_mng(params, vars->link_status);
4945         msleep(20);
4946         return rc;
4947 }
4948 /* This function should called upon link interrupt */
4949 /* In case vars->link_up, driver needs to
4950         1. Update the pbf
4951         2. Disable drain
4952         3. Update the shared memory
4953         4. Indicate link up
4954         5. Set LEDs
4955    Otherwise,
4956         1. Update shared memory
4957         2. Reset BigMac
4958         3. Report link down
4959         4. Unset LEDs
4960 */
4961 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4962 {
4963         struct bnx2x *bp = params->bp;
4964         u8 port = params->port;
4965         u16 gp_status;
4966         u8 link_10g;
4967         u8 ext_phy_link_up, rc = 0;
4968         u32 ext_phy_type;
4969
4970         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4971          port,
4972         (vars->phy_flags & PHY_XGXS_FLAG),
4973          REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4974
4975         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4976         REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4977         REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4978         REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4979
4980         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4981           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4982           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4983
4984         /* disable emac */
4985         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4986
4987         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4988
4989         /* Check external link change only for non-direct */
4990         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4991
4992         /* Read gp_status */
4993         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4994                               MDIO_REG_BANK_GP_STATUS,
4995                               MDIO_GP_STATUS_TOP_AN_STATUS1,
4996                               &gp_status);
4997
4998         rc = bnx2x_link_settings_status(params, vars, gp_status);
4999         if (rc != 0)
5000                 return rc;
5001
5002         /* anything 10 and over uses the bmac */
5003         link_10g = ((vars->line_speed == SPEED_10000) ||
5004                     (vars->line_speed == SPEED_12000) ||
5005                     (vars->line_speed == SPEED_12500) ||
5006                     (vars->line_speed == SPEED_13000) ||
5007                     (vars->line_speed == SPEED_15000) ||
5008                     (vars->line_speed == SPEED_16000));
5009
5010         bnx2x_link_int_ack(params, vars, link_10g);
5011
5012         /* In case external phy link is up, and internal link is down
5013         ( not initialized yet probably after link initialization, it needs
5014         to be initialized.
5015         Note that after link down-up as result of cable plug,
5016         the xgxs link would probably become up again without the need to
5017         initialize it*/
5018
5019         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5020             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
5021             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
5022             (ext_phy_link_up && !vars->phy_link_up))
5023                 bnx2x_init_internal_phy(params, vars);
5024
5025         /* link is up only if both local phy and external phy are up */
5026         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
5027
5028         if (vars->link_up)
5029                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
5030         else
5031                 rc = bnx2x_update_link_down(params, vars);
5032
5033         return rc;
5034 }
5035
5036 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5037 {
5038         u8 ext_phy_addr[PORT_MAX];
5039         u16 val;
5040         s8 port;
5041
5042         /* PART1 - Reset both phys */
5043         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5044                 /* Extract the ext phy address for the port */
5045                 u32 ext_phy_config = REG_RD(bp, shmem_base +
5046                                         offsetof(struct shmem_region,
5047                    dev_info.port_hw_config[port].external_phy_config));
5048
5049                 /* disable attentions */
5050                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5051                              (NIG_MASK_XGXS0_LINK_STATUS |
5052                               NIG_MASK_XGXS0_LINK10G |
5053                               NIG_MASK_SERDES0_LINK_STATUS |
5054                               NIG_MASK_MI_INT));
5055
5056                 ext_phy_addr[port] =
5057                         ((ext_phy_config &
5058                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5059                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5060
5061                 /* Need to take the phy out of low power mode in order
5062                         to write to access its registers */
5063                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5064                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
5065
5066                 /* Reset the phy */
5067                 bnx2x_cl45_write(bp, port,
5068                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5069                                ext_phy_addr[port],
5070                                MDIO_PMA_DEVAD,
5071                                MDIO_PMA_REG_CTRL,
5072                                1<<15);
5073         }
5074
5075         /* Add delay of 150ms after reset */
5076         msleep(150);
5077
5078         /* PART2 - Download firmware to both phys */
5079         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5080                 u16 fw_ver1;
5081
5082                 bnx2x_bcm8073_external_rom_boot(bp, port,
5083                                               ext_phy_addr[port], shmem_base);
5084
5085                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5086                               ext_phy_addr[port],
5087                               MDIO_PMA_DEVAD,
5088                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
5089                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
5090                         DP(NETIF_MSG_LINK,
5091                                  "bnx2x_8073_common_init_phy port %x:"
5092                                  "Download failed. fw version = 0x%x\n",
5093                                  port, fw_ver1);
5094                         return -EINVAL;
5095                 }
5096
5097                 /* Only set bit 10 = 1 (Tx power down) */
5098                 bnx2x_cl45_read(bp, port,
5099                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5100                               ext_phy_addr[port],
5101                               MDIO_PMA_DEVAD,
5102                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
5103
5104                 /* Phase1 of TX_POWER_DOWN reset */
5105                 bnx2x_cl45_write(bp, port,
5106                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5107                                ext_phy_addr[port],
5108                                MDIO_PMA_DEVAD,
5109                                MDIO_PMA_REG_TX_POWER_DOWN,
5110                                (val | 1<<10));
5111         }
5112
5113         /* Toggle Transmitter: Power down and then up with 600ms
5114            delay between */
5115         msleep(600);
5116
5117         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
5118         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
5119                 /* Phase2 of POWER_DOWN_RESET*/
5120                 /* Release bit 10 (Release Tx power down) */
5121                 bnx2x_cl45_read(bp, port,
5122                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5123                               ext_phy_addr[port],
5124                               MDIO_PMA_DEVAD,
5125                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
5126
5127                 bnx2x_cl45_write(bp, port,
5128                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5129                                ext_phy_addr[port],
5130                                MDIO_PMA_DEVAD,
5131                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
5132                 msleep(15);
5133
5134                 /* Read modify write the SPI-ROM version select register */
5135                 bnx2x_cl45_read(bp, port,
5136                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5137                               ext_phy_addr[port],
5138                               MDIO_PMA_DEVAD,
5139                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
5140                 bnx2x_cl45_write(bp, port,
5141                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5142                               ext_phy_addr[port],
5143                               MDIO_PMA_DEVAD,
5144                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
5145
5146                 /* set GPIO2 back to LOW */
5147                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5148                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5149         }
5150         return 0;
5151
5152 }
5153
5154
5155 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5156 {
5157         u8 ext_phy_addr;
5158         u32 val;
5159         s8 port;
5160         /* Use port1 because of the static port-swap */
5161         /* Enable the module detection interrupt */
5162         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
5163         val |= ((1<<MISC_REGISTERS_GPIO_3)|
5164                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
5165         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
5166
5167         bnx2x_hw_reset(bp, 1);
5168         msleep(5);
5169         for (port = 0; port < PORT_MAX; port++) {
5170                 /* Extract the ext phy address for the port */
5171                 u32 ext_phy_config = REG_RD(bp, shmem_base +
5172                                         offsetof(struct shmem_region,
5173                         dev_info.port_hw_config[port].external_phy_config));
5174
5175                 ext_phy_addr =
5176                         ((ext_phy_config &
5177                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5178                               PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5179                 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
5180                          ext_phy_addr);
5181
5182                 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
5183
5184                 /* Set fault module detected LED on */
5185                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5186                                   MISC_REGISTERS_GPIO_HIGH,
5187                                   port);
5188         }
5189
5190         return 0;
5191 }
5192
5193 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5194 {
5195         u8 rc = 0;
5196         u32 ext_phy_type;
5197
5198         DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
5199
5200         /* Read the ext_phy_type for arbitrary port(0) */
5201         ext_phy_type = XGXS_EXT_PHY_TYPE(
5202                         REG_RD(bp, shmem_base +
5203                            offsetof(struct shmem_region,
5204                              dev_info.port_hw_config[0].external_phy_config)));
5205
5206         switch (ext_phy_type) {
5207         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5208         {
5209                 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
5210                 break;
5211         }
5212         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5213                 /* GPIO1 affects both ports, so there's need to pull
5214                 it for single port alone */
5215                 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
5216
5217                 break;
5218         default:
5219                 DP(NETIF_MSG_LINK,
5220                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
5221                          ext_phy_type);
5222                 break;
5223         }
5224
5225         return rc;
5226 }
5227
5228
5229
5230 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
5231 {
5232         u16 val, cnt;
5233
5234         bnx2x_cl45_read(bp, port,
5235                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5236                       phy_addr,
5237                       MDIO_PMA_DEVAD,
5238                       MDIO_PMA_REG_7101_RESET, &val);
5239
5240         for (cnt = 0; cnt < 10; cnt++) {
5241                 msleep(50);
5242                 /* Writes a self-clearing reset */
5243                 bnx2x_cl45_write(bp, port,
5244                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5245                                phy_addr,
5246                                MDIO_PMA_DEVAD,
5247                                MDIO_PMA_REG_7101_RESET,
5248                                (val | (1<<15)));
5249                 /* Wait for clear */
5250                 bnx2x_cl45_read(bp, port,
5251                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5252                               phy_addr,
5253                               MDIO_PMA_DEVAD,
5254                               MDIO_PMA_REG_7101_RESET, &val);
5255
5256                 if ((val & (1<<15)) == 0)
5257                         break;
5258         }
5259 }
5260 #define RESERVED_SIZE 256
5261 /* max application is 160K bytes - data at end of RAM */
5262 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
5263
5264 /* Header is 14 bytes */
5265 #define HEADER_SIZE 14
5266 #define DATA_OFFSET HEADER_SIZE
5267
5268 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
5269         bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
5270                         ext_phy_addr, \
5271                         MDIO_PCS_DEVAD, \
5272                         MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
5273
5274 /* Programs an image to DSP's flash via the SPI port*/
5275 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
5276                                      u8 ext_phy_addr,
5277                                      char data[], u32 size)
5278 {
5279         const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
5280         /* Doesn't include last trans!*/
5281         const u16 last_trans_size = size%4; /* Num bytes on last trans */
5282         u16 trans_cnt, byte_cnt;
5283         u32 data_index;
5284         u16 tmp;
5285         u16 code_started = 0;
5286         u16 image_revision1, image_revision2;
5287         u16 cnt;
5288
5289         DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
5290         /* Going to flash*/
5291         if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
5292                 /* This very often will be the case, because the image is built
5293                 with 160Kbytes size whereas the total image size must actually
5294                 be 160Kbytes-RESERVED_SIZE */
5295                 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
5296                          "truncated to %d bytes\n", size, MAX_APP_SIZE);
5297                 size = MAX_APP_SIZE+HEADER_SIZE;
5298         }
5299         DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
5300         DP(NETIF_MSG_LINK, "          %c%c\n", data[0x150], data[0x151]);
5301         /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
5302            and issuing a reset.*/
5303
5304         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5305                           MISC_REGISTERS_GPIO_HIGH, port);
5306
5307         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5308
5309         /* wait 0.5 sec */
5310         for (cnt = 0; cnt < 100; cnt++)
5311                 msleep(5);
5312
5313         /* Make sure we can access the DSP
5314            And it's in the correct mode (waiting for download) */
5315
5316         bnx2x_cl45_read(bp, port,
5317                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5318                       ext_phy_addr,
5319                       MDIO_PCS_DEVAD,
5320                       MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
5321
5322         if (tmp != 0x000A) {
5323                 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
5324                          "Expected 0x000A, read 0x%04X\n", tmp);
5325                 DP(NETIF_MSG_LINK, "Download failed\n");
5326                 return -EINVAL;
5327         }
5328
5329         /* Mux the SPI interface away from the internal processor */
5330         bnx2x_cl45_write(bp, port,
5331                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5332                        ext_phy_addr,
5333                        MDIO_PCS_DEVAD,
5334                        MDIO_PCS_REG_7101_SPI_MUX, 1);
5335
5336         /* Reset the SPI port */
5337         bnx2x_cl45_write(bp, port,
5338                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5339                        ext_phy_addr,
5340                        MDIO_PCS_DEVAD,
5341                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5342         bnx2x_cl45_write(bp, port,
5343                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5344                        ext_phy_addr,
5345                        MDIO_PCS_DEVAD,
5346                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
5347                        (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
5348         bnx2x_cl45_write(bp, port,
5349                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5350                        ext_phy_addr,
5351                        MDIO_PCS_DEVAD,
5352                        MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
5353
5354         /* Erase the flash */
5355         bnx2x_cl45_write(bp, port,
5356                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5357                        ext_phy_addr,
5358                        MDIO_PCS_DEVAD,
5359                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5360                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5361
5362         bnx2x_cl45_write(bp, port,
5363                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5364                        ext_phy_addr,
5365                        MDIO_PCS_DEVAD,
5366                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5367                        1);
5368
5369         SPI_START_TRANSFER(bp, port, ext_phy_addr);
5370         bnx2x_cl45_write(bp, port,
5371                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5372                        ext_phy_addr,
5373                        MDIO_PCS_DEVAD,
5374                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5375                        MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
5376
5377         bnx2x_cl45_write(bp, port,
5378                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5379                        ext_phy_addr,
5380                        MDIO_PCS_DEVAD,
5381                        MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5382                        1);
5383         SPI_START_TRANSFER(bp, port, ext_phy_addr);
5384
5385         /* Wait 10 seconds, the maximum time for the erase to complete */
5386         DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
5387         for (cnt = 0; cnt < 1000; cnt++)
5388                 msleep(10);
5389
5390         DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
5391         data_index = 0;
5392         for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
5393                 bnx2x_cl45_write(bp, port,
5394                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5395                              ext_phy_addr,
5396                              MDIO_PCS_DEVAD,
5397                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5398                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5399
5400                 bnx2x_cl45_write(bp, port,
5401                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5402                                ext_phy_addr,
5403                                MDIO_PCS_DEVAD,
5404                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5405                                1);
5406                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5407
5408                 bnx2x_cl45_write(bp, port,
5409                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5410                                ext_phy_addr,
5411                                MDIO_PCS_DEVAD,
5412                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5413                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5414
5415                 /* Bits 23-16 of address */
5416                 bnx2x_cl45_write(bp, port,
5417                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5418                                ext_phy_addr,
5419                                MDIO_PCS_DEVAD,
5420                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5421                                (data_index>>16));
5422                 /* Bits 15-8 of address */
5423                 bnx2x_cl45_write(bp, port,
5424                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5425                                ext_phy_addr,
5426                                MDIO_PCS_DEVAD,
5427                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5428                                (data_index>>8));
5429
5430                 /* Bits 7-0 of address */
5431                 bnx2x_cl45_write(bp, port,
5432                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5433                                ext_phy_addr,
5434                                MDIO_PCS_DEVAD,
5435                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5436                                ((u16)data_index));
5437
5438                 byte_cnt = 0;
5439                 while (byte_cnt < 4 && data_index < size) {
5440                         bnx2x_cl45_write(bp, port,
5441                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5442                                        ext_phy_addr,
5443                                MDIO_PCS_DEVAD,
5444                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5445                                data[data_index++]);
5446                         byte_cnt++;
5447                 }
5448
5449                 bnx2x_cl45_write(bp, port,
5450                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5451                                ext_phy_addr,
5452                                MDIO_PCS_DEVAD,
5453                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5454                                byte_cnt+4);
5455
5456                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5457                 msleep(5); /* Wait 5 ms minimum between transs */
5458
5459                 /* Let the user know something's going on.*/
5460                 /* a pacifier ever 4K */
5461                 if ((data_index % 1023) == 0)
5462                         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5463         }
5464
5465         DP(NETIF_MSG_LINK, "\n");
5466         /* Transfer the last block if there is data remaining */
5467         if (last_trans_size) {
5468                 bnx2x_cl45_write(bp, port,
5469                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5470                         ext_phy_addr,
5471                         MDIO_PCS_DEVAD,
5472                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5473                         MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
5474
5475                 bnx2x_cl45_write(bp, port,
5476                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5477                                ext_phy_addr,
5478                                MDIO_PCS_DEVAD,
5479                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5480                                1);
5481
5482                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5483
5484                 bnx2x_cl45_write(bp, port,
5485                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5486                              ext_phy_addr,
5487                              MDIO_PCS_DEVAD,
5488                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5489                              MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
5490
5491                 /* Bits 23-16 of address */
5492                 bnx2x_cl45_write(bp, port,
5493                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5494                                ext_phy_addr,
5495                                MDIO_PCS_DEVAD,
5496                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5497                                (data_index>>16));
5498                 /* Bits 15-8 of address */
5499                 bnx2x_cl45_write(bp, port,
5500                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5501                                ext_phy_addr,
5502                                MDIO_PCS_DEVAD,
5503                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5504                                (data_index>>8));
5505
5506                 /* Bits 7-0 of address */
5507                 bnx2x_cl45_write(bp, port,
5508                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5509                                ext_phy_addr,
5510                                MDIO_PCS_DEVAD,
5511                                MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5512                                ((u16)data_index));
5513
5514                 byte_cnt = 0;
5515                 while (byte_cnt < last_trans_size && data_index < size) {
5516                         /* Bits 7-0 of address */
5517                         bnx2x_cl45_write(bp, port,
5518                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5519                                 ext_phy_addr,
5520                                 MDIO_PCS_DEVAD,
5521                                 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
5522                                 data[data_index++]);
5523                         byte_cnt++;
5524                 }
5525
5526                 bnx2x_cl45_write(bp, port,
5527                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5528                                ext_phy_addr,
5529                                MDIO_PCS_DEVAD,
5530                                MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
5531                                byte_cnt+4);
5532
5533                 SPI_START_TRANSFER(bp, port, ext_phy_addr);
5534         }
5535
5536         /* DSP Remove Download Mode */
5537         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5538                           MISC_REGISTERS_GPIO_LOW, port);
5539
5540         bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
5541
5542         /* wait 0.5 sec to allow it to run */
5543         for (cnt = 0; cnt < 100; cnt++)
5544                 msleep(5);
5545
5546         bnx2x_hw_reset(bp, port);
5547
5548         for (cnt = 0; cnt < 100; cnt++)
5549                 msleep(5);
5550
5551         /* Check that the code is started. In case the download
5552         checksum failed, the code won't be started. */
5553         bnx2x_cl45_read(bp, port,
5554                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5555                       ext_phy_addr,
5556                       MDIO_PCS_DEVAD,
5557                       MDIO_PCS_REG_7101_DSP_ACCESS,
5558                       &tmp);
5559
5560         code_started = (tmp & (1<<4));
5561         if (!code_started) {
5562                 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
5563                 return -EINVAL;
5564         }
5565
5566         /* Verify that the file revision is now equal to the image
5567         revision within the DSP */
5568         bnx2x_cl45_read(bp, port,
5569                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5570                       ext_phy_addr,
5571                       MDIO_PMA_DEVAD,
5572                       MDIO_PMA_REG_7101_VER1,
5573                       &image_revision1);
5574
5575         bnx2x_cl45_read(bp, port,
5576                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5577                       ext_phy_addr,
5578                       MDIO_PMA_DEVAD,
5579                       MDIO_PMA_REG_7101_VER2,
5580                       &image_revision2);
5581
5582         if (data[0x14e] != (image_revision2&0xFF) ||
5583             data[0x14f] != ((image_revision2&0xFF00)>>8) ||
5584             data[0x150] != (image_revision1&0xFF) ||
5585             data[0x151] != ((image_revision1&0xFF00)>>8)) {
5586                 DP(NETIF_MSG_LINK, "Download failed.\n");
5587                 return -EINVAL;
5588         }
5589         DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
5590         return 0;
5591 }
5592
5593 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
5594                       u8 driver_loaded, char data[], u32 size)
5595 {
5596         u8 rc = 0;
5597         u32 ext_phy_type;
5598         u8 ext_phy_addr;
5599         ext_phy_addr = ((ext_phy_config &
5600                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5601                         PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5602
5603         ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
5604
5605         switch (ext_phy_type) {
5606         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5607         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5608         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5609         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5610                 DP(NETIF_MSG_LINK,
5611                         "Flash download not supported for this ext phy\n");
5612                 rc = -EINVAL;
5613                 break;
5614         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5615                 /* Take ext phy out of reset */
5616                 if (!driver_loaded)
5617                         bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
5618                 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
5619                                                 data, size);
5620                 if (!driver_loaded)
5621                         bnx2x_turn_off_sf(bp, port);
5622                 break;
5623         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5624         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5625         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5626         default:
5627                 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
5628                 rc = -EINVAL;
5629                 break;
5630         }
5631         return rc;
5632 }
5633