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