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