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