Merge branch 'stable/xen-pcifront-fixes' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / net / bnx2x / bnx2x_link.c
1 /* Copyright 2008-2009 Broadcom Corporation
2  *
3  * Unless you and Broadcom execute a separate written software license
4  * agreement governing use of this software, this software is licensed to you
5  * under the terms of the GNU General Public License version 2, available
6  * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7  *
8  * Notwithstanding the above, under no circumstances may you combine this
9  * software in any way with any other Broadcom software provided under a
10  * license other than the GPL, without Broadcom's express prior written
11  * consent.
12  *
13  * Written by Yaniv Rosner
14  *
15  */
16
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/pci.h>
22 #include <linux/netdevice.h>
23 #include <linux/delay.h>
24 #include <linux/ethtool.h>
25 #include <linux/mutex.h>
26
27 #include "bnx2x.h"
28
29 /********************************************************/
30 #define ETH_HLEN                        14
31 #define ETH_OVREHEAD            (ETH_HLEN + 8 + 8)/* 16 for CRC + VLAN + LLC */
32 #define ETH_MIN_PACKET_SIZE             60
33 #define ETH_MAX_PACKET_SIZE             1500
34 #define ETH_MAX_JUMBO_PACKET_SIZE       9600
35 #define MDIO_ACCESS_TIMEOUT             1000
36 #define BMAC_CONTROL_RX_ENABLE  2
37
38 /***********************************************************/
39 /*                      Shortcut definitions               */
40 /***********************************************************/
41
42 #define NIG_LATCH_BC_ENABLE_MI_INT 0
43
44 #define NIG_STATUS_EMAC0_MI_INT \
45                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
46 #define NIG_STATUS_XGXS0_LINK10G \
47                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
48 #define NIG_STATUS_XGXS0_LINK_STATUS \
49                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
50 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
51                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
52 #define NIG_STATUS_SERDES0_LINK_STATUS \
53                 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
54 #define NIG_MASK_MI_INT \
55                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
56 #define NIG_MASK_XGXS0_LINK10G \
57                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
58 #define NIG_MASK_XGXS0_LINK_STATUS \
59                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
60 #define NIG_MASK_SERDES0_LINK_STATUS \
61                 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
62
63 #define MDIO_AN_CL73_OR_37_COMPLETE \
64                 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
65                  MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
66
67 #define XGXS_RESET_BITS \
68         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
69          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
70          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
71          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
72          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
73
74 #define SERDES_RESET_BITS \
75         (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
76          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
77          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
78          MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
79
80 #define AUTONEG_CL37            SHARED_HW_CFG_AN_ENABLE_CL37
81 #define AUTONEG_CL73            SHARED_HW_CFG_AN_ENABLE_CL73
82 #define AUTONEG_BAM             SHARED_HW_CFG_AN_ENABLE_BAM
83 #define AUTONEG_PARALLEL \
84                                 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
85 #define AUTONEG_SGMII_FIBER_AUTODET \
86                                 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
87 #define AUTONEG_REMOTE_PHY      SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
88
89 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
90                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
91 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
92                         MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
93 #define GP_STATUS_SPEED_MASK \
94                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
95 #define GP_STATUS_10M   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
96 #define GP_STATUS_100M  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
97 #define GP_STATUS_1G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
98 #define GP_STATUS_2_5G  MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
99 #define GP_STATUS_5G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
100 #define GP_STATUS_6G    MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
101 #define GP_STATUS_10G_HIG \
102                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
103 #define GP_STATUS_10G_CX4 \
104                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
105 #define GP_STATUS_12G_HIG \
106                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
107 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
108 #define GP_STATUS_13G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
109 #define GP_STATUS_15G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
110 #define GP_STATUS_16G   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
111 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
112 #define GP_STATUS_10G_KX4 \
113                         MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114
115 #define LINK_10THD                      LINK_STATUS_SPEED_AND_DUPLEX_10THD
116 #define LINK_10TFD                      LINK_STATUS_SPEED_AND_DUPLEX_10TFD
117 #define LINK_100TXHD            LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
118 #define LINK_100T4                      LINK_STATUS_SPEED_AND_DUPLEX_100T4
119 #define LINK_100TXFD            LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
120 #define LINK_1000THD            LINK_STATUS_SPEED_AND_DUPLEX_1000THD
121 #define LINK_1000TFD            LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
122 #define LINK_1000XFD            LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
123 #define LINK_2500THD            LINK_STATUS_SPEED_AND_DUPLEX_2500THD
124 #define LINK_2500TFD            LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
125 #define LINK_2500XFD            LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
126 #define LINK_10GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
127 #define LINK_10GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
128 #define LINK_12GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
129 #define LINK_12GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
130 #define LINK_12_5GTFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
131 #define LINK_12_5GXFD           LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
132 #define LINK_13GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
133 #define LINK_13GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
134 #define LINK_15GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
135 #define LINK_15GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
136 #define LINK_16GTFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
137 #define LINK_16GXFD                     LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138
139 #define PHY_XGXS_FLAG                   0x1
140 #define PHY_SGMII_FLAG                  0x2
141 #define PHY_SERDES_FLAG                 0x4
142
143 /* */
144 #define SFP_EEPROM_CON_TYPE_ADDR                0x2
145         #define SFP_EEPROM_CON_TYPE_VAL_LC              0x7
146         #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
147
148
149 #define SFP_EEPROM_COMP_CODE_ADDR               0x3
150         #define SFP_EEPROM_COMP_CODE_SR_MASK    (1<<4)
151         #define SFP_EEPROM_COMP_CODE_LR_MASK    (1<<5)
152         #define SFP_EEPROM_COMP_CODE_LRM_MASK   (1<<6)
153
154 #define SFP_EEPROM_FC_TX_TECH_ADDR              0x8
155         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
156         #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE      0x8
157
158 #define SFP_EEPROM_OPTIONS_ADDR                 0x40
159         #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
160 #define SFP_EEPROM_OPTIONS_SIZE                 2
161
162 #define EDC_MODE_LINEAR                         0x0022
163 #define EDC_MODE_LIMITING                               0x0044
164 #define EDC_MODE_PASSIVE_DAC                    0x0055
165
166
167
168 /**********************************************************/
169 /*                     INTERFACE                          */
170 /**********************************************************/
171
172 #define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
173         bnx2x_cl45_write(_bp, _phy, \
174                 (_phy)->def_md_devad, \
175                 (_bank + (_addr & 0xf)), \
176                 _val)
177
178 #define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
179         bnx2x_cl45_read(_bp, _phy, \
180                 (_phy)->def_md_devad, \
181                 (_bank + (_addr & 0xf)), \
182                 _val)
183
184 static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
185                           u8 devad, u16 reg, u16 *ret_val);
186
187 static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
188                            u8 devad, u16 reg, u16 val);
189
190 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
191 {
192         u32 val = REG_RD(bp, reg);
193
194         val |= bits;
195         REG_WR(bp, reg, val);
196         return val;
197 }
198
199 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
200 {
201         u32 val = REG_RD(bp, reg);
202
203         val &= ~bits;
204         REG_WR(bp, reg, val);
205         return val;
206 }
207
208 static void bnx2x_emac_init(struct link_params *params,
209                            struct link_vars *vars)
210 {
211         /* reset and unreset the emac core */
212         struct bnx2x *bp = params->bp;
213         u8 port = params->port;
214         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
215         u32 val;
216         u16 timeout;
217
218         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
219                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
220         udelay(5);
221         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
222                    (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
223
224         /* init emac - use read-modify-write */
225         /* self clear reset */
226         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
227         EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
228
229         timeout = 200;
230         do {
231                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
232                 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
233                 if (!timeout) {
234                         DP(NETIF_MSG_LINK, "EMAC timeout!\n");
235                         return;
236                 }
237                 timeout--;
238         } while (val & EMAC_MODE_RESET);
239
240         /* Set mac address */
241         val = ((params->mac_addr[0] << 8) |
242                 params->mac_addr[1]);
243         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
244
245         val = ((params->mac_addr[2] << 24) |
246                (params->mac_addr[3] << 16) |
247                (params->mac_addr[4] << 8) |
248                 params->mac_addr[5]);
249         EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
250 }
251
252 static u8 bnx2x_emac_enable(struct link_params *params,
253                           struct link_vars *vars, u8 lb)
254 {
255         struct bnx2x *bp = params->bp;
256         u8 port = params->port;
257         u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
258         u32 val;
259
260         DP(NETIF_MSG_LINK, "enabling EMAC\n");
261
262         /* enable emac and not bmac */
263         REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
264
265         /* for paladium */
266         if (CHIP_REV_IS_EMUL(bp)) {
267                 /* Use lane 1 (of lanes 0-3) */
268                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
269                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
270                             port*4, 1);
271         }
272         /* for fpga */
273         else
274
275         if (CHIP_REV_IS_FPGA(bp)) {
276                 /* Use lane 1 (of lanes 0-3) */
277                 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
278
279                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
280                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
281                             0);
282         } else
283         /* ASIC */
284         if (vars->phy_flags & PHY_XGXS_FLAG) {
285                 u32 ser_lane = ((params->lane_config &
286                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
287                             PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
288
289                 DP(NETIF_MSG_LINK, "XGXS\n");
290                 /* select the master lanes (out of 0-3) */
291                 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
292                            port*4, ser_lane);
293                 /* select XGXS */
294                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
295                            port*4, 1);
296
297         } else { /* SerDes */
298                 DP(NETIF_MSG_LINK, "SerDes\n");
299                 /* select SerDes */
300                 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
301                            port*4, 0);
302         }
303
304         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
305                     EMAC_RX_MODE_RESET);
306         bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
307                     EMAC_TX_MODE_RESET);
308
309         if (CHIP_REV_IS_SLOW(bp)) {
310                 /* config GMII mode */
311                 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
312                 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
313                             (val | EMAC_MODE_PORT_GMII));
314         } else { /* ASIC */
315                 /* pause enable/disable */
316                 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
317                                EMAC_RX_MODE_FLOW_EN);
318                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
319                         bnx2x_bits_en(bp, emac_base +
320                                     EMAC_REG_EMAC_RX_MODE,
321                                     EMAC_RX_MODE_FLOW_EN);
322
323                 bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
324                              (EMAC_TX_MODE_EXT_PAUSE_EN |
325                               EMAC_TX_MODE_FLOW_EN));
326                 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
327                         bnx2x_bits_en(bp, emac_base +
328                                     EMAC_REG_EMAC_TX_MODE,
329                                    (EMAC_TX_MODE_EXT_PAUSE_EN |
330                                     EMAC_TX_MODE_FLOW_EN));
331         }
332
333         /* KEEP_VLAN_TAG, promiscuous */
334         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
335         val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
336         EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
337
338         /* Set Loopback */
339         val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
340         if (lb)
341                 val |= 0x810;
342         else
343                 val &= ~0x810;
344         EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
345
346         /* enable emac */
347         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
348
349         /* enable emac for jumbo packets */
350         EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
351                 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
352                  (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
353
354         /* strip CRC */
355         REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
356
357         /* disable the NIG in/out to the bmac */
358         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
359         REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
360         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
361
362         /* enable the NIG in/out to the emac */
363         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
364         val = 0;
365         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
366                 val = 1;
367
368         REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
369         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
370
371         if (CHIP_REV_IS_EMUL(bp)) {
372                 /* take the BigMac out of reset */
373                 REG_WR(bp,
374                            GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
375                            (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
376
377                 /* enable access for bmac registers */
378                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
379         } else
380                 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
381
382         vars->mac_type = MAC_TYPE_EMAC;
383         return 0;
384 }
385
386 static void bnx2x_update_bmac2(struct link_params *params,
387                                struct link_vars *vars,
388                                u8 is_lb)
389 {
390         /*
391          * Set rx control: Strip CRC and enable BigMAC to relay
392          * control packets to the system as well
393          */
394         u32 wb_data[2];
395         struct bnx2x *bp = params->bp;
396         u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
397                 NIG_REG_INGRESS_BMAC0_MEM;
398         u32 val = 0x14;
399
400         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
401                 /* Enable BigMAC to react on received Pause packets */
402                 val |= (1<<5);
403         wb_data[0] = val;
404         wb_data[1] = 0;
405         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL,
406                         wb_data, 2);
407         udelay(30);
408
409         /* Tx control */
410         val = 0xc0;
411         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
412                 val |= 0x800000;
413         wb_data[0] = val;
414         wb_data[1] = 0;
415         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL,
416                         wb_data, 2);
417
418         val = 0x8000;
419         wb_data[0] = val;
420         wb_data[1] = 0;
421         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
422                         wb_data, 2);
423
424         /* mac control */
425         val = 0x3; /* Enable RX and TX */
426         if (is_lb) {
427                 val |= 0x4; /* Local loopback */
428                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
429         }
430
431         wb_data[0] = val;
432         wb_data[1] = 0;
433         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
434                         wb_data, 2);
435 }
436
437
438 static u8 bnx2x_bmac1_enable(struct link_params *params,
439                              struct link_vars *vars,
440                           u8 is_lb)
441 {
442         struct bnx2x *bp = params->bp;
443         u8 port = params->port;
444         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
445                                NIG_REG_INGRESS_BMAC0_MEM;
446         u32 wb_data[2];
447         u32 val;
448
449         DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
450
451         /* XGXS control */
452         wb_data[0] = 0x3c;
453         wb_data[1] = 0;
454         REG_WR_DMAE(bp, bmac_addr +
455                       BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
456                       wb_data, 2);
457
458         /* tx MAC SA */
459         wb_data[0] = ((params->mac_addr[2] << 24) |
460                        (params->mac_addr[3] << 16) |
461                        (params->mac_addr[4] << 8) |
462                         params->mac_addr[5]);
463         wb_data[1] = ((params->mac_addr[0] << 8) |
464                         params->mac_addr[1]);
465         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
466                     wb_data, 2);
467
468         /* tx control */
469         val = 0xc0;
470         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
471                 val |= 0x800000;
472         wb_data[0] = val;
473         wb_data[1] = 0;
474         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
475                         wb_data, 2);
476
477         /* mac control */
478         val = 0x3;
479         if (is_lb) {
480                 val |= 0x4;
481                 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
482         }
483         wb_data[0] = val;
484         wb_data[1] = 0;
485         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
486                     wb_data, 2);
487
488         /* set rx mtu */
489         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
490         wb_data[1] = 0;
491         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
492                         wb_data, 2);
493
494         /* rx control set to don't strip crc */
495         val = 0x14;
496         if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
497                 val |= 0x20;
498         wb_data[0] = val;
499         wb_data[1] = 0;
500         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
501                         wb_data, 2);
502
503         /* set tx mtu */
504         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
505         wb_data[1] = 0;
506         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
507                         wb_data, 2);
508
509         /* set cnt max size */
510         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
511         wb_data[1] = 0;
512         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
513                     wb_data, 2);
514
515         /* configure safc */
516         wb_data[0] = 0x1000200;
517         wb_data[1] = 0;
518         REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
519                     wb_data, 2);
520         /* fix for emulation */
521         if (CHIP_REV_IS_EMUL(bp)) {
522                 wb_data[0] = 0xf000;
523                 wb_data[1] = 0;
524                 REG_WR_DMAE(bp,
525                             bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
526                             wb_data, 2);
527         }
528
529
530         return 0;
531 }
532
533 static u8 bnx2x_bmac2_enable(struct link_params *params,
534                              struct link_vars *vars,
535                              u8 is_lb)
536 {
537         struct bnx2x *bp = params->bp;
538         u8 port = params->port;
539         u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
540                                NIG_REG_INGRESS_BMAC0_MEM;
541         u32 wb_data[2];
542
543         DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
544
545         wb_data[0] = 0;
546         wb_data[1] = 0;
547         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL,
548                         wb_data, 2);
549         udelay(30);
550
551         /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
552         wb_data[0] = 0x3c;
553         wb_data[1] = 0;
554         REG_WR_DMAE(bp, bmac_addr +
555                         BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
556                         wb_data, 2);
557
558         udelay(30);
559
560         /* tx MAC SA */
561         wb_data[0] = ((params->mac_addr[2] << 24) |
562                        (params->mac_addr[3] << 16) |
563                        (params->mac_addr[4] << 8) |
564                         params->mac_addr[5]);
565         wb_data[1] = ((params->mac_addr[0] << 8) |
566                         params->mac_addr[1]);
567         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
568                         wb_data, 2);
569
570         udelay(30);
571
572         /* Configure SAFC */
573         wb_data[0] = 0x1000200;
574         wb_data[1] = 0;
575         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
576                         wb_data, 2);
577         udelay(30);
578
579         /* set rx mtu */
580         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
581         wb_data[1] = 0;
582         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE,
583                         wb_data, 2);
584         udelay(30);
585
586         /* set tx mtu */
587         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
588         wb_data[1] = 0;
589         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE,
590                         wb_data, 2);
591         udelay(30);
592         /* set cnt max size */
593         wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
594         wb_data[1] = 0;
595         REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE,
596                         wb_data, 2);
597         udelay(30);
598         bnx2x_update_bmac2(params, vars, is_lb);
599
600         return 0;
601 }
602
603 static u8 bnx2x_bmac_enable(struct link_params *params,
604                             struct link_vars *vars,
605                             u8 is_lb)
606 {
607         u8 rc, port = params->port;
608         struct bnx2x *bp = params->bp;
609         u32 val;
610         /* reset and unreset the BigMac */
611         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
612                      (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
613         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         if (REG_RD(bp, params->shmem_base +
3529                          offsetof(struct shmem_region, dev_info.
3530                                   port_hw_config[params->port].default_cfg)) &
3531             PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
3532
3533                 bnx2x_cl45_read(bp, phy,
3534                                 MDIO_AN_DEVAD,
3535                                 MDIO_AN_REG_8073_BAM, &val);
3536                 bnx2x_cl45_write(bp, phy,
3537                                  MDIO_AN_DEVAD,
3538                                  MDIO_AN_REG_8073_BAM, val | 1);
3539                 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
3540         }
3541         if (params->loopback_mode == LOOPBACK_EXT) {
3542                 bnx2x_807x_force_10G(bp, phy);
3543                 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
3544                 return 0;
3545         } else {
3546                 bnx2x_cl45_write(bp, phy,
3547                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
3548         }
3549         if (phy->req_line_speed != SPEED_AUTO_NEG) {
3550                 if (phy->req_line_speed == SPEED_10000) {
3551                         val = (1<<7);
3552                 } else if (phy->req_line_speed ==  SPEED_2500) {
3553                         val = (1<<5);
3554                         /* Note that 2.5G works only
3555                         when used with 1G advertisment */
3556                 } else
3557                         val = (1<<5);
3558         } else {
3559                 val = 0;
3560                 if (phy->speed_cap_mask &
3561                         PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3562                         val |= (1<<7);
3563
3564                 /* Note that 2.5G works only when
3565                 used with 1G advertisment */
3566                 if (phy->speed_cap_mask &
3567                         (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3568                          PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3569                         val |= (1<<5);
3570                 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
3571         }
3572
3573         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
3574         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
3575
3576         if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3577              (phy->req_line_speed == SPEED_AUTO_NEG)) ||
3578             (phy->req_line_speed == SPEED_2500)) {
3579                 u16 phy_ver;
3580                 /* Allow 2.5G for A1 and above */
3581                 bnx2x_cl45_read(bp, phy,
3582                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
3583                                 &phy_ver);
3584                 DP(NETIF_MSG_LINK, "Add 2.5G\n");
3585                 if (phy_ver > 0)
3586                         tmp1 |= 1;
3587                 else
3588                         tmp1 &= 0xfffe;
3589         } else {
3590                 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3591                 tmp1 &= 0xfffe;
3592         }
3593
3594         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
3595         /* Add support for CL37 (passive mode) II */
3596
3597         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
3598         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
3599                          (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
3600                                   0x20 : 0x40)));
3601
3602         /* Add support for CL37 (passive mode) III */
3603         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
3604
3605         /* The SNR will improve about 2db by changing
3606         BW and FEE main tap. Rest commands are executed
3607         after link is up*/
3608         if (bnx2x_8073_is_snr_needed(bp, phy))
3609                 bnx2x_cl45_write(bp, phy,
3610                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
3611                                  0xFB0C);
3612
3613         /* Enable FEC (Forware Error Correction) Request in the AN */
3614         bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
3615         tmp1 |= (1<<15);
3616         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
3617
3618         bnx2x_ext_phy_set_pause(params, phy, vars);
3619
3620         /* Restart autoneg */
3621         msleep(500);
3622         bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
3623         DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
3624                    ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
3625         return 0;
3626 }
3627
3628 static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
3629                                  struct link_params *params,
3630                                  struct link_vars *vars)
3631 {
3632         struct bnx2x *bp = params->bp;
3633         u8 link_up = 0;
3634         u16 val1, val2;
3635         u16 link_status = 0;
3636         u16 an1000_status = 0;
3637
3638         bnx2x_cl45_read(bp, phy,
3639                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
3640
3641         DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
3642
3643         /* clear the interrupt LASI status register */
3644         bnx2x_cl45_read(bp, phy,
3645                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
3646         bnx2x_cl45_read(bp, phy,
3647                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
3648         DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
3649         /* Clear MSG-OUT */
3650         bnx2x_cl45_read(bp, phy,
3651                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
3652
3653         /* Check the LASI */
3654         bnx2x_cl45_read(bp, phy,
3655                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
3656
3657         DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3658
3659         /* Check the link status */
3660         bnx2x_cl45_read(bp, phy,
3661                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
3662         DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3663
3664         bnx2x_cl45_read(bp, phy,
3665                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
3666         bnx2x_cl45_read(bp, phy,
3667                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
3668         link_up = ((val1 & 4) == 4);
3669         DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3670
3671         if (link_up &&
3672              ((phy->req_line_speed != SPEED_10000))) {
3673                 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
3674                         return 0;
3675         }
3676         bnx2x_cl45_read(bp, phy,
3677                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
3678         bnx2x_cl45_read(bp, phy,
3679                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
3680
3681         /* Check the link status on 1.1.2 */
3682         bnx2x_cl45_read(bp, phy,
3683                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
3684         bnx2x_cl45_read(bp, phy,
3685                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
3686         DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3687                    "an_link_status=0x%x\n", val2, val1, an1000_status);
3688
3689         link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
3690         if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
3691                 /* The SNR will improve about 2dbby
3692                 changing the BW and FEE main tap.*/
3693                 /* The 1st write to change FFE main
3694                 tap is set before restart AN */
3695                 /* Change PLL Bandwidth in EDC
3696                 register */
3697                 bnx2x_cl45_write(bp, phy,
3698                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
3699                                  0x26BC);
3700
3701                 /* Change CDR Bandwidth in EDC register */
3702                 bnx2x_cl45_write(bp, phy,
3703                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
3704                                  0x0333);
3705         }
3706         bnx2x_cl45_read(bp, phy,
3707                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
3708                         &link_status);
3709
3710         /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
3711         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
3712                 link_up = 1;
3713                 vars->line_speed = SPEED_10000;
3714                 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
3715                            params->port);
3716         } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
3717                 link_up = 1;
3718                 vars->line_speed = SPEED_2500;
3719                 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
3720                            params->port);
3721         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
3722                 link_up = 1;
3723                 vars->line_speed = SPEED_1000;
3724                 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
3725                            params->port);
3726         } else {
3727                 link_up = 0;
3728                 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
3729                            params->port);
3730         }
3731
3732         if (link_up) {
3733                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
3734                 bnx2x_8073_resolve_fc(phy, params, vars);
3735         }
3736         return link_up;
3737 }
3738
3739 static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
3740                                   struct link_params *params)
3741 {
3742         struct bnx2x *bp = params->bp;
3743         u8 gpio_port;
3744         if (CHIP_IS_E2(bp))
3745                 gpio_port = BP_PATH(bp);
3746         else
3747                 gpio_port = params->port;
3748         DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
3749            gpio_port);
3750         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3751                             MISC_REGISTERS_GPIO_OUTPUT_LOW,
3752                             gpio_port);
3753 }
3754
3755 /******************************************************************/
3756 /*                      BCM8705 PHY SECTION                       */
3757 /******************************************************************/
3758 static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
3759                                  struct link_params *params,
3760                                  struct link_vars *vars)
3761 {
3762         struct bnx2x *bp = params->bp;
3763         DP(NETIF_MSG_LINK, "init 8705\n");
3764         /* Restore normal power mode*/
3765         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3766                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3767         /* HW reset */
3768         bnx2x_ext_phy_hw_reset(bp, params->port);
3769         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
3770         bnx2x_wait_reset_complete(bp, phy);
3771
3772         bnx2x_cl45_write(bp, phy,
3773                          MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
3774         bnx2x_cl45_write(bp, phy,
3775                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
3776         bnx2x_cl45_write(bp, phy,
3777                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
3778         bnx2x_cl45_write(bp, phy,
3779                          MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
3780         /* BCM8705 doesn't have microcode, hence the 0 */
3781         bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
3782         return 0;
3783 }
3784
3785 static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
3786                                  struct link_params *params,
3787                                  struct link_vars *vars)
3788 {
3789         u8 link_up = 0;
3790         u16 val1, rx_sd;
3791         struct bnx2x *bp = params->bp;
3792         DP(NETIF_MSG_LINK, "read status 8705\n");
3793         bnx2x_cl45_read(bp, phy,
3794                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
3795         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3796
3797         bnx2x_cl45_read(bp, phy,
3798                       MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
3799         DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
3800
3801         bnx2x_cl45_read(bp, phy,
3802                       MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
3803
3804         bnx2x_cl45_read(bp, phy,
3805                       MDIO_PMA_DEVAD, 0xc809, &val1);
3806         bnx2x_cl45_read(bp, phy,
3807                       MDIO_PMA_DEVAD, 0xc809, &val1);
3808
3809         DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
3810         link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
3811         if (link_up) {
3812                 vars->line_speed = SPEED_10000;
3813                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
3814         }
3815         return link_up;
3816 }
3817
3818 /******************************************************************/
3819 /*                      SFP+ module Section                       */
3820 /******************************************************************/
3821 static void bnx2x_sfp_set_transmitter(struct bnx2x *bp,
3822                                       struct bnx2x_phy *phy,
3823                                       u8 port,
3824                                       u8 tx_en)
3825 {
3826         u16 val;
3827
3828         DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
3829                  tx_en, port);
3830         /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
3831         bnx2x_cl45_read(bp, phy,
3832                       MDIO_PMA_DEVAD,
3833                       MDIO_PMA_REG_PHY_IDENTIFIER,
3834                       &val);
3835
3836         if (tx_en)
3837                 val &= ~(1<<15);
3838         else
3839                 val |= (1<<15);
3840
3841         bnx2x_cl45_write(bp, phy,
3842                        MDIO_PMA_DEVAD,
3843                        MDIO_PMA_REG_PHY_IDENTIFIER,
3844                        val);
3845 }
3846
3847 static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
3848                                             struct link_params *params,
3849                                           u16 addr, u8 byte_cnt, u8 *o_buf)
3850 {
3851         struct bnx2x *bp = params->bp;
3852         u16 val = 0;
3853         u16 i;
3854         if (byte_cnt > 16) {
3855                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
3856                             " is limited to 0xf\n");
3857                 return -EINVAL;
3858         }
3859         /* Set the read command byte count */
3860         bnx2x_cl45_write(bp, phy,
3861                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
3862                        (byte_cnt | 0xa000));
3863
3864         /* Set the read command address */
3865         bnx2x_cl45_write(bp, phy,
3866                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
3867                        addr);
3868
3869         /* Activate read command */
3870         bnx2x_cl45_write(bp, phy,
3871                          MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
3872                        0x2c0f);
3873
3874         /* Wait up to 500us for command complete status */
3875         for (i = 0; i < 100; i++) {
3876                 bnx2x_cl45_read(bp, phy,
3877                               MDIO_PMA_DEVAD,
3878                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
3879                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
3880                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
3881                         break;
3882                 udelay(5);
3883         }
3884
3885         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
3886                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
3887                 DP(NETIF_MSG_LINK,
3888                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
3889                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
3890                 return -EINVAL;
3891         }
3892
3893         /* Read the buffer */
3894         for (i = 0; i < byte_cnt; i++) {
3895                 bnx2x_cl45_read(bp, phy,
3896                               MDIO_PMA_DEVAD,
3897                               MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
3898                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
3899         }
3900
3901         for (i = 0; i < 100; i++) {
3902                 bnx2x_cl45_read(bp, phy,
3903                               MDIO_PMA_DEVAD,
3904                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
3905                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
3906                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
3907                         return 0;;
3908                 msleep(1);
3909         }
3910         return -EINVAL;
3911 }
3912
3913 static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
3914                                             struct link_params *params,
3915                                           u16 addr, u8 byte_cnt, u8 *o_buf)
3916 {
3917         struct bnx2x *bp = params->bp;
3918         u16 val, i;
3919
3920         if (byte_cnt > 16) {
3921                 DP(NETIF_MSG_LINK, "Reading from eeprom is"
3922                             " is limited to 0xf\n");
3923                 return -EINVAL;
3924         }
3925
3926         /* Need to read from 1.8000 to clear it */
3927         bnx2x_cl45_read(bp, phy,
3928                       MDIO_PMA_DEVAD,
3929                       MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
3930                       &val);
3931
3932         /* Set the read command byte count */
3933         bnx2x_cl45_write(bp, phy,
3934                        MDIO_PMA_DEVAD,
3935                        MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
3936                        ((byte_cnt < 2) ? 2 : byte_cnt));
3937
3938         /* Set the read command address */
3939         bnx2x_cl45_write(bp, phy,
3940                        MDIO_PMA_DEVAD,
3941                        MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
3942                        addr);
3943         /* Set the destination address */
3944         bnx2x_cl45_write(bp, phy,
3945                        MDIO_PMA_DEVAD,
3946                        0x8004,
3947                        MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
3948
3949         /* Activate read command */
3950         bnx2x_cl45_write(bp, phy,
3951                        MDIO_PMA_DEVAD,
3952                        MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
3953                        0x8002);
3954         /* Wait appropriate time for two-wire command to finish before
3955         polling the status register */
3956         msleep(1);
3957
3958         /* Wait up to 500us for command complete status */
3959         for (i = 0; i < 100; i++) {
3960                 bnx2x_cl45_read(bp, phy,
3961                               MDIO_PMA_DEVAD,
3962                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
3963                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
3964                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
3965                         break;
3966                 udelay(5);
3967         }
3968
3969         if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
3970                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
3971                 DP(NETIF_MSG_LINK,
3972                          "Got bad status 0x%x when reading from SFP+ EEPROM\n",
3973                          (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
3974                 return -EINVAL;
3975         }
3976
3977         /* Read the buffer */
3978         for (i = 0; i < byte_cnt; i++) {
3979                 bnx2x_cl45_read(bp, phy,
3980                               MDIO_PMA_DEVAD,
3981                               MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
3982                 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
3983         }
3984
3985         for (i = 0; i < 100; i++) {
3986                 bnx2x_cl45_read(bp, phy,
3987                               MDIO_PMA_DEVAD,
3988                               MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
3989                 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
3990                     MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
3991                         return 0;;
3992                 msleep(1);
3993         }
3994
3995         return -EINVAL;
3996 }
3997
3998 static u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
3999                                        struct link_params *params, u16 addr,
4000                                        u8 byte_cnt, u8 *o_buf)
4001 {
4002         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
4003                 return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
4004                                                        byte_cnt, o_buf);
4005         else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
4006                 return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
4007                                                        byte_cnt, o_buf);
4008         return -EINVAL;
4009 }
4010
4011 static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy,
4012                              struct link_params *params,
4013                                   u16 *edc_mode)
4014 {
4015         struct bnx2x *bp = params->bp;
4016         u8 val, check_limiting_mode = 0;
4017         *edc_mode = EDC_MODE_LIMITING;
4018
4019         /* First check for copper cable */
4020         if (bnx2x_read_sfp_module_eeprom(phy,
4021                                          params,
4022                                          SFP_EEPROM_CON_TYPE_ADDR,
4023                                          1,
4024                                          &val) != 0) {
4025                 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
4026                 return -EINVAL;
4027         }
4028
4029         switch (val) {
4030         case SFP_EEPROM_CON_TYPE_VAL_COPPER:
4031         {
4032                 u8 copper_module_type;
4033
4034                 /* Check if its active cable( includes SFP+ module)
4035                 of passive cable*/
4036                 if (bnx2x_read_sfp_module_eeprom(phy,
4037                                                params,
4038                                                SFP_EEPROM_FC_TX_TECH_ADDR,
4039                                                1,
4040                                                &copper_module_type) !=
4041                     0) {
4042                         DP(NETIF_MSG_LINK,
4043                                 "Failed to read copper-cable-type"
4044                                 " from SFP+ EEPROM\n");
4045                         return -EINVAL;
4046                 }
4047
4048                 if (copper_module_type &
4049                     SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
4050                         DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
4051                         check_limiting_mode = 1;
4052                 } else if (copper_module_type &
4053                         SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
4054                                 DP(NETIF_MSG_LINK, "Passive Copper"
4055                                             " cable detected\n");
4056                                 *edc_mode =
4057                                       EDC_MODE_PASSIVE_DAC;
4058                 } else {
4059                         DP(NETIF_MSG_LINK, "Unknown copper-cable-"
4060                                      "type 0x%x !!!\n", copper_module_type);
4061                         return -EINVAL;
4062                 }
4063                 break;
4064         }
4065         case SFP_EEPROM_CON_TYPE_VAL_LC:
4066                 DP(NETIF_MSG_LINK, "Optic module detected\n");
4067                 check_limiting_mode = 1;
4068                 break;
4069         default:
4070                 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
4071                          val);
4072                 return -EINVAL;
4073         }
4074
4075         if (check_limiting_mode) {
4076                 u8 options[SFP_EEPROM_OPTIONS_SIZE];
4077                 if (bnx2x_read_sfp_module_eeprom(phy,
4078                                                  params,
4079                                                  SFP_EEPROM_OPTIONS_ADDR,
4080                                                  SFP_EEPROM_OPTIONS_SIZE,
4081                                                  options) != 0) {
4082                         DP(NETIF_MSG_LINK, "Failed to read Option"
4083                                 " field from module EEPROM\n");
4084                         return -EINVAL;
4085                 }
4086                 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
4087                         *edc_mode = EDC_MODE_LINEAR;
4088                 else
4089                         *edc_mode = EDC_MODE_LIMITING;
4090         }
4091         DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
4092         return 0;
4093 }
4094 /* This function read the relevant field from the module ( SFP+ ),
4095         and verify it is compliant with this board */
4096 static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
4097                                   struct link_params *params)
4098 {
4099         struct bnx2x *bp = params->bp;
4100         u32 val, cmd;
4101         u32 fw_resp, fw_cmd_param;
4102         char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
4103         char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
4104         phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
4105         val = REG_RD(bp, params->shmem_base +
4106                          offsetof(struct shmem_region, dev_info.
4107                                   port_feature_config[params->port].config));
4108         if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4109             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
4110                 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
4111                 return 0;
4112         }
4113
4114         if (params->feature_config_flags &
4115             FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
4116                 /* Use specific phy request */
4117                 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
4118         } else if (params->feature_config_flags &
4119                    FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
4120                 /* Use first phy request only in case of non-dual media*/
4121                 if (DUAL_MEDIA(params)) {
4122                         DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
4123                            "verification\n");
4124                         return -EINVAL;
4125                 }
4126                 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
4127         } else {
4128                 /* No support in OPT MDL detection */
4129                 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
4130                           "verification\n");
4131                 return -EINVAL;
4132         }
4133
4134         fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
4135         fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
4136         if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
4137                 DP(NETIF_MSG_LINK, "Approved module\n");
4138                 return 0;
4139         }
4140
4141         /* format the warning message */
4142         if (bnx2x_read_sfp_module_eeprom(phy,
4143                                          params,
4144                                        SFP_EEPROM_VENDOR_NAME_ADDR,
4145                                        SFP_EEPROM_VENDOR_NAME_SIZE,
4146                                        (u8 *)vendor_name))
4147                 vendor_name[0] = '\0';
4148         else
4149                 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
4150         if (bnx2x_read_sfp_module_eeprom(phy,
4151                                          params,
4152                                        SFP_EEPROM_PART_NO_ADDR,
4153                                        SFP_EEPROM_PART_NO_SIZE,
4154                                        (u8 *)vendor_pn))
4155                 vendor_pn[0] = '\0';
4156         else
4157                 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
4158
4159         netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected,"
4160                              " Port %d from %s part number %s\n",
4161                     params->port, vendor_name, vendor_pn);
4162         phy->flags |= FLAGS_SFP_NOT_APPROVED;
4163         return -EINVAL;
4164 }
4165
4166 static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
4167                                                 struct link_params *params)
4168
4169 {
4170         u8 val;
4171         struct bnx2x *bp = params->bp;
4172         u16 timeout;
4173         /* Initialization time after hot-plug may take up to 300ms for some
4174         phys type ( e.g. JDSU ) */
4175         for (timeout = 0; timeout < 60; timeout++) {
4176                 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
4177                     == 0) {
4178                         DP(NETIF_MSG_LINK, "SFP+ module initialization "
4179                                      "took %d ms\n", timeout * 5);
4180                         return 0;
4181                 }
4182                 msleep(5);
4183         }
4184         return -EINVAL;
4185 }
4186
4187 static void bnx2x_8727_power_module(struct bnx2x *bp,
4188                                     struct bnx2x_phy *phy,
4189                                     u8 is_power_up) {
4190         /* Make sure GPIOs are not using for LED mode */
4191         u16 val;
4192         /*
4193          * In the GPIO register, bit 4 is use to detemine if the GPIOs are
4194          * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
4195          * output
4196          * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
4197          * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
4198          * where the 1st bit is the over-current(only input), and 2nd bit is
4199          * for power( only output )
4200         */
4201
4202         /*
4203          * In case of NOC feature is disabled and power is up, set GPIO control
4204          *  as input to enable listening of over-current indication
4205          */
4206         if (phy->flags & FLAGS_NOC)
4207                 return;
4208         if (!(phy->flags &
4209               FLAGS_NOC) && is_power_up)
4210                 val = (1<<4);
4211         else
4212                 /*
4213                  * Set GPIO control to OUTPUT, and set the power bit
4214                  * to according to the is_power_up
4215                  */
4216                 val = ((!(is_power_up)) << 1);
4217
4218         bnx2x_cl45_write(bp, phy,
4219                          MDIO_PMA_DEVAD,
4220                          MDIO_PMA_REG_8727_GPIO_CTRL,
4221                          val);
4222 }
4223
4224 static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
4225                                        struct bnx2x_phy *phy,
4226                                        u16 edc_mode)
4227 {
4228         u16 cur_limiting_mode;
4229
4230         bnx2x_cl45_read(bp, phy,
4231                       MDIO_PMA_DEVAD,
4232                       MDIO_PMA_REG_ROM_VER2,
4233                       &cur_limiting_mode);
4234         DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
4235                  cur_limiting_mode);
4236
4237         if (edc_mode == EDC_MODE_LIMITING) {
4238                 DP(NETIF_MSG_LINK,
4239                          "Setting LIMITING MODE\n");
4240                 bnx2x_cl45_write(bp, phy,
4241                                  MDIO_PMA_DEVAD,
4242                                  MDIO_PMA_REG_ROM_VER2,
4243                                  EDC_MODE_LIMITING);
4244         } else { /* LRM mode ( default )*/
4245
4246                 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
4247
4248                 /* Changing to LRM mode takes quite few seconds.
4249                 So do it only if current mode is limiting
4250                 ( default is LRM )*/
4251                 if (cur_limiting_mode != EDC_MODE_LIMITING)
4252                         return 0;
4253
4254                 bnx2x_cl45_write(bp, phy,
4255                                MDIO_PMA_DEVAD,
4256                                MDIO_PMA_REG_LRM_MODE,
4257                                0);
4258                 bnx2x_cl45_write(bp, phy,
4259                                MDIO_PMA_DEVAD,
4260                                MDIO_PMA_REG_ROM_VER2,
4261                                0x128);
4262                 bnx2x_cl45_write(bp, phy,
4263                                MDIO_PMA_DEVAD,
4264                                MDIO_PMA_REG_MISC_CTRL0,
4265                                0x4008);
4266                 bnx2x_cl45_write(bp, phy,
4267                                MDIO_PMA_DEVAD,
4268                                MDIO_PMA_REG_LRM_MODE,
4269                                0xaaaa);
4270         }
4271         return 0;
4272 }
4273
4274 static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
4275                                        struct bnx2x_phy *phy,
4276                                         u16 edc_mode)
4277 {
4278         u16 phy_identifier;
4279         u16 rom_ver2_val;
4280         bnx2x_cl45_read(bp, phy,
4281                        MDIO_PMA_DEVAD,
4282                        MDIO_PMA_REG_PHY_IDENTIFIER,
4283                        &phy_identifier);
4284
4285         bnx2x_cl45_write(bp, phy,
4286                        MDIO_PMA_DEVAD,
4287                        MDIO_PMA_REG_PHY_IDENTIFIER,
4288                        (phy_identifier & ~(1<<9)));
4289
4290         bnx2x_cl45_read(bp, phy,
4291                       MDIO_PMA_DEVAD,
4292                       MDIO_PMA_REG_ROM_VER2,
4293                       &rom_ver2_val);
4294         /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
4295         bnx2x_cl45_write(bp, phy,
4296                        MDIO_PMA_DEVAD,
4297                        MDIO_PMA_REG_ROM_VER2,
4298                        (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
4299
4300         bnx2x_cl45_write(bp, phy,
4301                        MDIO_PMA_DEVAD,
4302                        MDIO_PMA_REG_PHY_IDENTIFIER,
4303                        (phy_identifier | (1<<9)));
4304
4305         return 0;
4306 }
4307
4308 static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
4309                                      struct link_params *params,
4310                                      u32 action)
4311 {
4312         struct bnx2x *bp = params->bp;
4313
4314         switch (action) {
4315         case DISABLE_TX:
4316                 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
4317                 break;
4318         case ENABLE_TX:
4319                 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
4320                         bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
4321                 break;
4322         default:
4323                 DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
4324                    action);
4325                 return;
4326         }
4327 }
4328
4329 static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
4330                                      struct link_params *params)
4331 {
4332         struct bnx2x *bp = params->bp;
4333         u16 edc_mode;
4334         u8 rc = 0;
4335
4336         u32 val = REG_RD(bp, params->shmem_base +
4337                              offsetof(struct shmem_region, dev_info.
4338                                      port_feature_config[params->port].config));
4339
4340         DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
4341                  params->port);
4342
4343         if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
4344                 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
4345                 return -EINVAL;
4346         } else if (bnx2x_verify_sfp_module(phy, params) !=
4347                    0) {
4348                 /* check SFP+ module compatibility */
4349                 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
4350                 rc = -EINVAL;
4351                 /* Turn on fault module-detected led */
4352                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4353                                   MISC_REGISTERS_GPIO_HIGH,
4354                                   params->port);
4355                 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
4356                     ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4357                      PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
4358                         /* Shutdown SFP+ module */
4359                         DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
4360                         bnx2x_8727_power_module(bp, phy, 0);
4361                         return rc;
4362                 }
4363         } else {
4364                 /* Turn off fault module-detected led */
4365                 DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
4366                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4367                                           MISC_REGISTERS_GPIO_LOW,
4368                                           params->port);
4369         }
4370
4371         /* power up the SFP module */
4372         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
4373                 bnx2x_8727_power_module(bp, phy, 1);
4374
4375         /* Check and set limiting mode / LRM mode on 8726.
4376         On 8727 it is done automatically */
4377         if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
4378                 bnx2x_8726_set_limiting_mode(bp, phy, edc_mode);
4379         else
4380                 bnx2x_8727_set_limiting_mode(bp, phy, edc_mode);
4381         /*
4382          * Enable transmit for this module if the module is approved, or
4383          * if unapproved modules should also enable the Tx laser
4384          */
4385         if (rc == 0 ||
4386             (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
4387             PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
4388                 bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
4389         else
4390                 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
4391
4392         return rc;
4393 }
4394
4395 void bnx2x_handle_module_detect_int(struct link_params *params)
4396 {
4397         struct bnx2x *bp = params->bp;
4398         struct bnx2x_phy *phy = &params->phy[EXT_PHY1];
4399         u32 gpio_val;
4400         u8 port = params->port;
4401
4402         /* Set valid module led off */
4403         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4404                           MISC_REGISTERS_GPIO_HIGH,
4405                           params->port);
4406
4407         /* Get current gpio val refelecting module plugged in / out*/
4408         gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
4409
4410         /* Call the handling function in case module is detected */
4411         if (gpio_val == 0) {
4412
4413                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
4414                                    MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
4415                                    port);
4416
4417                 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
4418                         bnx2x_sfp_module_detection(phy, params);
4419                 else
4420                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
4421         } else {
4422                 u32 val = REG_RD(bp, params->shmem_base +
4423                                      offsetof(struct shmem_region, dev_info.
4424                                               port_feature_config[params->port].
4425                                               config));
4426
4427                 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
4428                                    MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
4429                                    port);
4430                 /* Module was plugged out. */
4431                 /* Disable transmit for this module */
4432                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4433                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
4434                         bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
4435         }
4436 }
4437
4438 /******************************************************************/
4439 /*              common BCM8706/BCM8726 PHY SECTION                */
4440 /******************************************************************/
4441 static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
4442                                       struct link_params *params,
4443                                       struct link_vars *vars)
4444 {
4445         u8 link_up = 0;
4446         u16 val1, val2, rx_sd, pcs_status;
4447         struct bnx2x *bp = params->bp;
4448         DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
4449         /* Clear RX Alarm*/
4450         bnx2x_cl45_read(bp, phy,
4451                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
4452         /* clear LASI indication*/
4453         bnx2x_cl45_read(bp, phy,
4454                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
4455         bnx2x_cl45_read(bp, phy,
4456                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
4457         DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
4458
4459         bnx2x_cl45_read(bp, phy,
4460                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
4461         bnx2x_cl45_read(bp, phy,
4462                         MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
4463         bnx2x_cl45_read(bp, phy,
4464                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
4465         bnx2x_cl45_read(bp, phy,
4466                         MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
4467
4468         DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
4469                         " link_status 0x%x\n", rx_sd, pcs_status, val2);
4470         /* link is up if both bit 0 of pmd_rx_sd and
4471          * bit 0 of pcs_status are set, or if the autoneg bit
4472          * 1 is set
4473          */
4474         link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
4475         if (link_up) {
4476                 if (val2 & (1<<1))
4477                         vars->line_speed = SPEED_1000;
4478                 else
4479                         vars->line_speed = SPEED_10000;
4480                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
4481         }
4482         return link_up;
4483 }
4484
4485 /******************************************************************/
4486 /*                      BCM8706 PHY SECTION                       */
4487 /******************************************************************/
4488 static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
4489                                  struct link_params *params,
4490                                  struct link_vars *vars)
4491 {
4492         u16 cnt, val;
4493         struct bnx2x *bp = params->bp;
4494         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4495                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
4496         /* HW reset */
4497         bnx2x_ext_phy_hw_reset(bp, params->port);
4498         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
4499         bnx2x_wait_reset_complete(bp, phy);
4500
4501         /* Wait until fw is loaded */
4502         for (cnt = 0; cnt < 100; cnt++) {
4503                 bnx2x_cl45_read(bp, phy,
4504                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
4505                 if (val)
4506                         break;
4507                 msleep(10);
4508         }
4509         DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
4510         if ((params->feature_config_flags &
4511              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
4512                 u8 i;
4513                 u16 reg;
4514                 for (i = 0; i < 4; i++) {
4515                         reg = MDIO_XS_8706_REG_BANK_RX0 +
4516                                 i*(MDIO_XS_8706_REG_BANK_RX1 -
4517                                    MDIO_XS_8706_REG_BANK_RX0);
4518                         bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
4519                         /* Clear first 3 bits of the control */
4520                         val &= ~0x7;
4521                         /* Set control bits according to configuration */
4522                         val |= (phy->rx_preemphasis[i] & 0x7);
4523                         DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
4524                                    " reg 0x%x <-- val 0x%x\n", reg, val);
4525                         bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
4526                 }
4527         }
4528         /* Force speed */
4529         if (phy->req_line_speed == SPEED_10000) {
4530                 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
4531
4532                 bnx2x_cl45_write(bp, phy,
4533                                  MDIO_PMA_DEVAD,
4534                                  MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
4535                 bnx2x_cl45_write(bp, phy,
4536                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
4537         } else {
4538                 /* Force 1Gbps using autoneg with 1G advertisment */
4539
4540                 /* Allow CL37 through CL73 */
4541                 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
4542                 bnx2x_cl45_write(bp, phy,
4543                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
4544
4545                 /* Enable Full-Duplex advertisment on CL37 */
4546                 bnx2x_cl45_write(bp, phy,
4547                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
4548                 /* Enable CL37 AN */
4549                 bnx2x_cl45_write(bp, phy,
4550                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
4551                 /* 1G support */
4552                 bnx2x_cl45_write(bp, phy,
4553                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
4554
4555                 /* Enable clause 73 AN */
4556                 bnx2x_cl45_write(bp, phy,
4557                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
4558                 bnx2x_cl45_write(bp, phy,
4559                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
4560                                  0x0400);
4561                 bnx2x_cl45_write(bp, phy,
4562                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
4563                                  0x0004);
4564         }
4565         bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
4566         return 0;
4567 }
4568
4569 static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy,
4570                                  struct link_params *params,
4571                                  struct link_vars *vars)
4572 {
4573         return bnx2x_8706_8726_read_status(phy, params, vars);
4574 }
4575
4576 /******************************************************************/
4577 /*                      BCM8726 PHY SECTION                       */
4578 /******************************************************************/
4579 static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
4580                                        struct link_params *params)
4581 {
4582         struct bnx2x *bp = params->bp;
4583         DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4584         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
4585 }
4586
4587 static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
4588                                          struct link_params *params)
4589 {
4590         struct bnx2x *bp = params->bp;
4591         /* Need to wait 100ms after reset */
4592         msleep(100);
4593
4594         /* Micro controller re-boot */
4595         bnx2x_cl45_write(bp, phy,
4596                          MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
4597
4598         /* Set soft reset */
4599         bnx2x_cl45_write(bp, phy,
4600                        MDIO_PMA_DEVAD,
4601                        MDIO_PMA_REG_GEN_CTRL,
4602                        MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
4603
4604         bnx2x_cl45_write(bp, phy,
4605                        MDIO_PMA_DEVAD,
4606                        MDIO_PMA_REG_MISC_CTRL1, 0x0001);
4607
4608         bnx2x_cl45_write(bp, phy,
4609                        MDIO_PMA_DEVAD,
4610                        MDIO_PMA_REG_GEN_CTRL,
4611                        MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
4612
4613         /* wait for 150ms for microcode load */
4614         msleep(150);
4615
4616         /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
4617         bnx2x_cl45_write(bp, phy,
4618                        MDIO_PMA_DEVAD,
4619                        MDIO_PMA_REG_MISC_CTRL1, 0x0000);
4620
4621         msleep(200);
4622         bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
4623 }
4624
4625 static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
4626                                  struct link_params *params,
4627                                  struct link_vars *vars)
4628 {
4629         struct bnx2x *bp = params->bp;
4630         u16 val1;
4631         u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
4632         if (link_up) {
4633                 bnx2x_cl45_read(bp, phy,
4634                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
4635                                 &val1);
4636                 if (val1 & (1<<15)) {
4637                         DP(NETIF_MSG_LINK, "Tx is disabled\n");
4638                         link_up = 0;
4639                         vars->line_speed = 0;
4640                 }
4641         }
4642         return link_up;
4643 }
4644
4645
4646 static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
4647                                  struct link_params *params,
4648                                  struct link_vars *vars)
4649 {
4650         struct bnx2x *bp = params->bp;
4651         u32 val;
4652         u32 swap_val, swap_override, aeu_gpio_mask, offset;
4653         DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
4654         /* Restore normal power mode*/
4655         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4656                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
4657
4658         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4659                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
4660
4661         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
4662         bnx2x_wait_reset_complete(bp, phy);
4663
4664         bnx2x_8726_external_rom_boot(phy, params);
4665
4666         /* Need to call module detected on initialization since
4667         the module detection triggered by actual module
4668         insertion might occur before driver is loaded, and when
4669         driver is loaded, it reset all registers, including the
4670         transmitter */
4671         bnx2x_sfp_module_detection(phy, params);
4672
4673         if (phy->req_line_speed == SPEED_1000) {
4674                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
4675                 bnx2x_cl45_write(bp, phy,
4676                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
4677                 bnx2x_cl45_write(bp, phy,
4678                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
4679                 bnx2x_cl45_write(bp, phy,
4680                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
4681                 bnx2x_cl45_write(bp, phy,
4682                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
4683                                  0x400);
4684         } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
4685                    (phy->speed_cap_mask &
4686                       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
4687                    ((phy->speed_cap_mask &
4688                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
4689                     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4690                 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
4691                 /* Set Flow control */
4692                 bnx2x_ext_phy_set_pause(params, phy, vars);
4693                 bnx2x_cl45_write(bp, phy,
4694                                  MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
4695                 bnx2x_cl45_write(bp, phy,
4696                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
4697                 bnx2x_cl45_write(bp, phy,
4698                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
4699                 bnx2x_cl45_write(bp, phy,
4700                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
4701                 bnx2x_cl45_write(bp, phy,
4702                                 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
4703                 /* Enable RX-ALARM control to receive
4704                 interrupt for 1G speed change */
4705                 bnx2x_cl45_write(bp, phy,
4706                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
4707                 bnx2x_cl45_write(bp, phy,
4708                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
4709                                  0x400);
4710
4711         } else { /* Default 10G. Set only LASI control */
4712                 bnx2x_cl45_write(bp, phy,
4713                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
4714         }
4715
4716         /* Set TX PreEmphasis if needed */
4717         if ((params->feature_config_flags &
4718              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
4719                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
4720                          "TX_CTRL2 0x%x\n",
4721                          phy->tx_preemphasis[0],
4722                          phy->tx_preemphasis[1]);
4723                 bnx2x_cl45_write(bp, phy,
4724                                  MDIO_PMA_DEVAD,
4725                                  MDIO_PMA_REG_8726_TX_CTRL1,
4726                                  phy->tx_preemphasis[0]);
4727
4728                 bnx2x_cl45_write(bp, phy,
4729                                  MDIO_PMA_DEVAD,
4730                                  MDIO_PMA_REG_8726_TX_CTRL2,
4731                                  phy->tx_preemphasis[1]);
4732         }
4733
4734         /* Set GPIO3 to trigger SFP+ module insertion/removal */
4735         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
4736                             MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port);
4737
4738         /* The GPIO should be swapped if the swap register is set and active */
4739         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
4740         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
4741
4742         /* Select function upon port-swap configuration */
4743         if (params->port == 0) {
4744                 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
4745                 aeu_gpio_mask = (swap_val && swap_override) ?
4746                         AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
4747                         AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
4748         } else {
4749                 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
4750                 aeu_gpio_mask = (swap_val && swap_override) ?
4751                         AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
4752                         AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
4753         }
4754         val = REG_RD(bp, offset);
4755         /* add GPIO3 to group */
4756         val |= aeu_gpio_mask;
4757         REG_WR(bp, offset, val);
4758         return 0;
4759
4760 }
4761
4762 static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
4763                                   struct link_params *params)
4764 {
4765         struct bnx2x *bp = params->bp;
4766         DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
4767         /* Set serial boot control for external load */
4768         bnx2x_cl45_write(bp, phy,
4769                          MDIO_PMA_DEVAD,
4770                          MDIO_PMA_REG_GEN_CTRL, 0x0001);
4771 }
4772
4773 /******************************************************************/
4774 /*                      BCM8727 PHY SECTION                       */
4775 /******************************************************************/
4776
4777 static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
4778                                     struct link_params *params, u8 mode)
4779 {
4780         struct bnx2x *bp = params->bp;
4781         u16 led_mode_bitmask = 0;
4782         u16 gpio_pins_bitmask = 0;
4783         u16 val;
4784         /* Only NOC flavor requires to set the LED specifically */
4785         if (!(phy->flags & FLAGS_NOC))
4786                 return;
4787         switch (mode) {
4788         case LED_MODE_FRONT_PANEL_OFF:
4789         case LED_MODE_OFF:
4790                 led_mode_bitmask = 0;
4791                 gpio_pins_bitmask = 0x03;
4792                 break;
4793         case LED_MODE_ON:
4794                 led_mode_bitmask = 0;
4795                 gpio_pins_bitmask = 0x02;
4796                 break;
4797         case LED_MODE_OPER:
4798                 led_mode_bitmask = 0x60;
4799                 gpio_pins_bitmask = 0x11;
4800                 break;
4801         }
4802         bnx2x_cl45_read(bp, phy,
4803                         MDIO_PMA_DEVAD,
4804                         MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4805                         &val);
4806         val &= 0xff8f;
4807         val |= led_mode_bitmask;
4808         bnx2x_cl45_write(bp, phy,
4809                          MDIO_PMA_DEVAD,
4810                          MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4811                          val);
4812         bnx2x_cl45_read(bp, phy,
4813                         MDIO_PMA_DEVAD,
4814                         MDIO_PMA_REG_8727_GPIO_CTRL,
4815                         &val);
4816         val &= 0xffe0;
4817         val |= gpio_pins_bitmask;
4818         bnx2x_cl45_write(bp, phy,
4819                          MDIO_PMA_DEVAD,
4820                          MDIO_PMA_REG_8727_GPIO_CTRL,
4821                          val);
4822 }
4823 static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
4824                                 struct link_params *params) {
4825         u32 swap_val, swap_override;
4826         u8 port;
4827         /**
4828          * The PHY reset is controlled by GPIO 1. Fake the port number
4829          * to cancel the swap done in set_gpio()
4830          */
4831         struct bnx2x *bp = params->bp;
4832         swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
4833         swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
4834         port = (swap_val && swap_override) ^ 1;
4835         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4836                             MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
4837 }
4838
4839 static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
4840                                  struct link_params *params,
4841                                  struct link_vars *vars)
4842 {
4843         u16 tmp1, val, mod_abs;
4844         u16 rx_alarm_ctrl_val;
4845         u16 lasi_ctrl_val;
4846         struct bnx2x *bp = params->bp;
4847         /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
4848
4849         bnx2x_wait_reset_complete(bp, phy);
4850         rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
4851         lasi_ctrl_val = 0x0004;
4852
4853         DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
4854         /* enable LASI */
4855         bnx2x_cl45_write(bp, phy,
4856                          MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
4857                          rx_alarm_ctrl_val);
4858
4859         bnx2x_cl45_write(bp, phy,
4860                          MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
4861
4862         /* Initially configure  MOD_ABS to interrupt when
4863         module is presence( bit 8) */
4864         bnx2x_cl45_read(bp, phy,
4865                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4866         /* Set EDC off by setting OPTXLOS signal input to low
4867         (bit 9).
4868         When the EDC is off it locks onto a reference clock and
4869         avoids becoming 'lost'.*/
4870         mod_abs &= ~(1<<8);
4871         if (!(phy->flags & FLAGS_NOC))
4872                 mod_abs &= ~(1<<9);
4873         bnx2x_cl45_write(bp, phy,
4874                          MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4875
4876
4877         /* Make MOD_ABS give interrupt on change */
4878         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4879                         &val);
4880         val |= (1<<12);
4881         if (phy->flags & FLAGS_NOC)
4882                 val |= (3<<5);
4883
4884         /**
4885          * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
4886          * status which reflect SFP+ module over-current
4887          */
4888         if (!(phy->flags & FLAGS_NOC))
4889                 val &= 0xff8f; /* Reset bits 4-6 */
4890         bnx2x_cl45_write(bp, phy,
4891                          MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
4892
4893         bnx2x_8727_power_module(bp, phy, 1);
4894
4895         bnx2x_cl45_read(bp, phy,
4896                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
4897
4898         bnx2x_cl45_read(bp, phy,
4899                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
4900
4901         /* Set option 1G speed */
4902         if (phy->req_line_speed == SPEED_1000) {
4903                 DP(NETIF_MSG_LINK, "Setting 1G force\n");
4904                 bnx2x_cl45_write(bp, phy,
4905                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
4906                 bnx2x_cl45_write(bp, phy,
4907                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
4908                 bnx2x_cl45_read(bp, phy,
4909                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
4910                 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
4911                 /**
4912                  * Power down the XAUI until link is up in case of dual-media
4913                  * and 1G
4914                  */
4915                 if (DUAL_MEDIA(params)) {
4916                         bnx2x_cl45_read(bp, phy,
4917                                         MDIO_PMA_DEVAD,
4918                                         MDIO_PMA_REG_8727_PCS_GP, &val);
4919                         val |= (3<<10);
4920                         bnx2x_cl45_write(bp, phy,
4921                                          MDIO_PMA_DEVAD,
4922                                          MDIO_PMA_REG_8727_PCS_GP, val);
4923                 }
4924         } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
4925                    ((phy->speed_cap_mask &
4926                      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
4927                    ((phy->speed_cap_mask &
4928                       PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
4929                    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4930
4931                 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
4932                 bnx2x_cl45_write(bp, phy,
4933                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
4934                 bnx2x_cl45_write(bp, phy,
4935                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
4936         } else {
4937                 /**
4938                  * Since the 8727 has only single reset pin, need to set the 10G
4939                  * registers although it is default
4940                  */
4941                 bnx2x_cl45_write(bp, phy,
4942                                  MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
4943                                  0x0020);
4944                 bnx2x_cl45_write(bp, phy,
4945                                  MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
4946                 bnx2x_cl45_write(bp, phy,
4947                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
4948                 bnx2x_cl45_write(bp, phy,
4949                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
4950                                  0x0008);
4951         }
4952
4953         /* Set 2-wire transfer rate of SFP+ module EEPROM
4954          * to 100Khz since some DACs(direct attached cables) do
4955          * not work at 400Khz.
4956          */
4957         bnx2x_cl45_write(bp, phy,
4958                          MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
4959                          0xa001);
4960
4961         /* Set TX PreEmphasis if needed */
4962         if ((params->feature_config_flags &
4963              FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
4964                 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
4965                            phy->tx_preemphasis[0],
4966                            phy->tx_preemphasis[1]);
4967                 bnx2x_cl45_write(bp, phy,
4968                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
4969                                  phy->tx_preemphasis[0]);
4970
4971                 bnx2x_cl45_write(bp, phy,
4972                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
4973                                  phy->tx_preemphasis[1]);
4974         }
4975
4976         return 0;
4977 }
4978
4979 static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
4980                                       struct link_params *params)
4981 {
4982         struct bnx2x *bp = params->bp;
4983         u16 mod_abs, rx_alarm_status;
4984         u32 val = REG_RD(bp, params->shmem_base +
4985                              offsetof(struct shmem_region, dev_info.
4986                                       port_feature_config[params->port].
4987                                       config));
4988         bnx2x_cl45_read(bp, phy,
4989                       MDIO_PMA_DEVAD,
4990                       MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4991         if (mod_abs & (1<<8)) {
4992
4993                 /* Module is absent */
4994                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4995                             "show module is absent\n");
4996
4997                 /* 1. Set mod_abs to detect next module
4998                 presence event
4999                    2. Set EDC off by setting OPTXLOS signal input to low
5000                         (bit 9).
5001                         When the EDC is off it locks onto a reference clock and
5002                         avoids becoming 'lost'.*/
5003                 mod_abs &= ~(1<<8);
5004                 if (!(phy->flags & FLAGS_NOC))
5005                         mod_abs &= ~(1<<9);
5006                 bnx2x_cl45_write(bp, phy,
5007                                MDIO_PMA_DEVAD,
5008                                MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5009
5010                 /* Clear RX alarm since it stays up as long as
5011                 the mod_abs wasn't changed */
5012                 bnx2x_cl45_read(bp, phy,
5013                               MDIO_PMA_DEVAD,
5014                               MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5015
5016         } else {
5017                 /* Module is present */
5018                 DP(NETIF_MSG_LINK, "MOD_ABS indication "
5019                             "show module is present\n");
5020                 /* First thing, disable transmitter,
5021                 and if the module is ok, the
5022                 module_detection will enable it*/
5023
5024                 /* 1. Set mod_abs to detect next module
5025                 absent event ( bit 8)
5026                    2. Restore the default polarity of the OPRXLOS signal and
5027                 this signal will then correctly indicate the presence or
5028                 absence of the Rx signal. (bit 9) */
5029                 mod_abs |= (1<<8);
5030                 if (!(phy->flags & FLAGS_NOC))
5031                         mod_abs |= (1<<9);
5032                 bnx2x_cl45_write(bp, phy,
5033                                  MDIO_PMA_DEVAD,
5034                                  MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
5035
5036                 /* Clear RX alarm since it stays up as long as
5037                 the mod_abs wasn't changed. This is need to be done
5038                 before calling the module detection, otherwise it will clear
5039                 the link update alarm */
5040                 bnx2x_cl45_read(bp, phy,
5041                                 MDIO_PMA_DEVAD,
5042                                 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5043
5044
5045                 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
5046                     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
5047                         bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5048
5049                 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
5050                         bnx2x_sfp_module_detection(phy, params);
5051                 else
5052                         DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
5053         }
5054
5055         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
5056                  rx_alarm_status);
5057         /* No need to check link status in case of
5058         module plugged in/out */
5059 }
5060
5061 static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
5062                                  struct link_params *params,
5063                                  struct link_vars *vars)
5064
5065 {
5066         struct bnx2x *bp = params->bp;
5067         u8 link_up = 0;
5068         u16 link_status = 0;
5069         u16 rx_alarm_status, lasi_ctrl, val1;
5070
5071         /* If PHY is not initialized, do not check link status */
5072         bnx2x_cl45_read(bp, phy,
5073                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
5074                         &lasi_ctrl);
5075         if (!lasi_ctrl)
5076                 return 0;
5077
5078         /* Check the LASI */
5079         bnx2x_cl45_read(bp, phy,
5080                         MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
5081                         &rx_alarm_status);
5082         vars->line_speed = 0;
5083         DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
5084
5085         bnx2x_cl45_read(bp, phy,
5086                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
5087
5088         DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
5089
5090         /* Clear MSG-OUT */
5091         bnx2x_cl45_read(bp, phy,
5092                         MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
5093
5094         /**
5095          * If a module is present and there is need to check
5096          * for over current
5097          */
5098         if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
5099                 /* Check over-current using 8727 GPIO0 input*/
5100                 bnx2x_cl45_read(bp, phy,
5101                                 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
5102                                 &val1);
5103
5104                 if ((val1 & (1<<8)) == 0) {
5105                         DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
5106                                        " on port %d\n", params->port);
5107                         netdev_err(bp->dev, "Error:  Power fault on Port %d has"
5108                                             " been detected and the power to "
5109                                             "that SFP+ module has been removed"
5110                                             " to prevent failure of the card."
5111                                             " Please remove the SFP+ module and"
5112                                             " restart the system to clear this"
5113                                             " error.\n",
5114                                    params->port);
5115
5116                         /*
5117                          * Disable all RX_ALARMs except for
5118                          * mod_abs
5119                          */
5120                         bnx2x_cl45_write(bp, phy,
5121                                          MDIO_PMA_DEVAD,
5122                                          MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
5123
5124                         bnx2x_cl45_read(bp, phy,
5125                                         MDIO_PMA_DEVAD,
5126                                         MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
5127                         /* Wait for module_absent_event */
5128                         val1 |= (1<<8);
5129                         bnx2x_cl45_write(bp, phy,
5130                                          MDIO_PMA_DEVAD,
5131                                          MDIO_PMA_REG_PHY_IDENTIFIER, val1);
5132                         /* Clear RX alarm */
5133                         bnx2x_cl45_read(bp, phy,
5134                                 MDIO_PMA_DEVAD,
5135                                 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5136                         return 0;
5137                 }
5138         } /* Over current check */
5139
5140         /* When module absent bit is set, check module */
5141         if (rx_alarm_status & (1<<5)) {
5142                 bnx2x_8727_handle_mod_abs(phy, params);
5143                 /* Enable all mod_abs and link detection bits */
5144                 bnx2x_cl45_write(bp, phy,
5145                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5146                                  ((1<<5) | (1<<2)));
5147         }
5148         DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
5149         bnx2x_8727_specific_func(phy, params, ENABLE_TX);
5150         /* If transmitter is disabled, ignore false link up indication */
5151         bnx2x_cl45_read(bp, phy,
5152                         MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
5153         if (val1 & (1<<15)) {
5154                 DP(NETIF_MSG_LINK, "Tx is disabled\n");
5155                 return 0;
5156         }
5157
5158         bnx2x_cl45_read(bp, phy,
5159                         MDIO_PMA_DEVAD,
5160                         MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
5161
5162         /* Bits 0..2 --> speed detected,
5163            bits 13..15--> link is down */
5164         if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
5165                 link_up = 1;
5166                 vars->line_speed = SPEED_10000;
5167         } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
5168                 link_up = 1;
5169                 vars->line_speed = SPEED_1000;
5170                 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
5171                            params->port);
5172         } else {
5173                 link_up = 0;
5174                 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
5175                            params->port);
5176         }
5177         if (link_up)
5178                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5179
5180         if ((DUAL_MEDIA(params)) &&
5181             (phy->req_line_speed == SPEED_1000)) {
5182                 bnx2x_cl45_read(bp, phy,
5183                                 MDIO_PMA_DEVAD,
5184                                 MDIO_PMA_REG_8727_PCS_GP, &val1);
5185                 /**
5186                  * In case of dual-media board and 1G, power up the XAUI side,
5187                  * otherwise power it down. For 10G it is done automatically
5188                  */
5189                 if (link_up)
5190                         val1 &= ~(3<<10);
5191                 else
5192                         val1 |= (3<<10);
5193                 bnx2x_cl45_write(bp, phy,
5194                                  MDIO_PMA_DEVAD,
5195                                  MDIO_PMA_REG_8727_PCS_GP, val1);
5196         }
5197         return link_up;
5198 }
5199
5200 static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
5201                                   struct link_params *params)
5202 {
5203         struct bnx2x *bp = params->bp;
5204         /* Disable Transmitter */
5205         bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5206         /* Clear LASI */
5207         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
5208
5209 }
5210
5211 /******************************************************************/
5212 /*              BCM8481/BCM84823/BCM84833 PHY SECTION             */
5213 /******************************************************************/
5214 static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
5215                                            struct link_params *params)
5216 {
5217         u16 val, fw_ver1, fw_ver2, cnt;
5218         struct bnx2x *bp = params->bp;
5219
5220         /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
5221         /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
5222         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
5223         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
5224         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
5225         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
5226         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
5227
5228         for (cnt = 0; cnt < 100; cnt++) {
5229                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
5230                 if (val & 1)
5231                         break;
5232                 udelay(5);
5233         }
5234         if (cnt == 100) {
5235                 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
5236                 bnx2x_save_spirom_version(bp, params->port, 0,
5237                                           phy->ver_addr);
5238                 return;
5239         }
5240
5241
5242         /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
5243         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
5244         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
5245         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
5246         for (cnt = 0; cnt < 100; cnt++) {
5247                 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
5248                 if (val & 1)
5249                         break;
5250                 udelay(5);
5251         }
5252         if (cnt == 100) {
5253                 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
5254                 bnx2x_save_spirom_version(bp, params->port, 0,
5255                                           phy->ver_addr);
5256                 return;
5257         }
5258
5259         /* lower 16 bits of the register SPI_FW_STATUS */
5260         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
5261         /* upper 16 bits of register SPI_FW_STATUS */
5262         bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
5263
5264         bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1,
5265                                   phy->ver_addr);
5266 }
5267
5268 static void bnx2x_848xx_set_led(struct bnx2x *bp,
5269                                 struct bnx2x_phy *phy)
5270 {
5271         u16 val;
5272
5273         /* PHYC_CTL_LED_CTL */
5274         bnx2x_cl45_read(bp, phy,
5275                         MDIO_PMA_DEVAD,
5276                         MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
5277         val &= 0xFE00;
5278         val |= 0x0092;
5279
5280         bnx2x_cl45_write(bp, phy,
5281                          MDIO_PMA_DEVAD,
5282                          MDIO_PMA_REG_8481_LINK_SIGNAL, val);
5283
5284         bnx2x_cl45_write(bp, phy,
5285                          MDIO_PMA_DEVAD,
5286                          MDIO_PMA_REG_8481_LED1_MASK,
5287                          0x80);
5288
5289         bnx2x_cl45_write(bp, phy,
5290                          MDIO_PMA_DEVAD,
5291                          MDIO_PMA_REG_8481_LED2_MASK,
5292                          0x18);
5293
5294         bnx2x_cl45_write(bp, phy,
5295                          MDIO_PMA_DEVAD,
5296                          MDIO_PMA_REG_8481_LED3_MASK,
5297                          0x0040);
5298
5299         /* 'Interrupt Mask' */
5300         bnx2x_cl45_write(bp, phy,
5301                          MDIO_AN_DEVAD,
5302                          0xFFFB, 0xFFFD);
5303 }
5304
5305 static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
5306                                       struct link_params *params,
5307                                       struct link_vars *vars)
5308 {
5309         struct bnx2x *bp = params->bp;
5310         u16 autoneg_val, an_1000_val, an_10_100_val;
5311
5312         bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
5313                       1 << NIG_LATCH_BC_ENABLE_MI_INT);
5314
5315         bnx2x_cl45_write(bp, phy,
5316                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
5317
5318         bnx2x_848xx_set_led(bp, phy);
5319
5320         /* set 1000 speed advertisement */
5321         bnx2x_cl45_read(bp, phy,
5322                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
5323                         &an_1000_val);
5324
5325         bnx2x_ext_phy_set_pause(params, phy, vars);
5326         bnx2x_cl45_read(bp, phy,
5327                         MDIO_AN_DEVAD,
5328                         MDIO_AN_REG_8481_LEGACY_AN_ADV,
5329                         &an_10_100_val);
5330         bnx2x_cl45_read(bp, phy,
5331                         MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
5332                         &autoneg_val);
5333         /* Disable forced speed */
5334         autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
5335         an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
5336
5337         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5338              (phy->speed_cap_mask &
5339              PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
5340             (phy->req_line_speed == SPEED_1000)) {
5341                 an_1000_val |= (1<<8);
5342                 autoneg_val |= (1<<9 | 1<<12);
5343                 if (phy->req_duplex == DUPLEX_FULL)
5344                         an_1000_val |= (1<<9);
5345                 DP(NETIF_MSG_LINK, "Advertising 1G\n");
5346         } else
5347                 an_1000_val &= ~((1<<8) | (1<<9));
5348
5349         bnx2x_cl45_write(bp, phy,
5350                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
5351                          an_1000_val);
5352
5353         /* set 10 speed advertisement */
5354         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5355              (phy->speed_cap_mask &
5356              (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
5357               PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
5358                 an_10_100_val |= (1<<7);
5359                 /* Enable autoneg and restart autoneg for legacy speeds */
5360                 autoneg_val |= (1<<9 | 1<<12);
5361
5362                 if (phy->req_duplex == DUPLEX_FULL)
5363                         an_10_100_val |= (1<<8);
5364                 DP(NETIF_MSG_LINK, "Advertising 100M\n");
5365         }
5366         /* set 10 speed advertisement */
5367         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5368             (phy->speed_cap_mask &
5369           (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
5370            PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
5371                 an_10_100_val |= (1<<5);
5372                 autoneg_val |= (1<<9 | 1<<12);
5373                 if (phy->req_duplex == DUPLEX_FULL)
5374                         an_10_100_val |= (1<<6);
5375                 DP(NETIF_MSG_LINK, "Advertising 10M\n");
5376         }
5377
5378         /* Only 10/100 are allowed to work in FORCE mode */
5379         if (phy->req_line_speed == SPEED_100) {
5380                 autoneg_val |= (1<<13);
5381                 /* Enabled AUTO-MDIX when autoneg is disabled */
5382                 bnx2x_cl45_write(bp, phy,
5383                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
5384                                  (1<<15 | 1<<9 | 7<<0));
5385                 DP(NETIF_MSG_LINK, "Setting 100M force\n");
5386         }
5387         if (phy->req_line_speed == SPEED_10) {
5388                 /* Enabled AUTO-MDIX when autoneg is disabled */
5389                 bnx2x_cl45_write(bp, phy,
5390                                  MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
5391                                  (1<<15 | 1<<9 | 7<<0));
5392                 DP(NETIF_MSG_LINK, "Setting 10M force\n");
5393         }
5394
5395         bnx2x_cl45_write(bp, phy,
5396                          MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
5397                          an_10_100_val);
5398
5399         if (phy->req_duplex == DUPLEX_FULL)
5400                 autoneg_val |= (1<<8);
5401
5402         bnx2x_cl45_write(bp, phy,
5403                          MDIO_AN_DEVAD,
5404                          MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
5405
5406         if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
5407             (phy->speed_cap_mask &
5408              PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
5409                 (phy->req_line_speed == SPEED_10000)) {
5410                 DP(NETIF_MSG_LINK, "Advertising 10G\n");
5411                 /* Restart autoneg for 10G*/
5412
5413                 bnx2x_cl45_write(bp, phy,
5414                                  MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
5415                                  0x3200);
5416         } else if (phy->req_line_speed != SPEED_10 &&
5417                    phy->req_line_speed != SPEED_100) {
5418                 bnx2x_cl45_write(bp, phy,
5419                                  MDIO_AN_DEVAD,
5420                                  MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
5421                                  1);
5422         }
5423         /* Save spirom version */
5424         bnx2x_save_848xx_spirom_version(phy, params);
5425
5426         return 0;
5427 }
5428
5429 static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
5430                                  struct link_params *params,
5431                                  struct link_vars *vars)
5432 {
5433         struct bnx2x *bp = params->bp;
5434         /* Restore normal power mode*/
5435         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5436                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5437
5438         /* HW reset */
5439         bnx2x_ext_phy_hw_reset(bp, params->port);
5440         bnx2x_wait_reset_complete(bp, phy);
5441
5442         bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
5443         return bnx2x_848xx_cmn_config_init(phy, params, vars);
5444 }
5445
5446 static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
5447                                   struct link_params *params,
5448                                   struct link_vars *vars)
5449 {
5450         struct bnx2x *bp = params->bp;
5451         u8 port, initialize = 1;
5452         u16 val;
5453         u16 temp;
5454         u32 actual_phy_selection;
5455         u8 rc = 0;
5456
5457         /* This is just for MDIO_CTL_REG_84823_MEDIA register. */
5458
5459         msleep(1);
5460         if (CHIP_IS_E2(bp))
5461                 port = BP_PATH(bp);
5462         else
5463                 port = params->port;
5464         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
5465                        MISC_REGISTERS_GPIO_OUTPUT_HIGH,
5466                        port);
5467         bnx2x_wait_reset_complete(bp, phy);
5468         /* Wait for GPHY to come out of reset */
5469         msleep(50);
5470         /* BCM84823 requires that XGXS links up first @ 10G for normal
5471         behavior */
5472         temp = vars->line_speed;
5473         vars->line_speed = SPEED_10000;
5474         bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
5475         bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
5476         vars->line_speed = temp;
5477
5478         /* Set dual-media configuration according to configuration */
5479
5480         bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
5481                         MDIO_CTL_REG_84823_MEDIA, &val);
5482         val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
5483                  MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
5484                  MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
5485                  MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
5486                  MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
5487         val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
5488                 MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
5489
5490         actual_phy_selection = bnx2x_phy_selection(params);
5491
5492         switch (actual_phy_selection) {
5493         case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
5494                 /* Do nothing. Essentialy this is like the priority copper */
5495                 break;
5496         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
5497                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
5498                 break;
5499         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
5500                 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
5501                 break;
5502         case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
5503                 /* Do nothing here. The first PHY won't be initialized at all */
5504                 break;
5505         case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
5506                 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
5507                 initialize = 0;
5508                 break;
5509         }
5510         if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
5511                 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
5512
5513         bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
5514                          MDIO_CTL_REG_84823_MEDIA, val);
5515         DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
5516                    params->multi_phy_config, val);
5517
5518         if (initialize)
5519                 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
5520         else
5521                 bnx2x_save_848xx_spirom_version(phy, params);
5522         return rc;
5523 }
5524
5525 static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
5526                                        struct link_params *params,
5527                                        struct link_vars *vars)
5528 {
5529         struct bnx2x *bp = params->bp;
5530         u16 val, val1, val2;
5531         u8 link_up = 0;
5532
5533         /* Check 10G-BaseT link status */
5534         /* Check PMD signal ok */
5535         bnx2x_cl45_read(bp, phy,
5536                         MDIO_AN_DEVAD, 0xFFFA, &val1);
5537         bnx2x_cl45_read(bp, phy,
5538                         MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
5539                         &val2);
5540         DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
5541
5542         /* Check link 10G */
5543         if (val2 & (1<<11)) {
5544                 vars->line_speed = SPEED_10000;
5545                 link_up = 1;
5546                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
5547         } else { /* Check Legacy speed link */
5548                 u16 legacy_status, legacy_speed;
5549
5550                 /* Enable expansion register 0x42 (Operation mode status) */
5551                 bnx2x_cl45_write(bp, phy,
5552                                  MDIO_AN_DEVAD,
5553                                  MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
5554
5555                 /* Get legacy speed operation status */
5556                 bnx2x_cl45_read(bp, phy,
5557                                 MDIO_AN_DEVAD,
5558                                 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
5559                                 &legacy_status);
5560
5561                 DP(NETIF_MSG_LINK, "Legacy speed status"
5562                              " = 0x%x\n", legacy_status);
5563                 link_up = ((legacy_status & (1<<11)) == (1<<11));
5564                 if (link_up) {
5565                         legacy_speed = (legacy_status & (3<<9));
5566                         if (legacy_speed == (0<<9))
5567                                 vars->line_speed = SPEED_10;
5568                         else if (legacy_speed == (1<<9))
5569                                 vars->line_speed = SPEED_100;
5570                         else if (legacy_speed == (2<<9))
5571                                 vars->line_speed = SPEED_1000;
5572                         else /* Should not happen */
5573                                 vars->line_speed = 0;
5574
5575                         if (legacy_status & (1<<8))
5576                                 vars->duplex = DUPLEX_FULL;
5577                         else
5578                                 vars->duplex = DUPLEX_HALF;
5579
5580                         DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
5581                                    " is_duplex_full= %d\n", vars->line_speed,
5582                                    (vars->duplex == DUPLEX_FULL));
5583                         /* Check legacy speed AN resolution */
5584                         bnx2x_cl45_read(bp, phy,
5585                                         MDIO_AN_DEVAD,
5586                                         MDIO_AN_REG_8481_LEGACY_MII_STATUS,
5587                                         &val);
5588                         if (val & (1<<5))
5589                                 vars->link_status |=
5590                                         LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5591                         bnx2x_cl45_read(bp, phy,
5592                                         MDIO_AN_DEVAD,
5593                                         MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
5594                                         &val);
5595                         if ((val & (1<<0)) == 0)
5596                                 vars->link_status |=
5597                                         LINK_STATUS_PARALLEL_DETECTION_USED;
5598                 }
5599         }
5600         if (link_up) {
5601                 DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
5602                            vars->line_speed);
5603                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5604         }
5605
5606         return link_up;
5607 }
5608
5609 static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
5610 {
5611         u8 status = 0;
5612         u32 spirom_ver;
5613         spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
5614         status = bnx2x_format_ver(spirom_ver, str, len);
5615         return status;
5616 }
5617
5618 static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
5619                                 struct link_params *params)
5620 {
5621         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5622                             MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
5623         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5624                             MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
5625 }
5626
5627 static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
5628                                         struct link_params *params)
5629 {
5630         bnx2x_cl45_write(params->bp, phy,
5631                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
5632         bnx2x_cl45_write(params->bp, phy,
5633                          MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
5634 }
5635
5636 static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
5637                                    struct link_params *params)
5638 {
5639         struct bnx2x *bp = params->bp;
5640         u8 port;
5641         if (CHIP_IS_E2(bp))
5642                 port = BP_PATH(bp);
5643         else
5644                 port = params->port;
5645         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
5646                             MISC_REGISTERS_GPIO_OUTPUT_LOW,
5647                             port);
5648 }
5649
5650 static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
5651                                      struct link_params *params, u8 mode)
5652 {
5653         struct bnx2x *bp = params->bp;
5654         u16 val;
5655
5656         switch (mode) {
5657         case LED_MODE_OFF:
5658
5659                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port);
5660
5661                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
5662                     SHARED_HW_CFG_LED_EXTPHY1) {
5663
5664                         /* Set LED masks */
5665                         bnx2x_cl45_write(bp, phy,
5666                                         MDIO_PMA_DEVAD,
5667                                         MDIO_PMA_REG_8481_LED1_MASK,
5668                                         0x0);
5669
5670                         bnx2x_cl45_write(bp, phy,
5671                                         MDIO_PMA_DEVAD,
5672                                         MDIO_PMA_REG_8481_LED2_MASK,
5673                                         0x0);
5674
5675                         bnx2x_cl45_write(bp, phy,
5676                                         MDIO_PMA_DEVAD,
5677                                         MDIO_PMA_REG_8481_LED3_MASK,
5678                                         0x0);
5679
5680                         bnx2x_cl45_write(bp, phy,
5681                                         MDIO_PMA_DEVAD,
5682                                         MDIO_PMA_REG_8481_LED5_MASK,
5683                                         0x0);
5684
5685                 } else {
5686                         bnx2x_cl45_write(bp, phy,
5687                                          MDIO_PMA_DEVAD,
5688                                          MDIO_PMA_REG_8481_LED1_MASK,
5689                                          0x0);
5690                 }
5691                 break;
5692         case LED_MODE_FRONT_PANEL_OFF:
5693
5694                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
5695                    params->port);
5696
5697                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
5698                     SHARED_HW_CFG_LED_EXTPHY1) {
5699
5700                         /* Set LED masks */
5701                         bnx2x_cl45_write(bp, phy,
5702                                         MDIO_PMA_DEVAD,
5703                                         MDIO_PMA_REG_8481_LED1_MASK,
5704                                         0x0);
5705
5706                         bnx2x_cl45_write(bp, phy,
5707                                         MDIO_PMA_DEVAD,
5708                                         MDIO_PMA_REG_8481_LED2_MASK,
5709                                         0x0);
5710
5711                         bnx2x_cl45_write(bp, phy,
5712                                         MDIO_PMA_DEVAD,
5713                                         MDIO_PMA_REG_8481_LED3_MASK,
5714                                         0x0);
5715
5716                         bnx2x_cl45_write(bp, phy,
5717                                         MDIO_PMA_DEVAD,
5718                                         MDIO_PMA_REG_8481_LED5_MASK,
5719                                         0x20);
5720
5721                 } else {
5722                         bnx2x_cl45_write(bp, phy,
5723                                          MDIO_PMA_DEVAD,
5724                                          MDIO_PMA_REG_8481_LED1_MASK,
5725                                          0x0);
5726                 }
5727                 break;
5728         case LED_MODE_ON:
5729
5730                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port);
5731
5732                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
5733                     SHARED_HW_CFG_LED_EXTPHY1) {
5734                         /* Set control reg */
5735                         bnx2x_cl45_read(bp, phy,
5736                                         MDIO_PMA_DEVAD,
5737                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
5738                                         &val);
5739                         val &= 0x8000;
5740                         val |= 0x2492;
5741
5742                         bnx2x_cl45_write(bp, phy,
5743                                         MDIO_PMA_DEVAD,
5744                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
5745                                         val);
5746
5747                         /* Set LED masks */
5748                         bnx2x_cl45_write(bp, phy,
5749                                         MDIO_PMA_DEVAD,
5750                                         MDIO_PMA_REG_8481_LED1_MASK,
5751                                         0x0);
5752
5753                         bnx2x_cl45_write(bp, phy,
5754                                         MDIO_PMA_DEVAD,
5755                                         MDIO_PMA_REG_8481_LED2_MASK,
5756                                         0x20);
5757
5758                         bnx2x_cl45_write(bp, phy,
5759                                         MDIO_PMA_DEVAD,
5760                                         MDIO_PMA_REG_8481_LED3_MASK,
5761                                         0x20);
5762
5763                         bnx2x_cl45_write(bp, phy,
5764                                         MDIO_PMA_DEVAD,
5765                                         MDIO_PMA_REG_8481_LED5_MASK,
5766                                         0x0);
5767                 } else {
5768                         bnx2x_cl45_write(bp, phy,
5769                                         MDIO_PMA_DEVAD,
5770                                         MDIO_PMA_REG_8481_LED1_MASK,
5771                                         0x20);
5772                 }
5773                 break;
5774
5775         case LED_MODE_OPER:
5776
5777                 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port);
5778
5779                 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
5780                     SHARED_HW_CFG_LED_EXTPHY1) {
5781
5782                         /* Set control reg */
5783                         bnx2x_cl45_read(bp, phy,
5784                                         MDIO_PMA_DEVAD,
5785                                         MDIO_PMA_REG_8481_LINK_SIGNAL,
5786                                         &val);
5787
5788                         if (!((val &
5789                               MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
5790                            >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)){
5791                                 DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n");
5792                                 bnx2x_cl45_write(bp, phy,
5793                                                  MDIO_PMA_DEVAD,
5794                                                  MDIO_PMA_REG_8481_LINK_SIGNAL,
5795                                                  0xa492);
5796                         }
5797
5798                         /* Set LED masks */
5799                         bnx2x_cl45_write(bp, phy,
5800                                         MDIO_PMA_DEVAD,
5801                                         MDIO_PMA_REG_8481_LED1_MASK,
5802                                         0x10);
5803
5804                         bnx2x_cl45_write(bp, phy,
5805                                         MDIO_PMA_DEVAD,
5806                                         MDIO_PMA_REG_8481_LED2_MASK,
5807                                         0x80);
5808
5809                         bnx2x_cl45_write(bp, phy,
5810                                         MDIO_PMA_DEVAD,
5811                                         MDIO_PMA_REG_8481_LED3_MASK,
5812                                         0x98);
5813
5814                         bnx2x_cl45_write(bp, phy,
5815                                         MDIO_PMA_DEVAD,
5816                                         MDIO_PMA_REG_8481_LED5_MASK,
5817                                         0x40);
5818
5819                 } else {
5820                         bnx2x_cl45_write(bp, phy,
5821                                          MDIO_PMA_DEVAD,
5822                                          MDIO_PMA_REG_8481_LED1_MASK,
5823                                          0x80);
5824                 }
5825                 break;
5826         }
5827 }
5828 /******************************************************************/
5829 /*                      SFX7101 PHY SECTION                       */
5830 /******************************************************************/
5831 static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
5832                                        struct link_params *params)
5833 {
5834         struct bnx2x *bp = params->bp;
5835         /* SFX7101_XGXS_TEST1 */
5836         bnx2x_cl45_write(bp, phy,
5837                          MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
5838 }
5839
5840 static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
5841                                  struct link_params *params,
5842                                  struct link_vars *vars)
5843 {
5844         u16 fw_ver1, fw_ver2, val;
5845         struct bnx2x *bp = params->bp;
5846         DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
5847
5848         /* Restore normal power mode*/
5849         bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5850                             MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5851         /* HW reset */
5852         bnx2x_ext_phy_hw_reset(bp, params->port);
5853         bnx2x_wait_reset_complete(bp, phy);
5854
5855         bnx2x_cl45_write(bp, phy,
5856                          MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
5857         DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
5858         bnx2x_cl45_write(bp, phy,
5859                          MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
5860
5861         bnx2x_ext_phy_set_pause(params, phy, vars);
5862         /* Restart autoneg */
5863         bnx2x_cl45_read(bp, phy,
5864                         MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
5865         val |= 0x200;
5866         bnx2x_cl45_write(bp, phy,
5867                          MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
5868
5869         /* Save spirom version */
5870         bnx2x_cl45_read(bp, phy,
5871                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
5872
5873         bnx2x_cl45_read(bp, phy,
5874                         MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
5875         bnx2x_save_spirom_version(bp, params->port,
5876                                   (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
5877         return 0;
5878 }
5879
5880 static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
5881                                  struct link_params *params,
5882                                  struct link_vars *vars)
5883 {
5884         struct bnx2x *bp = params->bp;
5885         u8 link_up;
5886         u16 val1, val2;
5887         bnx2x_cl45_read(bp, phy,
5888                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
5889         bnx2x_cl45_read(bp, phy,
5890                         MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
5891         DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
5892                    val2, val1);
5893         bnx2x_cl45_read(bp, phy,
5894                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
5895         bnx2x_cl45_read(bp, phy,
5896                         MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
5897         DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
5898                    val2, val1);
5899         link_up = ((val1 & 4) == 4);
5900         /* if link is up
5901          * print the AN outcome of the SFX7101 PHY
5902          */
5903         if (link_up) {
5904                 bnx2x_cl45_read(bp, phy,
5905                                 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
5906                                 &val2);
5907                 vars->line_speed = SPEED_10000;
5908                 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
5909                            val2, (val2 & (1<<14)));
5910                 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
5911                 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5912         }
5913         return link_up;
5914 }
5915
5916
5917 static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
5918 {
5919         if (*len < 5)
5920                 return -EINVAL;
5921         str[0] = (spirom_ver & 0xFF);
5922         str[1] = (spirom_ver & 0xFF00) >> 8;
5923         str[2] = (spirom_ver & 0xFF0000) >> 16;
5924         str[3] = (spirom_ver & 0xFF000000) >> 24;
5925         str[4] = '\0';
5926         *len -= 5;
5927         return 0;
5928 }
5929
5930 void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
5931 {
5932         u16 val, cnt;
5933
5934         bnx2x_cl45_read(bp, phy,
5935                       MDIO_PMA_DEVAD,
5936                       MDIO_PMA_REG_7101_RESET, &val);
5937
5938         for (cnt = 0; cnt < 10; cnt++) {
5939                 msleep(50);
5940                 /* Writes a self-clearing reset */
5941                 bnx2x_cl45_write(bp, phy,
5942                                MDIO_PMA_DEVAD,
5943                                MDIO_PMA_REG_7101_RESET,
5944                                (val | (1<<15)));
5945                 /* Wait for clear */
5946                 bnx2x_cl45_read(bp, phy,
5947                               MDIO_PMA_DEVAD,
5948                               MDIO_PMA_REG_7101_RESET, &val);
5949
5950                 if ((val & (1<<15)) == 0)
5951                         break;
5952         }
5953 }
5954
5955 static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
5956                                 struct link_params *params) {
5957         /* Low power mode is controlled by GPIO 2 */
5958         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
5959                             MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
5960         /* The PHY reset is controlled by GPIO 1 */
5961         bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5962                             MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
5963 }
5964
5965 static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
5966                                     struct link_params *params, u8 mode)
5967 {
5968         u16 val = 0;
5969         struct bnx2x *bp = params->bp;
5970         switch (mode) {
5971         case LED_MODE_FRONT_PANEL_OFF:
5972         case LED_MODE_OFF:
5973                 val = 2;
5974                 break;
5975         case LED_MODE_ON:
5976                 val = 1;
5977                 break;
5978         case LED_MODE_OPER:
5979                 val = 0;
5980                 break;
5981         }
5982         bnx2x_cl45_write(bp, phy,
5983                          MDIO_PMA_DEVAD,
5984                          MDIO_PMA_REG_7107_LINK_LED_CNTL,
5985                          val);
5986 }
5987
5988 /******************************************************************/
5989 /*                      STATIC PHY DECLARATION                    */
5990 /******************************************************************/
5991
5992 static struct bnx2x_phy phy_null = {
5993         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
5994         .addr           = 0,
5995         .flags          = FLAGS_INIT_XGXS_FIRST,
5996         .def_md_devad   = 0,
5997         .reserved       = 0,
5998         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5999         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6000         .mdio_ctrl      = 0,
6001         .supported      = 0,
6002         .media_type     = ETH_PHY_NOT_PRESENT,
6003         .ver_addr       = 0,
6004         .req_flow_ctrl  = 0,
6005         .req_line_speed = 0,
6006         .speed_cap_mask = 0,
6007         .req_duplex     = 0,
6008         .rsrv           = 0,
6009         .config_init    = (config_init_t)NULL,
6010         .read_status    = (read_status_t)NULL,
6011         .link_reset     = (link_reset_t)NULL,
6012         .config_loopback = (config_loopback_t)NULL,
6013         .format_fw_ver  = (format_fw_ver_t)NULL,
6014         .hw_reset       = (hw_reset_t)NULL,
6015         .set_link_led   = (set_link_led_t)NULL,
6016         .phy_specific_func = (phy_specific_func_t)NULL
6017 };
6018
6019 static struct bnx2x_phy phy_serdes = {
6020         .type           = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
6021         .addr           = 0xff,
6022         .flags          = 0,
6023         .def_md_devad   = 0,
6024         .reserved       = 0,
6025         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6026         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6027         .mdio_ctrl      = 0,
6028         .supported      = (SUPPORTED_10baseT_Half |
6029                            SUPPORTED_10baseT_Full |
6030                            SUPPORTED_100baseT_Half |
6031                            SUPPORTED_100baseT_Full |
6032                            SUPPORTED_1000baseT_Full |
6033                            SUPPORTED_2500baseX_Full |
6034                            SUPPORTED_TP |
6035                            SUPPORTED_Autoneg |
6036                            SUPPORTED_Pause |
6037                            SUPPORTED_Asym_Pause),
6038         .media_type     = ETH_PHY_UNSPECIFIED,
6039         .ver_addr       = 0,
6040         .req_flow_ctrl  = 0,
6041         .req_line_speed = 0,
6042         .speed_cap_mask = 0,
6043         .req_duplex     = 0,
6044         .rsrv           = 0,
6045         .config_init    = (config_init_t)bnx2x_init_serdes,
6046         .read_status    = (read_status_t)bnx2x_link_settings_status,
6047         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
6048         .config_loopback = (config_loopback_t)NULL,
6049         .format_fw_ver  = (format_fw_ver_t)NULL,
6050         .hw_reset       = (hw_reset_t)NULL,
6051         .set_link_led   = (set_link_led_t)NULL,
6052         .phy_specific_func = (phy_specific_func_t)NULL
6053 };
6054
6055 static struct bnx2x_phy phy_xgxs = {
6056         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
6057         .addr           = 0xff,
6058         .flags          = 0,
6059         .def_md_devad   = 0,
6060         .reserved       = 0,
6061         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6062         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6063         .mdio_ctrl      = 0,
6064         .supported      = (SUPPORTED_10baseT_Half |
6065                            SUPPORTED_10baseT_Full |
6066                            SUPPORTED_100baseT_Half |
6067                            SUPPORTED_100baseT_Full |
6068                            SUPPORTED_1000baseT_Full |
6069                            SUPPORTED_2500baseX_Full |
6070                            SUPPORTED_10000baseT_Full |
6071                            SUPPORTED_FIBRE |
6072                            SUPPORTED_Autoneg |
6073                            SUPPORTED_Pause |
6074                            SUPPORTED_Asym_Pause),
6075         .media_type     = ETH_PHY_UNSPECIFIED,
6076         .ver_addr       = 0,
6077         .req_flow_ctrl  = 0,
6078         .req_line_speed = 0,
6079         .speed_cap_mask = 0,
6080         .req_duplex     = 0,
6081         .rsrv           = 0,
6082         .config_init    = (config_init_t)bnx2x_init_xgxs,
6083         .read_status    = (read_status_t)bnx2x_link_settings_status,
6084         .link_reset     = (link_reset_t)bnx2x_int_link_reset,
6085         .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
6086         .format_fw_ver  = (format_fw_ver_t)NULL,
6087         .hw_reset       = (hw_reset_t)NULL,
6088         .set_link_led   = (set_link_led_t)NULL,
6089         .phy_specific_func = (phy_specific_func_t)NULL
6090 };
6091
6092 static struct bnx2x_phy phy_7101 = {
6093         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6094         .addr           = 0xff,
6095         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
6096         .def_md_devad   = 0,
6097         .reserved       = 0,
6098         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6099         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6100         .mdio_ctrl      = 0,
6101         .supported      = (SUPPORTED_10000baseT_Full |
6102                            SUPPORTED_TP |
6103                            SUPPORTED_Autoneg |
6104                            SUPPORTED_Pause |
6105                            SUPPORTED_Asym_Pause),
6106         .media_type     = ETH_PHY_BASE_T,
6107         .ver_addr       = 0,
6108         .req_flow_ctrl  = 0,
6109         .req_line_speed = 0,
6110         .speed_cap_mask = 0,
6111         .req_duplex     = 0,
6112         .rsrv           = 0,
6113         .config_init    = (config_init_t)bnx2x_7101_config_init,
6114         .read_status    = (read_status_t)bnx2x_7101_read_status,
6115         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6116         .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
6117         .format_fw_ver  = (format_fw_ver_t)bnx2x_7101_format_ver,
6118         .hw_reset       = (hw_reset_t)bnx2x_7101_hw_reset,
6119         .set_link_led   = (set_link_led_t)bnx2x_7101_set_link_led,
6120         .phy_specific_func = (phy_specific_func_t)NULL
6121 };
6122 static struct bnx2x_phy phy_8073 = {
6123         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6124         .addr           = 0xff,
6125         .flags          = FLAGS_HW_LOCK_REQUIRED,
6126         .def_md_devad   = 0,
6127         .reserved       = 0,
6128         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6129         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6130         .mdio_ctrl      = 0,
6131         .supported      = (SUPPORTED_10000baseT_Full |
6132                            SUPPORTED_2500baseX_Full |
6133                            SUPPORTED_1000baseT_Full |
6134                            SUPPORTED_FIBRE |
6135                            SUPPORTED_Autoneg |
6136                            SUPPORTED_Pause |
6137                            SUPPORTED_Asym_Pause),
6138         .media_type     = ETH_PHY_UNSPECIFIED,
6139         .ver_addr       = 0,
6140         .req_flow_ctrl  = 0,
6141         .req_line_speed = 0,
6142         .speed_cap_mask = 0,
6143         .req_duplex     = 0,
6144         .rsrv           = 0,
6145         .config_init    = (config_init_t)bnx2x_8073_config_init,
6146         .read_status    = (read_status_t)bnx2x_8073_read_status,
6147         .link_reset     = (link_reset_t)bnx2x_8073_link_reset,
6148         .config_loopback = (config_loopback_t)NULL,
6149         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6150         .hw_reset       = (hw_reset_t)NULL,
6151         .set_link_led   = (set_link_led_t)NULL,
6152         .phy_specific_func = (phy_specific_func_t)NULL
6153 };
6154 static struct bnx2x_phy phy_8705 = {
6155         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
6156         .addr           = 0xff,
6157         .flags          = FLAGS_INIT_XGXS_FIRST,
6158         .def_md_devad   = 0,
6159         .reserved       = 0,
6160         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6161         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6162         .mdio_ctrl      = 0,
6163         .supported      = (SUPPORTED_10000baseT_Full |
6164                            SUPPORTED_FIBRE |
6165                            SUPPORTED_Pause |
6166                            SUPPORTED_Asym_Pause),
6167         .media_type     = ETH_PHY_XFP_FIBER,
6168         .ver_addr       = 0,
6169         .req_flow_ctrl  = 0,
6170         .req_line_speed = 0,
6171         .speed_cap_mask = 0,
6172         .req_duplex     = 0,
6173         .rsrv           = 0,
6174         .config_init    = (config_init_t)bnx2x_8705_config_init,
6175         .read_status    = (read_status_t)bnx2x_8705_read_status,
6176         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6177         .config_loopback = (config_loopback_t)NULL,
6178         .format_fw_ver  = (format_fw_ver_t)bnx2x_null_format_ver,
6179         .hw_reset       = (hw_reset_t)NULL,
6180         .set_link_led   = (set_link_led_t)NULL,
6181         .phy_specific_func = (phy_specific_func_t)NULL
6182 };
6183 static struct bnx2x_phy phy_8706 = {
6184         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
6185         .addr           = 0xff,
6186         .flags          = FLAGS_INIT_XGXS_FIRST,
6187         .def_md_devad   = 0,
6188         .reserved       = 0,
6189         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6190         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6191         .mdio_ctrl      = 0,
6192         .supported      = (SUPPORTED_10000baseT_Full |
6193                            SUPPORTED_1000baseT_Full |
6194                            SUPPORTED_FIBRE |
6195                            SUPPORTED_Pause |
6196                            SUPPORTED_Asym_Pause),
6197         .media_type     = ETH_PHY_SFP_FIBER,
6198         .ver_addr       = 0,
6199         .req_flow_ctrl  = 0,
6200         .req_line_speed = 0,
6201         .speed_cap_mask = 0,
6202         .req_duplex     = 0,
6203         .rsrv           = 0,
6204         .config_init    = (config_init_t)bnx2x_8706_config_init,
6205         .read_status    = (read_status_t)bnx2x_8706_read_status,
6206         .link_reset     = (link_reset_t)bnx2x_common_ext_link_reset,
6207         .config_loopback = (config_loopback_t)NULL,
6208         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6209         .hw_reset       = (hw_reset_t)NULL,
6210         .set_link_led   = (set_link_led_t)NULL,
6211         .phy_specific_func = (phy_specific_func_t)NULL
6212 };
6213
6214 static struct bnx2x_phy phy_8726 = {
6215         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
6216         .addr           = 0xff,
6217         .flags          = (FLAGS_HW_LOCK_REQUIRED |
6218                            FLAGS_INIT_XGXS_FIRST),
6219         .def_md_devad   = 0,
6220         .reserved       = 0,
6221         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6222         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6223         .mdio_ctrl      = 0,
6224         .supported      = (SUPPORTED_10000baseT_Full |
6225                            SUPPORTED_1000baseT_Full |
6226                            SUPPORTED_Autoneg |
6227                            SUPPORTED_FIBRE |
6228                            SUPPORTED_Pause |
6229                            SUPPORTED_Asym_Pause),
6230         .media_type     = ETH_PHY_SFP_FIBER,
6231         .ver_addr       = 0,
6232         .req_flow_ctrl  = 0,
6233         .req_line_speed = 0,
6234         .speed_cap_mask = 0,
6235         .req_duplex     = 0,
6236         .rsrv           = 0,
6237         .config_init    = (config_init_t)bnx2x_8726_config_init,
6238         .read_status    = (read_status_t)bnx2x_8726_read_status,
6239         .link_reset     = (link_reset_t)bnx2x_8726_link_reset,
6240         .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
6241         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6242         .hw_reset       = (hw_reset_t)NULL,
6243         .set_link_led   = (set_link_led_t)NULL,
6244         .phy_specific_func = (phy_specific_func_t)NULL
6245 };
6246
6247 static struct bnx2x_phy phy_8727 = {
6248         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
6249         .addr           = 0xff,
6250         .flags          = FLAGS_FAN_FAILURE_DET_REQ,
6251         .def_md_devad   = 0,
6252         .reserved       = 0,
6253         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6254         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6255         .mdio_ctrl      = 0,
6256         .supported      = (SUPPORTED_10000baseT_Full |
6257                            SUPPORTED_1000baseT_Full |
6258                            SUPPORTED_FIBRE |
6259                            SUPPORTED_Pause |
6260                            SUPPORTED_Asym_Pause),
6261         .media_type     = ETH_PHY_SFP_FIBER,
6262         .ver_addr       = 0,
6263         .req_flow_ctrl  = 0,
6264         .req_line_speed = 0,
6265         .speed_cap_mask = 0,
6266         .req_duplex     = 0,
6267         .rsrv           = 0,
6268         .config_init    = (config_init_t)bnx2x_8727_config_init,
6269         .read_status    = (read_status_t)bnx2x_8727_read_status,
6270         .link_reset     = (link_reset_t)bnx2x_8727_link_reset,
6271         .config_loopback = (config_loopback_t)NULL,
6272         .format_fw_ver  = (format_fw_ver_t)bnx2x_format_ver,
6273         .hw_reset       = (hw_reset_t)bnx2x_8727_hw_reset,
6274         .set_link_led   = (set_link_led_t)bnx2x_8727_set_link_led,
6275         .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
6276 };
6277 static struct bnx2x_phy phy_8481 = {
6278         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6279         .addr           = 0xff,
6280         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
6281                           FLAGS_REARM_LATCH_SIGNAL,
6282         .def_md_devad   = 0,
6283         .reserved       = 0,
6284         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6285         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6286         .mdio_ctrl      = 0,
6287         .supported      = (SUPPORTED_10baseT_Half |
6288                            SUPPORTED_10baseT_Full |
6289                            SUPPORTED_100baseT_Half |
6290                            SUPPORTED_100baseT_Full |
6291                            SUPPORTED_1000baseT_Full |
6292                            SUPPORTED_10000baseT_Full |
6293                            SUPPORTED_TP |
6294                            SUPPORTED_Autoneg |
6295                            SUPPORTED_Pause |
6296                            SUPPORTED_Asym_Pause),
6297         .media_type     = ETH_PHY_BASE_T,
6298         .ver_addr       = 0,
6299         .req_flow_ctrl  = 0,
6300         .req_line_speed = 0,
6301         .speed_cap_mask = 0,
6302         .req_duplex     = 0,
6303         .rsrv           = 0,
6304         .config_init    = (config_init_t)bnx2x_8481_config_init,
6305         .read_status    = (read_status_t)bnx2x_848xx_read_status,
6306         .link_reset     = (link_reset_t)bnx2x_8481_link_reset,
6307         .config_loopback = (config_loopback_t)NULL,
6308         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
6309         .hw_reset       = (hw_reset_t)bnx2x_8481_hw_reset,
6310         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
6311         .phy_specific_func = (phy_specific_func_t)NULL
6312 };
6313
6314 static struct bnx2x_phy phy_84823 = {
6315         .type           = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
6316         .addr           = 0xff,
6317         .flags          = FLAGS_FAN_FAILURE_DET_REQ |
6318                           FLAGS_REARM_LATCH_SIGNAL,
6319         .def_md_devad   = 0,
6320         .reserved       = 0,
6321         .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6322         .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6323         .mdio_ctrl      = 0,
6324         .supported      = (SUPPORTED_10baseT_Half |
6325                            SUPPORTED_10baseT_Full |
6326                            SUPPORTED_100baseT_Half |
6327                            SUPPORTED_100baseT_Full |
6328                            SUPPORTED_1000baseT_Full |
6329                            SUPPORTED_10000baseT_Full |
6330                            SUPPORTED_TP |
6331                            SUPPORTED_Autoneg |
6332                            SUPPORTED_Pause |
6333                            SUPPORTED_Asym_Pause),
6334         .media_type     = ETH_PHY_BASE_T,
6335         .ver_addr       = 0,
6336         .req_flow_ctrl  = 0,
6337         .req_line_speed = 0,
6338         .speed_cap_mask = 0,
6339         .req_duplex     = 0,
6340         .rsrv           = 0,
6341         .config_init    = (config_init_t)bnx2x_848x3_config_init,
6342         .read_status    = (read_status_t)bnx2x_848xx_read_status,
6343         .link_reset     = (link_reset_t)bnx2x_848x3_link_reset,
6344         .config_loopback = (config_loopback_t)NULL,
6345         .format_fw_ver  = (format_fw_ver_t)bnx2x_848xx_format_ver,
6346         .hw_reset       = (hw_reset_t)NULL,
6347         .set_link_led   = (set_link_led_t)bnx2x_848xx_set_link_led,
6348         .phy_specific_func = (phy_specific_func_t)NULL
6349 };
6350
6351 /*****************************************************************/
6352 /*                                                               */
6353 /* Populate the phy according. Main function: bnx2x_populate_phy   */
6354 /*                                                               */
6355 /*****************************************************************/
6356
6357 static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
6358                                      struct bnx2x_phy *phy, u8 port,
6359                                      u8 phy_index)
6360 {
6361         /* Get the 4 lanes xgxs config rx and tx */
6362         u32 rx = 0, tx = 0, i;
6363         for (i = 0; i < 2; i++) {
6364                 /**
6365                  * INT_PHY and EXT_PHY1 share the same value location in the
6366                  * shmem. When num_phys is greater than 1, than this value
6367                  * applies only to EXT_PHY1
6368                  */
6369                 if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
6370                         rx = REG_RD(bp, shmem_base +
6371                                     offsetof(struct shmem_region,
6372                            dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
6373
6374                         tx = REG_RD(bp, shmem_base +
6375                                     offsetof(struct shmem_region,
6376                            dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
6377                 } else {
6378                         rx = REG_RD(bp, shmem_base +
6379                                     offsetof(struct shmem_region,
6380                           dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
6381
6382                         tx = REG_RD(bp, shmem_base +
6383                                     offsetof(struct shmem_region,
6384                           dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
6385                 }
6386
6387                 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
6388                 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
6389
6390                 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
6391                 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
6392         }
6393 }
6394
6395 static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
6396                                     u8 phy_index, u8 port)
6397 {
6398         u32 ext_phy_config = 0;
6399         switch (phy_index) {
6400         case EXT_PHY1:
6401                 ext_phy_config = REG_RD(bp, shmem_base +
6402                                               offsetof(struct shmem_region,
6403                         dev_info.port_hw_config[port].external_phy_config));
6404                 break;
6405         case EXT_PHY2:
6406                 ext_phy_config = REG_RD(bp, shmem_base +
6407                                               offsetof(struct shmem_region,
6408                         dev_info.port_hw_config[port].external_phy_config2));
6409                 break;
6410         default:
6411                 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
6412                 return -EINVAL;
6413         }
6414
6415         return ext_phy_config;
6416 }
6417 static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
6418                                  struct bnx2x_phy *phy)
6419 {
6420         u32 phy_addr;
6421         u32 chip_id;
6422         u32 switch_cfg = (REG_RD(bp, shmem_base +
6423                                        offsetof(struct shmem_region,
6424                         dev_info.port_feature_config[port].link_config)) &
6425                           PORT_FEATURE_CONNECTED_SWITCH_MASK);
6426         chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
6427         switch (switch_cfg) {
6428         case SWITCH_CFG_1G:
6429                 phy_addr = REG_RD(bp,
6430                                         NIG_REG_SERDES0_CTRL_PHY_ADDR +
6431                                         port * 0x10);
6432                 *phy = phy_serdes;
6433                 break;
6434         case SWITCH_CFG_10G:
6435                 phy_addr = REG_RD(bp,
6436                                         NIG_REG_XGXS0_CTRL_PHY_ADDR +
6437                                         port * 0x18);
6438                 *phy = phy_xgxs;
6439                 break;
6440         default:
6441                 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
6442                 return -EINVAL;
6443         }
6444         phy->addr = (u8)phy_addr;
6445         phy->mdio_ctrl = bnx2x_get_emac_base(bp,
6446                                             SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
6447                                             port);
6448         if (CHIP_IS_E2(bp))
6449                 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
6450         else
6451                 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
6452
6453         DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
6454                    port, phy->addr, phy->mdio_ctrl);
6455
6456         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
6457         return 0;
6458 }
6459
6460 static u8 bnx2x_populate_ext_phy(struct bnx2x *bp,
6461                                  u8 phy_index,
6462                                  u32 shmem_base,
6463                                  u32 shmem2_base,
6464                                  u8 port,
6465                                  struct bnx2x_phy *phy)
6466 {
6467         u32 ext_phy_config, phy_type, config2;
6468         u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
6469         ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
6470                                                   phy_index, port);
6471         phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6472         /* Select the phy type */
6473         switch (phy_type) {
6474         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6475                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
6476                 *phy = phy_8073;
6477                 break;
6478         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
6479                 *phy = phy_8705;
6480                 break;
6481         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
6482                 *phy = phy_8706;
6483                 break;
6484         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6485                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
6486                 *phy = phy_8726;
6487                 break;
6488         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6489                 /* BCM8727_NOC => BCM8727 no over current */
6490                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
6491                 *phy = phy_8727;
6492                 phy->flags |= FLAGS_NOC;
6493                 break;
6494         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6495                 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
6496                 *phy = phy_8727;
6497                 break;
6498         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
6499                 *phy = phy_8481;
6500                 break;
6501         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
6502                 *phy = phy_84823;
6503                 break;
6504         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
6505                 *phy = phy_7101;
6506                 break;
6507         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
6508                 *phy = phy_null;
6509                 return -EINVAL;
6510         default:
6511                 *phy = phy_null;
6512                 return 0;
6513         }
6514
6515         phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
6516         bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
6517
6518         /**
6519         * The shmem address of the phy version is located on different
6520         * structures. In case this structure is too old, do not set
6521         * the address
6522         */
6523         config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
6524                                         dev_info.shared_hw_config.config2));
6525         if (phy_index == EXT_PHY1) {
6526                 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
6527                                 port_mb[port].ext_phy_fw_version);
6528
6529         /* Check specific mdc mdio settings */
6530         if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
6531                 mdc_mdio_access = config2 &
6532                 SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
6533         } else {
6534                 u32 size = REG_RD(bp, shmem2_base);
6535
6536                 if (size >
6537                     offsetof(struct shmem2_region, ext_phy_fw_version2)) {
6538                         phy->ver_addr = shmem2_base +
6539                             offsetof(struct shmem2_region,
6540                                      ext_phy_fw_version2[port]);
6541                 }
6542                 /* Check specific mdc mdio settings */
6543                 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
6544                         mdc_mdio_access = (config2 &
6545                         SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
6546                         (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
6547                          SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
6548         }
6549         phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
6550
6551         /**
6552          * In case mdc/mdio_access of the external phy is different than the
6553          * mdc/mdio access of the XGXS, a HW lock must be taken in each access
6554          * to prevent one port interfere with another port's CL45 operations.
6555          */
6556         if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
6557                 phy->flags |= FLAGS_HW_LOCK_REQUIRED;
6558         DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
6559                    phy_type, port, phy_index);
6560         DP(NETIF_MSG_LINK, "             addr=0x%x, mdio_ctl=0x%x\n",
6561                    phy->addr, phy->mdio_ctrl);
6562         return 0;
6563 }
6564
6565 static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
6566                              u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
6567 {
6568         u8 status = 0;
6569         phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
6570         if (phy_index == INT_PHY)
6571                 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
6572         status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
6573                                         port, phy);
6574         return status;
6575 }
6576
6577 static void bnx2x_phy_def_cfg(struct link_params *params,
6578                               struct bnx2x_phy *phy,
6579                               u8 phy_index)
6580 {
6581         struct bnx2x *bp = params->bp;
6582         u32 link_config;
6583         /* Populate the default phy configuration for MF mode */
6584         if (phy_index == EXT_PHY2) {
6585                 link_config = REG_RD(bp, params->shmem_base +
6586                                          offsetof(struct shmem_region, dev_info.
6587                         port_feature_config[params->port].link_config2));
6588                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
6589                                         offsetof(struct shmem_region, dev_info.
6590                         port_hw_config[params->port].speed_capability_mask2));
6591         } else {
6592                 link_config = REG_RD(bp, params->shmem_base +
6593                                 offsetof(struct shmem_region, dev_info.
6594                                 port_feature_config[params->port].link_config));
6595                 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
6596                                 offsetof(struct shmem_region, dev_info.
6597                            port_hw_config[params->port].speed_capability_mask));
6598         }
6599         DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
6600                        " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
6601
6602         phy->req_duplex = DUPLEX_FULL;
6603         switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
6604         case PORT_FEATURE_LINK_SPEED_10M_HALF:
6605                 phy->req_duplex = DUPLEX_HALF;
6606         case PORT_FEATURE_LINK_SPEED_10M_FULL:
6607                 phy->req_line_speed = SPEED_10;
6608                 break;
6609         case PORT_FEATURE_LINK_SPEED_100M_HALF:
6610                 phy->req_duplex = DUPLEX_HALF;
6611         case PORT_FEATURE_LINK_SPEED_100M_FULL:
6612                 phy->req_line_speed = SPEED_100;
6613                 break;
6614         case PORT_FEATURE_LINK_SPEED_1G:
6615                 phy->req_line_speed = SPEED_1000;
6616                 break;
6617         case PORT_FEATURE_LINK_SPEED_2_5G:
6618                 phy->req_line_speed = SPEED_2500;
6619                 break;
6620         case PORT_FEATURE_LINK_SPEED_10G_CX4:
6621                 phy->req_line_speed = SPEED_10000;
6622                 break;
6623         default:
6624                 phy->req_line_speed = SPEED_AUTO_NEG;
6625                 break;
6626         }
6627
6628         switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
6629         case PORT_FEATURE_FLOW_CONTROL_AUTO:
6630                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
6631                 break;
6632         case PORT_FEATURE_FLOW_CONTROL_TX:
6633                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
6634                 break;
6635         case PORT_FEATURE_FLOW_CONTROL_RX:
6636                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
6637                 break;
6638         case PORT_FEATURE_FLOW_CONTROL_BOTH:
6639                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
6640                 break;
6641         default:
6642                 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6643                 break;
6644         }
6645 }
6646
6647 u32 bnx2x_phy_selection(struct link_params *params)
6648 {
6649         u32 phy_config_swapped, prio_cfg;
6650         u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
6651
6652         phy_config_swapped = params->multi_phy_config &
6653                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
6654
6655         prio_cfg = params->multi_phy_config &
6656                         PORT_HW_CFG_PHY_SELECTION_MASK;
6657
6658         if (phy_config_swapped) {
6659                 switch (prio_cfg) {
6660                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6661                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
6662                      break;
6663                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6664                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
6665                      break;
6666                 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
6667                      return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
6668                      break;
6669                 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
6670                      return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
6671                      break;
6672                 }
6673         } else
6674                 return_cfg = prio_cfg;
6675
6676         return return_cfg;
6677 }
6678
6679
6680 u8 bnx2x_phy_probe(struct link_params *params)
6681 {
6682         u8 phy_index, actual_phy_idx, link_cfg_idx;
6683         u32 phy_config_swapped;
6684         struct bnx2x *bp = params->bp;
6685         struct bnx2x_phy *phy;
6686         params->num_phys = 0;
6687         DP(NETIF_MSG_LINK, "Begin phy probe\n");
6688         phy_config_swapped = params->multi_phy_config &
6689                 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
6690
6691         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
6692               phy_index++) {
6693                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
6694                 actual_phy_idx = phy_index;
6695                 if (phy_config_swapped) {
6696                         if (phy_index == EXT_PHY1)
6697                                 actual_phy_idx = EXT_PHY2;
6698                         else if (phy_index == EXT_PHY2)
6699                                 actual_phy_idx = EXT_PHY1;
6700                 }
6701                 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
6702                                " actual_phy_idx %x\n", phy_config_swapped,
6703                            phy_index, actual_phy_idx);
6704                 phy = &params->phy[actual_phy_idx];
6705                 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
6706                                        params->shmem2_base, params->port,
6707                                        phy) != 0) {
6708                         params->num_phys = 0;
6709                         DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
6710                                    phy_index);
6711                         for (phy_index = INT_PHY;
6712                               phy_index < MAX_PHYS;
6713                               phy_index++)
6714                                 *phy = phy_null;
6715                         return -EINVAL;
6716                 }
6717                 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
6718                         break;
6719
6720                 bnx2x_phy_def_cfg(params, phy, phy_index);
6721                 params->num_phys++;
6722         }
6723
6724         DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
6725         return 0;
6726 }
6727
6728 static void set_phy_vars(struct link_params *params)
6729 {
6730         struct bnx2x *bp = params->bp;
6731         u8 actual_phy_idx, phy_index, link_cfg_idx;
6732         u8 phy_config_swapped = params->multi_phy_config &
6733                         PORT_HW_CFG_PHY_SWAPPED_ENABLED;
6734         for (phy_index = INT_PHY; phy_index < params->num_phys;
6735               phy_index++) {
6736                 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
6737                 actual_phy_idx = phy_index;
6738                 if (phy_config_swapped) {
6739                         if (phy_index == EXT_PHY1)
6740                                 actual_phy_idx = EXT_PHY2;
6741                         else if (phy_index == EXT_PHY2)
6742                                 actual_phy_idx = EXT_PHY1;
6743                 }
6744                 params->phy[actual_phy_idx].req_flow_ctrl  =
6745                         params->req_flow_ctrl[link_cfg_idx];
6746
6747                 params->phy[actual_phy_idx].req_line_speed =
6748                         params->req_line_speed[link_cfg_idx];
6749
6750                 params->phy[actual_phy_idx].speed_cap_mask =
6751                         params->speed_cap_mask[link_cfg_idx];
6752
6753                 params->phy[actual_phy_idx].req_duplex =
6754                         params->req_duplex[link_cfg_idx];
6755
6756                 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
6757                            " speed_cap_mask %x\n",
6758                            params->phy[actual_phy_idx].req_flow_ctrl,
6759                            params->phy[actual_phy_idx].req_line_speed,
6760                            params->phy[actual_phy_idx].speed_cap_mask);
6761         }
6762 }
6763
6764 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
6765 {
6766         struct bnx2x *bp = params->bp;
6767         DP(NETIF_MSG_LINK, "Phy Initialization started\n");
6768         DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
6769                    params->req_line_speed[0], params->req_flow_ctrl[0]);
6770         DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
6771                    params->req_line_speed[1], params->req_flow_ctrl[1]);
6772         vars->link_status = 0;
6773         vars->phy_link_up = 0;
6774         vars->link_up = 0;
6775         vars->line_speed = 0;
6776         vars->duplex = DUPLEX_FULL;
6777         vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6778         vars->mac_type = MAC_TYPE_NONE;
6779         vars->phy_flags = 0;
6780
6781         /* disable attentions */
6782         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
6783                        (NIG_MASK_XGXS0_LINK_STATUS |
6784                         NIG_MASK_XGXS0_LINK10G |
6785                         NIG_MASK_SERDES0_LINK_STATUS |
6786                         NIG_MASK_MI_INT));
6787
6788         bnx2x_emac_init(params, vars);
6789
6790         if (params->num_phys == 0) {
6791                 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
6792                 return -EINVAL;
6793         }
6794         set_phy_vars(params);
6795
6796         DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
6797         if (CHIP_REV_IS_FPGA(bp)) {
6798
6799                 vars->link_up = 1;
6800                 vars->line_speed = SPEED_10000;
6801                 vars->duplex = DUPLEX_FULL;
6802                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6803                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6804                 /* enable on E1.5 FPGA */
6805                 if (CHIP_IS_E1H(bp)) {
6806                         vars->flow_ctrl |=
6807                                         (BNX2X_FLOW_CTRL_TX |
6808                                          BNX2X_FLOW_CTRL_RX);
6809                         vars->link_status |=
6810                                         (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
6811                                          LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
6812                 }
6813
6814                 bnx2x_emac_enable(params, vars, 0);
6815                 if (!(CHIP_IS_E2(bp)))
6816                         bnx2x_pbf_update(params, vars->flow_ctrl,
6817                                          vars->line_speed);
6818                 /* disable drain */
6819                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
6820
6821                 /* update shared memory */
6822                 bnx2x_update_mng(params, vars->link_status);
6823
6824                 return 0;
6825
6826         } else
6827         if (CHIP_REV_IS_EMUL(bp)) {
6828
6829                 vars->link_up = 1;
6830                 vars->line_speed = SPEED_10000;
6831                 vars->duplex = DUPLEX_FULL;
6832                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6833                 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6834
6835                 bnx2x_bmac_enable(params, vars, 0);
6836
6837                 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6838                 /* Disable drain */
6839                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
6840                                     + params->port*4, 0);
6841
6842                 /* update shared memory */
6843                 bnx2x_update_mng(params, vars->link_status);
6844
6845                 return 0;
6846
6847         } else
6848         if (params->loopback_mode == LOOPBACK_BMAC) {
6849
6850                 vars->link_up = 1;
6851                 vars->line_speed = SPEED_10000;
6852                 vars->duplex = DUPLEX_FULL;
6853                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6854                 vars->mac_type = MAC_TYPE_BMAC;
6855
6856                 vars->phy_flags = PHY_XGXS_FLAG;
6857
6858                 bnx2x_xgxs_deassert(params);
6859
6860                 /* set bmac loopback */
6861                 bnx2x_bmac_enable(params, vars, 1);
6862
6863                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6864                     params->port*4, 0);
6865
6866         } else if (params->loopback_mode == LOOPBACK_EMAC) {
6867
6868                 vars->link_up = 1;
6869                 vars->line_speed = SPEED_1000;
6870                 vars->duplex = DUPLEX_FULL;
6871                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6872                 vars->mac_type = MAC_TYPE_EMAC;
6873
6874                 vars->phy_flags = PHY_XGXS_FLAG;
6875
6876                 bnx2x_xgxs_deassert(params);
6877                 /* set bmac loopback */
6878                 bnx2x_emac_enable(params, vars, 1);
6879                 bnx2x_emac_program(params, vars);
6880                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6881                     params->port*4, 0);
6882
6883         } else if ((params->loopback_mode == LOOPBACK_XGXS) ||
6884                    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6885
6886                 vars->link_up = 1;
6887                 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6888                 vars->duplex = DUPLEX_FULL;
6889                 if (params->req_line_speed[0] == SPEED_1000) {
6890                         vars->line_speed = SPEED_1000;
6891                         vars->mac_type = MAC_TYPE_EMAC;
6892                 } else {
6893                         vars->line_speed = SPEED_10000;
6894                         vars->mac_type = MAC_TYPE_BMAC;
6895                 }
6896
6897                 bnx2x_xgxs_deassert(params);
6898                 bnx2x_link_initialize(params, vars);
6899
6900                 if (params->req_line_speed[0] == SPEED_1000) {
6901                         bnx2x_emac_program(params, vars);
6902                         bnx2x_emac_enable(params, vars, 0);
6903                 } else
6904                 bnx2x_bmac_enable(params, vars, 0);
6905
6906                 if (params->loopback_mode == LOOPBACK_XGXS) {
6907                         /* set 10G XGXS loopback */
6908                         params->phy[INT_PHY].config_loopback(
6909                                 &params->phy[INT_PHY],
6910                                 params);
6911
6912                 } else {
6913                         /* set external phy loopback */
6914                         u8 phy_index;
6915                         for (phy_index = EXT_PHY1;
6916                               phy_index < params->num_phys; phy_index++) {
6917                                 if (params->phy[phy_index].config_loopback)
6918                                         params->phy[phy_index].config_loopback(
6919                                                 &params->phy[phy_index],
6920                                                 params);
6921                         }
6922                 }
6923
6924                 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6925                             params->port*4, 0);
6926
6927                 bnx2x_set_led(params, vars,
6928                               LED_MODE_OPER, vars->line_speed);
6929         } else
6930         /* No loopback */
6931         {
6932                 if (params->switch_cfg == SWITCH_CFG_10G)
6933                         bnx2x_xgxs_deassert(params);
6934                 else
6935                         bnx2x_serdes_deassert(bp, params->port);
6936
6937                 bnx2x_link_initialize(params, vars);
6938                 msleep(30);
6939                 bnx2x_link_int_enable(params);
6940         }
6941         return 0;
6942 }
6943 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6944                   u8 reset_ext_phy)
6945 {
6946         struct bnx2x *bp = params->bp;
6947         u8 phy_index, port = params->port, clear_latch_ind = 0;
6948         DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
6949         /* disable attentions */
6950         vars->link_status = 0;
6951         bnx2x_update_mng(params, vars->link_status);
6952         bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6953                      (NIG_MASK_XGXS0_LINK_STATUS |
6954                       NIG_MASK_XGXS0_LINK10G |
6955                       NIG_MASK_SERDES0_LINK_STATUS |
6956                       NIG_MASK_MI_INT));
6957
6958         /* activate nig drain */
6959         REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6960
6961         /* disable nig egress interface */
6962         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
6963         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
6964
6965         /* Stop BigMac rx */
6966         bnx2x_bmac_rx_disable(bp, port);
6967
6968         /* disable emac */
6969         REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6970
6971         msleep(10);
6972         /* The PHY reset is controled by GPIO 1
6973          * Hold it as vars low
6974          */
6975          /* clear link led */
6976         bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
6977
6978         if (reset_ext_phy) {
6979                 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6980                       phy_index++) {
6981                         if (params->phy[phy_index].link_reset)
6982                                 params->phy[phy_index].link_reset(
6983                                         &params->phy[phy_index],
6984                                         params);
6985                         if (params->phy[phy_index].flags &
6986                             FLAGS_REARM_LATCH_SIGNAL)
6987                                 clear_latch_ind = 1;
6988                 }
6989         }
6990
6991         if (clear_latch_ind) {
6992                 /* Clear latching indication */
6993                 bnx2x_rearm_latch_signal(bp, port, 0);
6994                 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
6995                                1 << NIG_LATCH_BC_ENABLE_MI_INT);
6996         }
6997         if (params->phy[INT_PHY].link_reset)
6998                 params->phy[INT_PHY].link_reset(
6999                         &params->phy[INT_PHY], params);
7000         /* reset BigMac */
7001         REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
7002                (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
7003
7004         /* disable nig ingress interface */
7005         REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
7006         REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
7007         REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
7008         REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
7009         vars->link_up = 0;
7010         return 0;
7011 }
7012
7013 /****************************************************************************/
7014 /*                              Common function                             */
7015 /****************************************************************************/
7016 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
7017                                      u32 shmem_base_path[],
7018                                      u32 shmem2_base_path[], u8 phy_index,
7019                                      u32 chip_id)
7020 {
7021         struct bnx2x_phy phy[PORT_MAX];
7022         struct bnx2x_phy *phy_blk[PORT_MAX];
7023         u16 val;
7024         s8 port;
7025         s8 port_of_path = 0;
7026
7027         bnx2x_ext_phy_hw_reset(bp, 0);
7028         /* PART1 - Reset both phys */
7029         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7030                 u32 shmem_base, shmem2_base;
7031                 /* In E2, same phy is using for port0 of the two paths */
7032                 if (CHIP_IS_E2(bp)) {
7033                         shmem_base = shmem_base_path[port];
7034                         shmem2_base = shmem2_base_path[port];
7035                         port_of_path = 0;
7036                 } else {
7037                         shmem_base = shmem_base_path[0];
7038                         shmem2_base = shmem2_base_path[0];
7039                         port_of_path = port;
7040                 }
7041
7042                 /* Extract the ext phy address for the port */
7043                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7044                                        port_of_path, &phy[port]) !=
7045                     0) {
7046                         DP(NETIF_MSG_LINK, "populate_phy failed\n");
7047                         return -EINVAL;
7048                 }
7049                 /* disable attentions */
7050                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7051                                port_of_path*4,
7052                              (NIG_MASK_XGXS0_LINK_STATUS |
7053                               NIG_MASK_XGXS0_LINK10G |
7054                               NIG_MASK_SERDES0_LINK_STATUS |
7055                               NIG_MASK_MI_INT));
7056
7057                 /* Need to take the phy out of low power mode in order
7058                         to write to access its registers */
7059                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7060                                   MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
7061
7062                 /* Reset the phy */
7063                 bnx2x_cl45_write(bp, &phy[port],
7064                                MDIO_PMA_DEVAD,
7065                                MDIO_PMA_REG_CTRL,
7066                                1<<15);
7067         }
7068
7069         /* Add delay of 150ms after reset */
7070         msleep(150);
7071
7072         if (phy[PORT_0].addr & 0x1) {
7073                 phy_blk[PORT_0] = &(phy[PORT_1]);
7074                 phy_blk[PORT_1] = &(phy[PORT_0]);
7075         } else {
7076                 phy_blk[PORT_0] = &(phy[PORT_0]);
7077                 phy_blk[PORT_1] = &(phy[PORT_1]);
7078         }
7079
7080         /* PART2 - Download firmware to both phys */
7081         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7082                 u16 fw_ver1;
7083                 if (CHIP_IS_E2(bp))
7084                         port_of_path = 0;
7085                 else
7086                         port_of_path = port;
7087
7088                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7089                            phy_blk[port]->addr);
7090                 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7091                                                   port_of_path);
7092
7093                 bnx2x_cl45_read(bp, phy_blk[port],
7094                               MDIO_PMA_DEVAD,
7095                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
7096                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
7097                         DP(NETIF_MSG_LINK,
7098                                  "bnx2x_8073_common_init_phy port %x:"
7099                                  "Download failed. fw version = 0x%x\n",
7100                                  port, fw_ver1);
7101                         return -EINVAL;
7102                 }
7103
7104                 /* Only set bit 10 = 1 (Tx power down) */
7105                 bnx2x_cl45_read(bp, phy_blk[port],
7106                               MDIO_PMA_DEVAD,
7107                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
7108
7109                 /* Phase1 of TX_POWER_DOWN reset */
7110                 bnx2x_cl45_write(bp, phy_blk[port],
7111                                MDIO_PMA_DEVAD,
7112                                MDIO_PMA_REG_TX_POWER_DOWN,
7113                                (val | 1<<10));
7114         }
7115
7116         /* Toggle Transmitter: Power down and then up with 600ms
7117            delay between */
7118         msleep(600);
7119
7120         /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
7121         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7122                 /* Phase2 of POWER_DOWN_RESET */
7123                 /* Release bit 10 (Release Tx power down) */
7124                 bnx2x_cl45_read(bp, phy_blk[port],
7125                               MDIO_PMA_DEVAD,
7126                               MDIO_PMA_REG_TX_POWER_DOWN, &val);
7127
7128                 bnx2x_cl45_write(bp, phy_blk[port],
7129                                MDIO_PMA_DEVAD,
7130                                MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
7131                 msleep(15);
7132
7133                 /* Read modify write the SPI-ROM version select register */
7134                 bnx2x_cl45_read(bp, phy_blk[port],
7135                               MDIO_PMA_DEVAD,
7136                               MDIO_PMA_REG_EDC_FFE_MAIN, &val);
7137                 bnx2x_cl45_write(bp, phy_blk[port],
7138                               MDIO_PMA_DEVAD,
7139                               MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
7140
7141                 /* set GPIO2 back to LOW */
7142                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7143                                   MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
7144         }
7145         return 0;
7146 }
7147 static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
7148                                      u32 shmem_base_path[],
7149                                      u32 shmem2_base_path[], u8 phy_index,
7150                                      u32 chip_id)
7151 {
7152         u32 val;
7153         s8 port;
7154         struct bnx2x_phy phy;
7155         /* Use port1 because of the static port-swap */
7156         /* Enable the module detection interrupt */
7157         val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
7158         val |= ((1<<MISC_REGISTERS_GPIO_3)|
7159                 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
7160         REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
7161
7162         bnx2x_ext_phy_hw_reset(bp, 0);
7163         msleep(5);
7164         for (port = 0; port < PORT_MAX; port++) {
7165                 u32 shmem_base, shmem2_base;
7166
7167                 /* In E2, same phy is using for port0 of the two paths */
7168                 if (CHIP_IS_E2(bp)) {
7169                         shmem_base = shmem_base_path[port];
7170                         shmem2_base = shmem2_base_path[port];
7171                 } else {
7172                         shmem_base = shmem_base_path[0];
7173                         shmem2_base = shmem2_base_path[0];
7174                 }
7175                 /* Extract the ext phy address for the port */
7176                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7177                                        port, &phy) !=
7178                     0) {
7179                         DP(NETIF_MSG_LINK, "populate phy failed\n");
7180                         return -EINVAL;
7181                 }
7182
7183                 /* Reset phy*/
7184                 bnx2x_cl45_write(bp, &phy,
7185                                  MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
7186
7187
7188                 /* Set fault module detected LED on */
7189                 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
7190                                   MISC_REGISTERS_GPIO_HIGH,
7191                                   port);
7192         }
7193
7194         return 0;
7195 }
7196 static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
7197                                      u32 shmem_base_path[],
7198                                      u32 shmem2_base_path[], u8 phy_index,
7199                                      u32 chip_id)
7200 {
7201         s8 port;
7202         u32 swap_val, swap_override;
7203         struct bnx2x_phy phy[PORT_MAX];
7204         struct bnx2x_phy *phy_blk[PORT_MAX];
7205         s8 port_of_path;
7206         swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
7207         swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
7208
7209         port = 1;
7210
7211         bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override));
7212
7213         /* Calculate the port based on port swap */
7214         port ^= (swap_val && swap_override);
7215
7216         msleep(5);
7217
7218         /* PART1 - Reset both phys */
7219         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7220                 u32 shmem_base, shmem2_base;
7221
7222                 /* In E2, same phy is using for port0 of the two paths */
7223                 if (CHIP_IS_E2(bp)) {
7224                         shmem_base = shmem_base_path[port];
7225                         shmem2_base = shmem2_base_path[port];
7226                         port_of_path = 0;
7227                 } else {
7228                         shmem_base = shmem_base_path[0];
7229                         shmem2_base = shmem2_base_path[0];
7230                         port_of_path = port;
7231                 }
7232
7233                 /* Extract the ext phy address for the port */
7234                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7235                                        port_of_path, &phy[port]) !=
7236                                        0) {
7237                         DP(NETIF_MSG_LINK, "populate phy failed\n");
7238                         return -EINVAL;
7239                 }
7240                 /* disable attentions */
7241                 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
7242                                port_of_path*4,
7243                                (NIG_MASK_XGXS0_LINK_STATUS |
7244                                 NIG_MASK_XGXS0_LINK10G |
7245                                 NIG_MASK_SERDES0_LINK_STATUS |
7246                                 NIG_MASK_MI_INT));
7247
7248
7249                 /* Reset the phy */
7250                 bnx2x_cl45_write(bp, &phy[port],
7251                                MDIO_PMA_DEVAD,
7252                                MDIO_PMA_REG_CTRL,
7253                                1<<15);
7254         }
7255
7256         /* Add delay of 150ms after reset */
7257         msleep(150);
7258         if (phy[PORT_0].addr & 0x1) {
7259                 phy_blk[PORT_0] = &(phy[PORT_1]);
7260                 phy_blk[PORT_1] = &(phy[PORT_0]);
7261         } else {
7262                 phy_blk[PORT_0] = &(phy[PORT_0]);
7263                 phy_blk[PORT_1] = &(phy[PORT_1]);
7264         }
7265         /* PART2 - Download firmware to both phys */
7266         for (port = PORT_MAX - 1; port >= PORT_0; port--) {
7267                 u16 fw_ver1;
7268                  if (CHIP_IS_E2(bp))
7269                         port_of_path = 0;
7270                 else
7271                         port_of_path = port;
7272                 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
7273                            phy_blk[port]->addr);
7274                 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
7275                                                   port_of_path);
7276                 bnx2x_cl45_read(bp, phy_blk[port],
7277                               MDIO_PMA_DEVAD,
7278                               MDIO_PMA_REG_ROM_VER1, &fw_ver1);
7279                 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
7280                         DP(NETIF_MSG_LINK,
7281                                  "bnx2x_8727_common_init_phy port %x:"
7282                                  "Download failed. fw version = 0x%x\n",
7283                                  port, fw_ver1);
7284                         return -EINVAL;
7285                 }
7286         }
7287
7288         return 0;
7289 }
7290
7291 static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
7292                                     u32 shmem2_base_path[], u8 phy_index,
7293                                     u32 ext_phy_type, u32 chip_id)
7294 {
7295         u8 rc = 0;
7296
7297         switch (ext_phy_type) {
7298         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7299                 rc = bnx2x_8073_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_BCM8727:
7305         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
7306                 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
7307                                                 shmem2_base_path,
7308                                                 phy_index, chip_id);
7309                 break;
7310
7311         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7312                 /* GPIO1 affects both ports, so there's need to pull
7313                 it for single port alone */
7314                 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
7315                                                 shmem2_base_path,
7316                                                 phy_index, chip_id);
7317                 break;
7318         case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
7319                 rc = -EINVAL;
7320                 break;
7321         default:
7322                 DP(NETIF_MSG_LINK,
7323                          "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
7324                          ext_phy_type);
7325                 break;
7326         }
7327
7328         return rc;
7329 }
7330
7331 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
7332                          u32 shmem2_base_path[], u32 chip_id)
7333 {
7334         u8 rc = 0;
7335         u8 phy_index;
7336         u32 ext_phy_type, ext_phy_config;
7337         DP(NETIF_MSG_LINK, "Begin common phy init\n");
7338
7339         if (CHIP_REV_IS_EMUL(bp))
7340                 return 0;
7341
7342         /* Read the ext_phy_type for arbitrary port(0) */
7343         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
7344               phy_index++) {
7345                 ext_phy_config = bnx2x_get_ext_phy_config(bp,
7346                                                           shmem_base_path[0],
7347                                                           phy_index, 0);
7348                 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
7349                 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
7350                                                 shmem2_base_path,
7351                                                 phy_index, ext_phy_type,
7352                                                 chip_id);
7353         }
7354         return rc;
7355 }
7356
7357 u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
7358 {
7359         u8 phy_index;
7360         struct bnx2x_phy phy;
7361         for (phy_index = INT_PHY; phy_index < MAX_PHYS;
7362               phy_index++) {
7363                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7364                                        0, &phy) != 0) {
7365                         DP(NETIF_MSG_LINK, "populate phy failed\n");
7366                         return 0;
7367                 }
7368
7369                 if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
7370                         return 1;
7371         }
7372         return 0;
7373 }
7374
7375 u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
7376                              u32 shmem_base,
7377                              u32 shmem2_base,
7378                              u8 port)
7379 {
7380         u8 phy_index, fan_failure_det_req = 0;
7381         struct bnx2x_phy phy;
7382         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
7383               phy_index++) {
7384                 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7385                                        port, &phy)
7386                     != 0) {
7387                         DP(NETIF_MSG_LINK, "populate phy failed\n");
7388                         return 0;
7389                 }
7390                 fan_failure_det_req |= (phy.flags &
7391                                         FLAGS_FAN_FAILURE_DET_REQ);
7392         }
7393         return fan_failure_det_req;
7394 }
7395
7396 void bnx2x_hw_reset_phy(struct link_params *params)
7397 {
7398         u8 phy_index;
7399         for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
7400               phy_index++) {
7401                 if (params->phy[phy_index].hw_reset) {
7402                         params->phy[phy_index].hw_reset(
7403                                 &params->phy[phy_index],
7404                                 params);
7405                         params->phy[phy_index] = phy_null;
7406                 }
7407         }
7408 }