bnx2x: Fix CL73 autoneg issues
[safe/jmp/linux-2.6] / 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.h"
26
27 /********************************************************/
28 #define ETH_HLEN                        14
29 #define ETH_OVREHEAD            (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
30 #define ETH_MIN_PACKET_SIZE             60
31 #define ETH_MAX_PACKET_SIZE             1500
32 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
33 #define MDIO_ACCESS_TIMEOUT             1000
34 #define BMAC_CONTROL_RX_ENABLE  2
35
36 /***********************************************************/
37 /*                      Shortcut definitions               */
38 /***********************************************************/
39
40 #define NIG_LATCH_BC_ENABLE_MI_INT 0
41
42 #define NIG_STATUS_EMAC0_MI_INT \
43                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
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
147 #define SFP_EEPROM_COMP_CODE_ADDR               0x3
148         #define SFP_EEPROM_COMP_CODE_SR_MASK    (1<<4)
149         #define SFP_EEPROM_COMP_CODE_LR_MASK    (1<<5)
150         #define SFP_EEPROM_COMP_CODE_LRM_MASK   (1<<6)
151
152 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
153         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
154         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE      0x8
155
156 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
157         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
158 #define SFP_EEPROM_OPTIONS_SIZE                 2
159
160 #define EDC_MODE_LINEAR                         0x0022
161 #define EDC_MODE_LIMITING                               0x0044
162 #define EDC_MODE_PASSIVE_DAC                    0x0055
163
164
165
166 /**********************************************************/
167 /*                     INTERFACE                          */
168 /**********************************************************/
169 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
170         bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
171                 DEFAULT_PHY_DEV_ADDR, \
172                 (_bank + (_addr & 0xf)), \
173                 _val)
174
175 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
176         bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
177                 DEFAULT_PHY_DEV_ADDR, \
178                 (_bank + (_addr & 0xf)), \
179                 _val)
180
181 static void bnx2x_set_serdes_access(struct link_params *params)
182 {
183         struct bnx2x *bp = params->bp;
184         u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
185
186         /* Set Clause 22 */
187         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1);
188         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
189         udelay(500);
190         REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
191         udelay(500);
192          /* Set Clause 45 */
193         REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0);
194 }
195 static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
196 {
197         struct bnx2x *bp = params->bp;
198
199         if (phy_flags & PHY_XGXS_FLAG) {
200                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
201                            params->port*0x18, 0);
202                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
203                            DEFAULT_PHY_DEV_ADDR);
204         } else {
205                 bnx2x_set_serdes_access(params);
206
207                 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
208                            params->port*0x10,
209                            DEFAULT_PHY_DEV_ADDR);
210         }
211 }
212
213 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
214 {
215         u32 val = REG_RD(bp, reg);
216
217         val |= bits;
218         REG_WR(bp, reg, val);
219         return val;
220 }
221
222 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
223 {
224         u32 val = REG_RD(bp, reg);
225
226         val &= ~bits;
227         REG_WR(bp, reg, val);
228         return val;
229 }
230
231 static void bnx2x_emac_init(struct link_params *params,
232                            struct link_vars *vars)
233 {
234         /* reset and unreset the emac core */
235         struct bnx2x *bp = params->bp;
236         u8 port = params->port;
237         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
238         u32 val;
239         u16 timeout;
240
241         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
242                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
243         udelay(5);
244         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
245                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
246
247         /* init emac - use read-modify-write */
248         /* self clear reset */
249         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
250         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
251
252         timeout = 200;
253         do {
254                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
255                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
256                 if (!timeout) {
257                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
258                         return;
259                 }
260                 timeout--;
261         } while (val & EMAC_MODE_RESET);
262
263         /* Set mac address */
264         val = ((params->mac_addr[0] << 8) |
265                 params->mac_addr[1]);
266         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
267
268         val = ((params->mac_addr[2] << 24) |
269                (params->mac_addr[3] << 16) |
270                (params->mac_addr[4] << 8) |
271                 params->mac_addr[5]);
272         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
273 }
274
275 static u8 bnx2x_emac_enable(struct link_params *params,
276                           struct link_vars *vars, u8 lb)
277 {
278         struct bnx2x *bp = params->bp;
279         u8 port = params->port;
280         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
281         u32 val;
282
283         DP(NETIF_MSG_LINK, "enabling EMAC\n");
284
285         /* enable emac and not bmac */
286         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
287
288         /* for paladium */
289         if (CHIP_REV_IS_EMUL(bp)) {
290                 /* Use lane 1 (of lanes 0-3) */
291                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
292                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
293                             port*4, 1);
294         }
295         /* for fpga */
296         else
297
298         if (CHIP_REV_IS_FPGA(bp)) {
299                 /* Use lane 1 (of lanes 0-3) */
300                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
301
302                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
303                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
304                             0);
305         } else
306         /* ASIC */
307         if (vars->phy_flags & PHY_XGXS_FLAG) {
308                 u32 ser_lane = ((params->lane_config &
309                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
310                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
311
312                 DP(NETIF_MSG_LINK, "XGXS\n");
313                 /* select the master lanes (out of 0-3) */
314                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
315                            port*4, ser_lane);
316                 /* select XGXS */
317                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
318                            port*4, 1);
319
320         } else { /* SerDes */
321                 DP(NETIF_MSG_LINK, "SerDes\n");
322                 /* select SerDes */
323                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
324                            port*4, 0);
325         }
326
327         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
328                     EMAC_RX_MODE_RESET);
329         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
330                     EMAC_TX_MODE_RESET);
331
332         if (CHIP_REV_IS_SLOW(bp)) {
333                 /* config GMII mode */
334                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
335                 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
336                             (val | EMAC_MODE_PORT_GMII));
337         } else { /* ASIC */
338                 /* pause enable/disable */
339                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
340                                EMAC_RX_MODE_FLOW_EN);
341                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
342                         bnx2x_bits_en(bp, emac_base +
343                                     EMAC_REG_EMAC_RX_MODE,
344                                     EMAC_RX_MODE_FLOW_EN);
345
346                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
347                              (EMAC_TX_MODE_EXT_PAUSE_EN |
348                               EMAC_TX_MODE_FLOW_EN));
349                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
350                         bnx2x_bits_en(bp, emac_base +
351                                     EMAC_REG_EMAC_TX_MODE,
352                                    (EMAC_TX_MODE_EXT_PAUSE_EN |
353                                     EMAC_TX_MODE_FLOW_EN));
354         }
355
356         /* KEEP_VLAN_TAG, promiscuous */
357         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
358         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
359         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
360
361         /* Set Loopback */
362         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
363         if (lb)
364                 val |= 0x810;
365         else
366                 val &= ~0x810;
367         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
368
369         /* enable emac */
370         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
371
372         /* enable emac for jumbo packets */
373         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
374                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
375                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
376
377         /* strip CRC */
378         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
379
380         /* disable the NIG in/out to the bmac */
381         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
382         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
383         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
384
385         /* enable the NIG in/out to the emac */
386         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
387         val = 0;
388         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
389                 val = 1;
390
391         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
392         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
393
394         if (CHIP_REV_IS_EMUL(bp)) {
395                 /* take the BigMac out of reset */
396                 REG_WR(bp,
397                            GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
398                            (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
399
400                 /* enable access for bmac registers */
401                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
402         } else
403                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
404
405         vars->mac_type = MAC_TYPE_EMAC;
406         return 0;
407 }
408
409
410
411 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
412                           u8 is_lb)
413 {
414         struct bnx2x *bp = params->bp;
415         u8 port = params->port;
416         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
417                                NIG_REG_INGRESS_BMAC0_MEM;
418         u32 wb_data[2];
419         u32 val;
420
421         DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
422         /* reset and unreset the BigMac */
423         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
424                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
425         msleep(1);
426
427         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
428                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
429
430         /* enable access for bmac registers */
431         REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
432
433         /* XGXS control */
434         wb_data[0] = 0x3c;
435         wb_data[1] = 0;
436         REG_WR_DMAE(bp, bmac_addr +
437                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
438                       wb_data, 2);
439
440         /* tx MAC SA */
441         wb_data[0] = ((params->mac_addr[2] << 24) |
442                        (params->mac_addr[3] << 16) |
443                        (params->mac_addr[4] << 8) |
444                         params->mac_addr[5]);
445         wb_data[1] = ((params->mac_addr[0] << 8) |
446                         params->mac_addr[1]);
447         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
448                     wb_data, 2);
449
450         /* tx control */
451         val = 0xc0;
452         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
453                 val |= 0x800000;
454         wb_data[0] = val;
455         wb_data[1] = 0;
456         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
457                         wb_data, 2);
458
459         /* mac control */
460         val = 0x3;
461         if (is_lb) {
462                 val |= 0x4;
463                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
464         }
465         wb_data[0] = val;
466         wb_data[1] = 0;
467         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
468                     wb_data, 2);
469
470         /* set rx mtu */
471         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
472         wb_data[1] = 0;
473         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
474                         wb_data, 2);
475
476         /* rx control set to don't strip crc */
477         val = 0x14;
478         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
479                 val |= 0x20;
480         wb_data[0] = val;
481         wb_data[1] = 0;
482         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
483                         wb_data, 2);
484
485         /* set tx mtu */
486         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
487         wb_data[1] = 0;
488         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
489                         wb_data, 2);
490
491         /* set cnt max size */
492         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
493         wb_data[1] = 0;
494         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
495                     wb_data, 2);
496
497         /* configure safc */
498         wb_data[0] = 0x1000200;
499         wb_data[1] = 0;
500         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
501                     wb_data, 2);
502         /* fix for emulation */
503         if (CHIP_REV_IS_EMUL(bp)) {
504                 wb_data[0] = 0xf000;
505                 wb_data[1] = 0;
506                 REG_WR_DMAE(bp,
507                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
508                             wb_data, 2);
509         }
510
511         REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
512         REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
513         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
514         val = 0;
515         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
516                 val = 1;
517         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
518         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
519         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
520         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
521         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
522         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
523
524         vars->mac_type = MAC_TYPE_BMAC;
525         return 0;
526 }
527
528 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
529 {
530         struct bnx2x *bp = params->bp;
531         u32 val;
532
533         if (phy_flags & PHY_XGXS_FLAG) {
534                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
535                 val = XGXS_RESET_BITS;
536
537         } else { /* SerDes */
538                 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
539                 val = SERDES_RESET_BITS;
540         }
541
542         val = val << (params->port*16);
543
544         /* reset and unreset the SerDes/XGXS */
545         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
546                     val);
547         udelay(500);
548         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
549                     val);
550         bnx2x_set_phy_mdio(params, phy_flags);
551 }
552
553 void bnx2x_link_status_update(struct link_params *params,
554                             struct link_vars   *vars)
555 {
556         struct bnx2x *bp = params->bp;
557         u8 link_10g;
558         u8 port = params->port;
559
560         if (params->switch_cfg ==  SWITCH_CFG_1G)
561                 vars->phy_flags = PHY_SERDES_FLAG;
562         else
563                 vars->phy_flags = PHY_XGXS_FLAG;
564         vars->link_status = REG_RD(bp, params->shmem_base +
565                                           offsetof(struct shmem_region,
566                                            port_mb[port].link_status));
567
568         vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
569
570         if (vars->link_up) {
571                 DP(NETIF_MSG_LINK, "phy link up\n");
572
573                 vars->phy_link_up = 1;
574                 vars->duplex = DUPLEX_FULL;
575                 switch (vars->link_status &
576                                         LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
577                         case LINK_10THD:
578                                 vars->duplex = DUPLEX_HALF;
579                                 /* fall thru */
580                         case LINK_10TFD:
581                                 vars->line_speed = SPEED_10;
582                                 break;
583
584                         case LINK_100TXHD:
585                                 vars->duplex = DUPLEX_HALF;
586                                 /* fall thru */
587                         case LINK_100T4:
588                         case LINK_100TXFD:
589                                 vars->line_speed = SPEED_100;
590                                 break;
591
592                         case LINK_1000THD:
593                                 vars->duplex = DUPLEX_HALF;
594                                 /* fall thru */
595                         case LINK_1000TFD:
596                                 vars->line_speed = SPEED_1000;
597                                 break;
598
599                         case LINK_2500THD:
600                                 vars->duplex = DUPLEX_HALF;
601                                 /* fall thru */
602                         case LINK_2500TFD:
603                                 vars->line_speed = SPEED_2500;
604                                 break;
605
606                         case LINK_10GTFD:
607                                 vars->line_speed = SPEED_10000;
608                                 break;
609
610                         case LINK_12GTFD:
611                                 vars->line_speed = SPEED_12000;
612                                 break;
613
614                         case LINK_12_5GTFD:
615                                 vars->line_speed = SPEED_12500;
616                                 break;
617
618                         case LINK_13GTFD:
619                                 vars->line_speed = SPEED_13000;
620                                 break;
621
622                         case LINK_15GTFD:
623                                 vars->line_speed = SPEED_15000;
624                                 break;
625
626                         case LINK_16GTFD:
627                                 vars->line_speed = SPEED_16000;
628                                 break;
629
630                         default:
631                                 break;
632                 }
633
634                 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
635                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
636                 else
637                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
638
639                 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
640                         vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
641                 else
642                         vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
643
644                 if (vars->phy_flags & PHY_XGXS_FLAG) {
645                         if (vars->line_speed &&
646                             ((vars->line_speed == SPEED_10) ||
647                              (vars->line_speed == SPEED_100))) {
648                                 vars->phy_flags |= PHY_SGMII_FLAG;
649                         } else {
650                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
651                         }
652                 }
653
654                 /* anything 10 and over uses the bmac */
655                 link_10g = ((vars->line_speed == SPEED_10000) ||
656                             (vars->line_speed == SPEED_12000) ||
657                             (vars->line_speed == SPEED_12500) ||
658                             (vars->line_speed == SPEED_13000) ||
659                             (vars->line_speed == SPEED_15000) ||
660                             (vars->line_speed == SPEED_16000));
661                 if (link_10g)
662                         vars->mac_type = MAC_TYPE_BMAC;
663                 else
664                         vars->mac_type = MAC_TYPE_EMAC;
665
666         } else { /* link down */
667                 DP(NETIF_MSG_LINK, "phy link down\n");
668
669                 vars->phy_link_up = 0;
670
671                 vars->line_speed = 0;
672                 vars->duplex = DUPLEX_FULL;
673                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
674
675                 /* indicate no mac active */
676                 vars->mac_type = MAC_TYPE_NONE;
677         }
678
679         DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
680                  vars->link_status, vars->phy_link_up);
681         DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
682                  vars->line_speed, vars->duplex, vars->flow_ctrl);
683 }
684
685 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
686 {
687         struct bnx2x *bp = params->bp;
688
689         REG_WR(bp, params->shmem_base +
690                    offsetof(struct shmem_region,
691                             port_mb[params->port].link_status),
692                         link_status);
693 }
694
695 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
696 {
697         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
698                 NIG_REG_INGRESS_BMAC0_MEM;
699         u32 wb_data[2];
700         u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
701
702         /* Only if the bmac is out of reset */
703         if (REG_RD(bp, MISC_REG_RESET_REG_2) &
704                         (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
705             nig_bmac_enable) {
706
707                 /* Clear Rx Enable bit in BMAC_CONTROL register */
708                 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
709                             wb_data, 2);
710                 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
711                 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
712                             wb_data, 2);
713
714                 msleep(1);
715         }
716 }
717
718 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
719                          u32 line_speed)
720 {
721         struct bnx2x *bp = params->bp;
722         u8 port = params->port;
723         u32 init_crd, crd;
724         u32 count = 1000;
725
726         /* disable port */
727         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
728
729         /* wait for init credit */
730         init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
731         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
732         DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
733
734         while ((init_crd != crd) && count) {
735                 msleep(5);
736
737                 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
738                 count--;
739         }
740         crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
741         if (init_crd != crd) {
742                 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
743                           init_crd, crd);
744                 return -EINVAL;
745         }
746
747         if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
748             line_speed == SPEED_10 ||
749             line_speed == SPEED_100 ||
750             line_speed == SPEED_1000 ||
751             line_speed == SPEED_2500) {
752                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
753                 /* update threshold */
754                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
755                 /* update init credit */
756                 init_crd = 778;         /* (800-18-4) */
757
758         } else {
759                 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
760                               ETH_OVREHEAD)/16;
761                 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
762                 /* update threshold */
763                 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
764                 /* update init credit */
765                 switch (line_speed) {
766                 case SPEED_10000:
767                         init_crd = thresh + 553 - 22;
768                         break;
769
770                 case SPEED_12000:
771                         init_crd = thresh + 664 - 22;
772                         break;
773
774                 case SPEED_13000:
775                         init_crd = thresh + 742 - 22;
776                         break;
777
778                 case SPEED_16000:
779                         init_crd = thresh + 778 - 22;
780                         break;
781                 default:
782                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
783                                   line_speed);
784                         return -EINVAL;
785                 }
786         }
787         REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
788         DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
789                  line_speed, init_crd);
790
791         /* probe the credit changes */
792         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
793         msleep(5);
794         REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
795
796         /* enable port */
797         REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
798         return 0;
799 }
800
801 static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
802 {
803         u32 emac_base;
804
805         switch (ext_phy_type) {
806         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
807         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
808         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
809                 /* All MDC/MDIO is directed through single EMAC */
810                 if (REG_RD(bp, NIG_REG_PORT_SWAP))
811                         emac_base = GRCBASE_EMAC0;
812                 else
813                         emac_base = GRCBASE_EMAC1;
814                 break;
815         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
816                 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
817                 break;
818         default:
819                 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
820                 break;
821         }
822         return emac_base;
823
824 }
825
826 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
827                   u8 phy_addr, u8 devad, u16 reg, u16 val)
828 {
829         u32 tmp, saved_mode;
830         u8 i, rc = 0;
831         u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
832
833         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
834          * (a value of 49==0x31) and make sure that the AUTO poll is off
835          */
836
837         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
838         tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
839                              EMAC_MDIO_MODE_CLOCK_CNT);
840         tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
841                 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
842         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
843         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
844         udelay(40);
845
846         /* address */
847
848         tmp = ((phy_addr << 21) | (devad << 16) | reg |
849                EMAC_MDIO_COMM_COMMAND_ADDRESS |
850                EMAC_MDIO_COMM_START_BUSY);
851         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
852
853         for (i = 0; i < 50; i++) {
854                 udelay(10);
855
856                 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
857                 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
858                         udelay(5);
859                         break;
860                 }
861         }
862         if (tmp & EMAC_MDIO_COMM_START_BUSY) {
863                 DP(NETIF_MSG_LINK, "write phy register failed\n");
864                 rc = -EFAULT;
865         } else {
866                 /* data */
867                 tmp = ((phy_addr << 21) | (devad << 16) | val |
868                        EMAC_MDIO_COMM_COMMAND_WRITE_45 |
869                        EMAC_MDIO_COMM_START_BUSY);
870                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
871
872                 for (i = 0; i < 50; i++) {
873                         udelay(10);
874
875                         tmp = REG_RD(bp, mdio_ctrl +
876                                          EMAC_REG_EMAC_MDIO_COMM);
877                         if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
878                                 udelay(5);
879                                 break;
880                         }
881                 }
882                 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
883                         DP(NETIF_MSG_LINK, "write phy register failed\n");
884                         rc = -EFAULT;
885                 }
886         }
887
888         /* Restore the saved mode */
889         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
890
891         return rc;
892 }
893
894 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
895                  u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
896 {
897         u32 val, saved_mode;
898         u16 i;
899         u8 rc = 0;
900
901         u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
902         /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
903          * (a value of 49==0x31) and make sure that the AUTO poll is off
904          */
905
906         saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
907         val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
908                              EMAC_MDIO_MODE_CLOCK_CNT));
909         val |= (EMAC_MDIO_MODE_CLAUSE_45 |
910                 (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
911         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
912         REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
913         udelay(40);
914
915         /* address */
916         val = ((phy_addr << 21) | (devad << 16) | reg |
917                EMAC_MDIO_COMM_COMMAND_ADDRESS |
918                EMAC_MDIO_COMM_START_BUSY);
919         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
920
921         for (i = 0; i < 50; i++) {
922                 udelay(10);
923
924                 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
925                 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
926                         udelay(5);
927                         break;
928                 }
929         }
930         if (val & EMAC_MDIO_COMM_START_BUSY) {
931                 DP(NETIF_MSG_LINK, "read phy register failed\n");
932
933                 *ret_val = 0;
934                 rc = -EFAULT;
935
936         } else {
937                 /* data */
938                 val = ((phy_addr << 21) | (devad << 16) |
939                        EMAC_MDIO_COMM_COMMAND_READ_45 |
940                        EMAC_MDIO_COMM_START_BUSY);
941                 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
942
943                 for (i = 0; i < 50; i++) {
944                         udelay(10);
945
946                         val = REG_RD(bp, mdio_ctrl +
947                                           EMAC_REG_EMAC_MDIO_COMM);
948                         if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
949                                 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
950                                 break;
951                         }
952                 }
953                 if (val & EMAC_MDIO_COMM_START_BUSY) {
954                         DP(NETIF_MSG_LINK, "read phy register failed\n");
955
956                         *ret_val = 0;
957                         rc = -EFAULT;
958                 }
959         }
960
961         /* Restore the saved mode */
962         REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
963
964         return rc;
965 }
966
967 static void bnx2x_set_aer_mmd(struct link_params *params,
968                             struct link_vars   *vars)
969 {
970         struct bnx2x *bp = params->bp;
971         u32 ser_lane;
972         u16 offset;
973
974         ser_lane = ((params->lane_config &
975                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
976                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
977
978         offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
979                 (params->phy_addr + ser_lane) : 0;
980
981         CL45_WR_OVER_CL22(bp, params->port,
982                               params->phy_addr,
983                               MDIO_REG_BANK_AER_BLOCK,
984                               MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
985 }
986
987 static void bnx2x_set_master_ln(struct link_params *params)
988 {
989         struct bnx2x *bp = params->bp;
990         u16 new_master_ln, ser_lane;
991         ser_lane =  ((params->lane_config &
992                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
993                      PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
994
995         /* set the master_ln for AN */
996         CL45_RD_OVER_CL22(bp, params->port,
997                               params->phy_addr,
998                               MDIO_REG_BANK_XGXS_BLOCK2,
999                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1000                               &new_master_ln);
1001
1002         CL45_WR_OVER_CL22(bp, params->port,
1003                               params->phy_addr,
1004                               MDIO_REG_BANK_XGXS_BLOCK2 ,
1005                               MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1006                               (new_master_ln | ser_lane));
1007 }
1008
1009 static u8 bnx2x_reset_unicore(struct link_params *params)
1010 {
1011         struct bnx2x *bp = params->bp;
1012         u16 mii_control;
1013         u16 i;
1014
1015         CL45_RD_OVER_CL22(bp, params->port,
1016                               params->phy_addr,
1017                               MDIO_REG_BANK_COMBO_IEEE0,
1018                               MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1019
1020         /* reset the unicore */
1021         CL45_WR_OVER_CL22(bp, params->port,
1022                               params->phy_addr,
1023                               MDIO_REG_BANK_COMBO_IEEE0,
1024                               MDIO_COMBO_IEEE0_MII_CONTROL,
1025                               (mii_control |
1026                                MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1027         if (params->switch_cfg == SWITCH_CFG_1G)
1028                 bnx2x_set_serdes_access(params);
1029
1030         /* wait for the reset to self clear */
1031         for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1032                 udelay(5);
1033
1034                 /* the reset erased the previous bank value */
1035                 CL45_RD_OVER_CL22(bp, params->port,
1036                                       params->phy_addr,
1037                               MDIO_REG_BANK_COMBO_IEEE0,
1038                               MDIO_COMBO_IEEE0_MII_CONTROL,
1039                               &mii_control);
1040
1041                 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1042                         udelay(5);
1043                         return 0;
1044                 }
1045         }
1046
1047         DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1048         return -EINVAL;
1049
1050 }
1051
1052 static void bnx2x_set_swap_lanes(struct link_params *params)
1053 {
1054         struct bnx2x *bp = params->bp;
1055         /* Each two bits represents a lane number:
1056            No swap is 0123 => 0x1b no need to enable the swap */
1057         u16 ser_lane, rx_lane_swap, tx_lane_swap;
1058
1059         ser_lane = ((params->lane_config &
1060                          PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1061                         PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1062         rx_lane_swap = ((params->lane_config &
1063                              PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1064                             PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1065         tx_lane_swap = ((params->lane_config &
1066                              PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1067                             PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1068
1069         if (rx_lane_swap != 0x1b) {
1070                 CL45_WR_OVER_CL22(bp, params->port,
1071                                       params->phy_addr,
1072                                     MDIO_REG_BANK_XGXS_BLOCK2,
1073                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1074                                     (rx_lane_swap |
1075                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1076                                     MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1077         } else {
1078                 CL45_WR_OVER_CL22(bp, params->port,
1079                                       params->phy_addr,
1080                                       MDIO_REG_BANK_XGXS_BLOCK2,
1081                                       MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1082         }
1083
1084         if (tx_lane_swap != 0x1b) {
1085                 CL45_WR_OVER_CL22(bp, params->port,
1086                                       params->phy_addr,
1087                                       MDIO_REG_BANK_XGXS_BLOCK2,
1088                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1089                                       (tx_lane_swap |
1090                                        MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1091         } else {
1092                 CL45_WR_OVER_CL22(bp, params->port,
1093                                       params->phy_addr,
1094                                       MDIO_REG_BANK_XGXS_BLOCK2,
1095                                       MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1096         }
1097 }
1098
1099 static void bnx2x_set_parallel_detection(struct link_params *params,
1100                                        u8                phy_flags)
1101 {
1102         struct bnx2x *bp = params->bp;
1103         u16 control2;
1104
1105         CL45_RD_OVER_CL22(bp, params->port,
1106                               params->phy_addr,
1107                               MDIO_REG_BANK_SERDES_DIGITAL,
1108                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1109                               &control2);
1110         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1111                 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1112         else
1113                 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1114         DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n",
1115                 params->speed_cap_mask, control2);
1116         CL45_WR_OVER_CL22(bp, params->port,
1117                               params->phy_addr,
1118                               MDIO_REG_BANK_SERDES_DIGITAL,
1119                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1120                               control2);
1121
1122         if ((phy_flags & PHY_XGXS_FLAG) &&
1123              (params->speed_cap_mask &
1124                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
1125                 DP(NETIF_MSG_LINK, "XGXS\n");
1126
1127                 CL45_WR_OVER_CL22(bp, params->port,
1128                                       params->phy_addr,
1129                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1130                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1131                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1132
1133                 CL45_RD_OVER_CL22(bp, params->port,
1134                                       params->phy_addr,
1135                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1136                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1137                                 &control2);
1138
1139
1140                 control2 |=
1141                     MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1142
1143                 CL45_WR_OVER_CL22(bp, params->port,
1144                                       params->phy_addr,
1145                                 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1146                                 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1147                                 control2);
1148
1149                 /* Disable parallel detection of HiG */
1150                 CL45_WR_OVER_CL22(bp, params->port,
1151                                       params->phy_addr,
1152                                 MDIO_REG_BANK_XGXS_BLOCK2,
1153                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1154                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1155                                 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1156         }
1157 }
1158
1159 static void bnx2x_set_autoneg(struct link_params *params,
1160                             struct link_vars *vars,
1161                             u8 enable_cl73)
1162 {
1163         struct bnx2x *bp = params->bp;
1164         u16 reg_val;
1165
1166         /* CL37 Autoneg */
1167
1168         CL45_RD_OVER_CL22(bp, params->port,
1169                               params->phy_addr,
1170                               MDIO_REG_BANK_COMBO_IEEE0,
1171                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1172
1173         /* CL37 Autoneg Enabled */
1174         if (vars->line_speed == SPEED_AUTO_NEG)
1175                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1176         else /* CL37 Autoneg Disabled */
1177                 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1178                              MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1179
1180         CL45_WR_OVER_CL22(bp, params->port,
1181                               params->phy_addr,
1182                               MDIO_REG_BANK_COMBO_IEEE0,
1183                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1184
1185         /* Enable/Disable Autodetection */
1186
1187         CL45_RD_OVER_CL22(bp, params->port,
1188                               params->phy_addr,
1189                               MDIO_REG_BANK_SERDES_DIGITAL,
1190                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1191         reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
1192                     MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
1193         reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
1194         if (vars->line_speed == SPEED_AUTO_NEG)
1195                 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1196         else
1197                 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1198
1199         CL45_WR_OVER_CL22(bp, params->port,
1200                               params->phy_addr,
1201                               MDIO_REG_BANK_SERDES_DIGITAL,
1202                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1203
1204         /* Enable TetonII and BAM autoneg */
1205         CL45_RD_OVER_CL22(bp, params->port,
1206                               params->phy_addr,
1207                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1208                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1209                           &reg_val);
1210         if (vars->line_speed == SPEED_AUTO_NEG) {
1211                 /* Enable BAM aneg Mode and TetonII aneg Mode */
1212                 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1213                             MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1214         } else {
1215                 /* TetonII and BAM Autoneg Disabled */
1216                 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1217                              MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1218         }
1219         CL45_WR_OVER_CL22(bp, params->port,
1220                               params->phy_addr,
1221                               MDIO_REG_BANK_BAM_NEXT_PAGE,
1222                               MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1223                               reg_val);
1224
1225         if (enable_cl73) {
1226                 /* Enable Cl73 FSM status bits */
1227                 CL45_WR_OVER_CL22(bp, params->port,
1228                                       params->phy_addr,
1229                                       MDIO_REG_BANK_CL73_USERB0,
1230                                     MDIO_CL73_USERB0_CL73_UCTRL,
1231                                       0xe);
1232
1233                 /* Enable BAM Station Manager*/
1234                 CL45_WR_OVER_CL22(bp, params->port,
1235                         params->phy_addr,
1236                         MDIO_REG_BANK_CL73_USERB0,
1237                         MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1238                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1239                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1240                         MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
1241
1242                 /* Advertise CL73 link speeds */
1243                         CL45_RD_OVER_CL22(bp, params->port,
1244                                               params->phy_addr,
1245                                               MDIO_REG_BANK_CL73_IEEEB1,
1246                                               MDIO_CL73_IEEEB1_AN_ADV2,
1247                                               &reg_val);
1248                 if (params->speed_cap_mask &
1249                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1250                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1251                 if (params->speed_cap_mask &
1252                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1253                         reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1254
1255                         CL45_WR_OVER_CL22(bp, params->port,
1256                                               params->phy_addr,
1257                                               MDIO_REG_BANK_CL73_IEEEB1,
1258                                               MDIO_CL73_IEEEB1_AN_ADV2,
1259                                       reg_val);
1260
1261                 /* CL73 Autoneg Enabled */
1262                 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1263
1264         } else /* CL73 Autoneg Disabled */
1265                 reg_val = 0;
1266
1267         CL45_WR_OVER_CL22(bp, params->port,
1268                               params->phy_addr,
1269                               MDIO_REG_BANK_CL73_IEEEB0,
1270                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1271 }
1272
1273 /* program SerDes, forced speed */
1274 static void bnx2x_program_serdes(struct link_params *params,
1275                                struct link_vars *vars)
1276 {
1277         struct bnx2x *bp = params->bp;
1278         u16 reg_val;
1279
1280         /* program duplex, disable autoneg and sgmii*/
1281         CL45_RD_OVER_CL22(bp, params->port,
1282                               params->phy_addr,
1283                               MDIO_REG_BANK_COMBO_IEEE0,
1284                               MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1285         reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1286                      MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1287                      MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
1288         if (params->req_duplex == DUPLEX_FULL)
1289                 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1290         CL45_WR_OVER_CL22(bp, params->port,
1291                               params->phy_addr,
1292                               MDIO_REG_BANK_COMBO_IEEE0,
1293                               MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1294
1295         /* program speed
1296            - needed only if the speed is greater than 1G (2.5G or 10G) */
1297         CL45_RD_OVER_CL22(bp, params->port,
1298                                       params->phy_addr,
1299                                       MDIO_REG_BANK_SERDES_DIGITAL,
1300                                       MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1301         /* clearing the speed value before setting the right speed */
1302         DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1303
1304         reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1305                      MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1306
1307         if (!((vars->line_speed == SPEED_1000) ||
1308               (vars->line_speed == SPEED_100) ||
1309               (vars->line_speed == SPEED_10))) {
1310
1311                 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1312                             MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1313                 if (vars->line_speed == SPEED_10000)
1314                         reg_val |=
1315                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1316                 if (vars->line_speed == SPEED_13000)
1317                         reg_val |=
1318                                 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1319         }
1320
1321         CL45_WR_OVER_CL22(bp, params->port,
1322                                       params->phy_addr,
1323                                       MDIO_REG_BANK_SERDES_DIGITAL,
1324                                       MDIO_SERDES_DIGITAL_MISC1, reg_val);
1325
1326 }
1327
1328 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1329 {
1330         struct bnx2x *bp = params->bp;
1331         u16 val = 0;
1332
1333         /* configure the 48 bits for BAM AN */
1334
1335         /* set extended capabilities */
1336         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1337                 val |= MDIO_OVER_1G_UP1_2_5G;
1338         if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1339                 val |= MDIO_OVER_1G_UP1_10G;
1340         CL45_WR_OVER_CL22(bp, params->port,
1341                               params->phy_addr,
1342                               MDIO_REG_BANK_OVER_1G,
1343                               MDIO_OVER_1G_UP1, val);
1344
1345         CL45_WR_OVER_CL22(bp, params->port,
1346                               params->phy_addr,
1347                               MDIO_REG_BANK_OVER_1G,
1348                               MDIO_OVER_1G_UP3, 0x400);
1349 }
1350
1351 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
1352 {
1353         *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1354         /* resolve pause mode and advertisement
1355          * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1356
1357         switch (params->req_flow_ctrl) {
1358         case BNX2X_FLOW_CTRL_AUTO:
1359                 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1360                         *ieee_fc |=
1361                              MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1362                 } else {
1363                         *ieee_fc |=
1364                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1365                 }
1366                 break;
1367         case BNX2X_FLOW_CTRL_TX:
1368                 *ieee_fc |=
1369                        MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1370                 break;
1371
1372         case BNX2X_FLOW_CTRL_RX:
1373         case BNX2X_FLOW_CTRL_BOTH:
1374                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1375                 break;
1376
1377         case BNX2X_FLOW_CTRL_NONE:
1378         default:
1379                 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1380                 break;
1381         }
1382 }
1383
1384 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1385                                            u16 ieee_fc)
1386 {
1387         struct bnx2x *bp = params->bp;
1388         u16 val;
1389         /* for AN, we are always publishing full duplex */
1390
1391         CL45_WR_OVER_CL22(bp, params->port,
1392                               params->phy_addr,
1393                               MDIO_REG_BANK_COMBO_IEEE0,
1394                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
1395         CL45_RD_OVER_CL22(bp, params->port,
1396                               params->phy_addr,
1397                               MDIO_REG_BANK_CL73_IEEEB1,
1398                               MDIO_CL73_IEEEB1_AN_ADV1, &val);
1399         val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
1400         val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
1401         CL45_WR_OVER_CL22(bp, params->port,
1402                               params->phy_addr,
1403                               MDIO_REG_BANK_CL73_IEEEB1,
1404                               MDIO_CL73_IEEEB1_AN_ADV1, val);
1405 }
1406
1407 static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
1408 {
1409         struct bnx2x *bp = params->bp;
1410         u16 mii_control;
1411
1412         DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1413         /* Enable and restart BAM/CL37 aneg */
1414
1415         if (enable_cl73) {
1416                 CL45_RD_OVER_CL22(bp, params->port,
1417                                       params->phy_addr,
1418                                       MDIO_REG_BANK_CL73_IEEEB0,
1419                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1420                                       &mii_control);
1421
1422                 CL45_WR_OVER_CL22(bp, params->port,
1423                                 params->phy_addr,
1424                                 MDIO_REG_BANK_CL73_IEEEB0,
1425                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1426                                 (mii_control |
1427                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1428                                 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1429         } else {
1430
1431                 CL45_RD_OVER_CL22(bp, params->port,
1432                                       params->phy_addr,
1433                                       MDIO_REG_BANK_COMBO_IEEE0,
1434                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1435                                       &mii_control);
1436                 DP(NETIF_MSG_LINK,
1437                          "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1438                          mii_control);
1439                 CL45_WR_OVER_CL22(bp, params->port,
1440                                       params->phy_addr,
1441                                       MDIO_REG_BANK_COMBO_IEEE0,
1442                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1443                                       (mii_control |
1444                                        MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1445                                        MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1446         }
1447 }
1448
1449 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1450                                          struct link_vars *vars)
1451 {
1452         struct bnx2x *bp = params->bp;
1453         u16 control1;
1454
1455         /* in SGMII mode, the unicore is always slave */
1456
1457         CL45_RD_OVER_CL22(bp, params->port,
1458                               params->phy_addr,
1459                               MDIO_REG_BANK_SERDES_DIGITAL,
1460                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1461                       &control1);
1462         control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1463         /* set sgmii mode (and not fiber) */
1464         control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1465                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1466                       MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1467         CL45_WR_OVER_CL22(bp, params->port,
1468                               params->phy_addr,
1469                               MDIO_REG_BANK_SERDES_DIGITAL,
1470                               MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1471                               control1);
1472
1473         /* if forced speed */
1474         if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1475                 /* set speed, disable autoneg */
1476                 u16 mii_control;
1477
1478                 CL45_RD_OVER_CL22(bp, params->port,
1479                                       params->phy_addr,
1480                                       MDIO_REG_BANK_COMBO_IEEE0,
1481                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1482                                       &mii_control);
1483                 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1484                                  MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1485                                  MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1486
1487                 switch (vars->line_speed) {
1488                 case SPEED_100:
1489                         mii_control |=
1490                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1491                         break;
1492                 case SPEED_1000:
1493                         mii_control |=
1494                                 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1495                         break;
1496                 case SPEED_10:
1497                         /* there is nothing to set for 10M */
1498                         break;
1499                 default:
1500                         /* invalid speed for SGMII */
1501                         DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1502                                   vars->line_speed);
1503                         break;
1504                 }
1505
1506                 /* setting the full duplex */
1507                 if (params->req_duplex == DUPLEX_FULL)
1508                         mii_control |=
1509                                 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1510                 CL45_WR_OVER_CL22(bp, params->port,
1511                                       params->phy_addr,
1512                                       MDIO_REG_BANK_COMBO_IEEE0,
1513                                       MDIO_COMBO_IEEE0_MII_CONTROL,
1514                                       mii_control);
1515
1516         } else { /* AN mode */
1517                 /* enable and restart AN */
1518                 bnx2x_restart_autoneg(params, 0);
1519         }
1520 }
1521
1522
1523 /*
1524  * link management
1525  */
1526
1527 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1528 {                                               /*  LD      LP   */
1529         switch (pause_result) {                 /* ASYM P ASYM P */
1530         case 0xb:                               /*   1  0   1  1 */
1531                 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1532                 break;
1533
1534         case 0xe:                               /*   1  1   1  0 */
1535                 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1536                 break;
1537
1538         case 0x5:                               /*   0  1   0  1 */
1539         case 0x7:                               /*   0  1   1  1 */
1540         case 0xd:                               /*   1  1   0  1 */
1541         case 0xf:                               /*   1  1   1  1 */
1542                 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1543                 break;
1544
1545         default:
1546                 break;
1547         }
1548 }
1549
1550 static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params,
1551                                   struct link_vars *vars)
1552 {
1553         struct bnx2x *bp = params->bp;
1554         u8 ext_phy_addr;
1555         u16 ld_pause;           /* local */
1556         u16 lp_pause;           /* link partner */
1557         u16 an_complete;        /* AN complete */
1558         u16 pause_result;
1559         u8 ret = 0;
1560         u32 ext_phy_type;
1561         u8 port = params->port;
1562         ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
1563         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1564         /* read twice */
1565
1566         bnx2x_cl45_read(bp, port,
1567                       ext_phy_type,
1568                       ext_phy_addr,
1569                       MDIO_AN_DEVAD,
1570                       MDIO_AN_REG_STATUS, &an_complete);
1571         bnx2x_cl45_read(bp, port,
1572                       ext_phy_type,
1573                       ext_phy_addr,
1574                       MDIO_AN_DEVAD,
1575                       MDIO_AN_REG_STATUS, &an_complete);
1576
1577         if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1578                 ret = 1;
1579                 bnx2x_cl45_read(bp, port,
1580                               ext_phy_type,
1581                               ext_phy_addr,
1582                               MDIO_AN_DEVAD,
1583                               MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1584                 bnx2x_cl45_read(bp, port,
1585                               ext_phy_type,
1586                               ext_phy_addr,
1587                               MDIO_AN_DEVAD,
1588                               MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1589                 pause_result = (ld_pause &
1590                                 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1591                 pause_result |= (lp_pause &
1592                                  MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1593                 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1594                    pause_result);
1595                 bnx2x_pause_resolve(vars, pause_result);
1596                 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1597                      ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1598                         bnx2x_cl45_read(bp, port,
1599                                       ext_phy_type,
1600                                       ext_phy_addr,
1601                                       MDIO_AN_DEVAD,
1602                                       MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1603
1604                         bnx2x_cl45_read(bp, port,
1605                                       ext_phy_type,
1606                                       ext_phy_addr,
1607                                       MDIO_AN_DEVAD,
1608                                       MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1609                         pause_result = (ld_pause &
1610                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1611                         pause_result |= (lp_pause &
1612                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1613
1614                         bnx2x_pause_resolve(vars, pause_result);
1615                         DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1616                                  pause_result);
1617                 }
1618         }
1619         return ret;
1620 }
1621
1622
1623 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1624                                   struct link_vars *vars,
1625                                   u32 gp_status)
1626 {
1627         struct bnx2x *bp = params->bp;
1628         u16 ld_pause;   /* local driver */
1629         u16 lp_pause;   /* link partner */
1630         u16 pause_result;
1631
1632         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1633
1634         /* resolve from gp_status in case of AN complete and not sgmii */
1635         if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1636             (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1637             (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1638             (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1639              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1640                 if ((gp_status &
1641                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
1642                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
1643                     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
1644                      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
1645
1646                         CL45_RD_OVER_CL22(bp, params->port,
1647                                               params->phy_addr,
1648                                               MDIO_REG_BANK_CL73_IEEEB1,
1649                                               MDIO_CL73_IEEEB1_AN_ADV1,
1650                                               &ld_pause);
1651                         CL45_RD_OVER_CL22(bp, params->port,
1652                                              params->phy_addr,
1653                                              MDIO_REG_BANK_CL73_IEEEB1,
1654                                              MDIO_CL73_IEEEB1_AN_LP_ADV1,
1655                                              &lp_pause);
1656                         pause_result = (ld_pause &
1657                                         MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
1658                                         >> 8;
1659                         pause_result |= (lp_pause &
1660                                         MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
1661                                         >> 10;
1662                         DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
1663                                  pause_result);
1664                 } else {
1665
1666                         CL45_RD_OVER_CL22(bp, params->port,
1667                                               params->phy_addr,
1668                                               MDIO_REG_BANK_COMBO_IEEE0,
1669                                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1670                                               &ld_pause);
1671                         CL45_RD_OVER_CL22(bp, params->port,
1672                                params->phy_addr,
1673                                MDIO_REG_BANK_COMBO_IEEE0,
1674                                MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1675                                &lp_pause);
1676                         pause_result = (ld_pause &
1677                                 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1678                         pause_result |= (lp_pause &
1679                                  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1680                         DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
1681                                  pause_result);
1682                 }
1683                 bnx2x_pause_resolve(vars, pause_result);
1684         } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1685                    (bnx2x_ext_phy_resolve_fc(params, vars))) {
1686                 return;
1687         } else {
1688                 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1689                         vars->flow_ctrl = params->req_fc_auto_adv;
1690                 else
1691                         vars->flow_ctrl = params->req_flow_ctrl;
1692         }
1693         DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1694 }
1695
1696 static void bnx2x_check_fallback_to_cl37(struct link_params *params)
1697 {
1698         struct bnx2x *bp = params->bp;
1699         u16 rx_status, ustat_val, cl37_fsm_recieved;
1700         DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
1701         /* Step 1: Make sure signal is detected */
1702         CL45_RD_OVER_CL22(bp, params->port,
1703                               params->phy_addr,
1704                               MDIO_REG_BANK_RX0,
1705                               MDIO_RX0_RX_STATUS,
1706                               &rx_status);
1707         if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
1708             (MDIO_RX0_RX_STATUS_SIGDET)) {
1709                 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
1710                              "rx_status(0x80b0) = 0x%x\n", rx_status);
1711                 CL45_WR_OVER_CL22(bp, params->port,
1712                                       params->phy_addr,
1713                                       MDIO_REG_BANK_CL73_IEEEB0,
1714                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1715                                       MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
1716                 return;
1717         }
1718         /* Step 2: Check CL73 state machine */
1719         CL45_RD_OVER_CL22(bp, params->port,
1720                               params->phy_addr,
1721                               MDIO_REG_BANK_CL73_USERB0,
1722                               MDIO_CL73_USERB0_CL73_USTAT1,
1723                               &ustat_val);
1724         if ((ustat_val &
1725              (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
1726               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
1727             (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
1728               MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
1729                 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
1730                              "ustat_val(0x8371) = 0x%x\n", ustat_val);
1731                 return;
1732         }
1733         /* Step 3: Check CL37 Message Pages received to indicate LP
1734         supports only CL37 */
1735         CL45_RD_OVER_CL22(bp, params->port,
1736                               params->phy_addr,
1737                               MDIO_REG_BANK_REMOTE_PHY,
1738                               MDIO_REMOTE_PHY_MISC_RX_STATUS,
1739                               &cl37_fsm_recieved);
1740         if ((cl37_fsm_recieved &
1741              (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
1742              MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
1743             (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
1744               MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
1745                 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
1746                              "misc_rx_status(0x8330) = 0x%x\n",
1747                          cl37_fsm_recieved);
1748                 return;
1749         }
1750         /* The combined cl37/cl73 fsm state information indicating that we are
1751         connected to a device which does not support cl73, but does support
1752         cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
1753         /* Disable CL73 */
1754         CL45_WR_OVER_CL22(bp, params->port,
1755                               params->phy_addr,
1756                               MDIO_REG_BANK_CL73_IEEEB0,
1757                               MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1758                               0);
1759         /* Restart CL37 autoneg */
1760         bnx2x_restart_autoneg(params, 0);
1761         DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
1762 }
1763 static u8 bnx2x_link_settings_status(struct link_params *params,
1764                                    struct link_vars *vars,
1765                                    u32 gp_status,
1766                                    u8 ext_phy_link_up)
1767 {
1768         struct bnx2x *bp = params->bp;
1769         u16 new_line_speed;
1770         u8 rc = 0;
1771         vars->link_status = 0;
1772
1773         if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1774                 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1775                          gp_status);
1776
1777                 vars->phy_link_up = 1;
1778                 vars->link_status |= LINK_STATUS_LINK_UP;
1779
1780                 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1781                         vars->duplex = DUPLEX_FULL;
1782                 else
1783                         vars->duplex = DUPLEX_HALF;
1784
1785                 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1786
1787                 switch (gp_status & GP_STATUS_SPEED_MASK) {
1788                 case GP_STATUS_10M:
1789                         new_line_speed = SPEED_10;
1790                         if (vars->duplex == DUPLEX_FULL)
1791                                 vars->link_status |= LINK_10TFD;
1792                         else
1793                                 vars->link_status |= LINK_10THD;
1794                         break;
1795
1796                 case GP_STATUS_100M:
1797                         new_line_speed = SPEED_100;
1798                         if (vars->duplex == DUPLEX_FULL)
1799                                 vars->link_status |= LINK_100TXFD;
1800                         else
1801                                 vars->link_status |= LINK_100TXHD;
1802                         break;
1803
1804                 case GP_STATUS_1G:
1805                 case GP_STATUS_1G_KX:
1806                         new_line_speed = SPEED_1000;
1807                         if (vars->duplex == DUPLEX_FULL)
1808                                 vars->link_status |= LINK_1000TFD;
1809                         else
1810                                 vars->link_status |= LINK_1000THD;
1811                         break;
1812
1813                 case GP_STATUS_2_5G:
1814                         new_line_speed = SPEED_2500;
1815                         if (vars->duplex == DUPLEX_FULL)
1816                                 vars->link_status |= LINK_2500TFD;
1817                         else
1818                                 vars->link_status |= LINK_2500THD;
1819                         break;
1820
1821                 case GP_STATUS_5G:
1822                 case GP_STATUS_6G:
1823                         DP(NETIF_MSG_LINK,
1824                                  "link speed unsupported  gp_status 0x%x\n",
1825                                   gp_status);
1826                         return -EINVAL;
1827
1828                 case GP_STATUS_10G_KX4:
1829                 case GP_STATUS_10G_HIG:
1830                 case GP_STATUS_10G_CX4:
1831                         new_line_speed = SPEED_10000;
1832                         vars->link_status |= LINK_10GTFD;
1833                         break;
1834
1835                 case GP_STATUS_12G_HIG:
1836                         new_line_speed = SPEED_12000;
1837                         vars->link_status |= LINK_12GTFD;
1838                         break;
1839
1840                 case GP_STATUS_12_5G:
1841                         new_line_speed = SPEED_12500;
1842                         vars->link_status |= LINK_12_5GTFD;
1843                         break;
1844
1845                 case GP_STATUS_13G:
1846                         new_line_speed = SPEED_13000;
1847                         vars->link_status |= LINK_13GTFD;
1848                         break;
1849
1850                 case GP_STATUS_15G:
1851                         new_line_speed = SPEED_15000;
1852                         vars->link_status |= LINK_15GTFD;
1853                         break;
1854
1855                 case GP_STATUS_16G:
1856                         new_line_speed = SPEED_16000;
1857                         vars->link_status |= LINK_16GTFD;
1858                         break;
1859
1860                 default:
1861                         DP(NETIF_MSG_LINK,
1862                                   "link speed unsupported gp_status 0x%x\n",
1863                                   gp_status);
1864                         return -EINVAL;
1865                 }
1866
1867                 /* Upon link speed change set the NIG into drain mode.
1868                 Comes to deals with possible FIFO glitch due to clk change
1869                 when speed is decreased without link down indicator */
1870                 if (new_line_speed != vars->line_speed) {
1871                         if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) !=
1872                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT &&
1873                             ext_phy_link_up) {
1874                                 DP(NETIF_MSG_LINK, "Internal link speed %d is"
1875                                             " different than the external"
1876                                             " link speed %d\n", new_line_speed,
1877                                           vars->line_speed);
1878                                 vars->phy_link_up = 0;
1879                                 return 0;
1880                         }
1881                         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1882                                     + params->port*4, 0);
1883                         msleep(1);
1884                 }
1885                 vars->line_speed = new_line_speed;
1886                 vars->link_status |= LINK_STATUS_SERDES_LINK;
1887
1888                 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1889                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1890                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1891                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1892                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1893                     (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1894                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
1895                         vars->autoneg = AUTO_NEG_ENABLED;
1896
1897                         if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1898                                 vars->autoneg |= AUTO_NEG_COMPLETE;
1899                                 vars->link_status |=
1900                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1901                         }
1902
1903                         vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1904                         vars->link_status |=
1905                                 LINK_STATUS_PARALLEL_DETECTION_USED;
1906
1907                 }
1908                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1909                         vars->link_status |=
1910                                 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1911
1912                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1913                         vars->link_status |=
1914                                 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1915
1916         } else { /* link_down */
1917                 DP(NETIF_MSG_LINK, "phy link down\n");
1918
1919                 vars->phy_link_up = 0;
1920
1921                 vars->duplex = DUPLEX_FULL;
1922                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1923                 vars->autoneg = AUTO_NEG_DISABLED;
1924                 vars->mac_type = MAC_TYPE_NONE;
1925
1926                 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1927                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1928                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT))) {
1929                         /* Check signal is detected */
1930                         bnx2x_check_fallback_to_cl37(params);
1931                 }
1932         }
1933
1934         DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
1935                  gp_status, vars->phy_link_up, vars->line_speed);
1936         DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
1937                  " autoneg 0x%x\n",
1938                  vars->duplex,
1939                  vars->flow_ctrl, vars->autoneg);
1940         DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1941
1942         return rc;
1943 }
1944
1945 static void bnx2x_set_gmii_tx_driver(struct link_params *params)
1946 {
1947         struct bnx2x *bp = params->bp;
1948         u16 lp_up2;
1949         u16 tx_driver;
1950         u16 bank;
1951
1952         /* read precomp */
1953         CL45_RD_OVER_CL22(bp, params->port,
1954                               params->phy_addr,
1955                               MDIO_REG_BANK_OVER_1G,
1956                               MDIO_OVER_1G_LP_UP2, &lp_up2);
1957
1958         /* bits [10:7] at lp_up2, positioned at [15:12] */
1959         lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1960                    MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1961                   MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1962
1963         if (lp_up2 == 0)
1964                 return;
1965
1966         for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
1967               bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
1968                 CL45_RD_OVER_CL22(bp, params->port,
1969                                       params->phy_addr,
1970                                       bank,
1971                                       MDIO_TX0_TX_DRIVER, &tx_driver);
1972
1973                 /* replace tx_driver bits [15:12] */
1974                 if (lp_up2 !=
1975                     (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
1976                         tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1977                         tx_driver |= lp_up2;
1978                         CL45_WR_OVER_CL22(bp, params->port,
1979                                               params->phy_addr,
1980                                               bank,
1981                                               MDIO_TX0_TX_DRIVER, tx_driver);
1982                 }
1983         }
1984 }
1985
1986 static u8 bnx2x_emac_program(struct link_params *params,
1987                            u32 line_speed, u32 duplex)
1988 {
1989         struct bnx2x *bp = params->bp;
1990         u8 port = params->port;
1991         u16 mode = 0;
1992
1993         DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1994         bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1995                      EMAC_REG_EMAC_MODE,
1996                      (EMAC_MODE_25G_MODE |
1997                      EMAC_MODE_PORT_MII_10M |
1998                      EMAC_MODE_HALF_DUPLEX));
1999         switch (line_speed) {
2000         case SPEED_10:
2001                 mode |= EMAC_MODE_PORT_MII_10M;
2002                 break;
2003
2004         case SPEED_100:
2005                 mode |= EMAC_MODE_PORT_MII;
2006                 break;
2007
2008         case SPEED_1000:
2009                 mode |= EMAC_MODE_PORT_GMII;
2010                 break;
2011
2012         case SPEED_2500:
2013                 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
2014                 break;
2015
2016         default:
2017                 /* 10G not valid for EMAC */
2018                 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
2019                 return -EINVAL;
2020         }
2021
2022         if (duplex == DUPLEX_HALF)
2023                 mode |= EMAC_MODE_HALF_DUPLEX;
2024         bnx2x_bits_en(bp,
2025                     GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
2026                     mode);
2027
2028         bnx2x_set_led(params, LED_MODE_OPER, line_speed);
2029         return 0;
2030 }
2031
2032 /*****************************************************************************/
2033 /*                           External Phy section                            */
2034 /*****************************************************************************/
2035 void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
2036 {
2037         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2038                        MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
2039         msleep(1);
2040         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2041                       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
2042 }
2043
2044 static void bnx2x_ext_phy_reset(struct link_params *params,
2045                               struct link_vars   *vars)
2046 {
2047         struct bnx2x *bp = params->bp;
2048         u32 ext_phy_type;
2049         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2050
2051         DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
2052         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2053         /* The PHY reset is controled by GPIO 1
2054          * Give it 1ms of reset pulse
2055          */
2056         if (vars->phy_flags & PHY_XGXS_FLAG) {
2057
2058                 switch (ext_phy_type) {
2059                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2060                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
2061                         break;
2062
2063                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2064                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2065                         DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
2066
2067                         /* Restore normal power mode*/
2068                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2069                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2070                                           params->port);
2071
2072                         /* HW reset */
2073                         bnx2x_ext_phy_hw_reset(bp, params->port);
2074
2075                         bnx2x_cl45_write(bp, params->port,
2076                                        ext_phy_type,
2077                                        ext_phy_addr,
2078                                        MDIO_PMA_DEVAD,
2079                                        MDIO_PMA_REG_CTRL, 0xa040);
2080                         break;
2081
2082                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
2083                         break;
2084
2085                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
2086
2087                         /* Restore normal power mode*/
2088                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2089                                           MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2090                                           params->port);
2091
2092                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2093                                           MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2094                                           params->port);
2095
2096                         bnx2x_cl45_write(bp, params->port,
2097                                        ext_phy_type,
2098                                        ext_phy_addr,
2099                                        MDIO_PMA_DEVAD,
2100                                        MDIO_PMA_REG_CTRL,
2101                                        1<<15);
2102                         break;
2103
2104                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2105                         DP(NETIF_MSG_LINK, "XGXS 8072\n");
2106
2107                         /* Unset Low Power Mode and SW reset */
2108                         /* Restore normal power mode*/
2109                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2110                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2111                                           params->port);
2112
2113                         bnx2x_cl45_write(bp, params->port,
2114                                        ext_phy_type,
2115                                        ext_phy_addr,
2116                                        MDIO_PMA_DEVAD,
2117                                        MDIO_PMA_REG_CTRL,
2118                                        1<<15);
2119                         break;
2120
2121                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2122                         DP(NETIF_MSG_LINK, "XGXS 8073\n");
2123
2124                         /* Restore normal power mode*/
2125                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2126                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2127                                           params->port);
2128
2129                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2130                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2131                                           params->port);
2132                         break;
2133
2134                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2135                         DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
2136
2137                         /* Restore normal power mode*/
2138                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2139                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2140                                           params->port);
2141
2142                         /* HW reset */
2143                         bnx2x_ext_phy_hw_reset(bp, params->port);
2144                         break;
2145
2146                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
2147                         /* Restore normal power mode*/
2148                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2149                                       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2150                                           params->port);
2151
2152                         /* HW reset */
2153                         bnx2x_ext_phy_hw_reset(bp, params->port);
2154
2155                         bnx2x_cl45_write(bp, params->port,
2156                                        ext_phy_type,
2157                                        ext_phy_addr,
2158                                        MDIO_PMA_DEVAD,
2159                                        MDIO_PMA_REG_CTRL,
2160                                        1<<15);
2161                         break;
2162                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2163                         DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
2164                         break;
2165
2166                 default:
2167                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2168                            params->ext_phy_config);
2169                         break;
2170                 }
2171
2172         } else { /* SerDes */
2173                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2174                 switch (ext_phy_type) {
2175                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2176                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
2177                         break;
2178
2179                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2180                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
2181                         bnx2x_ext_phy_hw_reset(bp, params->port);
2182                         break;
2183
2184                 default:
2185                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2186                                  params->ext_phy_config);
2187                         break;
2188                 }
2189         }
2190 }
2191
2192 static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2193                                     u32 shmem_base, u32 spirom_ver)
2194 {
2195         DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
2196                  (u16)(spirom_ver>>16), (u16)spirom_ver, port);
2197         REG_WR(bp, shmem_base +
2198                    offsetof(struct shmem_region,
2199                             port_mb[port].ext_phy_fw_version),
2200                         spirom_ver);
2201 }
2202
2203 static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
2204                                     u32 ext_phy_type, u8 ext_phy_addr,
2205                                     u32 shmem_base)
2206 {
2207         u16 fw_ver1, fw_ver2;
2208
2209         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2210                       MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2211         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD,
2212                       MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2213         bnx2x_save_spirom_version(bp, port, shmem_base,
2214                                 (u32)(fw_ver1<<16 | fw_ver2));
2215 }
2216
2217
2218 static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port,
2219                                          u8 ext_phy_addr, u32 shmem_base)
2220 {
2221         u16 val, fw_ver1, fw_ver2, cnt;
2222         /* For the 32 bits registers in 8481, access via MDIO2ARM interface.*/
2223         /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
2224         bnx2x_cl45_write(bp, port,
2225                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2226                        ext_phy_addr, MDIO_PMA_DEVAD,
2227                        0xA819, 0x0014);
2228         bnx2x_cl45_write(bp, port,
2229                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2230                        ext_phy_addr,
2231                        MDIO_PMA_DEVAD,
2232                        0xA81A,
2233                        0xc200);
2234         bnx2x_cl45_write(bp, port,
2235                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2236                        ext_phy_addr,
2237                        MDIO_PMA_DEVAD,
2238                        0xA81B,
2239                        0x0000);
2240         bnx2x_cl45_write(bp, port,
2241                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2242                        ext_phy_addr,
2243                        MDIO_PMA_DEVAD,
2244                        0xA81C,
2245                        0x0300);
2246         bnx2x_cl45_write(bp, port,
2247                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2248                        ext_phy_addr,
2249                        MDIO_PMA_DEVAD,
2250                        0xA817,
2251                        0x0009);
2252
2253         for (cnt = 0; cnt < 100; cnt++) {
2254                 bnx2x_cl45_read(bp, port,
2255                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2256                               ext_phy_addr,
2257                               MDIO_PMA_DEVAD,
2258                               0xA818,
2259                               &val);
2260                 if (val & 1)
2261                         break;
2262                 udelay(5);
2263         }
2264         if (cnt == 100) {
2265                 DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n");
2266                 bnx2x_save_spirom_version(bp, port,
2267                                         shmem_base, 0);
2268                 return;
2269         }
2270
2271
2272         /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
2273         bnx2x_cl45_write(bp, port,
2274                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2275                        ext_phy_addr, MDIO_PMA_DEVAD,
2276                        0xA819, 0x0000);
2277         bnx2x_cl45_write(bp, port,
2278                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2279                        ext_phy_addr, MDIO_PMA_DEVAD,
2280                        0xA81A, 0xc200);
2281         bnx2x_cl45_write(bp, port,
2282                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2283                        ext_phy_addr, MDIO_PMA_DEVAD,
2284                        0xA817, 0x000A);
2285         for (cnt = 0; cnt < 100; cnt++) {
2286                 bnx2x_cl45_read(bp, port,
2287                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2288                               ext_phy_addr,
2289                               MDIO_PMA_DEVAD,
2290                               0xA818,
2291                               &val);
2292                 if (val & 1)
2293                         break;
2294                 udelay(5);
2295         }
2296         if (cnt == 100) {
2297                 DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(2)\n");
2298                 bnx2x_save_spirom_version(bp, port,
2299                                         shmem_base, 0);
2300                 return;
2301         }
2302
2303         /* lower 16 bits of the register SPI_FW_STATUS */
2304         bnx2x_cl45_read(bp, port,
2305                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2306                       ext_phy_addr,
2307                       MDIO_PMA_DEVAD,
2308                       0xA81B,
2309                       &fw_ver1);
2310         /* upper 16 bits of register SPI_FW_STATUS */
2311         bnx2x_cl45_read(bp, port,
2312                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2313                       ext_phy_addr,
2314                       MDIO_PMA_DEVAD,
2315                       0xA81C,
2316                       &fw_ver2);
2317
2318         bnx2x_save_spirom_version(bp, port,
2319                                 shmem_base, (fw_ver2<<16) | fw_ver1);
2320 }
2321
2322 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
2323 {
2324         struct bnx2x *bp = params->bp;
2325         u8 port = params->port;
2326         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2327         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2328
2329         /* Need to wait 200ms after reset */
2330         msleep(200);
2331         /* Boot port from external ROM
2332          * Set ser_boot_ctl bit in the MISC_CTRL1 register
2333          */
2334         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2335                             MDIO_PMA_DEVAD,
2336                             MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2337
2338         /* Reset internal microprocessor */
2339         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2340                           MDIO_PMA_DEVAD,
2341                           MDIO_PMA_REG_GEN_CTRL,
2342                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2343         /* set micro reset = 0 */
2344         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2345                             MDIO_PMA_DEVAD,
2346                             MDIO_PMA_REG_GEN_CTRL,
2347                             MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2348         /* Reset internal microprocessor */
2349         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2350                           MDIO_PMA_DEVAD,
2351                           MDIO_PMA_REG_GEN_CTRL,
2352                           MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2353         /* wait for 100ms for code download via SPI port */
2354         msleep(100);
2355
2356         /* Clear ser_boot_ctl bit */
2357         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2358                             MDIO_PMA_DEVAD,
2359                             MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2360         /* Wait 100ms */
2361         msleep(100);
2362
2363         bnx2x_save_bcm_spirom_ver(bp, port,
2364                                 ext_phy_type,
2365                                 ext_phy_addr,
2366                                 params->shmem_base);
2367 }
2368
2369 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2370 {
2371         /* This is only required for 8073A1, version 102 only */
2372
2373         struct bnx2x *bp = params->bp;
2374         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2375         u16 val;
2376
2377         /* Read 8073 HW revision*/
2378         bnx2x_cl45_read(bp, params->port,
2379                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2380                       ext_phy_addr,
2381                       MDIO_PMA_DEVAD,
2382                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2383
2384         if (val != 1) {
2385                 /* No need to workaround in 8073 A1 */
2386                 return 0;
2387         }
2388
2389         bnx2x_cl45_read(bp, params->port,
2390                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2391                       ext_phy_addr,
2392                       MDIO_PMA_DEVAD,
2393                       MDIO_PMA_REG_ROM_VER2, &val);
2394
2395         /* SNR should be applied only for version 0x102 */
2396         if (val != 0x102)
2397                 return 0;
2398
2399         return 1;
2400 }
2401
2402 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2403 {
2404         struct bnx2x *bp = params->bp;
2405         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2406         u16 val, cnt, cnt1 ;
2407
2408         bnx2x_cl45_read(bp, params->port,
2409                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2410                       ext_phy_addr,
2411                       MDIO_PMA_DEVAD,
2412                       MDIO_PMA_REG_8073_CHIP_REV, &val);
2413
2414         if (val > 0) {
2415                 /* No need to workaround in 8073 A1 */
2416                 return 0;
2417         }
2418         /* XAUI workaround in 8073 A0: */
2419
2420         /* After loading the boot ROM and restarting Autoneg,
2421         poll Dev1, Reg $C820: */
2422
2423         for (cnt = 0; cnt < 1000; cnt++) {
2424                 bnx2x_cl45_read(bp, params->port,
2425                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2426                               ext_phy_addr,
2427                               MDIO_PMA_DEVAD,
2428                               MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
2429                               &val);
2430                   /* If bit [14] = 0 or bit [13] = 0, continue on with
2431                    system initialization (XAUI work-around not required,
2432                     as these bits indicate 2.5G or 1G link up). */
2433                 if (!(val & (1<<14)) || !(val & (1<<13))) {
2434                         DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2435                         return 0;
2436                 } else if (!(val & (1<<15))) {
2437                         DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2438                          /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2439                           it's MSB (bit 15) goes to 1 (indicating that the
2440                           XAUI workaround has completed),
2441                           then continue on with system initialization.*/
2442                         for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2443                                 bnx2x_cl45_read(bp, params->port,
2444                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2445                                         ext_phy_addr,
2446                                         MDIO_PMA_DEVAD,
2447                                         MDIO_PMA_REG_8073_XAUI_WA, &val);
2448                                 if (val & (1<<15)) {
2449                                         DP(NETIF_MSG_LINK,
2450                                           "XAUI workaround has completed\n");
2451                                         return 0;
2452                                  }
2453                                  msleep(3);
2454                         }
2455                         break;
2456                 }
2457                 msleep(3);
2458         }
2459         DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2460         return -EINVAL;
2461 }
2462
2463 static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
2464                                                   u8 ext_phy_addr,
2465                                                   u32 ext_phy_type,
2466                                                   u32 shmem_base)
2467 {
2468         /* Boot port from external ROM  */
2469         /* EDC grst */
2470         bnx2x_cl45_write(bp, port,
2471                        ext_phy_type,
2472                        ext_phy_addr,
2473                        MDIO_PMA_DEVAD,
2474                        MDIO_PMA_REG_GEN_CTRL,
2475                        0x0001);
2476
2477         /* ucode reboot and rst */
2478         bnx2x_cl45_write(bp, port,
2479                        ext_phy_type,
2480                        ext_phy_addr,
2481                        MDIO_PMA_DEVAD,
2482                        MDIO_PMA_REG_GEN_CTRL,
2483                        0x008c);
2484
2485         bnx2x_cl45_write(bp, port,
2486                        ext_phy_type,
2487                        ext_phy_addr,
2488                        MDIO_PMA_DEVAD,
2489                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2490
2491         /* Reset internal microprocessor */
2492         bnx2x_cl45_write(bp, port,
2493                        ext_phy_type,
2494                        ext_phy_addr,
2495                        MDIO_PMA_DEVAD,
2496                        MDIO_PMA_REG_GEN_CTRL,
2497                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2498
2499         /* Release srst bit */
2500         bnx2x_cl45_write(bp, port,
2501                        ext_phy_type,
2502                        ext_phy_addr,
2503                        MDIO_PMA_DEVAD,
2504                        MDIO_PMA_REG_GEN_CTRL,
2505                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2506
2507         /* wait for 100ms for code download via SPI port */
2508         msleep(100);
2509
2510         /* Clear ser_boot_ctl bit */
2511         bnx2x_cl45_write(bp, port,
2512                        ext_phy_type,
2513                        ext_phy_addr,
2514                        MDIO_PMA_DEVAD,
2515                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2516
2517         bnx2x_save_bcm_spirom_ver(bp, port,
2518                                 ext_phy_type,
2519                                 ext_phy_addr,
2520                                 shmem_base);
2521 }
2522
2523 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2524                                           u8 ext_phy_addr,
2525                                           u32 shmem_base)
2526 {
2527         bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
2528                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2529                                          shmem_base);
2530 }
2531
2532 static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port,
2533                                           u8 ext_phy_addr,
2534                                           u32 shmem_base)
2535 {
2536         bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr,
2537                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2538                                          shmem_base);
2539
2540 }
2541
2542 static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2543 {
2544         struct bnx2x *bp = params->bp;
2545         u8 port = params->port;
2546         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2547         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2548
2549         /* Need to wait 100ms after reset */
2550         msleep(100);
2551
2552         /* Set serial boot control for external load */
2553         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2554                        MDIO_PMA_DEVAD,
2555                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2556
2557         /* Micro controller re-boot */
2558         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2559                        MDIO_PMA_DEVAD,
2560                        MDIO_PMA_REG_GEN_CTRL,
2561                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2562
2563         /* Set soft reset */
2564         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2565                        MDIO_PMA_DEVAD,
2566                        MDIO_PMA_REG_GEN_CTRL,
2567                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2568
2569         /* Set PLL register value to be same like in P13 ver */
2570         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2571                        MDIO_PMA_DEVAD,
2572                        MDIO_PMA_REG_PLL_CTRL,
2573                        0x73A0);
2574
2575         /* Clear soft reset.
2576         Will automatically reset micro-controller re-boot */
2577         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2578                        MDIO_PMA_DEVAD,
2579                        MDIO_PMA_REG_GEN_CTRL,
2580                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2581
2582         /* wait for 150ms for microcode load */
2583         msleep(150);
2584
2585         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2586         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2587                        MDIO_PMA_DEVAD,
2588                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2589
2590         msleep(200);
2591         bnx2x_save_bcm_spirom_ver(bp, port,
2592                                 ext_phy_type,
2593                                 ext_phy_addr,
2594                                 params->shmem_base);
2595 }
2596
2597 static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port,
2598                                     u32 ext_phy_type, u8 ext_phy_addr,
2599                                     u8 tx_en)
2600 {
2601         u16 val;
2602
2603         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2604                  tx_en, port);
2605         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2606         bnx2x_cl45_read(bp, port,
2607                       ext_phy_type,
2608                       ext_phy_addr,
2609                       MDIO_PMA_DEVAD,
2610                       MDIO_PMA_REG_PHY_IDENTIFIER,
2611                       &val);
2612
2613         if (tx_en)
2614                 val &= ~(1<<15);
2615         else
2616                 val |= (1<<15);
2617
2618         bnx2x_cl45_write(bp, port,
2619                        ext_phy_type,
2620                        ext_phy_addr,
2621                        MDIO_PMA_DEVAD,
2622                        MDIO_PMA_REG_PHY_IDENTIFIER,
2623                        val);
2624 }
2625
2626 static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
2627                                           u16 addr, u8 byte_cnt, u8 *o_buf)
2628 {
2629         struct bnx2x *bp = params->bp;
2630         u16 val = 0;
2631         u16 i;
2632         u8 port = params->port;
2633         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2634         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2635
2636         if (byte_cnt > 16) {
2637                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2638                             " is limited to 0xf\n");
2639                 return -EINVAL;
2640         }
2641         /* Set the read command byte count */
2642         bnx2x_cl45_write(bp, port,
2643                        ext_phy_type,
2644                        ext_phy_addr,
2645                        MDIO_PMA_DEVAD,
2646                        MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2647                        (byte_cnt | 0xa000));
2648
2649         /* Set the read command address */
2650         bnx2x_cl45_write(bp, port,
2651                        ext_phy_type,
2652                        ext_phy_addr,
2653                        MDIO_PMA_DEVAD,
2654                        MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2655                        addr);
2656
2657         /* Activate read command */
2658         bnx2x_cl45_write(bp, port,
2659                        ext_phy_type,
2660                        ext_phy_addr,
2661                        MDIO_PMA_DEVAD,
2662                        MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2663                        0x2c0f);
2664
2665         /* Wait up to 500us for command complete status */
2666         for (i = 0; i < 100; i++) {
2667                 bnx2x_cl45_read(bp, port,
2668                               ext_phy_type,
2669                               ext_phy_addr,
2670                               MDIO_PMA_DEVAD,
2671                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2672                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2673                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2674                         break;
2675                 udelay(5);
2676         }
2677
2678         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2679                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2680                 DP(NETIF_MSG_LINK,
2681                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2682                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2683                 return -EINVAL;
2684         }
2685
2686         /* Read the buffer */
2687         for (i = 0; i < byte_cnt; i++) {
2688                 bnx2x_cl45_read(bp, port,
2689                               ext_phy_type,
2690                               ext_phy_addr,
2691                               MDIO_PMA_DEVAD,
2692                               MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2693                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2694         }
2695
2696         for (i = 0; i < 100; i++) {
2697                 bnx2x_cl45_read(bp, port,
2698                               ext_phy_type,
2699                               ext_phy_addr,
2700                               MDIO_PMA_DEVAD,
2701                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2702                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2703                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2704                         return 0;;
2705                 msleep(1);
2706         }
2707         return -EINVAL;
2708 }
2709
2710 static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
2711                                           u16 addr, u8 byte_cnt, u8 *o_buf)
2712 {
2713         struct bnx2x *bp = params->bp;
2714         u16 val, i;
2715         u8 port = params->port;
2716         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2717         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2718
2719         if (byte_cnt > 16) {
2720                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2721                             " is limited to 0xf\n");
2722                 return -EINVAL;
2723         }
2724
2725         /* Need to read from 1.8000 to clear it */
2726         bnx2x_cl45_read(bp, port,
2727                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
2728                       ext_phy_addr,
2729                       MDIO_PMA_DEVAD,
2730                       MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2731                       &val);
2732
2733         /* Set the read command byte count */
2734         bnx2x_cl45_write(bp, port,
2735                        ext_phy_type,
2736                        ext_phy_addr,
2737                        MDIO_PMA_DEVAD,
2738                        MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2739                        ((byte_cnt < 2) ? 2 : byte_cnt));
2740
2741         /* Set the read command address */
2742         bnx2x_cl45_write(bp, port,
2743                        ext_phy_type,
2744                        ext_phy_addr,
2745                        MDIO_PMA_DEVAD,
2746                        MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2747                        addr);
2748         /* Set the destination address */
2749         bnx2x_cl45_write(bp, port,
2750                        ext_phy_type,
2751                        ext_phy_addr,
2752                        MDIO_PMA_DEVAD,
2753                        0x8004,
2754                        MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
2755
2756         /* Activate read command */
2757         bnx2x_cl45_write(bp, port,
2758                        ext_phy_type,
2759                        ext_phy_addr,
2760                        MDIO_PMA_DEVAD,
2761                        MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2762                        0x8002);
2763         /* Wait appropriate time for two-wire command to finish before
2764         polling the status register */
2765         msleep(1);
2766
2767         /* Wait up to 500us for command complete status */
2768         for (i = 0; i < 100; i++) {
2769                 bnx2x_cl45_read(bp, port,
2770                               ext_phy_type,
2771                               ext_phy_addr,
2772                               MDIO_PMA_DEVAD,
2773                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2774                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2775                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2776                         break;
2777                 udelay(5);
2778         }
2779
2780         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2781                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2782                 DP(NETIF_MSG_LINK,
2783                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2784                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2785                 return -EINVAL;
2786         }
2787
2788         /* Read the buffer */
2789         for (i = 0; i < byte_cnt; i++) {
2790                 bnx2x_cl45_read(bp, port,
2791                               ext_phy_type,
2792                               ext_phy_addr,
2793                               MDIO_PMA_DEVAD,
2794                               MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
2795                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
2796         }
2797
2798         for (i = 0; i < 100; i++) {
2799                 bnx2x_cl45_read(bp, port,
2800                               ext_phy_type,
2801                               ext_phy_addr,
2802                               MDIO_PMA_DEVAD,
2803                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2804                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2805                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2806                         return 0;;
2807                 msleep(1);
2808         }
2809
2810         return -EINVAL;
2811 }
2812
2813 u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2814                                      u8 byte_cnt, u8 *o_buf)
2815 {
2816         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2817
2818         if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
2819                 return bnx2x_8726_read_sfp_module_eeprom(params, addr,
2820                                                        byte_cnt, o_buf);
2821         else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
2822                 return bnx2x_8727_read_sfp_module_eeprom(params, addr,
2823                                                        byte_cnt, o_buf);
2824         return -EINVAL;
2825 }
2826
2827 static u8 bnx2x_get_edc_mode(struct link_params *params,
2828                                   u16 *edc_mode)
2829 {
2830         struct bnx2x *bp = params->bp;
2831         u8 val, check_limiting_mode = 0;
2832         *edc_mode = EDC_MODE_LIMITING;
2833
2834         /* First check for copper cable */
2835         if (bnx2x_read_sfp_module_eeprom(params,
2836                                        SFP_EEPROM_CON_TYPE_ADDR,
2837                                        1,
2838                                        &val) != 0) {
2839                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
2840                 return -EINVAL;
2841         }
2842
2843         switch (val) {
2844         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2845         {
2846                 u8 copper_module_type;
2847
2848                 /* Check if its active cable( includes SFP+ module)
2849                 of passive cable*/
2850                 if (bnx2x_read_sfp_module_eeprom(params,
2851                                                SFP_EEPROM_FC_TX_TECH_ADDR,
2852                                                1,
2853                                                &copper_module_type) !=
2854                     0) {
2855                         DP(NETIF_MSG_LINK,
2856                                 "Failed to read copper-cable-type"
2857                                 " from SFP+ EEPROM\n");
2858                         return -EINVAL;
2859                 }
2860
2861                 if (copper_module_type &
2862                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2863                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2864                         check_limiting_mode = 1;
2865                 } else if (copper_module_type &
2866                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2867                                 DP(NETIF_MSG_LINK, "Passive Copper"
2868                                             " cable detected\n");
2869                                 *edc_mode =
2870                                       EDC_MODE_PASSIVE_DAC;
2871                 } else {
2872                         DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2873                                      "type 0x%x !!!\n", copper_module_type);
2874                         return -EINVAL;
2875                 }
2876                 break;
2877         }
2878         case SFP_EEPROM_CON_TYPE_VAL_LC:
2879                 DP(NETIF_MSG_LINK, "Optic module detected\n");
2880                 check_limiting_mode = 1;
2881                 break;
2882         default:
2883                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2884                          val);
2885                 return -EINVAL;
2886         }
2887
2888         if (check_limiting_mode) {
2889                 u8 options[SFP_EEPROM_OPTIONS_SIZE];
2890                 if (bnx2x_read_sfp_module_eeprom(params,
2891                                                SFP_EEPROM_OPTIONS_ADDR,
2892                                                SFP_EEPROM_OPTIONS_SIZE,
2893                                                options) != 0) {
2894                         DP(NETIF_MSG_LINK, "Failed to read Option"
2895                                 " field from module EEPROM\n");
2896                         return -EINVAL;
2897                 }
2898                 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
2899                         *edc_mode = EDC_MODE_LINEAR;
2900                 else
2901                         *edc_mode = EDC_MODE_LIMITING;
2902         }
2903         DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
2904         return 0;
2905 }
2906
2907 /* This function read the relevant field from the module ( SFP+ ),
2908         and verify it is compliant with this board */
2909 static u8 bnx2x_verify_sfp_module(struct link_params *params)
2910 {
2911         struct bnx2x *bp = params->bp;
2912         u32 val;
2913         u32 fw_resp;
2914         char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
2915         char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
2916
2917         val = REG_RD(bp, params->shmem_base +
2918                          offsetof(struct shmem_region, dev_info.
2919                                   port_feature_config[params->port].config));
2920         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2921             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
2922                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2923                 return 0;
2924         }
2925
2926         /* Ask the FW to validate the module */
2927         if (!(params->feature_config_flags &
2928               FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) {
2929                 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
2930                             "verification\n");
2931                 return -EINVAL;
2932         }
2933
2934         fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL);
2935         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
2936                 DP(NETIF_MSG_LINK, "Approved module\n");
2937                 return 0;
2938         }
2939
2940         /* format the warning message */
2941         if (bnx2x_read_sfp_module_eeprom(params,
2942                                        SFP_EEPROM_VENDOR_NAME_ADDR,
2943                                        SFP_EEPROM_VENDOR_NAME_SIZE,
2944                                        (u8 *)vendor_name))
2945                 vendor_name[0] = '\0';
2946         else
2947                 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
2948         if (bnx2x_read_sfp_module_eeprom(params,
2949                                        SFP_EEPROM_PART_NO_ADDR,
2950                                        SFP_EEPROM_PART_NO_SIZE,
2951                                        (u8 *)vendor_pn))
2952                 vendor_pn[0] = '\0';
2953         else
2954                 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
2955
2956         printk(KERN_INFO PFX  "Warning: "
2957                          "Unqualified SFP+ module "
2958                          "detected on %s, Port %d from %s part number %s\n"
2959                         , bp->dev->name, params->port,
2960                         vendor_name, vendor_pn);
2961         return -EINVAL;
2962 }
2963
2964 static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2965                                         u16 edc_mode)
2966 {
2967         struct bnx2x *bp = params->bp;
2968         u8 port = params->port;
2969         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2970         u16 cur_limiting_mode;
2971
2972         bnx2x_cl45_read(bp, port,
2973                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2974                       ext_phy_addr,
2975                       MDIO_PMA_DEVAD,
2976                       MDIO_PMA_REG_ROM_VER2,
2977                       &cur_limiting_mode);
2978         DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
2979                  cur_limiting_mode);
2980
2981         if (edc_mode == EDC_MODE_LIMITING) {
2982                 DP(NETIF_MSG_LINK,
2983                          "Setting LIMITING MODE\n");
2984                 bnx2x_cl45_write(bp, port,
2985                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2986                                ext_phy_addr,
2987                                MDIO_PMA_DEVAD,
2988                                MDIO_PMA_REG_ROM_VER2,
2989                                EDC_MODE_LIMITING);
2990         } else { /* LRM mode ( default )*/
2991
2992                 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
2993
2994                 /* Changing to LRM mode takes quite few seconds.
2995                 So do it only if current mode is limiting
2996                 ( default is LRM )*/
2997                 if (cur_limiting_mode != EDC_MODE_LIMITING)
2998                         return 0;
2999
3000                 bnx2x_cl45_write(bp, port,
3001                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3002                                ext_phy_addr,
3003                                MDIO_PMA_DEVAD,
3004                                MDIO_PMA_REG_LRM_MODE,
3005                                0);
3006                 bnx2x_cl45_write(bp, port,
3007                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3008                                ext_phy_addr,
3009                                MDIO_PMA_DEVAD,
3010                                MDIO_PMA_REG_ROM_VER2,
3011                                0x128);
3012                 bnx2x_cl45_write(bp, port,
3013                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3014                                ext_phy_addr,
3015                                MDIO_PMA_DEVAD,
3016                                MDIO_PMA_REG_MISC_CTRL0,
3017                                0x4008);
3018                 bnx2x_cl45_write(bp, port,
3019                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3020                                ext_phy_addr,
3021                                MDIO_PMA_DEVAD,
3022                                MDIO_PMA_REG_LRM_MODE,
3023                                0xaaaa);
3024         }
3025         return 0;
3026 }
3027
3028 static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
3029                                         u16 edc_mode)
3030 {
3031         struct bnx2x *bp = params->bp;
3032         u8 port = params->port;
3033         u16 phy_identifier;
3034         u16 rom_ver2_val;
3035         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3036
3037         bnx2x_cl45_read(bp, port,
3038                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3039                        ext_phy_addr,
3040                        MDIO_PMA_DEVAD,
3041                        MDIO_PMA_REG_PHY_IDENTIFIER,
3042                        &phy_identifier);
3043
3044         bnx2x_cl45_write(bp, port,
3045                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3046                        ext_phy_addr,
3047                        MDIO_PMA_DEVAD,
3048                        MDIO_PMA_REG_PHY_IDENTIFIER,
3049                        (phy_identifier & ~(1<<9)));
3050
3051         bnx2x_cl45_read(bp, port,
3052                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3053                       ext_phy_addr,
3054                       MDIO_PMA_DEVAD,
3055                       MDIO_PMA_REG_ROM_VER2,
3056                       &rom_ver2_val);
3057         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
3058         bnx2x_cl45_write(bp, port,
3059                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3060                        ext_phy_addr,
3061                        MDIO_PMA_DEVAD,
3062                        MDIO_PMA_REG_ROM_VER2,
3063                        (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
3064
3065         bnx2x_cl45_write(bp, port,
3066                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3067                        ext_phy_addr,
3068                        MDIO_PMA_DEVAD,
3069                        MDIO_PMA_REG_PHY_IDENTIFIER,
3070                        (phy_identifier | (1<<9)));
3071
3072         return 0;
3073 }
3074
3075
3076 static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
3077 {
3078         u8 val;
3079         struct bnx2x *bp = params->bp;
3080         u16 timeout;
3081         /* Initialization time after hot-plug may take up to 300ms for some
3082         phys type ( e.g. JDSU ) */
3083         for (timeout = 0; timeout < 60; timeout++) {
3084                 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
3085                     == 0) {
3086                         DP(NETIF_MSG_LINK, "SFP+ module initialization "
3087                                      "took %d ms\n", timeout * 5);
3088                         return 0;
3089                 }
3090                 msleep(5);
3091         }
3092         return -EINVAL;
3093 }
3094
3095 static void bnx2x_8727_power_module(struct bnx2x *bp,
3096                                   struct link_params *params,
3097                                   u8 ext_phy_addr, u8 is_power_up) {
3098         /* Make sure GPIOs are not using for LED mode */
3099         u16 val;
3100         u8 port = params->port;
3101         /*
3102          * In the GPIO register, bit 4 is use to detemine if the GPIOs are
3103          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
3104          * output
3105          * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
3106          * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
3107          * where the 1st bit is the over-current(only input), and 2nd bit is
3108          * for power( only output )
3109         */
3110
3111         /*
3112          * In case of NOC feature is disabled and power is up, set GPIO control
3113          *  as input to enable listening of over-current indication
3114          */
3115
3116         if (!(params->feature_config_flags &
3117               FEATURE_CONFIG_BCM8727_NOC) && is_power_up)
3118                 val = (1<<4);
3119         else
3120                 /*
3121                  * Set GPIO control to OUTPUT, and set the power bit
3122                  * to according to the is_power_up
3123                  */
3124                 val = ((!(is_power_up)) << 1);
3125
3126         bnx2x_cl45_write(bp, port,
3127                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3128                        ext_phy_addr,
3129                        MDIO_PMA_DEVAD,
3130                        MDIO_PMA_REG_8727_GPIO_CTRL,
3131                        val);
3132 }
3133
3134 static u8 bnx2x_sfp_module_detection(struct link_params *params)
3135 {
3136         struct bnx2x *bp = params->bp;
3137         u16 edc_mode;
3138         u8 rc = 0;
3139         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3140         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3141         u32 val = REG_RD(bp, params->shmem_base +
3142                              offsetof(struct shmem_region, dev_info.
3143                                      port_feature_config[params->port].config));
3144
3145         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
3146                  params->port);
3147
3148         if (bnx2x_get_edc_mode(params, &edc_mode) != 0) {
3149                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
3150                 return -EINVAL;
3151         } else if (bnx2x_verify_sfp_module(params) !=
3152                    0) {
3153                 /* check SFP+ module compatibility */
3154                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
3155                 rc = -EINVAL;
3156                 /* Turn on fault module-detected led */
3157                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
3158                                   MISC_REGISTERS_GPIO_HIGH,
3159                                   params->port);
3160                 if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
3161                     ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
3162                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
3163                         /* Shutdown SFP+ module */
3164                         DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
3165                         bnx2x_8727_power_module(bp, params,
3166                                               ext_phy_addr, 0);
3167                         return rc;
3168                 }
3169         } else {
3170                 /* Turn off fault module-detected led */
3171                 DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
3172                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
3173                                           MISC_REGISTERS_GPIO_LOW,
3174                                           params->port);
3175         }
3176
3177         /* power up the SFP module */
3178         if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
3179                 bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
3180
3181         /* Check and set limiting mode / LRM mode on 8726.
3182         On 8727 it is done automatically */
3183         if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
3184                 bnx2x_bcm8726_set_limiting_mode(params, edc_mode);
3185         else
3186                 bnx2x_bcm8727_set_limiting_mode(params, edc_mode);
3187         /*
3188          * Enable transmit for this module if the module is approved, or
3189          * if unapproved modules should also enable the Tx laser
3190          */
3191         if (rc == 0 ||
3192             (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
3193             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
3194                 bnx2x_sfp_set_transmitter(bp, params->port,
3195                                         ext_phy_type, ext_phy_addr, 1);
3196         else
3197                 bnx2x_sfp_set_transmitter(bp, params->port,
3198                                         ext_phy_type, ext_phy_addr, 0);
3199
3200         return rc;
3201 }
3202
3203 void bnx2x_handle_module_detect_int(struct link_params *params)
3204 {
3205         struct bnx2x *bp = params->bp;
3206         u32 gpio_val;
3207         u8 port = params->port;
3208
3209         /* Set valid module led off */
3210         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
3211                           MISC_REGISTERS_GPIO_HIGH,
3212                           params->port);
3213
3214         /* Get current gpio val refelecting module plugged in / out*/
3215         gpio_val = bnx2x_get_gpio(bp,  MISC_REGISTERS_GPIO_3, port);
3216
3217         /* Call the handling function in case module is detected */
3218         if (gpio_val == 0) {
3219
3220                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
3221                                       MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
3222                                       port);
3223
3224                 if (bnx2x_wait_for_sfp_module_initialized(params) ==
3225                     0)
3226                         bnx2x_sfp_module_detection(params);
3227                 else
3228                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
3229         } else {
3230                 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3231
3232                 u32 ext_phy_type =
3233                         XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3234                 u32 val = REG_RD(bp, params->shmem_base +
3235                                      offsetof(struct shmem_region, dev_info.
3236                                               port_feature_config[params->port].
3237                                               config));
3238
3239                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
3240                                       MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
3241                                       port);
3242                 /* Module was plugged out. */
3243                 /* Disable transmit for this module */
3244                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
3245                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
3246                         bnx2x_sfp_set_transmitter(bp, params->port,
3247                                                 ext_phy_type, ext_phy_addr, 0);
3248         }
3249 }
3250
3251 static void bnx2x_bcm807x_force_10G(struct link_params *params)
3252 {
3253         struct bnx2x *bp = params->bp;
3254         u8 port = params->port;
3255         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3256         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3257
3258         /* Force KR or KX */
3259         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3260                        MDIO_PMA_DEVAD,
3261                        MDIO_PMA_REG_CTRL,
3262                        0x2040);
3263         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3264                        MDIO_PMA_DEVAD,
3265                        MDIO_PMA_REG_10G_CTRL2,
3266                        0x000b);
3267         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3268                        MDIO_PMA_DEVAD,
3269                        MDIO_PMA_REG_BCM_CTRL,
3270                        0x0000);
3271         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3272                        MDIO_AN_DEVAD,
3273                        MDIO_AN_REG_CTRL,
3274                        0x0000);
3275 }
3276
3277 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
3278 {
3279         struct bnx2x *bp = params->bp;
3280         u8 port = params->port;
3281         u16 val;
3282         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3283         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3284
3285         bnx2x_cl45_read(bp, params->port,
3286                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
3287                       ext_phy_addr,
3288                       MDIO_PMA_DEVAD,
3289                       MDIO_PMA_REG_8073_CHIP_REV, &val);
3290
3291         if (val == 0) {
3292                 /* Mustn't set low power mode in 8073 A0 */
3293                 return;
3294         }
3295
3296         /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
3297         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3298                        MDIO_XS_DEVAD,
3299                        MDIO_XS_PLL_SEQUENCER, &val);
3300         val &= ~(1<<13);
3301         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3302                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3303
3304         /* PLL controls */
3305         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3306                        MDIO_XS_DEVAD, 0x805E, 0x1077);
3307         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3308                        MDIO_XS_DEVAD, 0x805D, 0x0000);
3309         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3310                        MDIO_XS_DEVAD, 0x805C, 0x030B);
3311         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3312                        MDIO_XS_DEVAD, 0x805B, 0x1240);
3313         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3314                        MDIO_XS_DEVAD, 0x805A, 0x2490);
3315
3316         /* Tx Controls */
3317         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3318                        MDIO_XS_DEVAD, 0x80A7, 0x0C74);
3319         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3320                        MDIO_XS_DEVAD, 0x80A6, 0x9041);
3321         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3322                        MDIO_XS_DEVAD, 0x80A5, 0x4640);
3323
3324         /* Rx Controls */
3325         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3326                        MDIO_XS_DEVAD, 0x80FE, 0x01C4);
3327         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3328                        MDIO_XS_DEVAD, 0x80FD, 0x9249);
3329         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3330                        MDIO_XS_DEVAD, 0x80FC, 0x2015);
3331
3332         /* Enable PLL sequencer  (use read-modify-write to set bit 13) */
3333         bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3334                        MDIO_XS_DEVAD,
3335                        MDIO_XS_PLL_SEQUENCER, &val);
3336         val |= (1<<13);
3337         bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3338                        MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3339 }
3340
3341 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
3342                                   struct link_vars *vars)
3343 {
3344         struct bnx2x *bp = params->bp;
3345         u16 cl37_val;
3346         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3347         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3348
3349         bnx2x_cl45_read(bp, params->port,
3350                       ext_phy_type,
3351                       ext_phy_addr,
3352                       MDIO_AN_DEVAD,
3353                       MDIO_AN_REG_CL37_FC_LD, &cl37_val);
3354
3355         cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3356         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3357
3358         if ((vars->ieee_fc &
3359             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
3360             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
3361                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
3362         }
3363         if ((vars->ieee_fc &
3364             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3365             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3366                 cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3367         }
3368         if ((vars->ieee_fc &
3369             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3370             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3371                 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3372         }
3373         DP(NETIF_MSG_LINK,
3374                  "Ext phy AN advertize cl37 0x%x\n", cl37_val);
3375
3376         bnx2x_cl45_write(bp, params->port,
3377                        ext_phy_type,
3378                        ext_phy_addr,
3379                        MDIO_AN_DEVAD,
3380                        MDIO_AN_REG_CL37_FC_LD, cl37_val);
3381         msleep(500);
3382 }
3383
3384 static void bnx2x_ext_phy_set_pause(struct link_params *params,
3385                                   struct link_vars *vars)
3386 {
3387         struct bnx2x *bp = params->bp;
3388         u16 val;
3389         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3390         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3391
3392         /* read modify write pause advertizing */
3393         bnx2x_cl45_read(bp, params->port,
3394                       ext_phy_type,
3395                       ext_phy_addr,
3396                       MDIO_AN_DEVAD,
3397                       MDIO_AN_REG_ADV_PAUSE, &val);
3398
3399         val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3400
3401         /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3402
3403         if ((vars->ieee_fc &
3404             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3405             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3406                 val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3407         }
3408         if ((vars->ieee_fc &
3409             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3410             MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3411                 val |=
3412                  MDIO_AN_REG_ADV_PAUSE_PAUSE;
3413         }
3414         DP(NETIF_MSG_LINK,
3415                  "Ext phy AN advertize 0x%x\n", val);
3416         bnx2x_cl45_write(bp, params->port,
3417                        ext_phy_type,
3418                        ext_phy_addr,
3419                        MDIO_AN_DEVAD,
3420                        MDIO_AN_REG_ADV_PAUSE, val);
3421 }
3422 static void bnx2x_set_preemphasis(struct link_params *params)
3423 {
3424         u16 bank, i = 0;
3425         struct bnx2x *bp = params->bp;
3426
3427         for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
3428               bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
3429                         CL45_WR_OVER_CL22(bp, params->port,
3430                                               params->phy_addr,
3431                                               bank,
3432                                               MDIO_RX0_RX_EQ_BOOST,
3433                                               params->xgxs_config_rx[i]);
3434         }
3435
3436         for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
3437                       bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
3438                         CL45_WR_OVER_CL22(bp, params->port,
3439                                               params->phy_addr,
3440                                               bank,
3441                                               MDIO_TX0_TX_DRIVER,
3442                                               params->xgxs_config_tx[i]);
3443         }
3444 }
3445
3446
3447 static void bnx2x_8481_set_led4(struct link_params *params,
3448                               u32 ext_phy_type, u8 ext_phy_addr)
3449 {
3450         struct bnx2x *bp = params->bp;
3451
3452         /* PHYC_CTL_LED_CTL */
3453         bnx2x_cl45_write(bp, params->port,
3454                        ext_phy_type,
3455                        ext_phy_addr,
3456                        MDIO_PMA_DEVAD,
3457                        MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482);
3458
3459         /* Unmask LED4 for 10G link */
3460         bnx2x_cl45_write(bp, params->port,
3461                        ext_phy_type,
3462                        ext_phy_addr,
3463                        MDIO_PMA_DEVAD,
3464                        MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6));
3465         /* 'Interrupt Mask' */
3466         bnx2x_cl45_write(bp, params->port,
3467                        ext_phy_type,
3468                        ext_phy_addr,
3469                        MDIO_AN_DEVAD,
3470                        0xFFFB, 0xFFFD);
3471 }
3472 static void bnx2x_8481_set_legacy_led_mode(struct link_params *params,
3473                                          u32 ext_phy_type, u8 ext_phy_addr)
3474 {
3475         struct bnx2x *bp = params->bp;
3476
3477         /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */
3478         /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */
3479         bnx2x_cl45_write(bp, params->port,
3480                        ext_phy_type,
3481                        ext_phy_addr,
3482                        MDIO_AN_DEVAD,
3483                        MDIO_AN_REG_8481_LEGACY_SHADOW,
3484                        (1<<15) | (0xd << 10) | (0xc<<4) | 0xe);
3485 }
3486
3487 static void bnx2x_8481_set_10G_led_mode(struct link_params *params,
3488                                       u32 ext_phy_type, u8 ext_phy_addr)
3489 {
3490         struct bnx2x *bp = params->bp;
3491         u16 val1;
3492
3493         /* LED1 (10G Link) */
3494         /* Enable continuse based on source 7(10G-link) */
3495         bnx2x_cl45_read(bp, params->port,
3496                        ext_phy_type,
3497                        ext_phy_addr,
3498                        MDIO_PMA_DEVAD,
3499                        MDIO_PMA_REG_8481_LINK_SIGNAL,
3500                        &val1);
3501         /* Set bit 2 to 0, and bits [1:0] to 10 */
3502         val1 &= ~((1<<0) | (1<<2)); /* Clear bits 0,2*/
3503         val1 |= (1<<1); /* Set bit 1 */
3504
3505         bnx2x_cl45_write(bp, params->port,
3506                        ext_phy_type,
3507                        ext_phy_addr,
3508                        MDIO_PMA_DEVAD,
3509                        MDIO_PMA_REG_8481_LINK_SIGNAL,
3510                        val1);
3511
3512         /* Unmask LED1 for 10G link */
3513         bnx2x_cl45_read(bp, params->port,
3514                       ext_phy_type,
3515                       ext_phy_addr,
3516                       MDIO_PMA_DEVAD,
3517                       MDIO_PMA_REG_8481_LED1_MASK,
3518                       &val1);
3519         /* Set bit 2 to 0, and bits [1:0] to 10 */
3520         val1 |= (1<<7);
3521         bnx2x_cl45_write(bp, params->port,
3522                        ext_phy_type,
3523                        ext_phy_addr,
3524                        MDIO_PMA_DEVAD,
3525                        MDIO_PMA_REG_8481_LED1_MASK,
3526                        val1);
3527
3528         /* LED2 (1G/100/10G Link) */
3529         /* Mask LED2 for 10G link */
3530         bnx2x_cl45_write(bp, params->port,
3531                        ext_phy_type,
3532                        ext_phy_addr,
3533                        MDIO_PMA_DEVAD,
3534                        MDIO_PMA_REG_8481_LED2_MASK,
3535                        0);
3536
3537         /* LED3 (10G/1G/100/10G Activity) */
3538         bnx2x_cl45_read(bp, params->port,
3539                       ext_phy_type,
3540                       ext_phy_addr,
3541                       MDIO_PMA_DEVAD,
3542                       MDIO_PMA_REG_8481_LINK_SIGNAL,
3543                       &val1);
3544         /* Enable blink based on source 4(Activity) */
3545         val1 &= ~((1<<7) | (1<<8)); /* Clear bits 7,8 */
3546         val1 |= (1<<6); /* Set only bit 6 */
3547         bnx2x_cl45_write(bp, params->port,
3548                        ext_phy_type,
3549                        ext_phy_addr,
3550                        MDIO_PMA_DEVAD,
3551                        MDIO_PMA_REG_8481_LINK_SIGNAL,
3552                        val1);
3553
3554         bnx2x_cl45_read(bp, params->port,
3555                       ext_phy_type,
3556                       ext_phy_addr,
3557                       MDIO_PMA_DEVAD,
3558                       MDIO_PMA_REG_8481_LED3_MASK,
3559                       &val1);
3560         val1 |= (1<<4); /* Unmask LED3 for 10G link */
3561         bnx2x_cl45_write(bp, params->port,
3562                        ext_phy_type,
3563                        ext_phy_addr,
3564                        MDIO_PMA_DEVAD,
3565                        MDIO_PMA_REG_8481_LED3_MASK,
3566                        val1);
3567 }
3568
3569
3570 static void bnx2x_init_internal_phy(struct link_params *params,
3571                                   struct link_vars *vars,
3572                                   u8 enable_cl73)
3573 {
3574         struct bnx2x *bp = params->bp;
3575
3576         if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
3577                 if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
3578                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3579                     (params->feature_config_flags &
3580                      FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
3581                         bnx2x_set_preemphasis(params);
3582
3583                 /* forced speed requested? */
3584                 if (vars->line_speed != SPEED_AUTO_NEG ||
3585                     ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
3586                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3587                           params->loopback_mode == LOOPBACK_EXT)) {
3588                         DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3589
3590                         /* disable autoneg */
3591                         bnx2x_set_autoneg(params, vars, 0);
3592
3593                         /* program speed and duplex */
3594                         bnx2x_program_serdes(params, vars);
3595
3596                 } else { /* AN_mode */
3597                         DP(NETIF_MSG_LINK, "not SGMII, AN\n");
3598
3599                         /* AN enabled */
3600                         bnx2x_set_brcm_cl37_advertisment(params);
3601
3602                         /* program duplex & pause advertisement (for aneg) */
3603                         bnx2x_set_ieee_aneg_advertisment(params,
3604                                                        vars->ieee_fc);
3605
3606                         /* enable autoneg */
3607                         bnx2x_set_autoneg(params, vars, enable_cl73);
3608
3609                         /* enable and restart AN */
3610                         bnx2x_restart_autoneg(params, enable_cl73);
3611                 }
3612
3613         } else { /* SGMII mode */
3614                 DP(NETIF_MSG_LINK, "SGMII\n");
3615
3616                 bnx2x_initialize_sgmii_process(params, vars);
3617         }
3618 }
3619
3620 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
3621 {
3622         struct bnx2x *bp = params->bp;
3623         u32 ext_phy_type;
3624         u8 ext_phy_addr;
3625         u16 cnt;
3626         u16 ctrl = 0;
3627         u16 val = 0;
3628         u8 rc = 0;
3629
3630         if (vars->phy_flags & PHY_XGXS_FLAG) {
3631                 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3632
3633                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3634                 /* Make sure that the soft reset is off (expect for the 8072:
3635                  * due to the lock, it will be done inside the specific
3636                  * handling)
3637                  */
3638                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3639                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3640                    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
3641                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3642                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3643                         /* Wait for soft reset to get cleared upto 1 sec */
3644                         for (cnt = 0; cnt < 1000; cnt++) {
3645                                 bnx2x_cl45_read(bp, params->port,
3646                                               ext_phy_type,
3647                                               ext_phy_addr,
3648                                               MDIO_PMA_DEVAD,
3649                                               MDIO_PMA_REG_CTRL, &ctrl);
3650                                 if (!(ctrl & (1<<15)))
3651                                         break;
3652                                 msleep(1);
3653                         }
3654                         DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3655                                  ctrl, cnt);
3656                 }
3657
3658                 switch (ext_phy_type) {
3659                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3660                         break;
3661
3662                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3663                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
3664
3665                         bnx2x_cl45_write(bp, params->port,
3666                                        ext_phy_type,
3667                                        ext_phy_addr,
3668                                        MDIO_PMA_DEVAD,
3669                                        MDIO_PMA_REG_MISC_CTRL,
3670                                        0x8288);
3671                         bnx2x_cl45_write(bp, params->port,
3672                                        ext_phy_type,
3673                                        ext_phy_addr,
3674                                        MDIO_PMA_DEVAD,
3675                                        MDIO_PMA_REG_PHY_IDENTIFIER,
3676                                        0x7fbf);
3677                         bnx2x_cl45_write(bp, params->port,
3678                                        ext_phy_type,
3679                                        ext_phy_addr,
3680                                        MDIO_PMA_DEVAD,
3681                                        MDIO_PMA_REG_CMU_PLL_BYPASS,
3682                                        0x0100);
3683                         bnx2x_cl45_write(bp, params->port,
3684                                        ext_phy_type,
3685                                        ext_phy_addr,
3686                                        MDIO_WIS_DEVAD,
3687                                        MDIO_WIS_REG_LASI_CNTL, 0x1);
3688
3689                         /* BCM8705 doesn't have microcode, hence the 0 */
3690                         bnx2x_save_spirom_version(bp, params->port,
3691                                                 params->shmem_base, 0);
3692                         break;
3693
3694                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3695                         /* Wait until fw is loaded */
3696                         for (cnt = 0; cnt < 100; cnt++) {
3697                                 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3698                                               ext_phy_addr, MDIO_PMA_DEVAD,
3699                                               MDIO_PMA_REG_ROM_VER1, &val);
3700                                 if (val)
3701                                         break;
3702                                 msleep(10);
3703                         }
3704                         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3705                                 "after %d ms\n", cnt);
3706                         if ((params->feature_config_flags &
3707                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3708                                 u8 i;
3709                                 u16 reg;
3710                                 for (i = 0; i < 4; i++) {
3711                                         reg = MDIO_XS_8706_REG_BANK_RX0 +
3712                                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
3713                                                    MDIO_XS_8706_REG_BANK_RX0);
3714                                         bnx2x_cl45_read(bp, params->port,
3715                                                       ext_phy_type,
3716                                                       ext_phy_addr,
3717                                                       MDIO_XS_DEVAD,
3718                                                       reg, &val);
3719                                         /* Clear first 3 bits of the control */
3720                                         val &= ~0x7;
3721                                         /* Set control bits according to
3722                                         configuation */
3723                                         val |= (params->xgxs_config_rx[i] &
3724                                                 0x7);
3725                                         DP(NETIF_MSG_LINK, "Setting RX"
3726                                                  "Equalizer to BCM8706 reg 0x%x"
3727                                                  " <-- val 0x%x\n", reg, val);
3728                                         bnx2x_cl45_write(bp, params->port,
3729                                                        ext_phy_type,
3730                                                        ext_phy_addr,
3731                                                        MDIO_XS_DEVAD,
3732                                                        reg, val);
3733                                 }
3734                         }
3735                         /* Force speed */
3736                         /* First enable LASI */
3737                         bnx2x_cl45_write(bp, params->port,
3738                                        ext_phy_type,
3739                                        ext_phy_addr,
3740                                        MDIO_PMA_DEVAD,
3741                                        MDIO_PMA_REG_RX_ALARM_CTRL,
3742                                        0x0400);
3743                         bnx2x_cl45_write(bp, params->port,
3744                                        ext_phy_type,
3745                                        ext_phy_addr,
3746                                        MDIO_PMA_DEVAD,
3747                                        MDIO_PMA_REG_LASI_CTRL, 0x0004);
3748
3749                         if (params->req_line_speed == SPEED_10000) {
3750                                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3751
3752                                 bnx2x_cl45_write(bp, params->port,
3753                                                ext_phy_type,
3754                                                ext_phy_addr,
3755                                                MDIO_PMA_DEVAD,
3756                                                MDIO_PMA_REG_DIGITAL_CTRL,
3757                                                0x400);
3758                         } else {
3759                                 /* Force 1Gbps using autoneg with 1G
3760                                 advertisment */
3761
3762                                 /* Allow CL37 through CL73 */
3763                                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3764                                 bnx2x_cl45_write(bp, params->port,
3765                                                ext_phy_type,
3766                                                ext_phy_addr,
3767                                                MDIO_AN_DEVAD,
3768                                                MDIO_AN_REG_CL37_CL73,
3769                                                0x040c);
3770
3771                                 /* Enable Full-Duplex advertisment on CL37 */
3772                                 bnx2x_cl45_write(bp, params->port,
3773                                                ext_phy_type,
3774                                                ext_phy_addr,
3775                                                MDIO_AN_DEVAD,
3776                                                MDIO_AN_REG_CL37_FC_LP,
3777                                                0x0020);
3778                                 /* Enable CL37 AN */
3779                                 bnx2x_cl45_write(bp, params->port,
3780                                                ext_phy_type,
3781                                                ext_phy_addr,
3782                                                MDIO_AN_DEVAD,
3783                                                MDIO_AN_REG_CL37_AN,
3784                                                0x1000);
3785                                 /* 1G support */
3786                                 bnx2x_cl45_write(bp, params->port,
3787                                                ext_phy_type,
3788                                                ext_phy_addr,
3789                                                MDIO_AN_DEVAD,
3790                                                MDIO_AN_REG_ADV, (1<<5));
3791
3792                                 /* Enable clause 73 AN */
3793                                 bnx2x_cl45_write(bp, params->port,
3794                                                ext_phy_type,
3795                                                ext_phy_addr,
3796                                                MDIO_AN_DEVAD,
3797                                                MDIO_AN_REG_CTRL,
3798                                                0x1200);
3799
3800                         }
3801                         bnx2x_save_bcm_spirom_ver(bp, params->port,
3802                                                 ext_phy_type,
3803                                                 ext_phy_addr,
3804                                                 params->shmem_base);
3805                         break;
3806                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3807                         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3808                         bnx2x_bcm8726_external_rom_boot(params);
3809
3810                         /* Need to call module detected on initialization since
3811                         the module detection triggered by actual module
3812                         insertion might occur before driver is loaded, and when
3813                         driver is loaded, it reset all registers, including the
3814                         transmitter */
3815                         bnx2x_sfp_module_detection(params);
3816
3817                         /* Set Flow control */
3818                         bnx2x_ext_phy_set_pause(params, vars);
3819                         if (params->req_line_speed == SPEED_1000) {
3820                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3821                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3822                                                ext_phy_addr, MDIO_PMA_DEVAD,
3823                                                MDIO_PMA_REG_CTRL, 0x40);
3824                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3825                                                ext_phy_addr, MDIO_PMA_DEVAD,
3826                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
3827                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3828                                                ext_phy_addr, MDIO_PMA_DEVAD,
3829                                                MDIO_PMA_REG_LASI_CTRL, 0x5);
3830                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3831                                                ext_phy_addr, MDIO_PMA_DEVAD,
3832                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3833                                                0x400);
3834                         } else if ((params->req_line_speed ==
3835                                     SPEED_AUTO_NEG) &&
3836                                    ((params->speed_cap_mask &
3837                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3838                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3839                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3840                                                ext_phy_addr, MDIO_AN_DEVAD,
3841                                                MDIO_AN_REG_ADV, 0x20);
3842                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3843                                                ext_phy_addr, MDIO_AN_DEVAD,
3844                                                MDIO_AN_REG_CL37_CL73, 0x040c);
3845                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3846                                                ext_phy_addr, MDIO_AN_DEVAD,
3847                                                MDIO_AN_REG_CL37_FC_LD, 0x0020);
3848                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3849                                                ext_phy_addr, MDIO_AN_DEVAD,
3850                                                MDIO_AN_REG_CL37_AN, 0x1000);
3851                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3852                                                ext_phy_addr, MDIO_AN_DEVAD,
3853                                                MDIO_AN_REG_CTRL, 0x1200);
3854
3855                                 /* Enable RX-ALARM control to receive
3856                                 interrupt for 1G speed change */
3857                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3858                                                ext_phy_addr, MDIO_PMA_DEVAD,
3859                                                MDIO_PMA_REG_LASI_CTRL, 0x4);
3860                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3861                                                ext_phy_addr, MDIO_PMA_DEVAD,
3862                                                MDIO_PMA_REG_RX_ALARM_CTRL,
3863                                                0x400);
3864
3865                         } else { /* Default 10G. Set only LASI control */
3866                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3867                                                ext_phy_addr, MDIO_PMA_DEVAD,
3868                                                MDIO_PMA_REG_LASI_CTRL, 1);
3869                         }
3870
3871                         /* Set TX PreEmphasis if needed */
3872                         if ((params->feature_config_flags &
3873                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3874                                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3875                                          "TX_CTRL2 0x%x\n",
3876                                          params->xgxs_config_tx[0],
3877                                          params->xgxs_config_tx[1]);
3878                                 bnx2x_cl45_write(bp, params->port,
3879                                                ext_phy_type,
3880                                                ext_phy_addr,
3881                                                MDIO_PMA_DEVAD,
3882                                                MDIO_PMA_REG_8726_TX_CTRL1,
3883                                                params->xgxs_config_tx[0]);
3884
3885                                 bnx2x_cl45_write(bp, params->port,
3886                                                ext_phy_type,
3887                                                ext_phy_addr,
3888                                                MDIO_PMA_DEVAD,
3889                                                MDIO_PMA_REG_8726_TX_CTRL2,
3890                                                params->xgxs_config_tx[1]);
3891                         }
3892                         break;
3893                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3894                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3895                 {
3896                         u16 tmp1;
3897                         u16 rx_alarm_ctrl_val;
3898                         u16 lasi_ctrl_val;
3899                         if (ext_phy_type ==
3900                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3901                                 rx_alarm_ctrl_val = 0x400;
3902                                 lasi_ctrl_val = 0x0004;
3903                         } else {
3904                                 rx_alarm_ctrl_val = (1<<2);
3905                                 lasi_ctrl_val = 0x0004;
3906                         }
3907
3908                         /* enable LASI */
3909                         bnx2x_cl45_write(bp, params->port,
3910                                    ext_phy_type,
3911                                    ext_phy_addr,
3912                                    MDIO_PMA_DEVAD,
3913                                    MDIO_PMA_REG_RX_ALARM_CTRL,
3914                                    rx_alarm_ctrl_val);
3915
3916                         bnx2x_cl45_write(bp, params->port,
3917                                        ext_phy_type,
3918                                        ext_phy_addr,
3919                                        MDIO_PMA_DEVAD,
3920                                        MDIO_PMA_REG_LASI_CTRL,
3921                                        lasi_ctrl_val);
3922
3923                         bnx2x_8073_set_pause_cl37(params, vars);
3924
3925                         if (ext_phy_type ==
3926                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)
3927                                 bnx2x_bcm8072_external_rom_boot(params);
3928                         else
3929                                 /* In case of 8073 with long xaui lines,
3930                                 don't set the 8073 xaui low power*/
3931                                 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3932
3933                         bnx2x_cl45_read(bp, params->port,
3934                                       ext_phy_type,
3935                                       ext_phy_addr,
3936                                       MDIO_PMA_DEVAD,
3937                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
3938                                       &tmp1);
3939
3940                         bnx2x_cl45_read(bp, params->port,
3941                                       ext_phy_type,
3942                                       ext_phy_addr,
3943                                       MDIO_PMA_DEVAD,
3944                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
3945
3946                         DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3947                                              "0x%x\n", tmp1);
3948
3949                         /* If this is forced speed, set to KR or KX
3950                          * (all other are not supported)
3951                          */
3952                         if (params->loopback_mode == LOOPBACK_EXT) {
3953                                 bnx2x_bcm807x_force_10G(params);
3954                                 DP(NETIF_MSG_LINK,
3955                                         "Forced speed 10G on 807X\n");
3956                                 break;
3957                         } else {
3958                                 bnx2x_cl45_write(bp, params->port,
3959                                                ext_phy_type, ext_phy_addr,
3960                                                MDIO_PMA_DEVAD,
3961                                                MDIO_PMA_REG_BCM_CTRL,
3962                                                0x0002);
3963                         }
3964                         if (params->req_line_speed != SPEED_AUTO_NEG) {
3965                                 if (params->req_line_speed == SPEED_10000) {
3966                                         val = (1<<7);
3967                                 } else if (params->req_line_speed ==
3968                                            SPEED_2500) {
3969                                         val = (1<<5);
3970                                         /* Note that 2.5G works only
3971                                         when used with 1G advertisment */
3972                                 } else
3973                                         val = (1<<5);
3974                         } else {
3975
3976                                 val = 0;
3977                                 if (params->speed_cap_mask &
3978                                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3979                                         val |= (1<<7);
3980
3981                                 /* Note that 2.5G works only when
3982                                 used with 1G advertisment */
3983                                 if (params->speed_cap_mask &
3984                                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3985                                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3986                                         val |= (1<<5);
3987                                 DP(NETIF_MSG_LINK,
3988                                          "807x autoneg val = 0x%x\n", val);
3989                         }
3990
3991                         bnx2x_cl45_write(bp, params->port,
3992                                        ext_phy_type,
3993                                        ext_phy_addr,
3994                                        MDIO_AN_DEVAD,
3995                                        MDIO_AN_REG_ADV, val);
3996                         if (ext_phy_type ==
3997                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3998                                 bnx2x_cl45_read(bp, params->port,
3999                                               ext_phy_type,
4000                                               ext_phy_addr,
4001                                               MDIO_AN_DEVAD,
4002                                               MDIO_AN_REG_8073_2_5G, &tmp1);
4003
4004                                 if (((params->speed_cap_mask &
4005                                       PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
4006                                      (params->req_line_speed ==
4007                                       SPEED_AUTO_NEG)) ||
4008                                     (params->req_line_speed ==
4009                                      SPEED_2500)) {
4010                                         u16 phy_ver;
4011                                         /* Allow 2.5G for A1 and above */
4012                                         bnx2x_cl45_read(bp, params->port,
4013                                          PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4014                                          ext_phy_addr,
4015                                          MDIO_PMA_DEVAD,
4016                                          MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
4017                                         DP(NETIF_MSG_LINK, "Add 2.5G\n");
4018                                         if (phy_ver > 0)
4019                                                 tmp1 |= 1;
4020                                         else
4021                                                 tmp1 &= 0xfffe;
4022                                 } else {
4023                                         DP(NETIF_MSG_LINK, "Disable 2.5G\n");
4024                                         tmp1 &= 0xfffe;
4025                                 }
4026
4027                                 bnx2x_cl45_write(bp, params->port,
4028                                                ext_phy_type,
4029                                                ext_phy_addr,
4030                                                MDIO_AN_DEVAD,
4031                                                MDIO_AN_REG_8073_2_5G, tmp1);
4032                         }
4033
4034                         /* Add support for CL37 (passive mode) II */
4035
4036                         bnx2x_cl45_read(bp, params->port,
4037                                        ext_phy_type,
4038                                        ext_phy_addr,
4039                                        MDIO_AN_DEVAD,
4040                                        MDIO_AN_REG_CL37_FC_LD,
4041                                        &tmp1);
4042
4043                         bnx2x_cl45_write(bp, params->port,
4044                                        ext_phy_type,
4045                                        ext_phy_addr,
4046                                        MDIO_AN_DEVAD,
4047                                        MDIO_AN_REG_CL37_FC_LD, (tmp1 |
4048                                        ((params->req_duplex == DUPLEX_FULL) ?
4049                                        0x20 : 0x40)));
4050
4051                         /* Add support for CL37 (passive mode) III */
4052                         bnx2x_cl45_write(bp, params->port,
4053                                        ext_phy_type,
4054                                        ext_phy_addr,
4055                                        MDIO_AN_DEVAD,
4056                                        MDIO_AN_REG_CL37_AN, 0x1000);
4057
4058                         if (ext_phy_type ==
4059                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4060                                 /* The SNR will improve about 2db by changing
4061                                 BW and FEE main tap. Rest commands are executed
4062                                 after link is up*/
4063                                 /*Change FFE main cursor to 5 in EDC register*/
4064                                 if (bnx2x_8073_is_snr_needed(params))
4065                                         bnx2x_cl45_write(bp, params->port,
4066                                                     ext_phy_type,
4067                                                     ext_phy_addr,
4068                                                     MDIO_PMA_DEVAD,
4069                                                     MDIO_PMA_REG_EDC_FFE_MAIN,
4070                                                     0xFB0C);
4071
4072                                 /* Enable FEC (Forware Error Correction)
4073                                 Request in the AN */
4074                                 bnx2x_cl45_read(bp, params->port,
4075                                               ext_phy_type,
4076                                               ext_phy_addr,
4077                                               MDIO_AN_DEVAD,
4078                                               MDIO_AN_REG_ADV2, &tmp1);
4079
4080                                 tmp1 |= (1<<15);
4081
4082                                 bnx2x_cl45_write(bp, params->port,
4083                                                ext_phy_type,
4084                                                ext_phy_addr,
4085                                                MDIO_AN_DEVAD,
4086                                                MDIO_AN_REG_ADV2, tmp1);
4087
4088                         }
4089
4090                         bnx2x_ext_phy_set_pause(params, vars);
4091
4092                         /* Restart autoneg */
4093                         msleep(500);
4094                         bnx2x_cl45_write(bp, params->port,
4095                                        ext_phy_type,
4096                                        ext_phy_addr,
4097                                        MDIO_AN_DEVAD,
4098                                        MDIO_AN_REG_CTRL, 0x1200);
4099                         DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
4100                            "Advertise 1G=%x, 10G=%x\n",
4101                            ((val & (1<<5)) > 0),
4102                            ((val & (1<<7)) > 0));
4103                         break;
4104                 }
4105
4106                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4107                 {
4108                         u16 tmp1;
4109                         u16 rx_alarm_ctrl_val;
4110                         u16 lasi_ctrl_val;
4111
4112                         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
4113
4114                         u16 mod_abs;
4115                         rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
4116                         lasi_ctrl_val = 0x0004;
4117
4118                         DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
4119                         /* enable LASI */
4120                         bnx2x_cl45_write(bp, params->port,
4121                                        ext_phy_type,
4122                                        ext_phy_addr,
4123                                        MDIO_PMA_DEVAD,
4124                                        MDIO_PMA_REG_RX_ALARM_CTRL,
4125                                        rx_alarm_ctrl_val);
4126
4127                         bnx2x_cl45_write(bp, params->port,
4128                                        ext_phy_type,
4129                                        ext_phy_addr,
4130                                        MDIO_PMA_DEVAD,
4131                                        MDIO_PMA_REG_LASI_CTRL,
4132                                        lasi_ctrl_val);
4133
4134                         /* Initially configure  MOD_ABS to interrupt when
4135                         module is presence( bit 8) */
4136                         bnx2x_cl45_read(bp, params->port,
4137                                       ext_phy_type,
4138                                       ext_phy_addr,
4139                                       MDIO_PMA_DEVAD,
4140                                       MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4141                         /* Set EDC off by setting OPTXLOS signal input to low
4142                         (bit 9).
4143                         When the EDC is off it locks onto a reference clock and
4144                         avoids becoming 'lost'.*/
4145                         mod_abs &= ~((1<<8) | (1<<9));
4146                         bnx2x_cl45_write(bp, params->port,
4147                                        ext_phy_type,
4148                                        ext_phy_addr,
4149                                        MDIO_PMA_DEVAD,
4150                                        MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4151
4152                         /* Make MOD_ABS give interrupt on change */
4153                         bnx2x_cl45_read(bp, params->port,
4154                                       ext_phy_type,
4155                                       ext_phy_addr,
4156                                       MDIO_PMA_DEVAD,
4157                                       MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4158                                       &val);
4159                         val |= (1<<12);
4160                         bnx2x_cl45_write(bp, params->port,
4161                                        ext_phy_type,
4162                                        ext_phy_addr,
4163                                        MDIO_PMA_DEVAD,
4164                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4165                                        val);
4166
4167                         /* Set 8727 GPIOs to input to allow reading from the
4168                         8727 GPIO0 status which reflect SFP+ module
4169                         over-current */
4170
4171                         bnx2x_cl45_read(bp, params->port,
4172                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4173                                        ext_phy_addr,
4174                                        MDIO_PMA_DEVAD,
4175                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4176                                        &val);
4177                         val &= 0xff8f; /* Reset bits 4-6 */
4178                         bnx2x_cl45_write(bp, params->port,
4179                                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4180                                        ext_phy_addr,
4181                                        MDIO_PMA_DEVAD,
4182                                        MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4183                                        val);
4184
4185                         bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
4186                         bnx2x_bcm8073_set_xaui_low_power_mode(params);
4187
4188                         bnx2x_cl45_read(bp, params->port,
4189                                       ext_phy_type,
4190                                       ext_phy_addr,
4191                                       MDIO_PMA_DEVAD,
4192                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
4193                                       &tmp1);
4194
4195                         bnx2x_cl45_read(bp, params->port,
4196                                       ext_phy_type,
4197                                       ext_phy_addr,
4198                                       MDIO_PMA_DEVAD,
4199                                       MDIO_PMA_REG_RX_ALARM, &tmp1);
4200
4201                         /* Set option 1G speed */
4202                         if (params->req_line_speed == SPEED_1000) {
4203
4204                                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
4205                                 bnx2x_cl45_write(bp, params->port,
4206                                                ext_phy_type,
4207                                                ext_phy_addr,
4208                                                MDIO_PMA_DEVAD,
4209                                                MDIO_PMA_REG_CTRL, 0x40);
4210                                 bnx2x_cl45_write(bp, params->port,
4211                                                ext_phy_type,
4212                                                ext_phy_addr,
4213                                                MDIO_PMA_DEVAD,
4214                                                MDIO_PMA_REG_10G_CTRL2, 0xD);
4215                                 bnx2x_cl45_read(bp, params->port,
4216                                       ext_phy_type,
4217                                       ext_phy_addr,
4218                                       MDIO_PMA_DEVAD,
4219                                       MDIO_PMA_REG_10G_CTRL2, &tmp1);
4220                                 DP(NETIF_MSG_LINK, "1.7 = 0x%x \n", tmp1);
4221
4222                         } else if ((params->req_line_speed ==
4223                                     SPEED_AUTO_NEG) &&
4224                                    ((params->speed_cap_mask &
4225                                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
4226
4227                                 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
4228                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4229                                                ext_phy_addr, MDIO_AN_DEVAD,
4230                                                MDIO_PMA_REG_8727_MISC_CTRL, 0);
4231                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4232                                                ext_phy_addr, MDIO_AN_DEVAD,
4233                                                MDIO_AN_REG_CL37_AN, 0x1300);
4234                         } else {
4235                                 /* Since the 8727 has only single reset pin,
4236                                 need to set the 10G registers although it is
4237                                 default */
4238                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4239                                                ext_phy_addr, MDIO_AN_DEVAD,
4240                                                MDIO_AN_REG_CTRL, 0x0020);
4241                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4242                                                ext_phy_addr, MDIO_AN_DEVAD,
4243                                                0x7, 0x0100);
4244                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4245                                                ext_phy_addr, MDIO_PMA_DEVAD,
4246                                                MDIO_PMA_REG_CTRL, 0x2040);
4247                                 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4248                                                ext_phy_addr, MDIO_PMA_DEVAD,
4249                                                MDIO_PMA_REG_10G_CTRL2, 0x0008);
4250                         }
4251
4252                         /* Set 2-wire transfer rate to 400Khz since 100Khz
4253                         is not operational */
4254                         bnx2x_cl45_write(bp, params->port,
4255                                        ext_phy_type,
4256                                        ext_phy_addr,
4257                                        MDIO_PMA_DEVAD,
4258                                        MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
4259                                        0xa101);
4260
4261                         /* Set TX PreEmphasis if needed */
4262                         if ((params->feature_config_flags &
4263                              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
4264                                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
4265                                          "TX_CTRL2 0x%x\n",
4266                                          params->xgxs_config_tx[0],
4267                                          params->xgxs_config_tx[1]);
4268                                 bnx2x_cl45_write(bp, params->port,
4269                                                ext_phy_type,
4270                                                ext_phy_addr,
4271                                                MDIO_PMA_DEVAD,
4272                                                MDIO_PMA_REG_8727_TX_CTRL1,
4273                                                params->xgxs_config_tx[0]);
4274
4275                                 bnx2x_cl45_write(bp, params->port,
4276                                                ext_phy_type,
4277                                                ext_phy_addr,
4278                                                MDIO_PMA_DEVAD,
4279                                                MDIO_PMA_REG_8727_TX_CTRL2,
4280                                                params->xgxs_config_tx[1]);
4281                         }
4282
4283                         break;
4284                 }
4285
4286                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4287                 {
4288                         u16 fw_ver1, fw_ver2;
4289                         DP(NETIF_MSG_LINK,
4290                                 "Setting the SFX7101 LASI indication\n");
4291
4292                         bnx2x_cl45_write(bp, params->port,
4293                                        ext_phy_type,
4294                                        ext_phy_addr,
4295                                        MDIO_PMA_DEVAD,
4296                                        MDIO_PMA_REG_LASI_CTRL, 0x1);
4297                         DP(NETIF_MSG_LINK,
4298                           "Setting the SFX7101 LED to blink on traffic\n");
4299                         bnx2x_cl45_write(bp, params->port,
4300                                        ext_phy_type,
4301                                        ext_phy_addr,
4302                                        MDIO_PMA_DEVAD,
4303                                        MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
4304
4305                         bnx2x_ext_phy_set_pause(params, vars);
4306                         /* Restart autoneg */
4307                         bnx2x_cl45_read(bp, params->port,
4308                                       ext_phy_type,
4309                                       ext_phy_addr,
4310                                       MDIO_AN_DEVAD,
4311                                       MDIO_AN_REG_CTRL, &val);
4312                         val |= 0x200;
4313                         bnx2x_cl45_write(bp, params->port,
4314                                        ext_phy_type,
4315                                        ext_phy_addr,
4316                                        MDIO_AN_DEVAD,
4317                                        MDIO_AN_REG_CTRL, val);
4318
4319                         /* Save spirom version */
4320                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4321                                       ext_phy_addr, MDIO_PMA_DEVAD,
4322                                       MDIO_PMA_REG_7101_VER1, &fw_ver1);
4323
4324                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4325                                       ext_phy_addr, MDIO_PMA_DEVAD,
4326                                       MDIO_PMA_REG_7101_VER2, &fw_ver2);
4327
4328                         bnx2x_save_spirom_version(params->bp, params->port,
4329                                                 params->shmem_base,
4330                                                 (u32)(fw_ver1<<16 | fw_ver2));
4331                         break;
4332                 }
4333                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
4334                         /* This phy uses the NIG latch mechanism since link
4335                                 indication arrives through its LED4 and not via
4336                                 its LASI signal, so we get steady signal
4337                                 instead of clear on read */
4338                         bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
4339                                     1 << NIG_LATCH_BC_ENABLE_MI_INT);
4340
4341                         bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
4342                         if (params->req_line_speed == SPEED_AUTO_NEG) {
4343
4344                                 u16 autoneg_val, an_1000_val, an_10_100_val;
4345                                 /* set 1000 speed advertisement */
4346                                 bnx2x_cl45_read(bp, params->port,
4347                                               ext_phy_type,
4348                                               ext_phy_addr,
4349                                               MDIO_AN_DEVAD,
4350                                               MDIO_AN_REG_8481_1000T_CTRL,
4351                                               &an_1000_val);
4352
4353                                 if (params->speed_cap_mask &
4354                                     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
4355                                         an_1000_val |= (1<<8);
4356                                         if (params->req_duplex == DUPLEX_FULL)
4357                                                 an_1000_val |= (1<<9);
4358                                         DP(NETIF_MSG_LINK, "Advertising 1G\n");
4359                                 } else
4360                                         an_1000_val &= ~((1<<8) | (1<<9));
4361
4362                                 bnx2x_cl45_write(bp, params->port,
4363                                                ext_phy_type,
4364                                                ext_phy_addr,
4365                                                MDIO_AN_DEVAD,
4366                                                MDIO_AN_REG_8481_1000T_CTRL,
4367                                                an_1000_val);
4368
4369                                 /* set 100 speed advertisement */
4370                                 bnx2x_cl45_read(bp, params->port,
4371                                               ext_phy_type,
4372                                               ext_phy_addr,
4373                                               MDIO_AN_DEVAD,
4374                                               MDIO_AN_REG_8481_LEGACY_AN_ADV,
4375                                               &an_10_100_val);
4376
4377                                 if (params->speed_cap_mask &
4378                                  (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
4379                                   PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) {
4380                                         an_10_100_val |= (1<<7);
4381                                         if (params->req_duplex == DUPLEX_FULL)
4382                                                 an_10_100_val |= (1<<8);
4383                                         DP(NETIF_MSG_LINK,
4384                                                 "Advertising 100M\n");
4385                                 } else
4386                                         an_10_100_val &= ~((1<<7) | (1<<8));
4387
4388                                 /* set 10 speed advertisement */
4389                                 if (params->speed_cap_mask &
4390                                   (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
4391                                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) {
4392                                         an_10_100_val |= (1<<5);
4393                                         if (params->req_duplex == DUPLEX_FULL)
4394                                                 an_10_100_val |= (1<<6);
4395                                         DP(NETIF_MSG_LINK, "Advertising 10M\n");
4396                                      }
4397                                 else
4398                                         an_10_100_val &= ~((1<<5) | (1<<6));
4399
4400                                 bnx2x_cl45_write(bp, params->port,
4401                                                ext_phy_type,
4402                                                ext_phy_addr,
4403                                                MDIO_AN_DEVAD,
4404                                                MDIO_AN_REG_8481_LEGACY_AN_ADV,
4405                                                an_10_100_val);
4406
4407                                 bnx2x_cl45_read(bp, params->port,
4408                                               ext_phy_type,
4409                                               ext_phy_addr,
4410                                               MDIO_AN_DEVAD,
4411                                               MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4412                                               &autoneg_val);
4413
4414                                 /* Disable forced speed */
4415                                 autoneg_val &= ~(1<<6|1<<13);
4416
4417                                 /* Enable autoneg and restart autoneg
4418                                 for legacy speeds */
4419                                 autoneg_val |= (1<<9|1<<12);
4420
4421                                 if (params->req_duplex == DUPLEX_FULL)
4422                                         autoneg_val |= (1<<8);
4423                                 else
4424                                         autoneg_val &= ~(1<<8);
4425
4426                                 bnx2x_cl45_write(bp, params->port,
4427                                                ext_phy_type,
4428                                                ext_phy_addr,
4429                                                MDIO_AN_DEVAD,
4430                                                MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4431                                                autoneg_val);
4432
4433                                 if (params->speed_cap_mask &
4434                                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
4435                                         DP(NETIF_MSG_LINK, "Advertising 10G\n");
4436                                         /* Restart autoneg for 10G*/
4437                         bnx2x_cl45_read(bp, params->port,
4438                                       ext_phy_type,
4439                                       ext_phy_addr,
4440                                       MDIO_AN_DEVAD,
4441                                       MDIO_AN_REG_CTRL, &val);
4442                         val |= 0x200;
4443                         bnx2x_cl45_write(bp, params->port,
4444                                        ext_phy_type,
4445                                        ext_phy_addr,
4446                                        MDIO_AN_DEVAD,
4447                                        MDIO_AN_REG_CTRL, val);
4448                                 }
4449                         } else {
4450                                 /* Force speed */
4451                                 u16 autoneg_ctrl, pma_ctrl;
4452                                 bnx2x_cl45_read(bp, params->port,
4453                                               ext_phy_type,
4454                                               ext_phy_addr,
4455                                               MDIO_AN_DEVAD,
4456                                               MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4457                                               &autoneg_ctrl);
4458
4459                                 /* Disable autoneg */
4460                                 autoneg_ctrl &= ~(1<<12);
4461
4462                                 /* Set 1000 force */
4463                                 switch (params->req_line_speed) {
4464                                 case SPEED_10000:
4465                                         DP(NETIF_MSG_LINK,
4466                                                 "Unable to set 10G force !\n");
4467                                         break;
4468                                 case SPEED_1000:
4469                                         bnx2x_cl45_read(bp, params->port,
4470                                                       ext_phy_type,
4471                                                       ext_phy_addr,
4472                                                       MDIO_PMA_DEVAD,
4473                                                       MDIO_PMA_REG_CTRL,
4474                                                       &pma_ctrl);
4475                                         autoneg_ctrl &= ~(1<<13);
4476                                         autoneg_ctrl |= (1<<6);
4477                                         pma_ctrl &= ~(1<<13);
4478                                         pma_ctrl |= (1<<6);
4479                                         DP(NETIF_MSG_LINK,
4480                                                 "Setting 1000M force\n");
4481                                         bnx2x_cl45_write(bp, params->port,
4482                                                        ext_phy_type,
4483                                                        ext_phy_addr,
4484                                                        MDIO_PMA_DEVAD,
4485                                                        MDIO_PMA_REG_CTRL,
4486                                                        pma_ctrl);
4487                                         break;
4488                                 case SPEED_100:
4489                                         autoneg_ctrl |= (1<<13);
4490                                         autoneg_ctrl &= ~(1<<6);
4491                                         DP(NETIF_MSG_LINK,
4492                                                 "Setting 100M force\n");
4493                                         break;
4494                                 case SPEED_10:
4495                                         autoneg_ctrl &= ~(1<<13);
4496                                         autoneg_ctrl &= ~(1<<6);
4497                                         DP(NETIF_MSG_LINK,
4498                                                 "Setting 10M force\n");
4499                                         break;
4500                                 }
4501
4502                                 /* Duplex mode */
4503                                 if (params->req_duplex == DUPLEX_FULL) {
4504                                         autoneg_ctrl |= (1<<8);
4505                                         DP(NETIF_MSG_LINK,
4506                                                 "Setting full duplex\n");
4507                                 } else
4508                                         autoneg_ctrl &= ~(1<<8);
4509
4510                                 /* Update autoneg ctrl and pma ctrl */
4511                                 bnx2x_cl45_write(bp, params->port,
4512                                                ext_phy_type,
4513                                                ext_phy_addr,
4514                                                MDIO_AN_DEVAD,
4515                                                MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4516                                                autoneg_ctrl);
4517                         }
4518
4519                         /* Save spirom version */
4520                         bnx2x_save_8481_spirom_version(bp, params->port,
4521                                                      ext_phy_addr,
4522                                                      params->shmem_base);
4523                         break;
4524                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4525                         DP(NETIF_MSG_LINK,
4526                                  "XGXS PHY Failure detected 0x%x\n",
4527                                  params->ext_phy_config);
4528                         rc = -EINVAL;
4529                         break;
4530                 default:
4531                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
4532                                   params->ext_phy_config);
4533                         rc = -EINVAL;
4534                         break;
4535                 }
4536
4537         } else { /* SerDes */
4538
4539                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
4540                 switch (ext_phy_type) {
4541                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
4542                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
4543                         break;
4544
4545                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
4546                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
4547                         break;
4548
4549                 default:
4550                         DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
4551                            params->ext_phy_config);
4552                         break;
4553                 }
4554         }
4555         return rc;
4556 }
4557
4558 static void bnx2x_8727_handle_mod_abs(struct link_params *params)
4559 {
4560         struct bnx2x *bp = params->bp;
4561         u16 mod_abs, rx_alarm_status;
4562         u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
4563         u32 val = REG_RD(bp, params->shmem_base +
4564                              offsetof(struct shmem_region, dev_info.
4565                                       port_feature_config[params->port].
4566                                       config));
4567         bnx2x_cl45_read(bp, params->port,
4568                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4569                       ext_phy_addr,
4570                       MDIO_PMA_DEVAD,
4571                       MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4572         if (mod_abs & (1<<8)) {
4573
4574                 /* Module is absent */
4575                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4576                             "show module is absent\n");
4577
4578                 /* 1. Set mod_abs to detect next module
4579                 presence event
4580                    2. Set EDC off by setting OPTXLOS signal input to low
4581                         (bit 9).
4582                         When the EDC is off it locks onto a reference clock and
4583                         avoids becoming 'lost'.*/
4584                 mod_abs &= ~((1<<8)|(1<<9));
4585                 bnx2x_cl45_write(bp, params->port,
4586                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4587                                ext_phy_addr,
4588                                MDIO_PMA_DEVAD,
4589                                MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4590
4591                 /* Clear RX alarm since it stays up as long as
4592                 the mod_abs wasn't changed */
4593                 bnx2x_cl45_read(bp, params->port,
4594                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4595                               ext_phy_addr,
4596                               MDIO_PMA_DEVAD,
4597                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4598
4599         } else {
4600                 /* Module is present */
4601                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4602                             "show module is present\n");
4603                 /* First thing, disable transmitter,
4604                 and if the module is ok, the
4605                 module_detection will enable it*/
4606
4607                 /* 1. Set mod_abs to detect next module
4608                 absent event ( bit 8)
4609                    2. Restore the default polarity of the OPRXLOS signal and
4610                 this signal will then correctly indicate the presence or
4611                 absence of the Rx signal. (bit 9) */
4612                 mod_abs |= ((1<<8)|(1<<9));
4613                 bnx2x_cl45_write(bp, params->port,
4614                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4615                        ext_phy_addr,
4616                        MDIO_PMA_DEVAD,
4617                        MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4618
4619                 /* Clear RX alarm since it stays up as long as
4620                 the mod_abs wasn't changed. This is need to be done
4621                 before calling the module detection, otherwise it will clear
4622                 the link update alarm */
4623                 bnx2x_cl45_read(bp, params->port,
4624                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4625                               ext_phy_addr,
4626                               MDIO_PMA_DEVAD,
4627                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4628
4629
4630                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4631                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
4632                         bnx2x_sfp_set_transmitter(bp, params->port,
4633                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4634                                         ext_phy_addr, 0);
4635
4636                 if (bnx2x_wait_for_sfp_module_initialized(params)
4637                     == 0)
4638                         bnx2x_sfp_module_detection(params);
4639                 else
4640                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
4641         }
4642
4643         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4644                  rx_alarm_status);
4645         /* No need to check link status in case of
4646         module plugged in/out */
4647 }
4648
4649
4650 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
4651                                  struct link_vars *vars,
4652                                  u8 is_mi_int)
4653 {
4654         struct bnx2x *bp = params->bp;
4655         u32 ext_phy_type;
4656         u8 ext_phy_addr;
4657         u16 val1 = 0, val2;
4658         u16 rx_sd, pcs_status;
4659         u8 ext_phy_link_up = 0;
4660         u8 port = params->port;
4661
4662         if (vars->phy_flags & PHY_XGXS_FLAG) {
4663                 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
4664                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4665                 switch (ext_phy_type) {
4666                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4667                         DP(NETIF_MSG_LINK, "XGXS Direct\n");
4668                         ext_phy_link_up = 1;
4669                         break;
4670
4671                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4672                         DP(NETIF_MSG_LINK, "XGXS 8705\n");
4673                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4674                                       ext_phy_addr,
4675                                       MDIO_WIS_DEVAD,
4676                                       MDIO_WIS_REG_LASI_STATUS, &val1);
4677                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4678
4679                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4680                                       ext_phy_addr,
4681                                       MDIO_WIS_DEVAD,
4682                                       MDIO_WIS_REG_LASI_STATUS, &val1);
4683                         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4684
4685                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4686                                       ext_phy_addr,
4687                                       MDIO_PMA_DEVAD,
4688                                       MDIO_PMA_REG_RX_SD, &rx_sd);
4689
4690                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4691                                       ext_phy_addr,
4692                                       1,
4693                                       0xc809, &val1);
4694                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4695                                       ext_phy_addr,
4696                                       1,
4697                                       0xc809, &val1);
4698
4699                         DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4700                         ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9))
4701                                            && ((val1 & (1<<8)) == 0));
4702                         if (ext_phy_link_up)
4703                                 vars->line_speed = SPEED_10000;
4704                         break;
4705
4706                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4707                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4708                         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
4709                         /* Clear RX Alarm*/
4710                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4711                                       ext_phy_addr,
4712                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
4713                                       &val2);
4714                         /* clear LASI indication*/
4715                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4716                                       ext_phy_addr,
4717                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4718                                       &val1);
4719                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4720                                       ext_phy_addr,
4721                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4722                                       &val2);
4723                         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
4724                                      "0x%x\n", val1, val2);
4725
4726                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4727                                       ext_phy_addr,
4728                                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
4729                                       &rx_sd);
4730                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4731                                       ext_phy_addr,
4732                                       MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
4733                                       &pcs_status);
4734                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4735                                       ext_phy_addr,
4736                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4737                                       &val2);
4738                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
4739                                       ext_phy_addr,
4740                                       MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4741                                       &val2);
4742
4743                         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
4744                            "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
4745                            rx_sd, pcs_status, val2);
4746                         /* link is up if both bit 0 of pmd_rx_sd and
4747                          * bit 0 of pcs_status are set, or if the autoneg bit
4748                            1 is set
4749                          */
4750                         ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
4751                                            (val2 & (1<<1)));
4752                         if (ext_phy_link_up) {
4753                                 if (ext_phy_type ==
4754                                      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
4755                                         /* If transmitter is disabled,
4756                                         ignore false link up indication */
4757                                         bnx2x_cl45_read(bp, params->port,
4758                                                    ext_phy_type,
4759                                                    ext_phy_addr,
4760                                                    MDIO_PMA_DEVAD,
4761                                                    MDIO_PMA_REG_PHY_IDENTIFIER,
4762                                                    &val1);
4763                                         if (val1 & (1<<15)) {
4764                                                 DP(NETIF_MSG_LINK, "Tx is "
4765                                                             "disabled\n");
4766                                                 ext_phy_link_up = 0;
4767                                                 break;
4768                                         }
4769                                 }
4770                                 if (val2 & (1<<1))
4771                                         vars->line_speed = SPEED_1000;
4772                                 else
4773                                         vars->line_speed = SPEED_10000;
4774                         }
4775                         break;
4776
4777                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
4778                 {
4779                         u16 link_status = 0;
4780                         u16 rx_alarm_status;
4781                         /* Check the LASI */
4782                         bnx2x_cl45_read(bp, params->port,
4783                                       ext_phy_type,
4784                                       ext_phy_addr,
4785                                       MDIO_PMA_DEVAD,
4786                                       MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4787
4788                         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4789                                  rx_alarm_status);
4790
4791                         bnx2x_cl45_read(bp, params->port,
4792                                       ext_phy_type,
4793                                       ext_phy_addr,
4794                                       MDIO_PMA_DEVAD,
4795                                       MDIO_PMA_REG_LASI_STATUS, &val1);
4796
4797                         DP(NETIF_MSG_LINK,
4798                                  "8727 LASI status 0x%x\n",
4799                                  val1);
4800
4801                         /* Clear MSG-OUT */
4802                         bnx2x_cl45_read(bp, params->port,
4803                                       ext_phy_type,
4804                                       ext_phy_addr,
4805                                       MDIO_PMA_DEVAD,
4806                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
4807                                       &val1);
4808
4809                         /*
4810                          * If a module is present and there is need to check
4811                          * for over current
4812                          */
4813                         if (!(params->feature_config_flags &
4814                               FEATURE_CONFIG_BCM8727_NOC) &&
4815                             !(rx_alarm_status & (1<<5))) {
4816                                 /* Check over-current using 8727 GPIO0 input*/
4817                                 bnx2x_cl45_read(bp, params->port,
4818                                               ext_phy_type,
4819                                               ext_phy_addr,
4820                                               MDIO_PMA_DEVAD,
4821                                               MDIO_PMA_REG_8727_GPIO_CTRL,
4822                                               &val1);
4823
4824                                 if ((val1 & (1<<8)) == 0) {
4825                                         DP(NETIF_MSG_LINK, "8727 Power fault"
4826                                                      " has been detected on "
4827                                                      "port %d\n",
4828                                                  params->port);
4829                                         printk(KERN_ERR PFX  "Error:  Power"
4830                                                  " fault on %s Port %d has"
4831                                                  " been detected and the"
4832                                                  " power to that SFP+ module"
4833                                                  " has been removed to prevent"
4834                                                  " failure of the card. Please"
4835                                                  " remove the SFP+ module and"
4836                                                  " restart the system to clear"
4837                                                  " this error.\n"
4838                         , bp->dev->name, params->port);
4839                                         /*
4840                                          * Disable all RX_ALARMs except for
4841                                          * mod_abs
4842                                          */
4843                                         bnx2x_cl45_write(bp, params->port,
4844                                                      ext_phy_type,
4845                                                      ext_phy_addr,
4846                                                      MDIO_PMA_DEVAD,
4847                                                      MDIO_PMA_REG_RX_ALARM_CTRL,
4848                                                      (1<<5));
4849
4850                                         bnx2x_cl45_read(bp, params->port,
4851                                                     ext_phy_type,
4852                                                     ext_phy_addr,
4853                                                     MDIO_PMA_DEVAD,
4854                                                     MDIO_PMA_REG_PHY_IDENTIFIER,
4855                                                     &val1);
4856                                         /* Wait for module_absent_event */
4857                                         val1 |= (1<<8);
4858                                         bnx2x_cl45_write(bp, params->port,
4859                                                     ext_phy_type,
4860                                                     ext_phy_addr,
4861                                                     MDIO_PMA_DEVAD,
4862                                                     MDIO_PMA_REG_PHY_IDENTIFIER,
4863                                                     val1);
4864                                         /* Clear RX alarm */
4865                                         bnx2x_cl45_read(bp, params->port,
4866                                                       ext_phy_type,
4867                                                       ext_phy_addr,
4868                                                       MDIO_PMA_DEVAD,
4869                                                       MDIO_PMA_REG_RX_ALARM,
4870                                                       &rx_alarm_status);
4871                                         break;
4872                                 }
4873                         } /* Over current check */
4874
4875                         /* When module absent bit is set, check module */
4876                         if (rx_alarm_status & (1<<5)) {
4877                                 bnx2x_8727_handle_mod_abs(params);
4878                                 /* Enable all mod_abs and link detection bits */
4879                                 bnx2x_cl45_write(bp, params->port,
4880                                                ext_phy_type,
4881                                                ext_phy_addr,
4882                                                MDIO_PMA_DEVAD,
4883                                                MDIO_PMA_REG_RX_ALARM_CTRL,
4884                                                ((1<<5) | (1<<2)));
4885                         }
4886
4887                         /* If transmitter is disabled,
4888                         ignore false link up indication */
4889                         bnx2x_cl45_read(bp, params->port,
4890                                       ext_phy_type,
4891                                       ext_phy_addr,
4892                                       MDIO_PMA_DEVAD,
4893                                       MDIO_PMA_REG_PHY_IDENTIFIER,
4894                                       &val1);
4895                         if (val1 & (1<<15)) {
4896                                 DP(NETIF_MSG_LINK, "Tx is disabled\n");
4897                                 ext_phy_link_up = 0;
4898                                 break;
4899                         }
4900
4901                         bnx2x_cl45_read(bp, params->port,
4902                                       ext_phy_type,
4903                                       ext_phy_addr,
4904                                       MDIO_PMA_DEVAD,
4905                                       MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4906                                       &link_status);
4907
4908                         /* Bits 0..2 --> speed detected,
4909                            bits 13..15--> link is down */
4910                         if ((link_status & (1<<2)) &&
4911                             (!(link_status & (1<<15)))) {
4912                                 ext_phy_link_up = 1;
4913                                 vars->line_speed = SPEED_10000;
4914                         } else if ((link_status & (1<<0)) &&
4915                                    (!(link_status & (1<<13)))) {
4916                                 ext_phy_link_up = 1;
4917                                 vars->line_speed = SPEED_1000;
4918                                 DP(NETIF_MSG_LINK,
4919                                          "port %x: External link"
4920                                          " up in 1G\n", params->port);
4921                         } else {
4922                                 ext_phy_link_up = 0;
4923                                 DP(NETIF_MSG_LINK,
4924                                          "port %x: External link"
4925                                          " is down\n", params->port);
4926                         }
4927                         break;
4928                 }
4929
4930                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4931                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4932                 {
4933                         u16 link_status = 0;
4934                         u16 an1000_status = 0;
4935
4936                         if (ext_phy_type ==
4937                              PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
4938                                 bnx2x_cl45_read(bp, params->port,
4939                                       ext_phy_type,
4940                                       ext_phy_addr,
4941                                       MDIO_PCS_DEVAD,
4942                                       MDIO_PCS_REG_LASI_STATUS, &val1);
4943                         bnx2x_cl45_read(bp, params->port,
4944                                       ext_phy_type,
4945                                       ext_phy_addr,
4946                                       MDIO_PCS_DEVAD,
4947                                       MDIO_PCS_REG_LASI_STATUS, &val2);
4948                         DP(NETIF_MSG_LINK,
4949                                  "870x LASI status 0x%x->0x%x\n",
4950                                   val1, val2);
4951                         } else {
4952                                 /* In 8073, port1 is directed through emac0 and
4953                                  * port0 is directed through emac1
4954                                  */
4955                                 bnx2x_cl45_read(bp, params->port,
4956                                               ext_phy_type,
4957                                               ext_phy_addr,
4958                                               MDIO_PMA_DEVAD,
4959                                               MDIO_PMA_REG_LASI_STATUS, &val1);
4960
4961                                 DP(NETIF_MSG_LINK,
4962                                          "8703 LASI status 0x%x\n",
4963                                           val1);
4964                         }
4965
4966                         /* clear the interrupt LASI status register */
4967                         bnx2x_cl45_read(bp, params->port,
4968                                       ext_phy_type,
4969                                       ext_phy_addr,
4970                                       MDIO_PCS_DEVAD,
4971                                       MDIO_PCS_REG_STATUS, &val2);
4972                         bnx2x_cl45_read(bp, params->port,
4973                                       ext_phy_type,
4974                                       ext_phy_addr,
4975                                       MDIO_PCS_DEVAD,
4976                                       MDIO_PCS_REG_STATUS, &val1);
4977                         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
4978                            val2, val1);
4979                         /* Clear MSG-OUT */
4980                         bnx2x_cl45_read(bp, params->port,
4981                                       ext_phy_type,
4982                                       ext_phy_addr,
4983                                       MDIO_PMA_DEVAD,
4984                                       MDIO_PMA_REG_M8051_MSGOUT_REG,
4985                                       &val1);
4986
4987                         /* Check the LASI */
4988                         bnx2x_cl45_read(bp, params->port,
4989                                       ext_phy_type,
4990                                       ext_phy_addr,
4991                                       MDIO_PMA_DEVAD,
4992                                       MDIO_PMA_REG_RX_ALARM, &val2);
4993
4994                         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
4995
4996                         /* Check the link status */
4997                         bnx2x_cl45_read(bp, params->port,
4998                                       ext_phy_type,
4999                                       ext_phy_addr,
5000                                       MDIO_PCS_DEVAD,
5001                                       MDIO_PCS_REG_STATUS, &val2);
5002                         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
5003
5004                         bnx2x_cl45_read(bp, params->port,
5005                                       ext_phy_type,
5006                                       ext_phy_addr,
5007                                       MDIO_PMA_DEVAD,
5008                                       MDIO_PMA_REG_STATUS, &val2);
5009                         bnx2x_cl45_read(bp, params->port,
5010                                       ext_phy_type,
5011                                       ext_phy_addr,
5012                                       MDIO_PMA_DEVAD,
5013                                       MDIO_PMA_REG_STATUS, &val1);
5014                         ext_phy_link_up = ((val1 & 4) == 4);
5015                         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
5016                         if (ext_phy_type ==
5017                             PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
5018
5019                                 if (ext_phy_link_up &&
5020                                     ((params->req_line_speed !=
5021                                         SPEED_10000))) {
5022                                         if (bnx2x_bcm8073_xaui_wa(params)
5023                                              != 0) {
5024                                                 ext_phy_link_up = 0;
5025                                                 break;
5026                                         }
5027                                 }
5028                                 bnx2x_cl45_read(bp, params->port,
5029                                               ext_phy_type,
5030                                               ext_phy_addr,
5031                                               MDIO_AN_DEVAD,
5032                                               MDIO_AN_REG_LINK_STATUS,
5033                                               &an1000_status);
5034                                 bnx2x_cl45_read(bp, params->port,
5035                                               ext_phy_type,
5036                                               ext_phy_addr,
5037                                               MDIO_AN_DEVAD,
5038                                               MDIO_AN_REG_LINK_STATUS,
5039                                               &an1000_status);
5040
5041                                 /* Check the link status on 1.1.2 */
5042                                 bnx2x_cl45_read(bp, params->port,
5043                                               ext_phy_type,
5044                                               ext_phy_addr,
5045                                               MDIO_PMA_DEVAD,
5046                                               MDIO_PMA_REG_STATUS, &val2);
5047                                 bnx2x_cl45_read(bp, params->port,
5048                                               ext_phy_type,
5049                                               ext_phy_addr,
5050                                               MDIO_PMA_DEVAD,
5051                                               MDIO_PMA_REG_STATUS, &val1);
5052                                 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
5053                                              "an_link_status=0x%x\n",
5054                                           val2, val1, an1000_status);
5055
5056                                 ext_phy_link_up = (((val1 & 4) == 4) ||
5057                                                 (an1000_status & (1<<1)));
5058                                 if (ext_phy_link_up &&
5059                                     bnx2x_8073_is_snr_needed(params)) {
5060                                         /* The SNR will improve about 2dbby
5061                                         changing the BW and FEE main tap.*/
5062
5063                                         /* The 1st write to change FFE main
5064                                         tap is set before restart AN */
5065                                         /* Change PLL Bandwidth in EDC
5066                                         register */
5067                                         bnx2x_cl45_write(bp, port, ext_phy_type,
5068                                                     ext_phy_addr,
5069                                                     MDIO_PMA_DEVAD,
5070                                                     MDIO_PMA_REG_PLL_BANDWIDTH,
5071                                                     0x26BC);
5072
5073                                         /* Change CDR Bandwidth in EDC
5074                                         register */
5075                                         bnx2x_cl45_write(bp, port, ext_phy_type,
5076                                                     ext_phy_addr,
5077                                                     MDIO_PMA_DEVAD,
5078                                                     MDIO_PMA_REG_CDR_BANDWIDTH,
5079                                                     0x0333);
5080                                 }
5081                                 bnx2x_cl45_read(bp, params->port,
5082                                            ext_phy_type,
5083                                            ext_phy_addr,
5084                                            MDIO_PMA_DEVAD,
5085                                            MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
5086                                            &link_status);
5087
5088                                 /* Bits 0..2 --> speed detected,
5089                                    bits 13..15--> link is down */
5090                                 if ((link_status & (1<<2)) &&
5091                                     (!(link_status & (1<<15)))) {
5092                                         ext_phy_link_up = 1;
5093                                         vars->line_speed = SPEED_10000;
5094                                         DP(NETIF_MSG_LINK,
5095                                                  "port %x: External link"
5096                                                  " up in 10G\n", params->port);
5097                                 } else if ((link_status & (1<<1)) &&
5098                                            (!(link_status & (1<<14)))) {
5099                                         ext_phy_link_up = 1;
5100                                         vars->line_speed = SPEED_2500;
5101                                         DP(NETIF_MSG_LINK,
5102                                                  "port %x: External link"
5103                                                  " up in 2.5G\n", params->port);
5104                                 } else if ((link_status & (1<<0)) &&
5105                                            (!(link_status & (1<<13)))) {
5106                                         ext_phy_link_up = 1;
5107                                         vars->line_speed = SPEED_1000;
5108                                         DP(NETIF_MSG_LINK,
5109                                                  "port %x: External link"
5110                                                  " up in 1G\n", params->port);
5111                                 } else {
5112                                         ext_phy_link_up = 0;
5113                                         DP(NETIF_MSG_LINK,
5114                                                  "port %x: External link"
5115                                                  " is down\n", params->port);
5116                                 }
5117                         } else {
5118                                 /* See if 1G link is up for the 8072 */
5119                                 bnx2x_cl45_read(bp, params->port,
5120                                               ext_phy_type,
5121                                               ext_phy_addr,
5122                                               MDIO_AN_DEVAD,
5123                                               MDIO_AN_REG_LINK_STATUS,
5124                                               &an1000_status);
5125                                 bnx2x_cl45_read(bp, params->port,
5126                                               ext_phy_type,
5127                                               ext_phy_addr,
5128                                               MDIO_AN_DEVAD,
5129                                               MDIO_AN_REG_LINK_STATUS,
5130                                               &an1000_status);
5131                                 if (an1000_status & (1<<1)) {
5132                                         ext_phy_link_up = 1;
5133                                         vars->line_speed = SPEED_1000;
5134                                         DP(NETIF_MSG_LINK,
5135                                                  "port %x: External link"
5136                                                  " up in 1G\n", params->port);
5137                                 } else if (ext_phy_link_up) {
5138                                         ext_phy_link_up = 1;
5139                                         vars->line_speed = SPEED_10000;
5140                                         DP(NETIF_MSG_LINK,
5141                                                  "port %x: External link"
5142                                                  " up in 10G\n", params->port);
5143                                 }
5144                         }
5145
5146
5147                         break;
5148                 }
5149                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5150                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5151                                       ext_phy_addr,
5152                                       MDIO_PMA_DEVAD,
5153                                       MDIO_PMA_REG_LASI_STATUS, &val2);
5154                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5155                                       ext_phy_addr,
5156                                       MDIO_PMA_DEVAD,
5157                                       MDIO_PMA_REG_LASI_STATUS, &val1);
5158                         DP(NETIF_MSG_LINK,
5159                                  "10G-base-T LASI status 0x%x->0x%x\n",
5160                                   val2, val1);
5161                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5162                                       ext_phy_addr,
5163                                       MDIO_PMA_DEVAD,
5164                                       MDIO_PMA_REG_STATUS, &val2);
5165                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5166                                       ext_phy_addr,
5167                                       MDIO_PMA_DEVAD,
5168                                       MDIO_PMA_REG_STATUS, &val1);
5169                         DP(NETIF_MSG_LINK,
5170                                  "10G-base-T PMA status 0x%x->0x%x\n",
5171                                  val2, val1);
5172                         ext_phy_link_up = ((val1 & 4) == 4);
5173                         /* if link is up
5174                          * print the AN outcome of the SFX7101 PHY
5175                          */
5176                         if (ext_phy_link_up) {
5177                                 bnx2x_cl45_read(bp, params->port,
5178                                               ext_phy_type,
5179                                               ext_phy_addr,
5180                                               MDIO_AN_DEVAD,
5181                                               MDIO_AN_REG_MASTER_STATUS,
5182                                               &val2);
5183                                 vars->line_speed = SPEED_10000;
5184                                 DP(NETIF_MSG_LINK,
5185                                          "SFX7101 AN status 0x%x->Master=%x\n",
5186                                           val2,
5187                                          (val2 & (1<<14)));
5188                         }
5189                         break;
5190                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5191                         /* Check 10G-BaseT link status */
5192                         /* Check PMD signal ok */
5193                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5194                                                       ext_phy_addr,
5195                                                       MDIO_AN_DEVAD,
5196                                                       0xFFFA,
5197                                                       &val1);
5198                         bnx2x_cl45_read(bp, params->port, ext_phy_type,
5199                                       ext_phy_addr,
5200                                       MDIO_PMA_DEVAD,
5201                                       MDIO_PMA_REG_8481_PMD_SIGNAL,
5202                                       &val2);
5203                         DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2);
5204
5205                         /* Check link 10G */
5206                         if (val2 & (1<<11)) {
5207                                 vars->line_speed = SPEED_10000;
5208                                 ext_phy_link_up = 1;
5209                                 bnx2x_8481_set_10G_led_mode(params,
5210                                                           ext_phy_type,
5211                                                           ext_phy_addr);
5212                         } else { /* Check Legacy speed link */
5213                                 u16 legacy_status, legacy_speed;
5214
5215                                 /* Enable expansion register 0x42
5216                                 (Operation mode status) */
5217                                 bnx2x_cl45_write(bp, params->port,
5218                                          ext_phy_type,
5219                                          ext_phy_addr,
5220                                          MDIO_AN_DEVAD,
5221                                          MDIO_AN_REG_8481_EXPANSION_REG_ACCESS,
5222                                          0xf42);
5223
5224                                 /* Get legacy speed operation status */
5225                                 bnx2x_cl45_read(bp, params->port,
5226                                           ext_phy_type,
5227                                           ext_phy_addr,
5228                                           MDIO_AN_DEVAD,
5229                                           MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
5230                                           &legacy_status);
5231
5232                                 DP(NETIF_MSG_LINK, "Legacy speed status"
5233                                              " = 0x%x\n", legacy_status);
5234                                 ext_phy_link_up = ((legacy_status & (1<<11))
5235                                                    == (1<<11));
5236                                 if (ext_phy_link_up) {
5237                                         legacy_speed = (legacy_status & (3<<9));
5238                                         if (legacy_speed == (0<<9))
5239                                                 vars->line_speed = SPEED_10;
5240                                         else if (legacy_speed == (1<<9))
5241                                                 vars->line_speed =
5242                                                         SPEED_100;
5243                                         else if (legacy_speed == (2<<9))
5244                                                 vars->line_speed =
5245                                                         SPEED_1000;
5246                                         else /* Should not happen */
5247                                                 vars->line_speed = 0;
5248
5249                                         if (legacy_status & (1<<8))
5250                                                 vars->duplex = DUPLEX_FULL;
5251                                         else
5252                                                 vars->duplex = DUPLEX_HALF;
5253
5254                                         DP(NETIF_MSG_LINK, "Link is up "
5255                                                      "in %dMbps, is_duplex_full"
5256                                                      "= %d\n",
5257                                                 vars->line_speed,
5258                                                 (vars->duplex == DUPLEX_FULL));
5259                                         bnx2x_8481_set_legacy_led_mode(params,
5260                                                                  ext_phy_type,
5261                                                                  ext_phy_addr);
5262                                 }
5263                         }
5264                         break;
5265                 default:
5266                         DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
5267                            params->ext_phy_config);
5268                         ext_phy_link_up = 0;
5269                         break;
5270                 }
5271                 /* Set SGMII mode for external phy */
5272                 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5273                         if (vars->line_speed < SPEED_1000)
5274                                 vars->phy_flags |= PHY_SGMII_FLAG;
5275                         else
5276                                 vars->phy_flags &= ~PHY_SGMII_FLAG;
5277                 }
5278
5279         } else { /* SerDes */
5280                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5281                 switch (ext_phy_type) {
5282                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
5283                         DP(NETIF_MSG_LINK, "SerDes Direct\n");
5284                         ext_phy_link_up = 1;
5285                         break;
5286
5287                 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
5288                         DP(NETIF_MSG_LINK, "SerDes 5482\n");
5289                         ext_phy_link_up = 1;
5290                         break;
5291
5292                 default:
5293                         DP(NETIF_MSG_LINK,
5294                                  "BAD SerDes ext_phy_config 0x%x\n",
5295                                  params->ext_phy_config);
5296                         ext_phy_link_up = 0;
5297                         break;
5298                 }
5299         }
5300
5301         return ext_phy_link_up;
5302 }
5303
5304 static void bnx2x_link_int_enable(struct link_params *params)
5305 {
5306         u8 port = params->port;
5307         u32 ext_phy_type;
5308         u32 mask;
5309         struct bnx2x *bp = params->bp;
5310
5311         /* setting the status to report on link up
5312            for either XGXS or SerDes */
5313
5314         if (params->switch_cfg == SWITCH_CFG_10G) {
5315                 mask = (NIG_MASK_XGXS0_LINK10G |
5316                         NIG_MASK_XGXS0_LINK_STATUS);
5317                 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5318                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5319                 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5320                     (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
5321                     (ext_phy_type !=
5322                                 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
5323                         mask |= NIG_MASK_MI_INT;
5324                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5325                 }
5326
5327         } else { /* SerDes */
5328                 mask = NIG_MASK_SERDES0_LINK_STATUS;
5329                 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5330                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5331                 if ((ext_phy_type !=
5332                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
5333                     (ext_phy_type !=
5334                                 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
5335                         mask |= NIG_MASK_MI_INT;
5336                         DP(NETIF_MSG_LINK, "enabled external phy int\n");
5337                 }
5338         }
5339         bnx2x_bits_en(bp,
5340                       NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5341                       mask);
5342
5343         DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
5344                  (params->switch_cfg == SWITCH_CFG_10G),
5345                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5346         DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5347                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5348                  REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5349                  REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5350         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5351            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5352            REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5353 }
5354
5355 static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
5356                                         u8 is_mi_int)
5357 {
5358         u32 latch_status = 0, is_mi_int_status;
5359         /* Disable the MI INT ( external phy int )
5360          * by writing 1 to the status register. Link down indication
5361          * is high-active-signal, so in this case we need to write the
5362          * status to clear the XOR
5363          */
5364         /* Read Latched signals */
5365         latch_status = REG_RD(bp,
5366                                   NIG_REG_LATCH_STATUS_0 + port*8);
5367         is_mi_int_status = REG_RD(bp,
5368                                   NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
5369         DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
5370                      "latch_status = 0x%x\n",
5371                  is_mi_int, is_mi_int_status, latch_status);
5372         /* Handle only those with latched-signal=up.*/
5373         if (latch_status & 1) {
5374                 /* For all latched-signal=up,Write original_signal to status */
5375                 if (is_mi_int)
5376                         bnx2x_bits_en(bp,
5377                                     NIG_REG_STATUS_INTERRUPT_PORT0
5378                                     + port*4,
5379                                     NIG_STATUS_EMAC0_MI_INT);
5380                 else
5381                         bnx2x_bits_dis(bp,
5382                                      NIG_REG_STATUS_INTERRUPT_PORT0
5383                                      + port*4,
5384                                      NIG_STATUS_EMAC0_MI_INT);
5385                 /* For all latched-signal=up : Re-Arm Latch signals */
5386                 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
5387                            (latch_status & 0xfffe) | (latch_status & 1));
5388         }
5389 }
5390 /*
5391  * link management
5392  */
5393 static void bnx2x_link_int_ack(struct link_params *params,
5394                              struct link_vars *vars, u8 is_10g,
5395                              u8 is_mi_int)
5396 {
5397         struct bnx2x *bp = params->bp;
5398         u8 port = params->port;
5399
5400         /* first reset all status
5401          * we assume only one line will be change at a time */
5402         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5403                      (NIG_STATUS_XGXS0_LINK10G |
5404                       NIG_STATUS_XGXS0_LINK_STATUS |
5405                       NIG_STATUS_SERDES0_LINK_STATUS));
5406         if (XGXS_EXT_PHY_TYPE(params->ext_phy_config)
5407             == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) {
5408                 bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
5409         }
5410         if (vars->phy_link_up) {
5411                 if (is_10g) {
5412                         /* Disable the 10G link interrupt
5413                          * by writing 1 to the status register
5414                          */
5415                         DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
5416                         bnx2x_bits_en(bp,
5417                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5418                                       NIG_STATUS_XGXS0_LINK10G);
5419
5420                 } else if (params->switch_cfg == SWITCH_CFG_10G) {
5421                         /* Disable the link interrupt
5422                          * by writing 1 to the relevant lane
5423                          * in the status register
5424                          */
5425                         u32 ser_lane = ((params->lane_config &
5426                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5427                                     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5428
5429                         DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
5430                                  vars->line_speed);
5431                         bnx2x_bits_en(bp,
5432                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5433                                       ((1 << ser_lane) <<
5434                                        NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
5435
5436                 } else { /* SerDes */
5437                         DP(NETIF_MSG_LINK, "SerDes phy link up\n");
5438                         /* Disable the link interrupt
5439                          * by writing 1 to the status register
5440                          */
5441                         bnx2x_bits_en(bp,
5442                                       NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5443                                       NIG_STATUS_SERDES0_LINK_STATUS);
5444                 }
5445
5446         } else { /* link_down */
5447         }
5448 }
5449
5450 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
5451 {
5452         u8 *str_ptr = str;
5453         u32 mask = 0xf0000000;
5454         u8 shift = 8*4;
5455         u8 digit;
5456         if (len < 10) {
5457                 /* Need more than 10chars for this format */
5458                 *str_ptr = '\0';
5459                 return -EINVAL;
5460         }
5461         while (shift > 0) {
5462
5463                 shift -= 4;
5464                 digit = ((num & mask) >> shift);
5465                 if (digit < 0xa)
5466                         *str_ptr = digit + '0';
5467                 else
5468                         *str_ptr = digit - 0xa + 'a';
5469                 str_ptr++;
5470                 mask = mask >> 4;
5471                 if (shift == 4*4) {
5472                         *str_ptr = ':';
5473                         str_ptr++;
5474                 }
5475         }
5476         *str_ptr = '\0';
5477         return 0;
5478 }
5479
5480 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
5481                               u8 *version, u16 len)
5482 {
5483         struct bnx2x *bp;
5484         u32 ext_phy_type = 0;
5485         u32 spirom_ver = 0;
5486         u8 status;
5487
5488         if (version == NULL || params == NULL)
5489                 return -EINVAL;
5490         bp = params->bp;
5491
5492         spirom_ver = REG_RD(bp, params->shmem_base +
5493                    offsetof(struct shmem_region,
5494                             port_mb[params->port].ext_phy_fw_version));
5495
5496         status = 0;
5497         /* reset the returned value to zero */
5498         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5499         switch (ext_phy_type) {
5500         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5501
5502                 if (len < 5)
5503                         return -EINVAL;
5504
5505                 version[0] = (spirom_ver & 0xFF);
5506                 version[1] = (spirom_ver & 0xFF00) >> 8;
5507                 version[2] = (spirom_ver & 0xFF0000) >> 16;
5508                 version[3] = (spirom_ver & 0xFF000000) >> 24;
5509                 version[4] = '\0';
5510
5511                 break;
5512         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5513         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5514         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
5515         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5516         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5517                 status = bnx2x_format_ver(spirom_ver, version, len);
5518                 break;
5519         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5520                 spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 |
5521                         (spirom_ver & 0x7F);
5522                 status = bnx2x_format_ver(spirom_ver, version, len);
5523                 break;
5524         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5525         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5526                 version[0] = '\0';
5527                 break;
5528
5529         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
5530                 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
5531                                     " type is FAILURE!\n");
5532                 status = -EINVAL;
5533                 break;
5534
5535         default:
5536                 break;
5537         }
5538         return status;
5539 }
5540
5541 static void bnx2x_set_xgxs_loopback(struct link_params *params,
5542                                   struct link_vars *vars,
5543                                   u8 is_10g)
5544 {
5545         u8 port = params->port;
5546         struct bnx2x *bp = params->bp;
5547
5548         if (is_10g) {
5549                 u32 md_devad;
5550
5551                 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
5552
5553                 /* change the uni_phy_addr in the nig */
5554                 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
5555                                           port*0x18));
5556
5557                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
5558
5559                 bnx2x_cl45_write(bp, port, 0,
5560                                params->phy_addr,
5561                                5,
5562                                (MDIO_REG_BANK_AER_BLOCK +
5563                                 (MDIO_AER_BLOCK_AER_REG & 0xf)),
5564                                0x2800);
5565
5566                 bnx2x_cl45_write(bp, port, 0,
5567                                params->phy_addr,
5568                                5,
5569                                (MDIO_REG_BANK_CL73_IEEEB0 +
5570                                 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5571                                0x6041);
5572                 msleep(200);
5573                 /* set aer mmd back */
5574                 bnx2x_set_aer_mmd(params, vars);
5575
5576                 /* and md_devad */
5577                 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5578                             md_devad);
5579
5580         } else {
5581                 u16 mii_control;
5582
5583                 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
5584
5585                 CL45_RD_OVER_CL22(bp, port,
5586                                       params->phy_addr,
5587                                       MDIO_REG_BANK_COMBO_IEEE0,
5588                                       MDIO_COMBO_IEEE0_MII_CONTROL,
5589                                       &mii_control);
5590
5591                 CL45_WR_OVER_CL22(bp, port,
5592                                       params->phy_addr,
5593                                       MDIO_REG_BANK_COMBO_IEEE0,
5594                                       MDIO_COMBO_IEEE0_MII_CONTROL,
5595                                       (mii_control |
5596                                        MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
5597         }
5598 }
5599
5600
5601 static void bnx2x_ext_phy_loopback(struct link_params *params)
5602 {
5603         struct bnx2x *bp = params->bp;
5604         u8 ext_phy_addr;
5605         u32 ext_phy_type;
5606
5607         if (params->switch_cfg == SWITCH_CFG_10G) {
5608                 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5609                 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
5610                 /* CL37 Autoneg Enabled */
5611                 switch (ext_phy_type) {
5612                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5613                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
5614                         DP(NETIF_MSG_LINK,
5615                                 "ext_phy_loopback: We should not get here\n");
5616                         break;
5617                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5618                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
5619                         break;
5620                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5621                         DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
5622                         break;
5623                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5624                         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
5625                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
5626                                        ext_phy_addr,
5627                                        MDIO_PMA_DEVAD,
5628                                        MDIO_PMA_REG_CTRL,
5629                                        0x0001);
5630                         break;
5631                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5632                         /* SFX7101_XGXS_TEST1 */
5633                         bnx2x_cl45_write(bp, params->port, ext_phy_type,
5634                                        ext_phy_addr,
5635                                        MDIO_XS_DEVAD,
5636                                        MDIO_XS_SFX7101_XGXS_TEST1,
5637                                        0x100);
5638                         DP(NETIF_MSG_LINK,
5639                                 "ext_phy_loopback: set ext phy loopback\n");
5640                         break;
5641                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5642
5643                         break;
5644                 } /* switch external PHY type */
5645         } else {
5646                 /* serdes */
5647                 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
5648                 ext_phy_addr = (params->ext_phy_config  &
5649                 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
5650                 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
5651         }
5652 }
5653
5654
5655 /*
5656  *------------------------------------------------------------------------
5657  * bnx2x_override_led_value -
5658  *
5659  * Override the led value of the requsted led
5660  *
5661  *------------------------------------------------------------------------
5662  */
5663 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
5664                           u32 led_idx, u32 value)
5665 {
5666         u32 reg_val;
5667
5668         /* If port 0 then use EMAC0, else use EMAC1*/
5669         u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5670
5671         DP(NETIF_MSG_LINK,
5672                  "bnx2x_override_led_value() port %x led_idx %d value %d\n",
5673                  port, led_idx, value);
5674
5675         switch (led_idx) {
5676         case 0: /* 10MB led */
5677                 /* Read the current value of the LED register in
5678                 the EMAC block */
5679                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5680                 /* Set the OVERRIDE bit to 1 */
5681                 reg_val |= EMAC_LED_OVERRIDE;
5682                 /* If value is 1, set the 10M_OVERRIDE bit,
5683                 otherwise reset it.*/
5684                 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
5685                         (reg_val & ~EMAC_LED_10MB_OVERRIDE);
5686                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5687                 break;
5688         case 1: /*100MB led    */
5689                 /*Read the current value of the LED register in
5690                 the EMAC block */
5691                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5692                 /*  Set the OVERRIDE bit to 1 */
5693                 reg_val |= EMAC_LED_OVERRIDE;
5694                 /*  If value is 1, set the 100M_OVERRIDE bit,
5695                 otherwise reset it.*/
5696                 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
5697                         (reg_val & ~EMAC_LED_100MB_OVERRIDE);
5698                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5699                 break;
5700         case 2: /* 1000MB led */
5701                 /* Read the current value of the LED register in the
5702                 EMAC block */
5703                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5704                 /* Set the OVERRIDE bit to 1 */
5705                 reg_val |= EMAC_LED_OVERRIDE;
5706                 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
5707                 reset it. */
5708                 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
5709                         (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
5710                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5711                 break;
5712         case 3: /* 2500MB led */
5713                 /*  Read the current value of the LED register in the
5714                 EMAC block*/
5715                 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5716                 /* Set the OVERRIDE bit to 1 */
5717                 reg_val |= EMAC_LED_OVERRIDE;
5718                 /*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
5719                 reset it.*/
5720                 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
5721                         (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
5722                 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5723                 break;
5724         case 4: /*10G led */
5725                 if (port == 0) {
5726                         REG_WR(bp, NIG_REG_LED_10G_P0,
5727                                     value);
5728                 } else {
5729                         REG_WR(bp, NIG_REG_LED_10G_P1,
5730                                     value);
5731                 }
5732                 break;
5733         case 5: /* TRAFFIC led */
5734                 /* Find if the traffic control is via BMAC or EMAC */
5735                 if (port == 0)
5736                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
5737                 else
5738                         reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
5739
5740                 /*  Override the traffic led in the EMAC:*/
5741                 if (reg_val == 1) {
5742                         /* Read the current value of the LED register in
5743                         the EMAC block */
5744                         reg_val = REG_RD(bp, emac_base +
5745                                              EMAC_REG_EMAC_LED);
5746                         /* Set the TRAFFIC_OVERRIDE bit to 1 */
5747                         reg_val |= EMAC_LED_OVERRIDE;
5748                         /* If value is 1, set the TRAFFIC bit, otherwise
5749                         reset it.*/
5750                         reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
5751                                 (reg_val & ~EMAC_LED_TRAFFIC);
5752                         REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5753                 } else { /* Override the traffic led in the BMAC: */
5754                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5755                                    + port*4, 1);
5756                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
5757                                     value);
5758                 }
5759                 break;
5760         default:
5761                 DP(NETIF_MSG_LINK,
5762                          "bnx2x_override_led_value() unknown led index %d "
5763                          "(should be 0-5)\n", led_idx);
5764                 return -EINVAL;
5765         }
5766
5767         return 0;
5768 }
5769
5770
5771 u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed)
5772 {
5773         u8 port = params->port;
5774         u16 hw_led_mode = params->hw_led_mode;
5775         u8 rc = 0;
5776         u32 tmp;
5777         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5778         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5779         struct bnx2x *bp = params->bp;
5780         DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5781         DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5782                  speed, hw_led_mode);
5783         switch (mode) {
5784         case LED_MODE_OFF:
5785                 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
5786                 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5787                            SHARED_HW_CFG_LED_MAC1);
5788
5789                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5790                 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
5791                 break;
5792
5793         case LED_MODE_OPER:
5794                 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5795                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
5796                         REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
5797                 } else {
5798                         REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5799                                    hw_led_mode);
5800                 }
5801
5802                 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
5803                            port*4, 0);
5804                 /* Set blinking rate to ~15.9Hz */
5805                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
5806                            LED_BLINK_RATE_VAL);
5807                 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
5808                            port*4, 1);
5809                 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5810                 EMAC_WR(bp, EMAC_REG_EMAC_LED,
5811                             (tmp & (~EMAC_LED_OVERRIDE)));
5812
5813                 if (CHIP_IS_E1(bp) &&
5814                     ((speed == SPEED_2500) ||
5815                      (speed == SPEED_1000) ||
5816                      (speed == SPEED_100) ||
5817                      (speed == SPEED_10))) {
5818                         /* On Everest 1 Ax chip versions for speeds less than
5819                         10G LED scheme is different */
5820                         REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5821                                    + port*4, 1);
5822                         REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
5823                                    port*4, 0);
5824                         REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
5825                                    port*4, 1);
5826                 }
5827                 break;
5828
5829         default:
5830                 rc = -EINVAL;
5831                 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
5832                          mode);
5833                 break;
5834         }
5835         return rc;
5836
5837 }
5838
5839 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
5840 {
5841         struct bnx2x *bp = params->bp;
5842         u16 gp_status = 0;
5843
5844         CL45_RD_OVER_CL22(bp, params->port,
5845                               params->phy_addr,
5846                               MDIO_REG_BANK_GP_STATUS,
5847                               MDIO_GP_STATUS_TOP_AN_STATUS1,
5848                               &gp_status);
5849         /* link is up only if both local phy and external phy are up */
5850         if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
5851             bnx2x_ext_phy_is_link_up(params, vars, 1))
5852                 return 0;
5853
5854         return -ESRCH;
5855 }
5856
5857 static u8 bnx2x_link_initialize(struct link_params *params,
5858                               struct link_vars *vars)
5859 {
5860         struct bnx2x *bp = params->bp;
5861         u8 port = params->port;
5862         u8 rc = 0;
5863         u8 non_ext_phy;
5864         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5865
5866         /* Activate the external PHY */
5867         bnx2x_ext_phy_reset(params, vars);
5868
5869         bnx2x_set_aer_mmd(params, vars);
5870
5871         if (vars->phy_flags & PHY_XGXS_FLAG)
5872                 bnx2x_set_master_ln(params);
5873
5874         rc = bnx2x_reset_unicore(params);
5875         /* reset the SerDes and wait for reset bit return low */
5876         if (rc != 0)
5877                 return rc;
5878
5879         bnx2x_set_aer_mmd(params, vars);
5880
5881         /* setting the masterLn_def again after the reset */
5882         if (vars->phy_flags & PHY_XGXS_FLAG) {
5883                 bnx2x_set_master_ln(params);
5884                 bnx2x_set_swap_lanes(params);
5885         }
5886
5887         if (vars->phy_flags & PHY_XGXS_FLAG) {
5888                 if ((params->req_line_speed &&
5889                     ((params->req_line_speed == SPEED_100) ||
5890                      (params->req_line_speed == SPEED_10))) ||
5891                     (!params->req_line_speed &&
5892                      (params->speed_cap_mask >=
5893                        PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5894                      (params->speed_cap_mask <
5895                        PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
5896                      ))  {
5897                         vars->phy_flags |= PHY_SGMII_FLAG;
5898                 } else {
5899                         vars->phy_flags &= ~PHY_SGMII_FLAG;
5900                 }
5901         }
5902         /* In case of external phy existance, the line speed would be the
5903          line speed linked up by the external phy. In case it is direct only,
5904           then the line_speed during initialization will be equal to the
5905            req_line_speed*/
5906         vars->line_speed = params->req_line_speed;
5907
5908         bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
5909
5910         /* init ext phy and enable link state int */
5911         non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
5912                        (params->loopback_mode == LOOPBACK_XGXS_10));
5913
5914         if (non_ext_phy ||
5915             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
5916             (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
5917             (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5918                 if (params->req_line_speed == SPEED_AUTO_NEG)
5919                         bnx2x_set_parallel_detection(params, vars->phy_flags);
5920                 bnx2x_init_internal_phy(params, vars, non_ext_phy);
5921         }
5922
5923         if (!non_ext_phy)
5924                 rc |= bnx2x_ext_phy_init(params, vars);
5925
5926         bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5927                      (NIG_STATUS_XGXS0_LINK10G |
5928                       NIG_STATUS_XGXS0_LINK_STATUS |
5929                       NIG_STATUS_SERDES0_LINK_STATUS));
5930
5931         return rc;
5932
5933 }
5934
5935
5936 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
5937 {
5938         struct bnx2x *bp = params->bp;
5939         u32 val;
5940
5941         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
5942         DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
5943                  params->req_line_speed, params->req_flow_ctrl);
5944         vars->link_status = 0;
5945         vars->phy_link_up = 0;
5946         vars->link_up = 0;
5947         vars->line_speed = 0;
5948         vars->duplex = DUPLEX_FULL;
5949         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5950         vars->mac_type = MAC_TYPE_NONE;
5951
5952         if (params->switch_cfg ==  SWITCH_CFG_1G)
5953                 vars->phy_flags = PHY_SERDES_FLAG;
5954         else
5955                 vars->phy_flags = PHY_XGXS_FLAG;
5956
5957         /* disable attentions */
5958         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
5959                        (NIG_MASK_XGXS0_LINK_STATUS |
5960                         NIG_MASK_XGXS0_LINK10G |
5961                         NIG_MASK_SERDES0_LINK_STATUS |
5962                         NIG_MASK_MI_INT));
5963
5964         bnx2x_emac_init(params, vars);
5965
5966         if (CHIP_REV_IS_FPGA(bp)) {
5967
5968                 vars->link_up = 1;
5969                 vars->line_speed = SPEED_10000;
5970                 vars->duplex = DUPLEX_FULL;
5971                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5972                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5973                 /* enable on E1.5 FPGA */
5974                 if (CHIP_IS_E1H(bp)) {
5975                         vars->flow_ctrl |=
5976                                         (BNX2X_FLOW_CTRL_TX |
5977                                          BNX2X_FLOW_CTRL_RX);
5978                         vars->link_status |=
5979                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
5980                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
5981                 }
5982
5983                 bnx2x_emac_enable(params, vars, 0);
5984                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5985                 /* disable drain */
5986                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
5987
5988                 /* update shared memory */
5989                 bnx2x_update_mng(params, vars->link_status);
5990
5991                 return 0;
5992
5993         } else
5994         if (CHIP_REV_IS_EMUL(bp)) {
5995
5996                 vars->link_up = 1;
5997                 vars->line_speed = SPEED_10000;
5998                 vars->duplex = DUPLEX_FULL;
5999                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6000                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6001
6002                 bnx2x_bmac_enable(params, vars, 0);
6003
6004                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6005                 /* Disable drain */
6006                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
6007                                     + params->port*4, 0);
6008
6009                 /* update shared memory */
6010                 bnx2x_update_mng(params, vars->link_status);
6011
6012                 return 0;
6013
6014         } else
6015         if (params->loopback_mode == LOOPBACK_BMAC) {
6016
6017                 vars->link_up = 1;
6018                 vars->line_speed = SPEED_10000;
6019                 vars->duplex = DUPLEX_FULL;
6020                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6021                 vars->mac_type = MAC_TYPE_BMAC;
6022
6023                 vars->phy_flags = PHY_XGXS_FLAG;
6024
6025                 bnx2x_phy_deassert(params, vars->phy_flags);
6026                 /* set bmac loopback */
6027                 bnx2x_bmac_enable(params, vars, 1);
6028
6029                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6030                     params->port*4, 0);
6031
6032         } else if (params->loopback_mode == LOOPBACK_EMAC) {
6033
6034                 vars->link_up = 1;
6035                 vars->line_speed = SPEED_1000;
6036                 vars->duplex = DUPLEX_FULL;
6037                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6038                 vars->mac_type = MAC_TYPE_EMAC;
6039
6040                 vars->phy_flags = PHY_XGXS_FLAG;
6041
6042                 bnx2x_phy_deassert(params, vars->phy_flags);
6043                 /* set bmac loopback */
6044                 bnx2x_emac_enable(params, vars, 1);
6045                 bnx2x_emac_program(params, vars->line_speed,
6046                                               vars->duplex);
6047                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6048                     params->port*4, 0);
6049
6050         } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
6051                    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6052
6053                 vars->link_up = 1;
6054                 vars->line_speed = SPEED_10000;
6055                 vars->duplex = DUPLEX_FULL;
6056                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6057
6058                 vars->phy_flags = PHY_XGXS_FLAG;
6059
6060                 val = REG_RD(bp,
6061                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
6062                                  params->port*0x18);
6063                 params->phy_addr = (u8)val;
6064
6065                 bnx2x_phy_deassert(params, vars->phy_flags);
6066                 bnx2x_link_initialize(params, vars);
6067
6068                 vars->mac_type = MAC_TYPE_BMAC;
6069
6070                 bnx2x_bmac_enable(params, vars, 0);
6071
6072                 if (params->loopback_mode == LOOPBACK_XGXS_10) {
6073                         /* set 10G XGXS loopback */
6074                         bnx2x_set_xgxs_loopback(params, vars, 1);
6075                 } else {
6076                         /* set external phy loopback */
6077                         bnx2x_ext_phy_loopback(params);
6078                 }
6079                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6080                             params->port*4, 0);
6081
6082                 bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed);
6083         } else
6084         /* No loopback */
6085         {
6086                 bnx2x_phy_deassert(params, vars->phy_flags);
6087                 switch (params->switch_cfg) {
6088                 case SWITCH_CFG_1G:
6089                         vars->phy_flags |= PHY_SERDES_FLAG;
6090                         if ((params->ext_phy_config &
6091                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
6092                              PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
6093                                 vars->phy_flags |= PHY_SGMII_FLAG;
6094                         }
6095
6096                         val = REG_RD(bp,
6097                                          NIG_REG_SERDES0_CTRL_PHY_ADDR+
6098                                          params->port*0x10);
6099
6100                         params->phy_addr = (u8)val;
6101
6102                         break;
6103                 case SWITCH_CFG_10G:
6104                         vars->phy_flags |= PHY_XGXS_FLAG;
6105                         val = REG_RD(bp,
6106                                  NIG_REG_XGXS0_CTRL_PHY_ADDR+
6107                                  params->port*0x18);
6108                         params->phy_addr = (u8)val;
6109
6110                         break;
6111                 default:
6112                         DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
6113                         return -EINVAL;
6114                 }
6115                 DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
6116
6117                 bnx2x_link_initialize(params, vars);
6118                 msleep(30);
6119                 bnx2x_link_int_enable(params);
6120         }
6121         return 0;
6122 }
6123
6124 static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
6125 {
6126         DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
6127
6128         /* Set serial boot control for external load */
6129         bnx2x_cl45_write(bp, port,
6130                        PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
6131                        MDIO_PMA_DEVAD,
6132                        MDIO_PMA_REG_GEN_CTRL, 0x0001);
6133 }
6134
6135 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6136                   u8 reset_ext_phy)
6137 {
6138         struct bnx2x *bp = params->bp;
6139         u32 ext_phy_config = params->ext_phy_config;
6140         u8 port = params->port;
6141         u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6142         u32 val = REG_RD(bp, params->shmem_base +
6143                              offsetof(struct shmem_region, dev_info.
6144                                       port_feature_config[params->port].
6145                                       config));
6146
6147         /* disable attentions */
6148         vars->link_status = 0;
6149         bnx2x_update_mng(params, vars->link_status);
6150         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6151                      (NIG_MASK_XGXS0_LINK_STATUS |
6152                       NIG_MASK_XGXS0_LINK10G |
6153                       NIG_MASK_SERDES0_LINK_STATUS |
6154                       NIG_MASK_MI_INT));
6155
6156         /* activate nig drain */
6157         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6158
6159         /* disable nig egress interface */
6160         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6161         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6162
6163         /* Stop BigMac rx */
6164         bnx2x_bmac_rx_disable(bp, port);
6165
6166         /* disable emac */
6167         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6168
6169         msleep(10);
6170         /* The PHY reset is controled by GPIO 1
6171          * Hold it as vars low
6172          */
6173          /* clear link led */
6174         bnx2x_set_led(params, LED_MODE_OFF, 0);
6175         if (reset_ext_phy) {
6176                 switch (ext_phy_type) {
6177                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
6178                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
6179                         break;
6180
6181                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6182                 {
6183
6184                         /* Disable Transmitter */
6185                         u8 ext_phy_addr =
6186                                 XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6187                         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
6188                             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
6189                                 bnx2x_sfp_set_transmitter(bp, port,
6190                                         PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6191                                         ext_phy_addr, 0);
6192                         break;
6193                 }
6194                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6195                         DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
6196                                  "low power mode\n",
6197                                  port);
6198                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6199                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6200                                           port);
6201                         break;
6202                 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6203                 {
6204                         u8 ext_phy_addr =
6205                                 XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6206                         /* Set soft reset */
6207                         bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
6208                         break;
6209                 }
6210                 default:
6211                         /* HW reset */
6212                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6213                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6214                                           port);
6215                         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6216                                           MISC_REGISTERS_GPIO_OUTPUT_LOW,
6217                                           port);
6218                         DP(NETIF_MSG_LINK, "reset external PHY\n");
6219                 }
6220         }
6221         /* reset the SerDes/XGXS */
6222         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6223                (0x1ff << (port*16)));
6224
6225         /* reset BigMac */
6226         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
6227                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6228
6229         /* disable nig ingress interface */
6230         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
6231         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
6232         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6233         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6234         vars->link_up = 0;
6235         return 0;
6236 }
6237
6238 static u8 bnx2x_update_link_down(struct link_params *params,
6239                                struct link_vars *vars)
6240 {
6241         struct bnx2x *bp = params->bp;
6242         u8 port = params->port;
6243
6244         DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
6245         bnx2x_set_led(params, LED_MODE_OFF, 0);
6246
6247         /* indicate no mac active */
6248         vars->mac_type = MAC_TYPE_NONE;
6249
6250         /* update shared memory */
6251         vars->link_status = 0;
6252         vars->line_speed = 0;
6253         bnx2x_update_mng(params, vars->link_status);
6254
6255         /* activate nig drain */
6256         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6257
6258         /* disable emac */
6259         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6260
6261         msleep(10);
6262
6263         /* reset BigMac */
6264         bnx2x_bmac_rx_disable(bp, params->port);
6265         REG_WR(bp, GRCBASE_MISC +
6266                    MISC_REGISTERS_RESET_REG_2_CLEAR,
6267                    (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6268         return 0;
6269 }
6270
6271 static u8 bnx2x_update_link_up(struct link_params *params,
6272                              struct link_vars *vars,
6273                              u8 link_10g, u32 gp_status)
6274 {
6275         struct bnx2x *bp = params->bp;
6276         u8 port = params->port;
6277         u8 rc = 0;
6278
6279         vars->link_status |= LINK_STATUS_LINK_UP;
6280         if (link_10g) {
6281                 bnx2x_bmac_enable(params, vars, 0);
6282                 bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000);
6283         } else {
6284                 bnx2x_emac_enable(params, vars, 0);
6285                 rc = bnx2x_emac_program(params, vars->line_speed,
6286                                       vars->duplex);
6287
6288                 /* AN complete? */
6289                 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
6290                         if (!(vars->phy_flags &
6291                               PHY_SGMII_FLAG))
6292                                 bnx2x_set_gmii_tx_driver(params);
6293                 }
6294         }
6295
6296         /* PBF - link up */
6297         rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6298                               vars->line_speed);
6299
6300         /* disable drain */
6301         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6302
6303         /* update shared memory */
6304         bnx2x_update_mng(params, vars->link_status);
6305         msleep(20);
6306         return rc;
6307 }
6308 /* This function should called upon link interrupt */
6309 /* In case vars->link_up, driver needs to
6310         1. Update the pbf
6311         2. Disable drain
6312         3. Update the shared memory
6313         4. Indicate link up
6314         5. Set LEDs
6315    Otherwise,
6316         1. Update shared memory
6317         2. Reset BigMac
6318         3. Report link down
6319         4. Unset LEDs
6320 */
6321 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6322 {
6323         struct bnx2x *bp = params->bp;
6324         u8 port = params->port;
6325         u16 gp_status;
6326         u8 link_10g;
6327         u8 ext_phy_link_up, rc = 0;
6328         u32 ext_phy_type;
6329         u8 is_mi_int = 0;
6330
6331         DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6332                  port, (vars->phy_flags & PHY_XGXS_FLAG),
6333                  REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6334
6335         is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6336                                     port*0x18) > 0);
6337         DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6338                  REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6339                  is_mi_int,
6340                  REG_RD(bp,
6341                             NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6342
6343         DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6344           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6345           REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6346
6347         /* disable emac */
6348         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6349
6350         ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
6351
6352         /* Check external link change only for non-direct */
6353         ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int);
6354
6355         /* Read gp_status */
6356         CL45_RD_OVER_CL22(bp, port, params->phy_addr,
6357                               MDIO_REG_BANK_GP_STATUS,
6358                               MDIO_GP_STATUS_TOP_AN_STATUS1,
6359                               &gp_status);
6360
6361         rc = bnx2x_link_settings_status(params, vars, gp_status,
6362                                       ext_phy_link_up);
6363         if (rc != 0)
6364                 return rc;
6365
6366         /* anything 10 and over uses the bmac */
6367         link_10g = ((vars->line_speed == SPEED_10000) ||
6368                     (vars->line_speed == SPEED_12000) ||
6369                     (vars->line_speed == SPEED_12500) ||
6370                     (vars->line_speed == SPEED_13000) ||
6371                     (vars->line_speed == SPEED_15000) ||
6372                     (vars->line_speed == SPEED_16000));
6373
6374         bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
6375
6376         /* In case external phy link is up, and internal link is down
6377         ( not initialized yet probably after link initialization, it needs
6378         to be initialized.
6379         Note that after link down-up as result of cable plug,
6380         the xgxs link would probably become up again without the need to
6381         initialize it*/
6382
6383         if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
6384             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
6385             (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
6386             (ext_phy_link_up && !vars->phy_link_up))
6387                 bnx2x_init_internal_phy(params, vars, 0);
6388
6389         /* link is up only if both local phy and external phy are up */
6390         vars->link_up = (ext_phy_link_up && vars->phy_link_up);
6391
6392         if (vars->link_up)
6393                 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
6394         else
6395                 rc = bnx2x_update_link_down(params, vars);
6396
6397         return rc;
6398 }
6399
6400 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6401 {
6402         u8 ext_phy_addr[PORT_MAX];
6403         u16 val;
6404         s8 port;
6405
6406         /* PART1 - Reset both phys */
6407         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6408                 /* Extract the ext phy address for the port */
6409                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6410                                         offsetof(struct shmem_region,
6411                    dev_info.port_hw_config[port].external_phy_config));
6412
6413                 /* disable attentions */
6414                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6415                              (NIG_MASK_XGXS0_LINK_STATUS |
6416                               NIG_MASK_XGXS0_LINK10G |
6417                               NIG_MASK_SERDES0_LINK_STATUS |
6418                               NIG_MASK_MI_INT));
6419
6420                 ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
6421
6422                 /* Need to take the phy out of low power mode in order
6423                         to write to access its registers */
6424                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6425                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6426
6427                 /* Reset the phy */
6428                 bnx2x_cl45_write(bp, port,
6429                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6430                                ext_phy_addr[port],
6431                                MDIO_PMA_DEVAD,
6432                                MDIO_PMA_REG_CTRL,
6433                                1<<15);
6434         }
6435
6436         /* Add delay of 150ms after reset */
6437         msleep(150);
6438
6439         /* PART2 - Download firmware to both phys */
6440         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6441                 u16 fw_ver1;
6442
6443                 bnx2x_bcm8073_external_rom_boot(bp, port,
6444                                               ext_phy_addr[port], shmem_base);
6445
6446                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6447                               ext_phy_addr[port],
6448                               MDIO_PMA_DEVAD,
6449                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6450                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6451                         DP(NETIF_MSG_LINK,
6452                                  "bnx2x_8073_common_init_phy port %x:"
6453                                  "Download failed. fw version = 0x%x\n",
6454                                  port, fw_ver1);
6455                         return -EINVAL;
6456                 }
6457
6458                 /* Only set bit 10 = 1 (Tx power down) */
6459                 bnx2x_cl45_read(bp, port,
6460                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6461                               ext_phy_addr[port],
6462                               MDIO_PMA_DEVAD,
6463                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
6464
6465                 /* Phase1 of TX_POWER_DOWN reset */
6466                 bnx2x_cl45_write(bp, port,
6467                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6468                                ext_phy_addr[port],
6469                                MDIO_PMA_DEVAD,
6470                                MDIO_PMA_REG_TX_POWER_DOWN,
6471                                (val | 1<<10));
6472         }
6473
6474         /* Toggle Transmitter: Power down and then up with 600ms
6475            delay between */
6476         msleep(600);
6477
6478         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
6479         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6480                 /* Phase2 of POWER_DOWN_RESET */
6481                 /* Release bit 10 (Release Tx power down) */
6482                 bnx2x_cl45_read(bp, port,
6483                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6484                               ext_phy_addr[port],
6485                               MDIO_PMA_DEVAD,
6486                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
6487
6488                 bnx2x_cl45_write(bp, port,
6489                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6490                                ext_phy_addr[port],
6491                                MDIO_PMA_DEVAD,
6492                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
6493                 msleep(15);
6494
6495                 /* Read modify write the SPI-ROM version select register */
6496                 bnx2x_cl45_read(bp, port,
6497                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6498                               ext_phy_addr[port],
6499                               MDIO_PMA_DEVAD,
6500                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
6501                 bnx2x_cl45_write(bp, port,
6502                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6503                               ext_phy_addr[port],
6504                               MDIO_PMA_DEVAD,
6505                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
6506
6507                 /* set GPIO2 back to LOW */
6508                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6509                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6510         }
6511         return 0;
6512
6513 }
6514
6515 static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6516 {
6517         u8 ext_phy_addr[PORT_MAX];
6518         s8 port, first_port, i;
6519         u32 swap_val, swap_override;
6520         DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
6521         swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
6522         swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
6523
6524         bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override));
6525         msleep(5);
6526
6527         if (swap_val && swap_override)
6528                 first_port = PORT_0;
6529         else
6530                 first_port = PORT_1;
6531
6532         /* PART1 - Reset both phys */
6533         for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
6534                 /* Extract the ext phy address for the port */
6535                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6536                                         offsetof(struct shmem_region,
6537                    dev_info.port_hw_config[port].external_phy_config));
6538
6539                 /* disable attentions */
6540                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6541                              (NIG_MASK_XGXS0_LINK_STATUS |
6542                               NIG_MASK_XGXS0_LINK10G |
6543                               NIG_MASK_SERDES0_LINK_STATUS |
6544                               NIG_MASK_MI_INT));
6545
6546                 ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
6547
6548                 /* Reset the phy */
6549                 bnx2x_cl45_write(bp, port,
6550                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6551                                ext_phy_addr[port],
6552                                MDIO_PMA_DEVAD,
6553                                MDIO_PMA_REG_CTRL,
6554                                1<<15);
6555         }
6556
6557         /* Add delay of 150ms after reset */
6558         msleep(150);
6559
6560         /* PART2 - Download firmware to both phys */
6561         for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
6562                 u16 fw_ver1;
6563
6564                 bnx2x_bcm8727_external_rom_boot(bp, port,
6565                                               ext_phy_addr[port], shmem_base);
6566
6567                 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6568                               ext_phy_addr[port],
6569                               MDIO_PMA_DEVAD,
6570                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6571                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6572                         DP(NETIF_MSG_LINK,
6573                                  "bnx2x_8727_common_init_phy port %x:"
6574                                  "Download failed. fw version = 0x%x\n",
6575                                  port, fw_ver1);
6576                         return -EINVAL;
6577                 }
6578         }
6579
6580         return 0;
6581 }
6582
6583
6584 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6585 {
6586         u8 ext_phy_addr;
6587         u32 val;
6588         s8 port;
6589
6590         /* Use port1 because of the static port-swap */
6591         /* Enable the module detection interrupt */
6592         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
6593         val |= ((1<<MISC_REGISTERS_GPIO_3)|
6594                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
6595         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
6596
6597         bnx2x_ext_phy_hw_reset(bp, 1);
6598         msleep(5);
6599         for (port = 0; port < PORT_MAX; port++) {
6600                 /* Extract the ext phy address for the port */
6601                 u32 ext_phy_config = REG_RD(bp, shmem_base +
6602                                         offsetof(struct shmem_region,
6603                         dev_info.port_hw_config[port].external_phy_config));
6604
6605                 ext_phy_addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
6606                 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
6607                          ext_phy_addr);
6608
6609                 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
6610
6611                 /* Set fault module detected LED on */
6612                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6613                                   MISC_REGISTERS_GPIO_HIGH,
6614                                   port);
6615         }
6616
6617         return 0;
6618 }
6619
6620 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6621 {
6622         u8 rc = 0;
6623         u32 ext_phy_type;
6624
6625         DP(NETIF_MSG_LINK, "Begin common phy init\n");
6626
6627         /* Read the ext_phy_type for arbitrary port(0) */
6628         ext_phy_type = XGXS_EXT_PHY_TYPE(
6629                         REG_RD(bp, shmem_base +
6630                            offsetof(struct shmem_region,
6631                              dev_info.port_hw_config[0].external_phy_config)));
6632
6633         switch (ext_phy_type) {
6634         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6635         {
6636                 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
6637                 break;
6638         }
6639
6640         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6641         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6642                 rc = bnx2x_8727_common_init_phy(bp, shmem_base);
6643                 break;
6644
6645         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6646                 /* GPIO1 affects both ports, so there's need to pull
6647                 it for single port alone */
6648                 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
6649
6650                 break;
6651         default:
6652                 DP(NETIF_MSG_LINK,
6653                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
6654                          ext_phy_type);
6655                 break;
6656         }
6657
6658         return rc;
6659 }
6660
6661 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
6662 {
6663         u16 val, cnt;
6664
6665         bnx2x_cl45_read(bp, port,
6666                       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6667                       phy_addr,
6668                       MDIO_PMA_DEVAD,
6669                       MDIO_PMA_REG_7101_RESET, &val);
6670
6671         for (cnt = 0; cnt < 10; cnt++) {
6672                 msleep(50);
6673                 /* Writes a self-clearing reset */
6674                 bnx2x_cl45_write(bp, port,
6675                                PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6676                                phy_addr,
6677                                MDIO_PMA_DEVAD,
6678                                MDIO_PMA_REG_7101_RESET,
6679                                (val | (1<<15)));
6680                 /* Wait for clear */
6681                 bnx2x_cl45_read(bp, port,
6682                               PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6683                               phy_addr,
6684                               MDIO_PMA_DEVAD,
6685                               MDIO_PMA_REG_7101_RESET, &val);
6686
6687                 if ((val & (1<<15)) == 0)
6688                         break;
6689         }
6690 }