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