]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/net/bnx2x/bnx2x_link.c
488e251a2d3ffa1183f04a384ed4439133a86232
[net-next-2.6.git] / drivers / net / bnx2x / bnx2x_link.c
1 /* Copyright 2008-2009 Broadcom Corporation
2  *
3  * Unless you and Broadcom execute a separate written software license
4  * agreement governing use of this software, this software is licensed to you
5  * under the terms of the GNU General Public License version 2, available
6  * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7  *
8  * Notwithstanding the above, under no circumstances may you combine this
9  * software in any way with any other Broadcom software provided under a
10  * license other than the GPL, without Broadcom's express prior written
11  * consent.
12  *
13  * Written by Yaniv Rosner
14  *
15  */
16
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/pci.h>
22 #include <linux/netdevice.h>
23 #include <linux/delay.h>
24 #include <linux/ethtool.h>
25 #include <linux/mutex.h>
26
27 #include "bnx2x.h"
28
29 /********************************************************/
30 #define ETH_HLEN                        14
31 #define ETH_OVREHEAD            (ETH_HLEN + 8 + 8)/* 16 for CRC + VLAN + LLC */
32 #define ETH_MIN_PACKET_SIZE             60
33 #define ETH_MAX_PACKET_SIZE             1500
34 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
35 #define MDIO_ACCESS_TIMEOUT             1000
36 #define BMAC_CONTROL_RX_ENABLE  2
37
38 /***********************************************************/
39 /*                      Shortcut definitions               */
40 /***********************************************************/
41
42 #define NIG_LATCH_BC_ENABLE_MI_INT 0
43
44 #define NIG_STATUS_EMAC0_MI_INT \
45                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
46 #define NIG_STATUS_XGXS0_LINK10G \
47                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
48 #define NIG_STATUS_XGXS0_LINK_STATUS \
49                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
50 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
51                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
52 #define NIG_STATUS_SERDES0_LINK_STATUS \
53                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
54 #define NIG_MASK_MI_INT \
55                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
56 #define NIG_MASK_XGXS0_LINK10G \
57                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
58 #define NIG_MASK_XGXS0_LINK_STATUS \
59                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
60 #define NIG_MASK_SERDES0_LINK_STATUS \
61                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
62
63 #define MDIO_AN_CL73_OR_37_COMPLETE \
64                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
65                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
66
67 #define XGXS_RESET_BITS \
68         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
69          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
70          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
71          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
72          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
73
74 #define SERDES_RESET_BITS \
75         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
76          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
77          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
78          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
79
80 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
81 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
82 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
83 #define AUTONEG_PARALLEL \
84                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
85 #define AUTONEG_SGMII_FIBER_AUTODET \
86                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
87 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
88
89 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
90                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
91 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
92                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
93 #define GP_STATUS_SPEED_MASK \
94                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
95 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
96 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
97 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
98 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
99 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
100 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
101 #define GP_STATUS_10G_HIG \
102                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
103 #define GP_STATUS_10G_CX4 \
104                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
105 #define GP_STATUS_12G_HIG \
106                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
107 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
108 #define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
109 #define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
110 #define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
111 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
112 #define GP_STATUS_10G_KX4 \
113                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114
115 #define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
116 #define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
117 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
118 #define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
119 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
120 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
121 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
122 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
123 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
124 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
125 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
126 #define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
127 #define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
128 #define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
129 #define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
130 #define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
131 #define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
132 #define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
133 #define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
134 #define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
135 #define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
136 #define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
137 #define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138
139 #define PHY_XGXS_FLAG                   0x1
140 #define PHY_SGMII_FLAG                  0x2
141 #define PHY_SERDES_FLAG                 0x4
142
143 /* */
144 #define SFP_EEPROM_CON_TYPE_ADDR                0x2
145         #define SFP_EEPROM_CON_TYPE_VAL_LC              0x7
146         #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
147
148
149 #define SFP_EEPROM_COMP_CODE_ADDR               0x3
150         #define SFP_EEPROM_COMP_CODE_SR_MASK    (1<<4)
151         #define SFP_EEPROM_COMP_CODE_LR_MASK    (1<<5)
152         #define SFP_EEPROM_COMP_CODE_LRM_MASK   (1<<6)
153
154 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
155         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
156         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE      0x8
157
158 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
159         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
160 #define SFP_EEPROM_OPTIONS_SIZE                 2
161
162 #define EDC_MODE_LINEAR                         0x0022
163 #define EDC_MODE_LIMITING                               0x0044
164 #define EDC_MODE_PASSIVE_DAC                    0x0055
165
166
167
168 /**********************************************************/
169 /*                     INTERFACE                          */
170 /**********************************************************/
171
172 #define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
173         bnx2x_cl45_write(_bp, _phy, \
174                 (_phy)->def_md_devad, \
175                 (_bank + (_addr & 0xf)), \
176                 _val)
177
178 #define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
179         bnx2x_cl45_read(_bp, _phy, \
180                 (_phy)->def_md_devad, \
181                 (_bank + (_addr & 0xf)), \
182                 _val)
183
184 static 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         msleep(1);
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
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         bnx2x_wait_reset_complete(bp, phy);
5435
5436         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
5437         return bnx2x_848xx_cmn_config_init(phy, params, vars);
5438 }
5439
5440 static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
5441                                   struct link_params *params,
5442                                   struct link_vars *vars)
5443 {
5444         struct bnx2x *bp = params->bp;
5445         u8 port, initialize = 1;
5446         u16 val;
5447         u16 temp;
5448         u32 actual_phy_selection;
5449         u8 rc = 0;
5450
5451         /* This is just for MDIO_CTL_REG_84823_MEDIA register. */
5452
5453         msleep(1);
5454         if (CHIP_IS_E2(bp))
5455                 port = BP_PATH(bp);
5456         else
5457                 port = params->port;
5458         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
5459                        MISC_REGISTERS_GPIO_OUTPUT_HIGH,
5460                        port);
5461         bnx2x_wait_reset_complete(bp, phy);
5462         /* Wait for GPHY to come out of reset */
5463         msleep(50);
5464         /* BCM84823 requires that XGXS links up first @ 10G for normal
5465         behavior */
5466         temp = vars->line_speed;
5467         vars->line_speed = SPEED_10000;
5468         bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
5469         bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
5470         vars->line_speed = temp;
5471
5472         /* Set dual-media configuration according to configuration */
5473
5474         bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
5475                         MDIO_CTL_REG_84823_MEDIA, &val);
5476         val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
5477                  MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
5478                  MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
5479                  MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
5480                  MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
5481         val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
5482                 MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
5483
5484         actual_phy_selection = bnx2x_phy_selection(params);
5485
5486         switch (actual_phy_selection) {
5487         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
5488                 /* Do nothing. Essentialy this is like the priority copper */
5489                 break;
5490         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
5491                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
5492                 break;
5493         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
5494                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
5495                 break;
5496         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
5497                 /* Do nothing here. The first PHY won't be initialized at all */
5498                 break;
5499         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
5500                 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
5501                 initialize = 0;
5502                 break;
5503         }
5504         if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
5505                 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
5506
5507         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
5508                          MDIO_CTL_REG_84823_MEDIA, val);
5509         DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
5510                    params->multi_phy_config, val);
5511
5512         if (initialize)
5513                 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
5514         else
5515                 bnx2x_save_848xx_spirom_version(phy, params);
5516         return rc;
5517 }
5518
5519 static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
5520                                        struct link_params *params,
5521                                        struct link_vars *vars)
5522 {
5523         struct bnx2x *bp = params->bp;
5524         u16 val, val1, val2;
5525         u8 link_up = 0;
5526
5527         /* Check 10G-BaseT link status */
5528         /* Check PMD signal ok */
5529         bnx2x_cl45_read(bp, phy,
5530                         MDIO_AN_DEVAD, 0xFFFA, &val1);
5531         bnx2x_cl45_read(bp, phy,
5532                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
5533                         &val2);
5534         DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
5535
5536         /* Check link 10G */
5537         if (val2 & (1<<11)) {
5538                 vars->line_speed = SPEED_10000;
5539                 link_up = 1;
5540                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
5541         } else { /* Check Legacy speed link */
5542                 u16 legacy_status, legacy_speed;
5543
5544                 /* Enable expansion register 0x42 (Operation mode status) */
5545                 bnx2x_cl45_write(bp, phy,
5546                                  MDIO_AN_DEVAD,
5547                                  MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
5548
5549                 /* Get legacy speed operation status */
5550                 bnx2x_cl45_read(bp, phy,
5551                                 MDIO_AN_DEVAD,
5552                                 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
5553                                 &legacy_status);
5554
5555                 DP(NETIF_MSG_LINK, "Legacy speed status"
5556                              " = 0x%x\n", legacy_status);
5557                 link_up = ((legacy_status & (1<<11)) == (1<<11));
5558                 if (link_up) {
5559                         legacy_speed = (legacy_status & (3<<9));
5560                         if (legacy_speed == (0<<9))
5561                                 vars->line_speed = SPEED_10;
5562                         else if (legacy_speed == (1<<9))
5563                                 vars->line_speed = SPEED_100;
5564                         else if (legacy_speed == (2<<9))
5565                                 vars->line_speed = SPEED_1000;
5566                         else /* Should not happen */
5567                                 vars->line_speed = 0;
5568
5569                         if (legacy_status & (1<<8))
5570                                 vars->duplex = DUPLEX_FULL;
5571                         else
5572                                 vars->duplex = DUPLEX_HALF;
5573
5574                         DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
5575                                    " is_duplex_full= %d\n", vars->line_speed,
5576                                    (vars->duplex == DUPLEX_FULL));
5577                         /* Check legacy speed AN resolution */
5578                         bnx2x_cl45_read(bp, phy,
5579                                         MDIO_AN_DEVAD,
5580                                         MDIO_AN_REG_8481_LEGACY_MII_STATUS,
5581                                         &val);
5582                         if (val & (1<<5))
5583                                 vars->link_status |=
5584                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5585                         bnx2x_cl45_read(bp, phy,
5586                                         MDIO_AN_DEVAD,
5587                                         MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
5588                                         &val);
5589                         if ((val & (1<<0)) == 0)
5590                                 vars->link_status |=
5591                                         LINK_STATUS_PARALLEL_DETECTION_USED;
5592                 }
5593         }
5594         if (link_up) {
5595                 DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
5596                            vars->line_speed);
5597                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5598         }
5599
5600         return link_up;
5601 }
5602
5603 static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
5604 {
5605         u8 status = 0;
5606         u32 spirom_ver;
5607         spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
5608         status = bnx2x_format_ver(spirom_ver, str, len);
5609         return status;
5610 }
5611
5612 static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
5613                                 struct link_params *params)
5614 {
5615         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5616                             MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
5617         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5618                             MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
5619 }
5620
5621 static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
5622                                         struct link_params *params)
5623 {
5624         bnx2x_cl45_write(params->bp, phy,
5625                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
5626         bnx2x_cl45_write(params->bp, phy,
5627                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
5628 }
5629
5630 static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
5631                                    struct link_params *params)
5632 {
5633         struct bnx2x *bp = params->bp;
5634         u8 port;
5635         if (CHIP_IS_E2(bp))
5636                 port = BP_PATH(bp);
5637         else
5638                 port = params->port;
5639         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
5640                             MISC_REGISTERS_GPIO_OUTPUT_LOW,
5641                             port);
5642 }
5643
5644 static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
5645                                      struct link_params *params, u8 mode)
5646 {
5647         struct bnx2x *bp = params->bp;
5648         u16 val;
5649
5650         switch (mode) {
5651         case LED_MODE_OFF:
5652
5653                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port);
5654
5655                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
5656                     SHARED_HW_CFG_LED_EXTPHY1) {
5657
5658                         /* Set LED masks */
5659                         bnx2x_cl45_write(bp, phy,
5660                                         MDIO_PMA_DEVAD,
5661                                         MDIO_PMA_REG_8481_LED1_MASK,
5662                                         0x0);
5663
5664                         bnx2x_cl45_write(bp, phy,
5665                                         MDIO_PMA_DEVAD,
5666                                         MDIO_PMA_REG_8481_LED2_MASK,
5667                                         0x0);
5668
5669                         bnx2x_cl45_write(bp, phy,
5670                                         MDIO_PMA_DEVAD,
5671                                         MDIO_PMA_REG_8481_LED3_MASK,
5672                                         0x0);
5673
5674                         bnx2x_cl45_write(bp, phy,
5675                                         MDIO_PMA_DEVAD,
5676                                         MDIO_PMA_REG_8481_LED5_MASK,
5677                                         0x0);
5678
5679                 } else {
5680                         bnx2x_cl45_write(bp, phy,
5681                                          MDIO_PMA_DEVAD,
5682                                          MDIO_PMA_REG_8481_LED1_MASK,
5683                                          0x0);
5684                 }
5685                 break;
5686         case LED_MODE_FRONT_PANEL_OFF:
5687
5688                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
5689                    params->port);
5690
5691                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
5692                     SHARED_HW_CFG_LED_EXTPHY1) {
5693
5694                         /* Set LED masks */
5695                         bnx2x_cl45_write(bp, phy,
5696                                         MDIO_PMA_DEVAD,
5697                                         MDIO_PMA_REG_8481_LED1_MASK,
5698                                         0x0);
5699
5700                         bnx2x_cl45_write(bp, phy,
5701                                         MDIO_PMA_DEVAD,
5702                                         MDIO_PMA_REG_8481_LED2_MASK,
5703                                         0x0);
5704
5705                         bnx2x_cl45_write(bp, phy,
5706                                         MDIO_PMA_DEVAD,
5707                                         MDIO_PMA_REG_8481_LED3_MASK,
5708                                         0x0);
5709
5710                         bnx2x_cl45_write(bp, phy,
5711                                         MDIO_PMA_DEVAD,
5712                                         MDIO_PMA_REG_8481_LED5_MASK,
5713                                         0x20);
5714
5715                 } else {
5716                         bnx2x_cl45_write(bp, phy,
5717                                          MDIO_PMA_DEVAD,
5718                                          MDIO_PMA_REG_8481_LED1_MASK,
5719                                          0x0);
5720                 }
5721                 break;
5722         case LED_MODE_ON:
5723
5724                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port);
5725
5726                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
5727                     SHARED_HW_CFG_LED_EXTPHY1) {
5728                         /* Set control reg */
5729                         bnx2x_cl45_read(bp, phy,
5730                                         MDIO_PMA_DEVAD,
5731                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
5732                                         &val);
5733                         val &= 0x8000;
5734                         val |= 0x2492;
5735
5736                         bnx2x_cl45_write(bp, phy,
5737                                         MDIO_PMA_DEVAD,
5738                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
5739                                         val);
5740
5741                         /* Set LED masks */
5742                         bnx2x_cl45_write(bp, phy,
5743                                         MDIO_PMA_DEVAD,
5744                                         MDIO_PMA_REG_8481_LED1_MASK,
5745                                         0x0);
5746
5747                         bnx2x_cl45_write(bp, phy,
5748                                         MDIO_PMA_DEVAD,
5749                                         MDIO_PMA_REG_8481_LED2_MASK,
5750                                         0x20);
5751
5752                         bnx2x_cl45_write(bp, phy,
5753                                         MDIO_PMA_DEVAD,
5754                                         MDIO_PMA_REG_8481_LED3_MASK,
5755                                         0x20);
5756
5757                         bnx2x_cl45_write(bp, phy,
5758                                         MDIO_PMA_DEVAD,
5759                                         MDIO_PMA_REG_8481_LED5_MASK,
5760                                         0x0);
5761                 } else {
5762                         bnx2x_cl45_write(bp, phy,
5763                                         MDIO_PMA_DEVAD,
5764                                         MDIO_PMA_REG_8481_LED1_MASK,
5765                                         0x20);
5766                 }
5767                 break;
5768
5769         case LED_MODE_OPER:
5770
5771                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port);
5772
5773                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
5774                     SHARED_HW_CFG_LED_EXTPHY1) {
5775
5776                         /* Set control reg */
5777                         bnx2x_cl45_read(bp, phy,
5778                                         MDIO_PMA_DEVAD,
5779                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
5780                                         &val);
5781
5782                         if (!((val &
5783                               MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
5784                            >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)){
5785                                 DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n");
5786                                 bnx2x_cl45_write(bp, phy,
5787                                                  MDIO_PMA_DEVAD,
5788                                                  MDIO_PMA_REG_8481_LINK_SIGNAL,
5789                                                  0xa492);
5790                         }
5791
5792                         /* Set LED masks */
5793                         bnx2x_cl45_write(bp, phy,
5794                                         MDIO_PMA_DEVAD,
5795                                         MDIO_PMA_REG_8481_LED1_MASK,
5796                                         0x10);
5797
5798                         bnx2x_cl45_write(bp, phy,
5799                                         MDIO_PMA_DEVAD,
5800                                         MDIO_PMA_REG_8481_LED2_MASK,
5801                                         0x80);
5802
5803                         bnx2x_cl45_write(bp, phy,
5804                                         MDIO_PMA_DEVAD,
5805                                         MDIO_PMA_REG_8481_LED3_MASK,
5806                                         0x98);
5807
5808                         bnx2x_cl45_write(bp, phy,
5809                                         MDIO_PMA_DEVAD,
5810                                         MDIO_PMA_REG_8481_LED5_MASK,
5811                                         0x40);
5812
5813                 } else {
5814                         bnx2x_cl45_write(bp, phy,
5815                                          MDIO_PMA_DEVAD,
5816                                          MDIO_PMA_REG_8481_LED1_MASK,
5817                                          0x80);
5818                 }
5819                 break;
5820         }
5821 }
5822 /******************************************************************/
5823 /*                      SFX7101 PHY SECTION                       */
5824 /******************************************************************/
5825 static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
5826                                        struct link_params *params)
5827 {
5828         struct bnx2x *bp = params->bp;
5829         /* SFX7101_XGXS_TEST1 */
5830         bnx2x_cl45_write(bp, phy,
5831                          MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
5832 }
5833
5834 static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
5835                                  struct link_params *params,
5836                                  struct link_vars *vars)
5837 {
5838         u16 fw_ver1, fw_ver2, val;
5839         struct bnx2x *bp = params->bp;
5840         DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
5841
5842         /* Restore normal power mode*/
5843         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5844                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5845         /* HW reset */
5846         bnx2x_ext_phy_hw_reset(bp, params->port);
5847         bnx2x_wait_reset_complete(bp, phy);
5848
5849         bnx2x_cl45_write(bp, phy,
5850                          MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
5851         DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
5852         bnx2x_cl45_write(bp, phy,
5853                          MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
5854
5855         bnx2x_ext_phy_set_pause(params, phy, vars);
5856         /* Restart autoneg */
5857         bnx2x_cl45_read(bp, phy,
5858                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
5859         val |= 0x200;
5860         bnx2x_cl45_write(bp, phy,
5861                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
5862
5863         /* Save spirom version */
5864         bnx2x_cl45_read(bp, phy,
5865                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
5866
5867         bnx2x_cl45_read(bp, phy,
5868                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
5869         bnx2x_save_spirom_version(bp, params->port,
5870                                   (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
5871         return 0;
5872 }
5873
5874 static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
5875                                  struct link_params *params,
5876                                  struct link_vars *vars)
5877 {
5878         struct bnx2x *bp = params->bp;
5879         u8 link_up;
5880         u16 val1, val2;
5881         bnx2x_cl45_read(bp, phy,
5882                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
5883         bnx2x_cl45_read(bp, phy,
5884                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
5885         DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
5886                    val2, val1);
5887         bnx2x_cl45_read(bp, phy,
5888                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
5889         bnx2x_cl45_read(bp, phy,
5890                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
5891         DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
5892                    val2, val1);
5893         link_up = ((val1 & 4) == 4);
5894         /* if link is up
5895          * print the AN outcome of the SFX7101 PHY
5896          */
5897         if (link_up) {
5898                 bnx2x_cl45_read(bp, phy,
5899                                 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
5900                                 &val2);
5901                 vars->line_speed = SPEED_10000;
5902                 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
5903                            val2, (val2 & (1<<14)));
5904                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
5905                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5906         }
5907         return link_up;
5908 }
5909
5910
5911 static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
5912 {
5913         if (*len < 5)
5914                 return -EINVAL;
5915         str[0] = (spirom_ver & 0xFF);
5916         str[1] = (spirom_ver & 0xFF00) >> 8;
5917         str[2] = (spirom_ver & 0xFF0000) >> 16;
5918         str[3] = (spirom_ver & 0xFF000000) >> 24;
5919         str[4] = '\0';
5920         *len -= 5;
5921         return 0;
5922 }
5923
5924 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
5925 {
5926         u16 val, cnt;
5927
5928         bnx2x_cl45_read(bp, phy,
5929                       MDIO_PMA_DEVAD,
5930                       MDIO_PMA_REG_7101_RESET, &val);
5931
5932         for (cnt = 0; cnt < 10; cnt++) {
5933                 msleep(50);
5934                 /* Writes a self-clearing reset */
5935                 bnx2x_cl45_write(bp, phy,
5936                                MDIO_PMA_DEVAD,
5937                                MDIO_PMA_REG_7101_RESET,
5938                                (val | (1<<15)));
5939                 /* Wait for clear */
5940                 bnx2x_cl45_read(bp, phy,
5941                               MDIO_PMA_DEVAD,
5942                               MDIO_PMA_REG_7101_RESET, &val);
5943
5944                 if ((val & (1<<15)) == 0)
5945                         break;
5946         }
5947 }
5948
5949 static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
5950                                 struct link_params *params) {
5951         /* Low power mode is controlled by GPIO 2 */
5952         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
5953                             MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
5954         /* The PHY reset is controlled by GPIO 1 */
5955         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5956                             MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
5957 }
5958
5959 static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
5960                                     struct link_params *params, u8 mode)
5961 {
5962         u16 val = 0;
5963         struct bnx2x *bp = params->bp;
5964         switch (mode) {
5965         case LED_MODE_FRONT_PANEL_OFF:
5966         case LED_MODE_OFF:
5967                 val = 2;
5968                 break;
5969         case LED_MODE_ON:
5970                 val = 1;
5971                 break;
5972         case LED_MODE_OPER:
5973                 val = 0;
5974                 break;
5975         }
5976         bnx2x_cl45_write(bp, phy,
5977                          MDIO_PMA_DEVAD,
5978                          MDIO_PMA_REG_7107_LINK_LED_CNTL,
5979                          val);
5980 }
5981
5982 /******************************************************************/
5983 /*                      STATIC PHY DECLARATION                    */
5984 /******************************************************************/
5985
5986 static struct bnx2x_phy phy_null = {
5987         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
5988         .addr           = 0,
5989         .flags          = FLAGS_INIT_XGXS_FIRST,
5990         .def_md_devad   = 0,
5991         .reserved       = 0,
5992         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5993         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5994         .mdio_ctrl      = 0,
5995         .supported      = 0,
5996         .media_type     = ETH_PHY_NOT_PRESENT,
5997         .ver_addr       = 0,
5998         .req_flow_ctrl  = 0,
5999         .req_line_speed = 0,
6000         .speed_cap_mask = 0,
6001         .req_duplex     = 0,
6002         .rsrv           = 0,
6003         .config_init    = (config_init_t)NULL,
6004         .read_status    = (read_status_t)NULL,
6005         .link_reset     = (link_reset_t)NULL,
6006         .config_loopback = (config_loopback_t)NULL,
6007         .format_fw_ver  = (format_fw_ver_t)NULL,
6008         .hw_reset       = (hw_reset_t)NULL,
6009         .set_link_led   = (set_link_led_t)NULL,
6010         .phy_specific_func = (phy_specific_func_t)NULL
6011 };
6012
6013 static struct bnx2x_phy phy_serdes = {
6014         .type           = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
6015         .addr           = 0xff,
6016         .flags          = 0,
6017         .def_md_devad   = 0,
6018         .reserved       = 0,
6019         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6020         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6021         .mdio_ctrl      = 0,
6022         .supported      = (SUPPORTED_10baseT_Half |
6023                            SUPPORTED_10baseT_Full |
6024                            SUPPORTED_100baseT_Half |
6025                            SUPPORTED_100baseT_Full |
6026                            SUPPORTED_1000baseT_Full |
6027                            SUPPORTED_2500baseX_Full |
6028                            SUPPORTED_TP |
6029                            SUPPORTED_Autoneg |
6030                            SUPPORTED_Pause |
6031                            SUPPORTED_Asym_Pause),
6032         .media_type     = ETH_PHY_UNSPECIFIED,
6033         .ver_addr       = 0,
6034         .req_flow_ctrl  = 0,
6035         .req_line_speed = 0,
6036         .speed_cap_mask = 0,
6037         .req_duplex     = 0,
6038         .rsrv           = 0,
6039         .config_init    = (config_init_t)bnx2x_init_serdes,
6040         .read_status    = (read_status_t)bnx2x_link_settings_status,
6041         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
6042         .config_loopback = (config_loopback_t)NULL,
6043         .format_fw_ver  = (format_fw_ver_t)NULL,
6044         .hw_reset       = (hw_reset_t)NULL,
6045         .set_link_led   = (set_link_led_t)NULL,
6046         .phy_specific_func = (phy_specific_func_t)NULL
6047 };
6048
6049 static struct bnx2x_phy phy_xgxs = {
6050         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
6051         .addr           = 0xff,
6052         .flags          = 0,
6053         .def_md_devad   = 0,
6054         .reserved       = 0,
6055         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6056         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6057         .mdio_ctrl      = 0,
6058         .supported      = (SUPPORTED_10baseT_Half |
6059                            SUPPORTED_10baseT_Full |
6060                            SUPPORTED_100baseT_Half |
6061                            SUPPORTED_100baseT_Full |
6062                            SUPPORTED_1000baseT_Full |
6063                            SUPPORTED_2500baseX_Full |
6064                            SUPPORTED_10000baseT_Full |
6065                            SUPPORTED_FIBRE |
6066                            SUPPORTED_Autoneg |
6067                            SUPPORTED_Pause |
6068                            SUPPORTED_Asym_Pause),
6069         .media_type     = ETH_PHY_UNSPECIFIED,
6070         .ver_addr       = 0,
6071         .req_flow_ctrl  = 0,
6072         .req_line_speed = 0,
6073         .speed_cap_mask = 0,
6074         .req_duplex     = 0,
6075         .rsrv           = 0,
6076         .config_init    = (config_init_t)bnx2x_init_xgxs,
6077         .read_status    = (read_status_t)bnx2x_link_settings_status,
6078         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
6079         .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
6080         .format_fw_ver  = (format_fw_ver_t)NULL,
6081         .hw_reset       = (hw_reset_t)NULL,
6082         .set_link_led   = (set_link_led_t)NULL,
6083         .phy_specific_func = (phy_specific_func_t)NULL
6084 };
6085
6086 static struct bnx2x_phy phy_7101 = {
6087         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6088         .addr           = 0xff,
6089         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
6090         .def_md_devad   = 0,
6091         .reserved       = 0,
6092         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6093         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6094         .mdio_ctrl      = 0,
6095         .supported      = (SUPPORTED_10000baseT_Full |
6096                            SUPPORTED_TP |
6097                            SUPPORTED_Autoneg |
6098                            SUPPORTED_Pause |
6099                            SUPPORTED_Asym_Pause),
6100         .media_type     = ETH_PHY_BASE_T,
6101         .ver_addr       = 0,
6102         .req_flow_ctrl  = 0,
6103         .req_line_speed = 0,
6104         .speed_cap_mask = 0,
6105         .req_duplex     = 0,
6106         .rsrv           = 0,
6107         .config_init    = (config_init_t)bnx2x_7101_config_init,
6108         .read_status    = (read_status_t)bnx2x_7101_read_status,
6109         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6110         .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
6111         .format_fw_ver  = (format_fw_ver_t)bnx2x_7101_format_ver,
6112         .hw_reset       = (hw_reset_t)bnx2x_7101_hw_reset,
6113         .set_link_led   = (set_link_led_t)bnx2x_7101_set_link_led,
6114         .phy_specific_func = (phy_specific_func_t)NULL
6115 };
6116 static struct bnx2x_phy phy_8073 = {
6117         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6118         .addr           = 0xff,
6119         .flags          = FLAGS_HW_LOCK_REQUIRED,
6120         .def_md_devad   = 0,
6121         .reserved       = 0,
6122         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6123         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6124         .mdio_ctrl      = 0,
6125         .supported      = (SUPPORTED_10000baseT_Full |
6126                            SUPPORTED_2500baseX_Full |
6127                            SUPPORTED_1000baseT_Full |
6128                            SUPPORTED_FIBRE |
6129                            SUPPORTED_Autoneg |
6130                            SUPPORTED_Pause |
6131                            SUPPORTED_Asym_Pause),
6132         .media_type     = ETH_PHY_UNSPECIFIED,
6133         .ver_addr       = 0,
6134         .req_flow_ctrl  = 0,
6135         .req_line_speed = 0,
6136         .speed_cap_mask = 0,
6137         .req_duplex     = 0,
6138         .rsrv           = 0,
6139         .config_init    = (config_init_t)bnx2x_8073_config_init,
6140         .read_status    = (read_status_t)bnx2x_8073_read_status,
6141         .link_reset     = (link_reset_t)bnx2x_8073_link_reset,
6142         .config_loopback = (config_loopback_t)NULL,
6143         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6144         .hw_reset       = (hw_reset_t)NULL,
6145         .set_link_led   = (set_link_led_t)NULL,
6146         .phy_specific_func = (phy_specific_func_t)NULL
6147 };
6148 static struct bnx2x_phy phy_8705 = {
6149         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
6150         .addr           = 0xff,
6151         .flags          = FLAGS_INIT_XGXS_FIRST,
6152         .def_md_devad   = 0,
6153         .reserved       = 0,
6154         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6155         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6156         .mdio_ctrl      = 0,
6157         .supported      = (SUPPORTED_10000baseT_Full |
6158                            SUPPORTED_FIBRE |
6159                            SUPPORTED_Pause |
6160                            SUPPORTED_Asym_Pause),
6161         .media_type     = ETH_PHY_XFP_FIBER,
6162         .ver_addr       = 0,
6163         .req_flow_ctrl  = 0,
6164         .req_line_speed = 0,
6165         .speed_cap_mask = 0,
6166         .req_duplex     = 0,
6167         .rsrv           = 0,
6168         .config_init    = (config_init_t)bnx2x_8705_config_init,
6169         .read_status    = (read_status_t)bnx2x_8705_read_status,
6170         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6171         .config_loopback = (config_loopback_t)NULL,
6172         .format_fw_ver  = (format_fw_ver_t)bnx2x_null_format_ver,
6173         .hw_reset       = (hw_reset_t)NULL,
6174         .set_link_led   = (set_link_led_t)NULL,
6175         .phy_specific_func = (phy_specific_func_t)NULL
6176 };
6177 static struct bnx2x_phy phy_8706 = {
6178         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
6179         .addr           = 0xff,
6180         .flags          = FLAGS_INIT_XGXS_FIRST,
6181         .def_md_devad   = 0,
6182         .reserved       = 0,
6183         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6184         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6185         .mdio_ctrl      = 0,
6186         .supported      = (SUPPORTED_10000baseT_Full |
6187                            SUPPORTED_1000baseT_Full |
6188                            SUPPORTED_FIBRE |
6189                            SUPPORTED_Pause |
6190                            SUPPORTED_Asym_Pause),
6191         .media_type     = ETH_PHY_SFP_FIBER,
6192         .ver_addr       = 0,
6193         .req_flow_ctrl  = 0,
6194         .req_line_speed = 0,
6195         .speed_cap_mask = 0,
6196         .req_duplex     = 0,
6197         .rsrv           = 0,
6198         .config_init    = (config_init_t)bnx2x_8706_config_init,
6199         .read_status    = (read_status_t)bnx2x_8706_read_status,
6200         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6201         .config_loopback = (config_loopback_t)NULL,
6202         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6203         .hw_reset       = (hw_reset_t)NULL,
6204         .set_link_led   = (set_link_led_t)NULL,
6205         .phy_specific_func = (phy_specific_func_t)NULL
6206 };
6207
6208 static struct bnx2x_phy phy_8726 = {
6209         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
6210         .addr           = 0xff,
6211         .flags          = (FLAGS_HW_LOCK_REQUIRED |
6212                            FLAGS_INIT_XGXS_FIRST),
6213         .def_md_devad   = 0,
6214         .reserved       = 0,
6215         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6216         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6217         .mdio_ctrl      = 0,
6218         .supported      = (SUPPORTED_10000baseT_Full |
6219                            SUPPORTED_1000baseT_Full |
6220                            SUPPORTED_Autoneg |
6221                            SUPPORTED_FIBRE |
6222                            SUPPORTED_Pause |
6223                            SUPPORTED_Asym_Pause),
6224         .media_type     = ETH_PHY_SFP_FIBER,
6225         .ver_addr       = 0,
6226         .req_flow_ctrl  = 0,
6227         .req_line_speed = 0,
6228         .speed_cap_mask = 0,
6229         .req_duplex     = 0,
6230         .rsrv           = 0,
6231         .config_init    = (config_init_t)bnx2x_8726_config_init,
6232         .read_status    = (read_status_t)bnx2x_8726_read_status,
6233         .link_reset     = (link_reset_t)bnx2x_8726_link_reset,
6234         .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
6235         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6236         .hw_reset       = (hw_reset_t)NULL,
6237         .set_link_led   = (set_link_led_t)NULL,
6238         .phy_specific_func = (phy_specific_func_t)NULL
6239 };
6240
6241 static struct bnx2x_phy phy_8727 = {
6242         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6243         .addr           = 0xff,
6244         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
6245         .def_md_devad   = 0,
6246         .reserved       = 0,
6247         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6248         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6249         .mdio_ctrl      = 0,
6250         .supported      = (SUPPORTED_10000baseT_Full |
6251                            SUPPORTED_1000baseT_Full |
6252                            SUPPORTED_FIBRE |
6253                            SUPPORTED_Pause |
6254                            SUPPORTED_Asym_Pause),
6255         .media_type     = ETH_PHY_SFP_FIBER,
6256         .ver_addr       = 0,
6257         .req_flow_ctrl  = 0,
6258         .req_line_speed = 0,
6259         .speed_cap_mask = 0,
6260         .req_duplex     = 0,
6261         .rsrv           = 0,
6262         .config_init    = (config_init_t)bnx2x_8727_config_init,
6263         .read_status    = (read_status_t)bnx2x_8727_read_status,
6264         .link_reset     = (link_reset_t)bnx2x_8727_link_reset,
6265         .config_loopback = (config_loopback_t)NULL,
6266         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6267         .hw_reset       = (hw_reset_t)bnx2x_8727_hw_reset,
6268         .set_link_led   = (set_link_led_t)bnx2x_8727_set_link_led,
6269         .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
6270 };
6271 static struct bnx2x_phy phy_8481 = {
6272         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6273         .addr           = 0xff,
6274         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
6275                           FLAGS_REARM_LATCH_SIGNAL,
6276         .def_md_devad   = 0,
6277         .reserved       = 0,
6278         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6279         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6280         .mdio_ctrl      = 0,
6281         .supported      = (SUPPORTED_10baseT_Half |
6282                            SUPPORTED_10baseT_Full |
6283                            SUPPORTED_100baseT_Half |
6284                            SUPPORTED_100baseT_Full |
6285                            SUPPORTED_1000baseT_Full |
6286                            SUPPORTED_10000baseT_Full |
6287                            SUPPORTED_TP |
6288                            SUPPORTED_Autoneg |
6289                            SUPPORTED_Pause |
6290                            SUPPORTED_Asym_Pause),
6291         .media_type     = ETH_PHY_BASE_T,
6292         .ver_addr       = 0,
6293         .req_flow_ctrl  = 0,
6294         .req_line_speed = 0,
6295         .speed_cap_mask = 0,
6296         .req_duplex     = 0,
6297         .rsrv           = 0,
6298         .config_init    = (config_init_t)bnx2x_8481_config_init,
6299         .read_status    = (read_status_t)bnx2x_848xx_read_status,
6300         .link_reset     = (link_reset_t)bnx2x_8481_link_reset,
6301         .config_loopback = (config_loopback_t)NULL,
6302         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
6303         .hw_reset       = (hw_reset_t)bnx2x_8481_hw_reset,
6304         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
6305         .phy_specific_func = (phy_specific_func_t)NULL
6306 };
6307
6308 static struct bnx2x_phy phy_84823 = {
6309         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
6310         .addr           = 0xff,
6311         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
6312                           FLAGS_REARM_LATCH_SIGNAL,
6313         .def_md_devad   = 0,
6314         .reserved       = 0,
6315         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6316         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6317         .mdio_ctrl      = 0,
6318         .supported      = (SUPPORTED_10baseT_Half |
6319                            SUPPORTED_10baseT_Full |
6320                            SUPPORTED_100baseT_Half |
6321                            SUPPORTED_100baseT_Full |
6322                            SUPPORTED_1000baseT_Full |
6323                            SUPPORTED_10000baseT_Full |
6324                            SUPPORTED_TP |
6325                            SUPPORTED_Autoneg |
6326                            SUPPORTED_Pause |
6327                            SUPPORTED_Asym_Pause),
6328         .media_type     = ETH_PHY_BASE_T,
6329         .ver_addr       = 0,
6330         .req_flow_ctrl  = 0,
6331         .req_line_speed = 0,
6332         .speed_cap_mask = 0,
6333         .req_duplex     = 0,
6334         .rsrv           = 0,
6335         .config_init    = (config_init_t)bnx2x_848x3_config_init,
6336         .read_status    = (read_status_t)bnx2x_848xx_read_status,
6337         .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
6338         .config_loopback = (config_loopback_t)NULL,
6339         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
6340         .hw_reset       = (hw_reset_t)NULL,
6341         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
6342         .phy_specific_func = (phy_specific_func_t)NULL
6343 };
6344
6345 /*****************************************************************/
6346 /*                                                               */
6347 /* Populate the phy according. Main function: bnx2x_populate_phy   */
6348 /*                                                               */
6349 /*****************************************************************/
6350
6351 static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
6352                                      struct bnx2x_phy *phy, u8 port,
6353                                      u8 phy_index)
6354 {
6355         /* Get the 4 lanes xgxs config rx and tx */
6356         u32 rx = 0, tx = 0, i;
6357         for (i = 0; i < 2; i++) {
6358                 /**
6359                  * INT_PHY and EXT_PHY1 share the same value location in the
6360                  * shmem. When num_phys is greater than 1, than this value
6361                  * applies only to EXT_PHY1
6362                  */
6363                 if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
6364                         rx = REG_RD(bp, shmem_base +
6365                                     offsetof(struct shmem_region,
6366                            dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
6367
6368                         tx = REG_RD(bp, shmem_base +
6369                                     offsetof(struct shmem_region,
6370                            dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
6371                 } else {
6372                         rx = REG_RD(bp, shmem_base +
6373                                     offsetof(struct shmem_region,
6374                           dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
6375
6376                         tx = REG_RD(bp, shmem_base +
6377                                     offsetof(struct shmem_region,
6378                           dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
6379                 }
6380
6381                 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
6382                 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
6383
6384                 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
6385                 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
6386         }
6387 }
6388
6389 static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
6390                                     u8 phy_index, u8 port)
6391 {
6392         u32 ext_phy_config = 0;
6393         switch (phy_index) {
6394         case EXT_PHY1:
6395                 ext_phy_config = REG_RD(bp, shmem_base +
6396                                               offsetof(struct shmem_region,
6397                         dev_info.port_hw_config[port].external_phy_config));
6398                 break;
6399         case EXT_PHY2:
6400                 ext_phy_config = REG_RD(bp, shmem_base +
6401                                               offsetof(struct shmem_region,
6402                         dev_info.port_hw_config[port].external_phy_config2));
6403                 break;
6404         default:
6405                 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
6406                 return -EINVAL;
6407         }
6408
6409         return ext_phy_config;
6410 }
6411 static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
6412                                  struct bnx2x_phy *phy)
6413 {
6414         u32 phy_addr;
6415         u32 chip_id;
6416         u32 switch_cfg = (REG_RD(bp, shmem_base +
6417                                        offsetof(struct shmem_region,
6418                         dev_info.port_feature_config[port].link_config)) &
6419                           PORT_FEATURE_CONNECTED_SWITCH_MASK);
6420         chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
6421         switch (switch_cfg) {
6422         case SWITCH_CFG_1G:
6423                 phy_addr = REG_RD(bp,
6424                                         NIG_REG_SERDES0_CTRL_PHY_ADDR +
6425                                         port * 0x10);
6426                 *phy = phy_serdes;
6427                 break;
6428         case SWITCH_CFG_10G:
6429                 phy_addr = REG_RD(bp,
6430                                         NIG_REG_XGXS0_CTRL_PHY_ADDR +
6431                                         port * 0x18);
6432                 *phy = phy_xgxs;
6433                 break;
6434         default:
6435                 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
6436                 return -EINVAL;
6437         }
6438         phy->addr = (u8)phy_addr;
6439         phy->mdio_ctrl = bnx2x_get_emac_base(bp,
6440                                             SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
6441                                             port);
6442         if (CHIP_IS_E2(bp))
6443                 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
6444         else
6445                 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
6446
6447         DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
6448                    port, phy->addr, phy->mdio_ctrl);
6449
6450         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
6451         return 0;
6452 }
6453
6454 static u8 bnx2x_populate_ext_phy(struct bnx2x *bp,
6455                                  u8 phy_index,
6456                                  u32 shmem_base,
6457                                  u32 shmem2_base,
6458                                  u8 port,
6459                                  struct bnx2x_phy *phy)
6460 {
6461         u32 ext_phy_config, phy_type, config2;
6462         u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
6463         ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
6464                                                   phy_index, port);
6465         phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6466         /* Select the phy type */
6467         switch (phy_type) {
6468         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6469                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
6470                 *phy = phy_8073;
6471                 break;
6472         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
6473                 *phy = phy_8705;
6474                 break;
6475         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
6476                 *phy = phy_8706;
6477                 break;
6478         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6479                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
6480                 *phy = phy_8726;
6481                 break;
6482         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6483                 /* BCM8727_NOC => BCM8727 no over current */
6484                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
6485                 *phy = phy_8727;
6486                 phy->flags |= FLAGS_NOC;
6487                 break;
6488         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6489                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
6490                 *phy = phy_8727;
6491                 break;
6492         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
6493                 *phy = phy_8481;
6494                 break;
6495         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
6496                 *phy = phy_84823;
6497                 break;
6498         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
6499                 *phy = phy_7101;
6500                 break;
6501         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
6502                 *phy = phy_null;
6503                 return -EINVAL;
6504         default:
6505                 *phy = phy_null;
6506                 return 0;
6507         }
6508
6509         phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
6510         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
6511
6512         /**
6513         * The shmem address of the phy version is located on different
6514         * structures. In case this structure is too old, do not set
6515         * the address
6516         */
6517         config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
6518                                         dev_info.shared_hw_config.config2));
6519         if (phy_index == EXT_PHY1) {
6520                 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
6521                                 port_mb[port].ext_phy_fw_version);
6522
6523         /* Check specific mdc mdio settings */
6524         if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
6525                 mdc_mdio_access = config2 &
6526                 SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
6527         } else {
6528                 u32 size = REG_RD(bp, shmem2_base);
6529
6530                 if (size >
6531                     offsetof(struct shmem2_region, ext_phy_fw_version2)) {
6532                         phy->ver_addr = shmem2_base +
6533                             offsetof(struct shmem2_region,
6534                                      ext_phy_fw_version2[port]);
6535                 }
6536                 /* Check specific mdc mdio settings */
6537                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
6538                         mdc_mdio_access = (config2 &
6539                         SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
6540                         (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
6541                          SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
6542         }
6543         phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
6544
6545         /**
6546          * In case mdc/mdio_access of the external phy is different than the
6547          * mdc/mdio access of the XGXS, a HW lock must be taken in each access
6548          * to prevent one port interfere with another port's CL45 operations.
6549          */
6550         if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
6551                 phy->flags |= FLAGS_HW_LOCK_REQUIRED;
6552         DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
6553                    phy_type, port, phy_index);
6554         DP(NETIF_MSG_LINK, "             addr=0x%x, mdio_ctl=0x%x\n",
6555                    phy->addr, phy->mdio_ctrl);
6556         return 0;
6557 }
6558
6559 static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
6560                              u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
6561 {
6562         u8 status = 0;
6563         phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
6564         if (phy_index == INT_PHY)
6565                 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
6566         status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
6567                                         port, phy);
6568         return status;
6569 }
6570
6571 static void bnx2x_phy_def_cfg(struct link_params *params,
6572                               struct bnx2x_phy *phy,
6573                               u8 phy_index)
6574 {
6575         struct bnx2x *bp = params->bp;
6576         u32 link_config;
6577         /* Populate the default phy configuration for MF mode */
6578         if (phy_index == EXT_PHY2) {
6579                 link_config = REG_RD(bp, params->shmem_base +
6580                                          offsetof(struct shmem_region, dev_info.
6581                         port_feature_config[params->port].link_config2));
6582                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
6583                                         offsetof(struct shmem_region, dev_info.
6584                         port_hw_config[params->port].speed_capability_mask2));
6585         } else {
6586                 link_config = REG_RD(bp, params->shmem_base +
6587                                 offsetof(struct shmem_region, dev_info.
6588                                 port_feature_config[params->port].link_config));
6589                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
6590                                 offsetof(struct shmem_region, dev_info.
6591                            port_hw_config[params->port].speed_capability_mask));
6592         }
6593         DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
6594                        " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
6595
6596         phy->req_duplex = DUPLEX_FULL;
6597         switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
6598         case PORT_FEATURE_LINK_SPEED_10M_HALF:
6599                 phy->req_duplex = DUPLEX_HALF;
6600         case PORT_FEATURE_LINK_SPEED_10M_FULL:
6601                 phy->req_line_speed = SPEED_10;
6602                 break;
6603         case PORT_FEATURE_LINK_SPEED_100M_HALF:
6604                 phy->req_duplex = DUPLEX_HALF;
6605         case PORT_FEATURE_LINK_SPEED_100M_FULL:
6606                 phy->req_line_speed = SPEED_100;
6607                 break;
6608         case PORT_FEATURE_LINK_SPEED_1G:
6609                 phy->req_line_speed = SPEED_1000;
6610                 break;
6611         case PORT_FEATURE_LINK_SPEED_2_5G:
6612                 phy->req_line_speed = SPEED_2500;
6613                 break;
6614         case PORT_FEATURE_LINK_SPEED_10G_CX4:
6615                 phy->req_line_speed = SPEED_10000;
6616                 break;
6617         default:
6618                 phy->req_line_speed = SPEED_AUTO_NEG;
6619                 break;
6620         }
6621
6622         switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
6623         case PORT_FEATURE_FLOW_CONTROL_AUTO:
6624                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
6625                 break;
6626         case PORT_FEATURE_FLOW_CONTROL_TX:
6627                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
6628                 break;
6629         case PORT_FEATURE_FLOW_CONTROL_RX:
6630                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
6631                 break;
6632         case PORT_FEATURE_FLOW_CONTROL_BOTH:
6633                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
6634                 break;
6635         default:
6636                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6637                 break;
6638         }
6639 }
6640
6641 u32 bnx2x_phy_selection(struct link_params *params)
6642 {
6643         u32 phy_config_swapped, prio_cfg;
6644         u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
6645
6646         phy_config_swapped = params->multi_phy_config &
6647                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
6648
6649         prio_cfg = params->multi_phy_config &
6650                         PORT_HW_CFG_PHY_SELECTION_MASK;
6651
6652         if (phy_config_swapped) {
6653                 switch (prio_cfg) {
6654                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6655                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
6656                      break;
6657                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6658                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
6659                      break;
6660                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
6661                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
6662                      break;
6663                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
6664                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
6665                      break;
6666                 }
6667         } else
6668                 return_cfg = prio_cfg;
6669
6670         return return_cfg;
6671 }
6672
6673
6674 u8 bnx2x_phy_probe(struct link_params *params)
6675 {
6676         u8 phy_index, actual_phy_idx, link_cfg_idx;
6677         u32 phy_config_swapped;
6678         struct bnx2x *bp = params->bp;
6679         struct bnx2x_phy *phy;
6680         params->num_phys = 0;
6681         DP(NETIF_MSG_LINK, "Begin phy probe\n");
6682         phy_config_swapped = params->multi_phy_config &
6683                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
6684
6685         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
6686               phy_index++) {
6687                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
6688                 actual_phy_idx = phy_index;
6689                 if (phy_config_swapped) {
6690                         if (phy_index == EXT_PHY1)
6691                                 actual_phy_idx = EXT_PHY2;
6692                         else if (phy_index == EXT_PHY2)
6693                                 actual_phy_idx = EXT_PHY1;
6694                 }
6695                 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
6696                                " actual_phy_idx %x\n", phy_config_swapped,
6697                            phy_index, actual_phy_idx);
6698                 phy = &params->phy[actual_phy_idx];
6699                 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
6700                                        params->shmem2_base, params->port,
6701                                        phy) != 0) {
6702                         params->num_phys = 0;
6703                         DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
6704                                    phy_index);
6705                         for (phy_index = INT_PHY;
6706                               phy_index < MAX_PHYS;
6707                               phy_index++)
6708                                 *phy = phy_null;
6709                         return -EINVAL;
6710                 }
6711                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
6712                         break;
6713
6714                 bnx2x_phy_def_cfg(params, phy, phy_index);
6715                 params->num_phys++;
6716         }
6717
6718         DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
6719         return 0;
6720 }
6721
6722 static void set_phy_vars(struct link_params *params)
6723 {
6724         struct bnx2x *bp = params->bp;
6725         u8 actual_phy_idx, phy_index, link_cfg_idx;
6726         u8 phy_config_swapped = params->multi_phy_config &
6727                         PORT_HW_CFG_PHY_SWAPPED_ENABLED;
6728         for (phy_index = INT_PHY; phy_index < params->num_phys;
6729               phy_index++) {
6730                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
6731                 actual_phy_idx = phy_index;
6732                 if (phy_config_swapped) {
6733                         if (phy_index == EXT_PHY1)
6734                                 actual_phy_idx = EXT_PHY2;
6735                         else if (phy_index == EXT_PHY2)
6736                                 actual_phy_idx = EXT_PHY1;
6737                 }
6738                 params->phy[actual_phy_idx].req_flow_ctrl  =
6739                         params->req_flow_ctrl[link_cfg_idx];
6740
6741                 params->phy[actual_phy_idx].req_line_speed =
6742                         params->req_line_speed[link_cfg_idx];
6743
6744                 params->phy[actual_phy_idx].speed_cap_mask =
6745                         params->speed_cap_mask[link_cfg_idx];
6746
6747                 params->phy[actual_phy_idx].req_duplex =
6748                         params->req_duplex[link_cfg_idx];
6749
6750                 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
6751                            " speed_cap_mask %x\n",
6752                            params->phy[actual_phy_idx].req_flow_ctrl,
6753                            params->phy[actual_phy_idx].req_line_speed,
6754                            params->phy[actual_phy_idx].speed_cap_mask);
6755         }
6756 }
6757
6758 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
6759 {
6760         struct bnx2x *bp = params->bp;
6761         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
6762         DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
6763                    params->req_line_speed[0], params->req_flow_ctrl[0]);
6764         DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
6765                    params->req_line_speed[1], params->req_flow_ctrl[1]);
6766         vars->link_status = 0;
6767         vars->phy_link_up = 0;
6768         vars->link_up = 0;
6769         vars->line_speed = 0;
6770         vars->duplex = DUPLEX_FULL;
6771         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6772         vars->mac_type = MAC_TYPE_NONE;
6773         vars->phy_flags = 0;
6774
6775         /* disable attentions */
6776         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
6777                        (NIG_MASK_XGXS0_LINK_STATUS |
6778                         NIG_MASK_XGXS0_LINK10G |
6779                         NIG_MASK_SERDES0_LINK_STATUS |
6780                         NIG_MASK_MI_INT));
6781
6782         bnx2x_emac_init(params, vars);
6783
6784         if (params->num_phys == 0) {
6785                 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
6786                 return -EINVAL;
6787         }
6788         set_phy_vars(params);
6789
6790         DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
6791         if (CHIP_REV_IS_FPGA(bp)) {
6792
6793                 vars->link_up = 1;
6794                 vars->line_speed = SPEED_10000;
6795                 vars->duplex = DUPLEX_FULL;
6796                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6797                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6798                 /* enable on E1.5 FPGA */
6799                 if (CHIP_IS_E1H(bp)) {
6800                         vars->flow_ctrl |=
6801                                         (BNX2X_FLOW_CTRL_TX |
6802                                          BNX2X_FLOW_CTRL_RX);
6803                         vars->link_status |=
6804                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
6805                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
6806                 }
6807
6808                 bnx2x_emac_enable(params, vars, 0);
6809                 if (!(CHIP_IS_E2(bp)))
6810                         bnx2x_pbf_update(params, vars->flow_ctrl,
6811                                          vars->line_speed);
6812                 /* disable drain */
6813                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
6814
6815                 /* update shared memory */
6816                 bnx2x_update_mng(params, vars->link_status);
6817
6818                 return 0;
6819
6820         } else
6821         if (CHIP_REV_IS_EMUL(bp)) {
6822
6823                 vars->link_up = 1;
6824                 vars->line_speed = SPEED_10000;
6825                 vars->duplex = DUPLEX_FULL;
6826                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6827                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6828
6829                 bnx2x_bmac_enable(params, vars, 0);
6830
6831                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6832                 /* Disable drain */
6833                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
6834                                     + params->port*4, 0);
6835
6836                 /* update shared memory */
6837                 bnx2x_update_mng(params, vars->link_status);
6838
6839                 return 0;
6840
6841         } else
6842         if (params->loopback_mode == LOOPBACK_BMAC) {
6843
6844                 vars->link_up = 1;
6845                 vars->line_speed = SPEED_10000;
6846                 vars->duplex = DUPLEX_FULL;
6847                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6848                 vars->mac_type = MAC_TYPE_BMAC;
6849
6850                 vars->phy_flags = PHY_XGXS_FLAG;
6851
6852                 bnx2x_xgxs_deassert(params);
6853
6854                 /* set bmac loopback */
6855                 bnx2x_bmac_enable(params, vars, 1);
6856
6857                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6858                     params->port*4, 0);
6859
6860         } else if (params->loopback_mode == LOOPBACK_EMAC) {
6861
6862                 vars->link_up = 1;
6863                 vars->line_speed = SPEED_1000;
6864                 vars->duplex = DUPLEX_FULL;
6865                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6866                 vars->mac_type = MAC_TYPE_EMAC;
6867
6868                 vars->phy_flags = PHY_XGXS_FLAG;
6869
6870                 bnx2x_xgxs_deassert(params);
6871                 /* set bmac loopback */
6872                 bnx2x_emac_enable(params, vars, 1);
6873                 bnx2x_emac_program(params, vars);
6874                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6875                     params->port*4, 0);
6876
6877         } else if ((params->loopback_mode == LOOPBACK_XGXS) ||
6878                    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6879
6880                 vars->link_up = 1;
6881                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6882                 vars->duplex = DUPLEX_FULL;
6883                 if (params->req_line_speed[0] == SPEED_1000) {
6884                         vars->line_speed = SPEED_1000;
6885                         vars->mac_type = MAC_TYPE_EMAC;
6886                 } else {
6887                         vars->line_speed = SPEED_10000;
6888                         vars->mac_type = MAC_TYPE_BMAC;
6889                 }
6890
6891                 bnx2x_xgxs_deassert(params);
6892                 bnx2x_link_initialize(params, vars);
6893
6894                 if (params->req_line_speed[0] == SPEED_1000) {
6895                         bnx2x_emac_program(params, vars);
6896                         bnx2x_emac_enable(params, vars, 0);
6897                 } else
6898                 bnx2x_bmac_enable(params, vars, 0);
6899
6900                 if (params->loopback_mode == LOOPBACK_XGXS) {
6901                         /* set 10G XGXS loopback */
6902                         params->phy[INT_PHY].config_loopback(
6903                                 &params->phy[INT_PHY],
6904                                 params);
6905
6906                 } else {
6907                         /* set external phy loopback */
6908                         u8 phy_index;
6909                         for (phy_index = EXT_PHY1;
6910                               phy_index < params->num_phys; phy_index++) {
6911                                 if (params->phy[phy_index].config_loopback)
6912                                         params->phy[phy_index].config_loopback(
6913                                                 &params->phy[phy_index],
6914                                                 params);
6915                         }
6916                 }
6917
6918                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6919                             params->port*4, 0);
6920
6921                 bnx2x_set_led(params, vars,
6922                               LED_MODE_OPER, vars->line_speed);
6923         } else
6924         /* No loopback */
6925         {
6926                 if (params->switch_cfg == SWITCH_CFG_10G)
6927                         bnx2x_xgxs_deassert(params);
6928                 else
6929                         bnx2x_serdes_deassert(bp, params->port);
6930
6931                 bnx2x_link_initialize(params, vars);
6932                 msleep(30);
6933                 bnx2x_link_int_enable(params);
6934         }
6935         return 0;
6936 }
6937 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6938                   u8 reset_ext_phy)
6939 {
6940         struct bnx2x *bp = params->bp;
6941         u8 phy_index, port = params->port, clear_latch_ind = 0;
6942         DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
6943         /* disable attentions */
6944         vars->link_status = 0;
6945         bnx2x_update_mng(params, vars->link_status);
6946         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6947                      (NIG_MASK_XGXS0_LINK_STATUS |
6948                       NIG_MASK_XGXS0_LINK10G |
6949                       NIG_MASK_SERDES0_LINK_STATUS |
6950                       NIG_MASK_MI_INT));
6951
6952         /* activate nig drain */
6953         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6954
6955         /* disable nig egress interface */
6956         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6957         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6958
6959         /* Stop BigMac rx */
6960         bnx2x_bmac_rx_disable(bp, port);
6961
6962         /* disable emac */
6963         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6964
6965         msleep(10);
6966         /* The PHY reset is controled by GPIO 1
6967          * Hold it as vars low
6968          */
6969          /* clear link led */
6970         bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
6971
6972         if (reset_ext_phy) {
6973                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6974                       phy_index++) {
6975                         if (params->phy[phy_index].link_reset)
6976                                 params->phy[phy_index].link_reset(
6977                                         &params->phy[phy_index],
6978                                         params);
6979                         if (params->phy[phy_index].flags &
6980                             FLAGS_REARM_LATCH_SIGNAL)
6981                                 clear_latch_ind = 1;
6982                 }
6983         }
6984
6985         if (clear_latch_ind) {
6986                 /* Clear latching indication */
6987                 bnx2x_rearm_latch_signal(bp, port, 0);
6988                 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
6989                                1 << NIG_LATCH_BC_ENABLE_MI_INT);
6990         }
6991         if (params->phy[INT_PHY].link_reset)
6992                 params->phy[INT_PHY].link_reset(
6993                         &params->phy[INT_PHY], params);
6994         /* reset BigMac */
6995         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
6996                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6997
6998         /* disable nig ingress interface */
6999         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
7000         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
7001         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
7002         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
7003         vars->link_up = 0;
7004         return 0;
7005 }
7006
7007 /****************************************************************************/
7008 /*                              Common function                             */
7009 /****************************************************************************/
7010 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
7011                                      u32 shmem_base_path[],
7012                                      u32 shmem2_base_path[], u8 phy_index,
7013                                      u32 chip_id)
7014 {
7015         struct bnx2x_phy phy[PORT_MAX];
7016         struct bnx2x_phy *phy_blk[PORT_MAX];
7017         u16 val;
7018         s8 port;
7019         s8 port_of_path = 0;
7020
7021         /* PART1 - Reset both phys */
7022         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7023                 u32 shmem_base, shmem2_base;
7024                 /* In E2, same phy is using for port0 of the two paths */
7025                 if (CHIP_IS_E2(bp)) {
7026                         shmem_base = shmem_base_path[port];
7027                         shmem2_base = shmem2_base_path[port];
7028                         port_of_path = 0;
7029                 } else {
7030                         shmem_base = shmem_base_path[0];
7031                         shmem2_base = shmem2_base_path[0];
7032                         port_of_path = port;
7033                 }
7034
7035                 /* Extract the ext phy address for the port */
7036                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7037                                        port_of_path, &phy[port]) !=
7038                     0) {
7039                         DP(NETIF_MSG_LINK, "populate_phy failed\n");
7040                         return -EINVAL;
7041                 }
7042                 /* disable attentions */
7043                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7044                                port_of_path*4,
7045                              (NIG_MASK_XGXS0_LINK_STATUS |
7046                               NIG_MASK_XGXS0_LINK10G |
7047                               NIG_MASK_SERDES0_LINK_STATUS |
7048                               NIG_MASK_MI_INT));
7049
7050                 /* Need to take the phy out of low power mode in order
7051                         to write to access its registers */
7052                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7053                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
7054
7055                 /* Reset the phy */
7056                 bnx2x_cl45_write(bp, &phy[port],
7057                                MDIO_PMA_DEVAD,
7058                                MDIO_PMA_REG_CTRL,
7059                                1<<15);
7060         }
7061
7062         /* Add delay of 150ms after reset */
7063         msleep(150);
7064
7065         if (phy[PORT_0].addr & 0x1) {
7066                 phy_blk[PORT_0] = &(phy[PORT_1]);
7067                 phy_blk[PORT_1] = &(phy[PORT_0]);
7068         } else {
7069                 phy_blk[PORT_0] = &(phy[PORT_0]);
7070                 phy_blk[PORT_1] = &(phy[PORT_1]);
7071         }
7072
7073         /* PART2 - Download firmware to both phys */
7074         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7075                 u16 fw_ver1;
7076                 if (CHIP_IS_E2(bp))
7077                         port_of_path = 0;
7078                 else
7079                         port_of_path = port;
7080
7081                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7082                            phy_blk[port]->addr);
7083                 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7084                                                   port_of_path);
7085
7086                 bnx2x_cl45_read(bp, phy_blk[port],
7087                               MDIO_PMA_DEVAD,
7088                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
7089                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
7090                         DP(NETIF_MSG_LINK,
7091                                  "bnx2x_8073_common_init_phy port %x:"
7092                                  "Download failed. fw version = 0x%x\n",
7093                                  port, fw_ver1);
7094                         return -EINVAL;
7095                 }
7096
7097                 /* Only set bit 10 = 1 (Tx power down) */
7098                 bnx2x_cl45_read(bp, phy_blk[port],
7099                               MDIO_PMA_DEVAD,
7100                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
7101
7102                 /* Phase1 of TX_POWER_DOWN reset */
7103                 bnx2x_cl45_write(bp, phy_blk[port],
7104                                MDIO_PMA_DEVAD,
7105                                MDIO_PMA_REG_TX_POWER_DOWN,
7106                                (val | 1<<10));
7107         }
7108
7109         /* Toggle Transmitter: Power down and then up with 600ms
7110            delay between */
7111         msleep(600);
7112
7113         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
7114         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7115                 /* Phase2 of POWER_DOWN_RESET */
7116                 /* Release bit 10 (Release Tx power down) */
7117                 bnx2x_cl45_read(bp, phy_blk[port],
7118                               MDIO_PMA_DEVAD,
7119                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
7120
7121                 bnx2x_cl45_write(bp, phy_blk[port],
7122                                MDIO_PMA_DEVAD,
7123                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
7124                 msleep(15);
7125
7126                 /* Read modify write the SPI-ROM version select register */
7127                 bnx2x_cl45_read(bp, phy_blk[port],
7128                               MDIO_PMA_DEVAD,
7129                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
7130                 bnx2x_cl45_write(bp, phy_blk[port],
7131                               MDIO_PMA_DEVAD,
7132                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
7133
7134                 /* set GPIO2 back to LOW */
7135                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7136                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
7137         }
7138         return 0;
7139 }
7140 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
7141                                      u32 shmem_base_path[],
7142                                      u32 shmem2_base_path[], u8 phy_index,
7143                                      u32 chip_id)
7144 {
7145         u32 val;
7146         s8 port;
7147         struct bnx2x_phy phy;
7148         /* Use port1 because of the static port-swap */
7149         /* Enable the module detection interrupt */
7150         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
7151         val |= ((1<<MISC_REGISTERS_GPIO_3)|
7152                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
7153         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
7154
7155         bnx2x_ext_phy_hw_reset(bp, 0);
7156         msleep(5);
7157         for (port = 0; port < PORT_MAX; port++) {
7158                 u32 shmem_base, shmem2_base;
7159
7160                 /* In E2, same phy is using for port0 of the two paths */
7161                 if (CHIP_IS_E2(bp)) {
7162                         shmem_base = shmem_base_path[port];
7163                         shmem2_base = shmem2_base_path[port];
7164                 } else {
7165                         shmem_base = shmem_base_path[0];
7166                         shmem2_base = shmem2_base_path[0];
7167                 }
7168                 /* Extract the ext phy address for the port */
7169                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7170                                        port, &phy) !=
7171                     0) {
7172                         DP(NETIF_MSG_LINK, "populate phy failed\n");
7173                         return -EINVAL;
7174                 }
7175
7176                 /* Reset phy*/
7177                 bnx2x_cl45_write(bp, &phy,
7178                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
7179
7180
7181                 /* Set fault module detected LED on */
7182                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
7183                                   MISC_REGISTERS_GPIO_HIGH,
7184                                   port);
7185         }
7186
7187         return 0;
7188 }
7189 static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
7190                                      u32 shmem_base_path[],
7191                                      u32 shmem2_base_path[], u8 phy_index,
7192                                      u32 chip_id)
7193 {
7194         s8 port;
7195         u32 swap_val, swap_override;
7196         struct bnx2x_phy phy[PORT_MAX];
7197         struct bnx2x_phy *phy_blk[PORT_MAX];
7198         s8 port_of_path;
7199         swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
7200         swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
7201
7202         port = 1;
7203
7204         bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override));
7205
7206         /* Calculate the port based on port swap */
7207         port ^= (swap_val && swap_override);
7208
7209         msleep(5);
7210
7211         /* PART1 - Reset both phys */
7212         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7213                 u32 shmem_base, shmem2_base;
7214
7215                 /* In E2, same phy is using for port0 of the two paths */
7216                 if (CHIP_IS_E2(bp)) {
7217                         shmem_base = shmem_base_path[port];
7218                         shmem2_base = shmem2_base_path[port];
7219                         port_of_path = 0;
7220                 } else {
7221                         shmem_base = shmem_base_path[0];
7222                         shmem2_base = shmem2_base_path[0];
7223                         port_of_path = port;
7224                 }
7225
7226                 /* Extract the ext phy address for the port */
7227                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7228                                        port_of_path, &phy[port]) !=
7229                                        0) {
7230                         DP(NETIF_MSG_LINK, "populate phy failed\n");
7231                         return -EINVAL;
7232                 }
7233                 /* disable attentions */
7234                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7235                                port_of_path*4,
7236                                (NIG_MASK_XGXS0_LINK_STATUS |
7237                                 NIG_MASK_XGXS0_LINK10G |
7238                                 NIG_MASK_SERDES0_LINK_STATUS |
7239                                 NIG_MASK_MI_INT));
7240
7241
7242                 /* Reset the phy */
7243                 bnx2x_cl45_write(bp, &phy[port],
7244                                MDIO_PMA_DEVAD,
7245                                MDIO_PMA_REG_CTRL,
7246                                1<<15);
7247         }
7248
7249         /* Add delay of 150ms after reset */
7250         msleep(150);
7251         if (phy[PORT_0].addr & 0x1) {
7252                 phy_blk[PORT_0] = &(phy[PORT_1]);
7253                 phy_blk[PORT_1] = &(phy[PORT_0]);
7254         } else {
7255                 phy_blk[PORT_0] = &(phy[PORT_0]);
7256                 phy_blk[PORT_1] = &(phy[PORT_1]);
7257         }
7258         /* PART2 - Download firmware to both phys */
7259         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7260                 u16 fw_ver1;
7261                  if (CHIP_IS_E2(bp))
7262                         port_of_path = 0;
7263                 else
7264                         port_of_path = port;
7265                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7266                            phy_blk[port]->addr);
7267                 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7268                                                   port_of_path);
7269                 bnx2x_cl45_read(bp, phy_blk[port],
7270                               MDIO_PMA_DEVAD,
7271                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
7272                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
7273                         DP(NETIF_MSG_LINK,
7274                                  "bnx2x_8727_common_init_phy port %x:"
7275                                  "Download failed. fw version = 0x%x\n",
7276                                  port, fw_ver1);
7277                         return -EINVAL;
7278                 }
7279         }
7280
7281         return 0;
7282 }
7283
7284 static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
7285                                     u32 shmem2_base_path[], u8 phy_index,
7286                                     u32 ext_phy_type, u32 chip_id)
7287 {
7288         u8 rc = 0;
7289
7290         switch (ext_phy_type) {
7291         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7292                 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
7293                                                 shmem2_base_path,
7294                                                 phy_index, chip_id);
7295                 break;
7296
7297         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7298         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
7299                 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
7300                                                 shmem2_base_path,
7301                                                 phy_index, chip_id);
7302                 break;
7303
7304         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7305                 /* GPIO1 affects both ports, so there's need to pull
7306                 it for single port alone */
7307                 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
7308                                                 shmem2_base_path,
7309                                                 phy_index, chip_id);
7310                 break;
7311         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
7312                 rc = -EINVAL;
7313                 break;
7314         default:
7315                 DP(NETIF_MSG_LINK,
7316                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
7317                          ext_phy_type);
7318                 break;
7319         }
7320
7321         return rc;
7322 }
7323
7324 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
7325                          u32 shmem2_base_path[], u32 chip_id)
7326 {
7327         u8 rc = 0;
7328         u8 phy_index;
7329         u32 ext_phy_type, ext_phy_config;
7330         DP(NETIF_MSG_LINK, "Begin common phy init\n");
7331
7332         if (CHIP_REV_IS_EMUL(bp))
7333                 return 0;
7334
7335         /* Read the ext_phy_type for arbitrary port(0) */
7336         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
7337               phy_index++) {
7338                 ext_phy_config = bnx2x_get_ext_phy_config(bp,
7339                                                           shmem_base_path[0],
7340                                                           phy_index, 0);
7341                 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
7342                 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
7343                                                 shmem2_base_path,
7344                                                 phy_index, ext_phy_type,
7345                                                 chip_id);
7346         }
7347         return rc;
7348 }
7349
7350 u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
7351 {
7352         u8 phy_index;
7353         struct bnx2x_phy phy;
7354         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
7355               phy_index++) {
7356                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7357                                        0, &phy) != 0) {
7358                         DP(NETIF_MSG_LINK, "populate phy failed\n");
7359                         return 0;
7360                 }
7361
7362                 if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
7363                         return 1;
7364         }
7365         return 0;
7366 }
7367
7368 u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
7369                              u32 shmem_base,
7370                              u32 shmem2_base,
7371                              u8 port)
7372 {
7373         u8 phy_index, fan_failure_det_req = 0;
7374         struct bnx2x_phy phy;
7375         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
7376               phy_index++) {
7377                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7378                                        port, &phy)
7379                     != 0) {
7380                         DP(NETIF_MSG_LINK, "populate phy failed\n");
7381                         return 0;
7382                 }
7383                 fan_failure_det_req |= (phy.flags &
7384                                         FLAGS_FAN_FAILURE_DET_REQ);
7385         }
7386         return fan_failure_det_req;
7387 }
7388
7389 void bnx2x_hw_reset_phy(struct link_params *params)
7390 {
7391         u8 phy_index;
7392         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
7393               phy_index++) {
7394                 if (params->phy[phy_index].hw_reset) {
7395                         params->phy[phy_index].hw_reset(
7396                                 &params->phy[phy_index],
7397                                 params);
7398                         params->phy[phy_index] = phy_null;
7399                 }
7400         }
7401 }