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