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