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