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