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