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